Compare commits
	
		
			5 Commits
		
	
	
		
			wip/carlos
			...
			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/gtk-shell-server-protocol.h | ||||||
| src/xdg-shell-protocol.c | src/xdg-shell-protocol.c | ||||||
| src/xdg-shell-server-protocol.h | src/xdg-shell-server-protocol.h | ||||||
|  | src/pointer-gestures-protocol.c | ||||||
|  | src/pointer-gestures-server-protocol.h | ||||||
| src/xserver-protocol.c | src/xserver-protocol.c | ||||||
| src/xserver-server-protocol.h | src/xserver-server-protocol.h | ||||||
| src/meta/meta-version.h | src/meta/meta-version.h | ||||||
|   | |||||||
| @@ -45,6 +45,8 @@ mutter_built_sources = \ | |||||||
|  |  | ||||||
| if HAVE_WAYLAND | if HAVE_WAYLAND | ||||||
| mutter_built_sources += \ | mutter_built_sources += \ | ||||||
|  | 	pointer-gestures-protocol.c		\ | ||||||
|  | 	pointer-gestures-server-protocol.h	\ | ||||||
| 	gtk-shell-protocol.c			\ | 	gtk-shell-protocol.c			\ | ||||||
| 	gtk-shell-server-protocol.h		\ | 	gtk-shell-server-protocol.h		\ | ||||||
| 	xdg-shell-protocol.c			\ | 	xdg-shell-protocol.c			\ | ||||||
| @@ -53,6 +55,7 @@ mutter_built_sources += \ | |||||||
| endif | endif | ||||||
|  |  | ||||||
| wayland_protocols =				\ | wayland_protocols =				\ | ||||||
|  | 	wayland/protocol/pointer-gestures.xml	\ | ||||||
| 	wayland/protocol/gtk-shell.xml		\ | 	wayland/protocol/gtk-shell.xml		\ | ||||||
| 	wayland/protocol/xdg-shell.xml		\ | 	wayland/protocol/xdg-shell.xml		\ | ||||||
| 	$(NULL) | 	$(NULL) | ||||||
| @@ -252,6 +255,12 @@ libmutter_la_SOURCES +=				\ | |||||||
| 	wayland/meta-wayland-data-device.c      \ | 	wayland/meta-wayland-data-device.c      \ | ||||||
| 	wayland/meta-wayland-data-device.h      \ | 	wayland/meta-wayland-data-device.h      \ | ||||||
| 	wayland/meta-wayland-data-device-private.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.c		\ | ||||||
| 	wayland/meta-wayland-keyboard.h		\ | 	wayland/meta-wayland-keyboard.h		\ | ||||||
| 	wayland/meta-wayland-pointer.c		\ | 	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) | #define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10) | ||||||
|  |  | ||||||
|  | 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 | static void | ||||||
| unbind_resource (struct wl_resource *resource) | 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_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 | static void | ||||||
| @@ -131,17 +242,20 @@ meta_wayland_pointer_send_motion (MetaWaylandPointer *pointer, | |||||||
|                                   const ClutterEvent *event) |                                   const ClutterEvent *event) | ||||||
| { | { | ||||||
|   struct wl_resource *resource; |   struct wl_resource *resource; | ||||||
|   struct wl_list *l; |   uint32_t time; | ||||||
|  |  | ||||||
|   l = &pointer->focus_resource_list; |  | ||||||
|   wl_resource_for_each(resource, l) |  | ||||||
|     { |  | ||||||
|   wl_fixed_t sx, sy; |   wl_fixed_t sx, sy; | ||||||
|  |  | ||||||
|  |   if (!pointer->focus_client) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   time = clutter_event_get_time (event); | ||||||
|   meta_wayland_pointer_get_relative_coordinates (pointer, |   meta_wayland_pointer_get_relative_coordinates (pointer, | ||||||
|                                                  pointer->focus_surface, |                                                  pointer->focus_surface, | ||||||
|                                                  &sx, &sy); |                                                  &sx, &sy); | ||||||
|       wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy); |  | ||||||
|  |   wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) | ||||||
|  |     { | ||||||
|  |       wl_pointer_send_motion (resource, time, sx, sy); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -150,19 +264,21 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer, | |||||||
|                                   const ClutterEvent *event) |                                   const ClutterEvent *event) | ||||||
| { | { | ||||||
|   struct wl_resource *resource; |   struct wl_resource *resource; | ||||||
|   struct wl_list *l; |  | ||||||
|   ClutterEventType event_type; |   ClutterEventType event_type; | ||||||
|  |  | ||||||
|   event_type = clutter_event_type (event); |   event_type = clutter_event_type (event); | ||||||
|  |  | ||||||
|   l = &pointer->focus_resource_list; |   if (pointer->focus_client && | ||||||
|   if (!wl_list_empty (l)) |       !wl_list_empty (&pointer->focus_client->pointer_resources)) | ||||||
|     { |     { | ||||||
|       struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource); |       struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource); | ||||||
|       struct wl_display *display = wl_client_get_display (client); |       struct wl_display *display = wl_client_get_display (client); | ||||||
|  |       uint32_t time; | ||||||
|       uint32_t button; |       uint32_t button; | ||||||
|       uint32_t serial; |       uint32_t serial; | ||||||
|  |  | ||||||
|  |       time = clutter_event_get_time (event); | ||||||
|  |  | ||||||
|       button = clutter_event_get_button (event); |       button = clutter_event_get_button (event); | ||||||
|       switch (button) |       switch (button) | ||||||
| 	{ | 	{ | ||||||
| @@ -183,10 +299,10 @@ meta_wayland_pointer_send_button (MetaWaylandPointer *pointer, | |||||||
|  |  | ||||||
|       serial = wl_display_next_serial (display); |       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, |           wl_pointer_send_button (resource, serial, | ||||||
|                                   clutter_event_get_time (event), button, |                                   time, button, | ||||||
|                                   event_type == CLUTTER_BUTTON_PRESS ? 1 : 0); |                                   event_type == CLUTTER_BUTTON_PRESS ? 1 : 0); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -241,8 +357,9 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer, | |||||||
|  |  | ||||||
|   pointer->display = display; |   pointer->display = display; | ||||||
|  |  | ||||||
|   wl_list_init (&pointer->resource_list); |   pointer->pointer_clients = | ||||||
|   wl_list_init (&pointer->focus_resource_list); |     g_hash_table_new_full (NULL, NULL, NULL, | ||||||
|  |                            (GDestroyNotify) meta_wayland_pointer_client_free); | ||||||
|  |  | ||||||
|   pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy; |   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); |   meta_wayland_pointer_set_focus (pointer, NULL); | ||||||
|   set_cursor_surface (pointer, NULL); |   set_cursor_surface (pointer, NULL); | ||||||
|  |  | ||||||
|  |   g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref); | ||||||
|   pointer->display = NULL; |   pointer->display = NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -358,7 +476,6 @@ handle_scroll_event (MetaWaylandPointer *pointer, | |||||||
|                      const ClutterEvent *event) |                      const ClutterEvent *event) | ||||||
| { | { | ||||||
|   struct wl_resource *resource; |   struct wl_resource *resource; | ||||||
|   struct wl_list *l; |  | ||||||
|   wl_fixed_t x_value = 0, y_value = 0; |   wl_fixed_t x_value = 0, y_value = 0; | ||||||
|  |  | ||||||
|   if (clutter_event_is_pointer_emulated (event)) |   if (clutter_event_is_pointer_emulated (event)) | ||||||
| @@ -399,8 +516,9 @@ handle_scroll_event (MetaWaylandPointer *pointer, | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   l = &pointer->focus_resource_list; |   if (pointer->focus_client) | ||||||
|   wl_resource_for_each (resource, l) |     { | ||||||
|  |       wl_resource_for_each (resource, &pointer->focus_client->pointer_resources) | ||||||
|         { |         { | ||||||
|           if (x_value) |           if (x_value) | ||||||
|             wl_pointer_send_axis (resource, clutter_event_get_time (event), |             wl_pointer_send_axis (resource, clutter_event_get_time (event), | ||||||
| @@ -410,6 +528,7 @@ handle_scroll_event (MetaWaylandPointer *pointer, | |||||||
|                                   WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); |                                   WL_POINTER_AXIS_VERTICAL_SCROLL, y_value); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| gboolean | gboolean | ||||||
| meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, | meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, | ||||||
| @@ -430,6 +549,14 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, | |||||||
|       handle_scroll_event (pointer, event); |       handle_scroll_event (pointer, event); | ||||||
|       break; |       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: |     default: | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
| @@ -437,29 +564,6 @@ meta_wayland_pointer_handle_event (MetaWaylandPointer *pointer, | |||||||
|   return FALSE; |   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 | static void | ||||||
| broadcast_focus (MetaWaylandPointer *pointer, | broadcast_focus (MetaWaylandPointer *pointer, | ||||||
|                  struct wl_resource *resource) |                  struct wl_resource *resource) | ||||||
| @@ -482,22 +586,23 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, | |||||||
|  |  | ||||||
|   if (pointer->focus_surface != NULL) |   if (pointer->focus_surface != NULL) | ||||||
|     { |     { | ||||||
|       struct wl_resource *resource; |       struct wl_client *client = | ||||||
|       struct wl_list *l; |         wl_resource_get_client (pointer->focus_surface->resource); | ||||||
|  |  | ||||||
|       l = &pointer->focus_resource_list; |  | ||||||
|       if (!wl_list_empty (l)) |  | ||||||
|         { |  | ||||||
|           struct wl_client *client = wl_resource_get_client (pointer->focus_surface->resource); |  | ||||||
|       struct wl_display *display = wl_client_get_display (client); |       struct wl_display *display = wl_client_get_display (client); | ||||||
|           uint32_t serial = wl_display_next_serial (display); |       uint32_t serial; | ||||||
|  |       struct wl_resource *resource; | ||||||
|  |  | ||||||
|           wl_resource_for_each (resource, l) |       serial = wl_display_next_serial (display); | ||||||
|  |  | ||||||
|  |       if (pointer->focus_client) | ||||||
|  |         { | ||||||
|  |           wl_resource_for_each (resource, | ||||||
|  |                                 &pointer->focus_client->pointer_resources) | ||||||
|             { |             { | ||||||
|               wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource); |               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); |       wl_list_remove (&pointer->focus_surface_listener.link); | ||||||
| @@ -506,8 +611,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, | |||||||
|  |  | ||||||
|   if (surface != NULL) |   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_resource *resource; | ||||||
|       struct wl_list *l; |  | ||||||
|       ClutterPoint pos; |       ClutterPoint pos; | ||||||
|  |  | ||||||
|       pointer->focus_surface = surface; |       pointer->focus_surface = surface; | ||||||
| @@ -521,18 +627,14 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, | |||||||
|                                   clutter_get_current_event_time (), |                                   clutter_get_current_event_time (), | ||||||
|                                   pos.x, pos.y); |                                   pos.x, pos.y); | ||||||
|  |  | ||||||
|       move_resources_for_client (&pointer->focus_resource_list, |       pointer->focus_client = | ||||||
|                                  &pointer->resource_list, |         meta_wayland_pointer_get_pointer_client (pointer, client); | ||||||
|                                  wl_resource_get_client (pointer->focus_surface->resource)); |       if (pointer->focus_client) | ||||||
|  |  | ||||||
|       l = &pointer->focus_resource_list; |  | ||||||
|       if (!wl_list_empty (l)) |  | ||||||
|         { |         { | ||||||
|           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); |           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); |               broadcast_focus (pointer, resource); | ||||||
|             } |             } | ||||||
| @@ -707,20 +809,20 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer, | |||||||
|                                           uint32_t id) |                                           uint32_t id) | ||||||
| { | { | ||||||
|   struct wl_resource *cr; |   struct wl_resource *cr; | ||||||
|  |   MetaWaylandPointerClient *pointer_client; | ||||||
|  |  | ||||||
|   cr = wl_resource_create (client, &wl_pointer_interface, wl_resource_get_version (seat_resource), id); |   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) |   pointer_client = meta_wayland_pointer_ensure_pointer_client (pointer, client); | ||||||
|     { |  | ||||||
|       wl_list_insert (&pointer->focus_resource_list, wl_resource_get_link (cr)); |   wl_list_insert (&pointer_client->pointer_resources, | ||||||
|  |                   wl_resource_get_link (cr)); | ||||||
|  |  | ||||||
|  |   if (pointer->focus_client == pointer_client) | ||||||
|     broadcast_focus (pointer, cr); |     broadcast_focus (pointer, cr); | ||||||
| } | } | ||||||
|   else |  | ||||||
|     { |  | ||||||
|       wl_list_insert (&pointer->resource_list, wl_resource_get_link (cr)); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| gboolean | gboolean | ||||||
| meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer, | meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer, | ||||||
|   | |||||||
| @@ -25,6 +25,8 @@ | |||||||
| #include <glib.h> | #include <glib.h> | ||||||
|  |  | ||||||
| #include "meta-wayland-types.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> | #include <meta/meta-cursor-tracker.h> | ||||||
|  |  | ||||||
| @@ -44,12 +46,19 @@ struct _MetaWaylandPointerGrab | |||||||
|   MetaWaylandPointer *pointer; |   MetaWaylandPointer *pointer; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct _MetaWaylandPointerClient | ||||||
|  | { | ||||||
|  |   struct wl_list pointer_resources; | ||||||
|  |   struct wl_list swipe_gesture_resources; | ||||||
|  |   struct wl_list pinch_gesture_resources; | ||||||
|  | }; | ||||||
|  |  | ||||||
| struct _MetaWaylandPointer | struct _MetaWaylandPointer | ||||||
| { | { | ||||||
|   struct wl_display *display; |   struct wl_display *display; | ||||||
|  |  | ||||||
|   struct wl_list resource_list; |   MetaWaylandPointerClient *focus_client; | ||||||
|   struct wl_list focus_resource_list; |   GHashTable *pointer_clients; | ||||||
|  |  | ||||||
|   MetaWaylandSurface *focus_surface; |   MetaWaylandSurface *focus_surface; | ||||||
|   struct wl_listener focus_surface_listener; |   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); | 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 */ | #endif /* META_WAYLAND_POINTER_H */ | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ | |||||||
| #include "meta-wayland-versions.h" | #include "meta-wayland-versions.h" | ||||||
| #include "meta-wayland-surface.h" | #include "meta-wayland-surface.h" | ||||||
| #include "meta-wayland-seat.h" | #include "meta-wayland-seat.h" | ||||||
|  | #include "meta-wayland-pointer-gestures.h" | ||||||
|  |  | ||||||
| typedef struct _MetaXWaylandSelection MetaXWaylandSelection; | typedef struct _MetaXWaylandSelection MetaXWaylandSelection; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -332,6 +332,8 @@ meta_wayland_seat_handle_event (MetaWaylandSeat *seat, | |||||||
|     case CLUTTER_BUTTON_PRESS: |     case CLUTTER_BUTTON_PRESS: | ||||||
|     case CLUTTER_BUTTON_RELEASE: |     case CLUTTER_BUTTON_RELEASE: | ||||||
|     case CLUTTER_SCROLL: |     case CLUTTER_SCROLL: | ||||||
|  |     case CLUTTER_TOUCHPAD_SWIPE: | ||||||
|  |     case CLUTTER_TOUCHPAD_PINCH: | ||||||
|       return meta_wayland_pointer_handle_event (&seat->pointer, event); |       return meta_wayland_pointer_handle_event (&seat->pointer, event); | ||||||
|  |  | ||||||
|     case CLUTTER_KEY_PRESS: |     case CLUTTER_KEY_PRESS: | ||||||
|   | |||||||
| @@ -43,4 +43,6 @@ typedef struct _MetaWaylandOutput MetaWaylandOutput; | |||||||
|  |  | ||||||
| typedef struct _MetaWaylandSerial MetaWaylandSerial; | typedef struct _MetaWaylandSerial MetaWaylandSerial; | ||||||
|  |  | ||||||
|  | typedef struct _MetaWaylandPointerClient MetaWaylandPointerClient; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -44,5 +44,6 @@ | |||||||
| #define META_XSERVER_VERSION                1 | #define META_XSERVER_VERSION                1 | ||||||
| #define META_GTK_SHELL_VERSION              2 | #define META_GTK_SHELL_VERSION              2 | ||||||
| #define META_WL_SUBCOMPOSITOR_VERSION       1 | #define META_WL_SUBCOMPOSITOR_VERSION       1 | ||||||
|  | #define META_WL_POINTER_GESTURES_VERSION    1 | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -310,6 +310,7 @@ meta_wayland_init (void) | |||||||
|   meta_wayland_outputs_init (compositor); |   meta_wayland_outputs_init (compositor); | ||||||
|   meta_wayland_data_device_manager_init (compositor); |   meta_wayland_data_device_manager_init (compositor); | ||||||
|   meta_wayland_shell_init (compositor); |   meta_wayland_shell_init (compositor); | ||||||
|  |   meta_wayland_pointer_gestures_init (compositor); | ||||||
|   meta_wayland_seat_init (compositor); |   meta_wayland_seat_init (compositor); | ||||||
|  |  | ||||||
|   compositor->display_name = wl_display_add_socket_auto (compositor->wayland_display); |   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