Define struct weston_matrix_pointer, which acts as pointer to a matrix,
not a matrix itself. This type is stored into
weston_surface::geometry.transformation_list instead of
weston_transform.

This is a step towards making surface transformations properly
inheritable. Transformation list can refer to another matrix, without
adding hooks to maintain a copy of that matrix.

Signed-off-by: Pekka Paalanen <[email protected]>
---
 src/compositor.c |   18 +++++++++++-------
 src/compositor.h |   27 +++++++++++++++++++--------
 src/shell.c      |   49 +++++++++++++++++++++++++++----------------------
 src/util.c       |    5 +++--
 4 files changed, 60 insertions(+), 39 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 24ae6e3..1533cbc 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -293,9 +293,12 @@ weston_surface_create(struct weston_compositor *compositor)
        wl_list_init(&surface->frame_callback_list);
 
        wl_list_init(&surface->geometry.transformation_list);
-       wl_list_insert(&surface->geometry.transformation_list,
-                      &surface->transform.position.link);
+
        weston_matrix_init(&surface->transform.position.matrix);
+       weston_transform_init(&surface->transform.position);
+       wl_list_insert(&surface->geometry.transformation_list,
+                      &surface->transform.position.ptr.link);
+
        pixman_region32_init(&surface->transform.boundingbox);
        surface->transform.dirty = 1;
 
