diff options
author | Jonas Ådahl <jadahl@gmail.com> | 2015-07-17 23:16:39 +0800 |
---|---|---|
committer | Jonas Ådahl <jadahl@gmail.com> | 2015-09-13 21:26:22 +0800 |
commit | 79c86ae8903b3f1e223553937369b17b146849a9 (patch) | |
tree | aa2dbbcbd45c33f54ae5ad459a4ddb38a05d4d84 /src/backends/meta-cursor-renderer.c | |
parent | 7c7cf91c322923056532279ca316635ed406cacf (diff) | |
download | mutter-79c86ae8903b3f1e223553937369b17b146849a9.tar.gz |
Support scaling of cursor sprites given what output they are on
This commits refactors cursor handling code and plugs in logic so that
cursor sprites changes appearance as it moves across the screen.
Renderers are adapted to handle the necessary functionality.
The logic for changing the cursor sprite appearance is done outside of
MetaCursorSprite, and actually where depends on what type of cursor it
is. In mutter we now have two types of cursors that may have their
appearance changed:
- Themed cursors (aka root cursors)
- wl_surface cursors
Themed cursors are created by MetaScreen and when created, when
applicable(*), it will extend the cursor via connecting to a signal
which is emitted everytime the cursor is moved. The signal handler will
calculate the expected scale given the monitor it is on and reload the
theme in a correct size when needed.
wl_surface cursors are created when a wl_surface is assigned the
"cursor" role, i.e. when a client calls wl_pointer.set_cursor. A
cursor role object is created which is connected to the cursor object
by the position signal, and will set a correct texture scale given what
monitor the cursor is on and what scale the wl_surface's active buffer
is in. It will also push new buffers to the same to the cursor object
when new ones are committed to the surface.
This commit also makes texture loading lazy, since the renderer doesn't
calculate a rectangle when the cursor position changes.
The native backend is refactored to be triple-buffered; see the comment
in meta-cursor-renderer-native.c for further explanations.
* when we are running as a Wayland compositor
https://bugzilla.gnome.org/show_bug.cgi?id=744932
Diffstat (limited to 'src/backends/meta-cursor-renderer.c')
-rw-r--r-- | src/backends/meta-cursor-renderer.c | 99 |
1 files changed, 56 insertions, 43 deletions
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index 689ac2652..48cd239a9 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -37,7 +37,6 @@ struct _MetaCursorRendererPrivate { int current_x, current_y; - MetaRectangle current_rect; MetaCursorSprite *displayed_cursor; gboolean handled_by_backend; @@ -47,28 +46,33 @@ typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate; G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT); static void -queue_redraw (MetaCursorRenderer *renderer) +queue_redraw (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) { MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); MetaBackend *backend = meta_get_backend (); ClutterActor *stage = meta_backend_get_stage (backend); CoglTexture *texture; + MetaRectangle rect = { 0 }; + + if (cursor_sprite) + rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); /* During early initialization, we can have no stage */ if (!stage) return; - if (priv->displayed_cursor && !priv->handled_by_backend) - texture = meta_cursor_sprite_get_cogl_texture (priv->displayed_cursor, - NULL, NULL); + if (cursor_sprite && !priv->handled_by_backend) + texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); else texture = NULL; - meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect); + meta_stage_set_cursor (META_STAGE (stage), texture, &rect); } static gboolean -meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer) +meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) { return FALSE; } @@ -84,35 +88,50 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer) { } +MetaRectangle +meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) +{ + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + CoglTexture *texture; + int hot_x, hot_y; + int width, height; + float texture_scale; + + texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); + if (!texture) + return (MetaRectangle) { 0 }; + + meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y); + texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite); + width = cogl_texture_get_width (texture); + height = cogl_texture_get_height (texture); + + return (MetaRectangle) { + .x = (int)roundf (priv->current_x - (hot_x * texture_scale)), + .y = (int)roundf (priv->current_y - (hot_y * texture_scale)), + .width = (int)roundf (width * texture_scale), + .height = (int)roundf (height * texture_scale), + }; +} + static void -update_cursor (MetaCursorRenderer *renderer) +update_cursor (MetaCursorRenderer *renderer, + MetaCursorSprite *cursor_sprite) { MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); gboolean handled_by_backend; gboolean should_redraw = FALSE; - if (priv->displayed_cursor) - { - CoglTexture *texture; - int hot_x, hot_y; - - texture = meta_cursor_sprite_get_cogl_texture (priv->displayed_cursor, - &hot_x, &hot_y); - - priv->current_rect.x = priv->current_x - hot_x; - priv->current_rect.y = priv->current_y - hot_y; - priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture)); - priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture)); - } - else - { - priv->current_rect.x = 0; - priv->current_rect.y = 0; - priv->current_rect.width = 0; - priv->current_rect.height = 0; - } + if (cursor_sprite) + meta_cursor_sprite_prepare_at (cursor_sprite, + priv->current_x, + priv->current_y); - handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer); + handled_by_backend = + META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer, + cursor_sprite); if (handled_by_backend != priv->handled_by_backend) { priv->handled_by_backend = handled_by_backend; @@ -123,7 +142,7 @@ update_cursor (MetaCursorRenderer *renderer) should_redraw = TRUE; if (should_redraw) - queue_redraw (renderer); + queue_redraw (renderer, cursor_sprite); } MetaCursorRenderer * @@ -140,16 +159,18 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, if (priv->displayed_cursor == cursor_sprite) return; - priv->displayed_cursor = cursor_sprite; - update_cursor (renderer); + + update_cursor (renderer, cursor_sprite); } void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer) { - update_cursor (renderer); - queue_redraw (renderer); + MetaCursorRendererPrivate *priv = + meta_cursor_renderer_get_instance_private (renderer); + + update_cursor (renderer, priv->displayed_cursor); } void @@ -163,7 +184,7 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, priv->current_x = x; priv->current_y = y; - update_cursor (renderer); + update_cursor (renderer, priv->displayed_cursor); } MetaCursorSprite * @@ -174,14 +195,6 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer) return priv->displayed_cursor; } -const MetaRectangle * -meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer) -{ - MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); - - return &priv->current_rect; -} - #ifdef HAVE_WAYLAND void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer, |