Compare commits
	
		
			5 Commits
		
	
	
		
			3.21.1
			...
			wip/garnac
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3b17f67b97 | ||
| 
						 | 
					0db347d642 | ||
| 
						 | 
					6963dbef16 | ||
| 
						 | 
					2b96fc7d0c | ||
| 
						 | 
					109389acf0 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -66,6 +66,8 @@ src/gtk-shell-protocol.c
 | 
			
		||||
src/gtk-shell-server-protocol.h
 | 
			
		||||
src/xdg-shell-protocol.c
 | 
			
		||||
src/xdg-shell-server-protocol.h
 | 
			
		||||
src/pointer-gestures-protocol.c
 | 
			
		||||
src/pointer-gestures-server-protocol.h
 | 
			
		||||
src/xserver-protocol.c
 | 
			
		||||
src/xserver-server-protocol.h
 | 
			
		||||
src/meta/meta-version.h
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,8 @@ mutter_built_sources = \
 | 
			
		||||
 | 
			
		||||
if HAVE_WAYLAND
 | 
			
		||||
mutter_built_sources += \
 | 
			
		||||
	pointer-gestures-protocol.c		\
 | 
			
		||||
	pointer-gestures-server-protocol.h	\
 | 
			
		||||
	gtk-shell-protocol.c			\
 | 
			
		||||
	gtk-shell-server-protocol.h		\
 | 
			
		||||
	xdg-shell-protocol.c			\
 | 
			
		||||
@@ -53,6 +55,7 @@ mutter_built_sources += \
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
wayland_protocols =				\
 | 
			
		||||
	wayland/protocol/pointer-gestures.xml	\
 | 
			
		||||
	wayland/protocol/gtk-shell.xml		\
 | 
			
		||||
	wayland/protocol/xdg-shell.xml		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
@@ -252,6 +255,12 @@ libmutter_la_SOURCES +=				\
 | 
			
		||||
	wayland/meta-wayland-data-device.c      \
 | 
			
		||||
	wayland/meta-wayland-data-device.h      \
 | 
			
		||||
	wayland/meta-wayland-data-device-private.h	\
 | 
			
		||||
	wayland/meta-wayland-pointer-gestures.c	\
 | 
			
		||||
	wayland/meta-wayland-pointer-gestures.h	\
 | 
			
		||||
	wayland/meta-wayland-pointer-gesture-swipe.c	\
 | 
			
		||||
	wayland/meta-wayland-pointer-gesture-swipe.h	\
 | 
			
		||||
	wayland/meta-wayland-pointer-gesture-pinch.c	\
 | 
			
		||||
	wayland/meta-wayland-pointer-gesture-pinch.h	\
 | 
			
		||||
	wayland/meta-wayland-keyboard.c		\
 | 
			
		||||
	wayland/meta-wayland-keyboard.h		\
 | 
			
		||||
	wayland/meta-wayland-pointer.c		\
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										160
									
								
								src/wayland/meta-wayland-pointer-gesture-pinch.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/wayland/meta-wayland-pointer-gesture-pinch.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Wayland Support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-pointer-gesture-pinch.h"
 | 
			
		||||
#include "meta-wayland-pointer.h"
 | 
			
		||||
#include "meta-wayland-surface.h"
 | 
			
		||||