@@ -539,7 +542,7 @@ weston_surface_update_transform_enable(struct 
weston_surface *surface)
 {
        struct weston_matrix *matrix = &surface->transform.matrix;
        struct weston_matrix *inverse = &surface->transform.inverse;
-       struct weston_transform *tform;
+       struct weston_matrix_pointer *ptr;
 
        surface->transform.enabled = 1;
 
@@ -548,8 +551,9 @@ weston_surface_update_transform_enable(struct 
weston_surface *surface)
        surface->transform.position.matrix.d[13] = surface->geometry.y;
 
        weston_matrix_init(matrix);
-       wl_list_for_each(tform, &surface->geometry.transformation_list, link)
-               weston_matrix_multiply(matrix, &tform->matrix);
+       wl_list_for_each(ptr, &surface->geometry.transformation_list, link) {
+               weston_matrix_multiply(matrix, ptr->matrix);
+       }
 
        if (weston_matrix_invert(inverse, matrix) < 0) {
                /* Oops, bad total transformation, not invertible */
@@ -581,9 +585,9 @@ weston_surface_update_transform(struct weston_surface 
*surface)
 
        /* transform.position is always in transformation_list */
        if (surface->geometry.transformation_list.next ==
-           &surface->transform.position.link &&
+           &surface->transform.position.ptr.link &&
            surface->geometry.transformation_list.prev ==
-           &surface->transform.position.link) {
+           &surface->transform.position.ptr.link) {
                weston_surface_update_transform_disable(surface);
        } else {
                if (weston_surface_update_transform_enable(surface) < 0)
diff --git a/src/compositor.h b/src/compositor.h
index 3a3580a..b681481 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -37,11 +37,6 @@
        const __typeof__( ((type *)0)->member ) *__mptr = (ptr);        \
        (type *)( (char *)__mptr - offsetof(type,member) );})
 
-struct weston_transform {
-       struct weston_matrix matrix;
-       struct wl_list link;
-};
-
 struct weston_surface;
 struct shell_surface;
 struct weston_seat;
@@ -345,6 +340,16 @@ struct weston_compositor {
        struct weston_xkb_info xkb_info;
 };
 
+struct weston_matrix_pointer {
+       struct weston_matrix *matrix;
+       struct wl_list link;
+};
+
+struct weston_transform {
+       struct weston_matrix matrix;
+       struct weston_matrix_pointer ptr;
+};
+
 struct weston_buffer_reference {
        struct wl_buffer *buffer;
        struct wl_listener destroy_listener;
@@ -357,8 +362,8 @@ struct weston_region {
 
 /* Using weston_surface transformations
  *
- * To add a transformation to a surface, create a struct weston_transform, and
- * add it to the list surface->geometry.transformation_list. Whenever you
+ * To add a transformation to a surface, create a struct weston_matrix_pointer,
+ * and add it to the list surface->geometry.transformation_list. Whenever you
  * change the list, anything under surface->geometry, or anything in the
  * weston_transforms linked into the list, you must call
  * weston_surface_geometry_dirty().
@@ -402,7 +407,7 @@ struct weston_surface {
                float x, y; /* surface translation on display */
                int32_t width, height;
 
-               /* struct weston_transform */
+               /* struct weston_matrix_pointer::link */
                struct wl_list transformation_list;
        } geometry;
 
@@ -845,4 +850,10 @@ weston_transformed_rect(int width, int height,
                        enum wl_output_transform transform,
                        pixman_box32_t rect);
 
+static inline void
+weston_transform_init(struct weston_transform *tform)
+{
+       tform->ptr.matrix = &tform->matrix;
+}
+
 #endif
diff --git a/src/shell.c b/src/shell.c
index 5b9acd7..e25140d 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -587,9 +587,9 @@ surface_translate(struct weston_surface *surface, double d)
        struct weston_transform *transform;
 
        transform = &shsurf->workspace_transform;
-       if (wl_list_empty(&transform->link))
+       if (wl_list_empty(&transform->ptr.link))
                wl_list_insert(surface->geometry.transformation_list.prev,
-                              &shsurf->workspace_transform.link);
+                              &shsurf->workspace_transform.ptr.link);
 
        weston_matrix_init(&shsurf->workspace_transform.matrix);
        weston_matrix_translate(&shsurf->workspace_transform.matrix,
@@ -666,9 +666,9 @@ workspace_deactivate_transforms(struct workspace *ws)
 
        wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
                shsurf = get_shell_surface(surface);
-               if (!wl_list_empty(&shsurf->workspace_transform.link)) {
-                       wl_list_remove(&shsurf->workspace_transform.link);
-                       wl_list_init(&shsurf->workspace_transform.link);
+               if (!wl_list_empty(&shsurf->workspace_transform.ptr.link)) {
+                       wl_list_remove(&shsurf->workspace_transform.ptr.link);
+                       wl_list_init(&shsurf->workspace_transform.ptr.link);
                }
                weston_surface_geometry_dirty(surface);
        }
@@ -919,9 +919,9 @@ take_surface_to_workspace_by_seat(struct desktop_shell 
*shell,
                update_workspace(shell, index, from, to);
        else {
                shsurf = get_shell_surface(surface);
-               if (wl_list_empty(&shsurf->workspace_transform.link))
+               if (wl_list_empty(&shsurf->workspace_transform.ptr.link))
                        wl_list_insert(&shell->workspaces.anim_sticky_list,
-                                      &shsurf->workspace_transform.link);
+                                      &shsurf->workspace_transform.ptr.link);
 
                animate_workspace_change(shell, index, from, to);
        }
@@ -1434,8 +1434,8 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
        }
        shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
        shsurf->fullscreen.framerate = 0;
-       wl_list_remove(&shsurf->fullscreen.transform.link);
-       wl_list_init(&shsurf->fullscreen.transform.link);
+       wl_list_remove(&shsurf->fullscreen.transform.ptr.link);
+       wl_list_init(&shsurf->fullscreen.transform.ptr.link);
        if (shsurf->fullscreen.black_surface)
                weston_surface_destroy(shsurf->fullscreen.black_surface);
        shsurf->fullscreen.black_surface = NULL;
@@ -1444,7 +1444,7 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
                                    shsurf->saved_x, shsurf->saved_y);
        if (shsurf->saved_rotation_valid) {
                wl_list_insert(&shsurf->surface->geometry.transformation_list,
-                              &shsurf->rotation.transform.link);
+                              &shsurf->rotation.transform.ptr.link);
                shsurf->saved_rotation_valid = false;
        }
 
@@ -1508,9 +1508,9 @@ set_surface_type(struct shell_surface *shsurf)
                shsurf->saved_y = surface->geometry.y;
                shsurf->saved_position_valid = true;
 
-               if (!wl_list_empty(&shsurf->rotation.transform.link)) {
-                       wl_list_remove(&shsurf->rotation.transform.link);
-                       wl_list_init(&shsurf->rotation.transform.link);
+               if (!wl_list_empty(&shsurf->rotation.transform.ptr.link)) {
+                       wl_list_remove(&shsurf->rotation.transform.ptr.link);
+                       wl_list_init(&shsurf->rotation.transform.ptr.link);
                        weston_surface_geometry_dirty(shsurf->surface);
                        shsurf->saved_rotation_valid = true;
                }
@@ -1686,9 +1686,9 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
                                (float) surface->geometry.height;
 
                weston_matrix_scale(matrix, scale, scale, 1);
-               wl_list_remove(&shsurf->fullscreen.transform.link);
+               wl_list_remove(&shsurf->fullscreen.transform.ptr.link);
                wl_list_insert(&surface->geometry.transformation_list,
-                              &shsurf->fullscreen.transform.link);
+                              &shsurf->fullscreen.transform.ptr.link);
                x = output->x + (output->width - surface->geometry.width * 
scale) / 2;
                y = output->y + (output->height - surface->geometry.height * 
scale) / 2;
                weston_surface_set_position(surface, x, y);
