Compare commits

...

240 Commits

Author SHA1 Message Date
Andrea Cavalli ea5e7c688e Test 2021-09-12 16:41:24 +02:00
Andrea Cavalli f5a4fe32db Test 2021-09-12 16:22:16 +02:00
Andrea Cavalli 672bba9ed0 Test 2021-09-12 16:08:21 +02:00
Andrea Cavalli d448ffcb05 Test 2021-09-12 16:05:52 +02:00
Andrea Cavalli 012d982d90 Test 2021-09-12 16:00:33 +02:00
Andrea Cavalli 6d2e5cd62e Change defaults 2021-09-12 15:57:52 +02:00
Andrea Cavalli e2d60a037c Change defaults 2021-09-12 15:44:42 +02:00
Andrea Cavalli 52687e0853 default 192DPI 2021-09-12 13:19:26 +02:00
Ryan Gonzalez 18f1ce0b6e xwayland: Clear output buffers on scale change 2021-08-23 13:21:28 -05:00
Ryan Gonzalez aa849658c5 xwayland: Allow controlling global output scale via properties
This adds a new property, _XWAYLAND_GLOBAL_OUTPUT_SCALE, to control the
global output scale from the compositor.
2021-08-23 13:21:28 -05:00
Christopher Snowhill b46a9bba29 xwayland: Fix cursor size, present scale, and present damage 2021-08-23 13:21:28 -05:00
Dario Nieuwenhuis fbc7cefc43 xwayland: Multi DPI support via global factor rescaling
To benefit from Wayland's multi DPI capabilities in XWayland a global scaling
factor is introduced, which is applied to all outputs.

The RandR size of an output is calculated by the (integer-)multiplication of
this global scaling factor with its logical size received via the xdg-output
protocol.

In other words the size of any RandR screen corresponds to the mode size of
its wl_output multiplied with the quotient of global scaling factor divided by
the compositor's internal output-dependent scaling factor.

HiDPI aware X clients can then provide Pixmaps enlarged by the global scaling
factor and the Wayland compositor is supposed to downscale these buffers on
outputs scaled by less than the global scaling factor.

A Wayland compositor needs to scale all X communication in its XWM part by the
global scaling factor, such that X windows have the correct geometry.

In summary:
* All positions in Wayland internal communication must be carried out by the
compositor in logical coordinates, i.e. in its compositor space.
* All positions in X internal communication are based on RandR sizes.
* All positions in Wayland to X communication must be multiplied by the global
scaling factor.
* All positions in X to Wayland communication must be divided by the global
scaling factor.

In order to not break compositors that do not support these transformations,
the global scaling factor is set to 1 by default, which behaves the same as
before.

[dirbaio@dirbaio.net: fix incorrect scaling in a few places]
[rymg19@gmail.com: minor style fixes]
Signed-off-by: Roman Gilg <subdiff@gmail.com>
Signed-off-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2021-08-23 13:21:28 -05:00
Povilas Kanapickas 18d3131f9a meson: Implement developer documentation build
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-08-20 10:26:07 +00:00
Povilas Kanapickas 722da1c62c meson: Add option to disable libdrm support
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-08-20 07:11:44 +00:00
Adam Jackson 1f720dc9a3 dmx: Fix some redeclaration warnings from gcc 11
Of the form:

    ../hw/dmx/config/xdmxconfig.c:68:26: warning: redundant redeclaration of ‘dmxConfigEntry’ [-Wredundant-decls]
       68 | extern DMXConfigEntryPtr dmxConfigEntry;
          |                          ^~~~~~~~~~~~~~
2021-08-17 16:06:57 -04:00
Adam Jackson b49f0f9b32 xkb: Silence a warning from gcc 11
I get this:

    In function ‘TryCopyStr’,
        inlined from ‘CopyISOLockArgs’ at ../xkb/xkbtext.c:875:9:
    ../xkb/xkbtext.c:720:13: warning: ‘tbuf’ may be used uninitialized [-Wmaybe-uninitialized]
      720 |             strcat(to, from);
          |             ^~~~~~~~~~~~~~~~
    ../xkb/xkbtext.c: In function ‘CopyISOLockArgs’:
    <built-in>: note: by argument 1 of type ‘const char *’ to ‘__builtin_strlen’ declared here
    ../xkb/xkbtext.c:871:10: note: ‘tbuf’ declared here
      871 |     char tbuf[64];
          |          ^~~~

Just initialize tbuf so it definitely works.
2021-08-17 16:04:40 -04:00
Adam Jackson c1138d8ec8 xinput: Silence a warning from gcc 11
[45/388] Compiling C object Xi/liblibxserver_xi.a.p/xichangehierarchy.c.o
../Xi/xichangehierarchy.c:61:32: warning: argument 1 of type ‘int[256]’ with mismatched bound [-Warray-parameter=]
   61 | XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
      |                            ~~~~^~~~~~~~~~~~~~~~~
In file included from ../Xi/xichangehierarchy.c:54:
../Xi/xichangehierarchy.h:42:37: note: previously declared as ‘int[]’
   42 | void XISendDeviceHierarchyEvent(int flags[]);
      |                                 ~~~~^~~~~~~
2021-08-17 16:02:44 -04:00
Adam Jackson f3a98334e6 selinux: Stop using security_context_t
This is apparently deprecated now and is and was always just char *.
2021-08-17 16:02:39 -04:00
Simon Ser 6f63873da5 xwayland: fix xdg_output leak
The xdg_output wasn't cleaned up when destroying the xwl_output.

Signed-off-by: Simon Ser <contact@emersion.fr>
2021-08-12 07:07:26 +00:00
Demi Marie Obenour 659260a0b7 More missing version checks in SProcs
The bug in XFixes was also found in GenericEvent and Damage.
2021-08-08 12:43:01 +00:00
Roman Gilg e4dabe8d93 Remove build-only include from public header
The dix-config.h file is not installed, but dix.h is. The include makes the
compilation of external drivers fail (for example the libinput driver).

The Xserver compilation also works without the include, so just remove it.

Signed-off-by: Roman Gilg <subdiff@gmail.com>
2021-08-07 14:26:26 +02:00
Demi Marie Obenour 31fb35a7af XFixes: add version check for byteswapped clients
The version check for byteswapped clients was missing.
2021-08-06 11:12:40 -04:00
Olivier Fourdan 7eba412072 xfree86: Move xf86CVTMode() function
The xf86CVTMode() was implemented in a standalone source file because it
was being used for both the xfree86 API and the standalone cvt utility.

Now that the cvt utility is removed (as part of libxcvt) we can move the
small xf86CVTMode() function with the rest of the xf86Modes sources.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
2021-08-06 11:29:29 +00:00
Olivier Fourdan f2781e9536 xfree86/cvt: Drop cvt utility
The cvt utility is now replaced by the standalone version found in
libxcvt, no need to build the one in xfree86 anymore.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
2021-08-06 11:29:29 +00:00
Olivier Fourdan f788289bdc xfree86: Use libxcvt
Replace the local implementation of the VESA CVT standard timing
modelines generator with the one from libxct to avoid code duplication.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
2021-08-06 11:29:29 +00:00
Olivier Fourdan 6ea2c001f9 xwayland: Use libxcvt
Xwayland is using a copy of the CVT generator found in Xorg.

Rather than duplicating the code within the xserver tree, use the
libxcvt implementation instead.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
2021-08-06 11:29:29 +00:00
Olivier Fourdan a4ab57cb74 build: Add dependency on libxcvt
libxcvt is a library providing a standalone version of the X server
implementation of the VESA CVT standard timing modelines generator.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
2021-08-06 11:29:29 +00:00
Olivier Fourdan 84897891e5 ci: Install libxcvt from git
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2021-08-06 11:29:29 +00:00
Demi Marie Obenour 5c2592cbb1 Add do-while loops to DIX macros
This ensures they will behave properly in conditionals and always
require a trailing semicolon.
2021-07-31 08:55:52 -04:00
Alex Richardson d83c84bd9d Mark the dixChangeWindowProperty() value argument as const
It is copied using memcpy() and not modified so we can add const. This
fixes a -Wincompatible-pointer-types-discards-qualifiers compiler warning
that was failing a -Werror XVnc build for me.

Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
2021-07-30 08:36:35 +00:00
Zoltán Böszörményi fb5322ce28 glamoregl: Initialize glamor on the main device
This allows e.g. an UDL device (driven by llvmpipe) to be automatically
set up with GPU acceleration via reverse PRIME.

The result is e.g.:

  # DISPLAY=:0.2 xrandr --listproviders
  Providers: number : 2
  Provider 0: id: 0xec cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 1 outputs: 1 associated providers: 1 name:modesetting
  Provider 1: id: 0x12c cap: 0xb, Source Output, Sink Output, Sink Offload crtcs: 2 outputs: 2 associated providers: 1 name:Intel

Signed-off-by: Zoltán Böszörményi <zboszor@gmail.com>
2021-07-30 00:27:39 +00:00
Zoltán Böszörményi f08bc32f5a xf86: Assign GPUs to screens according to configuration
If there is an explicit configuration, assign the RandR provider
of the GPUDevice to the screen it was specified for.

If there is no configuration (default case) the screen number is
still 0 so it doesn't change behaviour.

The result is e.g:

  # DISPLAY=:0.2 xrandr --listproviders
  Providers: number : 2
  Provider 0: id: 0xd2 cap: 0x2, Sink Output crtcs: 1 outputs: 1 associated providers: 0 name:modesetting
  Provider 1: id: 0xfd cap: 0xb, Source Output, Sink Output, Sink Offload crtcs: 2 outputs: 2 associated providers: 0 name:Intel

Signed-off-by: Zoltán Böszörményi <zboszor@gmail.com>
2021-07-30 00:27:39 +00:00
Zoltán Böszörményi cd567415cc xf86: Extract screen configuration matching into its own function
Signed-off-by: Zoltán Böszörményi <zboszor@gmail.com>
2021-07-30 00:27:39 +00:00
Boris-Barboris 16571b8926 Don't hardcode fps for fake screen
Currently, when main hardware screen is powered-off,
X server initializes fake screen's timer with
1 second update interval.

Streaming software like Nomachine or Vnc, as well as
desktop input automation suffers from it, since it
will forever be stuck on 1 fps until the display is
turned back on.

This commit adds command line option -fakescreenfps <int>
that allows the user to change the default fake screen
timer.

Signed-off-by: Baranin Alexander <ismailsiege@gmail.com>
2021-07-29 08:09:00 +00:00
Łukasz Spintzyk 8836b9d243 modesetting: unflip not possible when glamor is not set
This is fixing crashes of xfce when running under qemu
2021-07-22 13:24:21 +02:00
Łukasz Spintzyk d6c02ffd9c present: fallback get_crtc to return crtc belonging to screen with present extension
Since crtc can belong to secondary output that may not have present
extension enabled we should fallback to first enabled crtc or fake crtc.

Fix for issue xorg/xserver#1195
2021-07-20 08:10:46 +02:00
Michel Dänzer f6f2f203bc present: Drop flip_idler member from present_vblank_rec
It's redundant with the pixmap member of struct xwl_present_event.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:20:56 +02:00
Michel Dänzer 212cfbcf68 xwayland/present: Use present_vblank_ptr instead of xwl_present_event*
Where the latter isn't really needed.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:20:35 +02:00
Michel Dänzer fe8c7855f3 xwayland/present: Fold xwl_present_release_event into _free_event
The only difference was unhooking from the vblank.event_queue list,
which is already done by xwl_present_flip_notify_vblank in
xwl_present_msc_bump.
2021-07-09 16:20:20 +02:00
Michel Dänzer 31d2ebca77 xwayland/present: Drop target_msc member from struct xwl_present_event
Use present_vblank_rec::exec_msc instead.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:20:04 +02:00
Michel Dänzer 495ec59664 xwayland/present: Drop pending member from struct xwl_present_event
We are handling two cases here: the active flip or the pending flip.

For the pending flip (event->pending == TRUE), we called
xwl_present_release_pixmap.

For the active flip (event->pending == FALSE), we called
xwl_present_release_event. However, xwl_present_flip_notify_vblank
already unhooked event->vblank.event_queue. So this was effectively the
same as calling xwl_present_release_pixmap.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:19:30 +02:00
Michel Dänzer f73340445f xwayland/present: Drop list member from struct xwl_present_event
Use present_vblank_rec::event_queue instead.

The changes in xwl_present_execute shouldn't really be needed, since
we should never hit queue_vblank in present_execute_wait. But let's be
safe rather than sorry, plus this simplifies the code.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:18:56 +02:00
Michel Dänzer aac31d2758 xwayland/present: Drop exec_queue member from struct xwl_present_window
Doesn't serve any purpose anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:18:47 +02:00
Michel Dänzer f8c086b214 xwayland/present: Fold xwl_present_event_notify into its caller
Can just call xwl_present_execute directly.

This allows dropping the window member from struct xwl_present_window as
well.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:18:33 +02:00
Michel Dänzer c30f3d08ac xwayland/present: Use exec_queue for deferring completion events
We clear the vblank->pixmap field, so next time xwl_present_execute
falls through to present_execute_post.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:18:07 +02:00
Michel Dänzer 4503c8d9ea xwayland/present: Fold xwl_present_idle_notify into its caller
Allows simplification by avoiding indirection.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:17:55 +02:00
Michel Dänzer b2a06e0700 xwayland/present: Drop sync_flip member of struct xwl_present_window
The same information can be determined from the flip queue.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:17:44 +02:00
Michel Dänzer fc53e3c536 xwaland/present: Drop flip_pending member of struct xwl_present_window
Use the first element of the flip_queue list for the same purpose.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:17:23 +02:00
Michel Dänzer c592c66625 xwayland/present: Fold xwl_present_flip_notify into its callers
No need for them to be separate anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:17:15 +02:00
Michel Dänzer 4230176080 xwayland/present: Embed present_vblank_rec in xwl_present_event
This allows for various simplifications.

Use the pointer to the struct memory as the event ID. In contrast to
the SCMD code for Xorg (where pending DRM events cannot be cancelled),
this is safe here, because we can destroy pending Wayland callbacks. So
we can't get a callback with a stale pointer to freed memory.

Remove xwl_present_window::release_list in favour of
present_vblank_rec::window_list.

Remove xwl_present_event::xwl_present_window in favour of
present_vblank_rec::window.

xwl_present_free_event is never called for a NULL pointer anymore, no
need to check.

v2:
* Restore DestroyWindow wrapping order to make sure
  present_destroy_window doesn't call xwl_present_abort_vblank.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:15:50 +02:00
Michel Dänzer 61cc5d96ed present: Refactor present_vblank_init helper ouf of _vblank_create
Allows embedding into another struct.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:15:39 +02:00
Michel Dänzer 35f173ddb6 xwayland/present: Drop abort member of struct xwl_present_event
We can call xwl_present_free_event unconditionally from
xwl_present_abort_vblank, since the sync_callback is already destroyed
in xwl_present_cleanup.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:15:10 +02:00
Michel Dänzer 0517460301 xwayland/present: Simplify calls to Xwayland-private functions
Change parameter types to what's really needed, or just fold the
function into its only caller.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:14:56 +02:00
Michel Dänzer 490248ea70 xwayland/present: Rename present_wnmd_* functions to xwl_present_*
The WNMD indirection is gone.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:14:47 +02:00
Michel Dänzer 0c0cbbc7cb present: Remove present_wnmd_info_rec
Doesn't serve any purpose anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:14:38 +02:00
Michel Dänzer 561c63d0f1 xwayland/present: Merge present_wnmd_flips_stop & xwl_present_flips_stop
Just use the latter instead of the former elsewhere. No need for them
to be separate anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:14:28 +02:00
Michel Dänzer a67f16fde1 xwayland/present: Fold present_wnmd_get_ust_msc into its callers
Just use xwl_present_get_ust_msc directly. No need for the indirection
anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:14:19 +02:00
Michel Dänzer 080c1ca3f5 xwayland/present: Fold present_wnmd_queue_vblank into its callers
Just use xwl_present_queue_vblank directly. No need for the indirection
anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:14:09 +02:00
Michel Dänzer c22887bc7a xwayland/present: Fold present_wnmd_get_crtc into present_wnmd_pixmap
And use xwl_present_get_crtc directly.

No need for them to be separate anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:59 +02:00
Michel Dänzer cb35ff596e xwayland/present: Fold present_wnmd_check_flip into its callers
Mainly into xwl_present_check_flip, and call that from
present_wnmd_check_flip_window.

No need for them to be separate anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:48 +02:00
Michel Dänzer 7b78cf6b3a xwayland/present: Simplify query_capabilities
No need for the WNMD indirection anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:39 +02:00
Michel Dänzer 244403ec87 xwayland/present: Fold present_wnmd_abort_vblank into its only caller
No need for them to be separate anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:32 +02:00
Michel Dänzer f7adbc2166 xwayland/present: Drop present_wnmd_flush in favour of xwl_present_flush
No need for the indirection anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:24 +02:00
Michel Dänzer 7fd114365d xwayland/present: Fold present_wnmd_flip into present_wnmd_execute
No need for the indirection anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:15 +02:00
Michel Dänzer 2e1dcd731f xwayland/present: Fold present_wnmd_screen_init into xwl_present_init
No need for them to be separate anymore.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:13:04 +02:00
Michel Dänzer b6419359b6 present: Move present_wnmd.c contents to hw/xwayland/xwayland-present.c
This will allow eliminating indirections and making the Xwayland Present
code more efficient and easier to follow.

While this technically changes the Xorg video driver ABI, I don't know
of any drivers using the dropped present_wnmd_* symbols, and I doubt a
Xorg driver could make use of them as is anyway.

(As a bonus, Xorg no longer links any Xwayland specific Present code)

v2:
* Wrap DestroyWindow before initializing Present, so that
  present_destroy_window runs before xwl_present_cleanup. Avoids crash
  due to present_destroy_window calling xwl_present_* functions when
  xwl_present_window was already freed. (Olivier Fourdan)

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:11:22 +02:00
Michel Dänzer c35a716b02 present: Fold wnmd_init_mode_hooks into wnmd_screen_init
Preparation for moving WNMD code to hw/xwayland. No functional change
intended.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:11:11 +02:00
Michel Dänzer 10bdd87fe4 present: Move present_wnmd_screen_init to present_wnmd.c
Now all WNMD code is in present_wnmd.c.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:11:02 +02:00
Michel Dänzer b6d54b0f5d present: Dispatch clear_window_flip via present_screen_priv hook
Eliminates special cases in present_destroy_window.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:10:54 +02:00
Michel Dänzer 93666ebe37 present: Remove create_event_id hook
Each present_vblank_create caller generates and sets the ID afterwards.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:10:43 +02:00
Michel Dänzer 44f705a5b6 present: Pass capabilities to present_vblank_create by value
Preparation for moving WNMD code to hw/xwayland. No functional change
intended.

Acked-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 16:10:06 +02:00
Michel Dänzer 86e645bcfa xwayland/eglstream: Drop xwl_eglstream_set_window_pixmap
Not sure why we'd need to abandon a pending stream for a pixmap just
because it's no longer a window pixmap. Let's try not to.

Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 15:51:43 +02:00
Michel Dänzer ba8763c27b xwayland/eglstream: Consolidate pending_cb destruction
Into a new xwl_eglstream_destroy_pending_stream helper.

Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 15:50:57 +02:00
Michel Dänzer 204f10c29e xwayland: Call RRTellChanged if the RandR configuration may have changed
This makes sure RandR events are sent to interested clients as needed.
This was happening implicitly in some cases, but not in others, e.g. if
the root window size didn't change.

If this were to call RRTellChanged more often than necessary in some
cases, that should be harmless, as it only sends events if something
has actually changed since last time.

Should fix https://bugzilla.redhat.com/show_bug.cgi?id=1979892 .

v2:
* Call RRTellChanged at the very end of update_screen_size, just in
  case.

Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 11:48:15 +02:00
Michel Dänzer a6d178b6af randr: Bail from RRTellChanged if there's no root window yet
This can happen if RRTellChanged is called during initialization.

Continuing in that case makes no sense conceptually:

* Any event sent over the wire requires a corresponding window.
* No root window probably means there can't be any clients which could
  receive the events.

In practice, it would result in a crash down the road due to
dereferencing the NULL ScreenRec::root pointer.

Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-07-09 11:48:15 +02:00
Matt Turner 7e20c8b7b8 Build xz tarballs instead of bzip2
Signed-off-by: Matt Turner <mattst88@gmail.com>
2021-07-08 12:32:01 -07:00
Dave Airlie a955286869 glamor: add EXT_gpu_shader4 support
This enables a number of the GLSL 1.30 paths on GPUs that have
EXT_gpu_shader4 but don't have GLSL 1.30 exposed.

(Intel gen4/5 mainly)

Reviewed-by: Adam Jackson <ajax@redhat.com>
2021-07-07 08:42:09 +10:00
Dave Airlie a2f5b917f5 glamor: add glamor_glsl_has_ints wrapper
This should make adding gpu shader4 support cleaner

Reviewed-by: Adam Jackson <ajax@redhat.com>
2021-07-07 08:41:50 +10:00
Povilas Kanapickas b4f55712da xserver 21.0.99.1
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-07-05 21:40:55 +03:00
Povilas Kanapickas b67e514dbb meson: Fix warnings when reading back and checking feature flags
Meson does not like comparing things of different types which is a
problem when reading back values of feature flags as they may contain
either false (bool) or 1 (string).

Since there is a strong reason why we use false when the feature does
not exist, we work around this issue by always converting the returned
value to int via to_int().

Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1190
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-07-05 12:46:14 +00:00
Adam Jackson b2a0de4f07 xfixes: Allow the client to upgrade the fixes protocol version
If you say FixesQueryVersion twice we remember whatever the second
version number was. With just libXfixes this isn't an issue because the
request is hidden in extension setup, but libxcb-xfixes doesn't do that
for you, which means the second one can _lower_ the requested fixes
version, disabling requests that the client thought it had enabled.

Paper over this by allowing the version number to be raised but not
lowered. Also go ahead and delete the minor version number from the
client state since xfixes doesn't have minor versions (yet, anyway).
2021-07-01 19:18:19 +00:00
Olivier Fourdan 7d509b6f34 xwayland/eglstream: Remove stream validity
To avoid an EGL stream in the wrong state, if the window pixmap changed
before the stream was connected, we would still keep the pending stream
but mark it as invalid. Once the callback is received, the pending would
be simply discarded.

But all of this is actually to avoid a bug in egl-wayland, there should
not be any problem with Xwayland destroying an EGL stream while the
compositor is still using it.

