Compare commits
	
		
			2 Commits
		
	
	
		
			3.28.0
			...
			wip/viewpo
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 0829749049 | ||
|   | 725d0ad680 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -66,6 +66,8 @@ src/meta-dbus-idle-monitor.[ch] | ||||
| src/meta-dbus-login1.[ch] | ||||
| src/gtk-shell-protocol.c | ||||
| src/gtk-shell-server-protocol.h | ||||
| src/scaler-protocol.c | ||||
| src/scaler-server-protocol.h | ||||
| src/xdg-shell-protocol.c | ||||
| src/xdg-shell-server-protocol.h | ||||
| src/xserver-protocol.c | ||||
|   | ||||
| @@ -49,6 +49,8 @@ mutter_built_sources += \ | ||||
| 	gtk-shell-server-protocol.h		\ | ||||
| 	xdg-shell-protocol.c			\ | ||||
| 	xdg-shell-server-protocol.h		\ | ||||
| 	scaler-protocol.c			\ | ||||
| 	scaler-server-protocol.h		\ | ||||
| 	$(NULL) | ||||
| endif | ||||
|  | ||||
|   | ||||
| @@ -34,4 +34,9 @@ void meta_shaped_texture_set_texture (MetaShapedTexture *stex, | ||||
|                                       CoglTexture       *texture); | ||||
| gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self); | ||||
|  | ||||
| void meta_shaped_texture_set_viewport (MetaShapedTexture     *stex, | ||||
|                                        cairo_rectangle_int_t *src_rect, | ||||
|                                        int                    dest_width, | ||||
|                                        int                    dest_height); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -85,7 +85,12 @@ struct _MetaShapedTexturePrivate | ||||
|   cairo_region_t *clip_region; | ||||
|   cairo_region_t *unobscured_region; | ||||
|  | ||||
|   /* Viewport stuff */ | ||||
|   cairo_rectangle_int_t viewport_src_rect; | ||||
|   guint viewport_dest_width, viewport_dest_height; | ||||
|  | ||||
|   guint tex_width, tex_height; | ||||
|   guint dest_width, dest_height; | ||||
|  | ||||
|   guint create_mipmaps : 1; | ||||
| }; | ||||
| @@ -136,7 +141,7 @@ set_unobscured_region (MetaShapedTexture *self, | ||||
|   g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy); | ||||
|   if (unobscured_region) | ||||
|     { | ||||
|       cairo_rectangle_int_t bounds = { 0, 0, priv->tex_width, priv->tex_height }; | ||||
|       cairo_rectangle_int_t bounds = { 0, 0, priv->dest_width, priv->dest_height }; | ||||
|       priv->unobscured_region = cairo_region_copy (unobscured_region); | ||||
|       cairo_region_intersect_rectangle (priv->unobscured_region, &bounds); | ||||
|     } | ||||
| @@ -212,24 +217,45 @@ get_unblended_pipeline (CoglContext *ctx) | ||||
|   return cogl_pipeline_copy (template); | ||||
| } | ||||
|  | ||||
| static void | ||||
| scale_coords_by_src (cairo_rectangle_int_t *coords, | ||||
|                      int dest_width, int dest_height, | ||||
|                      cairo_rectangle_int_t *src_rect) | ||||
| { | ||||
|   if (src_rect->width == 0 && src_rect->height == 0) | ||||
|     return; | ||||
|  | ||||
|   coords->x      = ((coords->x      / dest_width)  * src_rect->width)  + src_rect->x; | ||||
|   coords->y      = ((coords->y      / dest_height) * src_rect->height) + src_rect->y; | ||||
|   coords->width  = ((coords->width  / dest_width)  * src_rect->width); | ||||
|   coords->height = ((coords->height / dest_height) * src_rect->height); | ||||
| } | ||||
|  | ||||
| static void | ||||
| paint_clipped_rectangle (CoglFramebuffer       *fb, | ||||
|                          CoglPipeline          *pipeline, | ||||
|                          cairo_rectangle_int_t *rect, | ||||
|                          ClutterActorBox       *alloc) | ||||
|                          ClutterActorBox       *alloc, | ||||
|                          cairo_rectangle_int_t *src_rect) | ||||
| { | ||||
|   cairo_rectangle_int_t pixel_coords; | ||||
|   float coords[8]; | ||||
|   float x1, y1, x2, y2; | ||||
|   float dest_width = alloc->x2 - alloc->x1; | ||||
|   float dest_height = alloc->y2 - alloc->y1; | ||||
|  | ||||
|   x1 = rect->x; | ||||
|   y1 = rect->y; | ||||
|   x2 = rect->x + rect->width; | ||||
|   y2 = rect->y + rect->height; | ||||
|  | ||||
|   coords[0] = rect->x / (alloc->x2 - alloc->x1); | ||||
|   coords[1] = rect->y / (alloc->y2 - alloc->y1); | ||||
|   coords[2] = (rect->x + rect->width) / (alloc->x2 - alloc->x1); | ||||
|   coords[3] = (rect->y + rect->height) / (alloc->y2 - alloc->y1); | ||||
|   pixel_coords = *rect; | ||||
|   scale_coords_by_src (&pixel_coords, dest_width, dest_height, src_rect); | ||||
|  | ||||
|   coords[0] = pixel_coords.x / dest_width; | ||||
|   coords[1] = pixel_coords.y / dest_height; | ||||
|   coords[2] = (pixel_coords.x + pixel_coords.width) / dest_width; | ||||
|   coords[3] = (pixel_coords.y + pixel_coords.height) / dest_height; | ||||
|  | ||||
|   coords[4] = coords[0]; | ||||
|   coords[5] = coords[1]; | ||||
| @@ -241,6 +267,32 @@ paint_clipped_rectangle (CoglFramebuffer       *fb, | ||||
|                                                  &coords[0], 8); | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_size (MetaShapedTexture *stex) | ||||
| { | ||||
|   MetaShapedTexturePrivate *priv = stex->priv; | ||||
|   guint dest_width, dest_height; | ||||
|  | ||||
|   if (priv->viewport_dest_width > 0) | ||||
|     dest_width = priv->viewport_dest_width; | ||||
|   else | ||||
|     dest_width = priv->tex_width; | ||||
|  | ||||
|   if (priv->viewport_dest_height > 0) | ||||
|     dest_height = priv->viewport_dest_height; | ||||
|   else | ||||
|     dest_height = priv->tex_height; | ||||
|  | ||||
|   if (priv->dest_width != dest_width || | ||||
|       priv->dest_height != dest_height) | ||||
|     { | ||||
|       priv->dest_width = dest_width; | ||||
|       priv->dest_height = dest_height; | ||||
|       clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); | ||||
|       g_signal_emit (stex, signals[SIZE_CHANGED], 0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| set_cogl_texture (MetaShapedTexture *stex, | ||||
|                   CoglTexture       *cogl_tex) | ||||
| @@ -274,8 +326,7 @@ set_cogl_texture (MetaShapedTexture *stex, | ||||
|     { | ||||
|       priv->tex_width = width; | ||||
|       priv->tex_height = height; | ||||
|       clutter_actor_queue_relayout (CLUTTER_ACTOR (stex)); | ||||
|       g_signal_emit (stex, signals[SIZE_CHANGED], 0); | ||||
|       update_size (stex); | ||||
|     } | ||||
|  | ||||
|   /* NB: We don't queue a redraw of the actor here because we don't | ||||
| @@ -292,7 +343,7 @@ meta_shaped_texture_paint (ClutterActor *actor) | ||||
| { | ||||
|   MetaShapedTexture *stex = (MetaShapedTexture *) actor; | ||||
|   MetaShapedTexturePrivate *priv = stex->priv; | ||||
|   guint tex_width, tex_height; | ||||
|   guint dest_width, dest_height; | ||||
|   guchar opacity; | ||||
|   CoglContext *ctx; | ||||
|   CoglFramebuffer *fb; | ||||
| @@ -329,13 +380,13 @@ meta_shaped_texture_paint (ClutterActor *actor) | ||||
|   if (paint_tex == NULL) | ||||
|     return; | ||||
|  | ||||
|   tex_width = priv->tex_width; | ||||
|   tex_height = priv->tex_height; | ||||
|   dest_width = priv->dest_width; | ||||
|   dest_height = priv->dest_height; | ||||
|  | ||||
|   if (tex_width == 0 || tex_height == 0) /* no contents yet */ | ||||
|   if (dest_width == 0 || dest_height == 0) /* no contents yet */ | ||||
|     return; | ||||
|  | ||||
|   cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height }; | ||||
|   cairo_rectangle_int_t tex_rect = { 0, 0, dest_width, dest_height }; | ||||
|  | ||||
|   /* Use nearest-pixel interpolation if the texture is unscaled. This | ||||
|    * improves performance, especially with software rendering. | ||||
| @@ -418,7 +469,7 @@ meta_shaped_texture_paint (ClutterActor *actor) | ||||
|             { | ||||
|               cairo_rectangle_int_t rect; | ||||
|               cairo_region_get_rectangle (region, i, &rect); | ||||
|               paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc); | ||||
|               paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc, &priv->viewport_src_rect); | ||||
|             } | ||||
|  | ||||
|           cogl_object_unref (opaque_pipeline); | ||||
| @@ -473,16 +524,13 @@ meta_shaped_texture_paint (ClutterActor *actor) | ||||
|               if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect)) | ||||
|                 continue; | ||||
|  | ||||
|               paint_clipped_rectangle (fb, blended_pipeline, &rect, &alloc); | ||||
|               paint_clipped_rectangle (fb, blended_pipeline, &rect, &alloc, &priv->viewport_src_rect); | ||||
|             } | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           /* 3) blended_region is NULL. Do a full paint. */ | ||||
|           cogl_framebuffer_draw_rectangle (fb, blended_pipeline, | ||||
|                                            0, 0, | ||||
|                                            alloc.x2 - alloc.x1, | ||||
|                                            alloc.y2 - alloc.y1); | ||||
|           paint_clipped_rectangle (fb, blended_pipeline, &tex_rect, &alloc, &priv->viewport_src_rect); | ||||
|         } | ||||
|  | ||||
|       cogl_object_unref (blended_pipeline); | ||||
| @@ -505,10 +553,10 @@ meta_shaped_texture_get_preferred_width (ClutterActor *self, | ||||
|   priv = META_SHAPED_TEXTURE (self)->priv; | ||||
|  | ||||
|   if (min_width_p) | ||||
|     *min_width_p = priv->tex_width; | ||||
|     *min_width_p = priv->dest_width; | ||||
|  | ||||
|   if (natural_width_p) | ||||
|     *natural_width_p = priv->tex_width; | ||||
|     *natural_width_p = priv->dest_width; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -524,10 +572,10 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self, | ||||
|   priv = META_SHAPED_TEXTURE (self)->priv; | ||||
|  | ||||
|   if (min_height_p) | ||||
|     *min_height_p = priv->tex_height; | ||||
|     *min_height_p = priv->dest_height; | ||||
|  | ||||
|   if (natural_height_p) | ||||
|     *natural_height_p = priv->tex_height; | ||||
|     *natural_height_p = priv->dest_height; | ||||
| } | ||||
|  | ||||
| static cairo_region_t * | ||||
| @@ -762,6 +810,22 @@ meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, | ||||
|     priv->opaque_region = NULL; | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_shaped_texture_set_viewport (MetaShapedTexture     *stex, | ||||
|                                   cairo_rectangle_int_t *src_rect, | ||||
|                                   int                    dest_width, | ||||
|                                   int                    dest_height) | ||||
| { | ||||
|   MetaShapedTexturePrivate *priv = stex->priv; | ||||
|  | ||||
|   priv->viewport_src_rect = *src_rect; | ||||
|  | ||||
|   priv->viewport_dest_width = dest_width; | ||||
|   priv->viewport_dest_height = dest_height; | ||||
|   update_size (stex); | ||||
|   clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * meta_shaped_texture_get_image: | ||||
|  * @stex: A #MetaShapedTexture | ||||
|   | ||||
| @@ -235,6 +235,16 @@ meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, | ||||
|   meta_shaped_texture_set_opaque_region (priv->texture, region); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_surface_actor_set_viewport (MetaSurfaceActor      *self, | ||||
|                                  cairo_rectangle_int_t *src_rect, | ||||
|                                  int                    dest_width, | ||||
|                                  int                    dest_height) | ||||
| { | ||||
|   MetaSurfaceActorPrivate *priv = self->priv; | ||||
|   meta_shaped_texture_set_viewport (priv->texture, src_rect, dest_width, dest_height); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| is_frozen (MetaSurfaceActor *self) | ||||
| { | ||||
|   | ||||
| @@ -61,6 +61,11 @@ void meta_surface_actor_set_input_region (MetaSurfaceActor *self, | ||||
| void meta_surface_actor_set_opaque_region (MetaSurfaceActor *self, | ||||
|                                            cairo_region_t   *region); | ||||
|  | ||||
| void meta_surface_actor_set_viewport (MetaSurfaceActor      *self, | ||||
|                                       cairo_rectangle_int_t *src_rect, | ||||
|                                       int                    dest_width, | ||||
|                                       int                    dest_height); | ||||
|  | ||||
| void meta_surface_actor_process_damage (MetaSurfaceActor *actor, | ||||
|                                         int x, int y, int width, int height); | ||||
| void meta_surface_actor_pre_paint (MetaSurfaceActor *actor); | ||||
|   | ||||
| @@ -32,6 +32,7 @@ | ||||
| #include <wayland-server.h> | ||||
| #include "gtk-shell-server-protocol.h" | ||||
| #include "xdg-shell-server-protocol.h" | ||||
| #include "scaler-server-protocol.h" | ||||
|  | ||||
| #include "meta-wayland-private.h" | ||||
| #include "meta-xwayland-private.h" | ||||
| @@ -265,6 +266,7 @@ pending_state_init (MetaWaylandPendingState *state) | ||||
|   wl_list_init (&state->frame_callback_list); | ||||
|  | ||||
|   state->has_new_geometry = FALSE; | ||||
|   state->viewport.changed = FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -420,6 +422,12 @@ commit_pending_state (MetaWaylandSurface      *surface, | ||||
|   wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list); | ||||
|   wl_list_init (&pending->frame_callback_list); | ||||
|  | ||||
|   if (pending->viewport.changed) | ||||
|     meta_surface_actor_set_viewport (surface->surface_actor, | ||||
|                                      &pending->viewport.src_rect, | ||||
|                                      pending->viewport.dest_width, | ||||
|                                      pending->viewport.dest_height); | ||||
|  | ||||
|   if (surface == compositor->seat->pointer.cursor_surface) | ||||
|     cursor_surface_commit (surface, pending); | ||||
|   else if (meta_wayland_data_device_is_dnd_surface (&compositor->seat->data_device, surface)) | ||||
| @@ -1681,6 +1689,136 @@ bind_subcompositor (struct wl_client *client, | ||||
|   wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, data, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| destroy_wl_viewport (struct wl_resource *resource) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (resource); | ||||
|  | ||||
|   surface->has_viewport = FALSE; | ||||
|   surface->pending.viewport.changed = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| wl_viewport_destroy (struct wl_client *client, | ||||
|                      struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| viewport_set_src (struct wl_resource *resource, | ||||
|                   wl_fixed_t src_x, | ||||
|                   wl_fixed_t src_y, | ||||
|                   wl_fixed_t src_width, | ||||
|                   wl_fixed_t src_height) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (resource); | ||||
|   surface->pending.viewport.src_rect.x = wl_fixed_to_int (src_x); | ||||
|   surface->pending.viewport.src_rect.y = wl_fixed_to_int (src_y); | ||||
|   surface->pending.viewport.src_rect.width = wl_fixed_to_int (src_width); | ||||
|   surface->pending.viewport.src_rect.height = wl_fixed_to_int (src_height); | ||||
|   surface->pending.viewport.changed = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| viewport_set_dest (struct wl_resource *resource, | ||||
|                    int dst_width, | ||||
|                    int dst_height) | ||||
| { | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (resource); | ||||
|   surface->pending.viewport.dest_width = dst_width; | ||||
|   surface->pending.viewport.dest_height = dst_height; | ||||
|   surface->pending.viewport.changed = TRUE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| wl_viewport_set (struct wl_client *client, | ||||
|                  struct wl_resource *resource, | ||||
|                  wl_fixed_t src_x, | ||||
|                  wl_fixed_t src_y, | ||||
|                  wl_fixed_t src_width, | ||||
|                  wl_fixed_t src_height, | ||||
|                  int dst_width, | ||||
|                  int dst_height) | ||||
| { | ||||
|   viewport_set_src (resource, src_x, src_y, src_width, src_height); | ||||
|   viewport_set_dest (resource, dst_width, dst_height); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wl_viewport_set_source (struct wl_client *client, | ||||
|                         struct wl_resource *resource, | ||||
|                         wl_fixed_t src_x, | ||||
|                         wl_fixed_t src_y, | ||||
|                         wl_fixed_t src_width, | ||||
|                         wl_fixed_t src_height) | ||||
| { | ||||
|   viewport_set_src (resource, src_x, src_y, src_width, src_height); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wl_viewport_set_destination (struct wl_client *client, | ||||
|                              struct wl_resource *resource, | ||||
|                              int dst_width, | ||||
|                              int dst_height) | ||||
| { | ||||
|   viewport_set_dest (resource, dst_width, dst_height); | ||||
| } | ||||
|  | ||||
| static const struct wl_viewport_interface meta_wayland_viewport_interface = { | ||||
|   wl_viewport_destroy, | ||||
|   wl_viewport_set, | ||||
|   wl_viewport_set_source, | ||||
|   wl_viewport_set_destination, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| wl_scaler_destroy (struct wl_client *client, | ||||
|                    struct wl_resource *resource) | ||||
| { | ||||
|   wl_resource_destroy (resource); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wl_scaler_get_viewport (struct wl_client *client, | ||||
|                         struct wl_resource *master_resource, | ||||
|                         uint32_t viewport_id, | ||||
|                         struct wl_resource *surface_resource) | ||||
| { | ||||
|   struct wl_resource *resource; | ||||
|   MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); | ||||
|  | ||||
|   if (surface->has_viewport) | ||||
|     { | ||||
|       wl_resource_post_error (master_resource, | ||||
|                               WL_SCALER_ERROR_VIEWPORT_EXISTS, | ||||
|                               "viewport already exists on surface"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   resource = wl_resource_create (client, &wl_viewport_interface, wl_resource_get_version (master_resource), viewport_id); | ||||
|   wl_resource_set_implementation (resource, &meta_wayland_viewport_interface, surface, destroy_wl_viewport); | ||||
|  | ||||
|   surface->has_viewport = TRUE; | ||||
| } | ||||
|  | ||||
| static const struct wl_scaler_interface meta_wayland_scaler_interface = { | ||||
|   wl_scaler_destroy, | ||||
|   wl_scaler_get_viewport, | ||||
| }; | ||||
|  | ||||
| static void | ||||
| bind_scaler (struct wl_client *client, | ||||
|              void             *data, | ||||
|              guint32           version, | ||||
|              guint32           id) | ||||
| { | ||||
|   struct wl_resource *resource; | ||||
|  | ||||
|   resource = wl_resource_create (client, &wl_scaler_interface, version, id); | ||||
|   wl_resource_set_implementation (resource, &meta_wayland_scaler_interface, data, NULL); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_wayland_shell_init (MetaWaylandCompositor *compositor) | ||||
| { | ||||
| @@ -1707,6 +1845,12 @@ meta_wayland_shell_init (MetaWaylandCompositor *compositor) | ||||
|                         META_WL_SUBCOMPOSITOR_VERSION, | ||||
|                         compositor, bind_subcompositor) == NULL) | ||||
|     g_error ("Failed to register a global wl-subcompositor object"); | ||||
|  | ||||
|   if (wl_global_create (compositor->wayland_display, | ||||
|                         &wl_scaler_interface, | ||||
|                         META_WL_SCALER_VERSION, | ||||
|                         compositor, bind_scaler) == NULL) | ||||
|     g_error ("Failed to register a global wl-subcompositor object"); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -58,6 +58,12 @@ typedef struct | ||||
|  | ||||
|   MetaRectangle new_geometry; | ||||
|   gboolean has_new_geometry; | ||||
|  | ||||
|   struct { | ||||
|     gboolean changed; | ||||
|     cairo_rectangle_int_t src_rect; | ||||
|     int32_t dest_width, dest_height; | ||||
|   } viewport; | ||||
| } MetaWaylandPendingState; | ||||
|  | ||||
| struct _MetaWaylandSurface | ||||
| @@ -72,6 +78,7 @@ struct _MetaWaylandSurface | ||||
|   int scale; | ||||
|   int32_t offset_x, offset_y; | ||||
|   GList *subsurfaces; | ||||
|   gboolean has_viewport; | ||||
|  | ||||
|   /* All the pending state that wl_surface.commit will apply. */ | ||||
|   MetaWaylandPendingState pending; | ||||
|   | ||||
| @@ -44,5 +44,6 @@ | ||||
| #define META_XSERVER_VERSION                1 | ||||
| #define META_GTK_SHELL_VERSION              1 | ||||
| #define META_WL_SUBCOMPOSITOR_VERSION       1 | ||||
| #define META_WL_SCALER_VERSION              2 | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										210
									
								
								src/wayland/protocol/scaler.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								src/wayland/protocol/scaler.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <protocol name="scaler"> | ||||
|  | ||||
|   <copyright> | ||||
|     Copyright © 2013-2014 Collabora, Ltd. | ||||
|  | ||||
|     Permission to use, copy, modify, distribute, and sell this | ||||
|     software and its documentation for any purpose is hereby granted | ||||
|     without fee, provided that the above copyright notice appear in | ||||
|     all copies and that both that copyright notice and this permission | ||||
|     notice appear in supporting documentation, and that the name of | ||||
|     the copyright holders not be used in advertising or publicity | ||||
|     pertaining to distribution of the software without specific, | ||||
|     written prior permission.  The copyright holders make no | ||||
|     representations about the suitability of this software for any | ||||
|     purpose.  It is provided "as is" without express or implied | ||||
|     warranty. | ||||
|  | ||||
|     THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | ||||
|     SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||
|     FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||||
|     SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||
|     AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||||
|     ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||||
|     THIS SOFTWARE. | ||||
|   </copyright> | ||||
|  | ||||
|   <interface name="wl_scaler" version="2"> | ||||
|     <description summary="surface cropping and scaling"> | ||||
|       The global interface exposing surface cropping and scaling | ||||
|       capabilities is used to instantiate an interface extension for a | ||||
|       wl_surface object. This extended interface will then allow | ||||
|       cropping and scaling the surface contents, effectively | ||||
|       disconnecting the direct relationship between the buffer and the | ||||
|       surface size. | ||||
|     </description> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="unbind from the cropping and scaling interface"> | ||||
| 	Informs the server that the client will not be using this | ||||
| 	protocol object anymore. This does not affect any other objects, | ||||
| 	wl_viewport objects included. | ||||
|       </description> | ||||
|     </request> | ||||
|  | ||||
|     <enum name="error"> | ||||
|       <entry name="viewport_exists" value="0" | ||||
|              summary="the surface already has a viewport object associated"/> | ||||
|     </enum> | ||||
|  | ||||
|     <request name="get_viewport"> | ||||
|       <description summary="extend surface interface for crop and scale"> | ||||
| 	Instantiate an interface extension for the given wl_surface to | ||||
| 	crop and scale its content. If the given wl_surface already has | ||||
| 	a wl_viewport object associated, the viewport_exists | ||||
| 	protocol error is raised. | ||||
|       </description> | ||||
|  | ||||
|       <arg name="id" type="new_id" interface="wl_viewport" | ||||
|            summary="the new viewport interface id"/> | ||||
|       <arg name="surface" type="object" interface="wl_surface" | ||||
|            summary="the surface"/> | ||||
|     </request> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="wl_viewport" version="2"> | ||||
|     <description summary="crop and scale interface to a wl_surface"> | ||||
|       An additional interface to a wl_surface object, which allows the | ||||
|       client to specify the cropping and scaling of the surface | ||||
|       contents. | ||||
|  | ||||
|       This interface allows to define the source rectangle (src_x, | ||||
|       src_y, src_width, src_height) from where to take the wl_buffer | ||||
|       contents, and scale that to destination size (dst_width, | ||||
|       dst_height). This state is double-buffered, and is applied on the | ||||
|       next wl_surface.commit. | ||||
|  | ||||
|       The two parts of crop and scale state are independent: the source | ||||
|       rectangle, and the destination size. Initially both are unset, that | ||||
|       is, no scaling is applied. The whole of the current wl_buffer is | ||||
|       used as the source, and the surface size is as defined in | ||||
|       wl_surface.attach. | ||||
|  | ||||
|       If the destination size is set, it causes the surface size to become | ||||
|       dst_width, dst_height. The source (rectangle) is scaled to exactly | ||||
|       this size. This overrides whatever the attached wl_buffer size is, | ||||
|       unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface | ||||
|       has no content and therefore no size. Otherwise, the size is always | ||||
|       at least 1x1 in surface coordinates. | ||||
|  | ||||
|       If the source rectangle is set, it defines what area of the | ||||
|       wl_buffer is taken as the source. If the source rectangle is set and | ||||
|       the destination size is not set, the surface size becomes the source | ||||
|       rectangle size rounded up to the nearest integer. If the source size | ||||
|       is already exactly integers, this results in cropping without scaling. | ||||
|  | ||||
|       The coordinate transformations from buffer pixel coordinates up to | ||||
|       the surface-local coordinates happen in the following order: | ||||
|         1. buffer_transform (wl_surface.set_buffer_transform) | ||||
|         2. buffer_scale (wl_surface.set_buffer_scale) | ||||
|         3. crop and scale (wl_viewport.set*) | ||||
|       This means, that the source rectangle coordinates of crop and scale | ||||
|       are given in the coordinates after the buffer transform and scale, | ||||
|       i.e. in the coordinates that would be the surface-local coordinates | ||||
|       if the crop and scale was not applied. | ||||
|  | ||||
|       If the source rectangle is partially or completely outside of the | ||||
|       wl_buffer, then the surface contents are undefined (not void), and | ||||
|       the surface size is still dst_width, dst_height. | ||||
|  | ||||
|       The x, y arguments of wl_surface.attach are applied as normal to | ||||
|       the surface. They indicate how many pixels to remove from the | ||||
|       surface size from the left and the top. In other words, they are | ||||
|       still in the surface-local coordinate system, just like dst_width | ||||
|       and dst_height are. | ||||
|  | ||||
|       If the wl_surface associated with the wl_viewport is destroyed, | ||||
|       the wl_viewport object becomes inert. | ||||
|  | ||||
|       If the wl_viewport object is destroyed, the crop and scale | ||||
|       state is removed from the wl_surface. The change will be applied | ||||
|       on the next wl_surface.commit. | ||||
|     </description> | ||||
|  | ||||
|     <request name="destroy" type="destructor"> | ||||
|       <description summary="remove scaling and cropping from the surface"> | ||||
| 	The associated wl_surface's crop and scale state is removed. | ||||
| 	The change is applied on the next wl_surface.commit. | ||||
|       </description> | ||||
|     </request> | ||||
|  | ||||
|     <enum name="error"> | ||||
|       <entry name="bad_value" value="0" | ||||
|              summary="negative or zero values in width or height"/> | ||||
|     </enum> | ||||
|  | ||||
|     <request name="set"> | ||||
|       <description summary="set the crop and scale state"> | ||||
| 	Set both source rectangle and destination size of the associated | ||||
| 	wl_surface. See wl_viewport for the description, and relation to | ||||
| 	the wl_buffer size. | ||||
|  | ||||
| 	The bad_value protocol error is raised if src_width or | ||||
| 	src_height is negative, or if dst_width or dst_height is not | ||||
| 	positive. | ||||
|  | ||||
| 	The crop and scale state is double-buffered state, and will be | ||||
| 	applied on the next wl_surface.commit. | ||||
|  | ||||
| 	Arguments dst_x and dst_y do not exist here, use the x and y | ||||
| 	arguments to wl_surface.attach. The x, y, dst_width, and dst_height | ||||
| 	define the surface-local coordinate system irrespective of the | ||||
| 	attached wl_buffer size. | ||||
|       </description> | ||||
|  | ||||
|       <arg name="src_x" type="fixed" summary="source rectangle x"/> | ||||
|       <arg name="src_y" type="fixed" summary="source rectangle y"/> | ||||
|       <arg name="src_width" type="fixed" summary="source rectangle width"/> | ||||
|       <arg name="src_height" type="fixed" summary="source rectangle height"/> | ||||
|       <arg name="dst_width" type="int" summary="surface width"/> | ||||
|       <arg name="dst_height" type="int" summary="surface height"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="set_source" since="2"> | ||||
|       <description summary="set the source rectangle for cropping"> | ||||
| 	Set the source rectangle of the associated wl_surface. See | ||||
| 	wl_viewport for the description, and relation to the wl_buffer | ||||
| 	size. | ||||
|  | ||||
| 	If width is -1.0 and height is -1.0, the destination size is unset | ||||
| 	instead. Any other pair of values for width and height that | ||||
| 	contains zero or negative values raises the bad_value protocol | ||||
| 	error. | ||||
|  | ||||
| 	The crop and scale state is double-buffered state, and will be | ||||
| 	applied on the next wl_surface.commit. | ||||
|       </description> | ||||
|  | ||||
|       <arg name="x" type="fixed" summary="source rectangle x"/> | ||||
|       <arg name="y" type="fixed" summary="source rectangle y"/> | ||||
|       <arg name="width" type="fixed" summary="source rectangle width"/> | ||||
|       <arg name="height" type="fixed" summary="source rectangle height"/> | ||||
|     </request> | ||||
|  | ||||
|     <request name="set_destination" since="2"> | ||||
|       <description summary="set the surface size for scaling"> | ||||
| 	Set the destination size of the associated wl_surface. See | ||||
| 	wl_viewport for the description, and relation to the wl_buffer | ||||
| 	size. | ||||
|  | ||||
| 	If width is -1 and height is -1, the destination size is unset | ||||
| 	instead. Any other pair of values for width and height that | ||||
| 	contains zero or negative values raises the bad_value protocol | ||||
| 	error. | ||||
|  | ||||
| 	The crop and scale state is double-buffered state, and will be | ||||
| 	applied on the next wl_surface.commit. | ||||
|  | ||||
| 	Arguments x and y do not exist here, use the x and y arguments to | ||||
| 	wl_surface.attach. The x, y, width, and height define the | ||||
| 	surface-local coordinate system irrespective of the attached | ||||
| 	wl_buffer size. | ||||
|       </description> | ||||
|  | ||||
|       <arg name="width" type="int" summary="surface width"/> | ||||
|       <arg name="height" type="int" summary="surface height"/> | ||||
|     </request> | ||||
|   </interface> | ||||
| </protocol> | ||||
		Reference in New Issue
	
	Block a user