@@ -1881,7 +1881,7 @@ shell_map_popup(struct shell_surface *shsurf)
                        parent->geometry.y;
        }
        wl_list_insert(es->geometry.transformation_list.prev,
-                      &shsurf->popup.parent_transform.link);
+                      &shsurf->popup.parent_transform.ptr.link);
 
        shsurf->popup.initial_up = 0;
        weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
@@ -2018,7 +2018,7 @@ create_shell_surface(void *shell, struct weston_surface 
*surface,
        shsurf->fullscreen.framerate = 0;
        shsurf->fullscreen.black_surface = NULL;
        shsurf->ping_timer = NULL;
-       wl_list_init(&shsurf->fullscreen.transform.link);
+       wl_list_init(&shsurf->fullscreen.transform.ptr.link);
 
        wl_signal_init(&shsurf->resource.destroy_signal);
        shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
@@ -2029,10 +2029,15 @@ create_shell_surface(void *shell, struct weston_surface 
*surface,
        wl_list_init(&shsurf->link);
 
        /* empty when not in use */
-       wl_list_init(&shsurf->rotation.transform.link);
+       wl_list_init(&shsurf->rotation.transform.ptr.link);
+       weston_transform_init(&shsurf->rotation.transform);
        weston_matrix_init(&shsurf->rotation.rotation);
 
-       wl_list_init(&shsurf->workspace_transform.link);
+       weston_transform_init(&shsurf->popup.parent_transform);
+       weston_transform_init(&shsurf->fullscreen.transform);
+
+       wl_list_init(&shsurf->workspace_transform.ptr.link);
+       weston_transform_init(&shsurf->workspace_transform);
 
        shsurf->type = SHELL_SURFACE_NONE;
        shsurf->next_type = SHELL_SURFACE_NONE;
@@ -2497,7 +2502,7 @@ rotate_grab_motion(struct wl_pointer_grab *grab,
        dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
        r = sqrtf(dx * dx + dy * dy);
 
-       wl_list_remove(&shsurf->rotation.transform.link);
+       wl_list_remove(&shsurf->rotation.transform.ptr.link);
        weston_surface_geometry_dirty(shsurf->surface);
 
        if (r > 20.0f) {
@@ -2518,9 +2523,9 @@ rotate_grab_motion(struct wl_pointer_grab *grab,
 
                wl_list_insert(
                        &shsurf->surface->geometry.transformation_list,
-                       &shsurf->rotation.transform.link);
+                       &shsurf->rotation.transform.ptr.link);
        } else {
-               wl_list_init(&shsurf->rotation.transform.link);
+               wl_list_init(&shsurf->rotation.transform.ptr.link);
                weston_matrix_init(&shsurf->rotation.rotation);
                weston_matrix_init(&rotate->rotation);
        }
diff --git a/src/util.c b/src/util.c
index bae1bb9..91c83a6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -115,7 +115,7 @@ weston_surface_animation_destroy(struct 
weston_surface_animation *animation)
 {
        wl_list_remove(&animation->animation.link);
        wl_list_remove(&animation->listener.link);
-       wl_list_remove(&animation->transform.link);
+       wl_list_remove(&animation->transform.ptr.link);
        weston_surface_geometry_dirty(animation->surface);
        if (animation->done)
                animation->done(animation, animation->data);
@@ -177,8 +177,9 @@ weston_surface_animation_run(struct weston_surface *surface,
        animation->start = start;
        animation->stop = stop;
        weston_matrix_init(&animation->transform.matrix);
+       weston_transform_init(&animation->transform);
        wl_list_insert(&surface->geometry.transformation_list,
-                      &animation->transform.link);
+                      &animation->transform.ptr.link);
        weston_spring_init(&animation->spring, 200.0, 0.0, 1.0);
        animation->spring.friction = 700;
        animation->animation.frame_counter = 0;
-- 
1.7.8.6

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to