With that bug now fixed in egl-wayland 1.1.7, we can safely drop all
that logic from Xwayland EGLstream backend.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1189
2021-06-30 09:06:37 +02:00
Olivier Fourdan 2be9f795bc xwayland/eglstream: Keep pending stream if the pixmap didn't change
If the pixmap does not actually change in set_window_pixmap(), there is
no need to invalidate the pending stream, if there's one.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-06-29 15:59:41 +02:00
orbea 2531ee0245 hw/dmx/config: Link directly with libdmxconfig.a
When building xserver with slibtool (https://dev.midipix.org/cross/slibtool)
the build will fail.

  /usr/bin/ld: cannot find -ldmxconfig

This is because xserver creates libdmxconfig.a internally and then links with
the linker flag -ldmxconfig. However according to automake documentation the
-lfoo linker flags should only be used for external dependencies and all
internal libraries should be linked with the libtool archive file (.la) or
the static archive (.a) when the former is not available.

GNU libtool is far more permissive and happens to silently obscure this issue
while slibtool fails because it instead sees '-L./.libs -ldmxconfig'.
2021-06-25 18:54:46 +00:00
Povilas Kanapickas 2f53d1cf73 config: Fix platform busid parsing when there is no ID_PATH prop
On at least Lenovo Thinkpad E585 udev does not have ID_PATH property for
the drm node (see
https://gitlab.freedesktop.org/xorg/xserver/-/issues/993). While this is
likely udev bug, this causes the device to be not recognized as
attribs->busid is NULL, which causes platform_find_pci_info to be not
called and corresponding xf86_platform_devices[i]->pdev to be NULL.

At this moment pdev being NULL will cause a crash, but this is a
different bug.

Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/993
Fixes: 0816e8fc linux: Make platform device probe less fragile
Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-25 13:24:51 +03:00
Olivier Certner d4b38e1119 os: Properly report failure to link lock file
Stop assuming that a failure to link always means that the file indeed
exists. In case of other failure (e.g., permissions), the user would get an
inconsistent "Can't read lock file" message.

Signed-off-by: Olivier Certner <olce.freedesktop@certner.fr>
2021-06-25 10:18:18 +00:00
Łukasz Spintzyk d66b7ec129 xfree86: Fix out of array bound access to xf86Entities
Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-06-24 09:05:57 +02:00
Povilas Kanapickas 0d93bbfa2c xfree86: Fix potentially NULL reference to platform device's PCI device
xf86_platform_devices[i].pdev may be NULL in cases we fail to parse the
busid in config_udev_odev_setup_attribs() (see also [1], [2]) such as
when udev does not give use ID_PATH. This in turn leads to
platform_find_pci_info() being not called and pdev being NULL.

[1]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/993
[2]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1076

Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-23 14:29:10 +03:00
Povilas Kanapickas 303763941f xfree86: Consistently check for reference to primaryBus pci_device
This is the only place where we don't check whether
primaryBus.id.plat->pdev is not NULL before accessing its members.

It may be NULL in cases we fail to parse the busid in
config_udev_odev_setup_attribs() (see also [1], [2]) such as when udev
does not give use ID_PATH. This in turn leads to
platform_find_pci_info() being not called and pdev being NULL in one of
the items within the xf86_platform_devices array. For this to cause a
crash we only need it to become the primaryBus device.

[1]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/993
[2]: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1076

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-23 14:29:10 +03:00
Povilas Kanapickas b9722d39cd configure.ac: Switch project version to 20.x.y style
Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-23 14:23:55 +03:00
Zoltán Böszörményi ef89b6648e xfree86: Fix NULL pointer dereference crash
screenp->displays[count] (passed to configDisplay() in
configScreen()) is NULL if there is no Virtual setting
in the configuration.

Fixes: f8a6be04d0 ("xfree86: Change
displays array to pointers array to fix invalid pointer issues
after table reallocation")

Signed-off-by: Zoltán Böszörményi <zboszor@gmail.com>
2021-06-21 14:11:37 +02:00
Olivier Fourdan aad61e8e03 glx: Fix use after free in MakeCurrent
The fix from commit c468d34c7 - "glx: Set ContextTag for all contexts"
is actually incomplete, it correctly sets the context tag for direct
contexts as well, but would fail to mark the context's currentClient.

As a result, when the context is destroyed, it would be freed
immediately rather than being just scheduled for deletion, even though
it is still current for some client. leading to a use-after-free.

Make sure to also set the context's currentClient for direct contexts as
well, not just indirect ones.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Fixes: c468d34c7 - "glx: Set ContextTag for all contexts"
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1186
Reviewed-by: Adam Jackson <ajax@redhat.com>
2021-06-21 08:39:38 +02:00
Povilas Kanapickas 021b3c2f77 configure.ac: Bump inputproto dep to 2.3.99.1
This should have been part of 6cbcbc81525b131b5b94409ea870af663d5c28bb.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-16 13:01:17 +00:00
Daniel Strnad 05b3c681ea hw/xfree86: Propagate physical dimensions from DRM connector
Physical dimmension of display can be obtained not just by configuration or
DDC, but also directly from kernel via drmModeGetConnector(). Until now
xserver silently discarded these values even when no configuration nor EDID
were present and fallbacked to default DPI.
2021-06-15 13:21:11 +00:00
Łukasz Spintzyk f8a6be04d0 xfree86: Change displays array to pointers array to fix invalid pointer issues after table reallocation
There are rare cases when xf86SetDepthBpp is resizing displays array in confScreen.
As that array is shared between set of ScrnInfoRec's then realloc might invalidate chached DispPtr display values in
otheres ScrnInfoRec objects.

If we will change displays array as an array of pointers to DispRec then cached DispRec pointers in ScrnInfoRec
won't be invalid after reallocation of displays array.

Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-06-15 10:01:14 +00:00
Povilas Kanapickas 1a1bd5cf7a modesetting: Add a limit on async page flip error log frequency
In certain circumstances we will have a lot of flip errors without a
reasonable way to prevent them. In such case we reduce the number of
logged messages to at least not fill the error logs.

The details are as follows:

At least on i915 hardware support for async page flip support depends on
the used modifiers which themselves can change dynamically for a screen.
This results in the following problems:

- We can't know about whether a particular CRTC will be able to do an
async flip without hardcoding the same logic as the kernel as there's no
interface to query this information.

- There is no way to give this information to an application, because
the protocol of the present extension does not specify anything about
changing of the capabilities on runtime or the need to re-query them.

Even if the above was solved, the only benefit would be avoiding a
roundtrip to the kernel and reduced amount of error logs. The former
does not seem to be a good enough benefit compared to the amount of work
that would need to be done. The latter is solved in this commit.

Reviewed-by: Eero Tamminen <eero.t.tamminen@intel.com>
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-15 12:53:33 +03:00
Povilas Kanapickas 9992245c5f modesetting: Extract flip failure logging to a single place
Reviewed-by: Eero Tamminen <eero.t.tamminen@intel.com>
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-06-15 12:53:33 +03:00
Jose Maria Casanova Crespo 9adb13e296 glamor: Avoid using GL_QUADS on V3D
Like in 0e3f1252da ("glamor: Avoid using GL_QUADS on VC4")
this will avoid mesa to fallback doing conversion for QUADS primitives.

Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
2021-06-14 21:36:13 +02:00
Michel Dänzer 104c7c5048 xwayland/present: Move wl_buffer check into xwl_glamor_check_flip
Keeps the glamor specific code together more.

Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-06-14 10:44:03 +02:00
Michel Dänzer 3641c24bd0 xwayland/eglstream: Handle xwl_pixmap_get returning NULL
In xwl_glamor_eglstream_get_wl_buffer_for_pixmap. This can likely be hit
now with an SHM pixmap via the Present flip path. There might be other
corner cases.

Fixes: f3eb1684fa "xwayland: enable MIT-SHM shared pixmaps"
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-06-14 10:43:59 +02:00
Michel Dänzer d163e0a1d5 ci: Fix UPSTREAM_REPO -> FDO_UPSTREAM_REPO
The latter is what ci-templates expect.

Fixes: ab73c16930 "ci: Update to the latest templates"
Reviewed-by: Simon Ser <contact@emersion.fr>
2021-06-11 18:25:01 +02:00
Lukasz Spintzyk 7e7c147105 modesetting: Disable reverse prime offload mode for displays running on evdi,udl
This mode for displays running on evdi/udl as side effect of failed glamor_egl_init
reverse_prime_offload_mode was initialized to FALSE

After Mesa upgrade to 21.0.0 GL_RENDERER is not llvmpipe that results in successful glamor_egl_init
and reverse_prime_offload_mode enabled.

This commit is explicitly disabling reverse_prime_offload_mode for evdi and udl drivers

Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-06-08 16:20:36 +00:00
Olivier Fourdan c468d34c72 glx: Set ContextTag for all contexts
Currently, xorgGlxMakeCurrent() would set the context tag only for
indirect GLX contexts.

However, several other places expect to find a context for the tag or
they would raise a GLXBadContextTag error, such as WaitGL() or WaitX().

Set the context tag for direct contexts as well, to avoid raising an
error and possibly killing the client.

Thanks to Erik Kurzinger <ekurzinger@nvidia.com> for spotting the issue.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2021-06-08 07:20:53 +00:00
Olivier Fourdan 6b47321bc6 dix: Add optional terminate delay
When the command line option "-terminate" is used, it could be
interesting to give it an optional grace period to let the Xserver
running for a little longer in case a new connection occurs.

This adds an optional parameter to the "-terminate" command line option
for this purpose.

v2: Use a delay in seconds instead of milliseconds
    (Martin Peres <martin.peres@mupuf.org>)
v3: Clarify man page entry, ensure terminateDelay is always >= 0,
    simplify TimerFree(). (Peter Hutterer <peter.hutterer@who-t.net>)

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-06-07 17:28:05 +02:00
Olivier Fourdan e167299f60 xfixes: Add ClientDisconnectMode
With Wayland compositors now being able to start Xwayland on demand, the
next logical step is to be able to stop Xwayland when there is no more
need for it.

The Xserver itself is capable of terminating itself once all X11 clients
are gone, yet in a typical full session, there are a number of X11
clients running continuously (e.g. the Xsettings daemon, IBus, etc.).

Those always-running clients will prevent the Xserver from terminating,
because the actual number of X11 clients will never drop to 0. Worse,
the X11 window manager of a Wayland compositor also counts as an X11
client, hence also preventing Xwayland from stopping.

Some compositors such as mutter use the XRes extension to query the X11
clients connected, match their PID with the actual executable name and
compare those with a list of executables that can be ignored when
deciding to kill the Xserver.

But that's not just clumsy, it is also racy, because a new X11 client
might initiate a connection the X11 server right when the compositor is
about to kill it.

To solve this issue directly at the Xserver level, this add new entries
to the XFixes extension to let the X11 clients themselves specify the
disconnect mode they expect.

Typically, those X11 daemon clients would specify the disconnect mode
XFixesClientDisconnectFlagTerminate to let the Xserver know that they
should not be accounted for when checking the remaining clients prior
to terminate.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-06-07 17:28:05 +02:00
Erik Kurzinger b7a85e44da glx: don't create implicit GLXWindow if one already exists
If a GLXMakeCurrent request specifies an X window as its drawable,
__glXGetDrawable will implicitly create a GLXWindow for it. However,
the client may have already explicitly created a GLXWindow for that X
window. If that happens, two __glXDrawableRes resources will be added
to the window.

If the explicitly-created GLXWindow is later destroyed by the client,
DrawableGone will call FreeResourceByType on the X window, but this
will actually free the resource for the implicitly-created GLXWindow,
since that one would be at the head of the list.

Then if the X window is destroyed after that, the resource for the
explicitly-created GLXWindow will be freed. But that GLXWindow was
already destroyed above. This crashes the server when it tries to call
the destroyed GLXWindow's destructor. It also means the
implicitly-created GLXWindow would have been leaked since the
FreeResourceByType call mentioned above skips calling the destructor.

To fix this, if __glXGetDrawable is given an X window, it should check
if there is already a GLXWindow associated with it, and only create an
implicit one if there is not.

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2021-06-07 14:53:13 +00:00
Jan Beich 8274dd6643 meson: provide fallback for *proto dependencies
Meson has a built-in facility to use bundled versions of dependencies
if system packages are too old. Enable for xorgproto after 8e504d8b36eb:

Run-time dependency xproto found: YES 7.0.33
Run-time dependency randrproto found: YES 1.6.0
Run-time dependency renderproto found: YES 0.11.1
Run-time dependency xextproto found: YES 7.3.0
Dependency inputproto found: NO found 2.3.2 but need: '>= 2.3.99.1'
Found CMake: /usr/local/bin/cmake (3.20.2)
Run-time dependency inputproto found: NO (tried pkgconfig and cmake)
Looking for a fallback subproject for the dependency inputproto

meson.build:73:0: ERROR: Neither a subproject directory nor a xorgproto.wrap file was found.
2021-06-01 02:44:58 +00:00
Olivier Fourdan 34a58d7714 xwayland/eglstream: Log when GL_OES_EGL_image is missing
That will dramatically affect performance, might as well log when we
cannot use GL_OES_EGL_image with the NVIDIA closed-source driver.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-31 08:24:00 +00:00
Olivier Fourdan fae58e9b03 xwayland/eglstream: Use "nvidia" for GLVND
If the EGLStream backend is able to use hardware acceleration with the
NVIDIA closed source driver, we should use the "nvidia" GLX
implementation instead of the one from Mesa to take advantage of the
NVIDIA hardware accelerated rendering.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-31 08:24:00 +00:00
Olivier Fourdan 24fc8aea1e xwayland: Add preferred GLVND vendor to xwl_screen
If Xwayland's EGLstream backend supports hardware acceleration with the
NVIDIA closed-source driver, the GLX library also needs to be one
shipped by NVIDIA, that's what GLVND is for.

Add a new member to the xwl_screen that the backend can optionally set
to the preferred GLVND vendor to use.

If not set, "mesa" is assumed.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-31 08:24:00 +00:00
Niveditha Rau 2de5ded3c6 glx: Check for byte-swapping in SetReplyHeader
Check for the need to byte-swap when attempting to display
GL apps between a big-endian server and little-endian client
or vice versa.

Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1127
2021-05-30 13:49:37 -07:00
Adam Jackson bcb1de600a glx: Fix error return code in GLXGetDrawableAttributes
This should only ever throw GLXBadDrawable, says the protocol spec.
2021-05-30 10:59:58 +00:00
Povilas Kanapickas eb6f8daca5 Xi: Work around broken libxcb that doesn't ignore unknown device classes
libxcb 14.1 and older are not forwards-compatible with new device
classes as it does not properly ignore unknown device classes. Since
breaking libxcb would break quite a lot of applications, we instead
report Gesture device class only if the client advertised support for XI
2.4.

Clients may still not work in cases when a client advertises XI 2.4
support and then a completely separate module within the client uses
broken libxcb to call XIQueryDevice.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-05-30 13:46:59 +03:00
Povilas Kanapickas 7e692633fb Xi: Implement gesture support for XIQueryDevice 2021-05-30 13:46:59 +03:00
Povilas Kanapickas 0886254f96 xfree86: Bump input minor ABI due to addition touchpad gestures
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-05-30 13:26:46 +03:00
Povilas Kanapickas 1cdc3b5d14 xfree86: Implement gesture support for test input driver 2021-05-30 13:26:45 +03:00
Povilas Kanapickas dccc0275f4 Bump XI protocol version to 2.4 2021-05-30 13:26:44 +03:00
Povilas Kanapickas 75feb13668 Xi: Include gestures among events that may freeze device 2021-05-30 13:26:43 +03:00
Povilas Kanapickas 5163fc8bc2 Implement gesture processing logic 2021-05-30 13:26:42 +03:00
Povilas Kanapickas d3c52df161 hw/xfree86: Implement public APIs to submit gesture events 2021-05-30 13:26:41 +03:00
Povilas Kanapickas 100a2ad6da dix: Implement gesture event submission code path 2021-05-30 13:26:40 +03:00
Povilas Kanapickas 7656a9c8dd dix: Implement internal gesture state handling 2021-05-30 13:26:39 +03:00
Povilas Kanapickas 0bf4123fd3 dix: Implement gesture event fixups before delivery 2021-05-30 13:26:38 +03:00
Povilas Kanapickas 227f601de3 xi: Implement conversions from internal to Xi2 gesture event structs 2021-05-30 13:26:37 +03:00
Povilas Kanapickas f3462178ca test/xi2: Verify that XI_GestureSwipeEnd is ignored when outside mask 2021-05-30 13:26:36 +03:00
Povilas Kanapickas 407a2234b3 test/xi2: Update tests for gesture event types 2021-05-30 13:26:35 +03:00
Povilas Kanapickas f83f7dbb1c xi: Bump max supported XI2 event type 2021-05-30 13:26:34 +03:00
Povilas Kanapickas 8190954639 xi: Implement selection logic for gesture event types 2021-05-30 13:26:33 +03:00
Povilas Kanapickas 080bac39c8 xi: Implement grab support for new gesture event types 2021-05-30 13:26:32 +03:00
Povilas Kanapickas b544a1fdb8 xi: Implement internal gesture event struct 2021-05-30 13:26:31 +03:00
Povilas Kanapickas 22fa31ed56 dix: Add new internal event enums for gesture events 2021-05-30 13:26:30 +03:00
Povilas Kanapickas 8e504d8b36 meson: Depend on inputproto 2.3.99.1
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-05-30 13:26:29 +03:00
Povilas Kanapickas 2acde60147 .gitlab-ci: Install xorgproto 2021.4.99.2 from git
This is required for the support of upcoming XI 2.4 protocol.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-05-30 13:26:28 +03:00
Claes Nästén 236d177550 os: include unistd.h when HAVE_PSTACK is defined
On Solaris when HAVE_PSTACK is defined unistd.h needs to be included to
avoid implicit declarations of pipe, read, execle etc.
2021-05-27 21:33:12 +00:00
Erik Kurzinger 7515c23a41 xwayland/eglstream: flush stream after eglSwapBuffers
When eglSwapBuffers inserts a new frame into a window's stream, there may be a
delay before the state of the consumer end of the stream is updated to reflect
this. If the subsequent wl_surface_attach, wl_surface_damage, wl_surface_commit
calls are received by the compositor before then, it will (typically) re-use
the previous frame acquired from the stream instead of the latest one.

This can leave the window displaying out-of-date contents, which might never be
updated thereafter.

To fix this, after calling eglSwapBuffers, xwl_glamor_eglstream_post_damage
should call eglStreamFlushNV. This call will block until it can be guaranteed
that the state of the consumer end of the stream has been updated to reflect
that a new frame is available.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1171

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
2021-05-20 12:46:23 +00:00
Simon Ser f3eb1684fa xwayland: enable MIT-SHM shared pixmaps
Allow X11 clients to create shared pixmaps via the MIT-SHM
extension under Xwayland. Tested with a wlroots patch [1].

Also add a few assertions to make sure we have wl_buffers where we
need them.

[1]: https://github.com/swaywm/wlroots/pull/2875

Signed-off-by: Simon Ser <contact@emersion.fr>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-18 15:19:55 +00:00
Erik Kurzinger 3d33d885fc xwayland/eglstream: allow commits to dma-buf backed pixmaps
As of commit 098e0f52 xwl_glamor_eglstream_allow_commits will not allow commits
if the xwl_pixmap does not have an EGLSurface. This is valid for pixmaps backed
by an EGLStream, however pixmaps backed by a dma-buf for OpenGL or Vulkan
rendering will never have an EGLSurface.  Unlike EGLStream backed pixmaps,
though, glamor will render directly to the buffer that Xwayland passes to the
compositor. Hence, they don't require the intermediate copy in
xwl_glamor_eglstream_post_damage that EGLStream backed pixmaps do, so there is
no need for an EGLSurface.

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-17 12:32:22 -04:00
Olivier Fourdan 012350e3db xwayland/eglstream: Set ALU to GXCopy for blitting
The EGLstream backend's post damage function uses a shader and
glDrawArrays() to copy the data from the glamor's pixmap texture prior
to do the eglSwapBuffers().

However, glDrawArrays() can be affected by the GL state, and therefore
not reliably produce the expected copy, causing the content of the
buffer to be corrupted.

Make sure to set the ALU to GXCopy prior to call glDrawArrays() to get
the expected result.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-11 14:08:58 +02:00
Olivier Fourdan d85bfa6ab7 xwayland/eglstream: Do not always increment pixmap refcnt on commit
Currently, the EGLstream backend would increment the pixmap refcount for
each commit, and decrease that refcount on the wl_buffer release
callback.

But that's relying on the compositor sending us a release callback for
each commit, otherwise the pixmap refcount will keep increasing and the
pixmap will be leaked.

So instead, increment the refcount on the pixmap only when we have not
received a release notification for the wl_buffer, to avoid increasing
the pixmap refcount more than once without a corresponding release
event.

This way, if the pixmap is still in use when released on the X11 side,
the EGL stream will be kept until the compositor releases it.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-11 14:08:58 +02:00
Olivier Fourdan b583395cd3 xwayland/eglstream: Check eglSwapBuffers()
EGLstream's post_damage() would unconditionally return success
regardless of the actual status of the eglSwapBuffers().

Yet, if eglSwapBuffers() fails, we should not post the corresponding
damage as they wouldn't match the actual content of the buffer.

Use the eglSwapBuffers() return value as the return value for
post_damage() and do not take a refrence on the pixmap if it fails.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-11 14:08:58 +02:00
Olivier Fourdan a457999710 xwayland/eglstream: Fix calloc/malloc
Use calloc() instead of malloc() like the rest of the code.

Also fix the arguments of calloc() calls to match the definition which
is calloc(size_t nmemb, size_t size).

This is a cleanup patch, no functional change.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-11 14:08:58 +02:00
Olivier Fourdan 098e0f52c0 xwayland/eglstream: Do not commit without surface
The EGL surface for the xwl_pixmap is created once the stream is ready
and valid.

If the pixmap's EGL surface fails, for whatever reason, the xwl_pixmap
will be unusable and will end up as an invalid wl_buffer.

Make sure we do not allow commits in that case and recreate the
xwl_pixmap/stream.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan bee2ebb29f xwayland/eglstream: Drop the list of pending streams
Now that the pending stream is associated with the xwl_pixmap for
EGLStream and the xwl_pixmap itself is associated to the pixmap, we have
a reliable way to get to those data from any pending stream.

As a result, the list of pending streams that we keep in the EGLStream
global structure becomes useless.

So we can drop the pending stream's xwl_pixmap and also the list of
pending streams altogether, and save us a walk though that list for each
callback.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Suggested-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-11 14:08:58 +02:00
Olivier Fourdan e19bf86c17 xwayland/eglstream: Keep a reference to the pixmap
Commit affc47452 - "xwayland: Drop the separate refcount for the
xwl_pixmap" removed the separate reference counter for the xwl_pixmap
which holds the EGLStream.

While that works fine for the common case, if the window's pixmap is
changed before the stream is ready, the older pixmap will be destroyed
and the xwl_pixmap along with it, even if the compositor is still using
the stream.

The code that was removed with commit affc47452 was taking care of that
by increasing the separate reference counter for the xwl_pixmap, but it
no longer the case.

As a result, we may end up with the EGL stream in the wrong state when
trying to use it, which will cascade down into all sort of issues.

To avoid the problem, increase the reference count on the pixmap when it
is marked as invalid in EGLStream's SetWindowPixmap().

This way, the xwl_pixmap and the EGLStream are kept until released by
the compositor, even when the pixmap changes before stream is ready.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Fixes: affc47452 xwayland: Drop the separate refcount for the xwl_pixmap
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan cb61ecc729 xwayland/eglstream: Dissociate pending stream from window
Previously, we would have pending streams associated with top level X11
windows, keeping temporary accounting for the pending streams before
they get fully initialized for the xwl_pixmap which would be associated
with X11 pixmaps.

If the window content changes before the stream is ready, the
corresponding pending stream would be marked as invalid and the pending
stream would be eventually removed once the stream becomes ready.

Since commit affc47452 - "xwayland: Drop the separate refcount for the
xwl_pixmap", we no longer keep a separate reference counter for the
xwl_pixmap, but rather tie it to the X11 pixmap lifespan. Yet, the
pending stream would still be associated with the X11 toplevel window.

Dissociate the pending streams from the X11 toplevel window, to keep it
tied only to the xwl_pixmap so that we can have:

 - pixmap <-> xwl_pixmap
 - xwl_pixmap <-> pending stream

Of course, the pending streams remain temporary and get removed as soon
as the ready callback is triggered, but the pending streams are not
linked to the X11 window anymore which can change their content, and
therefore their X11 pixmap at any time.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan cc596bcfb2 xwayland/eglstream: Add more error checking
eglCreateStreamKHR() can fail and return EGL_NO_STREAM_KHR, in which
case there is no point in trying to create a buffer from it.

Similarly, eglCreateStreamProducerSurfaceKHR() also fail and return
EGL_NO_SURFACE, which in turn will be used in eglMakeCurrent() as
draw/read surface, and therefore would mean no draw/read buffer.

In those cases, log the error, and bail out early. That won't solve the
issue but will help with investigating the root cause of issues with
EGLStream backend.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan 823f3254fa xwayland/eglstream: Small refactoring
Some functions are called "callback" whereas they are not longer
callback functions or "unref" while they no longer deal with a reference
counter anymore, which is quite confusing. Rename those functions to be
more explicit.

Also, the pending streams can be destroyed in different places, move the
common code to separate function to avoid duplicating code and help with
readability of the code.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
2021-05-11 14:08:58 +02:00
Olivier Fourdan 85244d2a20 xwayland/eglstream: Check framebuffer status
The EGLStream backend would sometime generate GL errors trying to draw
to the framebuffer, which gives an invalid buffer, which in turn would
generate a Wayland error from the compositor which is fatal to the
client.

Check the framebuffer status and bail out early if it's not complete,
to avoid getting into trouble later.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan 252cbad316 xwayland/glamor: Add return status to post_damage
If the glamor backend failed to post damage, the caller should do the
same to avoid a failure to attach the buffer to the Wayland surface.

Change the API of Xwayland's glamor backend post_damage() to return a
status so that xwl_window_post_damage() can tell whether the callee
failed.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan 3b265c59a6 glamor: Dump backtrace on GL error
Currrently, when a GL error is triggered, glamor would log the error
which may not be sufficient to trace it back to the cause of the error.

Also dump the backtrace which may give more information as to where the
error comes from.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan 25d2f4948f xwayland: Check buffer prior to attaching it
If the buffer is NULL, do not even try to attach it, and risk a Wayland
protocol error which would be fatal to us.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Olivier Fourdan 4f0889e983 xwayland/eglstream: Check buffer creation
EGLStream wl_eglstream_display_create_stream() may fail, yet Xwayland
would try to attach the buffer which may cause a fatal Wayland protocol
error raised by the compositor.

Check if the buffer creation worked, and fail gracefully otherwise (like
wayland-eglsurface does).

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
https://gitlab.freedesktop.org/xorg/xserver/-/issues/1156
2021-05-11 14:08:58 +02:00
Erik Kurzinger 4f6fbd5009 xwayland-eglstream: fix X11 rendering to flipping GL / VK window
If a window is being used for direct rendering with OpenGL or Vulkan, and is
using the flipping path for presentation, it's pixmap will be set to a dma-buf
backed pixmap created by the client-side GL driver. However, this means that
xwl_glamor_eglstream_post_damage won't work since it requires that the pixmap
has an EGLSurface that it can render to, which dma-buf backed pixmaps do not.

In this case, though, xwl_glamor_eglstream_post_damage is not necessary since
glamor will have rendered directly to the pixmap, so we can simply pass it
directly to the compositor. There's no need for the intermediate copy we
normally do in that function.

Therefore, this change adds an early-return case to post_damage for dma-buf
backed pixmaps, and removes the corresponding asserts from that function and
allow_commits.

Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-04-30 11:08:41 -04:00
qarmin a50a0e3485 glxcmds: Fix possible out of bounds 2021-04-24 19:42:52 +00:00
Mazlan, Hazwan Arif 3ea46f9336 dri2: Sync i965_pci_ids.h from mesa iris_pci_ids.h
Copied TGL PCI ID from MESA iris_pci_ids.h
This update brings in a significant number of new platform ID's
Sync up until commit f02ae698

Signed-off-by: Mazlan, Hazwan Arif <hazwan.arif.mazlan@intel.com>
2021-04-24 19:21:41 +00:00
Jon Turney d3933a24d1 CI: Add an x86 MinGW-w64 cross build
Only cross-build for x86 MinGW-w64, as x64 MinGW-w64 will probably
require fixing LLP64 issues.

I don't know any source for pre-built cross-dependencies of the X
server, so build these from git.

Don't build with GLX enabled, so I don't have to deal with
cross-building mesa and it's dependencies, for the moment.
2021-04-24 19:43:00 +01:00
luporl 7e142cb2a8 xserver: fix RGB mask handling
On FreeBSD 13.0-CURRENT for PowerPC64 big-endian (BE), X was
crashing in some cases. For instance, when twm was started
and the background was clicked to open its menu, X crashed
with a segmentation fault, trying to dereference a null pointer
at CreatePicture().

There were 2 issues with xorg-server handling of RGB masks that
caused the pointer above to be null and thus the crash:
- wrong use of ffs() to get the RGB offsets from the masks
- overflow when shifting a 16-bit integer

This change fixes both issues. They happen when the system is BE
but has a video adapter using a little-endian (LE) ARGB32
framebuffer. In order to display the correct colors, this setup
requires a BE RGBA32 color format to be used by X, by setting
the RGB masks appropriately, that didn't work properly because of
the issues above.
2021-04-16 14:40:49 +00:00
Łukasz Spintzyk 5be3b80b8d modesetting: Remove few common functions from ms namespace
A lot of that code is the same as in xf86-amdgpu and xf86-nouveau drivers. By removing that functions from
ms namespace we can move that code to common implementation.

Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-04-16 10:53:43 +00:00
Łukasz Spintzyk c282be503e modesetting: remove unnecessary ms_covering_xf86_crtc dup of ms_covering_randr_crtc
Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-04-16 10:53:43 +00:00
Łukasz Spintzyk b923364c5e modesetting: Find crtc on secondary outputs as fallback instead of returning primary crtc
Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-04-16 10:53:43 +00:00
Łukasz Spintzyk d2dce22b67 present: fix msc offset calculation in screen mode
Instead of getting the current msc value from the window crtc,
which not exist take the last saved msc value saved in
the window_priv struct

Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-04-16 10:53:43 +00:00
Łukasz Spintzyk 908deb0895 present: Use crtc's screen present operation for syncing
Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-04-16 10:53:43 +00:00
Łukasz Spintzyk d03c0de77b modesetting: Initialize present extension despite glamor is disabled
Signed-off-by: Łukasz Spintzyk <lukasz.spintzyk@synaptics.com>
2021-04-16 10:53:43 +00:00
Matthieu Herrb 7aaf54a188 Fix XChangeFeedbackControl() request underflow
CVE-2021-3472 / ZDI-CAN-1259

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

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
2021-04-13 14:28:13 +02:00
Peter Hutterer 66ce61983d xkb: silence a compiler warning
xkb.c: In function ‘ProcXkbSetMap’:
xkb.c:2747:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
 2747 |     DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD);

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-04-09 17:37:29 +00:00
Peter Hutterer f6b8f8c071 xkb: don't require a trailing slash for the XKM output dir
Rework the function to use a single snprintf call instead of a mix of
strcpy/strcats. This now also appends a trailing slash where needed so we
don't rely on the build system to set this for us.

Also, since /tmp/ is the fallback and we never check if everything succeeded,
assert if we can't use /tmp/. This will never be triggered anyway, the only
caller to OutputDirectory() uses sizeof(PATH_MAX-sized array).

Follow-up from 6c51818a0f

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-04-09 17:37:29 +00:00
Jan Beich eceafd4a2d meson: switch getpeer* checks to autotools style
Checking for function "getpeereid" : YES
Checking for function "getpeerucred" : NO
[...]
include/meson.build:182:7: ERROR: Argument to "not" is not a boolean.

Fixes: 68c2cfadd6 ("meson: Make sure defines are either set to 1 or not defined")
2021-04-09 16:44:27 +00:00
Jan Beich 9f8421af63 meson: check pthread_setname_np like autotools
FreeBSD < 12.2 and OpenBSD only have pthread_set_name_np.
As libpthread isn't in scope use -Werror to trip the check.

Header <pthread.h> has symbol "PTHREAD_MUTEX_RECURSIVE" : YES
Checking if "pthread_setname_np(tid, name)" compiles: YES

os/inputthread.c:326:5: error: implicit declaration of function 'pthread_setname_np' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    pthread_setname_np (pthread_self(), "InputThread");
    ^
os/inputthread.c:447:5: error: implicit declaration of function 'pthread_setname_np' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    pthread_setname_np (pthread_self(), "MainThread");
    ^

Fixes: c20e7b5e22 ("meson: Automatically detect HAVE_PTHREAD_SETNAME_NP")
2021-04-09 15:43:37 +00:00
Erik Kurzinger 38e875904b xwayland: implement pixmap_from_buffers for the eglstream backend
Provides an implementation for the pixmap_from_buffers DRI3 function for
xwayland's eglstream backend. This will be used by the NVIDIA GLX driver
to pass buffers from client applications to the server. These can then
be presented using the PRESENT extension.

To hopefully make this less error-prone, we also introduce a "type"
field for this struct to distinguish between xwl_pixmaps for the new
DRI3-created pixmaps and those for the existing glamor-created pixmaps.

Additionally, the patch enables wnmd present mode with the eglstream backend.
This involves creating a wl_buffer for the provided dma-buf before importing it
into EGL and passing this to the compositor so it can be scanned out directly
if possible.

Since both backends now support this present mode, the HAS_PRESENT_FLIP flag is
no longer needed, so it can be removed.

Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
2021-04-09 14:00:01 +00:00
Erik Kurzinger bc99dd2127 xwayland: Add check_flip() glamor backend function
This is preliminary work for hardware accelerated rendering with the
NVIDIA driver.

This exposes a new glamor backend function, check_flip, which can be
used to control whether flipping is supported for the given pixmap.

Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
2021-04-09 14:00:01 +00:00
Erik Kurzinger 400d4d0fdd xwayland: move formats and modifiers functions to common glamor code
This is preliminary work for hardware accelerated rendering with the
NVIDIA driver.

This moves the modifiers and formats functions previously only available
to the GBM backend to the common glamor code so that it can be used by
both the GBM and EGLStream backends.

Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com>
2021-04-09 14:00:01 +00:00
Olivier Fourdan ae225417c0 xwayland: Move dmabuf interface to common glamor code
This is preliminary work for hardware accelerated rendering with the
NVIDIA driver.

The EGLStream backend can possibly also use the dmabuf interface, so
move the relevant code from the GBM specific source to the common bits.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2021-04-09 14:00:01 +00:00
Povilas Kanapickas d231ce2d9c meson: Disable LTO for tests
`-flto=auto` together with `-Wl,-wrap` causes link errors at least in
certain compilers (e.g. GCC 10.2.0). Since this is reoccurring issue
(internet search shows similar problems with GCC 4.6 a decade ago) let's
disable LTO for tests even if it's disabled elsewhere.

Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1116
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-04-09 11:18:54 +00:00
Povilas Kanapickas 68c2cfadd6 meson: Make sure defines are either set to 1 or not defined
This will make the behavior of meson consistent with autotools. The
configuration macros are exposed to public headers so any inconsistency
is likely to break code for anyone who's not careful to use #ifdef
instead of #if.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-04-09 11:18:54 +00:00
Povilas Kanapickas faff5bbdf5 meson: Sync the name of INPUTTHREAD conf macro with autotools build
The rest of dix code uses INPUTTHREAD, so having a different name in
meson configuration was an oversight.

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

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-04-09 11:18:54 +00:00
Povilas Kanapickas b25795462f meson: Add missing pthread dependency for libxserver_os library
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-04-09 11:18:54 +00:00
Povilas Kanapickas 9582ef4efc meson: Fix typo in libxserver_os dependencies for openbsd
This has not been tested, but os_deps is not used anywhere in the file,
so it's likely this was a typo.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-04-09 11:18:54 +00:00
Povilas Kanapickas 689496ed65 meson: Switch project version to 20.x.y style 2021-04-08 14:06:02 +00:00
Povilas Kanapickas 2df55813d0 meson: Drop version subpatch handling 2021-04-08 14:06:02 +00:00
Adam Jackson 5d3679104a meson.build: Keep the protocol version looking like xserver 1.20.x did
This effectively changes the versioning to be as if xserver 21.0 was
xserver 1.21.0. This should keep any client-side version checks that
know about the Xorg 7.0 -> xserver 1.0 epoch from getting confused.
2021-04-08 14:06:02 +00:00
George Matsumura 3e4e70db10 meson: Fix DragonFly BSD identifier in meson build files
This changes the operating system identifier tested against
host_machine.system() in meson build files from "dragonflybsd"
to the officially stable "dragonfly".

Signed-off-by: George Matsumura <gmmatsumura01@bvsd.org>
2021-04-08 02:23:21 +00:00
Edouard Gaulué 199f278a1b French text in Preferences Pane Review 2021-04-07 16:19:24 -07:00
Jeremy Huddleston Sequoia 65b27d82f2 xquartz: Call PseudoramiXExtensionInit() through InitOutput() just like xwin
Fixes: https://github.com/XQuartz/XQuartz/issues/140
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-04-07 16:11:59 -07:00
Pascal VITOUX 34e2a64ce0 xfree86: fix gtf support detection for EDID 1.4
According to the "VESA Enhanced EDID Standard", all GTF compliant
displays are continuous frequency.

The GTF support flags in 'Display Range Limits Descriptor' cannot be
used if the display is a non-continuous frequency multi-mode display.

Closes #1105
Signed-off-by: Pascal VITOUX <vitoux.pascal@gmail.com>
Fixes: 6a79a737 ("xfree86: add drm modes on non-GTF panels")
Reviewed-by: Aaron Ma aaron.ma@canonical.com
2021-04-06 11:25:42 +00:00
Aaron Plattner b75d0cca28 modesetting: Defer crtc gamma size upgrade to drmmode_setup_colormap
Rather than trying to create a gamma ramp array of the appropriate size in
drmmode_crtc_init when the GAMMA_LUT property should be used, just flag the crtc
as wanting to use the GAMMA_LUT property and then replace the gamma ramp later,
right before calling xf86HandleColormaps. This avoids a problem during initial
startup where xf86RandR12CreateObjects12 hard-codes a gamma ramp size of 256,
causing xf86RandR12CrtcSetGamma to read past the end of the DIX layer's RandR
gamma ramp array:

  PreInit
    drmmode_pre_init
      drmmode_crtc_init
        crtc->gamma_size = 1024

  ScreenInit
    xf86CrtcScreenInit
      xf86RandR12Init
        xf86RandR12Init12
          xf86RandR12CreateObjects12
            RRCrtcCreate
              randr_crtc->gammaSize = 0
          xf86RandR12InitGamma(pScrn, 256)
            RRCrtcGammaSetSize
              randr_crtc->gammaSize = 256
          xf86RandR12InitGamma
            xf86RandR12CrtcInitGamma
              RRCrtcGammaSet
                xf86RandR12CrtcSetGamma
                  // crtc->gamma_size is 1024 here, while randr_crtc->gammaRed
                  // is a 256-element array.
                  memcpy(crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof(crtc->gamma_red[0]));
    drmmode_setup_colormap
      xf86HandleColormaps
        xf86RandR12InitGamma
          RRCrtcGammaSetSize
            randr_crtc->gammaSize = 1024

Fixes: 245b9db0 - modesetting: Use GAMMA_LUT when available
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1126
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Reviewed-by: Robert Morell <rmorell@nvidia.com>
2021-04-05 14:25:33 -07:00
Jeremie Courreges-Anglas ab8f8c9841 xserver/os: safer IPv6 "kame hack" fix, only override sin6_scope_id if zero
This helps on KAME-based systems which want to get rid of this hack.
The assumption is that if sin6_scope_id is set, then the interface index
is no longer embedded in the address.

Signed-off-by: Jeremie Courreges-Anglas <jca@wxcvbn.org>
2021-04-04 21:06:35 +00:00
Povilas Kanapickas aeed57d722 xkb: Fix parsing of XkbSA_DeviceValuator action type
The xkb spec defines that the 7th element of the DeviceValuator key
action description is "valuator 2 value".

This error most likely was accidentally introduced as a copy-paste error
in edeb033f29.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-03-30 18:47:04 +00:00
Povilas Kanapickas a3931ec6f4 xfree86: Create a symlink X -> Xorg when installing using meson
This brings the behavior closer than what we currently have with
autotools-based build system.

Meson does not currently have native support for symlinks.
See https://github.com/mesonbuild/meson/issues/1602.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-03-26 09:29:25 +00:00
Povilas Kanapickas 09cd65233e xfree86: Set appropriate install_mode for suid_wrapper 2021-03-26 09:18:55 +00:00
Povilas Kanapickas 88b5e1a219 meson: Bump min meson version to 0.47 to get install_mode support 2021-03-26 09:18:55 +00:00
Povilas Kanapickas 82d2156ba7 xfree86: Fix meson overwriting suid wrapper with the wrapped executable
Meson gets confused when there are two targets of the same name within
the same directory, so we use a different intermediate name.

This is a problem with the Xorg SUID wrapper which has the same filename
as the real Xorg executable and is configured in the same meson.build
file. This commit works around this by using a different filename in
build stage and renaming only when installing.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-03-26 09:08:02 +00:00
Povilas Kanapickas ba51acb1de miext: Remove if check which is always true
In both cases we check for width > 0 just above, and the variable is not
modified between the checks, so the condition is always true.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-03-26 09:02:14 +00:00
Povilas Kanapickas 99e7ccffb3 dix: Fix URL to description of focus in/out model
The current URL points to an unrelated patch for acpid.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-03-25 23:18:14 +02:00
Simon Ser 1b7dca27eb xwayland: remove wl_log_set_handler_client workaround
This bumps the minimum Wayland version to 1.5 (released in 2014).

Signed-off-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Martin Peres <martin.peres@mupuf.org>
2021-03-24 08:13:11 +01:00
Michel Dänzer 6c51818a0f meson: Make sure XKM_OUTPUT_DIR has a trailing slash
RunXkbComp passes an invalid file path to xkbcomp if there's no
trailing slash.

Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1146
Suggested-by: Dylan Baker <dylan.c.baker@intel.com>
2021-03-15 16:53:46 +01:00
Jan Beich 376eaadde3 meson: hide C API if Xorg is disabled (like autotools)
When building only Xwayland using Meson some files are always installed.
This causes package conflict if Xwayland is built separately from Xorg.

  include/xorg/compositeext.h
  include/xorg/damage.h
  include/xorg/damagestr.h
  include/xorg/dbestruct.h
  include/xorg/dri3.h
  include/xorg/fb.h
  include/xorg/fboverlay.h
  include/xorg/fbpict.h
  include/xorg/fbrop.h
  include/xorg/geext.h
  include/xorg/geint.h
  include/xorg/glyphstr.h
  include/xorg/mi.h
  include/xorg/micmap.h
  include/xorg/micoord.h
  include/xorg/migc.h
  include/xorg/miline.h
  include/xorg/mioverlay.h
  include/xorg/mipict.h
  include/xorg/mipointer.h
  include/xorg/mipointrst.h
  include/xorg/mistruct.h
  include/xorg/misync.h
  include/xorg/misyncfd.h
  include/xorg/misyncshm.h
  include/xorg/misyncstr.h
  include/xorg/mizerarc.h
  include/xorg/panoramiX.h
  include/xorg/panoramiXsrv.h
  include/xorg/picture.h
  include/xorg/picturestr.h
  include/xorg/present.h
  include/xorg/presentext.h
  include/xorg/randrstr.h
  include/xorg/rrtransform.h
  include/xorg/shadow.h
  include/xorg/shmint.h
  include/xorg/syncsdk.h
  include/xorg/vndserver.h
  include/xorg/wfbrename.h
  include/xorg/xace.h
  include/xorg/xacestr.h
  include/xorg/xorg-server.h
  include/xorg/xvdix.h
  include/xorg/xvmcext.h
  share/aclocal/xorg-server.m4

Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
2021-03-11 00:22:36 +00:00
Jeremy Huddleston Sequoia 4ae36f418e xquartz: Ensure the mouse pointer is shown when switching to a native macOS alert or window
Fixes: https://github.com/XQuartz/XQuartz/issues/100
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-03-08 21:03:57 -08:00
Matthieu Herrb b2d96b5cd4 Avoid sequences of malloc(0) / free() by checking the length.
This has an impact on heap fragmentation.

Signed-off-by: Matthieu Herrb <matthieu.herrb@laas.fr>
2021-03-08 20:32:54 +00:00
Jeremy Huddleston Sequoia 15a413e11d xquartz: Update meson build to remove deleted files
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-03-05 23:17:21 -08:00
Jeremy Huddleston Sequoia e59848548a xquartz: Fix appFlags build failure with macOS 10.15+ SDKs
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-03-05 23:17:21 -08:00
Olivier Fourdan 69e087caa4 xwayland: Fix path in pkg-config with autoconf
When using autoconf/automake to build Xwayland, the actual path to
Xwayland is not fully qualified and refers to the "exec_prefix".

As a result, the path provided by the generated pkg-config file is wrong
when using autoconf to build the Xserver.

Fix the xwayland.pc file to also set the variable "prefix" and
"exec_prefix" so that the path to Xwayland is fully resolved.

Add those variables to the meson build as well for good measure.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
2021-03-05 11:11:54 +01:00
Olivier Fourdan d7391f383d xwayland: Fix LeaveNotify for relative pointer
Since commit 20c78f38, we use the relative pointer for enter/leave
events.

However, sprite_check_lost_focus() which verifies whether the pointer has
left an Xwayland surface still explicitly check for the absolute
pointer.

As a result, no LeaveNotify event is emitted anymore now when the
pointer crosses from an Xwayland surface to a Wayland native one.

Make sure to check the last slave device against get_pointer_event() as
well, not just the absolute pointer.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Martin Peres <martin.peres@mupuf.org>
Acked-by: Roman Gilg <subdiff@gmail.com>
Tested-by: Roman Gilg <subdiff@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Fixes: 20c78f38 - xwayland: use get_pointer_device() for enter/leave
                  handling too
2021-03-05 07:48:57 +01:00
Jacob Cherry a5367face1 xfree86: Fix autoconfig secondary GPU devices
The code path added by commit 69e4b8e6 (xfree86: attempt to autoconfig
gpu slave devices (v3)) assumes that it will only be run if the primary
device on the screen is the first device in xf86configptr->conf_device_lst.
While this is true most of the time, there are two specific cases where
this assumption fails.

First, if the first device in conf_device_lst is assigned to a different
seat than the running X server, it will be skipped by the previous
FIND_SUITABLE macro usage. Second, if the primary device was explicitly
assigned to the screen but auto_gpu_device is still set and no secondary
devices were explicitly listed, that device may not be the first device
in conf_device_lst.

When the first device in conf_device_lst is not the primary device
assigned to the screen, two problems emerge. First, the first device in
conf_device_lst will never be assigned to the screen as a secondary
device. Second, the primary device is additionally assigned to the
screen as a secondary device. The combination of these problems causes
certain otherwise valid configurations to be invalid. For example, if a
primary device is assigned to a screen and a secondary device is listed
in the config but not explicitly assigned to the screen, then one order
of the device sections results in a usable PRIME or Reverse PRIME setup
and the other order does not.

This commit removes the assumption that the primary device is the first
device in conf_device_lst by starting the loop from the start of
conf_device_lst and skipping the primary device when it is encountered.

Signed-off-by: Jacob Cherry <jcherry@nvidia.com>
2021-03-03 17:50:31 +00:00
Olivier Fourdan 97ed0048e4 xwayland: Delay cursor visibility update
Xwayland won't emulate XWarpPointer requests if the cursor is visible,
this is to avoid having the cursor jumping on screen and preventing
random X11 clients from controlling the pointer in Wayland, while
allowing games which use that mechanism with a hidden cursor to work in
Xwayland.

There are, however, games which tend to do it in the wrong order, i.e.
show the cursor before moving the pointer, and because Xwayland will not
allow an X11 client to move the pointer while the cursor is visible, the
requests will fail.

Add a workaround for such X11 clients, when the cursor is being shown,
keep it invisible until the cursor is actually moved. This way, X11
clients which show their cursor just before moving it would still have a
chance to succeed.

v2: Add a timeout to show the cursor for well behaved clients.
v3: Some cleanup (Michel)
v4: Do not cancel cursor delay when updating the cursor to avoid
    delaying cursor visibility indefinitely if the client keeps
    settings different cursors (Michel)

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Tested-by: Jaap Buurman jaapbuurman@gmail.com
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/734
2021-03-03 15:28:27 +01:00
Jeremy Huddleston Sequoia 9d329a0fb1 xquartz: Remove a check for NSAppKitVersionNumber >= NSAppKitVersionNumber10_7
This check is always true on our supported systems.

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-22 09:20:25 -08:00
Jeremy Huddleston Sequoia 839b49ac05 xquartz: Don't include strndup.c any more since we no longer support 10.8 and older
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-22 09:20:25 -08:00
Jeremy Huddleston Sequoia 677eb6827b xquartz: Add a launch trampoline to better integrate with modern versions of macOS
Fixes: https://github.com/XQuartz/XQuartz/issues/6
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-22 09:20:25 -08:00
Jeremy Huddleston Sequoia 25035229b7 xquartz: Don't process AppKit events if we haven't finished initializing
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-20 21:04:25 -08:00
Jeremy Huddleston Sequoia 487286d472 xquartz: Allocate each fbconfig separately
A change during the 1.20 development cycle resulted in fbconfigs being walked
and deallocated individually during __glXScreenDestroy.  This change
now avoids a use-after-free caused by that change.

==50859==ERROR: AddressSanitizer: heap-use-after-free on address 0x00010d3819c8 at pc 0x0001009d4230 bp 0x00016feca7a0 sp 0x00016feca798
READ of size 8 at 0x00010d3819c8 thread T5
    #0 0x1009d422c in __glXScreenDestroy glxscreens.c:448
    #1 0x10091cc98 in __glXAquaScreenDestroy indirect.c:510
    #2 0x1009d2734 in glxCloseScreen glxscreens.c:169
    #3 0x100740a24 in dix_main main.c:325
    #4 0x10023ed50 in server_thread quartzStartup.c:65
    #5 0x199ae7fd0 in _pthread_start+0x13c (libsystem_pthread.dylib:arm64e+0x6fd0)
    #6 0x199ae2d38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1d38)

0x00010d3819c8 is located 200 bytes inside of 12800-byte region [0x00010d381900,0x00010d384b00)
freed by thread T5 here:
    #0 0x101477ba8 in wrap_free+0x98 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3fba8)
    #1 0x1009d4240 in __glXScreenDestroy glxscreens.c:449
    #2 0x10091cc98 in __glXAquaScreenDestroy indirect.c:510
    #3 0x1009d2734 in glxCloseScreen glxscreens.c:169
    #4 0x100740a24 in dix_main main.c:325
    #5 0x10023ed50 in server_thread quartzStartup.c:65
    #6 0x199ae7fd0 in _pthread_start+0x13c (libsystem_pthread.dylib:arm64e+0x6fd0)
    #7 0x199ae2d38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1d38)

previously allocated by thread T5 here:
    #0 0x101477e38 in wrap_calloc+0x9c (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3fe38)
    #1 0x100925a40 in __glXAquaCreateVisualConfigs visualConfigs.c:116
    #2 0x10091cb24 in __glXAquaScreenProbe+0x224 (X11.bin:arm64+0x100730b24)
    #3 0x1009cd840 in xorgGlxServerInit glxext.c:528
    #4 0x10074539c in _CallCallbacks dixutils.c:743
    #5 0x100932a70 in CallCallbacks callback.h:83
    #6 0x100932478 in GlxExtensionInit vndext.c:244
    #7 0x10020a364 in InitExtensions miinitext.c:267
    #8 0x10073fe7c in dix_main main.c:197
    #9 0x10023ed50 in server_thread quartzStartup.c:65
    #10 0x199ae7fd0 in _pthread_start+0x13c (libsystem_pthread.dylib:arm64e+0x6fd0)
    #11 0x199ae2d38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1d38)

Regressed-in: 4b0a3cbab1
CC: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-20 17:29:40 -08:00
Jeremy Huddleston Sequoia 6a83fb51b7 xquartz: Fix a compiler warning about const incompatible pointer assignment
driWrap.c:541:30: error: assigning to 'GCOps *' (aka 'struct _GCOps *') from 'const GCOps *' (aka 'const struct _GCOps *') discards
      qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
        pGCPriv->originalOps = pGC->ops;
                             ^ ~~~~~~~~

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-20 15:18:47 -08:00
Jeremy Huddleston Sequoia a3ddcdd56c xquartz: Fix build with sparkle enabled
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 23:16:32 -08:00
Jeremy Huddleston Sequoia 279bcbd9cf xquartz: Silence a compiler warning about missing internal methods on NSApplication
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:34:14 -08:00
Jeremy Huddleston Sequoia fe89c70e47 xquartz: Rewrite Window menu handling to not depend on X11App.windowsMenu.numberOfItems being correct in -awakeFromNib
Fixes: https://github.com/XQuartz/XQuartz/issues/56
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 41aed8f696 xquartz: Convert X11Controller ivars into @properties
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia c2750e1fab xquartz: Convert X11Application ivars into @properties
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia f51b97b0de xquartz: Fold quartzCommon.h into quartz.h
Everything declared in it comes from quartz.c, so match reality.

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 4b4500c48f xquartz: Fold away some unnecessary hops to X11Controller through X11Application
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 39c0e1c0ab xquartz: Fold away array_with_strings_and_numbers and simplify with more modern Objective-C
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 87f8fe1f74 xqaurtz: Remove message_kit_thread() and use dispatch instead
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 94e4e17348 xquartz: Use objc_autoreleasePoolPush / objc_autoreleasePoolPop directly in QuartzBlockHandler
It violates @autoreleasepool best practices, and this helps collapse quartzCocoa.m into quartz.c

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia fba421f700 xquartz: Minor code modernization -- @autoreleasepool adoption
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 318f8a4a8a xquartz: Remove some dead code for compatibility with older nibs
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 72a39dccf9 xquartz: Remove a workaround for AppKit versions older than Lion
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-18 22:32:14 -08:00
Jeremy Huddleston Sequoia 7e28750358 xquartz: Fix applications menu table background color for dark mode
Fixes: https://github.com/XQuartz/XQuartz/issues/32
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-17 16:24:08 -08:00
Jeremy Huddleston Sequoia 85beee9885 xquartz: Apply Xcode 12.4 automatic updates to nibs
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-17 16:24:06 -08:00
Jeremy Huddleston Sequoia 4e892aa6e1 xquartz: Update the about box copyright to 2021
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-17 13:38:31 -08:00
Jeremy Huddleston Sequoia c9a3b14c14 xquartz: Ensure we call into TIS on the main thread
There is a place where this code was called on the main thread.

We're using a rather nasty anti-pattern to just call a block inline rather
than synchonously calling it on the main thread if we're already on the main
thread.  This code could use a good overhaul, but I don't have time to rip
it apart right now.  This will address the immediate issue.

Fixes: https://github.com/XQuartz/XQuartz/issues/40
Fixes: https://github.com/XQuartz/XQuartz/issues/48
Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
2021-02-17 09:53:33 -08:00
Povilas Kanapickas af17b5c499 dix: Use correct listener to deliver touch end events
This fixes an problem left in f682e0563f
due to an incorrect cherry-pick.

We must use old listener->listener to deliver the touch event. Otherwise
grab won't let the event through and the abovementioned commit has no
effect.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
2021-02-17 04:29:48 +00:00
Peter Hutterer 20c78f38a0 xwayland: use get_pointer_device() for enter/leave handling too
In Weston, clicking the window decoration of an Xwayland client gives us a
wl_pointer.button event immediately followed by a wl_pointer.leave event.
The leave event does not contain any button state information, so the button
remains logically down in the DIX.

Once the pointer button is released, a wl_pointer.enter event is sent with
the current button state (zero). This needs to trigger a ButtonRelease event
but for that we need to ensure that the device is the same as the one we send
ButtonPress events through.

Fixes a regression introduced in a4095162ca.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
2021-02-17 14:18:02 +10:00
Olivier Fourdan dee2bb033e dix: Guard against non-existing PtrFeedbackPtr
Trying to change the pointer control settings on a device without
PtrFeedbackPtr would be a bug and a crash in the Xserver.

Guard against that case by returning early with a BadImplementation
error, that might kill the X11 client but the Xserver would survive.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1137
2021-02-16 09:37:46 +01:00
Olivier Fourdan ab76272a7d xwayland: Add PtrFeedback to the touch device
Trying to change the acceleration/threshold on Xwayland cannot work, and
the corresponding handler xwl_pointer_control() is a no-op.

Yet, an X11 client trying to change those on the touch device may
possibly cause a crash because the touch device in Xwayland doesn't set
that.

Initialize the touch device's PtrFeedback to make sure that just cannot
happen.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1137
2021-02-16 09:37:46 +01:00
Olivier Fourdan a4095162ca xwayland: Use relative device for buttons/axis
We are using the relative pointer for motion events, but buttons and
axis events still go through the absolute pointer device.

That means additional DeviceChanged events that could be avoided if the
buttons and axis events were coming from the same device as motion
events.

Route those events to the relative pointer if available so that motion,
buttons and axis events come from the same device (most of the time).

Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
2021-02-15 09:42:00 +01:00
Olivier Fourdan 1abab61dc2 xwayland: Add wheel axis to relative pointer
The relative pointer only has 2 axis, if we want to route the mouse
wheel events to that device, we need to add the axis definition, similar
to what is done for the absolute pointer.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
2021-02-15 09:42:00 +01:00
Olivier Fourdan 7181792824 xwayland: Split dispatch_pointer_motion_event
This is a cleanup patch, no functional change.

Split the function dispatch_pointer_motion_event() into three separate
simpler functions, relative motion with a warp emulator, relative motion
and absolute motion.

This makes the code a lot easier to read for me, rather than having
everything in a single function with nested if/else conditions.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-02-15 09:42:00 +01:00
Olivier Fourdan c5c5322ad6 xwayland: Use relative values for raw events
Xwayland supports relative motion events from the Wayland compositor via
the relative-pointer protocol, and converts those to the absolute range
in device units for raw events.

Some X11 clients however wrongly assume relative values in the axis
values even for devices explicitly labeled as absolute. While this is a
bug in the client, such applications would work fine in plain Xorg but
not with Xwayland.

To avoid that issue, use the relative values for raw events without
conversion, so that such application continue to work in Xwayland.

Thanks Peter for figuring out the root cause.

v2: Don't duplicate relative and absolute events (Peter)
v3: Use POINTER_RAWONLY (Peter)

Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
2021-02-15 09:42:00 +01:00
Olivier Fourdan ebdb2e2646 xwayland: Use a resolution of 0 for relative motion
That's what evdev/libinput drivers do.

Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
2021-02-15 09:42:00 +01:00
Olivier Fourdan b5e1f13681 dix: Add POINTER_RAWONLY flag
This add a new flag POINTER_RAWONLY for GetPointerEvents() which does
pretty much the opposite of POINTER_NORAW.

Basically, this tells GetPointerEvents() that we only want the
DeviceChanged events and any raw events for this motion but no actual
motion events.

This is preliminary work for Xwayland to be able to use relative motion
events for raw events. Xwayland would use absolute events for raw
events, but some X11 clients (wrongly) assume raw events to be always
relative.

To allow such clients to work with Xwayland, it needs to switch to
relative raw events (if those are available from the Wayland
compositor).

However, Xwayland cannot use relative motion events for actual pointer
location because that would cause a drift over time, the pointer being
actually controlled by the Wayland compositor.

So Xwayland needs to be able to send only relative raw events, hence
this API.

Bump the ABI_XINPUT_VERSION minor version to reflect that API addition.

v2: Actually avoid sending motion events (Peter)
v3: Keep sending raw emulated events with RAWONLY (Peter)

Suggested-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
2021-02-15 09:42:00 +01:00
Povilas Kanapickas 213129012b Xi: Deliver pointer emulated touch events to grabbing client
Delivery of emulated events usually happens only to the owning client.
If there are grabs, only the grabbing client may receive these events.

This logic does not work during the touch event replay in
DeactivatePointerGrab(), as the previous grab is no longer in the
listener queue of the touch, so the next owner gets whole emulated event
sequence. This may trigger implicit grabs. After replay,
DeactivatePointerGrab() will update the global grab without regard to
this new implicit grab, which leads to issues down the line.

This change is effectively the same as 35e5a76cc1 except that the change
is limited to only emulated pointer events. Otherwise, in the case of a
device grab we end up not sending any touch events to clients that
selected XI_TouchOwnership event and should get touch events before they
get ownership of touch sequence.

Fixes #7

https://bugs.freedesktop.org/show_bug.cgi?id=96536
2021-02-15 04:40:16 +00:00
Povilas Kanapickas 30e11535af Revert "Xi: Use current device active grab to deliver touch events if any"
This reverts commit 98e3db2ac4.
2021-02-15 04:40:16 +00:00
Povilas Kanapickas f682e0563f dix: Send touch end to clients that do async grab without touch events
If a XI2 client started listening to touches due to a selection and then
creates an active async grab that does not include touch events, then it
currently won't get the touch end event which will produce inconsistent
view of the pending touches.

Note that we only need to consider touch listeners and can ignore
pointer emulation. Under XI2 if a active grab replaces a passive
implicit grab and the active grab does not include the button release
event, the client won't get it either.
2021-02-08 05:21:29 +02:00
287 changed files with 28479 additions and 113609 deletions

View File

@ -8,10 +8,10 @@
# gcc/clang or other packages, which might break the build with older commits
# using the same tag.
variables:
UPSTREAM_REPO: xorg/xserver
FDO_UPSTREAM_REPO: xorg/xserver
FDO_DISTRIBUTION_VERSION: buster-slim
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/debian-install.sh'
FDO_DISTRIBUTION_TAG: "2021-01-19-git"
FDO_DISTRIBUTION_TAG: "2021-07-09"
include:
- project: 'freedesktop/ci-templates'
@ -83,3 +83,9 @@ meson-noglamor:
variables:
MESON_EXTRA_OPTIONS: >
-Dglamor=false
mingw-cross-build:
extends: .common-build-and-test
script:
- meson --cross-file=.gitlab-ci/cross-i686-w64-mingw32.txt -Dglx=false -Dsecure-rpc=false -Dlisten_tcp=true build/
- ninja -j${FDO_CI_CONCURRENT:-4} -C build/ install

View File

@ -0,0 +1,20 @@
[binaries]
c = 'i686-w64-mingw32-gcc'
cpp = 'i686-w64-mingw32-g++'
ar = 'i686-w64-mingw32-ar'
strip = 'i686-w64-mingw32-strip'
pkgconfig = '/usr/local/bin/i686-w64-mingw32-pkg-config'
windres = 'i686-w64-mingw32-windres'
exe_wrapper = 'wine'
[properties]
# Directory that contains 'bin', 'lib', etc for the toolchain
root = '/usr/i686-w64-mingw32'
# Directory that contains 'bin', 'lib', etc which have been cross-compiled
sys_root = '/usr/i686-w64-mingw32'
[host_machine]
system = 'windows'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'

View File

@ -0,0 +1,79 @@
#!/bin/bash
set -e
set -o xtrace
HOST=$1
# Debian's cross-pkg-config wrappers are broken for MinGW targets, since
# dpkg-architecture doesn't know about MinGW target triplets.
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930492
cat >/usr/local/bin/${HOST}-pkg-config <<EOF
#!/bin/sh
PKG_CONFIG_SYSROOT_DIR=/usr/${HOST} PKG_CONFIG_LIBDIR=/usr/${HOST}/lib/pkgconfig:/usr/share/pkgconfig pkg-config \$@
EOF
chmod +x /usr/local/bin/${HOST}-pkg-config
# when cross-compiling, some autoconf tests cannot be run:
# --enable-malloc0returnsnull
export xorg_cv_malloc0_returns_null=yes
build() {
url=$1
commit=$2
config=$3
name=$(basename ${url} .git)
if [[ $commit =~ ^[[:xdigit:]]{1,}$ ]]
then
git clone ${url} ${name}
git -C ${name} checkout ${commit}
else
git clone --depth 1 --branch ${commit:-master} --recurse-submodules -c advice.detachedHead=false ${url} ${name}
fi
pushd ${name}
NOCONFIGURE=1 ./autogen.sh || ./.bootstrap
./configure ${config} --host=${HOST} --prefix= --with-sysroot=/usr/${HOST}/
make -j$(nproc)
DESTDIR=/usr/${HOST} make install
popd
rm -rf ${OLDPWD}
}
build 'https://gitlab.freedesktop.org/pixman/pixman.git' 'pixman-0.38.4'
build 'https://gitlab.freedesktop.org/xorg/lib/pthread-stubs.git' '0.4'
# we can't use the xorgproto pkgconfig files from /usr/share/pkgconfig, because
# these would add -I/usr/include to CFLAGS, which breaks cross-compilation
build 'https://gitlab.freedesktop.org/xorg/proto/xorgproto.git' 'xorgproto-2021.4.99.2' '--datadir=/lib'
build 'https://gitlab.freedesktop.org/xorg/lib/libXau.git' 'libXau-1.0.9'
build 'https://gitlab.freedesktop.org/xorg/proto/xcbproto.git' 'xcb-proto-1.14'
build 'https://gitlab.freedesktop.org/xorg/lib/libxcb.git' 'libxcb-1.14'
build 'https://gitlab.freedesktop.org/xorg/lib/libxtrans.git' 'xtrans-1.4.0'
# the default value of keysymdefdir is taken from the includedir variable for
# xproto, which isn't adjusted by pkg-config for the sysroot
build 'https://gitlab.freedesktop.org/xorg/lib/libX11.git' 'libX11-1.6.9' "--with-keysymdefdir=/usr/${HOST}/include/X11"
build 'https://gitlab.freedesktop.org/xorg/lib/libxkbfile.git' 'libxkbfile-1.1.0'
# freetype needs an explicit --build to know it's cross-compiling
# disable png as freetype tries to use libpng-config, even when cross-compiling
build 'git://git.savannah.gnu.org/freetype/freetype2.git' 'VER-2-10-1' "--build=$(cc -dumpmachine) --with-png=no"
build 'https://gitlab.freedesktop.org/xorg//font/util.git' 'font-util-1.3.2'
build 'https://gitlab.freedesktop.org/xorg/lib/libfontenc.git' 'libfontenc-1.1.4'
build 'https://gitlab.freedesktop.org/xorg/lib/libXfont.git' 'libXfont2-2.0.3'
build 'https://gitlab.freedesktop.org/xorg/lib/libXdmcp.git' 'libXdmcp-1.1.3'
build 'https://gitlab.freedesktop.org/xorg/lib/libXfixes.git' 'libXfixes-5.0.3'
build 'https://gitlab.freedesktop.org/xorg/lib/libxcb-util.git' '0.4.0'
build 'https://gitlab.freedesktop.org/xorg/lib/libxcb-image.git' '0.4.0'
build 'https://gitlab.freedesktop.org/xorg/lib/libxcb-wm.git' '0.4.1'
# workaround xcb_windefs.h leaking all Windows API types into X server build
# (some of which clash which types defined by Xmd.h) XXX: This is a bit of a
# hack, as it makes this header depend on xorgproto. Maybe an upstreamable
# fix would involve a macro defined in the X server (XFree86Server?
# XCB_NO_WINAPI?), which makes xcb_windefs.h wrap things like XWinsock.h
# does???
sed -i s#winsock2#X11/Xwinsock# /usr/${HOST}/include/xcb/xcb_windefs.h

View File

@ -25,7 +25,9 @@ apt-get install -y \
build-essential \
ca-certificates \
ccache \
dpkg-dev \
flex \
gcc-mingw-w64-i686 \
git \
libaudit-dev \
libbsd-dev \
@ -87,21 +89,40 @@ apt-get install -y \
libxt-dev \
libxtst-dev \
libxv-dev \
libz-mingw-w64-dev \
mesa-common-dev \
meson \
mingw-w64-tools \
nettle-dev \
pkg-config \
python3-mako \
python3-numpy \
python3-six \
x11proto-dev \
xfonts-utils \
xkb-data \
xtrans-dev \
xutils-dev
.gitlab-ci/cross-prereqs-build.sh i686-w64-mingw32
cd /root
# xserver requires libxcvt
git clone https://gitlab.freedesktop.org/xorg/lib//libxcvt.git --depth 1 --branch=libxcvt-0.1.0
cd libxcvt
meson _build
ninja -C _build -j${FDO_CI_CONCURRENT:-4} install
cd ..
rm -rf libxcvt
# xserver requires xorgproto >= 2021.4.99.2 for XI 2.3.99.1
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2021.4.99.2
pushd xorgproto
./autogen.sh
make -j${FDO_CI_CONCURRENT:-4} install
popd
rm -rf xorgproto
# weston 9.0 requires libwayland >= 1.18
git clone https://gitlab.freedesktop.org/wayland/wayland.git --depth 1 --branch=1.18.0
cd wayland

View File

@ -138,9 +138,15 @@ ProcGEDispatch(ClientPtr client)
static int _X_COLD
SProcGEDispatch(ClientPtr client)
{
GEClientInfoPtr pGEClient = GEGetClient(client);
REQUEST(xGEReq);
if (stuff->ReqType >= GENumberRequests)
if (pGEClient->major_version >= ARRAY_SIZE(version_requests))
return BadRequest;
if (stuff->ReqType > version_requests[pGEClient->major_version])
return BadRequest;
return (*SProcGEVector[stuff->ReqType]) (client);
}

View File

@ -74,4 +74,6 @@ libxserver_xext_vidmode = static_library('libxserver_xext_vidmode',
dependencies: common_dep,
)
install_data(hdrs_xext, install_dir: xorgsdkdir)
if build_xorg
install_data(hdrs_xext, install_dir: xorgsdkdir)
endif

View File

@ -37,8 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid)
typedef struct {
security_context_t octx;
security_context_t dctx;
char *octx;
char *dctx;
CARD32 octx_len;
CARD32 dctx_len;
CARD32 id;
@ -48,10 +48,10 @@ typedef struct {
* Extension Dispatch
*/
static security_context_t
static char *
SELinuxCopyContext(char *ptr, unsigned len)
{
security_context_t copy = malloc(len + 1);
char *copy = malloc(len + 1);
if (!copy)
return NULL;
@ -84,7 +84,7 @@ static int
SELinuxSendContextReply(ClientPtr client, security_id_t sid)
{
SELinuxGetContextReply rep;
security_context_t ctx = NULL;
char *ctx = NULL;
int len = 0;
if (sid) {
@ -117,7 +117,7 @@ ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
{
PrivateRec **privPtr = &client->devPrivates;
security_id_t *pSid;
security_context_t ctx = NULL;
char *ctx = NULL;
char *ptr;
int rc;
@ -165,7 +165,7 @@ ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset)
static int
ProcSELinuxSetDeviceContext(ClientPtr client)
{
security_context_t ctx;
char *ctx;
security_id_t sid;
DeviceIntPtr dev;
SELinuxSubjectRec *subj;

View File

@ -114,7 +114,7 @@ SELinuxLabelClient(ClientPtr client)
int fd = XaceGetConnectionNumber(client);
SELinuxSubjectRec *subj;
SELinuxObjectRec *obj;
security_context_t ctx;
char *ctx;
subj = dixLookupPrivate(&client->devPrivates, subjectKey);
obj = dixLookupPrivate(&client->devPrivates, objectKey);
@ -169,7 +169,7 @@ SELinuxLabelInitial(void)
XaceScreenAccessRec srec;
SELinuxSubjectRec *subj;
SELinuxObjectRec *obj;
security_context_t ctx;
char *ctx;
void *unused;
/* Do the serverClient */
@ -773,7 +773,7 @@ SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
subj = dixLookupPrivate(&wClient(pWin)->devPrivates, subjectKey);
if (subj->sid) {
security_context_t ctx;
char *ctx;
int rc = avc_sid_to_context_raw(subj->sid, &ctx);
if (rc < 0)
@ -791,7 +791,7 @@ SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
obj = dixLookupPrivate(&pWin->devPrivates, objectKey);
if (obj->sid) {
security_context_t ctx;
char *ctx;
int rc = avc_sid_to_context_raw(obj->sid, &ctx);
if (rc < 0)
@ -847,7 +847,7 @@ void
SELinuxFlaskInit(void)
{
struct selinux_opt avc_option = { AVC_OPT_SETENFORCE, (char *) 0 };
security_context_t ctx;
char *ctx;
int ret = TRUE;
switch (selinuxEnforcingState) {

View File

@ -97,7 +97,7 @@ static int
SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec * obj, int map, int polymap)
{
const char *name = NameForAtom(atom);
security_context_t ctx;
char *ctx;
int rc = Success;
obj->poly = 1;
@ -255,7 +255,7 @@ SELinuxEventToSID(unsigned type, security_id_t sid_of_window,
{
const char *name = LookupEventName(type);
security_id_t sid;
security_context_t ctx;
char *ctx;
type &= 127;
@ -291,7 +291,7 @@ SELinuxEventToSID(unsigned type, security_id_t sid_of_window,
int
SELinuxExtensionToSID(const char *name, security_id_t * sid_rtn)
{
security_context_t ctx;
char *ctx;
/* Look in the mappings of extension names to contexts */
if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EXT) < 0) {
@ -347,10 +347,10 @@ SELinuxTypeToClass(RESTYPE type)
return (security_class_t) (unsigned long) tmp;
}
security_context_t
char *
SELinuxDefaultClientLabel(void)
{
security_context_t ctx;
char *ctx;
if (selabel_lookup_raw(label_hnd, &ctx, "remote", SELABEL_X_CLIENT) < 0)
FatalError("SELinux: failed to look up remote-client context\n");

View File

@ -99,7 +99,7 @@ int
security_class_t SELinuxTypeToClass(RESTYPE type);
security_context_t SELinuxDefaultClientLabel(void);
char *SELinuxDefaultClientLabel(void);
void
SELinuxLabelInit(void);

View File

@ -464,8 +464,11 @@ ProcXChangeFeedbackControl(ClientPtr client)
break;
case StringFeedbackClass:
{
xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
xStringFeedbackCtl *f;
REQUEST_AT_LEAST_EXTRA_SIZE(xChangeFeedbackControlReq,
sizeof(xStringFeedbackCtl));
f = ((xStringFeedbackCtl *) &stuff[1]);
if (client->swapped) {
if (len < bytes_to_int32(sizeof(xStringFeedbackCtl)))
return BadLength;

View File

@ -95,6 +95,7 @@ SOFTWARE.
#include "exevents.h"
#include "extnsionst.h"
#include "exglobals.h"
#include "eventstr.h"
#include "dixevents.h" /* DeliverFocusedEvent */
#include "dixgrabs.h" /* CreateGrab() */
#include "scrnintstr.h"
@ -168,6 +169,49 @@ IsTouchEvent(InternalEvent *event)
return FALSE;
}
Bool
IsGestureEvent(InternalEvent *event)
{
switch (event->any.type) {
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
return TRUE;
default:
break;
}
return FALSE;
}
Bool
IsGestureBeginEvent(InternalEvent *event)
{
switch (event->any.type) {
case ET_GesturePinchBegin:
case ET_GestureSwipeBegin:
return TRUE;
default:
break;
}
return FALSE;
}
Bool
IsGestureEndEvent(InternalEvent *event)
{
switch (event->any.type) {
case ET_GesturePinchEnd:
case ET_GestureSwipeEnd:
return TRUE;
default:
break;
}
return FALSE;
}
/**
* @return the device matching the deviceid of the device set in the event, or
* NULL if the event is not an XInput event.
@ -647,6 +691,25 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
/* Don't remove touch class if from->touch is non-existent. The to device
* may have an active touch grab, so we need to keep the touch class record
* around. */
if (from->gesture) {
if (!to->gesture) {
classes = to->unused_classes;
to->gesture = classes->gesture;
if (!to->gesture) {
if (!InitGestureClassDeviceStruct(to, from->gesture->max_touches))
FatalError("[Xi] no memory for class shift.\n");
}
else
classes->gesture = NULL;
}
to->gesture->sourceid = from->gesture->sourceid;
/* to->gesture->gesture is separate on the master, don't copy */
}
/* Don't remove gesture class if from->gesture is non-existent. The to device
* may have an active gesture grab, so we need to keep the gesture class record
* around. */
}
/**
@ -1292,21 +1355,13 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
int rc;
InputClients *iclients = NULL;
*mask = NULL;
*grab = NULL;
if (listener->type == TOUCH_LISTENER_GRAB ||
listener->type == TOUCH_LISTENER_POINTER_GRAB) {
*grab = listener->grab;
BUG_RETURN_VAL(!*grab, FALSE);
}
else if (ti->emulate_pointer && dev->deviceGrab.grab &&
!dev->deviceGrab.fromPassiveGrab) {
/* There may be an active pointer grab on the device */
*grab = dev->deviceGrab.grab;
}
if (*grab) {
*client = rClient(*grab);
*win = (*grab)->window;
*mask = (*grab)->xi2mask;
@ -1363,6 +1418,8 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* if owner selected, oclients is NULL */
*client = oclients ? rClient(oclients) : wClient(*win);
}
*grab = NULL;
}
return TRUE;
@ -1379,6 +1436,16 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
int nevents;
DeviceIntPtr kbd;
/* There may be a pointer grab on the device */
if (!grab) {
grab = dev->deviceGrab.grab;
if (grab) {
win = grab->window;
xi2mask = grab->xi2mask;
client = rClient(grab);
}
}
/* We don't deliver pointer events to non-owners */
if (!TouchResourceIsOwner(ti, listener->listener))
return !Success;
@ -1676,6 +1743,72 @@ ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
free(ev);
}
static BOOL
IsAnotherGestureActiveOnMaster(DeviceIntPtr dev, InternalEvent* ev)
{
GestureClassPtr g = dev->gesture;
if (g->gesture.active && g->gesture.sourceid != ev->gesture_event.sourceid) {
return TRUE;
}
return FALSE;
}
/**
* Processes and delivers a Gesture{Pinch,Swipe}{Begin,Update,End}.
*
* Due to having rather different delivery semantics (see the Xi 2.4 protocol
* spec for more information), this implements its own grab and event-selection
* delivery logic.
*/
void
ProcessGestureEvent(InternalEvent *ev, DeviceIntPtr dev)
{
GestureInfoPtr gi;
DeviceIntPtr kbd;
Bool deactivateGestureGrab = FALSE;
Bool delivered = FALSE;
if (!dev->gesture)
return;
if (IsMaster(dev) && IsAnotherGestureActiveOnMaster(dev, ev))
return;
if (IsGestureBeginEvent(ev))
gi = GestureBeginGesture(dev, ev);
else
gi = GestureFindActiveByEventType(dev, ev->any.type);
if (!gi) {
/* This may happen if gesture is no longer active or was never started. */
return;
}
kbd = GetMaster(dev, KEYBOARD_OR_FLOAT);
event_set_state_gesture(kbd, &ev->gesture_event);
if (IsGestureBeginEvent(ev))
GestureSetupListener(dev, gi, ev);
if (IsGestureEndEvent(ev) &&
dev->deviceGrab.grab &&
dev->deviceGrab.fromPassiveGrab &&
GrabIsGestureGrab(dev->deviceGrab.grab))
deactivateGestureGrab = TRUE;
delivered = DeliverGestureEventToOwner(dev, gi, ev);
if (delivered && !deactivateGestureGrab &&
(IsGestureBeginEvent(ev) || IsGestureEndEvent(ev)))
FreezeThisEventIfNeededForSyncGrab(dev, ev);
if (IsGestureEndEvent(ev))
GestureEndGesture(gi);
if (deactivateGestureGrab)
(*dev->deviceGrab.DeactivateGrab) (dev);
}
/**
* Process DeviceEvents and DeviceChangedEvents.
*/
@ -1870,6 +2003,14 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
case ET_BarrierLeave:
ProcessBarrierEvent(ev, device);
break;
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
ProcessGestureEvent(ev, device);
break;
default:
ProcessDeviceEvent(ev, device);
break;
@ -2074,6 +2215,111 @@ DeliverTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti,
}
}
/**
* Attempts to deliver a gesture event to the given client.
*/
static Bool
DeliverOneGestureEvent(ClientPtr client, DeviceIntPtr dev, GestureInfoPtr gi,
GrabPtr grab, WindowPtr win, InternalEvent *ev)
{
int err;
xEvent *xi2;
Mask filter;
Window child = DeepestSpriteWin(&gi->sprite)->drawable.id;
/* If we fail here, we're going to leave a client hanging. */
err = EventToXI2(ev, &xi2);
if (err != Success)
FatalError("[Xi] %s: XI2 conversion failed in %s"
" (%d)\n", dev->name, __func__, err);
FixUpEventFromWindow(&gi->sprite, xi2, win, child, FALSE);
filter = GetEventFilter(dev, xi2);
if (XaceHook(XACE_RECEIVE_ACCESS, client, win, xi2, 1) != Success)
return FALSE;
err = TryClientEvents(client, dev, xi2, 1, filter, filter, NullGrab);
free(xi2);
/* Returning the value from TryClientEvents isn't useful, since all our
* resource-gone cleanups will update the delivery list anyway. */
return TRUE;
}
/**
* Given a gesture event and a potential listener, retrieve info needed for processing the event.
*
* @param dev The device generating the gesture event.
* @param ev The gesture event to process.
* @param listener The gesture event listener that may receive the gesture event.
* @param[out] client The client that should receive the gesture event.
* @param[out] win The window to deliver the event on.
* @param[out] grab The grab to deliver the event through, if any.
* @return TRUE if an event should be delivered to the listener, FALSE
* otherwise.
*/
static Bool
RetrieveGestureDeliveryData(DeviceIntPtr dev, InternalEvent *ev, GestureListener* listener,
ClientPtr *client, WindowPtr *win, GrabPtr *grab)
{
int rc;
int evtype;
InputClients *iclients = NULL;
*grab = NULL;
if (listener->type == GESTURE_LISTENER_GRAB ||
listener->type == GESTURE_LISTENER_NONGESTURE_GRAB) {
*grab = listener->grab;
BUG_RETURN_VAL(!*grab, FALSE);
*client = rClient(*grab);
*win = (*grab)->window;
}
else {
rc = dixLookupResourceByType((void **) win, listener->listener, listener->resource_type,
serverClient, DixSendAccess);
if (rc != Success)
return FALSE;
/* note that we only will have XI2 listeners as
listener->type == GESTURE_LISTENER_REGULAR */
evtype = GetXI2Type(ev->any.type);
nt_list_for_each_entry(iclients, wOtherInputMasks(*win)->inputClients, next)
if (xi2mask_isset(iclients->xi2mask, dev, evtype))
break;
BUG_RETURN_VAL(!iclients, FALSE);
*client = rClient(iclients);
}
return TRUE;
}
/**
* Delivers a gesture to the owner, if possible and needed. Returns whether
* an event was delivered.
*/
Bool
DeliverGestureEventToOwner(DeviceIntPtr dev, GestureInfoPtr gi, InternalEvent *ev)
{
GrabPtr grab = NULL;
ClientPtr client;
WindowPtr win;
if (!gi->has_listener || gi->listener.type == GESTURE_LISTENER_NONGESTURE_GRAB) {
return 0;
}
if (!RetrieveGestureDeliveryData(dev, ev, &gi->listener, &client, &win, &grab))
return 0;
ev->gesture_event.deviceid = dev->id;
return DeliverOneGestureEvent(client, dev, gi, grab, win, ev);
}
int
InitProximityClassDeviceStruct(DeviceIntPtr dev)
{
@ -2379,8 +2625,8 @@ GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
/* Touch grab */
int
GrabTouch(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr mod_dev,
GrabParameters *param, GrabMask *mask)
GrabTouchOrGesture(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr mod_dev,
int type, GrabParameters *param, GrabMask *mask)
{
WindowPtr pWin;
GrabPtr grab;
@ -2398,7 +2644,7 @@ GrabTouch(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr mod_dev,
return rc;
grab = CreateGrab(client->index, dev, mod_dev, pWin, XI2,
mask, param, XI_TouchBegin, 0, NullWindow, NullCursor);
mask, param, type, 0, NullWindow, NullCursor);
if (!grab)
return BadAlloc;

View File

@ -850,6 +850,74 @@ SBarrierEvent(xXIBarrierEvent * from,
swapl(&to->eventid);
}
static void
SGesturePinchEvent(xXIGesturePinchEvent* from,
xXIGesturePinchEvent* to)
{
*to = *from;
swaps(&to->sequenceNumber);
swapl(&to->length);
swaps(&to->evtype);
swaps(&to->deviceid);
swapl(&to->time);
swapl(&to->detail);
swapl(&to->root);
swapl(&to->event);
swapl(&to->child);
swapl(&to->root_x);
swapl(&to->root_y);
swapl(&to->event_x);
swapl(&to->event_y);
swapl(&to->delta_x);
swapl(&to->delta_y);
swapl(&to->delta_unaccel_x);
swapl(&to->delta_unaccel_y);
swapl(&to->scale);
swapl(&to->delta_angle);
swaps(&to->sourceid);
swapl(&to->mods.base_mods);
swapl(&to->mods.latched_mods);
swapl(&to->mods.locked_mods);
swapl(&to->mods.effective_mods);
swapl(&to->flags);
}
static void
SGestureSwipeEvent(xXIGestureSwipeEvent* from,
xXIGestureSwipeEvent* to)
{
*to = *from;
swaps(&to->sequenceNumber);
swapl(&to->length);
swaps(&to->evtype);
swaps(&to->deviceid);
swapl(&to->time);
swapl(&to->detail);
swapl(&to->root);
swapl(&to->event);
swapl(&to->child);
swapl(&to->root_x);
swapl(&to->root_y);
swapl(&to->event_x);
swapl(&to->event_y);
swapl(&to->delta_x);
swapl(&to->delta_y);
swapl(&to->delta_unaccel_x);
swapl(&to->delta_unaccel_y);
swaps(&to->sourceid);
swapl(&to->mods.base_mods);
swapl(&to->mods.latched_mods);
swapl(&to->mods.locked_mods);
swapl(&to->mods.effective_mods);
swapl(&to->flags);
}
/** Event swapping function for XI2 events. */
void _X_COLD
XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
@ -901,6 +969,18 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
SBarrierEvent((xXIBarrierEvent *) from,
(xXIBarrierEvent *) to);
break;
case XI_GesturePinchBegin:
case XI_GesturePinchUpdate:
case XI_GesturePinchEnd:
SGesturePinchEvent((xXIGesturePinchEvent*) from,
(xXIGesturePinchEvent*) to);
break;
case XI_GestureSwipeBegin:
case XI_GestureSwipeUpdate:
case XI_GestureSwipeEnd:
SGestureSwipeEvent((xXIGestureSwipeEvent*) from,
(xXIGestureSwipeEvent*) to);
break;
default:
ErrorF("[Xi] Unknown event type to swap. This is a bug.\n");
break;

View File

@ -39,6 +39,6 @@
int SProcXIChangeHierarchy(ClientPtr /* client */ );
int ProcXIChangeHierarchy(ClientPtr /* client */ );
void XISendDeviceHierarchyEvent(int flags[]);
void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]);
#endif /* CHDEVHIER_H */

View File

@ -114,14 +114,18 @@ ProcXIPassiveGrabDevice(ClientPtr client)
stuff->grab_type != XIGrabtypeKeycode &&
stuff->grab_type != XIGrabtypeEnter &&
stuff->grab_type != XIGrabtypeFocusIn &&
stuff->grab_type != XIGrabtypeTouchBegin) {
stuff->grab_type != XIGrabtypeTouchBegin &&
stuff->grab_type != XIGrabtypeGesturePinchBegin &&
stuff->grab_type != XIGrabtypeGestureSwipeBegin) {
client->errorValue = stuff->grab_type;
return BadValue;
}
if ((stuff->grab_type == XIGrabtypeEnter ||
stuff->grab_type == XIGrabtypeFocusIn ||
stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
stuff->grab_type == XIGrabtypeTouchBegin ||
stuff->grab_type == XIGrabtypeGesturePinchBegin ||
stuff->grab_type == XIGrabtypeGestureSwipeBegin) && stuff->detail != 0) {
client->errorValue = stuff->detail;
return BadValue;
}
@ -217,7 +221,16 @@ ProcXIPassiveGrabDevice(ClientPtr client)
status = GrabWindow(client, dev, stuff->grab_type, &param, &mask);
break;
case XIGrabtypeTouchBegin:
status = GrabTouch(client, dev, mod_dev, &param, &mask);
status = GrabTouchOrGesture(client, dev, mod_dev, XI_TouchBegin,
&param, &mask);
break;
case XIGrabtypeGesturePinchBegin:
status = GrabTouchOrGesture(client, dev, mod_dev,
XI_GesturePinchBegin, &param, &mask);
break;
case XIGrabtypeGestureSwipeBegin:
status = GrabTouchOrGesture(client, dev, mod_dev,
XI_GestureSwipeBegin, &param, &mask);
break;
}
@ -307,7 +320,9 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
stuff->grab_type != XIGrabtypeKeycode &&
stuff->grab_type != XIGrabtypeEnter &&
stuff->grab_type != XIGrabtypeFocusIn &&
stuff->grab_type != XIGrabtypeTouchBegin) {
stuff->grab_type != XIGrabtypeTouchBegin &&
stuff->grab_type != XIGrabtypeGesturePinchBegin &&
stuff->grab_type != XIGrabtypeGestureSwipeBegin) {
client->errorValue = stuff->grab_type;
return BadValue;
}
@ -348,6 +363,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
case XIGrabtypeTouchBegin:
tempGrab->type = XI_TouchBegin;
break;
case XIGrabtypeGesturePinchBegin:
tempGrab->type = XI_GesturePinchBegin;
break;
case XIGrabtypeGestureSwipeBegin:
tempGrab->type = XI_GestureSwipeBegin;
break;
}
tempGrab->grabtype = XI2;
tempGrab->modifierDevice = mod_dev;

View File

@ -43,6 +43,9 @@
#include "xace.h"
#include "inpututils.h"
#include "exglobals.h"
#include "privates.h"
#include "xiquerydevice.h"
static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d);
@ -234,6 +237,9 @@ SizeDeviceClasses(DeviceIntPtr dev)
if (dev->touch)
len += sizeof(xXITouchInfo);
if (dev->gesture)
len += sizeof(xXIGestureInfo);
return len;
}
@ -464,6 +470,46 @@ SwapTouchInfo(DeviceIntPtr dev, xXITouchInfo * touch)
swaps(&touch->sourceid);
}
static Bool ShouldListGestureInfo(ClientPtr client)
{
/* libxcb 14.1 and older are not forwards-compatible with new device classes as it does not
* properly ignore unknown device classes. Since breaking libxcb would break quite a lot of
* applications, we instead report Gesture device class only if the client advertised support
* for XI 2.4. Clients may still not work in cases when a client advertises XI 2.4 support
* and then a completely separate module within the client uses broken libxcb to call
* XIQueryDevice.
*/
XIClientPtr pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
if (pXIClient->major_version) {
return version_compare(pXIClient->major_version, pXIClient->minor_version, 2, 4) >= 0;
}
return FALSE;
}
/**
* List gesture information
*
* @return The number of bytes written into info.
*/
static int
ListGestureInfo(DeviceIntPtr dev, xXIGestureInfo * gesture)
{
gesture->type = XIGestureClass;
gesture->length = sizeof(xXIGestureInfo) >> 2;
gesture->sourceid = dev->gesture->sourceid;
gesture->num_touches = dev->gesture->max_touches;
return gesture->length << 2;
}
static void
SwapGestureInfo(DeviceIntPtr dev, xXIGestureInfo * gesture)
{
swaps(&gesture->type);
swaps(&gesture->length);
swaps(&gesture->sourceid);
}
int
GetDeviceUse(DeviceIntPtr dev, uint16_t * attachment)
{
@ -567,6 +613,13 @@ ListDeviceClasses(ClientPtr client, DeviceIntPtr dev,
total_len += len;
}
if (dev->gesture && ShouldListGestureInfo(client)) {
(*nclasses)++;
len = ListGestureInfo(dev, (xXIGestureInfo *) any);
any += len;
total_len += len;
}
return total_len;
}
@ -598,7 +651,9 @@ SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo * info)
case XITouchClass:
SwapTouchInfo(dev, (xXITouchInfo *) any);
break;
case XIGestureClass:
SwapGestureInfo(dev, (xXIGestureInfo *) any);
break;
}
any += len * 4;

