[PATCH xserver v2] xwayland: Add grab protocol support

Peter Hutterer peter.hutterer at who-t.net
Thu Jun 8 07:13:59 UTC 2017


On Wed, Jun 07, 2017 at 09:31:18AM +0200, Olivier Fourdan wrote:
> Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>  v2: Remove break after return statement (Peter's review)
> 
>  configure.ac                 |  2 +-
>  hw/xwayland/Makefile.am      |  7 +++-
>  hw/xwayland/xwayland-input.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
>  hw/xwayland/xwayland.c       |  2 +-
>  hw/xwayland/xwayland.h       |  5 ++-
>  5 files changed, 111 insertions(+), 4 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 40ac1e7..50a6a8e 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -2353,7 +2353,7 @@ AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
>  
>  dnl Xwayland DDX
>  
> -XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.5 $LIBDRM epoxy"
> +XWAYLANDMODULES="wayland-client >= 1.3.0 wayland-protocols >= 1.7 $LIBDRM epoxy"

btw, this one needs to be changed to 1.8 or whatever it comes in, afacit the
grab bits aren't in the protocols yet.

Cheers,
   Peter

>  if test "x$XF86VIDMODE" = xyes; then
>  	XWAYLANDMODULES="$XWAYLANDMODULES $VIDMODEPROTO"
>  fi
> diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am
> index 7eda9be..c14b95b 100644
> --- a/hw/xwayland/Makefile.am
> +++ b/hw/xwayland/Makefile.am
> @@ -57,7 +57,9 @@ Xwayland_built_sources +=					\
>  	pointer-constraints-unstable-v1-client-protocol.h	\
>  	pointer-constraints-unstable-v1-protocol.c		\
>  	tablet-unstable-v2-client-protocol.h			\
> -	tablet-unstable-v2-protocol.c
> +	tablet-unstable-v2-protocol.c				\
> +	xwayland-keyboard-grab-unstable-v1-protocol.c		\
> +	xwayland-keyboard-grab-unstable-v1-client-protocol.h
>  
>  nodist_Xwayland_SOURCES = $(Xwayland_built_sources)
>  CLEANFILES = $(Xwayland_built_sources)
> @@ -83,6 +85,9 @@ pointer-constraints-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)
>  tablet-unstable-v2-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml
>  	$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
>  tablet-unstable-v2-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/unstable/tablet/tablet-unstable-v2.xml
> +xwayland-keyboard-grab-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
> +	$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
> +xwayland-keyboard-grab-unstable-v1-client-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
>  	$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
>  
>  %-protocol.c : %.xml
> diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
> index 02fdf6e..ae5d554 100644
> --- a/hw/xwayland/xwayland-input.c
> +++ b/hw/xwayland/xwayland-input.c
> @@ -1016,6 +1016,85 @@ static const struct wl_touch_listener touch_listener = {
>      touch_handle_cancel
>  };
>  
> +static struct xwl_seat *
> +find_matching_seat(DeviceIntPtr device)
> +{
> +    DeviceIntPtr dev;
> +
> +    for (dev = inputInfo.devices; dev; dev = dev->next)
> +        if (dev->deviceProc == xwl_keyboard_proc &&
> +            device == GetMaster(dev, MASTER_KEYBOARD))
> +                return (struct xwl_seat *) dev->public.devicePrivate;
> +
> +    return NULL;
> +}
> +
> +static void
> +release_grab(struct xwl_seat *xwl_seat)
> +{
> +    if (xwl_seat->keyboard_grab)
> +        zwp_xwayland_keyboard_grab_v1_destroy(xwl_seat->keyboard_grab);
> +    xwl_seat->keyboard_grab = NULL;
> +}
> +
> +static void
> +set_grab(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window)
> +{
> +    struct xwl_screen *xwl_screen;
> +
> +    if (!xwl_window)
> +        return;
> +
> +    /* We already have a grab */
> +    if (xwl_seat->keyboard_grab)
> +        release_grab (xwl_seat);
> +
> +    xwl_screen = xwl_seat->xwl_screen;
> +    if (xwl_screen->wp_grab)
> +        xwl_seat->keyboard_grab =
> +            zwp_xwayland_keyboard_grab_manager_v1_grab_keyboard(xwl_screen->wp_grab,
> +                                                                xwl_window->surface,
> +                                                                xwl_seat->seat);
> +}
> +
> +static void
> +xwl_keyboard_activate_grab(DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bool passive)
> +{
> +    struct xwl_seat *xwl_seat = device->public.devicePrivate;
> +
> +    /* We are not interested in passive grabs */
> +    if (!passive) {
> +        /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
> +        if (xwl_seat == NULL)
> +            xwl_seat = find_matching_seat(device);
> +        if (xwl_seat)
> +            set_grab(xwl_seat, xwl_window_from_window(grab->window));
> +    }
> +
> +    ActivateKeyboardGrab(device, grab, time, passive);
> +}
> +
> +static void
> +xwl_keyboard_deactivate_grab(DeviceIntPtr device)
> +{
> +    struct xwl_seat *xwl_seat = device->public.devicePrivate;
> +
> +    /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
> +    if (xwl_seat == NULL)
> +        xwl_seat = find_matching_seat(device);
> +    if (xwl_seat)
> +        release_grab (xwl_seat);
> +
> +    DeactivateKeyboardGrab(device);
> +}
> +
> +static void
> +setup_keyboard_grab_handler (DeviceIntPtr device)
> +{
> +    device->deviceGrab.ActivateGrab = xwl_keyboard_activate_grab;
> +    device->deviceGrab.DeactivateGrab = xwl_keyboard_deactivate_grab;
> +}
> +
>  static DeviceIntPtr
>  add_device(struct xwl_seat *xwl_seat,
>             const char *driver, DeviceProc device_proc)
> @@ -1104,6 +1183,8 @@ release_relative_pointer(struct xwl_seat *xwl_seat)
>  static void
>  init_keyboard(struct xwl_seat *xwl_seat)
>  {
> +    DeviceIntPtr master;
> +
>      xwl_seat->wl_keyboard = wl_seat_get_keyboard(xwl_seat->seat);
>      wl_keyboard_add_listener(xwl_seat->wl_keyboard,
>                               &keyboard_listener, xwl_seat);
> @@ -1115,6 +1196,10 @@ init_keyboard(struct xwl_seat *xwl_seat)
>      }
>      EnableDevice(xwl_seat->keyboard, TRUE);
>      xwl_seat->keyboard->key->xkbInfo->checkRepeat = keyboard_check_repeat;
> +
> +    master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD);
> +    if (master)
> +        setup_keyboard_grab_handler(master);
>  }
>  
>  static void
> @@ -1172,6 +1257,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
>      if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->wl_keyboard == NULL) {
>          init_keyboard(xwl_seat);
>      } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && xwl_seat->wl_keyboard) {
> +        release_grab(xwl_seat);
>          release_keyboard(xwl_seat);
>      }
>  
> @@ -1271,6 +1357,7 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
>  
>      release_tablet_manager_seat(xwl_seat);
>  
> +    release_grab(xwl_seat);
>      wl_seat_destroy(xwl_seat->seat);
>      xwl_cursor_release(&xwl_seat->cursor);
>      wl_array_release(&xwl_seat->keys);
> @@ -2287,6 +2374,16 @@ init_pointer_constraints(struct xwl_screen *xwl_screen,
>  }
>  
>  static void
> +init_keyboard_grab(struct xwl_screen *xwl_screen,
> +                   uint32_t id, uint32_t version)
> +{
> +    xwl_screen->wp_grab =
> +         wl_registry_bind(xwl_screen->registry, id,
> +                          &zwp_xwayland_keyboard_grab_manager_v1_interface,
> +                          1);
> +}
> +
> +static void
>  input_handler(void *data, struct wl_registry *registry, uint32_t id,
>                const char *interface, uint32_t version)
>  {
> @@ -2301,6 +2398,8 @@ input_handler(void *data, struct wl_registry *registry, uint32_t id,
>          init_pointer_constraints(xwl_screen, id, version);
>      } else if (strcmp(interface, "zwp_tablet_manager_v2") == 0) {
>          init_tablet_manager(xwl_screen, id, version);
> +    } else if (strcmp(interface, "zwp_xwayland_keyboard_grab_manager_v1") == 0) {
> +        init_keyboard_grab(xwl_screen, id, version);
>      }
>  }
>  
> diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
> index 551443f..cb929ca 100644
> --- a/hw/xwayland/xwayland.c
> +++ b/hw/xwayland/xwayland.c
> @@ -234,7 +234,7 @@ xwl_close_screen(ScreenPtr screen)
>      return screen->CloseScreen(screen);
>  }
>  
> -static struct xwl_window *
> +struct xwl_window *
>  xwl_window_from_window(WindowPtr window)
>  {
>      struct xwl_window *xwl_window;
> diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
> index a05e086..4e59c98 100644
> --- a/hw/xwayland/xwayland.h
> +++ b/hw/xwayland/xwayland.h
> @@ -45,6 +45,7 @@
>  #include "relative-pointer-unstable-v1-client-protocol.h"
>  #include "pointer-constraints-unstable-v1-client-protocol.h"
>  #include "tablet-unstable-v2-client-protocol.h"
> +#include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
>  
>  struct xwl_screen {
>      int width;
> @@ -80,7 +81,7 @@ struct xwl_screen {
>      struct wl_shell *shell;
>      struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
>      struct zwp_pointer_constraints_v1 *pointer_constraints;
> -
> +    struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
>      uint32_t serial;
>  
>  #define XWL_FORMAT_ARGB8888 (1 << 0)
> @@ -188,6 +189,7 @@ struct xwl_seat {
>      struct xorg_list tablets;
>      struct xorg_list tablet_tools;
>      struct xorg_list tablet_pads;
> +    struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab;
>  };
>  
>  struct xwl_tablet {
> @@ -305,6 +307,7 @@ RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
>  void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);
>  struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);
>  
> +struct xwl_window *xwl_window_from_window(WindowPtr window);
>  
>  Bool xwl_shm_create_screen_resources(ScreenPtr screen);
>  PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height,
> -- 
> 2.9.4
> 


More information about the wayland-devel mailing list