#include "pointer-gestures-server-protocol.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_pinch_begin (MetaWaylandPointer *pointer,
 | 
			
		||||
                    const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  uint32_t serial;
 | 
			
		||||
 | 
			
		||||
  pointer_client = pointer->focus_client;
 | 
			
		||||
  serial = wl_display_next_serial (pointer->display);
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      _wl_pointer_gesture_pinch_send_begin (resource, serial,
 | 
			
		||||
                                            clutter_event_get_time (event),
 | 
			
		||||
                                            pointer->focus_surface->resource,
 | 
			
		||||
                                            2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_pinch_update (MetaWaylandPointer *pointer,
 | 
			
		||||
                     const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  gdouble dx, dy, scale, rotation;
 | 
			
		||||
 | 
			
		||||
  pointer_client = pointer->focus_client;
 | 
			
		||||
  clutter_event_get_gesture_motion_delta (event, &dx, &dy);
 | 
			
		||||
  rotation = clutter_event_get_gesture_pinch_angle_delta (event);
 | 
			
		||||
  scale = clutter_event_get_gesture_pinch_scale (event);
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      _wl_pointer_gesture_pinch_send_update (resource,
 | 
			
		||||
                                             clutter_event_get_time (event),
 | 
			
		||||
                                             wl_fixed_from_double (dx),
 | 
			
		||||
                                             wl_fixed_from_double (dy),
 | 
			
		||||
                                             wl_fixed_from_double (scale),
 | 
			
		||||
                                             wl_fixed_from_double (rotation));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_pinch_end (MetaWaylandPointer *pointer,
 | 
			
		||||
                  const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  gboolean cancelled = FALSE;
 | 
			
		||||
  uint32_t serial;
 | 
			
		||||
 | 
			
		||||
  pointer_client = pointer->focus_client;
 | 
			
		||||
  serial = wl_display_next_serial (pointer->display);
 | 
			
		||||
 | 
			
		||||
  if (event->touchpad_pinch.phase == CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL)
 | 
			
		||||
    cancelled = TRUE;
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      _wl_pointer_gesture_pinch_send_end (resource, serial,
 | 
			
		||||
                                          clutter_event_get_time (event),
 | 
			
		||||
                                          cancelled);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_pointer_gesture_pinch_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                 const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  if (event->type != CLUTTER_TOUCHPAD_PINCH)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!pointer->focus_client)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (event->touchpad_pinch.phase)
 | 
			
		||||
    {
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN:
 | 
			
		||||
      handle_pinch_begin (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE:
 | 
			
		||||
      handle_pinch_update (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_END:
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL:
 | 
			
		||||
      handle_pinch_end (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pointer_gesture_pinch_destroy (struct wl_client   *client,
 | 
			
		||||
                               struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
  wl_resource_destroy (resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct _wl_pointer_gesture_pinch_interface pointer_gesture_pinch_interface = {
 | 
			
		||||
  pointer_gesture_pinch_destroy
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_pointer_gesture_pinch_create_new_resource (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                        struct wl_client   *client,
 | 
			
		||||
                                                        struct wl_resource *gestures_resource,
 | 
			
		||||
                                                        uint32_t            id)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *res;
 | 
			
		||||
 | 
			
		||||
  pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
 | 
			
		||||
  g_return_if_fail (pointer_client != NULL);
 | 
			
		||||
 | 
			
		||||
  res = wl_resource_create (client, &_wl_pointer_gesture_pinch_interface,
 | 
			
		||||
                            wl_resource_get_version (gestures_resource), id);
 | 
			
		||||
  wl_resource_set_implementation (res, &pointer_gesture_pinch_interface, pointer,
 | 
			
		||||
                                  meta_wayland_pointer_unbind_pointer_client_resource);
 | 
			
		||||
  wl_list_insert (&pointer_client->pinch_gesture_resources,
 | 
			
		||||
                  wl_resource_get_link (res));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								src/wayland/meta-wayland-pointer-gesture-pinch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/wayland/meta-wayland-pointer-gesture-pinch.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Wayland Support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_WAYLAND_POINTER_GESTURE_PINCH_H
 | 
			
		||||
#define META_WAYLAND_POINTER_GESTURE_PINCH_H
 | 
			
		||||
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-types.h"
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_pointer_gesture_pinch_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                          const ClutterEvent *event);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_pointer_gesture_pinch_create_new_resource (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                             struct wl_client   *client,
 | 
			
		||||
                                                             struct wl_resource *gestures_resource,
 | 
			
		||||
                                                             uint32_t            id);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_POINTER_GESTURE_PINCH_H */
 | 
			
		||||
							
								
								
									
										156
									
								
								src/wayland/meta-wayland-pointer-gesture-swipe.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								src/wayland/meta-wayland-pointer-gesture-swipe.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Wayland Support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-pointer-gesture-swipe.h"
 | 
			
		||||
#include "meta-wayland-pointer.h"
 | 
			
		||||
#include "meta-wayland-surface.h"
 | 
			
		||||
#include "pointer-gestures-server-protocol.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_swipe_begin (MetaWaylandPointer *pointer,
 | 
			
		||||
                    const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  uint32_t serial, fingers;
 | 
			
		||||
 | 
			
		||||
  pointer_client = pointer->focus_client;
 | 
			
		||||
  serial = wl_display_next_serial (pointer->display);
 | 
			
		||||
  fingers = clutter_event_get_gesture_swipe_finger_count (event);
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      _wl_pointer_gesture_swipe_send_begin (resource, serial,
 | 
			
		||||
                                            clutter_event_get_time (event),
 | 
			
		||||
                                            pointer->focus_surface->resource,
 | 
			
		||||
                                            fingers);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_swipe_update (MetaWaylandPointer *pointer,
 | 
			
		||||
                     const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  gdouble dx, dy;
 | 
			
		||||
 | 
			
		||||
  pointer_client = pointer->focus_client;
 | 
			
		||||
  clutter_event_get_gesture_motion_delta (event, &dx, &dy);
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      _wl_pointer_gesture_swipe_send_update (resource,
 | 
			
		||||
                                             clutter_event_get_time (event),
 | 
			
		||||
                                             wl_fixed_from_double (dx),
 | 
			
		||||
                                             wl_fixed_from_double (dy));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_swipe_end (MetaWaylandPointer *pointer,
 | 
			
		||||
                  const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  gboolean cancelled = FALSE;
 | 
			
		||||
  uint32_t serial;
 | 
			
		||||
 | 
			
		||||
  pointer_client = pointer->focus_client;
 | 
			
		||||
  serial = wl_display_next_serial (pointer->display);
 | 
			
		||||
 | 
			
		||||
  if (event->touchpad_swipe.phase == CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL)
 | 
			
		||||
    cancelled = TRUE;
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      _wl_pointer_gesture_swipe_send_end (resource, serial,
 | 
			
		||||
                                          clutter_event_get_time (event),
 | 
			
		||||
                                          cancelled);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_pointer_gesture_swipe_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                 const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  if (event->type != CLUTTER_TOUCHPAD_SWIPE)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!pointer->focus_client)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (event->touchpad_swipe.phase)
 | 
			
		||||
    {
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_BEGIN:
 | 
			
		||||
      handle_swipe_begin (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE:
 | 
			
		||||
      handle_swipe_update (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
    case CLUTTER_TOUCHPAD_GESTURE_PHASE_END:
 | 
			
		||||
      handle_swipe_end (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pointer_gesture_swipe_release (struct wl_client   *client,
 | 
			
		||||
                               struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
  wl_resource_destroy (resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct _wl_pointer_gesture_swipe_interface pointer_gesture_swipe_interface = {
 | 
			
		||||
  pointer_gesture_swipe_release
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_pointer_gesture_swipe_create_new_resource (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                        struct wl_client   *client,
 | 
			
		||||
                                                        struct wl_resource *pointer_resource,
 | 
			
		||||
                                                        uint32_t            id)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_resource *res;
 | 
			
		||||
 | 
			
		||||
  pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
 | 
			
		||||
  g_return_if_fail (pointer_client != NULL);
 | 
			
		||||
 | 
			
		||||
  res = wl_resource_create (client, &_wl_pointer_gesture_swipe_interface,
 | 
			
		||||
                            wl_resource_get_version (pointer_resource), id);
 | 
			
		||||
  wl_resource_set_implementation (res, &pointer_gesture_swipe_interface, pointer,
 | 
			
		||||
                                  meta_wayland_pointer_unbind_pointer_client_resource);
 | 
			
		||||
  wl_list_insert (&pointer_client->swipe_gesture_resources,
 | 
			
		||||
                  wl_resource_get_link (res));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								src/wayland/meta-wayland-pointer-gesture-swipe.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/wayland/meta-wayland-pointer-gesture-swipe.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Wayland Support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_WAYLAND_POINTER_GESTURE_SWIPE_H
 | 
			
		||||
#define META_WAYLAND_POINTER_GESTURE_SWIPE_H
 | 
			
		||||
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-types.h"
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_pointer_gesture_swipe_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                          const ClutterEvent *event);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_pointer_gesture_swipe_create_new_resource (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                             struct wl_client   *client,
 | 
			
		||||
                                                             struct wl_resource *pointer_resource,
 | 
			
		||||
                                                             uint32_t            id);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_POINTER_GESTURE_SWIPE_H */
 | 
			
		||||
							
								
								
									
										82
									
								
								src/wayland/meta-wayland-pointer-gestures.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/wayland/meta-wayland-pointer-gestures.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Wayland Support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include "meta-wayland-pointer-gestures.h"
 | 
			
		||||
#include "pointer-gestures-server-protocol.h"
 | 
			
		||||
#include "meta-wayland-versions.h"
 | 
			
		||||
#include "meta-wayland-private.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
gestures_get_swipe (struct wl_client   *client,
 | 
			
		||||
                    struct wl_resource *resource,
 | 
			
		||||
                    uint32_t            id,
 | 
			
		||||
                    struct wl_resource *pointer_resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_gesture_swipe_create_new_resource (pointer, client, resource, id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
gestures_get_pinch (struct wl_client   *client,
 | 
			
		||||
                    struct wl_resource *resource,
 | 
			
		||||
                    uint32_t            id,
 | 
			
		||||
                    struct wl_resource *pointer_resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointer *pointer = wl_resource_get_user_data (pointer_resource);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_gesture_pinch_create_new_resource (pointer, client, resource, id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct _wl_pointer_gestures_interface pointer_gestures_interface = {
 | 
			
		||||
  gestures_get_swipe,
 | 
			
		||||
  gestures_get_pinch
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
bind_pointer_gestures (struct wl_client *client,
 | 
			
		||||
                       void             *data,
 | 
			
		||||
                       guint32           version,
 | 
			
		||||
                       guint32           id)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerGestures *gestures = data;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
 | 
			
		||||
  resource = wl_resource_create (client, &_wl_pointer_gestures_interface, version, id);
 | 
			
		||||
  wl_resource_set_implementation (resource, &pointer_gestures_interface,
 | 
			
		||||
                                  gestures, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
  wl_global_create (compositor->wayland_display,
 | 
			
		||||
                    &_wl_pointer_gestures_interface,
 | 
			
		||||
                    META_WL_POINTER_GESTURES_VERSION,
 | 
			
		||||
                    gestures, bind_pointer_gestures);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								src/wayland/meta-wayland-pointer-gestures.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/wayland/meta-wayland-pointer-gestures.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Wayland Support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_WAYLAND_POINTER_GESTURES_H
 | 
			
		||||
#define META_WAYLAND_POINTER_GESTURES_H
 | 
			
		||||
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-types.h"
 | 
			
		||||
 | 
			
		||||
void meta_wayland_pointer_gestures_init (MetaWaylandCompositor *compositor);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_POINTER_GESTURES_H */
 | 
			
		||||
@@ -58,10 +58,121 @@
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unbind_resource (struct wl_resource *resource)
 | 
			
		||||
static MetaWaylandPointerClient *
 | 
			
		||||
meta_wayland_pointer_client_new (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
 | 
			
		||||
  pointer_client = g_slice_new0 (MetaWaylandPointerClient);
 | 
			
		||||
  wl_list_init (&pointer_client->pointer_resources);
 | 
			
		||||
  wl_list_init (&pointer_client->swipe_gesture_resources);
 | 
			
		||||
  wl_list_init (&pointer_client->pinch_gesture_resources);
 | 
			
		||||
 | 
			
		||||
  return pointer_client;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_pointer_client_free (MetaWaylandPointerClient *pointer_client)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
 | 
			
		||||
  /* Since we make every wl_pointer resource defunct when we stop advertising
 | 
			
		||||
   * the pointer capability on the wl_seat, we need to make sure all the
 | 
			
		||||
   * resources in the pointer client instance gets removed.
 | 
			
		||||
   */
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->pointer_resources)
 | 
			
		||||
    {
 | 
			
		||||
      wl_list_remove (wl_resource_get_link (resource));
 | 
			
		||||
      wl_list_init (wl_resource_get_link (resource));
 | 
			
		||||
    }
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->swipe_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      wl_list_remove (wl_resource_get_link (resource));
 | 
			
		||||
      wl_list_init (wl_resource_get_link (resource));
 | 
			
		||||
    }
 | 
			
		||||
  wl_resource_for_each (resource, &pointer_client->pinch_gesture_resources)
 | 
			
		||||
    {
 | 
			
		||||
      wl_list_remove (wl_resource_get_link (resource));
 | 
			
		||||
      wl_list_init (wl_resource_get_link (resource));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_slice_free (MetaWaylandPointerClient, pointer_client);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_wayland_pointer_client_is_empty (MetaWaylandPointerClient *pointer_client)
 | 
			
		||||
{
 | 
			
		||||
  return (wl_list_empty (&pointer_client->pointer_resources) &&
 | 
			
		||||
          wl_list_empty (&pointer_client->swipe_gesture_resources) &&
 | 
			
		||||
          wl_list_empty (&pointer_client->pinch_gesture_resources));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWaylandPointerClient *
 | 
			
		||||
meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
 | 
			
		||||
                                         struct wl_client   *client)
 | 
			
		||||
{
 | 
			
		||||
  return g_hash_table_lookup (pointer->pointer_clients, client);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWaylandPointerClient *
 | 
			
		||||
meta_wayland_pointer_ensure_pointer_client (MetaWaylandPointer *pointer,
 | 
			
		||||
                                            struct wl_client   *client)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
 | 
			
		||||
  pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
 | 
			
		||||
  if (pointer_client)
 | 
			
		||||
    return pointer_client;
 | 
			
		||||
 | 
			
		||||
  pointer_client = meta_wayland_pointer_client_new ();
 | 
			
		||||
  g_hash_table_insert (pointer->pointer_clients, client, pointer_client);
 | 
			
		||||
 | 
			
		||||
  if (!pointer->focus_client &&
 | 
			
		||||
      pointer->focus_surface &&
 | 
			
		||||
      wl_resource_get_client (pointer->focus_surface->resource) == client)
 | 
			
		||||
    pointer->focus_client = pointer_client;
 | 
			
		||||
 | 
			
		||||
  return pointer_client;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_pointer_cleanup_pointer_client (MetaWaylandPointer       *pointer,
 | 
			
		||||
                                             MetaWaylandPointerClient *pointer_client,
 | 
			
		||||
                                             struct wl_client         *client)
 | 
			
		||||
{
 | 
			
		||||
  if (meta_wayland_pointer_client_is_empty (pointer_client))
 | 
			
		||||
    {
 | 
			
		||||
      if (pointer->focus_client == pointer_client)
 | 
			
		||||
        pointer->focus_client = NULL;
 | 
			
		||||
      g_hash_table_remove (pointer->pointer_clients, client);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandPointer *pointer = wl_resource_get_user_data (resource);
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
  struct wl_client *client = wl_resource_get_client (resource);
 | 
			
		||||
 | 
			
		||||
  wl_list_remove (wl_resource_get_link (resource));
 | 
			
		||||
 | 
			
		||||
  pointer_client = meta_wayland_pointer_get_pointer_client (pointer, client);
 | 
			
		||||
  if (!pointer_client)
 | 
			
		||||
    {
 | 
			
		||||
      /* This happens if all pointer devices were unplugged and no new resources
 | 
			
		||||
       * were created by the client.
 | 
			
		||||
       *
 | 
			
		||||
       * If this is a resource that was previously made defunct, pointer_client
 | 
			
		||||
       * be non-NULL but it is harmless since the below cleanup call will be
 | 
			
		||||
       * prevented from removing the pointer client because of valid resources.
 | 
			
		||||
       */
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_cleanup_pointer_client (pointer,
 | 
			
		||||
                                               pointer_client,
 | 
			
		||||
                                               client);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -131,17 +242,20 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer,
 | 
			
		||||
                                  const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  struct wl_list *l;
 | 
			
		||||
  uint32_t time;
 | 
			
		||||
  wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
  l = &pointer->focus_resource_list;
 | 
			
		||||
  wl_resource_for_each(resource, l)
 | 
			
		||||
  if (!pointer->focus_client)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  time = clutter_event_get_time (event);
 | 
			
		||||
  meta_wayland_pointer_get_relative_coordinates (pointer,
 | 
			
		||||
                                                 pointer->focus_surface,
 | 
			
		||||
                                                 &sx, &sy);
 | 
			
		||||
 | 
			
		||||
  wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
 | 
			
		||||
    {
 | 
			
		||||
      wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
      meta_wayland_pointer_get_relative_coordinates (pointer,
 | 
			
		||||
                                                     pointer->focus_surface,
 | 
			
		||||
                                                     &sx, &sy);
 | 
			
		||||
      wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy);
 | 
			
		||||
      wl_pointer_send_motion (resource, time, sx, sy);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -150,19 +264,21 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
 | 
			
		||||
                                  const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  struct wl_list *l;
 | 
			
		||||
  ClutterEventType event_type;
 | 
			
		||||
 | 
			
		||||
  event_type = clutter_event_type (event);
 | 
			
		||||
 | 
			
		||||
  l = &pointer->focus_resource_list;
 | 
			
		||||
  if (!wl_list_empty (l))
 | 
			
		||||
  if (pointer->focus_client &&
 | 
			
		||||
      !wl_list_empty (&pointer->focus_client->pointer_resources))
 | 
			
		||||
    {
 | 
			
		||||
      struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
 | 
			
		||||
      struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
      uint32_t time;
 | 
			
		||||
      uint32_t button;
 | 
			
		||||
      uint32_t serial;
 | 
			
		||||
 | 
			
		||||
      time = clutter_event_get_time (event);
 | 
			
		||||
 | 
			
		||||
      button = clutter_event_get_button (event);
 | 
			
		||||
      switch (button)
 | 
			
		||||
	{
 | 
			
		||||
@@ -183,10 +299,10 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer,
 | 
			
		||||
 | 
			
		||||
      serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
      wl_resource_for_each(resource, l)
 | 
			
		||||
      wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
 | 
			
		||||
        {
 | 
			
		||||
          wl_pointer_send_button (resource, serial,
 | 
			
		||||
                                  clutter_event_get_time (event), button,
 | 
			
		||||
                                  time, button,
 | 
			
		||||
                                  event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -241,8 +357,9 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer,
 | 
			
		||||
 | 
			
		||||
  pointer->display = display;
 | 
			
		||||
 | 
			
		||||
  wl_list_init (&pointer->resource_list);
 | 
			
		||||
  wl_list_init (&pointer->focus_resource_list);
 | 
			
		||||
  pointer->pointer_clients =
 | 
			
		||||
    g_hash_table_new_full (NULL, NULL, NULL,
 | 
			
		||||
                           (GDestroyNotify) meta_wayland_pointer_client_free);
 | 
			
		||||
 | 
			
		||||
  pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy;
 | 
			
		||||
 | 
			
		||||
@@ -265,6 +382,7 @@ meta_wayland_pointer_release (MetaWaylandPointer *pointer)
 | 
			
		||||
  meta_wayland_pointer_set_focus (pointer, NULL);
 | 
			
		||||
  set_cursor_surface (pointer, NULL);
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
 | 
			
		||||
  pointer->display = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -358,7 +476,6 @@ handle_scroll_event (MetaWaylandPointer *pointer,
 | 
			
		||||
                     const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  struct wl_list *l;
 | 
			
		||||
  wl_fixed_t x_value = 0, y_value = 0;
 | 
			
		||||
 | 
			
		||||
  if (clutter_event_is_pointer_emulated (event))
 | 
			
		||||
@@ -399,15 +516,17 @@ handle_scroll_event (MetaWaylandPointer *pointer,
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  l = &pointer->focus_resource_list;
 | 
			
		||||
  wl_resource_for_each (resource, l)
 | 
			
		||||
  if (pointer->focus_client)
 | 
			
		||||
    {
 | 
			
		||||
      if (x_value)
 | 
			
		||||
        wl_pointer_send_axis (resource, clutter_event_get_time (event),
 | 
			
		||||
                              WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
 | 
			
		||||
      if (y_value)
 | 
			
		||||
        wl_pointer_send_axis (resource, clutter_event_get_time (event),
 | 
			
		||||
                              WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
 | 
			
		||||
      wl_resource_for_each (resource, &pointer->focus_client->pointer_resources)
 | 
			
		||||
        {
 | 
			
		||||
          if (x_value)
 | 
			
		||||
            wl_pointer_send_axis (resource, clutter_event_get_time (event),
 | 
			
		||||
                                  WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
 | 
			
		||||
          if (y_value)
 | 
			
		||||
            wl_pointer_send_axis (resource, clutter_event_get_time (event),
 | 
			
		||||
                                  WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -430,6 +549,14 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
      handle_scroll_event (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case CLUTTER_TOUCHPAD_SWIPE:
 | 
			
		||||
      meta_wayland_pointer_gesture_swipe_handle_event (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case CLUTTER_TOUCHPAD_PINCH:
 | 
			
		||||
      meta_wayland_pointer_gesture_pinch_handle_event (pointer, event);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
@@ -437,29 +564,6 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer,
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
move_resources (struct wl_list *destination, struct wl_list *source)
 | 
			
		||||
{
 | 
			
		||||
  wl_list_insert_list (destination, source);
 | 
			
		||||
  wl_list_init (source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
move_resources_for_client (struct wl_list *destination,
 | 
			
		||||
			   struct wl_list *source,
 | 
			
		||||
			   struct wl_client *client)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource, *tmp;
 | 
			
		||||
  wl_resource_for_each_safe (resource, tmp, source)
 | 
			
		||||
    {
 | 
			
		||||
      if (wl_resource_get_client (resource) == client)
 | 
			
		||||
        {
 | 
			
		||||
          wl_list_remove (wl_resource_get_link (resource));
 | 
			
		||||
          wl_list_insert (destination, wl_resource_get_link (resource));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
broadcast_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
                 struct wl_resource *resource)
 | 
			
		||||
@@ -482,22 +586,23 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
 | 
			
		||||
  if (pointer->focus_surface != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      struct wl_client *client =
 | 
			
		||||
        wl_resource_get_client (pointer->focus_surface->resource);
 | 
			
		||||
      struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
      uint32_t serial;
 | 
			
		||||
      struct wl_resource *resource;
 | 
			
		||||
      struct wl_list *l;
 | 
			
		||||
 | 
			
		||||
      l = &pointer->focus_resource_list;
 | 
			
		||||
      if (!wl_list_empty (l))
 | 
			
		||||
      serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
      if (pointer->focus_client)
 | 
			
		||||
        {
 | 
			
		||||
          struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
 | 
			
		||||
          struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
          uint32_t serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
          wl_resource_for_each (resource, l)
 | 
			
		||||
          wl_resource_for_each (resource,
 | 
			
		||||
                                &pointer->focus_client->pointer_resources)
 | 
			
		||||
            {
 | 
			
		||||
              wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          move_resources (&pointer->resource_list, &pointer->focus_resource_list);
 | 
			
		||||
          pointer->focus_client = NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      wl_list_remove (&pointer->focus_surface_listener.link);
 | 
			
		||||
@@ -506,8 +611,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
 | 
			
		||||
  if (surface != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      struct wl_client *client = wl_resource_get_client (surface->resource);
 | 
			
		||||
      struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
      struct wl_resource *resource;
 | 
			
		||||
      struct wl_list *l;
 | 
			
		||||
      ClutterPoint pos;
 | 
			
		||||
 | 
			
		||||
      pointer->focus_surface = surface;
 | 
			
		||||
@@ -521,18 +627,14 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
 | 
			
		||||
                                  clutter_get_current_event_time (),
 | 
			
		||||
                                  pos.x, pos.y);
 | 
			
		||||
 | 
			
		||||
      move_resources_for_client (&pointer->focus_resource_list,
 | 
			
		||||
                                 &pointer->resource_list,
 | 
			
		||||
                                 wl_resource_get_client (pointer->focus_surface->resource));
 | 
			
		||||
 | 
			
		||||
      l = &pointer->focus_resource_list;
 | 
			
		||||
      if (!wl_list_empty (l))
 | 
			
		||||
      pointer->focus_client =
 | 
			
		||||
        meta_wayland_pointer_get_pointer_client (pointer, client);
 | 
			
		||||
      if (pointer->focus_client)
 | 
			
		||||
        {
 | 
			
		||||
          struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource);
 | 
			
		||||
          struct wl_display *display = wl_client_get_display (client);
 | 
			
		||||
          pointer->focus_serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
          wl_resource_for_each (resource, l)
 | 
			
		||||
          wl_resource_for_each (resource,
 | 
			
		||||
                                &pointer->focus_client->pointer_resources)
 | 
			
		||||
            {
 | 
			
		||||
              broadcast_focus (pointer, resource);
 | 
			
		||||
            }
 | 
			
		||||
@@ -707,19 +809,19 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
 | 
			
		||||
                                          uint32_t id)
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *cr;
 | 
			
		||||
  MetaWaylandPointerClient *pointer_client;
 | 
			
		||||
 | 
			
		||||
  cr = wl_resource_create (client, &wl_pointer_interface, wl_resource_get_version (seat_resource), id);
 | 
			
		||||
  wl_resource_set_implementation (cr, &pointer_interface, pointer, unbind_resource);
 | 
			
		||||
  wl_resource_set_implementation (cr, &pointer_interface, pointer,
 | 
			
		||||
                                  meta_wayland_pointer_unbind_pointer_client_resource);
 | 
			
		||||
 | 
			
		||||
  if (pointer->focus_surface && wl_resource_get_client (pointer->focus_surface->resource) == client)
 | 
			
		||||
    {
 | 
			
		||||
      wl_list_insert (&pointer->focus_resource_list, wl_resource_get_link (cr));
 | 
			
		||||
      broadcast_focus (pointer, cr);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      wl_list_insert (&pointer->resource_list, wl_resource_get_link (cr));
 | 
			
		||||
    }
 | 
			
		||||
  pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client);
 | 
			
		||||
 | 
			
		||||
  wl_list_insert (&pointer_client->pointer_resources,
 | 
			
		||||
                  wl_resource_get_link (cr));
 | 
			
		||||
 | 
			
		||||
  if (pointer->focus_client == pointer_client)
 | 
			
		||||
    broadcast_focus (pointer, cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,8 @@
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-types.h"
 | 
			
		||||
#include "meta-wayland-pointer-gesture-swipe.h"
 | 
			
		||||
#include "meta-wayland-pointer-gesture-pinch.h"
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-cursor-tracker.h>
 | 
			
		||||
 | 
			
		||||
@@ -44,12 +46,19 @@ struct _MetaWaylandPointerGrab
 | 
			
		||||
  MetaWaylandPointer *pointer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandPointerClient
 | 
			
		||||
{
 | 
			
		||||
  struct wl_list pointer_resources;
 | 
			
		||||
  struct wl_list swipe_gesture_resources;
 | 
			
		||||
  struct wl_list pinch_gesture_resources;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandPointer
 | 
			
		||||
{
 | 
			
		||||
  struct wl_display *display;
 | 
			
		||||
 | 
			
		||||
  struct wl_list resource_list;
 | 
			
		||||
  struct wl_list focus_resource_list;
 | 
			
		||||
  MetaWaylandPointerClient *focus_client;
 | 
			
		||||
  GHashTable *pointer_clients;
 | 
			
		||||
 | 
			
		||||
  MetaWaylandSurface *focus_surface;
 | 
			
		||||
  struct wl_listener focus_surface_listener;
 | 
			
		||||
@@ -127,4 +136,8 @@ gboolean meta_wayland_pointer_can_popup (MetaWaylandPointer *pointer,
 | 
			
		||||
 | 
			
		||||
MetaWaylandSurface *meta_wayland_pointer_get_top_popup (MetaWaylandPointer *pointer);
 | 
			
		||||
 | 
			
		||||
MetaWaylandPointerClient * meta_wayland_pointer_get_pointer_client (MetaWaylandPointer *pointer,
 | 
			
		||||
                                                                    struct wl_client   *client);
 | 
			
		||||
void meta_wayland_pointer_unbind_pointer_client_resource (struct wl_resource *resource);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_POINTER_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@
 | 
			
		||||
#include "meta-wayland-versions.h"
 | 
			
		||||
#include "meta-wayland-surface.h"
 | 
			
		||||
#include "meta-wayland-seat.h"
 | 
			
		||||
#include "meta-wayland-pointer-gestures.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaXWaylandSelection MetaXWaylandSelection;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -332,6 +332,8 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
 | 
			
		||||
    case CLUTTER_BUTTON_PRESS:
 | 
			
		||||
    case CLUTTER_BUTTON_RELEASE:
 | 
			
		||||
    case CLUTTER_SCROLL:
 | 
			
		||||
    case CLUTTER_TOUCHPAD_SWIPE:
 | 
			
		||||
    case CLUTTER_TOUCHPAD_PINCH:
 | 
			
		||||
      return meta_wayland_pointer_handle_event (&seat->pointer, event);
 | 
			
		||||
 | 
			
		||||
    case CLUTTER_KEY_PRESS:
 | 
			
		||||
 
 | 
			
		||||
@@ -43,4 +43,6 @@ typedef struct _MetaWaylandOutput MetaWaylandOutput;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandSerial MetaWaylandSerial;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandPointerClient MetaWaylandPointerClient;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -44,5 +44,6 @@
 | 
			
		||||
#define META_XSERVER_VERSION                1
 | 
			
		||||
#define META_GTK_SHELL_VERSION              2
 | 
			
		||||
#define META_WL_SUBCOMPOSITOR_VERSION       1
 | 
			
		||||
#define META_WL_POINTER_GESTURES_VERSION    1
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -310,6 +310,7 @@ meta_wayland_init (void)
 | 
			
		||||
  meta_wayland_outputs_init (compositor);
 | 
			
		||||
  meta_wayland_data_device_manager_init (compositor);
 | 
			
		||||
  meta_wayland_shell_init (compositor);
 | 
			
		||||
  meta_wayland_pointer_gestures_init (compositor);
 | 
			
		||||
  meta_wayland_seat_init (compositor);
 | 
			
		||||
 | 
			
		||||
  compositor->display_name = wl_display_add_socket_auto (compositor->wayland_display);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										172
									
								
								src/wayland/protocol/pointer-gestures.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								src/wayland/protocol/pointer-gestures.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,172 @@
 | 
			
		||||
<protocol name="pointer_gestures">
 | 
			
		||||
  <interface name="_wl_pointer_gestures" version="1">
 | 
			
		||||
    <description summary="touchpad gestures">
 | 
			
		||||
      A global interface to provide semantic touchpad gestures for a given
 | 
			
		||||
      pointer.
 | 
			
		||||
 | 
			
		||||
      Two gestures are currently supported: swipe and zoom/rotate.
 | 
			
		||||
      All gestures follow a three-stage cycle: begin, update, end and
 | 
			
		||||
      are identified by a unique id.
 | 
			
		||||
 | 
			
		||||
      Warning! The protocol described in this file is experimental. Each
 | 
			
		||||
      version of this protocol should be considered incompatible with any
 | 
			
		||||
      other version, and a client binding to a version different to the one
 | 
			
		||||
      advertised will be terminated. Once the protocol is declared stable,
 | 
			
		||||
      compatibility is guaranteed, the '_' prefix will be removed from the
 | 
			
		||||
      name and the version will be reset to 1.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="get_swipe_gesture">
 | 
			
		||||
      <description summary="get swipe gesture">
 | 
			
		||||
	Create a swipe gesture object. See the
 | 
			
		||||
	wl_pointer_gesture_swipe interface for details.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="id" type="new_id" interface="_wl_pointer_gesture_swipe"/>
 | 
			
		||||
      <arg name="pointer" type="object" interface="wl_pointer"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <request name="get_pinch_gesture">
 | 
			
		||||
      <description summary="get pinch gesture">
 | 
			
		||||
	Create a pinch gesture object. See the
 | 
			
		||||
	wl_pointer_gesture_pinch interface for details.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="id" type="new_id" interface="_wl_pointer_gesture_pinch"/>
 | 
			
		||||
      <arg name="pointer" type="object" interface="wl_pointer"/>
 | 
			
		||||
    </request>
 | 
			
		||||
  </interface>
 | 
			
		||||
 | 
			
		||||
  <interface name="_wl_pointer_gesture_swipe" version="1">
 | 
			
		||||
    <description summary="a swipe gesture object">
 | 
			
		||||
      A swipe gesture object notifies a client about a multi-finger swipe
 | 
			
		||||
      gesture detected on an indirect input device such as a touchpad.
 | 
			
		||||
      The gesture is usually initiated by multiple fingers moving in the
 | 
			
		||||
      same direction but once initiated the direction may change.
 | 
			
		||||
      The precise conditions of when such a gesture is detected are
 | 
			
		||||
      implementation-dependent.
 | 
			
		||||
 | 
			
		||||
      A gesture consists of three stages: begin, update (optional) and end.
 | 
			
		||||
      There cannot be multiple simultaneous pinch or swipe gestures on a
 | 
			
		||||
      same pointer/seat, how compositors prevent these situations is
 | 
			
		||||
      implementation-dependent.
 | 
			
		||||
 | 
			
		||||
      A gesture may be cancelled by the compositor or the hardware.
 | 
			
		||||
      Clients should not consider performing permanent or irreversible
 | 
			
		||||
      actions until the end of a gesture has been received.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="destroy" type="destructor">
 | 
			
		||||
      <description summary="destroy the pointer swipe gesture object"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <event name="begin">
 | 
			
		||||
      <description summary="multi-finger swipe begin">
 | 
			
		||||
	This event is sent when a multi-finger swipe gesture is detected
 | 
			
		||||
	on the device.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="serial" type="uint"/>
 | 
			
		||||
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
			
		||||
      <arg name="surface" type="object" interface="wl_surface"/>
 | 
			
		||||
      <arg name="fingers" type="uint" summary="number of fingers"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="update">
 | 
			
		||||
      <description summary="multi-finger swipe motion">
 | 
			
		||||
	This event is sent when a multi-finger swipe gesture changes the
 | 
			
		||||
	position of the logical center.
 | 
			
		||||
 | 
			
		||||
	The dx and dy coordinates are relative coordinates of the logical
 | 
			
		||||
	center of the gesture compared to the previous event.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
			
		||||
      <arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/>
 | 
			
		||||
      <arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="end">
 | 
			
		||||
      <description summary="multi-finger swipe end">
 | 
			
		||||
	This event is sent when a multi-finger swipe gesture ceases to
 | 
			
		||||
	be valid. This may happen when one or more finger is lifted or
 | 
			
		||||
	the gesture is cancelled.
 | 
			
		||||
 | 
			
		||||
	When a gesture is cancelled, the client should undo state changes
 | 
			
		||||
	caused by this gesture. What causes a gesture to be cancelled is
 | 
			
		||||
	implementation-dependent.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="serial" type="uint"/>
 | 
			
		||||
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
			
		||||
      <arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/>
 | 
			
		||||
    </event>
 | 
			
		||||
  </interface>
 | 
			
		||||
 | 
			
		||||
  <interface name="_wl_pointer_gesture_pinch" version="1">
 | 
			
		||||
    <description summary="a pinch gesture object">
 | 
			
		||||
      A pinch gesture object notifies a client about a multi-finger pinch
 | 
			
		||||
      gesture detected on an indirect input device such as a touchpad.
 | 
			
		||||
      The gesture is usually initiated by multiple fingers moving towards
 | 
			
		||||
      each other or away from each other, or by two or more fingers rotating
 | 
			
		||||
      around a logical center of gravity.  The precise conditions of when
 | 
			
		||||
      such a gesture is detected are implementation-dependent.
 | 
			
		||||
 | 
			
		||||
      A gesture consists of three stages: begin, update (optional) and end.
 | 
			
		||||
      There cannot be multiple simultaneous pinch or swipe gestures on a
 | 
			
		||||
      same pointer/seat, how compositors prevent these situations is
 | 
			
		||||
      implementation-dependent.
 | 
			
		||||
 | 
			
		||||
      A gesture may be cancelled by the compositor or the hardware.
 | 
			
		||||
      Clients should not consider performing permanent or irreversible
 | 
			
		||||
      actions until the end of a gesture has been received.
 | 
			
		||||
    </description>
 | 
			
		||||
 | 
			
		||||
    <request name="destroy" type="destructor">
 | 
			
		||||
      <description summary="destroy the pinch gesture object"/>
 | 
			
		||||
    </request>
 | 
			
		||||
 | 
			
		||||
    <event name="begin">
 | 
			
		||||
      <description summary="multi-finger pinch begin">
 | 
			
		||||
	This event is sent when a multi-finger pinch gesture is detected
 | 
			
		||||
	on the device.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="serial" type="uint"/>
 | 
			
		||||
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
			
		||||
      <arg name="surface" type="object" interface="wl_surface"/>
 | 
			
		||||
      <arg name="fingers" type="uint" summary="number of fingers"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="update">
 | 
			
		||||
      <description summary="multi-finger pinch motion">
 | 
			
		||||
	This event is sent when a multi-finger pinch gesture changes the
 | 
			
		||||
	position of the logical center, the rotation or the relative scale.
 | 
			
		||||
 | 
			
		||||
	The dx and dy coordinates are relative coordinates in the
 | 
			
		||||
	surface coordinate space of the logical center of the gesture.
 | 
			
		||||
 | 
			
		||||
	The scale factor is an absolute scale compared to the
 | 
			
		||||
	pointer_gesture_pinch.begin event, e.g. a scale of 2 means the fingers
 | 
			
		||||
	are now twice as far apart as on pointer_gesture_pinch.begin.
 | 
			
		||||
 | 
			
		||||
	The rotation is the relative angle in degrees clockwise compared to the previous
 | 
			
		||||
	pointer_gesture_pinch.begin or pointer_gesture_pinch.update event.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
			
		||||
      <arg name="dx" type="fixed" summary="delta x coordinate in surface coordinate space"/>
 | 
			
		||||
      <arg name="dy" type="fixed" summary="delta y coordinate in surface coordinate space"/>
 | 
			
		||||
      <arg name="scale" type="fixed" summary="scale relative to the initial finger position"/>
 | 
			
		||||
      <arg name="rotation" type="fixed" summary="angle in degrees cw relative to the previous event"/>
 | 
			
		||||
    </event>
 | 
			
		||||
 | 
			
		||||
    <event name="end">
 | 
			
		||||
      <description summary="multi-finger pinch end">
 | 
			
		||||
	This event is sent when a multi-finger pinch gesture ceases to
 | 
			
		||||
	be valid. This may happen when one or more finger is lifted or
 | 
			
		||||
	the gesture is cancelled.
 | 
			
		||||
 | 
			
		||||
	When a gesture is cancelled, the client should undo state changes
 | 
			
		||||
	caused by this gesture. What causes a gesture to be cancelled is
 | 
			
		||||
	implementation-dependent.
 | 
			
		||||
      </description>
 | 
			
		||||
      <arg name="serial" type="uint"/>
 | 
			
		||||
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
 | 
			
		||||
      <arg name="cancelled" type="int" summary="1 if the gesture was cancelled, 0 otherwise"/>
 | 
			
		||||
    </event>
 | 
			
		||||
  </interface>
 | 
			
		||||
</protocol>
 | 
			
		||||
		Reference in New Issue
	
	Block a user