View File

@ -226,8 +226,41 @@ ProcXISelectEvents(ClientPtr client)
return BadValue;
}
/* Only one client per window may select for touch events on the
* same devices, including master devices.
/* All three pinch gesture events must be selected at once */
if ((BitIsOn(bits, XI_GesturePinchBegin) ||
BitIsOn(bits, XI_GesturePinchUpdate) ||
BitIsOn(bits, XI_GesturePinchEnd)) &&
(!BitIsOn(bits, XI_GesturePinchBegin) ||
!BitIsOn(bits, XI_GesturePinchUpdate) ||
!BitIsOn(bits, XI_GesturePinchEnd))) {
client->errorValue = XI_GesturePinchBegin;
return BadValue;
}
/* All three swipe gesture events must be selected at once. Note
that the XI_GestureSwipeEnd is at index 32 which is on the next
4-byte mask element */
if (evmask->mask_len == 1 &&
(BitIsOn(bits, XI_GestureSwipeBegin) ||
BitIsOn(bits, XI_GestureSwipeUpdate)))
{
client->errorValue = XI_GestureSwipeBegin;
return BadValue;
}
if (evmask->mask_len >= 2 &&
(BitIsOn(bits, XI_GestureSwipeBegin) ||
BitIsOn(bits, XI_GestureSwipeUpdate) ||
BitIsOn(bits, XI_GestureSwipeEnd)) &&
(!BitIsOn(bits, XI_GestureSwipeBegin) ||
!BitIsOn(bits, XI_GestureSwipeUpdate) ||
!BitIsOn(bits, XI_GestureSwipeEnd))) {
client->errorValue = XI_GestureSwipeBegin;
return BadValue;
}
/* Only one client per window may select for touch or gesture events
* on the same devices, including master devices.
* XXX: This breaks if a device goes from floating to attached. */
if (BitIsOn(bits, XI_TouchBegin)) {
rc = check_for_touch_selection_conflicts(client,
@ -237,6 +270,22 @@ ProcXISelectEvents(ClientPtr client)
if (rc != Success)
return rc;
}
if (BitIsOn(bits, XI_GesturePinchBegin)) {
rc = check_for_touch_selection_conflicts(client,
win,
evmask->deviceid,
XI_GesturePinchBegin);
if (rc != Success)
return rc;
}
if (BitIsOn(bits, XI_GestureSwipeBegin)) {
rc = check_for_touch_selection_conflicts(client,
win,
evmask->deviceid,
XI_GestureSwipeBegin);
if (rc != Success)
return rc;
}
}
if (XICheckInvalidMaskBits(client, (unsigned char *) &evmask[1],

View File

@ -16,4 +16,6 @@ libxserver_composite = static_library('libxserver_composite',
dependencies: common_dep,
)
install_data(hdrs_composite, install_dir: xorgsdkdir)
if build_xorg
install_data(hdrs_composite, install_dir: xorgsdkdir)
endif

View File

@ -502,6 +502,34 @@ static char *strrstr(const char *haystack, const char *needle)
return last;
}
/* For certain devices udev does not create ID_PATH entry (which is presumably a bug
* in udev). We work around that by implementing a minimal ID_PATH calculator
* ourselves along the same logic that udev uses. This works only for the case of
* a PCI device being directly connected to a PCI bus, but it will cover most end
* users with e.g. a new laptop which only has beta hardware driver support.
* See https://gitlab.freedesktop.org/xorg/xserver/-/issues/993 */
static char*
config_udev_get_fallback_bus_id(struct udev_device *udev_device)
{
const char *sysname;
char *busid;
udev_device = udev_device_get_parent(udev_device);
if (udev_device == NULL)
return NULL;
if (strcmp(udev_device_get_subsystem(udev_device), "pci") != 0)
return NULL;
sysname = udev_device_get_sysname(udev_device);
busid = XNFalloc(strlen(sysname) + 5);
busid[0] = '\0';
strcat(busid, "pci:");
strcat(busid, sysname);
return busid;
}
static void
config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
@ -526,6 +554,9 @@ config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path
attribs->busid[3] = ':';
}
if (!value)
attribs->busid = config_udev_get_fallback_bus_id(udev_device);
/* ownership of attribs is passed to probe layer */
probe_callback(attribs);
}

View File

@ -26,12 +26,12 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60)
AC_INIT([xorg-server], 1.20.99.1, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
RELEASE_DATE="2018-05-14"
AC_INIT([xorg-server], 21.0.99.1, [https://gitlab.freedesktop.org/xorg/xserver/issues], xorg-server)
RELEASE_DATE="2021-07-05"
RELEASE_NAME="Carrot and Ginger Soup"
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_INIT_AUTOMAKE([foreign dist-xz])
AC_USE_SYSTEM_EXTENSIONS
# Require xorg-macros minimum of 1.14 for XORG_COMPILER_BRAND in XORG_DEFAULT_OPTIONS
@ -363,12 +363,10 @@ esac
dnl augment XORG_RELEASE_VERSION for our snapshot number and to expose the
dnl major number
PVMAJOR=`echo $PACKAGE_VERSION | cut -d . -f 1`
PVS=`echo $PACKAGE_VERSION | cut -d . -f 4 | cut -d - -f 1`
if test "x$PVS" = "x"; then
PVS="0"
fi
VENDOR_RELEASE="((($PVMAJOR) * 10000000) + (($PVM) * 100000) + (($PVP) * 1000) + $PVS)"
dnl Convert to the old-style 1.x.y version scheme used up to 1.20.x for
dnl backwards compatibility
VENDOR_RELEASE="((10000000) + (($PVMAJOR) * 100000) + (($PVM) * 1000) + $PVP)"
VENDOR_MAN_VERSION="Version ${PACKAGE_VERSION}"
VENDOR_NAME="The X.Org Foundation"
@ -733,10 +731,10 @@ XPROTO="xproto >= 7.0.31"
RANDRPROTO="randrproto >= 1.6.0"
RENDERPROTO="renderproto >= 0.11"
XEXTPROTO="xextproto >= 7.2.99.901"
INPUTPROTO="inputproto >= 2.3"
INPUTPROTO="inputproto >= 2.3.99.1"
KBPROTO="kbproto >= 1.0.3"
FONTSPROTO="fontsproto >= 2.1.3"
FIXESPROTO="fixesproto >= 5.0"
FIXESPROTO="fixesproto >= 6.0"
DAMAGEPROTO="damageproto >= 1.1"
XCMISCPROTO="xcmiscproto >= 1.2.0"
BIGREQSPROTO="bigreqsproto >= 1.1.0"
@ -760,6 +758,7 @@ LIBUDEV="libudev >= 143"
LIBSELINUX="libselinux >= 2.0.86"
LIBDBUS="dbus-1 >= 1.0"
LIBPIXMAN="pixman-1 >= 0.27.2"
LIBXCVT="libxcvt"
dnl Pixman is always required, but we separate it out so we can link
dnl specific modules against it
@ -767,7 +766,7 @@ PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau"
dnl Core modules for most extensions, et al.
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN"
SDK_REQUIRED_MODULES="$XPROTO $RANDRPROTO $RENDERPROTO $XEXTPROTO $INPUTPROTO $KBPROTO $FONTSPROTO $LIBPIXMAN $LIBXCVT"
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
AC_SUBST(SDK_REQUIRED_MODULES)
@ -1760,11 +1759,14 @@ fi
AC_MSG_RESULT([$XORG])
if test "x$XORG" = xyes; then
PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT)
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
XORG_INCS="$XORG_DDXINCS $XORG_OSINCS"
XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H"
XORG_CFLAGS="$XORGSERVER_CFLAGS $LIBXCVT_CFLAGS -DHAVE_XORG_CONFIG_H"
XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB"
XORG_SYS_LIBS="$XORG_SYS_LIBS $LIBXCVT_LIBS"
dnl ==================================================================
dnl symbol visibility
@ -2207,7 +2209,7 @@ if test "x$DMX" = xyes; then
fi
DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
XDMX_CFLAGS="$DMXMODULES_CFLAGS"
XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $RANDR_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB"
XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $RANDR_LIB $RENDER_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB"
XDMX_SYS_LIBS="$DMXMODULES_LIBS"
AC_SUBST([XDMX_CFLAGS])
AC_SUBST([XDMX_LIBS])
@ -2293,7 +2295,7 @@ AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
dnl Xwayland DDX
XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.18"
XWAYLANDMODULES="wayland-client >= 1.5.0 wayland-protocols >= 1.18"
if test "x$XF86VIDMODE" = xyes; then
XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO"
fi
@ -2349,8 +2351,10 @@ if test "x$XWAYLAND" = xyes; then
AC_SUBST(have_eglstream, "false")
fi
PKG_CHECK_MODULES([LIBXCVT], $LIBXCVT)
XWAYLAND_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS"
XWAYLAND_SYS_LIBS="$XWAYLANDMODULES_LIBS $GLX_SYS_LIBS $LIBXCVT_LIBS"
AC_SUBST([XWAYLAND_LIBS])
AC_SUBST([XWAYLAND_SYS_LIBS])
@ -2484,7 +2488,6 @@ hw/xfree86/x86emu/Makefile
hw/xfree86/xkb/Makefile
hw/xfree86/utils/Makefile
hw/xfree86/utils/man/Makefile
hw/xfree86/utils/cvt/Makefile
hw/xfree86/utils/gtf/Makefile
hw/dmx/config/Makefile
hw/dmx/config/man/Makefile

View File

@ -561,7 +561,11 @@ static int _X_COLD
SProcDamageDispatch(ClientPtr client)
{
REQUEST(xDamageReq);
if (stuff->damageReqType >= XDamageNumberRequests)
DamageClientPtr pDamageClient = GetDamageClient(client);
if (pDamageClient->major_version >= ARRAY_SIZE(version_requests))
return BadRequest;
if (stuff->damageReqType > version_requests[pDamageClient->major_version])
return BadRequest;
return (*SProcDamageVector[stuff->damageReqType]) (client);
}

View File

@ -13,4 +13,6 @@ libxserver_dbe = static_library('libxserver_dbe',
dependencies: common_dep,
)
install_data(hdrs_dbe, install_dir: xorgsdkdir)
if build_xorg
install_data(hdrs_dbe, install_dir: xorgsdkdir)
endif

View File

@ -23,6 +23,7 @@ libdix_la_SOURCES = \
extension.c \
gc.c \
getevents.c \
gestures.c \
globals.c \
glyphcurs.c \
grabs.c \

View File

@ -458,6 +458,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
return FALSE;
TouchEndPhysicallyActiveTouches(dev);
GestureEndActiveGestures(dev);
ReleaseButtonsAndKeys(dev);
SyncRemoveDeviceIdleTime(dev->idle_counter);
dev->idle_counter = NULL;
@ -1670,6 +1671,32 @@ InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
return FALSE;
}
/**
* Sets up gesture capabilities on @device.
*
* @max_touches The maximum number of simultaneous touches, or 0 for unlimited.
*/
Bool
InitGestureClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches)
{
GestureClassPtr g;
BUG_RETURN_VAL(device == NULL, FALSE);
BUG_RETURN_VAL(device->gesture != NULL, FALSE);
g = calloc(1, sizeof(*g));
if (!g)
return FALSE;
g->sourceid = device->id;
g->max_touches = max_touches;
GestureInitGestureInfo(&g->gesture);
device->gesture = g;
return TRUE;
}
/*
* Check if the given buffer contains elements between low (inclusive) and
* high (inclusive) only.
@ -2257,6 +2284,9 @@ ProcChangePointerControl(ClientPtr client)
REQUEST(xChangePointerControlReq);
REQUEST_SIZE_MATCH(xChangePointerControlReq);
/* If the device has no PtrFeedbackPtr, the xserver has a bug */
BUG_RETURN_VAL (!mouse->ptrfeed, BadImplementation);
ctrl = mouse->ptrfeed->ctrl;
if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
client->errorValue = stuff->doAccel;

View File

@ -128,6 +128,7 @@ int ProcInitialConnection();
#include "inputstr.h"
#include "xkbsrv.h"
#include "client.h"
#include "xfixesint.h"
#ifdef XSERVER_DTRACE
#include "registry.h"
@ -164,6 +165,7 @@ static int nextFreeClientID; /* always MIN free client ID */
static int nClients; /* number of authorized clients */
CallbackListPtr ClientStateCallback;
OsTimerPtr dispatchExceptionTimer;
/* dispatchException & isItTimeToYield must be declared volatile since they
* are modified by signal handlers - otherwise optimizer may assume it doesn't
@ -399,6 +401,58 @@ SmartScheduleClient(void)
return best;
}
static CARD32
DispatchExceptionCallback(OsTimerPtr timer, CARD32 time, void *arg)
{
dispatchException |= dispatchExceptionAtReset;
/* Don't re-arm the timer */
return 0;
}
static void
CancelDispatchExceptionTimer(void)
{
TimerFree(dispatchExceptionTimer);
dispatchExceptionTimer = NULL;
}
static void
SetDispatchExceptionTimer(void)
{
/* The timer delay is only for terminate, not reset */
if (!(dispatchExceptionAtReset & DE_TERMINATE)) {
dispatchException |= dispatchExceptionAtReset;
return;
}
CancelDispatchExceptionTimer();
if (terminateDelay == 0)
dispatchException |= dispatchExceptionAtReset;
else
dispatchExceptionTimer = TimerSet(dispatchExceptionTimer,
0, terminateDelay * 1000 /* msec */,
&DispatchExceptionCallback,
NULL);
}
static Bool
ShouldDisconnectRemainingClients(void)
{
int i;
for (i = 1; i < currentMaxClients; i++) {
if (clients[i]) {
if (!XFixesShouldDisconnectClient(clients[i]))
return FALSE;
}
}
/* All remaining clients can be safely ignored */
return TRUE;
}
void
EnableLimitedSchedulingLatency(void)
{
@ -3419,6 +3473,7 @@ ProcNoOperation(ClientPtr client)
*********************/
char dispatchExceptionAtReset = DE_RESET;
int terminateDelay = 0;
void
CloseDownClient(ClientPtr client)
@ -3475,7 +3530,7 @@ CloseDownClient(ClientPtr client)
if (really_close_down) {
if (client->clientState == ClientStateRunning && nClients == 0)
dispatchException |= dispatchExceptionAtReset;
SetDispatchExceptionTimer();
client->clientState = ClientStateGone;
if (ClientStateCallback) {
@ -3487,6 +3542,7 @@ CloseDownClient(ClientPtr client)
CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
}
TouchListenerGone(client->clientAsMask);
GestureListenerGone(client->clientAsMask);
FreeClientResources(client);
/* Disable client ID tracking. This must be done after
* ClientStateCallback. */
@ -3503,6 +3559,9 @@ CloseDownClient(ClientPtr client)
while (!clients[currentMaxClients - 1])
currentMaxClients--;
}
if (ShouldDisconnectRemainingClients())
SetDispatchExceptionTimer();
}
static void
@ -3704,6 +3763,7 @@ SendConnSetup(ClientPtr client, const char *reason)
clientinfo.setup = (xConnSetup *) lConnectionInfo;
CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
}
CancelDispatchExceptionTimer();
return Success;
}

View File

@ -56,7 +56,7 @@
*
* For a full description of the focus in/out model from a window's
* perspective, see
* http://lists.freedesktop.org/archives/xorg/2008-December/041740.html
* https://lists.freedesktop.org/archives/xorg/2008-December/041684.html
*
* Additional notes:
* - The core protocol spec says that "In a LeaveNotify event, if a child of the

View File

@ -59,6 +59,8 @@ static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
static int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi);
static int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi);
static int eventToGestureSwipeEvent(GestureEvent *ev, xEvent **xi);
static int eventToGesturePinchEvent(GestureEvent *ev, xEvent **xi);
/* Do not use, read comments below */
BOOL EventIsKeyRepeat(xEvent *event);
@ -163,6 +165,12 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
case ET_TouchOwnership:
case ET_BarrierHit:
case ET_BarrierLeave:
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
ret = BadMatch;
break;
default:
@ -221,6 +229,12 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
case ET_TouchOwnership:
case ET_BarrierHit:
case ET_BarrierLeave:
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
*count = 0;
*xi = NULL;
return BadMatch;
@ -285,6 +299,14 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
case ET_BarrierHit:
case ET_BarrierLeave:
return eventToBarrierEvent(&ev->barrier_event, xi);
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
return eventToGesturePinchEvent(&ev->gesture_event, xi);
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
return eventToGestureSwipeEvent(&ev->gesture_event, xi);
default:
break;
}
@ -816,6 +838,88 @@ eventToBarrierEvent(BarrierEvent *ev, xEvent **xi)
return Success;
}
int
eventToGesturePinchEvent(GestureEvent *ev, xEvent **xi)
{
int len = sizeof(xXIGesturePinchEvent);
xXIGesturePinchEvent *xpe;
*xi = calloc(1, len);
xpe = (xXIGesturePinchEvent *) * xi;
xpe->type = GenericEvent;
xpe->extension = IReqCode;
xpe->evtype = GetXI2Type(ev->type);
xpe->time = ev->time;
xpe->length = bytes_to_int32(len - sizeof(xEvent));
xpe->detail = ev->num_touches;
xpe->root = ev->root;
xpe->deviceid = ev->deviceid;
xpe->sourceid = ev->sourceid;
xpe->root_x = double_to_fp1616(ev->root_x);
xpe->root_y = double_to_fp1616(ev->root_y);
xpe->flags |= (ev->flags & GESTURE_CANCELLED) ? XIGesturePinchEventCancelled : 0;
xpe->delta_x = double_to_fp1616(ev->delta_x);
xpe->delta_y = double_to_fp1616(ev->delta_y);
xpe->delta_unaccel_x = double_to_fp1616(ev->delta_unaccel_x);
xpe->delta_unaccel_y = double_to_fp1616(ev->delta_unaccel_y);
xpe->scale = double_to_fp1616(ev->scale);
xpe->delta_angle = double_to_fp1616(ev->delta_angle);
xpe->mods.base_mods = ev->mods.base;
xpe->mods.latched_mods = ev->mods.latched;
xpe->mods.locked_mods = ev->mods.locked;
xpe->mods.effective_mods = ev->mods.effective;
xpe->group.base_group = ev->group.base;
xpe->group.latched_group = ev->group.latched;
xpe->group.locked_group = ev->group.locked;
xpe->group.effective_group = ev->group.effective;
return Success;
}
int
eventToGestureSwipeEvent(GestureEvent *ev, xEvent **xi)
{
int len = sizeof(xXIGestureSwipeEvent);
xXIGestureSwipeEvent *xde;
*xi = calloc(1, len);
xde = (xXIGestureSwipeEvent *) * xi;
xde->type = GenericEvent;
xde->extension = IReqCode;
xde->evtype = GetXI2Type(ev->type);
xde->time = ev->time;
xde->length = bytes_to_int32(len - sizeof(xEvent));
xde->detail = ev->num_touches;
xde->root = ev->root;
xde->deviceid = ev->deviceid;
xde->sourceid = ev->sourceid;
xde->root_x = double_to_fp1616(ev->root_x);
xde->root_y = double_to_fp1616(ev->root_y);
xde->flags |= (ev->flags & GESTURE_CANCELLED) ? XIGestureSwipeEventCancelled : 0;
xde->delta_x = double_to_fp1616(ev->delta_x);
xde->delta_y = double_to_fp1616(ev->delta_y);
xde->delta_unaccel_x = double_to_fp1616(ev->delta_unaccel_x);
xde->delta_unaccel_y = double_to_fp1616(ev->delta_unaccel_y);
xde->mods.base_mods = ev->mods.base;
xde->mods.latched_mods = ev->mods.latched;
xde->mods.locked_mods = ev->mods.locked;
xde->mods.effective_mods = ev->mods.effective;
xde->group.base_group = ev->group.base;
xde->group.latched_group = ev->group.latched;
xde->group.locked_group = ev->group.locked;
xde->group.effective_group = ev->group.effective;
return Success;
}
/**
* Return the corresponding core type for the given event or 0 if no core
* equivalent exists.
@ -969,8 +1073,68 @@ GetXI2Type(enum EventType type)
case ET_BarrierLeave:
xi2type = XI_BarrierLeave;
break;
case ET_GesturePinchBegin:
xi2type = XI_GesturePinchBegin;
break;
case ET_GesturePinchUpdate:
xi2type = XI_GesturePinchUpdate;
break;
case ET_GesturePinchEnd:
xi2type = XI_GesturePinchEnd;
break;
case ET_GestureSwipeBegin:
xi2type = XI_GestureSwipeBegin;
break;
case ET_GestureSwipeUpdate:
xi2type = XI_GestureSwipeUpdate;
break;
case ET_GestureSwipeEnd:
xi2type = XI_GestureSwipeEnd;
break;
default:
break;
}
return xi2type;
}
/**
* Converts a gesture type to corresponding Gesture{Pinch,Swipe}Begin.
* Returns 0 if the input type is not a gesture.
*/
enum EventType
GestureTypeToBegin(enum EventType type)
{
switch (type) {
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
return ET_GesturePinchBegin;
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
return ET_GestureSwipeBegin;
default:
return 0;
}
}
/**
* Converts a gesture type to corresponding Gesture{Pinch,Swipe}End.
* Returns 0 if the input type is not a gesture.
*/
enum EventType
GestureTypeToEnd(enum EventType type)
{
switch (type) {
case ET_GesturePinchBegin:
case ET_GesturePinchUpdate:
case ET_GesturePinchEnd:
return ET_GesturePinchEnd;
case ET_GestureSwipeBegin:
case ET_GestureSwipeUpdate:
case ET_GestureSwipeEnd:
return ET_GestureSwipeEnd;
default:
return 0;
}
}

View File

@ -1328,6 +1328,15 @@ ComputeFreezes(void)
TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch);
}
else if (IsGestureEvent(event)) {
GestureInfoPtr gi =
GestureFindActiveByEventType(replayDev, event->any.type);
if (gi) {
GestureEmitGestureEndToOwner(replayDev, gi);
GestureEndGesture(gi);
}
ProcessGestureEvent(event, replayDev);
}
else {
WindowPtr w = XYToWindow(replayDev->spriteInfo->sprite,
event->device_event.root_x,
@ -1480,16 +1489,28 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
if (ti->active &&
CLIENT_BITS(listener->listener) == grab->resource) {
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) {
if (listener->type == TOUCH_LISTENER_REGULAR &&
listener->state != TOUCH_LISTENER_AWAITING_BEGIN &&
listener->state != TOUCH_LISTENER_HAS_END) {
/* if the listener already got any events relating to the touch, we must send
a touch end because the grab overrides the previous listener and won't
itself send any touch events.
*/
TouchEmitTouchEnd(mouse, ti, 0, listener->listener);
}
listener->type = TOUCH_LISTENER_POINTER_GRAB;
} else {
listener->type = TOUCH_LISTENER_GRAB;
}
listener->listener = grab->resource;
listener->level = grab->grabtype;
listener->state = TOUCH_LISTENER_IS_OWNER;
listener->window = grab->window;
listener->state = TOUCH_LISTENER_IS_OWNER;
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
listener->type = TOUCH_LISTENER_POINTER_GRAB;
else
listener->type = TOUCH_LISTENER_GRAB;
if (listener->grab)
FreeGrab(listener->grab);
listener->grab = AllocGrab(grab);
@ -1497,6 +1518,46 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
}
}
/**
* Update gesture records when an explicit grab is activated. Any gestures owned
* by the grabbing client are updated so the listener state reflects the new
* grab.
*/
static void
UpdateGesturesForGrab(DeviceIntPtr mouse)
{
if (!mouse->gesture || mouse->deviceGrab.fromPassiveGrab)
return;
GestureInfoPtr gi = &mouse->gesture->gesture;
GestureListener *listener = &gi->listener;
GrabPtr grab = mouse->deviceGrab.grab;
if (gi->active && CLIENT_BITS(listener->listener) == grab->resource) {
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, GetXI2Type(gi->type))) {
if (listener->type == GESTURE_LISTENER_REGULAR) {
/* if the listener already got any events relating to the gesture, we must send
a gesture end because the grab overrides the previous listener and won't
itself send any gesture events.
*/
GestureEmitGestureEndToOwner(mouse, gi);
}
listener->type = GESTURE_LISTENER_NONGESTURE_GRAB;
} else {
listener->type = GESTURE_LISTENER_GRAB;
}
listener->listener = grab->resource;
listener->window = grab->window;
if (listener->grab)
FreeGrab(listener->grab);
listener->grab = AllocGrab(grab);
}
}
/**
* Activate a pointer grab on the given device. A pointer grab will cause all
* core pointer events of this device to be delivered to the grabbing client only.
@ -1547,6 +1608,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
PostNewCursor(mouse);
UpdateTouchesForGrab(mouse);
UpdateGesturesForGrab(mouse);
CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
(Bool) grab->keyboardMode);
if (oldgrab)
@ -1602,6 +1664,16 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
if (dev->deviceGrab.sync.other == grab)
dev->deviceGrab.sync.other = NullGrab;
}
/* in case of explicit gesture grab, send end event to the grab client */
if (!wasPassive && mouse->gesture) {
GestureInfoPtr gi = &mouse->gesture->gesture;
if (gi->active && GestureResourceIsOwner(gi, grab_resource)) {
GestureEmitGestureEndToOwner(mouse, gi);
GestureEndGesture(gi);
}
}
DoEnterLeaveEvents(mouse, mouse->id, grab->window,
mouse->spriteInfo->sprite->win, NotifyUngrab);
if (grab->confineTo)
@ -2533,6 +2605,44 @@ FixUpXI2DeviceEventFromWindow(SpritePtr pSprite, int evtype,
(pSprite->hot.pScreen == pWin->drawable.pScreen);
}
static void
FixUpXI2PinchEventFromWindow(SpritePtr pSprite, xXIGesturePinchEvent *event,
WindowPtr pWin, Window child)
{
event->root = RootWindow(pSprite)->drawable.id;
event->event = pWin->drawable.id;
if (pSprite->hot.pScreen == pWin->drawable.pScreen) {
event->event_x = event->root_x - double_to_fp1616(pWin->drawable.x);
event->event_y = event->root_y - double_to_fp1616(pWin->drawable.y);
event->child = child;
}
else {
event->event_x = 0;
event->event_y = 0;
event->child = None;
}
}
static void
FixUpXI2SwipeEventFromWindow(SpritePtr pSprite, xXIGestureSwipeEvent *event,
WindowPtr pWin, Window child)
{
event->root = RootWindow(pSprite)->drawable.id;
event->event = pWin->drawable.id;
if (pSprite->hot.pScreen == pWin->drawable.pScreen) {
event->event_x = event->root_x - double_to_fp1616(pWin->drawable.x);
event->event_y = event->root_y - double_to_fp1616(pWin->drawable.y);
event->child = child;
}
else {
event->event_x = 0;
event->event_y = 0;
event->child = None;
}
}
/**
* Adjust event fields to comply with the window properties.
*
@ -2566,6 +2676,18 @@ FixUpEventFromWindow(SpritePtr pSprite,
case XI_BarrierHit:
case XI_BarrierLeave:
return;
case XI_GesturePinchBegin:
case XI_GesturePinchUpdate:
case XI_GesturePinchEnd:
FixUpXI2PinchEventFromWindow(pSprite,
(xXIGesturePinchEvent*) xE, pWin, child);
break;
case XI_GestureSwipeBegin:
case XI_GestureSwipeUpdate:
case XI_GestureSwipeEnd:
FixUpXI2SwipeEventFromWindow(pSprite,
(xXIGestureSwipeEvent*) xE, pWin, child);
break;
default:
FixUpXI2DeviceEventFromWindow(pSprite, evtype,
(xXIDeviceEvent*) xE, pWin, child);

362
dix/gestures.c Normal file
View File

@ -0,0 +1,362 @@
/*
* Copyright © 2011 Collabra Ltd.
* Copyright © 2011 Red Hat, Inc.
* Copyright © 2020 Povilas Kanapickas <povilas@radix.lt>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "inputstr.h"
#include "scrnintstr.h"
#include "dixgrabs.h"
#include "eventstr.h"
#include "exevents.h"
#include "exglobals.h"
#include "inpututils.h"
#include "eventconvert.h"
#include "windowstr.h"
#include "mi.h"
#define GESTURE_HISTORY_SIZE 100
Bool
GestureInitGestureInfo(GestureInfoPtr gi)
{
memset(gi, 0, sizeof(*gi));
gi->sprite.spriteTrace = calloc(32, sizeof(*gi->sprite.spriteTrace));
if (!gi->sprite.spriteTrace) {
return FALSE;
}
gi->sprite.spriteTraceSize = 32;
gi->sprite.spriteTrace[0] = screenInfo.screens[0]->root;
gi->sprite.hot.pScreen = screenInfo.screens[0];
gi->sprite.hotPhys.pScreen = screenInfo.screens[0];
return TRUE;
}
/**
* Given an event type returns the associated gesture event info.
*/
GestureInfoPtr
GestureFindActiveByEventType(DeviceIntPtr dev, int type)
{
GestureClassPtr g = dev->gesture;
enum EventType type_to_expect = GestureTypeToBegin(type);
if (!g || type_to_expect == 0 || !g->gesture.active ||
g->gesture.type != type_to_expect) {
return NULL;
}
return &g->gesture;
}
/**
* Sets up gesture info for a new gesture. Returns NULL on failure.
*/
GestureInfoPtr
GestureBeginGesture(DeviceIntPtr dev, InternalEvent *ev)
{
GestureClassPtr g = dev->gesture;
enum EventType gesture_type = GestureTypeToBegin(ev->any.type);
/* Note that we ignore begin events when an existing gesture is active */
if (!g || gesture_type == 0 || g->gesture.active)
return NULL;
g->gesture.type = gesture_type;
if (!GestureBuildSprite(dev, &g->gesture))
return NULL;
g->gesture.active = TRUE;
g->gesture.num_touches = ev->gesture_event.num_touches;
g->gesture.sourceid = ev->gesture_event.sourceid;
g->gesture.has_listener = FALSE;
return &g->gesture;
}
/**
* Releases a gesture: this must only be called after all events
* related to that gesture have been sent and finalised.
*/
void
GestureEndGesture(GestureInfoPtr gi)
{
if (gi->has_listener) {
if (gi->listener.grab) {
FreeGrab(gi->listener.grab);
gi->listener.grab = NULL;
}
gi->listener.listener = 0;
gi->has_listener = FALSE;
}
gi->active = FALSE;
gi->num_touches = 0;
gi->sprite.spriteTraceGood = 0;
}
/**
* Ensure a window trace is present in gi->sprite, constructing one for
* Gesture{Pinch,Swipe}Begin events.
*/
Bool
GestureBuildSprite(DeviceIntPtr sourcedev, GestureInfoPtr gi)
{
SpritePtr sprite = &gi->sprite;
if (!sourcedev->spriteInfo->sprite)
return FALSE;
if (!CopySprite(sourcedev->spriteInfo->sprite, sprite))
return FALSE;
if (sprite->spriteTraceGood <= 0)
return FALSE;
return TRUE;
}
/**
* @returns TRUE if the specified grab or selection is the current owner of
* the gesture sequence.
*/
Bool
GestureResourceIsOwner(GestureInfoPtr gi, XID resource)
{
return (gi->listener.listener == resource);
}
void
GestureAddListener(GestureInfoPtr gi, XID resource, int resource_type,
enum GestureListenerType type, WindowPtr window, const GrabPtr grab)
{
GrabPtr g = NULL;
BUG_RETURN(gi->has_listener);
/* We need a copy of the grab, not the grab itself since that may be deleted by
* a UngrabButton request and leaves us with a dangling pointer */
if (grab)
g = AllocGrab(grab);
gi->listener.listener = resource;
gi->listener.resource_type = resource_type;
gi->listener.type = type;
gi->listener.window = window;
gi->listener.grab = g;
gi->has_listener = TRUE;
}
static void
GestureAddGrabListener(DeviceIntPtr dev, GestureInfoPtr gi, GrabPtr grab)
{
enum GestureListenerType type;
/* FIXME: owner_events */
if (grab->grabtype == XI2) {
if (xi2mask_isset(grab->xi2mask, dev, XI_GesturePinchBegin) ||
xi2mask_isset(grab->xi2mask, dev, XI_GestureSwipeBegin)) {
type = GESTURE_LISTENER_GRAB;
} else
type = GESTURE_LISTENER_NONGESTURE_GRAB;
}
else if (grab->grabtype == XI || grab->grabtype == CORE) {
type = GESTURE_LISTENER_NONGESTURE_GRAB;
}
else {
BUG_RETURN_MSG(1, "Unsupported grab type\n");
}
/* grab listeners are always RT_NONE since we keep the grab pointer */
GestureAddListener(gi, grab->resource, RT_NONE, type, grab->window, grab);
}
/**
* Add one listener if there is a grab on the given window.
*/
static void
GestureAddPassiveGrabListener(DeviceIntPtr dev, GestureInfoPtr gi, WindowPtr win, InternalEvent *ev)
{
Bool activate = FALSE;
Bool check_core = FALSE;
GrabPtr grab = CheckPassiveGrabsOnWindow(win, dev, ev, check_core,
activate);
if (!grab)
return;
/* We'll deliver later in gesture-specific code */
ActivateGrabNoDelivery(dev, grab, ev, ev);
GestureAddGrabListener(dev, gi, grab);
}
static void
GestureAddRegularListener(DeviceIntPtr dev, GestureInfoPtr gi, WindowPtr win, InternalEvent *ev)
{
InputClients *iclients = NULL;
OtherInputMasks *inputMasks = NULL;
uint16_t evtype = GetXI2Type(ev->any.type);
int mask;
mask = EventIsDeliverable(dev, ev->any.type, win);
if (!mask)
return;
inputMasks = wOtherInputMasks(win);
if (mask & EVENT_XI2_MASK) {
nt_list_for_each_entry(iclients, inputMasks->inputClients, next) {
if (!xi2mask_isset(iclients->xi2mask, dev, evtype))
continue;
GestureAddListener(gi, iclients->resource, RT_INPUTCLIENT,
GESTURE_LISTENER_REGULAR, win, NULL);
return;
}
}
}
void
GestureSetupListener(DeviceIntPtr dev, GestureInfoPtr gi, InternalEvent *ev)
{
int i;
SpritePtr sprite = &gi->sprite;
WindowPtr win;
/* Any current grab will consume all gesture events */
if (dev->deviceGrab.grab) {
GestureAddGrabListener(dev, gi, dev->deviceGrab.grab);
return;
}
/* Find passive grab that would be activated by this event, if any. If we're handling
* ReplayDevice then the search starts from the descendant of the grab window, otherwise
* the search starts at the root window. The search ends at deepest child window. */
i = 0;
if (syncEvents.playingEvents) {
while (i < dev->spriteInfo->sprite->spriteTraceGood) {
if (dev->spriteInfo->sprite->spriteTrace[i++] == syncEvents.replayWin)
break;
}
}
for (; i < sprite->spriteTraceGood; i++) {
win = sprite->spriteTrace[i];
GestureAddPassiveGrabListener(dev, gi, win, ev);
if (gi->has_listener)
return;
}
/* Find the first client with an applicable event selection,
* going from deepest child window back up to the root window. */
for (i = sprite->spriteTraceGood - 1; i >= 0; i--) {
win = sprite->spriteTrace[i];
GestureAddRegularListener(dev, gi, win, ev);
if (gi->has_listener)
return;
}
}
/* As gesture grabs don't turn into active grabs with their own resources, we
* need to walk all the gestures and remove this grab from listener */
void
GestureListenerGone(XID resource)
{
GestureInfoPtr gi;
DeviceIntPtr dev;
InternalEvent *events = InitEventList(GetMaximumEventsNum());
if (!events)
FatalError("GestureListenerGone: couldn't allocate events\n");
for (dev = inputInfo.devices; dev; dev = dev->next) {
if (!dev->gesture)
continue;
gi = &dev->gesture->gesture;
if (!gi->active)
continue;
if (CLIENT_BITS(gi->listener.listener) == resource)
GestureEndGesture(gi);
}
FreeEventList(events, GetMaximumEventsNum());
}
/**
* End physically active gestures for a device.
*/
void
GestureEndActiveGestures(DeviceIntPtr dev)
{
GestureClassPtr g = dev->gesture;
InternalEvent *eventlist;
if (!g)
return;
eventlist = InitEventList(GetMaximumEventsNum());
input_lock();
mieqProcessInputEvents();
if (g->gesture.active) {
int j;
int type = GetXI2Type(GestureTypeToEnd(g->gesture.type));
int nevents = GetGestureEvents(eventlist, dev, type, g->gesture.num_touches,
0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
for (j = 0; j < nevents; j++)
mieqProcessDeviceEvent(dev, eventlist + j, NULL);
}
input_unlock();
FreeEventList(eventlist, GetMaximumEventsNum());
}
/**
* Generate and deliver a Gesture{Pinch,Swipe}End event to the owner.
*
* @param dev The device to deliver the event for.
* @param gi The gesture record to deliver the event for.
*/
void
GestureEmitGestureEndToOwner(DeviceIntPtr dev, GestureInfoPtr gi)
{
InternalEvent event;
/* We're not processing a gesture end for a frozen device */
if (dev->deviceGrab.sync.frozen)
return;
DeliverDeviceClassesChangedEvent(gi->sourceid, GetTimeInMillis());
InitGestureEvent(&event, dev, GetTimeInMillis(), GestureTypeToEnd(gi->type),
0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
DeliverGestureEventToOwner(dev, gi, &event);
}

View File

@ -1343,7 +1343,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
int buttons, CARD32 ms, int flags,
const ValuatorMask *mask_in)
{
int num_events = 1;
int num_events = 0;
DeviceEvent *event;
RawDeviceEvent *raw = NULL;
double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */
@ -1386,6 +1386,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
num_events++;
init_raw(pDev, raw, ms, type, buttons);
if (flags & POINTER_EMULATED)
raw->flags = XIPointerEmulated;
set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw);
}
@ -1454,36 +1458,37 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
master->last.valuators[1] = screeny;
}
event = &events->device_event;
init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL);
if ((flags & POINTER_RAWONLY) == 0) {
num_events++;
if (type == MotionNotify) {
event->type = ET_Motion;
event->detail.button = 0;
}
else {
if (type == ButtonPress) {
event->type = ET_ButtonPress;
set_button_down(pDev, buttons, BUTTON_POSTED);
event = &events->device_event;
init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL);
if (type == MotionNotify) {
event->type = ET_Motion;
event->detail.button = 0;
}
else if (type == ButtonRelease) {
event->type = ET_ButtonRelease;
set_button_up(pDev, buttons, BUTTON_POSTED);
else {
if (type == ButtonPress) {
event->type = ET_ButtonPress;
set_button_down(pDev, buttons, BUTTON_POSTED);
}
else if (type == ButtonRelease) {
event->type = ET_ButtonRelease;
set_button_up(pDev, buttons, BUTTON_POSTED);
}
event->detail.button = buttons;
}
event->detail.button = buttons;
/* root_x and root_y must be in per-screen coordinates */
event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
if (flags & POINTER_EMULATED)
event->flags = XIPointerEmulated;
set_valuators(pDev, event, &mask);
}
/* root_x and root_y must be in per-screen coordinates */
event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y);
if (flags & POINTER_EMULATED) {
if (raw)
raw->flags = XIPointerEmulated;
event->flags = XIPointerEmulated;
}
set_valuators(pDev, event, &mask);
return num_events;
}
@ -2094,3 +2099,139 @@ PostSyntheticMotion(DeviceIntPtr pDev,
/* FIXME: MD/SD considerations? */
(*pDev->public.processInputProc) ((InternalEvent *) &ev, pDev);
}
void
InitGestureEvent(InternalEvent *ievent, DeviceIntPtr dev, CARD32 ms,
int type, uint16_t num_touches, uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x, double delta_unaccel_y,
double scale, double delta_angle)
{
ScreenPtr scr = dev->spriteInfo->sprite->hotPhys.pScreen;
GestureEvent *event = &ievent->gesture_event;
double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */
init_gesture_event(event, dev, ms);
screenx = dev->spriteInfo->sprite->hotPhys.x;
screeny = dev->spriteInfo->sprite->hotPhys.y;
event->type = type;
event->root = scr->root->drawable.id;
event->root_x = screenx - scr->x;
event->root_y = screeny - scr->y;
event->num_touches = num_touches;
event->flags = flags;
event->delta_x = delta_x;
event->delta_y = delta_y;
event->delta_unaccel_x = delta_unaccel_x;
event->delta_unaccel_y = delta_unaccel_y;
event->scale = scale;
event->delta_angle = delta_angle;
}
/**
* Get events for a pinch or swipe gesture.
*
* events is not NULL-terminated; the return value is the number of events.
* The DDX is responsible for allocating the event structure in the first
* place via GetMaximumEventsNum(), and for freeing it.
*
* @param[out] events The list of events generated
* @param dev The device to generate the events for
* @param type XI_Gesture{Pinch,Swipe}{Begin,Update,End}
* @prama num_touches The number of touches in the gesture
* @param flags Event flags
* @param delta_x,delta_y accelerated relative motion delta
* @param delta_unaccel_x,delta_unaccel_y unaccelerated relative motion delta
* @param scale (valid only to pinch events) absolute scale of a pinch gesture
* @param delta_angle (valid only to pinch events) the ange delta in degrees between the last and
* the current pinch event.
*/
int
GetGestureEvents(InternalEvent *events, DeviceIntPtr dev,
uint16_t type, uint16_t num_touches, uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x, double delta_unaccel_y,
double scale, double delta_angle)
{
GestureClassPtr g = dev->gesture;
CARD32 ms = GetTimeInMillis();
enum EventType evtype;
int num_events = 0;
uint32_t evflags = 0;
if (!dev->enabled || !g)
return 0;
if (!IsMaster(dev))
events = UpdateFromMaster(events, dev, DEVCHANGE_POINTER_EVENT,
&num_events);
switch (type) {
case XI_GesturePinchBegin:
evtype = ET_GesturePinchBegin;
break;
case XI_GesturePinchUpdate:
evtype = ET_GesturePinchUpdate;
break;
case XI_GesturePinchEnd:
evtype = ET_GesturePinchEnd;
if (flags & XIGesturePinchEventCancelled)
evflags |= GESTURE_CANCELLED;
break;
case XI_GestureSwipeBegin:
evtype = ET_GestureSwipeBegin;
break;
case XI_GestureSwipeUpdate:
evtype = ET_GestureSwipeUpdate;
break;
case XI_GestureSwipeEnd:
evtype = ET_GestureSwipeEnd;
if (flags & XIGestureSwipeEventCancelled)
evflags |= GESTURE_CANCELLED;
break;
default:
return 0;
}
InitGestureEvent(events, dev, ms, evtype, num_touches, evflags,
delta_x, delta_y, delta_unaccel_x, delta_unaccel_y,
scale, delta_angle);
num_events++;
return num_events;
}
void
QueueGesturePinchEvents(DeviceIntPtr dev, uint16_t type,
uint16_t num_touches, uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x,
double delta_unaccel_y,
double scale, double delta_angle)
{
int nevents;
nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags,
delta_x, delta_y,
delta_unaccel_x, delta_unaccel_y,
scale, delta_angle);
queueEventList(dev, InputEventList, nevents);
}
void
QueueGestureSwipeEvents(DeviceIntPtr dev, uint16_t type,
uint16_t num_touches, uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x,
double delta_unaccel_y)
{
int nevents;
nevents = GetGestureEvents(InputEventList, dev, type, num_touches, flags,
delta_x, delta_y,
delta_unaccel_x, delta_unaccel_y,
0.0, 0.0);
queueEventList(dev, InputEventList, nevents);
}

View File

@ -716,3 +716,10 @@ GrabIsKeyboardGrab(GrabPtr grab)
return (grab->type == KeyPress ||
grab->type == DeviceKeyPress || grab->type == XI_KeyPress);
}
Bool
GrabIsGestureGrab(GrabPtr grab)
{
return (grab->type == XI_GesturePinchBegin ||
grab->type == XI_GestureSwipeBegin);
}

View File

@ -746,6 +746,21 @@ init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms,
event->source_type = source_type;
}
/**
* Initializes the given gesture event to zero (or default values),
* for the given device.
*/
void
init_gesture_event(GestureEvent *event, DeviceIntPtr dev, Time ms)
{
memset(event, 0, sizeof(GestureEvent));
event->header = ET_Internal;
event->length = sizeof(GestureEvent);
event->time = ms;
event->deviceid = dev->id;
event->sourceid = dev->id;
}
int
event_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd)
{
@ -794,6 +809,24 @@ event_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd, DeviceEvent *event)
}
}
void
event_set_state_gesture(DeviceIntPtr kbd, GestureEvent *event)
{
if (kbd && kbd->key) {
XkbStatePtr state= &kbd->key->xkbInfo->state;
event->mods.base = state->base_mods;
event->mods.latched = state->latched_mods;
event->mods.locked = state->locked_mods;
event->mods.effective = state->mods;
event->group.base = state->base_group;
event->group.latched = state->latched_group;
event->group.locked = state->locked_group;
event->group.effective = state->group;
}
}
/**
* Return the event filter mask for the given device and the given core or
* XI1 protocol type.

View File

@ -12,6 +12,7 @@ srcs_dix = [
'eventconvert.c',
'extension.c',
'gc.c',
'gestures.c',
'getevents.c',
'globals.c',
'glyphcurs.c',

View File

@ -253,7 +253,7 @@ ProcChangeProperty(ClientPtr client)
int
dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
Atom type, int format, int mode, unsigned long len,
void *value, Bool sendevent)
const void *value, Bool sendevent)
{
PropertyPtr pProp;
PropertyRec savedProp;

64
doc/dtrace/meson.build Normal file
View File

@ -0,0 +1,64 @@
if build_docs
basename = 'Xserver-DTrace'
input_xml = basename + '.xml'
custom_target(
basename + '.html',
output: basename + '.html',
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
'--stringparam', 'target.database.document=' + join_paths(doc_sgml_path, 'X11/dbs/masterdb.html.xml'),
'--stringparam', 'current.docid=' + basename,
'-o', meson.current_build_dir(),
'xhtml-nochunks', '@INPUT0@'],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc/xorg-server'),
)
if build_docs_pdf
foreach format : ['ps', 'pdf']
output_fn = basename + '.' + format
custom_target(
output_fn,
output: output_fn,
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
'--stringparam', 'target.database.document=' + join_paths(doc_sgml_path, 'X11/dbs/masterdb.pdf.xml'),
'--stringparam', 'current.docid=' + basename,
'-o', meson.current_build_dir(),
'--with-fop', format, '@INPUT0@'],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc/xorg-server'),
)
endforeach
endif
foreach format_data : [['html', 'xorg-xhtml.xsl'], ['pdf', 'xorg-fo.xsl']]
format = format_data[0]
stylesheet = format_data[1]
output_fn = basename + '.' + format + '.db'
custom_target(
output_fn,
output: output_fn,
input: [input_xml],
command: [xsltproc] + docs_xslt_search_flags + [
'--stringparam', 'targets.filename', output_fn,
'--stringparam', 'collect.xref.targets', 'only',
'--stringparam', 'olink.base.uri', basename + '.' + format,
'--nonet',
'--output', join_paths(meson.current_build_dir(), output_fn),
'--xinclude', join_paths(doc_stylesheet_srcdir, stylesheet),
'@INPUT0@'],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc/xorg-server'),
)
endforeach
endif

39
doc/meson.build Normal file
View File

@ -0,0 +1,39 @@
if build_docs_devel
foreach basename : ['Xserver-spec', 'Xinput']
input_xml = basename + '.xml'
custom_target(
basename + '.html',
output: basename + '.html',
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
'-o', meson.current_build_dir(),
'xhtml-nochunks', '@INPUT0@'],
build_by_default: true,
install: false,
)
if build_docs_pdf
foreach format : ['ps', 'pdf']
output_fn = basename + '.' + format
custom_target(
output_fn,
output: output_fn,
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
'-o', meson.current_build_dir(),
'--with-fop', format, '@INPUT0@'],
build_by_default: true,
install: false,
)
endforeach
endif
endforeach
endif
subdir('dtrace')

View File

@ -17,4 +17,6 @@ if build_dri3
)
endif
install_data(hdrs_dri3, install_dir: xorgsdkdir)
if build_xorg
install_data(hdrs_dri3, install_dir: xorgsdkdir)
endif

View File

@ -54,4 +54,6 @@ libxserver_wfb = static_library('libxserver_wfb',
build_by_default: false,
)
install_data(hdrs_fb, install_dir: xorgsdkdir)
if build_xorg
install_data(hdrs_fb, install_dir: xorgsdkdir)
endif

View File

@ -414,6 +414,7 @@ glamor_debug_output_callback(GLenum source,
LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
screen->myNum, length, message);
xorg_backtrace();
}
/**
@ -745,7 +746,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
* have instanced arrays, but this is not always the case.
* etnaviv offers GLSL 140 with OpenGL 2.1.
*/
if (glamor_priv->glsl_version >= 130 &&
if (glamor_glsl_has_ints(glamor_priv) &&
!epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
glamor_priv->glsl_version = 120;
} else {
@ -771,6 +772,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
goto fail;
}
if (!glamor_priv->is_gles && glamor_priv->glsl_version == 120 &&
epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
glamor_priv->use_gpu_shader4 = epoxy_has_gl_extension("GL_EXT_gpu_shader4");
glamor_priv->has_rw_pbo = FALSE;
if (!glamor_priv->is_gles)
glamor_priv->has_rw_pbo = TRUE;
@ -798,7 +803,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
epoxy_gl_version() >= 30 ||
epoxy_has_gl_extension("GL_NV_pack_subimage");
glamor_priv->has_dual_blend =
glamor_priv->glsl_version >= 130 &&
glamor_glsl_has_ints(glamor_priv) &&
epoxy_has_gl_extension("GL_ARB_blend_func_extended");
glamor_priv->has_clear_texture =
epoxy_gl_version() >= 44 ||
@ -816,7 +821,8 @@ glamor_init(ScreenPtr screen, unsigned int flags)
* cached IB.
*/
if (strstr((char *)glGetString(GL_VENDOR), "Broadcom") &&
strstr((char *)glGetString(GL_RENDERER), "VC4"))
(strstr((char *)glGetString(GL_RENDERER), "VC4") ||
strstr((char *)glGetString(GL_RENDERER), "V3D")))
glamor_priv->use_quads = FALSE;
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);

View File

@ -208,11 +208,6 @@ static const glamor_facet glamor_facet_composite_glyphs_120 = {
.locations = glamor_program_location_atlas,
};
static inline Bool
glamor_glyph_use_130(glamor_screen_private *glamor_priv) {
return glamor_priv->glsl_version >= 130;
}
static Bool
glamor_glyphs_init_facet(ScreenPtr screen)
{
@ -274,7 +269,7 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
box->y2 - box->y1);
box++;
if (glamor_glyph_use_130(glamor_priv))
if (glamor_glsl_has_ints(glamor_priv))
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph);
else
glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph);
@ -287,7 +282,7 @@ glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst,
glDisable(GL_SCISSOR_TEST);
if (glamor_glyph_use_130(glamor_priv)) {
if (glamor_glsl_has_ints(glamor_priv)) {
glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
}
@ -305,7 +300,7 @@ glamor_glyph_start(ScreenPtr screen, int count)
/* Set up the vertex buffers for the font and destination */
if (glamor_glyph_use_130(glamor_priv)) {
if (glamor_glsl_has_ints(glamor_priv)) {
v = glamor_get_vbo_space(screen, count * (6 * sizeof (GLshort)), &vbo_offset);
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@ -439,7 +434,7 @@ glamor_composite_glyphs(CARD8 op,
/* First glyph in the current atlas?
*/
if (_X_UNLIKELY(glyphs_queued == 0)) {
if (glamor_glyph_use_130(glamor_priv))
if (glamor_glsl_has_ints(glamor_priv))
prog = glamor_setup_program_render(op, src, glyph_pict, dst,
glyphs_program,
&glamor_facet_composite_glyphs_130,
@ -458,7 +453,7 @@ glamor_composite_glyphs(CARD8 op,
*/
glyphs_queued++;
if (_X_LIKELY(glamor_glyph_use_130(glamor_priv))) {
if (_X_LIKELY(glamor_glsl_has_ints(glamor_priv))) {
v[0] = x - glyph->info.x;
v[1] = y - glyph->info.y;
v[2] = glyph_draw->width;

View File

@ -1060,9 +1060,14 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
goto error;
}
if (strstr((const char *)renderer, "llvmpipe")) {
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Refusing to try glamor on llvmpipe\n");
goto error;
if (scrn->confScreen->num_gpu_devices)
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Allowing glamor on llvmpipe for PRIME\n");
else {
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Refusing to try glamor on llvmpipe\n");
goto error;
}
}
/*

View File

@ -47,7 +47,7 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
unsigned long count;
char *bits;
if (glamor_priv->glsl_version < 130)
if (!glamor_glsl_has_ints(glamor_priv))
return NULL;
privates = FontGetPrivate(font, glamor_font_private_index);
@ -210,7 +210,7 @@ glamor_font_init(ScreenPtr screen)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
if (glamor_priv->glsl_version < 130)
if (!glamor_glsl_has_ints(glamor_priv))
return TRUE;
if (glamor_font_generation != serverGeneration) {

View File

@ -213,6 +213,7 @@ typedef struct glamor_screen_private {
Bool has_texture_swizzle;
Bool is_core_profile;
Bool can_copyplane;
Bool use_gpu_shader4;
int max_fbo_size;
struct glamor_format formats[33];

View File

@ -187,6 +187,7 @@ fs_location_vars(glamor_program_location locations)
static const char vs_template[] =
"%s" /* version */
"%s" /* exts */
"%s" /* defines */
"%s" /* prim vs_vars */
"%s" /* fill vs_vars */
@ -199,6 +200,7 @@ static const char vs_template[] =
static const char fs_template[] =
"%s" /* version */
"%s" /* exts */
GLAMOR_DEFAULT_PRECISION
"%s" /* defines */
"%s" /* prim fs_vars */
@ -262,6 +264,7 @@ glamor_build_program(ScreenPtr screen,
char *fs_prog_string;
GLint fs_prog, vs_prog;
Bool gpu_shader4 = FALSE;
if (!fill)
fill = &facet_null_fill;
@ -270,8 +273,14 @@ glamor_build_program(ScreenPtr screen,
flags |= fill->flags;
version = MAX(version, fill->version);
if (version > glamor_priv->glsl_version)
goto fail;
if (version > glamor_priv->glsl_version) {
if (version == 130 && !glamor_priv->use_gpu_shader4)
goto fail;
else {
version = 120;
gpu_shader4 = TRUE;
}
}
vs_vars = vs_location_vars(locations);
fs_vars = fs_location_vars(locations);
@ -291,6 +300,7 @@ glamor_build_program(ScreenPtr screen,
if (asprintf(&vs_prog_string,
vs_template,
str(version_string),
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n" : "",
str(defines),
str(prim->vs_vars),
str(fill->vs_vars),
@ -302,6 +312,7 @@ glamor_build_program(ScreenPtr screen,
if (asprintf(&fs_prog_string,
fs_template,
str(version_string),
gpu_shader4 ? "#extension GL_EXT_gpu_shader4 : require\n#define texelFetch texelFetch2D\n#define uint unsigned int\n" : "",
str(defines),
str(prim->fs_vars),
str(fill->fs_vars),

View File

@ -69,7 +69,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
glamor_bounds_union_rect(&bounds, &prect[i]);
}
if (glamor_priv->glsl_version >= 130) {
if (glamor_glsl_has_ints(glamor_priv)) {
prog = glamor_use_program_fill(pixmap, gc,
&glamor_priv->poly_fill_rect_program,
&glamor_facet_polyfillrect_130);
@ -151,7 +151,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
scissor.y1 + off_y,
scissor.x2 - scissor.x1,
scissor.y2 - scissor.y1);
if (glamor_priv->glsl_version >= 130)
if (glamor_glsl_has_ints(glamor_priv))
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nrect);
else {
glamor_glDrawArrays_GL_QUADS(glamor_priv, nrect);
@ -163,7 +163,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
bail:
glDisable(GL_SCISSOR_TEST);
if (glamor_priv->glsl_version >= 130) {
if (glamor_glsl_has_ints(glamor_priv)) {
glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);

View File

@ -560,8 +560,8 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
case PictFilterGood:
case PictFilterBest:
case PictFilterBilinear:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
break;
}

View File

@ -64,7 +64,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
glamor_make_current(glamor_priv);
if (glamor_priv->glsl_version >= 130) {
if (glamor_glsl_has_ints(glamor_priv)) {
prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
&glamor_facet_fillspans_130);
@ -134,7 +134,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
box->x2 - box->x1,
box->y2 - box->y1);
box++;
if (glamor_priv->glsl_version >= 130)
if (glamor_glsl_has_ints(glamor_priv))
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, n);
else {
glamor_glDrawArrays_GL_QUADS(glamor_priv, n);
@ -146,7 +146,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
bail:
glDisable(GL_SCISSOR_TEST);
if (glamor_priv->glsl_version >= 130)
if (glamor_glsl_has_ints(glamor_priv))
glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);

View File

@ -732,5 +732,9 @@ glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
}
}
static inline Bool
glamor_glsl_has_ints(glamor_screen_private *glamor_priv) {
return glamor_priv->glsl_version >= 130 || glamor_priv->use_gpu_shader4;
}
#endif

View File

@ -380,15 +380,15 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[0]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[1]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@ -397,8 +397,8 @@ glamor_xv_render(glamor_port_private *port_priv, int id)
case FOURCC_I420:
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, src_pixmap_priv[2]->fbo->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
break;

View File

@ -487,8 +487,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
__GLXscreen *pGlxScreen;
int rc;
if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
DixWriteAccess, &pGlxDraw, &rc)) {
rc = dixLookupResourceByType((void **)&pGlxDraw, drawId,
__glXDrawableRes, client, DixWriteAccess);
if (rc == Success &&
/* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable.
* Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is
* an X window, but the client has already created a GLXWindow
* associated with it, so we don't want to create another one. */
(pGlxDraw->drawId == drawId ||
pGlxDraw->type == GLX_DRAWABLE_WINDOW)) {
if (glxc != NULL &&
glxc->config != NULL &&
glxc->config != pGlxDraw->config) {
@ -655,11 +662,12 @@ xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId,
glxc->readPriv = NULL;
return __glXError(GLXBadContext);
}
glxc->currentClient = client;
glxServer.setContextTagPrivate(client, newContextTag, glxc);
}
glxServer.setContextTagPrivate(client, newContextTag, glxc);
if (glxc)
glxc->currentClient = client;
if (prevglxc) {
prevglxc->currentClient = NULL;
if (!prevglxc->idExists) {
@ -985,7 +993,6 @@ __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
/* Pad with zeroes, so that attributes count is constant. */
while (p < GLX_VIS_CONFIG_TOTAL) {
buf[p++] = 0;
buf[p++] = 0;
}
assert(p == GLX_VIS_CONFIG_TOTAL);
@ -1874,7 +1881,7 @@ DoGetDrawableAttributes(__GLXclientState * cl, XID drawId)
int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client,
DixGetAttrAccess);
if (err != Success)
return error;
return __glXError(GLXBadDrawable);
}
if (pGlxDraw)
pDraw = pGlxDraw->pDraw;

View File

@ -79,5 +79,7 @@ if build_glx
],
)
install_data(hdrs_vnd, install_dir : xorgsdkdir)
if build_xorg
install_data(hdrs_vnd, install_dir : xorgsdkdir)
endif
endif

View File

@ -92,6 +92,9 @@ static void SetReplyHeader(ClientPtr client, void *replyPtr)
xGenericReply *rep = (xGenericReply *) replyPtr;
rep->type = X_Reply;
rep->sequenceNumber = client->sequence;
if (client->swapped) {
swaps(&rep->sequenceNumber);
}
rep->length = 0;
}

View File

@ -38,23 +38,20 @@ AM_CFLAGS = \
bin_PROGRAMS = xdmxconfig vdltodmx dmxtodmx
xdmxconfig_DEPENDENCIES = libdmxconfig.a
xdmxconfig_SOURCES = \
xdmxconfig.c \
$(top_srcdir)/hw/dmx/dmxlog.c \
Canvas.c \
Canvas.h \
CanvasP.h
xdmxconfig_LDADD = -L. -ldmxconfig @XDMXCONFIG_DEP_LIBS@
xdmxconfig_LDADD = libdmxconfig.a @XDMXCONFIG_DEP_LIBS@
xdmxconfig_CFLAGS = $(AM_CFLAGS) @XDMXCONFIG_DEP_CFLAGS@
vdltodmx_DEPENDENCIES = libdmxconfig.a
vdltodmx_SOURCES = vdltodmx.c
vdltodmx_LDADD = -L. -ldmxconfig
vdltodmx_LDADD = libdmxconfig.a
dmxtodmx_DEPENDENCIES = libdmxconfig.a
dmxtodmx_SOURCES = dmxtodmx.c
dmxtodmx_LDADD = -L. -ldmxconfig
dmxtodmx_LDADD = libdmxconfig.a
EXTRA_DIST = \
test-a.in test-a.out \

View File

@ -72,7 +72,6 @@ typedef struct DMXConfigCmdStruct {
DMXConfigList *xinputs;
} DMXConfigCmd, *DMXConfigCmdPtr;
extern DMXConfigEntryPtr dmxConfigEntry;
static DMXConfigCmd dmxConfigCmd;
static int dmxDisplaysFromCommandLine;

View File

@ -65,7 +65,6 @@ extern FILE *yyin;
#define DMX_CANVAS_WIDTH 400
#define DMX_CANVAS_HEIGHT 500
extern DMXConfigEntryPtr dmxConfigEntry;
static DMXConfigVirtualPtr dmxConfigCurrent, dmxConfigNewVirtual;
static DMXConfigDisplayPtr dmxConfigCurrentDisplay, dmxConfigNewDisplay;
static int dmxConfigGrabbed, dmxConfigGrabbedFine;

View File

@ -68,9 +68,6 @@
* _any_ header files. */
extern FontPtr defaultFont;
/* Hack to get Present to build (present requires RandR) */
RESTYPE RRCrtcType;
/** This routine provides information to the DMX protocol extension
* about a particular screen. */
Bool

View File

@ -109,8 +109,6 @@ Bool dmxGLXSyncSwap = FALSE;
Bool dmxGLXFinishSwap = FALSE;
#endif
RESTYPE RRProviderType = 0;
Bool dmxIgnoreBadFontPaths = FALSE;
Bool dmxAddRemoveScreens = FALSE;

37
hw/dmx/doc/meson.build Normal file
View File

@ -0,0 +1,37 @@
if build_docs_devel
foreach basename : ['dmx', 'scaled']
input_xml = basename + '.xml'
custom_target(
basename + '.html',
output: basename + '.html',
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
'-o', meson.current_build_dir(),
'xhtml-nochunks', '@INPUT0@'],
build_by_default: true,
install: false,
)
if build_docs_pdf
foreach format : ['ps', 'pdf']
output_fn = basename + '.' + format
custom_target(
output_fn,
output: output_fn,
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
'-o', meson.current_build_dir(),
'--with-fop', format, '@INPUT0@'],
build_by_default: true,
install: false,
)
endforeach
endif
endforeach
endif

View File

@ -27,7 +27,7 @@ srcs = [
subdir('config')
subdir('input')
subdir('examples')
# XXX: subdir('doc')
subdir('doc')
# XXX: subdir('doxygen')
install_man(configure_file(

View File

@ -106,6 +106,37 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only)
return foundScreen;
}
static screenLayoutPtr
xf86BusConfigMatch(ScrnInfoPtr scrnInfo, Bool is_gpu) {
screenLayoutPtr layout;
int i, j;
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
layout++) {
for (i = 0; i < scrnInfo->numEntities; i++) {
GDevPtr dev =
xf86GetDevFromEntity(scrnInfo->entityList[i],
scrnInfo->entityInstanceList[i]);
if (is_gpu) {
for (j = 0; j < layout->screen->num_gpu_devices; j++) {
if (dev == layout->screen->gpu_devices[j]) {
/* A match has been found */
return layout;
}
}
} else {
if (dev == layout->screen->device) {
/* A match has been found */
return layout;
}
}
}
}
return NULL;
}
/**
* @return TRUE if all buses are configured and set up correctly and FALSE
* otherwise.
@ -114,7 +145,7 @@ Bool
xf86BusConfig(void)
{
screenLayoutPtr layout;
int i, j;
int i;
/*
* 3 step probe to (hopefully) ensure that we always find at least 1
@ -170,27 +201,10 @@ xf86BusConfig(void)
*
*/
for (i = 0; i < xf86NumScreens; i++) {
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
layout++) {
Bool found = FALSE;
for (j = 0; j < xf86Screens[i]->numEntities; j++) {
GDevPtr dev =
xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
xf86Screens[i]->entityInstanceList[j]);
if (dev == layout->screen->device) {
/* A match has been found */
xf86Screens[i]->confScreen = layout->screen;
found = TRUE;
break;
}
}
if (found)
break;
}
if (layout->screen == NULL) {
layout = xf86BusConfigMatch(xf86Screens[i], FALSE);
if (layout && layout->screen)
xf86Screens[i]->confScreen = layout->screen;
else {
/* No match found */
xf86Msg(X_ERROR,
"Screen %d deleted because of no matching config section.\n",
@ -199,9 +213,12 @@ xf86BusConfig(void)
}
}
/* bind GPU conf screen to protocol screen 0 */
for (i = 0; i < xf86NumGPUScreens; i++)
xf86GPUScreens[i]->confScreen = xf86Screens[0]->confScreen;
/* bind GPU conf screen to the configured protocol screen, or 0 if not configured */
for (i = 0; i < xf86NumGPUScreens; i++) {
layout = xf86BusConfigMatch(xf86GPUScreens[i], TRUE);
int scrnum = (layout && layout->screen) ? layout->screen->screennum : 0;
xf86GPUScreens[i]->confScreen = xf86Screens[scrnum]->confScreen;
}
/* If no screens left, return now. */
if (xf86NumScreens == 0) {
@ -296,7 +313,8 @@ xf86IsEntityPrimary(int entityIndex)
#ifdef XSERVER_LIBPCIACCESS
if (primaryBus.type == BUS_PLATFORM && pEnt->bus.type == BUS_PCI)
return MATCH_PCI_DEVICES(pEnt->bus.id.pci, primaryBus.id.plat->pdev);
if (primaryBus.id.plat->pdev)
return MATCH_PCI_DEVICES(pEnt->bus.id.pci, primaryBus.id.plat->pdev);
#endif
if (primaryBus.type != pEnt->bus.type)
@ -527,8 +545,8 @@ xf86GetDevFromEntity(int entityIndex, int instance)
for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
if (xf86Entities[entityIndex]->devices[i]->screen == instance)
break;
return xf86Entities[entityIndex]->devices[i];
return xf86Entities[entityIndex]->devices[i];
return NULL;
}
/*

View File

@ -1738,15 +1738,34 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
if (auto_gpu_device && conf_screen->num_gpu_devices == 0 &&
xf86configptr->conf_device_lst) {
XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next;
/* Loop through the entire device list and skip the primary device
* assigned to the screen. This is important because there are two
* cases where the assigned primary device is not the first device in
* the device list. Firstly, if the first device in the list is assigned
* to a different seat than this X server, it will not have been picked
* by the previous FIND_SUITABLE. Secondly, if the device was explicitly
* assigned in the config but there is still only one screen, this code
* path is executed but the explicitly assigned device may not be the
* first device in the list. */
XF86ConfDevicePtr ptmp, sdevice = xf86configptr->conf_device_lst;
for (i = 0; i < MAX_GPUDEVICES; i++) {
if (!sdevice)
break;
FIND_SUITABLE (XF86ConfDevicePtr, sdevice, conf_screen->scrn_gpu_devices[i]);
if (!conf_screen->scrn_gpu_devices[i])
FIND_SUITABLE (XF86ConfDevicePtr, sdevice, ptmp);
if (!ptmp)
break;
/* skip the primary device on the screen */
if (ptmp != conf_screen->scrn_device) {
conf_screen->scrn_gpu_devices[i] = ptmp;
} else {
sdevice = ptmp->list.next;
i--; /* run the next iteration with the same index */
continue;
}
screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
screenp->gpu_devices[i]->myScreenSection = screenp;
@ -1775,31 +1794,30 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
count++;
dispptr = (XF86ConfDisplayPtr) dispptr->list.next;
}
screenp->displays = xnfallocarray(count, sizeof(DispRec));
screenp->displays = xnfallocarray(count, sizeof(DispPtr));
screenp->numdisplays = count;
/* Fill in the default Virtual size, if any */
if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
for (count = 0, dispptr = conf_screen->scrn_display_lst;
dispptr;
dispptr = (XF86ConfDisplayPtr) dispptr->list.next, count++) {
screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
}
}
for (count = 0, dispptr = conf_screen->scrn_display_lst;
dispptr;
dispptr = (XF86ConfDisplayPtr) dispptr->list.next, count++) {
/* Now do the per-Display Virtual sizes */
count = 0;
dispptr = conf_screen->scrn_display_lst;
while (dispptr) {
configDisplay(&(screenp->displays[count]), dispptr);
count++;
dispptr = (XF86ConfDisplayPtr) dispptr->list.next;
/* Allocate individual Display records */
screenp->displays[count] = xnfcalloc(1, sizeof(DispRec));
/* Fill in the default Virtual size, if any */
if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
screenp->displays[count]->virtualX = conf_screen->scrn_virtualX;
screenp->displays[count]->virtualY = conf_screen->scrn_virtualY;
}
/* Now do the per-Display Virtual sizes */
configDisplay(screenp->displays[count], dispptr);
}
/*
* figure out how many videoadaptor references there are and fill them in
*/
count = 0;
conf_adaptor = conf_screen->scrn_adaptor_lst;
while (conf_adaptor) {
count++;

View File

@ -55,6 +55,7 @@
#include "xf86Xinput.h"
#include "xf86InPriv.h"
#include "mivalidate.h"
#include "xf86Crtc.h"
/* For xf86GetClocks */
#if defined(CSRG_BASED) || defined(__GNU__)
@ -526,8 +527,8 @@ xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
* Find the Display subsection matching the depth/fbbpp and initialise
* scrp->display with it.
*/
for (i = 0, disp = scrp->confScreen->displays;
i < scrp->confScreen->numdisplays; i++, disp++) {
for (i = 0; i < scrp->confScreen->numdisplays; i++) {
disp = scrp->confScreen->displays[i];
if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
|| (disp->depth == scrp->depth && disp->fbbpp <= 0)
|| (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
@ -541,8 +542,8 @@ xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
* depth or fbbpp specified.
*/
if (i == scrp->confScreen->numdisplays) {
for (i = 0, disp = scrp->confScreen->displays;
i < scrp->confScreen->numdisplays; i++, disp++) {
for (i = 0; i < scrp->confScreen->numdisplays; i++) {
disp = scrp->confScreen->displays[i];
if (disp->depth <= 0 && disp->fbbpp <= 0) {
scrp->display = disp;
break;
@ -557,24 +558,25 @@ xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
scrp->confScreen->numdisplays++;
scrp->confScreen->displays =
xnfreallocarray(scrp->confScreen->displays,
scrp->confScreen->numdisplays, sizeof(DispRec));
scrp->confScreen->numdisplays, sizeof(DispPtr));
xf86DrvMsg(scrp->scrnIndex, X_INFO,
"Creating default Display subsection in Screen section\n"
"\t\"%s\" for depth/fbbpp %d/%d\n",
scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
scrp->confScreen->displays[i].blackColour.red = -1;
scrp->confScreen->displays[i].blackColour.green = -1;
scrp->confScreen->displays[i].blackColour.blue = -1;
scrp->confScreen->displays[i].whiteColour.red = -1;
scrp->confScreen->displays[i].whiteColour.green = -1;
scrp->confScreen->displays[i].whiteColour.blue = -1;
scrp->confScreen->displays[i].defaultVisual = -1;
scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
scrp->confScreen->displays[i].modes[0] = NULL;
scrp->confScreen->displays[i].depth = depth;
scrp->confScreen->displays[i].fbbpp = fbbpp;
scrp->display = &scrp->confScreen->displays[i];
scrp->confScreen->displays[i] = xnfcalloc(1, sizeof(DispRec));
memset(scrp->confScreen->displays[i], 0, sizeof(DispRec));
scrp->confScreen->displays[i]->blackColour.red = -1;
scrp->confScreen->displays[i]->blackColour.green = -1;
scrp->confScreen->displays[i]->blackColour.blue = -1;
scrp->confScreen->displays[i]->whiteColour.red = -1;
scrp->confScreen->displays[i]->whiteColour.green = -1;
scrp->confScreen->displays[i]->whiteColour.blue = -1;
scrp->confScreen->displays[i]->defaultVisual = -1;
scrp->confScreen->displays[i]->modes = xnfalloc(sizeof(char *));
scrp->confScreen->displays[i]->modes[0] = NULL;
scrp->confScreen->displays[i]->depth = depth;
scrp->confScreen->displays[i]->fbbpp = fbbpp;
scrp->display = scrp->confScreen->displays[i];
}
/*
@ -729,9 +731,9 @@ xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
scrp->mask.red = mask.red;
scrp->mask.green = mask.green;
scrp->mask.blue = mask.blue;
scrp->offset.red = ffs(mask.red);
scrp->offset.green = ffs(mask.green);
scrp->offset.blue = ffs(mask.blue);
scrp->offset.red = ffs(mask.red) - 1;
scrp->offset.green = ffs(mask.green) - 1;
scrp->offset.blue = ffs(mask.blue) - 1;
}
return TRUE;
}
@ -850,8 +852,9 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
{
MessageType from = X_DEFAULT;
xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
int ddcWidthmm, ddcHeightmm;
int probedWidthmm, probedHeightmm;
int widthErr, heightErr;
xf86OutputPtr compat = xf86CompatOutput(pScrn);
/* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
pScrn->widthmm = pScrn->monitor->widthmm;
@ -861,11 +864,15 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
/* DDC gives display size in mm for individual modes,
* but cm for monitor
*/
ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
probedWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
probedHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
}
else if (compat && compat->mm_width > 0 && compat->mm_height > 0) {
probedWidthmm = compat->mm_width;
probedHeightmm = compat->mm_height;
}
else {
ddcWidthmm = ddcHeightmm = 0;
probedWidthmm = probedHeightmm = 0;
}
if (monitorResolution > 0) {
@ -891,15 +898,15 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
pScrn->widthmm, pScrn->heightmm);
/* Warn if config and probe disagree about display size */
if (ddcWidthmm && ddcHeightmm) {
if (probedWidthmm && probedHeightmm) {
if (pScrn->widthmm > 0) {
widthErr = abs(ddcWidthmm - pScrn->widthmm);
widthErr = abs(probedWidthmm - pScrn->widthmm);
}
else {
widthErr = 0;
}
if (pScrn->heightmm > 0) {
heightErr = abs(ddcHeightmm - pScrn->heightmm);
heightErr = abs(probedHeightmm - pScrn->heightmm);
}
else {
heightErr = 0;
@ -908,17 +915,17 @@ xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
/* Should include config file name for monitor here */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
ddcWidthmm, ddcHeightmm, pScrn->widthmm,
probedWidthmm, probedHeightmm, pScrn->widthmm,
pScrn->heightmm);
}
}
}
else if (ddcWidthmm && ddcHeightmm) {
else if (probedWidthmm && probedHeightmm) {
from = X_PROBED;
xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
ddcWidthmm, ddcHeightmm);
pScrn->widthmm = ddcWidthmm;
pScrn->heightmm = ddcHeightmm;
probedWidthmm, probedHeightmm);
pScrn->widthmm = probedWidthmm;
pScrn->heightmm = probedHeightmm;
if (pScrn->widthmm > 0) {
pScrn->xDpi =
(int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);

View File

@ -209,9 +209,11 @@ xf86AutoConfigOutputDevices(void)
if (!xf86Info.autoBindGPU)
return;
for (i = 0; i < xf86NumGPUScreens; i++)
for (i = 0; i < xf86NumGPUScreens; i++) {
int scrnum = xf86GPUScreens[i]->confScreen->screennum;
RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
xf86ScrnToScreen(xf86Screens[0]));
xf86ScrnToScreen(xf86Screens[scrnum]));
}
}
static void
@ -689,8 +691,10 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
}
}
for (i = 0; i < xf86NumGPUScreens; i++)
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
for (i = 0; i < xf86NumGPUScreens; i++) {
int scrnum = xf86GPUScreens[i]->confScreen->screennum;
AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen);
}
xf86AutoConfigOutputDevices();

View File

@ -75,7 +75,7 @@
*/
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(25, 2)
#define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 2)
#define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 4)
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(10, 0)
#define MODINFOSTRING1 0xef23fdc5

View File

@ -1590,6 +1590,58 @@ xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid, uint16_t type,
QueueTouchEvents(dev, type, touchid, flags, mask);
}
/**
* Post a gesture pinch event. The driver is responsible for maintaining the
* correct event sequence (GesturePinchBegin, GesturePinchUpdate,
* GesturePinchEnd).
*
* @param dev The device to post the event for
* @param type One of XI_GesturePinchBegin, XI_GesturePinchUpdate,
* XI_GesturePinchEnd
* @param num_touches The number of touches in the gesture
* @param flags Flags for this event
* @param delta_x,delta_y accelerated relative motion delta
* @param delta_unaccel_x,delta_unaccel_y unaccelerated relative motion delta
* @param scale absolute scale of a pinch gesture
* @param delta_angle the ange delta in degrees between the last and the current pinch event.
*/
void
xf86PostGesturePinchEvent(DeviceIntPtr dev, uint16_t type,
uint16_t num_touches, uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x,
double delta_unaccel_y,
double scale, double delta_angle)
{
QueueGesturePinchEvents(dev, type, num_touches, flags, delta_x, delta_y,
delta_unaccel_x, delta_unaccel_y,
scale, delta_angle);
}
/**
* Post a gesture swipe event. The driver is responsible for maintaining the
* correct event sequence (GestureSwipeBegin, GestureSwipeUpdate,
* GestureSwipeEnd).
*
* @param dev The device to post the event for
* @param type One of XI_GestureSwipeBegin, XI_GestureSwipeUpdate,
* XI_GestureSwipeEnd
* @param num_touches The number of touches in the gesture
* @param flags Flags for this event
* @param delta_x,delta_y accelerated relative motion delta
* @param delta_unaccel_x,delta_unaccel_y unaccelerated relative motion delta
*/
void
xf86PostGestureSwipeEvent(DeviceIntPtr dev, uint16_t type,
uint16_t num_touches, uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x,
double delta_unaccel_y)
{
QueueGestureSwipeEvents(dev, type, num_touches, flags, delta_x, delta_y,
delta_unaccel_x, delta_unaccel_y);
}
void
xf86InputEnableVTProbe(void)
{

View File

@ -158,6 +158,20 @@ extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device,
extern _X_EXPORT void xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid,
uint16_t type, uint32_t flags,
const ValuatorMask *mask);
extern _X_EXPORT void xf86PostGesturePinchEvent(DeviceIntPtr dev, uint16_t type,
uint16_t num_touches,
uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x,
double delta_unaccel_y,
double scale, double delta_angle);
extern _X_EXPORT void xf86PostGestureSwipeEvent(DeviceIntPtr dev, uint16_t type,
uint16_t num_touches,
uint32_t flags,
double delta_x, double delta_y,
double delta_unaccel_x,
double delta_unaccel_y);
extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max,
int from_min);

View File

@ -365,10 +365,12 @@ xf86MergeOutputClassOptions(int entityIndex, void **options)
break;
case BUS_PCI:
for (i = 0; i < xf86_num_platform_devices; i++) {
if (MATCH_PCI_DEVICES(xf86_platform_devices[i].pdev,
entity->bus.id.pci)) {
dev = &xf86_platform_devices[i];
break;
if (xf86_platform_devices[i].pdev) {
if (MATCH_PCI_DEVICES(xf86_platform_devices[i].pdev,
entity->bus.id.pci)) {
dev = &xf86_platform_devices[i];
break;
}
}
}
break;
@ -606,7 +608,7 @@ xf86platformAddGPUDevices(DriverPtr drvp)
int
xf86platformAddDevice(int index)
{
int i, old_screens, scr_index;
int i, old_screens, scr_index, scrnum;
DriverPtr drvp = NULL;
screenLayoutPtr layout;
static const char *hotplug_driver_name = "modesetting";
@ -672,14 +674,15 @@ xf86platformAddDevice(int index)
xf86NumGPUScreens = old_screens;
return -1;
}
/* attach unbound to 0 protocol screen */
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
/* attach unbound to the configured protocol screen (or 0) */
scrnum = xf86GPUScreens[i]->confScreen->screennum;
AttachUnboundGPU(xf86Screens[scrnum]->pScreen, xf86GPUScreens[i]->pScreen);
if (xf86Info.autoBindGPU)
RRProviderAutoConfigGpuScreen(xf86ScrnToScreen(xf86GPUScreens[i]),
xf86ScrnToScreen(xf86Screens[0]));
xf86ScrnToScreen(xf86Screens[scrnum]));
RRResourcesChanged(xf86Screens[0]->pScreen);
RRTellChanged(xf86Screens[0]->pScreen);
RRResourcesChanged(xf86Screens[scrnum]->pScreen);
RRTellChanged(xf86Screens[scrnum]->pScreen);
return 0;
}
@ -688,7 +691,7 @@ void
xf86platformRemoveDevice(int index)
{
EntityPtr entity;
int ent_num, i, j;
int ent_num, i, j, scrnum;
Bool found;
for (ent_num = 0; ent_num < xf86NumEntities; ent_num++) {
@ -715,6 +718,8 @@ xf86platformRemoveDevice(int index)
goto out;
}
scrnum = xf86GPUScreens[i]->confScreen->screennum;
xf86GPUScreens[i]->pScreen->CloseScreen(xf86GPUScreens[i]->pScreen);
RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
@ -724,8 +729,8 @@ xf86platformRemoveDevice(int index)
xf86_remove_platform_device(index);
RRResourcesChanged(xf86Screens[0]->pScreen);
RRTellChanged(xf86Screens[0]->pScreen);
RRResourcesChanged(xf86Screens[scrnum]->pScreen);
RRTellChanged(xf86Screens[scrnum]->pScreen);
out:
return;
}

View File

@ -351,7 +351,7 @@ typedef struct _confscreenrec {
MonPtr monitor;
GDevPtr device;
int numdisplays;
DispPtr displays;
DispPtr *displays;
int numxvadaptors;
confXvAdaptorPtr xvadaptors;
void *options;

View File

@ -768,7 +768,7 @@ gtf_supported(xf86MonPtr mon)
} else {
for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_timing_des = &(mon->det_mon[i]);
if (det_timing_des && (det_timing_des->type == DS_RANGES) &&
if (det_timing_des && (det_timing_des->type == DS_RANGES) && (mon->features.msc & 0x1) &&
(det_timing_des->section.ranges.display_range_timing_flags == DR_DEFAULT_GTF
|| det_timing_des->section.ranges.display_range_timing_flags == DR_SECONDARY_GTF))
return TRUE;

View File

@ -0,0 +1,35 @@
if build_docs_devel
basename = 'ddxDesign'
input_xml = basename + '.xml'
custom_target(
basename + '.html',
output: basename + '.html',
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-xhtml.xsl'),
'-o', meson.current_build_dir(),
'xhtml-nochunks', '@INPUT0@'],
build_by_default: true,
install: false,
)
if build_docs_pdf
foreach format : ['ps', 'pdf']
output_fn = basename + '.' + format
custom_target(
output_fn,
output: output_fn,
input: [input_xml],
command: [xmlto] + docs_xmlto_search_flags + [
'-x', join_paths(doc_stylesheet_srcdir, 'xorg-fo.xsl'),
'--stringparam', 'img.src.path=' + meson.current_build_dir(),
'-o', meson.current_build_dir(),
'--with-fop', format, '@INPUT0@'],
build_by_default: true,
install: false,
)
endforeach
endif
endif

View File

@ -239,3 +239,14 @@ CHIPSET(0x4500, ehl_4x8, "Intel(R) HD Graphics (Elkhart Lake 4x8)")
CHIPSET(0x4571, ehl_4x8, "Intel(R) HD Graphics (Elkhart Lake 4x8)")
CHIPSET(0x4551, ehl_4x4, "Intel(R) HD Graphics (Elkhart Lake 4x4)")
CHIPSET(0x4541, ehl_2x4, "Intel(R) HD Graphics (Elkhart Lake 2x4)")
CHIPSET(0x9A40, tgl_1x6x16, "Intel(R) HD Graphics (Tigerlake 1x6x16 GT2)")
CHIPSET(0x9A49, tgl_1x6x16, "Intel(R) HD Graphics (Tigerlake 1x6x16 GT2)")
CHIPSET(0x9A59, tgl_1x6x16, "Intel(R) HD Graphics (Tigerlake 1x6x16 GT2)")
CHIPSET(0x9A60, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT1)")
CHIPSET(0x9A68, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT1)")
CHIPSET(0x9A70, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT1)")
CHIPSET(0x9A78, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT1)")
CHIPSET(0x9AC0, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT2)")
CHIPSET(0x9AC9, tg1_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT2)")
CHIPSET(0x9AD9, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1x2x16 GT2)")
CHIPSET(0x9AF8, tgl_1x2x16, "Intel(R) HD Graphics (Tigerlake 1X2X16 GT2)")

View File

@ -31,7 +31,7 @@ extern "C" {
#include <stdint.h>
#define XF86IT_PROTOCOL_VERSION_MAJOR 1
#define XF86IT_PROTOCOL_VERSION_MINOR 0
#define XF86IT_PROTOCOL_VERSION_MINOR 1
enum xf86ITResponseType {
XF86IT_RESPONSE_SERVER_VERSION,
@ -70,6 +70,8 @@ enum xf86ITEventType {
XF86IT_EVENT_BUTTON,
XF86IT_EVENT_KEY,
XF86IT_EVENT_TOUCH,
XF86IT_EVENT_GESTURE_PINCH,
XF86IT_EVENT_GESTURE_SWIPE,
};
typedef struct {
@ -127,6 +129,30 @@ typedef struct {
xf86ITValuatorData valuators;
} xf86ITEventTouch;
typedef struct {
xf86ITEventHeader header;
uint16_t gesture_type;
uint16_t num_touches;
uint32_t flags;
double delta_x;
double delta_y;
double delta_unaccel_x;
double delta_unaccel_y;
double scale;
double delta_angle;
} xf86ITEventGesturePinch;
typedef struct {
xf86ITEventHeader header;
uint16_t gesture_type;
uint16_t num_touches;
uint32_t flags;
double delta_x;
double delta_y;
double delta_unaccel_x;
double delta_unaccel_y;
} xf86ITEventGestureSwipe;
typedef union {
xf86ITEventHeader header;
xf86ITEventClientVersion version;
@ -135,6 +161,8 @@ typedef union {
xf86ITEventButton button;
xf86ITEventKey key;
xf86ITEventTouch touch;
xf86ITEventGesturePinch pinch;
xf86ITEventGestureSwipe swipe;
} xf86ITEventAny;
#ifdef __cplusplus

View File

@ -58,6 +58,7 @@
enum xf86ITDeviceType {
DEVICE_KEYBOARD = 1,
DEVICE_POINTER,
DEVICE_POINTER_GESTURE,
DEVICE_POINTER_ABS,
DEVICE_POINTER_ABS_PROXIMITY,
DEVICE_TOUCH,
@ -474,6 +475,14 @@ init_touch(InputInfoPtr pInfo)
InitTouchClassDeviceStruct(dev, ntouches, XIDirectTouch, 2);
}
static void
init_gesture(InputInfoPtr pInfo)
{
DeviceIntPtr dev = pInfo->dev;
int ntouches = TOUCH_MAX_SLOTS;
InitGestureClassDeviceStruct(dev, ntouches);
}
static void
device_init(DeviceIntPtr dev)
{
@ -489,6 +498,10 @@ device_init(DeviceIntPtr dev)
case DEVICE_POINTER:
init_pointer(pInfo);
break;
case DEVICE_POINTER_GESTURE:
init_pointer(pInfo);
init_gesture(pInfo);
break;
case DEVICE_POINTER_ABS:
init_pointer_absolute(pInfo);
break;
@ -678,6 +691,37 @@ handle_touch(InputInfoPtr pInfo, xf86ITEventTouch *event)
xf86PostTouchEvent(dev, event->touchid, event->touch_type, 0, mask);
}
static void
handle_gesture_swipe(InputInfoPtr pInfo, xf86ITEventGestureSwipe *event)
{
DeviceIntPtr dev = pInfo->dev;
xf86ITDevicePtr driver_data = pInfo->private;
xf86IDrvMsg(pInfo, X_DEBUG, "Handling gesture swipe event\n");
driver_data->last_event_num++;
xf86PostGestureSwipeEvent(dev, event->gesture_type, event->num_touches, event->flags,
event->delta_x, event->delta_y,
event->delta_unaccel_x, event->delta_unaccel_y);
}
static void
handle_gesture_pinch(InputInfoPtr pInfo, xf86ITEventGesturePinch *event)
{
DeviceIntPtr dev = pInfo->dev;
xf86ITDevicePtr driver_data = pInfo->private;
xf86IDrvMsg(pInfo, X_DEBUG, "Handling gesture pinch event\n");
driver_data->last_event_num++;
xf86PostGesturePinchEvent(dev, event->gesture_type, event->num_touches, event->flags,
event->delta_x, event->delta_y,
event->delta_unaccel_x, event->delta_unaccel_y,
event->scale, event->delta_angle);
}
static void
client_new_handle_event(InputInfoPtr pInfo, xf86ITEventAny *event)
{
@ -715,6 +759,12 @@ client_ready_handle_event(InputInfoPtr pInfo, xf86ITEventAny *event)
case XF86IT_EVENT_TOUCH:
handle_touch(pInfo, &event->touch);
break;
case XF86IT_EVENT_GESTURE_PINCH:
handle_gesture_pinch(pInfo, &(event->pinch));
break;
case XF86IT_EVENT_GESTURE_SWIPE:
handle_gesture_swipe(pInfo, &(event->swipe));
break;
case XF86IT_EVENT_CLIENT_VERSION:
xf86IDrvMsg(pInfo, X_ERROR, "Only single ClientVersion event is allowed\n");
teardown_client_connection(pInfo);
@ -759,6 +809,8 @@ is_supported_event(enum xf86ITEventType type)
case XF86IT_EVENT_BUTTON:
case XF86IT_EVENT_KEY:
case XF86IT_EVENT_TOUCH:
case XF86IT_EVENT_GESTURE_PINCH:
case XF86IT_EVENT_GESTURE_SWIPE:
return true;
}
return false;
@ -775,6 +827,8 @@ get_event_size(enum xf86ITEventType type)
case XF86IT_EVENT_BUTTON: return sizeof(xf86ITEventButton);
case XF86IT_EVENT_KEY: return sizeof(xf86ITEventKey);
case XF86IT_EVENT_TOUCH: return sizeof(xf86ITEventTouch);
case XF86IT_EVENT_GESTURE_PINCH: return sizeof(xf86ITEventGesturePinch);
case XF86IT_EVENT_GESTURE_SWIPE: return sizeof(xf86ITEventGestureSwipe);
}
abort();
}
@ -864,6 +918,7 @@ get_type_name(InputInfoPtr pInfo, xf86ITDevicePtr driver_data)
switch (driver_data->device_type) {
case DEVICE_TOUCH: return XI_TOUCHSCREEN;
case DEVICE_POINTER: return XI_MOUSE;
case DEVICE_POINTER_GESTURE: return XI_TOUCHPAD;
case DEVICE_POINTER_ABS: return XI_MOUSE;
case DEVICE_POINTER_ABS_PROXIMITY: return XI_TABLET;
case DEVICE_KEYBOARD: return XI_KEYBOARD;
@ -986,6 +1041,8 @@ pre_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
driver_data->device_type = DEVICE_KEYBOARD;
} else if (strcmp(device_type_option, "Pointer") == 0) {
driver_data->device_type = DEVICE_POINTER;
} else if (strcmp(device_type_option, "PointerGesture") == 0) {
driver_data->device_type = DEVICE_POINTER_GESTURE;
} else if (strcmp(device_type_option, "PointerAbsolute") == 0) {
driver_data->device_type = DEVICE_POINTER_ABS;
} else if (strcmp(device_type_option, "PointerAbsoluteProximity") == 0) {

View File

@ -552,7 +552,7 @@ can_exchange(ScrnInfoPtr scrn, DrawablePtr draw,
return FALSE;
#endif
if (ms_crtc_on(config->crtc[i]))
if (xf86_crtc_on(config->crtc[i]))
num_crtcs_on++;
}

View File

@ -1933,28 +1933,41 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
"Failed to initialize the DRI2 extension.\n");
}
if (!(ms->drmmode.present_enable = ms_present_screen_init(pScreen))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize the Present extension.\n");
}
/* enable reverse prime if we are a GPU screen, and accelerated, and not
* i915. i915 is happy scanning out from sysmem. */
* i915, evdi or udl. i915 is happy scanning out from sysmem.
* evdi and udl are virtual drivers scanning out from sysmem
* backed dumb buffers.
*/
if (pScreen->isGPU) {
drmVersionPtr version;
/* enable if we are an accelerated GPU screen */
ms->drmmode.reverse_prime_offload_mode = TRUE;
/* disable if we detect i915 */
if ((version = drmGetVersion(ms->drmmode.fd))) {
if (!strncmp("i915", version->name, version->name_len)) {
ms->drmmode.reverse_prime_offload_mode = FALSE;
}
if (!strncmp("evdi", version->name, version->name_len)) {
ms->drmmode.reverse_prime_offload_mode = FALSE;
}
if (!strncmp("udl", version->name, version->name_len)) {
ms->drmmode.reverse_prime_offload_mode = FALSE;
}
if (!ms->drmmode.reverse_prime_offload_mode) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Disable reverse prime offload mode for %s.\n", version->name);
}
drmFreeVersion(version);
}
}
}
#endif
if (!(ms->drmmode.present_enable = ms_present_screen_init(pScreen))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize the Present extension.\n");
}
pScrn->vtSema = TRUE;

View File

@ -200,7 +200,7 @@ void ms_drm_abort(ScrnInfoPtr scrn,
void *match_data);
void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
Bool ms_crtc_on(xf86CrtcPtr crtc);
Bool xf86_crtc_on(xf86CrtcPtr crtc);
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
RRCrtcPtr ms_randr_crtc_covering_drawable(DrawablePtr pDraw);

View File

@ -2404,38 +2404,10 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
"Allocated crtc nr. %d to this screen.\n", num);
/* If the GAMMA_LUT property is available, replace the server's default
* gamma ramps with ones of the appropriate size. */
if (drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id) {
Bool try_gamma_lut =
xf86ReturnOptValBool(drmmode->Options, OPTION_USE_GAMMA_LUT, TRUE);
uint64_t size = drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value;
if (try_gamma_lut && size != crtc->gamma_size) {
uint16_t *gamma = malloc(3 * size * sizeof(uint16_t));
if (gamma) {
free(crtc->gamma_red);
crtc->gamma_size = size;
crtc->gamma_red = gamma;
crtc->gamma_green = gamma + size;
crtc->gamma_blue = gamma + size * 2;
drmmode_crtc->use_gamma_lut = TRUE;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
"Gamma ramp set to %ld entries on CRTC %d\n",
size, num);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Failed to allocate memory for %ld gamma ramp "
"entries on CRTC %d. Falling back to legacy "
"%d-entry mode.\n",
size, num, crtc->gamma_size);
}
}
}
drmmode_crtc->use_gamma_lut =
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id &&
drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value &&
xf86ReturnOptValBool(drmmode->Options, OPTION_USE_GAMMA_LUT, TRUE);
if (drmmode_crtc->use_gamma_lut &&
drmmode_crtc->props[DRMMODE_CRTC_CTM].prop_id) {
@ -3906,15 +3878,64 @@ drmmode_load_palette(ScrnInfoPtr pScrn, int numColors,
}
}
static Bool
drmmode_crtc_upgrade_lut(xf86CrtcPtr crtc, int num)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
uint64_t size;
if (!drmmode_crtc->use_gamma_lut)
return TRUE;
assert(drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].prop_id);
size = drmmode_crtc->props[DRMMODE_CRTC_GAMMA_LUT_SIZE].value;
if (size != crtc->gamma_size) {
ScrnInfoPtr pScrn = crtc->scrn;
uint16_t *gamma = malloc(3 * size * sizeof(uint16_t));
if (gamma) {
free(crtc->gamma_red);
crtc->gamma_size = size;
crtc->gamma_red = gamma;
crtc->gamma_green = gamma + size;
crtc->gamma_blue = gamma + size * 2;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
"Gamma ramp set to %ld entries on CRTC %d\n",
size, num);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to allocate memory for %ld gamma ramp entries "
"on CRTC %d.\n",
size, num);
return FALSE;
}
}
return TRUE;
}
Bool
drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Initializing kms color map for depth %d, %d bpc.\n",
pScrn->depth, pScrn->rgbBits);
if (!miCreateDefColormap(pScreen))
return FALSE;
/* If the GAMMA_LUT property is available, replace the server's default
* gamma ramps with ones of the appropriate size. */
for (i = 0; i < xf86_config->num_crtc; i++)
if (!drmmode_crtc_upgrade_lut(xf86_config->crtc[i], i))
return FALSE;
/* Adapt color map size and depth to color depth of screen. */
if (!xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, 10,
drmmode_load_palette, NULL,

View File

@ -167,7 +167,14 @@ do_queue_flip_on_crtc(modesettingPtr ms, xf86CrtcPtr crtc,
(void *) (uintptr_t) seq);
}
static Bool
enum queue_flip_status {
QUEUE_FLIP_SUCCESS,
QUEUE_FLIP_ALLOC_FAILED,
QUEUE_FLIP_QUEUE_ALLOC_FAILED,
QUEUE_FLIP_DRM_FLUSH_FAILED,
};
static int
queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
struct ms_flipdata *flipdata,
int ref_crtc_vblank_pipe, uint32_t flags)
@ -177,13 +184,10 @@ queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
struct ms_crtc_pageflip *flip;
uint32_t seq;
int err;
flip = calloc(1, sizeof(struct ms_crtc_pageflip));
if (flip == NULL) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"flip queue: carrier alloc failed.\n");
return FALSE;
return QUEUE_FLIP_ALLOC_FAILED;
}
/* Only the reference crtc will finally deliver its page flip
@ -195,24 +199,21 @@ queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
seq = ms_drm_queue_alloc(crtc, flip, ms_pageflip_handler, ms_pageflip_abort);
if (!seq) {
free(flip);
return FALSE;
return QUEUE_FLIP_QUEUE_ALLOC_FAILED;
}
/* take a reference on flipdata for use in flip */
flipdata->flip_count++;
while (do_queue_flip_on_crtc(ms, crtc, flags, seq)) {
err = errno;
/* We may have failed because the event queue was full. Flush it
* and retry. If there was nothing to flush, then we failed for
* some other reason and should just return an error.
*/
if (ms_flush_drm_events(screen) <= 0) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"flip queue failed: %s\n", strerror(err));
/* Aborting will also decrement flip_count and free(flip). */
ms_drm_abort_seq(scrn, seq);
return FALSE;
return QUEUE_FLIP_DRM_FLUSH_FAILED;
}
/* We flushed some events, so try again. */
@ -220,7 +221,77 @@ queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
}
/* The page flip succeeded. */
return TRUE;
return QUEUE_FLIP_SUCCESS;
}
#define MS_ASYNC_FLIP_LOG_ENABLE_LOGS_INTERVAL_MS 10000
#define MS_ASYNC_FLIP_LOG_FREQUENT_LOGS_INTERVAL_MS 1000
#define MS_ASYNC_FLIP_FREQUENT_LOG_COUNT 10
static void
ms_print_pageflip_error(int screen_index, const char *log_prefix,
int crtc_index, int flags, int err)
{
/* In certain circumstances we will have a lot of flip errors without a
* reasonable way to prevent them. In such case we reduce the number of
* logged messages to at least not fill the error logs.
*
* The details are as follows:
*
* At least on i915 hardware support for async page flip support depends
* on the used modifiers which themselves can change dynamically for a
* screen. This results in the following problems:
*
* - We can't know about whether a particular CRTC will be able to do an
* async flip without hardcoding the same logic as the kernel as there's
* no interface to query this information.
*
* - There is no way to give this information to an application, because
* the protocol of the present extension does not specify anything about
* changing of the capabilities on runtime or the need to re-query them.
*
* Even if the above was solved, the only benefit would be avoiding a
* roundtrip to the kernel and reduced amount of error logs. The former
* does not seem to be a good enough benefit compared to the amount of work
* that would need to be done. The latter is solved below. */
static CARD32 error_last_time_ms;
static int frequent_logs;
static Bool logs_disabled;
if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
CARD32 curr_time_ms = GetTimeInMillis();
int clocks_since_last_log = curr_time_ms - error_last_time_ms;
if (clocks_since_last_log >
MS_ASYNC_FLIP_LOG_ENABLE_LOGS_INTERVAL_MS) {
frequent_logs = 0;
logs_disabled = FALSE;
}
if (!logs_disabled) {
if (clocks_since_last_log <
MS_ASYNC_FLIP_LOG_FREQUENT_LOGS_INTERVAL_MS) {
frequent_logs++;
}
if (frequent_logs > MS_ASYNC_FLIP_FREQUENT_LOG_COUNT) {
xf86DrvMsg(screen_index, X_WARNING,
"%s: detected too frequent flip errors, disabling "
"logs until frequency is reduced\n", log_prefix);
logs_disabled = TRUE;
} else {
xf86DrvMsg(screen_index, X_WARNING,
"%s: queue async flip during flip on CRTC %d failed: %s\n",
log_prefix, crtc_index, strerror(err));
}
}
error_last_time_ms = curr_time_ms;
} else {
xf86DrvMsg(screen_index, X_WARNING,
"%s: queue flip during flip on CRTC %d failed: %s\n",
log_prefix, crtc_index, strerror(err));
}
}
@ -311,18 +382,32 @@ ms_do_pageflip(ScreenPtr screen,
* may never complete; this is a configuration error.
*/
for (i = 0; i < config->num_crtc; i++) {
enum queue_flip_status flip_status;
xf86CrtcPtr crtc = config->crtc[i];
if (!ms_crtc_on(crtc))
if (!xf86_crtc_on(crtc))
continue;
if (!queue_flip_on_crtc(screen, crtc, flipdata,
ref_crtc_vblank_pipe,
flags)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s: Queue flip on CRTC %d failed: %s\n",
log_prefix, i, strerror(errno));
goto error_undo;
flip_status = queue_flip_on_crtc(screen, crtc, flipdata,
ref_crtc_vblank_pipe,
flags);
switch (flip_status) {
case QUEUE_FLIP_ALLOC_FAILED:
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s: carrier alloc for queue flip on CRTC %d failed.\n",
log_prefix, i);
goto error_undo;
case QUEUE_FLIP_QUEUE_ALLOC_FAILED:
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s: entry alloc for queue flip on CRTC %d failed.\n",
log_prefix, i);
goto error_undo;
case QUEUE_FLIP_DRM_FLUSH_FAILED:
ms_print_pageflip_error(scrn->scrnIndex, log_prefix, i, flags, errno);
goto error_undo;
case QUEUE_FLIP_SUCCESS:
break;
}
}

View File

@ -259,7 +259,7 @@ ms_present_check_unflip(RRCrtcPtr crtc,
if (drmmode_crtc->rotate_bo.gbm)
return FALSE;
if (ms_crtc_on(config->crtc[i]))
if (xf86_crtc_on(config->crtc[i]))
num_crtcs_on++;
}
@ -272,6 +272,9 @@ ms_present_check_unflip(RRCrtcPtr crtc,
pixmap->devKind != drmmode_bo_get_pitch(&ms->drmmode.front_bo))
return FALSE;
if (!ms->drmmode.glamor)
return FALSE;
#ifdef GBM_BO_WITH_MODIFIERS
/* Check if buffer format/modifier is supported by all active CRTCs */
gbm = ms->glamor.gbm_bo_from_pixmap(screen, pixmap);

View File

@ -49,7 +49,7 @@
static struct xorg_list ms_drm_queue;
static uint32_t ms_drm_seq;
static void ms_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
static void box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
{
dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
@ -64,20 +64,7 @@ static void ms_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
}
static void ms_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
{
if (crtc->enabled) {
crtc_box->x1 = crtc->x;
crtc_box->x2 =
crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
crtc_box->y1 = crtc->y;
crtc_box->y2 =
crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
} else
crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
}
static void ms_randr_crtc_box(RRCrtcPtr crtc, BoxPtr crtc_box)
static void rr_crtc_box(RRCrtcPtr crtc, BoxPtr crtc_box)
{
if (crtc->mode) {
crtc_box->x1 = crtc->x;
@ -99,133 +86,44 @@ static void ms_randr_crtc_box(RRCrtcPtr crtc, BoxPtr crtc_box)
crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
}
static int ms_box_area(BoxPtr box)
static int box_area(BoxPtr box)
{
return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
}
static Bool rr_crtc_on(RRCrtcPtr crtc, Bool crtc_is_xf86_hint)
{
if (!crtc) {
return FALSE;
}
if (crtc_is_xf86_hint && crtc->devPrivate) {
return xf86_crtc_on(crtc->devPrivate);
} else {
return !!crtc->mode;
}
}
Bool
ms_crtc_on(xf86CrtcPtr crtc)
xf86_crtc_on(xf86CrtcPtr crtc)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn;
}
/*
* Return the first output which is connected to an active CRTC on this screen.
*
* RRFirstOutput() will return an output from a secondary screen if it is primary,
* which is not the behavior that ms_covering_crtc() wants.
*/
static RROutputPtr ms_first_output(ScreenPtr pScreen)
{
rrScrPriv(pScreen);
RROutputPtr output;
int i, j;
if (!pScrPriv)
return NULL;
if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc &&
(pScrPriv->primaryOutput->pScreen == pScreen)) {
return pScrPriv->primaryOutput;
}
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
for (j = 0; j < pScrPriv->numOutputs; j++) {
output = pScrPriv->outputs[j];
if (output->crtc == crtc)
return output;
}
}
return NULL;
}
/*
* Return the crtc covering 'box'. If two crtcs cover a portion of
* 'box', then prefer the crtc with greater coverage.
*/
static xf86CrtcPtr
ms_covering_xf86_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcPtr crtc, best_crtc;
int coverage, best_coverage;
int c;
BoxRec crtc_box, cover_box;
Bool crtc_on;
best_crtc = NULL;
best_coverage = 0;
if (!xf86_config)
return NULL;
for (c = 0; c < xf86_config->num_crtc; c++) {
crtc = xf86_config->crtc[c];
if (screen_is_ms)
crtc_on = ms_crtc_on(crtc);
else
crtc_on = crtc->enabled;
/* If the CRTC is off, treat it as not covering */
if (!crtc_on)
continue;
ms_crtc_box(crtc, &crtc_box);
ms_box_intersect(&cover_box, &crtc_box, box);
coverage = ms_box_area(&cover_box);
if (coverage > best_coverage) {
best_crtc = crtc;
best_coverage = coverage;
}
}
/* Fallback to primary crtc for drawable's on secondary outputs */
if (best_crtc == NULL && !pScreen->isGPU) {
RROutputPtr primary_output = NULL;
ScreenPtr secondary;
if (dixPrivateKeyRegistered(rrPrivKey))
primary_output = ms_first_output(scrn->pScreen);
if (!primary_output || !primary_output->crtc)
return NULL;
crtc = primary_output->crtc->devPrivate;
if (!ms_crtc_on(crtc))
return NULL;
xorg_list_for_each_entry(secondary, &pScreen->secondary_list, secondary_head) {
if (!secondary->is_output_secondary)
continue;
if (ms_covering_xf86_crtc(secondary, box, FALSE)) {
/* The drawable is on a secondary output, return primary crtc */
return crtc;
}
}
}
return best_crtc;
}
static RRCrtcPtr
ms_covering_randr_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
rr_crtc_covering_box(ScreenPtr pScreen, BoxPtr box, Bool screen_is_xf86_hint)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
rrScrPrivPtr pScrPriv;
RRCrtcPtr crtc, best_crtc;
int coverage, best_coverage;
int c;
BoxRec crtc_box, cover_box;
Bool crtc_on;
best_crtc = NULL;
best_coverage = 0;
@ -241,57 +139,47 @@ ms_covering_randr_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
for (c = 0; c < pScrPriv->numCrtcs; c++) {
crtc = pScrPriv->crtcs[c];
if (screen_is_ms) {
crtc_on = ms_crtc_on((xf86CrtcPtr) crtc->devPrivate);
} else {
crtc_on = !!crtc->mode;
}
/* If the CRTC is off, treat it as not covering */
if (!crtc_on)
if (!rr_crtc_on(crtc, screen_is_xf86_hint))
continue;
ms_randr_crtc_box(crtc, &crtc_box);
ms_box_intersect(&cover_box, &crtc_box, box);
coverage = ms_box_area(&cover_box);
rr_crtc_box(crtc, &crtc_box);
box_intersect(&cover_box, &crtc_box, box);
coverage = box_area(&cover_box);
if (coverage > best_coverage) {
best_crtc = crtc;
best_coverage = coverage;
}
}
/* Fallback to primary crtc for drawable's on secondary outputs */
if (best_crtc == NULL && !pScreen->isGPU) {
RROutputPtr primary_output = NULL;
return best_crtc;
}
static RRCrtcPtr
rr_crtc_covering_box_on_secondary(ScreenPtr pScreen, BoxPtr box)
{
if (!pScreen->isGPU) {
ScreenPtr secondary;
if (dixPrivateKeyRegistered(rrPrivKey))
primary_output = ms_first_output(scrn->pScreen);
if (!primary_output || !primary_output->crtc)
return NULL;
crtc = primary_output->crtc;
if (!ms_crtc_on((xf86CrtcPtr) crtc->devPrivate))
return NULL;
RRCrtcPtr crtc = NULL;
xorg_list_for_each_entry(secondary, &pScreen->secondary_list, secondary_head) {
if (!secondary->is_output_secondary)
continue;
if (ms_covering_randr_crtc(secondary, box, FALSE)) {
/* The drawable is on a secondary output, return primary crtc */
crtc = rr_crtc_covering_box(secondary, box, FALSE);
if (crtc)
return crtc;
}
}
}
return best_crtc;
return NULL;
}
xf86CrtcPtr
ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
{
ScreenPtr pScreen = pDraw->pScreen;
RRCrtcPtr crtc = NULL;
BoxRec box;
box.x1 = pDraw->x;
@ -299,13 +187,18 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
return ms_covering_xf86_crtc(pScreen, &box, TRUE);
crtc = rr_crtc_covering_box(pScreen, &box, TRUE);
if (crtc) {
return crtc->devPrivate;
}
return NULL;
}
RRCrtcPtr
ms_randr_crtc_covering_drawable(DrawablePtr pDraw)
{
ScreenPtr pScreen = pDraw->pScreen;
RRCrtcPtr crtc = NULL;
BoxRec box;
box.x1 = pDraw->x;
@ -313,7 +206,11 @@ ms_randr_crtc_covering_drawable(DrawablePtr pDraw)
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
return ms_covering_randr_crtc(pScreen, &box, TRUE);
crtc = rr_crtc_covering_box(pScreen, &box, TRUE);
if (!crtc) {
crtc = rr_crtc_covering_box_on_secondary(pScreen, &box);
}
return crtc;
}
static Bool

View File

@ -138,6 +138,12 @@ if get_option('xf86-input-inputtest')
subdir('drivers/inputtest')
endif
meson.add_install_script(
'sh', '-c',
'ln -fs Xorg @0@@1@'.format(
'${DESTDIR}',
join_paths(get_option('prefix'), get_option('bindir'), 'X')))
if get_option('suid_wrapper')
executable('Xorg.wrap',
'xorg-wrapper.c',
@ -146,25 +152,25 @@ if get_option('suid_wrapper')
c_args: xorg_c_args,
install: true,
install_dir: get_option('libexecdir'),
# install_mode: ['r-sr-xr-x', 0, 0],
install_mode: ['r-sr-xr-x', 0, 0],
)
configure_file(
# meson gets confused when there are two targets of the same name
# within the same directory, so we use a different intermediate name.
xorg_sh = configure_file(
input: 'Xorg.sh.in',
output: 'Xorg',
output: 'Xorg.sh',
configuration: conf_data,
)
install_data(
xorg_sh,
install_mode: 'rwxr-xr-x',
install_dir: join_paths(get_option('prefix'), get_option('bindir')),
rename: ['Xorg']
)
endif
executable('cvt',
['utils/cvt/cvt.c', 'modes/xf86cvt.c'],
include_directories: [inc, xorg_inc],
dependencies: xorg_deps,
link_with: libxserver_os,
c_args: xorg_c_args,
install: true,
)
executable('gtf',
'utils/gtf/gtf.c',
include_directories: [inc, xorg_inc],
@ -219,14 +225,10 @@ install_man(configure_file(
configuration: manpage_config,
))
install_man(configure_file(
input: 'utils/man/cvt.man',
output: 'cvt.1',
configuration: manpage_config,
))
install_man(configure_file(
input: 'utils/man/gtf.man',
output: 'gtf.1',
configuration: manpage_config,
))
subdir('doc')

View File

@ -8,7 +8,6 @@ libxf86modes_la_SOURCES = \
xf86Crtc.c \
xf86Crtc.h \
xf86Cursors.c \
xf86cvt.c \
xf86gtf.c \
xf86EdidModes.c \
xf86Modes.c \

View File

@ -1,7 +1,6 @@
srcs_xorg_modes = [
'xf86Crtc.c',
'xf86Cursors.c',
'xf86cvt.c',
'xf86gtf.c',
'xf86EdidModes.c',
'xf86Modes.c',
@ -15,8 +14,8 @@ endif
xorg_modes = static_library('xorg_modes',
srcs_xorg_modes,
include_directories: [inc, xorg_inc],
dependencies: common_dep,
include_directories: [ inc, xorg_inc ],
dependencies: [ common_dep, libxcvt_dep ],
c_args: xorg_c_args,
)

View File

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

View File

@ -29,6 +29,7 @@
#include <xorg-config.h>
#endif
#include <libxcvt/libxcvt.h>
#include "xf86Modes.h"
#include "xf86Priv.h"
@ -792,3 +793,33 @@ xf86PruneDuplicateModes(DisplayModePtr modes)
return modes;
}
/*
* Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
*/
DisplayModePtr
xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
Bool Interlaced)
{
struct libxcvt_mode_info *libxcvt_mode_info;
DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
libxcvt_mode_info =
libxcvt_gen_mode_info(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
Mode->VDisplay = libxcvt_mode_info->vdisplay;
Mode->HDisplay = libxcvt_mode_info->hdisplay;
Mode->Clock = libxcvt_mode_info->dot_clock;
Mode->HSyncStart = libxcvt_mode_info->hsync_start;
Mode->HSyncEnd = libxcvt_mode_info->hsync_end;
Mode->HTotal = libxcvt_mode_info->htotal;
Mode->VSyncStart = libxcvt_mode_info->vsync_start;
Mode->VSyncEnd = libxcvt_mode_info->vsync_end;
Mode->VTotal = libxcvt_mode_info->vtotal;
Mode->VRefresh = libxcvt_mode_info->vrefresh;
Mode->Flags = libxcvt_mode_info->mode_flags;
free(libxcvt_mode_info);
return Mode;
}

View File

@ -806,6 +806,12 @@ xf86RandR12CreateScreenResources(ScreenPtr pScreen)
mmWidth = output->conf_monitor->mon_width;
mmHeight = output->conf_monitor->mon_height;
}
else if (output &&
(output->mm_width > 0 &&
output->mm_height > 0)) {
mmWidth = output->mm_width;
mmHeight = output->mm_height;
}
else {
/*
* Otherwise, just set the screen to DEFAULT_DPI

View File

@ -1,295 +0,0 @@
/*
* Copyright 2005-2006 Luc Verhaegen.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* The reason for having this function in a file of its own is
* so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
* code is shared directly.
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include "xf86.h"
#include "xf86Modes.h"
#include <string.h>
/*
* Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
*
* These calculations are stolen from the CVT calculation spreadsheet written
* by Graham Loveridge. He seems to be claiming no copyright and there seems to
* be no license attached to this. He apparently just wants to see his name
* mentioned.
*
* This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
*
* Comments and structure corresponds to the comments and structure of the xls.
* This should ease importing of future changes to the standard (not very
* likely though).
*
* About margins; i'm sure that they are to be the bit between HDisplay and
* HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and
* VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
* outside sync "margin" for some reason. Since we prefer seeing proper
* blanking instead of the overscan colour, and since the Crtc* values will
* probably get altered after us, we will disable margins altogether. With
* these calculations, Margins will plainly expand H/VDisplay, and we don't
* want that. -- libv
*
*/
DisplayModePtr
xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
Bool Interlaced)
{
DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec));
/* 1) top/bottom margin size (% of height) - default: 1.8 */
#define CVT_MARGIN_PERCENTAGE 1.8
/* 2) character cell horizontal granularity (pixels) - default 8 */
#define CVT_H_GRANULARITY 8
/* 4) Minimum vertical porch (lines) - default 3 */
#define CVT_MIN_V_PORCH 3
/* 4) Minimum number of vertical back porch lines - default 6 */
#define CVT_MIN_V_BPORCH 6
/* Pixel Clock step (kHz) */
#define CVT_CLOCK_STEP 250
Bool Margins = FALSE;
float VFieldRate, HPeriod;
int HDisplayRnd, HMargin;
int VDisplayRnd, VMargin, VSync;
float Interlace; /* Please rename this */
char *tmp;
/* CVT default is 60.0Hz */
if (!VRefresh)
VRefresh = 60.0;
/* 1. Required field rate */
if (Interlaced)
VFieldRate = VRefresh * 2;
else
VFieldRate = VRefresh;
/* 2. Horizontal pixels */
HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
/* 3. Determine left and right borders */
if (Margins) {
/* right margin is actually exactly the same as left */
HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
HMargin -= HMargin % CVT_H_GRANULARITY;
}
else
HMargin = 0;
/* 4. Find total active pixels */
Mode->HDisplay = HDisplayRnd + 2 * HMargin;
/* 5. Find number of lines per field */
if (Interlaced)
VDisplayRnd = VDisplay / 2;
else
VDisplayRnd = VDisplay;
/* 6. Find top and bottom margins */
/* nope. */
if (Margins)
/* top and bottom margins are equal again. */
VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
else
VMargin = 0;
Mode->VDisplay = VDisplay + 2 * VMargin;
/* 7. Interlace */
if (Interlaced)
Interlace = 0.5;
else
Interlace = 0.0;
/* Determine VSync Width from aspect ratio */
if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
VSync = 4;
else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
VSync = 5;
else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
VSync = 6;
else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
VSync = 7;
else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
VSync = 7;
else /* Custom */
VSync = 10;
if (!Reduced) { /* simplified GTF calculation */
/* 4) Minimum time of vertical sync + back porch interval (µs)
* default 550.0 */
#define CVT_MIN_VSYNC_BP 550.0
/* 3) Nominal HSync width (% of line period) - default 8 */
#define CVT_HSYNC_PERCENTAGE 8
float HBlankPercentage;
int VSyncAndBackPorch, VBackPorch;
int HBlank;
/* 8. Estimated Horizontal period */
HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) /
(VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
/* 9. Find number of lines in sync + backporch */
if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) <
(VSync + CVT_MIN_V_PORCH))
VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
else
VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1;
/* 10. Find number of lines in back porch */
VBackPorch = VSyncAndBackPorch - VSync;
(void) VBackPorch;
/* 11. Find total number of lines in vertical field */
Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
+ CVT_MIN_V_PORCH;
/* 5) Definition of Horizontal blanking time limitation */
/* Gradient (%/kHz) - default 600 */
#define CVT_M_FACTOR 600
/* Offset (%) - default 40 */
#define CVT_C_FACTOR 40
/* Blanking time scaling factor - default 128 */
#define CVT_K_FACTOR 128
/* Scaling factor weighting - default 20 */
#define CVT_J_FACTOR 20
#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
CVT_J_FACTOR
/* 12. Find ideal blanking duty cycle from formula */
HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0;
/* 13. Blanking time */
if (HBlankPercentage < 20)
HBlankPercentage = 20;
HBlank = Mode->HDisplay * HBlankPercentage / (100.0 - HBlankPercentage);
HBlank -= HBlank % (2 * CVT_H_GRANULARITY);
/* 14. Find total number of pixels in a line. */
Mode->HTotal = Mode->HDisplay + HBlank;
/* Fill in HSync values */
Mode->HSyncEnd = Mode->HDisplay + HBlank / 2;
Mode->HSyncStart = Mode->HSyncEnd -
(Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100;
Mode->HSyncStart += CVT_H_GRANULARITY -
Mode->HSyncStart % CVT_H_GRANULARITY;
/* Fill in VSync values */
Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH;
Mode->VSyncEnd = Mode->VSyncStart + VSync;
}
else { /* Reduced blanking */
/* Minimum vertical blanking interval time (µs) - default 460 */
#define CVT_RB_MIN_VBLANK 460.0
/* Fixed number of clocks for horizontal sync */
#define CVT_RB_H_SYNC 32.0
/* Fixed number of clocks for horizontal blanking */
#define CVT_RB_H_BLANK 160.0
/* Fixed number of lines for vertical front porch - default 3 */
#define CVT_RB_VFPORCH 3
int VBILines;
/* 8. Estimate Horizontal period. */
HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) /
(VDisplayRnd + 2 * VMargin);
/* 9. Find number of lines in vertical blanking */
VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
/* 10. Check if vertical blanking is sufficient */
if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
/* 11. Find total number of lines in vertical field */
Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
/* 12. Find total number of pixels in a line */
Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK;
/* Fill in HSync values */
Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2;
Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC;
/* Fill in VSync values */
Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH;
Mode->VSyncEnd = Mode->VSyncStart + VSync;
}
/* 15/13. Find pixel clock frequency (kHz for xf86) */
Mode->Clock = Mode->HTotal * 1000.0 / HPeriod;
Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP;
/* 16/14. Find actual Horizontal Frequency (kHz) */
Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal);
/* 17/15. Find actual Field rate */
Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
((float) (Mode->HTotal * Mode->VTotal));
/* 18/16. Find actual vertical frame frequency */
/* ignore - just set the mode flag for interlaced */
if (Interlaced)
Mode->VTotal *= 2;
XNFasprintf(&tmp, "%dx%d", HDisplay, VDisplay);
Mode->name = tmp;
if (Reduced)
Mode->Flags |= V_PHSYNC | V_NVSYNC;
else
Mode->Flags |= V_NHSYNC | V_PVSYNC;
if (Interlaced)
Mode->Flags |= V_INTERLACE;
return Mode;
}

View File

@ -85,6 +85,9 @@ xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *bu
bustype = StringToBusType(busid, &id);
if (bustype == BUS_PCI) {
struct pci_device *pPci = device->pdev;
if (!pPci)
return FALSE;
if (xf86ComparePciBusString(busid,
((pPci->domain << 8)
| pPci->bus),

View File

@ -1,4 +1,3 @@
SUBDIRS = \
gtf \
cvt \
man

View File

@ -1 +0,0 @@
cvt

View File

@ -1,35 +0,0 @@
# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
bin_PROGRAMS = cvt
AM_CPPFLAGS = $(XORG_INCS) \
-I$(top_srcdir)/hw/xfree86/ddc \
-I$(top_srcdir)/hw/xfree86/modes \
-I$(top_srcdir)/hw/xfree86/parser
# gah
cvt_SOURCES = cvt.c \
$(top_srcdir)/hw/xfree86/modes/xf86cvt.c \
$(top_srcdir)/os/xprintf.c
cvt_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)

View File

@ -1,294 +0,0 @@
/*
* Copyright 2005-2006 Luc Verhaegen.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
/* Standalone VESA CVT standard timing modelines generator. */
#include "xf86.h"
#include "xf86Modes.h"
/* FatalError implementation used by the server code we built in */
void
FatalError(const char *f, ...)
{
va_list args;
va_start(args, f);
vfprintf(stderr, f, args);
va_end(args);
exit(1);
}
/* xnfalloc implementation used by the server code we built in */
void *
XNFalloc(unsigned long n)
{
void *r;
r = malloc(n);
if (!r) {
perror("malloc failed");
exit(1);
}
return r;
}
/* xnfcalloc implementation used by the server code we built in */
void *
XNFcallocarray(size_t nmemb, size_t size)
{
void *r;
r = calloc(nmemb, size);
if (!r) {
perror("calloc failed");
exit(1);
}
return r;
}
/*
* Quickly check whether this is a CVT standard mode.
*/
static Bool
CVTCheckStandard(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
Bool Verbose)
{
Bool IsCVT = TRUE;
if ((!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) ||
(!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) ||
(!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) ||
(!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) ||
(!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)));
else {
if (Verbose)
fprintf(stderr, "Warning: Aspect Ratio is not CVT standard.\n");
IsCVT = FALSE;
}
if ((VRefresh != 50.0) && (VRefresh != 60.0) &&
(VRefresh != 75.0) && (VRefresh != 85.0)) {
if (Verbose)
fprintf(stderr, "Warning: Refresh Rate is not CVT standard "
"(50, 60, 75 or 85Hz).\n");
IsCVT = FALSE;
}
return IsCVT;
}
/*
* I'm not documenting --interlaced for obvious reasons, even though I did
* implement it. I also can't deny having looked at gtf here.
*/
static void
PrintUsage(char *Name)
{
fprintf(stderr, "\n");
fprintf(stderr, "usage: %s [-v|--verbose] [-r|--reduced] X Y [refresh]\n",
Name);
fprintf(stderr, "\n");
fprintf(stderr, " -v|--verbose : Warn about CVT standard adherence.\n");
fprintf(stderr, " -r|--reduced : Create a mode with reduced blanking "
"(default: normal blanking).\n");
fprintf(stderr, " X : Desired horizontal resolution "
"(multiple of 8, required).\n");
fprintf(stderr,
" Y : Desired vertical resolution (required).\n");
fprintf(stderr,
" refresh : Desired refresh rate (default: 60.0Hz).\n");
fprintf(stderr, "\n");
fprintf(stderr, "Calculates VESA CVT (Coordinated Video Timing) modelines"
" for use with X.\n");
}
/*
*
*/
static void
PrintComment(DisplayModeRec * Mode, Bool CVT, Bool Reduced)
{
printf("# %dx%d %.2f Hz ", Mode->HDisplay, Mode->VDisplay, Mode->VRefresh);
if (CVT) {
printf("(CVT %.2fM",
((float) Mode->HDisplay * Mode->VDisplay) / 1000000.0);
if (!(Mode->VDisplay % 3) &&
((Mode->VDisplay * 4 / 3) == Mode->HDisplay))
printf("3");
else if (!(Mode->VDisplay % 9) &&
((Mode->VDisplay * 16 / 9) == Mode->HDisplay))
printf("9");
else if (!(Mode->VDisplay % 10) &&
((Mode->VDisplay * 16 / 10) == Mode->HDisplay))
printf("A");
else if (!(Mode->VDisplay % 4) &&
((Mode->VDisplay * 5 / 4) == Mode->HDisplay))
printf("4");
else if (!(Mode->VDisplay % 9) &&
((Mode->VDisplay * 15 / 9) == Mode->HDisplay))
printf("9");
if (Reduced)
printf("-R");
printf(") ");
}
else
printf("(CVT) ");
printf("hsync: %.2f kHz; ", Mode->HSync);
printf("pclk: %.2f MHz", ((float) Mode->Clock) / 1000.0);
printf("\n");
}
/*
* Originally grabbed from xf86Mode.c.
*
* Ignoring the actual Mode->name, as the user will want something solid
* to grab hold of.
*/
static void
PrintModeline(DisplayModePtr Mode, int HDisplay, int VDisplay, float VRefresh,
Bool Reduced)
{
if (Reduced)
printf("Modeline \"%dx%dR\" ", HDisplay, VDisplay);
else
printf("Modeline \"%dx%d_%.2f\" ", HDisplay, VDisplay, VRefresh);
printf("%6.2f %i %i %i %i %i %i %i %i", Mode->Clock / 1000.,
Mode->HDisplay, Mode->HSyncStart, Mode->HSyncEnd, Mode->HTotal,
Mode->VDisplay, Mode->VSyncStart, Mode->VSyncEnd, Mode->VTotal);
if (Mode->Flags & V_INTERLACE)
printf(" interlace");
if (Mode->Flags & V_PHSYNC)
printf(" +hsync");
if (Mode->Flags & V_NHSYNC)
printf(" -hsync");
if (Mode->Flags & V_PVSYNC)
printf(" +vsync");
if (Mode->Flags & V_NVSYNC)
printf(" -vsync");
printf("\n");
}
/*
*
*/
int
main(int argc, char *argv[])
{
DisplayModeRec *Mode;
int HDisplay = 0, VDisplay = 0;
float VRefresh = 0.0;
Bool Reduced = FALSE, Verbose = FALSE, IsCVT;
Bool Interlaced = FALSE;
int n;
if ((argc < 3) || (argc > 7)) {
PrintUsage(argv[0]);
return 1;
}
/* This doesn't filter out bad flags properly. Bad flags get passed down
* to atoi/atof, which then return 0, so that these variables can get
* filled next time round. So this is just a cosmetic problem.
*/
for (n = 1; n < argc; n++) {
if (!strcmp(argv[n], "-r") || !strcmp(argv[n], "--reduced"))
Reduced = TRUE;
else if (!strcmp(argv[n], "-i") || !strcmp(argv[n], "--interlaced"))
Interlaced = TRUE;
else if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--verbose"))
Verbose = TRUE;
else if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help")) {
PrintUsage(argv[0]);
return 0;
}
else if (!HDisplay) {
HDisplay = atoi(argv[n]);
if (!HDisplay) {
PrintUsage(argv[0]);
return 1;
}
}
else if (!VDisplay) {
VDisplay = atoi(argv[n]);
if (!VDisplay) {
PrintUsage(argv[0]);
return 1;
}
}
else if (!VRefresh) {
VRefresh = atof(argv[n]);
if (!VRefresh) {
PrintUsage(argv[0]);
return 1;
}
}
else {
PrintUsage(argv[0]);
return 1;
}
}
if (!HDisplay || !VDisplay) {
PrintUsage(argv[0]);
return 0;
}
/* Default to 60.0Hz */
if (!VRefresh)
VRefresh = 60.0;
/* Horizontal timing is always a multiple of 8: round up. */
if (HDisplay & 0x07) {
HDisplay &= ~0x07;
HDisplay += 8;
}
if (Reduced) {
if ((VRefresh / 60.0) != floor(VRefresh / 60.0)) {
fprintf(stderr,
"\nERROR: Multiple of 60Hz refresh rate required for "
" reduced blanking.\n");
PrintUsage(argv[0]);
return 0;
}
}
IsCVT = CVTCheckStandard(HDisplay, VDisplay, VRefresh, Reduced, Verbose);
Mode = xf86CVTMode(HDisplay, VDisplay, VRefresh, Reduced, Interlaced);
PrintComment(Mode, IsCVT, Reduced);
PrintModeline(Mode, HDisplay, VDisplay, VRefresh, Reduced);
return 0;
}

View File

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

View File

@ -1,41 +0,0 @@
.TH CVT 1 @vendorversion@
.SH NAME
cvt - calculate VESA CVT mode lines
.SH SYNOPSIS
.B cvt
.RB [ \-v | \-\-verbose ]
.RB [ \-r | \-\-reduced ]
.I h-resolution
.I v-resolution
.RB [ refresh ]
.SH DESCRIPTION
.I Cvt
is a utility for calculating VESA Coordinated Video Timing modes. Given the
desired horizontal and vertical resolutions, a modeline adhering to the CVT
standard is printed. This modeline can be included in Xorg
.B xorg.conf(@filemansuffix@)
.
.SH OPTIONS
.TP 8
.BR refresh
Provide a vertical refresh rate in Hz. The CVT standard prefers either 50.0,
60.0, 75.0 or 85.0Hz. The default is 60.0Hz.
.TP 8
.BR \-v | \-\-verbose
Warn verbosely when a given mode does not completely correspond with CVT
standards.
.TP 8
.BR \-r | \-\-reduced
Create a mode with reduced blanking. This allows for higher frequency signals,
with a lower or equal dotclock. Not for Cathode Ray Tube based displays though.
.SH "SEE ALSO"
xorg.conf(@filemansuffix@), gtf(@appmansuffix@)
.SH AUTHOR
Luc Verhaegen.
.PP
This program is based on the Coordinated Video Timing sample
implementation written by Graham Loveridge. This file is publicly
available at <http://www.vesa.org/Public/CVT/CVTd6r1.xls>. CVT is a
VESA trademark.

View File

@ -59,7 +59,7 @@
/* Based originally on code from indirect.c which was based on code from i830_dri.c. */
__GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) {
int numConfigs = 0;
__GLXconfig *visualConfigs, *c;
__GLXconfig *visualConfigs, *c, *l;
struct glCapabilities caps;
struct glCapabilitiesConfig *conf;
int stereo, depth, aux, buffers, stencil, accum, color, msample;
@ -113,14 +113,13 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber)
if(numConfigsPtr)
*numConfigsPtr = numConfigs;
visualConfigs = calloc(sizeof(*visualConfigs), numConfigs);
if(NULL == visualConfigs) {
ErrorF("xcalloc failure when allocating visualConfigs\n");
freeGlCapabilities(&caps);
return NULL;
}
/* Note that as of 1.20.0, we cannot allocate all the configs at once.
* __glXScreenDestroy now walks all the fbconfigs and frees them one at a time.
* See 4b0a3cbab131eb453e2b3fc0337121969258a7be.
*/
visualConfigs = calloc(sizeof(*visualConfigs), 1);
l = NULL;
c = visualConfigs; /* current buffer */
for(conf = caps.configurations; conf; conf = conf->next) {
for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) {
@ -137,7 +136,8 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber)
// Global
c->visualID = -1;
c->visualType = GLX_TRUE_COLOR;
c->next = c + 1;
c->next = calloc(sizeof(*visualConfigs), 1);
assert(c->next);
c->level = 0;
c->indexBits = 0;
@ -260,6 +260,7 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber)
/* EXT_framebuffer_sRGB */
c->sRGBCapable = GL_FALSE;
l = c;
c = c->next;
}
}
@ -271,11 +272,8 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber)
}
}
(c-1)->next = NULL;
if (c - visualConfigs != numConfigs) {
FatalError("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, (int)(c - visualConfigs));
}
free(c);
l->next = NULL;
freeGlCapabilities(&caps);
return visualConfigs;

View File

@ -3,7 +3,6 @@ AM_CFLAGS = $(DIX_CFLAGS)
AM_OBJCFLAGS = $(DIX_CFLAGS)
AM_CPPFLAGS = \
-DXSERVER_VERSION=\"$(VERSION)\" \
-DINXQUARTZ \
-DUSE_NEW_CLUT \
-DXFree86Server \
-I$(top_srcdir)/miext/rootless \
@ -30,7 +29,6 @@ libXquartz_la_SOURCES = \
darwinXinput.c \
keysym2ucs.c \
quartz.c \
quartzCocoa.m \
quartzKeyboard.c \
quartzStartup.c \
quartzRandR.c
@ -46,7 +44,6 @@ EXTRA_DIST = \
darwinEvents.h \
keysym2ucs.h \
quartz.h \
quartzCommon.h \
quartzKeyboard.h \
quartzRandR.h \
sanitizedCarbon.h \

View File

@ -31,18 +31,16 @@
#ifndef X11APPLICATION_H
#define X11APPLICATION_H 1
#include <X11/Xdefs.h>
#if __OBJC__
#import "X11Controller.h"
@interface X11Application : NSApplication {
X11Controller *_controller;
@interface X11Application : NSApplication
unsigned int _x_active : 1;
}
- (void)set_controller:controller;
- (void)set_window_menu:(NSArray *)list;
@property (nonatomic, readwrite, strong) X11Controller *controller;
@property (nonatomic, readonly, assign) OSX_BOOL x_active;
- (CFPropertyListRef)prefs_get_copy:(NSString *)key CF_RETURNS_RETAINED;
- (int)prefs_get_integer:(NSString *)key default:(int)def;
@ -58,9 +56,6 @@
- (void)prefs_set_array:(NSString *)key value:(NSArray *)value;
- (void)prefs_set_string:(NSString *)key value:(NSString *)value;
- (void)prefs_synchronize;
- (X11Controller *)controller;
- (OSX_BOOL)x_active;
@end
extern X11Application * X11App;

View File

@ -34,8 +34,6 @@
#include <dix-config.h>
#endif
#include "quartzCommon.h"
#import "X11Application.h"
#include "darwin.h"
@ -79,6 +77,10 @@ static dispatch_queue_t eventTranslationQueue;
#endif
#endif
#ifndef APPKIT_APPFLAGS_HACK
#define APPKIT_APPFLAGS_HACK 1
#endif
extern Bool noTestExtensions;
extern Bool noRenderExtension;
@ -104,10 +106,63 @@ CFStringRef app_prefs_domain_cfstr = NULL;
#define ALL_KEY_MASKS (NSShiftKeyMask | NSControlKeyMask | \
NSAlternateKeyMask | NSCommandKeyMask)
#if APPKIT_APPFLAGS_HACK && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
// This was removed from the SDK in 10.15
@interface NSApplication () {
@protected
/* All instance variables are private */
short _running;
struct __appFlags {
unsigned int _hidden:1;
unsigned int _appleEventActivationInProgress:1;
unsigned int _active:1;
unsigned int _hasBeenRun:1;
unsigned int _doingUnhide:1;
unsigned int _delegateReturnsValidRequestor:1;
unsigned int _deactPending:1;
unsigned int _invalidState:1;
unsigned int _invalidEvent:1;
unsigned int _postedWindowsNeedUpdateNote:1;
unsigned int _wantsToActivate:1;
unsigned int _doingHide:1;
unsigned int _dontSendShouldTerminate:1;
unsigned int _ignoresFullScreen:1;
unsigned int _finishedLaunching:1;
unsigned int _hasEventDelegate:1;
unsigned int _appTerminating:1;
unsigned int _didNSOpenOrPrint:1;
unsigned int _inDealloc:1;
unsigned int _pendingDidFinish:1;
unsigned int _hasKeyFocus:1;
unsigned int _panelsNonactivating:1;
unsigned int _hiddenOnLaunch:1;
unsigned int _openStatus:2;
unsigned int _batchOrdering:1;
unsigned int _waitingForTerminationReply:1;
unsigned int _unused:1;
unsigned int _enumeratingMemoryPressureHandlers:1;
unsigned int _didTryRestoringPersistentState:1;
unsigned int _windowDragging:1;
unsigned int _mightBeSwitching:1;
} _appFlags;
id _mainMenu;
}
@end
#endif
@interface NSApplication (Internal)
- (void)_setKeyWindow:(id)window;
- (void)_setMainWindow:(id)window;
@end
@interface X11Application (Private)
- (void) sendX11NSEvent:(NSEvent *)e;
@end
@interface X11Application ()
@property (nonatomic, readwrite, assign) OSX_BOOL x_active;
@end
@implementation X11Application
typedef struct message_struct message;
@ -117,72 +172,14 @@ struct message_struct {
NSObject *arg;
};
static mach_port_t _port;
/* Quartz mode initialization routine. This is often dynamically loaded
but is statically linked into this X server. */
Bool
QuartzModeBundleInit(void);
static void
init_ports(void)
{
kern_return_t r;
NSPort *p;
if (_port != MACH_PORT_NULL) return;
r = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &_port);
if (r != KERN_SUCCESS) return;
p = [NSMachPort portWithMachPort:_port];
[p setDelegate:NSApp];
[p scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:
NSDefaultRunLoopMode];
}
static void
message_kit_thread(SEL selector, NSObject *arg)
{
message msg;
kern_return_t r;
msg.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg.hdr.msgh_size = sizeof(msg);
msg.hdr.msgh_remote_port = _port;
msg.hdr.msgh_local_port = MACH_PORT_NULL;
msg.hdr.msgh_reserved = 0;
msg.hdr.msgh_id = 0;
msg.selector = selector;
msg.arg = [arg retain];
r = mach_msg(&msg.hdr, MACH_SEND_MSG, msg.hdr.msgh_size,
0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
if (r != KERN_SUCCESS)
ErrorF("%s: mach_msg failed: %x\n", __FUNCTION__, r);
}
- (void) handleMachMessage:(void *)_msg
{
message *msg = _msg;
[self performSelector:msg->selector withObject:msg->arg];
[msg->arg release];
}
- (void) set_controller:obj
{
if (_controller == nil) _controller = [obj retain];
}
- (void) dealloc
{
if (_controller != nil) [_controller release];
if (_port != MACH_PORT_NULL)
mach_port_deallocate(mach_task_self(), _port);
self.controller = nil;
[super dealloc];
}
@ -212,10 +209,12 @@ message_kit_thread(SEL selector, NSObject *arg)
- (void) activateX:(OSX_BOOL)state
{
if (_x_active == state)
OSX_BOOL const x_active = self.x_active;
if (x_active == state)
return;
DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active);
DEBUG_LOG("state=%d, x_active=%d, \n", state, x_active);
if (state) {
if (bgMouseLocationUpdated) {
DarwinSendPointerEvents(darwinPointer, MotionNotify, 0,
@ -239,7 +238,7 @@ message_kit_thread(SEL selector, NSObject *arg)
DarwinSendDDXEvent(kXquartzDeactivate, 0);
}
_x_active = state;
self.x_active = state;
}
- (void) became_key:(NSWindow *)win
@ -249,7 +248,16 @@ message_kit_thread(SEL selector, NSObject *arg)
- (void) sendEvent:(NSEvent *)e
{
/* Don't try sending to X if we haven't initialized. This can happen if AppKit takes over
* (eg: uncaught exception) early in launch.
*/
if (!eventTranslationQueue) {
[super sendEvent:e];
return;
}
OSX_BOOL for_appkit, for_x;
OSX_BOOL const x_active = self.x_active;
/* By default pass down the responder chain and to X. */
for_appkit = YES;
@ -265,13 +273,13 @@ message_kit_thread(SEL selector, NSObject *arg)
if ([e window] != nil) {
/* Pointer event has an (AppKit) window. Probably something for the kit. */
for_x = NO;
if (_x_active) [self activateX:NO];
if (x_active) [self activateX:NO];
}
else if ([self modalWindow] == nil) {
/* Must be an X window. Tell appkit windows to resign main/key */
for_appkit = NO;
if (!_x_active && quartzProcs->IsX11Window([e windowNumber])) {
if (!x_active && quartzProcs->IsX11Window([e windowNumber])) {
if ([self respondsToSelector:@selector(_setKeyWindow:)] && [self respondsToSelector:@selector(_setMainWindow:)]) {
NSWindow *keyWindow = [self keyWindow];
if (keyWindow) {
@ -415,10 +423,12 @@ message_kit_thread(SEL selector, NSObject *arg)
BOOL order_all_windows = YES, workspaces, ok;
for_appkit = NO;
#if APPKIT_APPFLAGS_HACK
/* FIXME: This is a hack to avoid passing the event to AppKit which
* would result in it raising one of its windows.
*/
_appFlags._active = YES;
#endif
[self set_front_process:nil];
@ -486,19 +496,9 @@ message_kit_thread(SEL selector, NSObject *arg)
}
}
- (void) set_window_menu:(NSArray *)list
{
[_controller set_window_menu:list];
}
- (void) set_window_menu_check:(NSNumber *)n
{
[_controller set_window_menu_check:n];
}
- (void) set_apps_menu:(NSArray *)list
{
[_controller set_apps_menu:list];
[self.controller set_apps_menu:list];
}
- (void) set_front_process:unused
@ -509,16 +509,6 @@ message_kit_thread(SEL selector, NSObject *arg)
[self activateX:YES];
}
- (void) set_can_quit:(NSNumber *)state
{
[_controller set_can_quit:[state boolValue]];
}
- (void) server_ready:unused
{
[_controller server_ready];
}
- (void) show_hide_menubar:(NSNumber *)state
{
/* Also shows/hides the dock */
@ -531,7 +521,7 @@ message_kit_thread(SEL selector, NSObject *arg)
- (void) launch_client:(NSString *)cmd
{
(void)[_controller application:self openFile:cmd];
(void)[self.controller application:self openFile:cmd];
}
/* user preferences */
@ -941,123 +931,83 @@ cfarray_to_nsarray(CFArrayRef in)
AppleWMCopyToPasteboard);
}
- (X11Controller *) controller
{
return _controller;
}
- (OSX_BOOL) x_active
{
return _x_active;
}
@end
static NSArray *
array_with_strings_and_numbers(int nitems, const char **items,
const char *numbers)
{
NSMutableArray *array, *subarray;
NSString *string, *number;
int i;
/* (Can't autorelease on the X server thread) */
array = [[NSMutableArray alloc] initWithCapacity:nitems];
for (i = 0; i < nitems; i++) {
subarray = [[NSMutableArray alloc] initWithCapacity:2];
string = [[NSString alloc] initWithUTF8String:items[i]];
[subarray addObject:string];
[string release];
if (numbers[i] != 0) {
number = [[NSString alloc] initWithFormat:@"%d", numbers[i]];
[subarray addObject:number];
[number release];
}
else
[subarray addObject:@""];
[array addObject:subarray];
[subarray release];
}
return array;
}
void
X11ApplicationSetWindowMenu(int nitems, const char **items,
const char *shortcuts)
{
NSArray *array;
array = array_with_strings_and_numbers(nitems, items, shortcuts);
@autoreleasepool {
NSMutableArray <NSArray <NSString *> *> * const allMenuItems = [NSMutableArray array];
/* Send the array of strings over to the appkit thread */
for (int i = 0; i < nitems; i++) {
NSMutableArray <NSString *> * const menuItem = [NSMutableArray array];
[menuItem addObject:@(items[i])];
message_kit_thread(@selector (set_window_menu:), array);
[array release];
if (shortcuts[i] == 0) {
[menuItem addObject:@""];
} else {
[menuItem addObject:[NSString stringWithFormat:@"%d", shortcuts[i]]];
}
[allMenuItems addObject:menuItem];
}
dispatch_async(dispatch_get_main_queue(), ^{
[X11App.controller set_window_menu:allMenuItems];
});
}
}
void
X11ApplicationSetWindowMenuCheck(int idx)
{
NSNumber *n;
n = [[NSNumber alloc] initWithInt:idx];
message_kit_thread(@selector (set_window_menu_check:), n);
[n release];
dispatch_async(dispatch_get_main_queue(), ^{
[X11App.controller set_window_menu_check:@(idx)];
});
}
void
X11ApplicationSetFrontProcess(void)
{
message_kit_thread(@selector (set_front_process:), nil);
dispatch_async(dispatch_get_main_queue(), ^{
[X11App set_front_process:nil];
});
}
void
X11ApplicationSetCanQuit(int state)
{
NSNumber *n;
n = [[NSNumber alloc] initWithBool:state];
message_kit_thread(@selector (set_can_quit:), n);
[n release];
dispatch_async(dispatch_get_main_queue(), ^{
X11App.controller.can_quit = !!state;
});
}
void
X11ApplicationServerReady(void)
{
message_kit_thread(@selector (server_ready:), nil);
dispatch_async(dispatch_get_main_queue(), ^{
[X11App.controller server_ready];
});
}
void
X11ApplicationShowHideMenubar(int state)
{
NSNumber *n;
n = [[NSNumber alloc] initWithBool:state];
message_kit_thread(@selector (show_hide_menubar:), n);
[n release];
dispatch_async(dispatch_get_main_queue(), ^{
[X11App show_hide_menubar:@(state)];
});
}
void
X11ApplicationLaunchClient(const char *cmd)
{
NSString *string;
string = [[NSString alloc] initWithUTF8String:cmd];
message_kit_thread(@selector (launch_client:), string);
[string release];
@autoreleasepool {
NSString *string = @(cmd);
dispatch_async(dispatch_get_main_queue(), ^{
[X11App launch_client:string];
});
}
}
/* This is a special function in that it is run from the *SERVER* thread and
@ -1174,77 +1124,71 @@ xpbproxy_x_thread(void *args)
void
X11ApplicationMain(int argc, char **argv, char **envp)
{
NSAutoreleasePool *pool;
#ifdef DEBUG
while (access("/tmp/x11-block", F_OK) == 0) sleep(1);
#endif
pool = [[NSAutoreleasePool alloc] init];
X11App = (X11Application *)[X11Application sharedApplication];
init_ports();
@autoreleasepool {
X11App = (X11Application *)[X11Application sharedApplication];
app_prefs_domain_cfstr =
(CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
app_prefs_domain_cfstr = (CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
if (app_prefs_domain_cfstr == NULL) {
ErrorF(
"X11ApplicationMain: Unable to determine bundle identifier. Your installation of XQuartz may be broken.\n");
app_prefs_domain_cfstr = CFSTR(BUNDLE_ID_PREFIX ".X11");
}
if (app_prefs_domain_cfstr == NULL) {
ErrorF("X11ApplicationMain: Unable to determine bundle identifier. Your installation of XQuartz may be broken.\n");
app_prefs_domain_cfstr = CFSTR(BUNDLE_ID_PREFIX ".X11");
}
[NSApp read_defaults];
[NSBundle loadNibNamed:@"main" owner:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:NSApp
selector:@selector (became_key:)
name:
NSWindowDidBecomeKeyNotification object:nil];
[NSApp read_defaults];
[NSBundle loadNibNamed:@"main" owner:NSApp];
[NSNotificationCenter.defaultCenter addObserver:NSApp
selector:@selector (became_key:)
name:NSWindowDidBecomeKeyNotification
object:nil];
/*
* The xpr Quartz mode is statically linked into this server.
* Initialize all the Quartz functions.
*/
QuartzModeBundleInit();
/*
* The xpr Quartz mode is statically linked into this server.
* Initialize all the Quartz functions.
*/
QuartzModeBundleInit();
/* Calculate the height of the menubar so we can avoid it. */
aquaMenuBarHeight = [[NSApp mainMenu] menuBarHeight];
if (!aquaMenuBarHeight) {
NSScreen* primaryScreen = [[NSScreen screens] objectAtIndex:0];
aquaMenuBarHeight = NSHeight([primaryScreen frame]) - NSMaxY([primaryScreen visibleFrame]);
}
/* Calculate the height of the menubar so we can avoid it. */
aquaMenuBarHeight = NSApp.mainMenu.menuBarHeight;
if (!aquaMenuBarHeight) {
NSScreen* primaryScreen = NSScreen.screens[0];
aquaMenuBarHeight = NSHeight(primaryScreen.frame) - NSMaxY(primaryScreen.visibleFrame);
}
eventTranslationQueue = dispatch_queue_create(
BUNDLE_ID_PREFIX ".X11.NSEventsToX11EventsQueue", NULL);
assert(eventTranslationQueue != NULL);
eventTranslationQueue = dispatch_queue_create(BUNDLE_ID_PREFIX ".X11.NSEventsToX11EventsQueue", NULL);
assert(eventTranslationQueue != NULL);
/* Set the key layout seed before we start the server */
last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
/* Set the key layout seed before we start the server */
last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
if (!last_key_layout)
ErrorF(
"X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n");
if (!last_key_layout) {
ErrorF("X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n");
}
if (!QuartsResyncKeymap(FALSE)) {
ErrorF("X11ApplicationMain: Could not build a valid keymap.\n");
}
if (!QuartsResyncKeymap(FALSE)) {
ErrorF("X11ApplicationMain: Could not build a valid keymap.\n");
}
/* Tell the server thread that it can proceed */
QuartzInitServer(argc, argv, envp);
/* Tell the server thread that it can proceed */
QuartzInitServer(argc, argv, envp);
/* This must be done after QuartzInitServer because it can result in
* an mieqEnqueue() - <rdar://problem/6300249>
*/
check_xinitrc();
/* This must be done after QuartzInitServer because it can result in
* an mieqEnqueue() - <rdar://problem/6300249>
*/
check_xinitrc();
create_thread(xpbproxy_x_thread, NULL);
create_thread(xpbproxy_x_thread, NULL);
#if XQUARTZ_SPARKLE
[[X11App controller] setup_sparkle];
[[SUUpdater sharedUpdater] resetUpdateCycle];
// [[SUUpdater sharedUpdater] checkForUpdates:X11App];
[[X11App controller] setup_sparkle];
[[SUUpdater sharedUpdater] resetUpdateCycle];
// [[SUUpdater sharedUpdater] checkForUpdates:X11App];
#endif
}
[pool release];
[NSApp run];
/* not reached */
}
@ -1647,8 +1591,7 @@ handle_mouse:
}
#endif
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_7 &&
XQuartzScrollInDeviceDirection &&
if (XQuartzScrollInDeviceDirection &&
[e isDirectionInvertedFromDevice]) {
deltaX *= -1;
deltaY *= -1;

View File

@ -47,62 +47,42 @@
#endif
@interface X11Controller : NSObject <NSTableViewDataSource>
{
IBOutlet NSPanel *prefs_panel;
@property (nonatomic, readwrite, strong) IBOutlet NSPanel *prefs_panel;
IBOutlet NSButton *fake_buttons;
IBOutlet NSButton *enable_fullscreen;
IBOutlet NSButton *enable_fullscreen_menu;
IBOutlet NSTextField *enable_fullscreen_menu_text;
IBOutlet NSButton *enable_keyequivs;
IBOutlet NSButton *sync_keymap;
IBOutlet NSButton *option_sends_alt;
IBOutlet NSButton *scroll_in_device_direction;
IBOutlet NSButton *click_through;
IBOutlet NSButton *focus_follows_mouse;
IBOutlet NSButton *focus_on_new_window;
IBOutlet NSButton *enable_auth;
IBOutlet NSButton *enable_tcp;
IBOutlet NSButton *sync_pasteboard;
IBOutlet NSButton *sync_pasteboard_to_clipboard;
IBOutlet NSButton *sync_pasteboard_to_primary;
IBOutlet NSButton *sync_clipboard_to_pasteboard;
IBOutlet NSButton *sync_primary_immediately;
IBOutlet NSTextField *sync_text1;
IBOutlet NSTextField *sync_text2;
IBOutlet NSPopUpButton *depth;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *fake_buttons;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *enable_fullscreen;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *enable_fullscreen_menu;
@property (nonatomic, readwrite, strong) IBOutlet NSTextField *enable_fullscreen_menu_text;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *enable_keyequivs;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *sync_keymap;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *option_sends_alt;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *scroll_in_device_direction;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *click_through;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *focus_follows_mouse;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *focus_on_new_window;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *enable_auth;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *enable_tcp;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *sync_pasteboard;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *sync_pasteboard_to_clipboard;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *sync_pasteboard_to_primary;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *sync_clipboard_to_pasteboard;
@property (nonatomic, readwrite, strong) IBOutlet NSButton *sync_primary_immediately;
@property (nonatomic, readwrite, strong) IBOutlet NSTextField *sync_text1;
@property (nonatomic, readwrite, strong) IBOutlet NSTextField *sync_text2;
@property (nonatomic, readwrite, strong) IBOutlet NSPopUpButton *depth;
IBOutlet NSMenuItem *window_separator;
// window_separator is DEPRECATED due to this radar:
// <rdar://problem/7088335> NSApplication releases the separator in the Windows menu even though it's an IBOutlet
// It is kept around for localization compatibility and is subject to removal "eventually"
// If it is !NULL (meaning it is in the nib), it is removed from the menu and released
@property (nonatomic, readwrite, strong) IBOutlet NSMenuItem *x11_about_item;
@property (nonatomic, readwrite, strong) IBOutlet NSMenuItem *dock_window_separator;
@property (nonatomic, readwrite, strong) IBOutlet NSMenuItem *apps_separator;
@property (nonatomic, readwrite, strong) IBOutlet NSMenuItem *toggle_fullscreen_item;
IBOutlet NSMenuItem *x11_about_item;
IBOutlet NSMenuItem *dock_window_separator;
IBOutlet NSMenuItem *apps_separator;
IBOutlet NSMenuItem *toggle_fullscreen_item;
#ifdef XQUARTZ_SPARKLE
NSMenuItem *check_for_updates_item; // Programmatically enabled
#endif
IBOutlet NSMenuItem *copy_menu_item;
IBOutlet NSMenu *dock_apps_menu;
IBOutlet NSTableView *apps_table;
@property (nonatomic, readwrite, strong) IBOutlet NSMenuItem *copy_menu_item;
@property (nonatomic, readwrite, strong) IBOutlet NSMenu *dock_apps_menu;
@property (nonatomic, readwrite, strong) IBOutlet NSTableView *apps_table;
NSArray *apps;
NSMutableArray *table_apps;
@property (nonatomic, readwrite, strong) IBOutlet NSMenu *dock_menu;
IBOutlet NSMenu *dock_menu;
// This is where in the Windows menu we'll start (this will be the index of the separator)
NSInteger windows_menu_start;
int checked_window_item;
x_list *pending_apps;
OSX_BOOL finished_launching;
OSX_BOOL can_quit;
}
@property (nonatomic, readwrite, assign) OSX_BOOL can_quit;
- (void)set_window_menu:(NSArray *)list;
- (void)set_window_menu_check:(NSNumber *)n;
@ -112,7 +92,6 @@
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)
update;
#endif
- (void)set_can_quit:(OSX_BOOL)state;
- (void)server_ready;
- (OSX_BOOL)application:(NSApplication *)app openFile:(NSString *)filename;

View File

@ -34,8 +34,6 @@
#include <dix-config.h>
#endif
#include "quartzCommon.h"
#import "X11Controller.h"
#import "X11Application.h"
@ -58,6 +56,19 @@
extern aslclient aslc;
extern char *bundle_id_prefix;
@interface X11Controller ()
#ifdef XQUARTZ_SPARKLE
@property (nonatomic, readwrite, strong) NSMenuItem *check_for_updates_item; // Programatically enabled
#endif
@property (nonatomic, readwrite, strong) NSArray *apps;
@property (nonatomic, readwrite, strong) NSMutableArray *table_apps;
@property (nonatomic, readwrite, assign) NSInteger windows_menu_nitems;
@property (nonatomic, readwrite, assign) int checked_window_item;
@property (nonatomic, readwrite, assign) x_list *pending_apps;
@property (nonatomic, readwrite, assign) OSX_BOOL finished_launching;
@end
@implementation X11Controller
- (void) awakeFromNib
@ -66,7 +77,7 @@ extern char *bundle_id_prefix;
NSArray *array;
/* Point X11Application at ourself. */
[xapp set_controller:self];
xapp.controller = self;
array = [xapp prefs_get_array:@PREFS_APPSMENU];
if (array != nil) {
@ -102,15 +113,7 @@ extern char *bundle_id_prefix;
addObserver: self
selector: @selector(apps_table_done:)
name: NSWindowWillCloseNotification
object: [apps_table window]];
// Setup data about our Windows menu
if (window_separator) {
[[window_separator menu] removeItem:window_separator];
window_separator = nil;
}
windows_menu_start = [[X11App windowsMenu] numberOfItems];
object: self.apps_table.window];
}
- (void) item_selected:sender
@ -121,80 +124,16 @@ extern char *bundle_id_prefix;
AppleWMWindowMenuItem, [sender tag]);
}
- (void) remove_window_menu
{
NSMenu *menu;
int count, i;
/* Work backwards so we don't mess up the indices */
menu = [X11App windowsMenu];
count = [menu numberOfItems];
for (i = count - 1; i >= windows_menu_start; i--)
[menu removeItemAtIndex:i];
count = [dock_menu indexOfItem:dock_window_separator];
for (i = 0; i < count; i++)
[dock_menu removeItemAtIndex:0];
}
- (void) install_window_menu:(NSArray *)list
{
NSMenu *menu;
NSMenuItem *item;
int first, count, i;
menu = [X11App windowsMenu];
first = windows_menu_start + 1;
count = [list count];
// Push a Separator
if (count) {
[menu addItem:[NSMenuItem separatorItem]];
}
for (i = 0; i < count; i++) {
NSString *name, *shortcut;
name = [[list objectAtIndex:i] objectAtIndex:0];
shortcut = [[list objectAtIndex:i] objectAtIndex:1];
if (windowItemModMask == 0 || windowItemModMask == -1)
shortcut = @"";
item =
(NSMenuItem *)[menu addItemWithTitle:name action:
@selector
(item_selected:) keyEquivalent:shortcut];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
item = (NSMenuItem *)[dock_menu insertItemWithTitle:name
action:@selector
(item_selected:) keyEquivalent:shortcut
atIndex:i];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
}
if (checked_window_item >= 0 && checked_window_item < count) {
item = (NSMenuItem *)[menu itemAtIndex:first + checked_window_item];
[item setState:NSOnState];
item = (NSMenuItem *)[dock_menu itemAtIndex:checked_window_item];
[item setState:NSOnState];
}
}
- (void) remove_apps_menu
{
NSMenu *menu;
NSMenuItem *item;
int i;
if (apps == nil || apps_separator == nil) return;
NSMenuItem * const apps_separator = self.apps_separator;
NSMenu * const dock_apps_menu = self.dock_apps_menu;
if (self.apps == nil || apps_separator == nil) return;
menu = [apps_separator menu];
@ -214,8 +153,7 @@ extern char *bundle_id_prefix;
}
}
[apps release];
apps = nil;
self.apps = nil;
}
- (void) prepend_apps_item:(NSArray *)list index:(int)i menu:(NSMenu *)menu
@ -252,6 +190,9 @@ extern char *bundle_id_prefix;
count = [list count];
NSMenuItem * const apps_separator = self.apps_separator;
NSMenu * const dock_apps_menu = self.dock_apps_menu;
if (count == 0 || apps_separator == nil) return;
menu = [apps_separator menu];
@ -263,28 +204,89 @@ extern char *bundle_id_prefix;
[self prepend_apps_item:list index:i menu:dock_apps_menu];
}
apps = [list retain];
self.apps = list;
}
- (void) set_window_menu:(NSArray *)list
{
[self remove_window_menu];
[self install_window_menu:list];
NSMenu * const menu = X11App.windowsMenu;
NSMenu * const dock_menu = self.dock_menu;
DarwinSendDDXEvent(kXquartzControllerNotify, 1,
AppleWMWindowMenuNotify);
/* First, remove the existing items from the Window Menu */
NSInteger itemsToRemove = self.windows_menu_nitems;
if (itemsToRemove > 0) {
NSInteger indexForRemoval = menu.numberOfItems - itemsToRemove - 1; /* we also want to remove the separator */
for (NSInteger i = 0 ; i < itemsToRemove + 1 ; i++) {
[menu removeItemAtIndex:indexForRemoval];
}
for (NSInteger i = 0 ; i < itemsToRemove; i++) {
[dock_menu removeItemAtIndex:0];
}
}
NSInteger const itemsToAdd = list.count;
self.windows_menu_nitems = itemsToAdd;
if (itemsToAdd > 0) {
NSMenuItem *item;
// Push a Separator
[menu addItem:[NSMenuItem separatorItem]];
for (NSInteger i = 0; i < itemsToAdd; i++) {
NSString *name, *shortcut;
name = list[i][0];
shortcut = list[i][1];
if (windowItemModMask == 0 || windowItemModMask == -1)
shortcut = @"";
item = (NSMenuItem *)[menu addItemWithTitle:name
action:@selector(item_selected:)
keyEquivalent:shortcut];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
item = (NSMenuItem *)[dock_menu insertItemWithTitle:name
action:@selector(item_selected:)
keyEquivalent:shortcut
atIndex:i];
[item setKeyEquivalentModifierMask:(NSUInteger)windowItemModMask];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
}
int const checked_window_item = self.checked_window_item;
if (checked_window_item >= 0 && checked_window_item < itemsToAdd) {
NSInteger first = menu.numberOfItems - itemsToAdd;
item = (NSMenuItem *)[menu itemAtIndex:first + checked_window_item];
[item setState:NSOnState];
item = (NSMenuItem *)[dock_menu itemAtIndex:checked_window_item];
[item setState:NSOnState];
}
}
DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMWindowMenuNotify);
}
- (void) set_window_menu_check:(NSNumber *)nn
{
NSMenu *menu;
NSMenu * const menu = X11App.windowsMenu;
NSMenu * const dock_menu = self.dock_menu;
NSMenuItem *item;
int first, count;
int n = [nn intValue];
int n = nn.intValue;
menu = [X11App windowsMenu];
first = windows_menu_start + 1;
count = [menu numberOfItems] - first;
NSInteger const count = self.windows_menu_nitems;
NSInteger const first = menu.numberOfItems - count;
int const checked_window_item = self.checked_window_item;
if (checked_window_item >= 0 && checked_window_item < count) {
item = (NSMenuItem *)[menu itemAtIndex:first + checked_window_item];
@ -298,7 +300,7 @@ extern char *bundle_id_prefix;
item = (NSMenuItem *)[dock_menu itemAtIndex:n];
[item setState:NSOnState];
}
checked_window_item = n;
self.checked_window_item = n;
}
- (void) set_apps_menu:(NSArray *)list
@ -310,31 +312,29 @@ extern char *bundle_id_prefix;
#ifdef XQUARTZ_SPARKLE
- (void) setup_sparkle
{
if (check_for_updates_item)
if (self.check_for_updates_item)
return; // already did it...
NSMenu *menu = [x11_about_item menu];
NSMenu *menu = [self.x11_about_item menu];
check_for_updates_item =
[menu insertItemWithTitle:NSLocalizedString(
@"Check for X11 Updates...",
@"Check for X11 Updates...")
action:@selector (
checkForUpdates:)
keyEquivalent:@""
atIndex:1];
NSMenuItem * const check_for_updates_item =
[menu insertItemWithTitle:NSLocalizedString(@"Check for X11 Updates...", @"Check for X11 Updates...")
action:@selector(checkForUpdates:)
keyEquivalent:@""
atIndex:1];
[check_for_updates_item setTarget:[SUUpdater sharedUpdater]];
[check_for_updates_item setEnabled:YES];
self.check_for_updates_item = check_for_updates_item;
// Set X11Controller as the delegate for the updater.
[[SUUpdater sharedUpdater] setDelegate:self];
}
// Sent immediately before installing the specified update.
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)
update
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
{
//[self set_can_quit:YES];
//self.can_quit = YES;
}
#endif
@ -446,6 +446,7 @@ extern char *bundle_id_prefix;
{
int tag;
NSString *item;
NSArray * const apps = self.apps;
tag = [sender tag] - 1;
if (apps == nil || tag < 0 || tag >= [apps count])
@ -459,12 +460,13 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_show:sender
{
NSArray *columns;
NSMutableArray *oldapps = nil;
NSMutableArray *oldapps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
if (table_apps != nil)
oldapps = table_apps;
NSMutableArray * const table_apps = [[NSMutableArray alloc] initWithCapacity:1];
self.table_apps = table_apps;
table_apps = [[NSMutableArray alloc] initWithCapacity:1];
NSArray * const apps = self.apps;
if (apps != nil)
[table_apps addObjectsFromArray:apps];
@ -485,6 +487,8 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_done:sender
{
NSMutableArray * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
[apps_table deselectAll:sender]; /* flush edits? */
[self remove_apps_menu];
@ -495,13 +499,14 @@ extern char *bundle_id_prefix;
[[apps_table window] orderOut:sender];
[table_apps release];
table_apps = nil;
self.table_apps = nil;
}
- (IBAction) apps_table_new:sender
{
NSMutableArray *item;
NSMutableArray * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
int row = [apps_table selectedRow], i;
@ -529,6 +534,8 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_duplicate:sender
{
NSMutableArray * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
int row = [apps_table selectedRow], i;
NSObject *item;
@ -553,6 +560,8 @@ extern char *bundle_id_prefix;
- (IBAction) apps_table_delete:sender
{
NSMutableArray * const table_apps = self.table_apps;
NSTableView * const apps_table = self.apps_table;
int row = [apps_table selectedRow];
if (row >= 0) {
@ -575,6 +584,7 @@ extern char *bundle_id_prefix;
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
{
NSMutableArray * const table_apps = self.table_apps;
if (table_apps == nil) return 0;
return [table_apps count];
@ -583,6 +593,7 @@ extern char *bundle_id_prefix;
- (id) tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSMutableArray * const table_apps = self.table_apps;
NSArray *item;
int col;
@ -600,6 +611,7 @@ extern char *bundle_id_prefix;
- (void) tableView:(NSTableView *)tableView setObjectValue:(id)object
forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSMutableArray * const table_apps = self.table_apps;
NSMutableArray *item;
int col;
@ -660,11 +672,10 @@ extern char *bundle_id_prefix;
- (IBAction) enable_fullscreen_changed:sender
{
XQuartzRootlessDefault = ![enable_fullscreen intValue];
XQuartzRootlessDefault = !self.enable_fullscreen.intValue;
[enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
[enable_fullscreen_menu_text setTextColor:XQuartzRootlessDefault ?[
NSColor disabledControlTextColor] : [NSColor controlTextColor]];
[self.enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
[self.enable_fullscreen_menu_text setTextColor:XQuartzRootlessDefault ? NSColor.disabledControlTextColor : NSColor.controlTextColor];
DarwinSendDDXEvent(kXquartzSetRootless, 1, XQuartzRootlessDefault);
@ -677,102 +688,85 @@ extern char *bundle_id_prefix;
DarwinSendDDXEvent(kXquartzToggleFullscreen, 0);
}
- (void) set_can_quit:(OSX_BOOL)state
{
can_quit = state;
}
- (IBAction)prefs_changed:sender
{
if (!sender)
return;
if (sender == fake_buttons) {
darwinFakeButtons = [fake_buttons intValue];
if (sender == self.fake_buttons) {
darwinFakeButtons = self.fake_buttons.intValue;
[NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons];
}
else if (sender == enable_keyequivs) {
XQuartzEnableKeyEquivalents = [enable_keyequivs intValue];
else if (sender == self.enable_keyequivs) {
XQuartzEnableKeyEquivalents = self.enable_keyequivs.intValue;
[NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:
XQuartzEnableKeyEquivalents];
}
else if (sender == sync_keymap) {
darwinSyncKeymap = [sync_keymap intValue];
else if (sender == self.sync_keymap) {
darwinSyncKeymap = self.sync_keymap.intValue;
[NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap];
}
else if (sender == enable_fullscreen_menu) {
XQuartzFullscreenMenu = [enable_fullscreen_menu intValue];
else if (sender == self.enable_fullscreen_menu) {
XQuartzFullscreenMenu = self.enable_fullscreen_menu.intValue;
[NSApp prefs_set_boolean:@PREFS_FULLSCREEN_MENU value:
XQuartzFullscreenMenu];
}
else if (sender == option_sends_alt) {
else if (sender == self.option_sends_alt) {
BOOL prev_opt_sends_alt = XQuartzOptionSendsAlt;
XQuartzOptionSendsAlt = [option_sends_alt intValue];
XQuartzOptionSendsAlt = self.option_sends_alt.intValue;
[NSApp prefs_set_boolean:@PREFS_OPTION_SENDS_ALT value:
XQuartzOptionSendsAlt];
if (prev_opt_sends_alt != XQuartzOptionSendsAlt)
QuartsResyncKeymap(TRUE);
}
else if (sender == click_through) {
[NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through
intValue]];
else if (sender == self.click_through) {
[NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:self.click_through.intValue];
}
else if (sender == focus_follows_mouse) {
[NSApp prefs_set_boolean:@PREFS_FFM value:[focus_follows_mouse
intValue]];
else if (sender == self.focus_follows_mouse) {
[NSApp prefs_set_boolean:@PREFS_FFM value:self.focus_follows_mouse.intValue];
}
else if (sender == focus_on_new_window) {
[NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:[
focus_on_new_window intValue]];
else if (sender == self.focus_on_new_window) {
[NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:self.focus_on_new_window.intValue];
}
else if (sender == enable_auth) {
[NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]
];
else if (sender == self.enable_auth) {
[NSApp prefs_set_boolean:@PREFS_NO_AUTH value:!self.enable_auth.intValue];
}
else if (sender == enable_tcp) {
[NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]];
else if (sender == self.enable_tcp) {
[NSApp prefs_set_boolean:@PREFS_NO_TCP value:!self.enable_tcp.intValue];
}
else if (sender == depth) {
[NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]];
else if (sender == self.depth) {
[NSApp prefs_set_integer:@PREFS_DEPTH value:self.depth.selectedTag];
}
else if (sender == sync_pasteboard) {
BOOL pbproxy_active = [sync_pasteboard intValue];
else if (sender == self.sync_pasteboard) {
BOOL pbproxy_active = self.sync_pasteboard.intValue;
[NSApp prefs_set_boolean:@PREFS_SYNC_PB value:pbproxy_active];
[sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[sync_pasteboard_to_primary setEnabled:pbproxy_active];
[sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
[sync_primary_immediately setEnabled:pbproxy_active];
[self.sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[self.sync_pasteboard_to_primary setEnabled:pbproxy_active];
[self.sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
[self.sync_primary_immediately setEnabled:pbproxy_active];
// setEnabled doesn't do this...
[sync_text1 setTextColor:pbproxy_active ?[NSColor controlTextColor] :
[NSColor disabledControlTextColor]];
[sync_text2 setTextColor:pbproxy_active ?[NSColor controlTextColor] :
[NSColor disabledControlTextColor]];
[self.sync_text1 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
[self.sync_text2 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
}
else if (sender == sync_pasteboard_to_clipboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:[
sync_pasteboard_to_clipboard intValue]];
else if (sender == self.sync_pasteboard_to_clipboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD value:self.sync_pasteboard_to_clipboard.intValue];
}
else if (sender == sync_pasteboard_to_primary) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:[
sync_pasteboard_to_primary intValue]];
else if (sender == self.sync_pasteboard_to_primary) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PB_TO_PRIMARY value:self.sync_pasteboard_to_primary.intValue];
}
else if (sender == sync_clipboard_to_pasteboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:[
sync_clipboard_to_pasteboard intValue]];
else if (sender == self.sync_clipboard_to_pasteboard) {
[NSApp prefs_set_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB value:self.sync_clipboard_to_pasteboard.intValue];
}
else if (sender == sync_primary_immediately) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:[
sync_primary_immediately intValue]];
else if (sender == self.sync_primary_immediately) {
[NSApp prefs_set_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT value:self.sync_primary_immediately.intValue];
}
else if (sender == scroll_in_device_direction) {
XQuartzScrollInDeviceDirection =
[scroll_in_device_direction intValue];
[NSApp prefs_set_boolean:@PREFS_SCROLL_IN_DEV_DIRECTION value:
XQuartzScrollInDeviceDirection];
else if (sender == self.scroll_in_device_direction) {
XQuartzScrollInDeviceDirection = self.scroll_in_device_direction.intValue;
[NSApp prefs_set_boolean:@PREFS_SCROLL_IN_DEV_DIRECTION value:XQuartzScrollInDeviceDirection];
}
[NSApp prefs_synchronize];
@ -785,71 +779,42 @@ extern char *bundle_id_prefix;
BOOL pbproxy_active =
[NSApp prefs_get_boolean:@PREFS_SYNC_PB default:YES];
// Remove preferences from the GUI which are not supported
// TODO: Change 1117 to NSAppKitVersionNumber10_7 when it is defined
if (scroll_in_device_direction && NSAppKitVersionNumber < 1117) {
[scroll_in_device_direction removeFromSuperview];
scroll_in_device_direction = nil;
}
else {
[scroll_in_device_direction setIntValue:
XQuartzScrollInDeviceDirection];
}
[self.scroll_in_device_direction setIntValue:XQuartzScrollInDeviceDirection];
[fake_buttons setIntValue:darwinFakeButtons];
[enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents];
[sync_keymap setIntValue:darwinSyncKeymap];
[option_sends_alt setIntValue:XQuartzOptionSendsAlt];
[click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH
default:NO]];
[focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM
default:NO]];
[focus_on_new_window setIntValue:[NSApp prefs_get_boolean:
@PREFS_FOCUS_ON_NEW_WINDOW default:YES]
];
[self.fake_buttons setIntValue:darwinFakeButtons];
[self.enable_keyequivs setIntValue:XQuartzEnableKeyEquivalents];
[self.sync_keymap setIntValue:darwinSyncKeymap];
[self.option_sends_alt setIntValue:XQuartzOptionSendsAlt];
[self.click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]];
[self.focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]];
[self.focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]];
[enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default
:NO]];
[enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:
NO]];
[self.enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]];
[self.enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]];
[depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp
prefs_get_integer:
@PREFS_DEPTH default:
-1]]];
[self.depth selectItemAtIndex:[self.depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]];
[sync_pasteboard setIntValue:pbproxy_active];
[sync_pasteboard_to_clipboard setIntValue:[NSApp prefs_get_boolean:
@PREFS_SYNC_PB_TO_CLIPBOARD
default:YES]];
[sync_pasteboard_to_primary setIntValue:[NSApp prefs_get_boolean:
@PREFS_SYNC_PB_TO_PRIMARY
default:YES]];
[sync_clipboard_to_pasteboard setIntValue:[NSApp prefs_get_boolean:
@PREFS_SYNC_CLIPBOARD_TO_PB
default:YES]];
[sync_primary_immediately setIntValue:[NSApp prefs_get_boolean:
@PREFS_SYNC_PRIMARY_ON_SELECT
default:NO]];
[self.sync_pasteboard setIntValue:pbproxy_active];
[self.sync_pasteboard_to_clipboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_CLIPBOARD default:YES]];
[self.sync_pasteboard_to_primary setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PB_TO_PRIMARY default:YES]];
[self.sync_clipboard_to_pasteboard setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_CLIPBOARD_TO_PB default:YES]];
[self.sync_primary_immediately setIntValue:[NSApp prefs_get_boolean:@PREFS_SYNC_PRIMARY_ON_SELECT default:NO]];
[sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[sync_pasteboard_to_primary setEnabled:pbproxy_active];
[sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
[sync_primary_immediately setEnabled:pbproxy_active];
[self.sync_pasteboard_to_clipboard setEnabled:pbproxy_active];
[self.sync_pasteboard_to_primary setEnabled:pbproxy_active];
[self.sync_clipboard_to_pasteboard setEnabled:pbproxy_active];
[self.sync_primary_immediately setEnabled:pbproxy_active];
// setEnabled doesn't do this...
[sync_text1 setTextColor:pbproxy_active ?[NSColor controlTextColor] : [
NSColor disabledControlTextColor]];
[sync_text2 setTextColor:pbproxy_active ?[NSColor controlTextColor] : [
NSColor disabledControlTextColor]];
[self.sync_text1 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
[self.sync_text2 setTextColor:pbproxy_active ? NSColor.controlTextColor : NSColor.disabledControlTextColor];
[enable_fullscreen setIntValue:!XQuartzRootlessDefault];
[enable_fullscreen_menu setIntValue:XQuartzFullscreenMenu];
[enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
[enable_fullscreen_menu_text setTextColor:XQuartzRootlessDefault ?[
NSColor disabledControlTextColor] : [NSColor controlTextColor]];
[self.enable_fullscreen setIntValue:!XQuartzRootlessDefault];
[self.enable_fullscreen_menu setIntValue:XQuartzFullscreenMenu];
[self.enable_fullscreen_menu setEnabled:!XQuartzRootlessDefault];
[self.enable_fullscreen_menu_text setTextColor:XQuartzRootlessDefault ? NSColor.disabledControlTextColor : NSColor.controlTextColor];
[prefs_panel makeKeyAndOrderFront:sender];
[self.prefs_panel makeKeyAndOrderFront:sender];
}
- (IBAction) quit:sender
@ -865,11 +830,12 @@ extern char *bundle_id_prefix;
- (OSX_BOOL) validateMenuItem:(NSMenuItem *)item
{
NSMenu *menu = [item menu];
NSMenu * const dock_menu = self.dock_menu;
if (item == toggle_fullscreen_item)
if (item == self.toggle_fullscreen_item)
return !XQuartzIsRootless;
else if (menu == [X11App windowsMenu] || menu == dock_menu
|| (menu == [x11_about_item menu] && [item tag] == 42))
|| (menu == [self.x11_about_item menu] && [item tag] == 42))
return (AppleWMSelectedEvents() & AppleWMControllerNotifyMask) != 0;
else
return TRUE;
@ -897,7 +863,7 @@ extern char *bundle_id_prefix;
NSString *msg;
NSString *title;
if (can_quit ||
if (self.can_quit ||
[X11App prefs_get_boolean:@PREFS_NO_QUIT_ALERT default:NO])
return NSTerminateNow;
@ -936,26 +902,26 @@ extern char *bundle_id_prefix;
{
x_list *node;
finished_launching = YES;
self.finished_launching = YES;
for (node = pending_apps; node != NULL; node = node->next) {
for (node = self.pending_apps; node != NULL; node = node->next) {
NSString *filename = node->data;
[self launch_client:filename];
[filename release];
}
x_list_free(pending_apps);
pending_apps = NULL;
x_list_free(self.pending_apps);
self.pending_apps = NULL;
}
- (OSX_BOOL) application:(NSApplication *)app openFile:(NSString *)filename
{
const char *name = [filename UTF8String];
if (finished_launching)
if (self.finished_launching)
[self launch_client:filename];
else if (name[0] != ':') /* ignore display names */
pending_apps = x_list_prepend(pending_apps, [filename retain]);
self.pending_apps = x_list_prepend(self.pending_apps, [filename retain]);
/* FIXME: report failures. */
return YES;

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