wl_region implementation
authorTaekyun Kim <tkq.kim@samsung.com>
Thu, 26 Mar 2015 03:37:43 +0000 (12:37 +0900)
committerTaekyun Kim <tkq.kim@samsung.com>
Fri, 19 Jun 2015 09:06:39 +0000 (18:06 +0900)
Implemented using pixman region.

Change-Id: If83abf5a2da62ae69e3f8b5be141156cc043d619

src/Makefile.am
src/compositor.c
src/pepper-internal.h
src/region.c [new file with mode: 0644]

index 0867fd09e2f7e9fcfc3539ac8d718e010fab3074..da8789e86cb0165c5e23fdd11521e6ac53627fb2 100644 (file)
@@ -19,7 +19,8 @@ libpepper_la_SOURCES = pepper.h                 \
                        input.c                  \
                        client.c                 \
                        shell.c                  \
-                       surface.c
+                       surface.c                \
+                       region.c
 
 # wayland backend
 if ENABLE_WAYLAND_BACKEND
index 5840f28c415b56d4ddbeb66241022608bf243261..6f9a7b9627d8da5a9c696a5d34b68ef380a868fc 100644 (file)
@@ -15,7 +15,8 @@ compositor_create_region(struct wl_client   *client,
                          struct wl_resource *resource,
                          uint32_t            id)
 {
-    PEPPER_TRACE("TODO: %s\n", __FUNCTION__);
+    pepper_compositor_t *compositor = wl_resource_get_user_data(resource);
+    pepper_region_create(compositor, client, resource, id);
 }
 
 static const struct wl_compositor_interface compositor_interface =
index 71d807cbbc128fbfee91db86c765b260b564d259..a0a3cf01a5f43bd3cda27faacd03d049b2a4689b 100644 (file)
@@ -4,8 +4,10 @@
 #include "common.h"
 #include "pepper.h"
 #include <wayland-util.h>
+#include <pixman.h>
 
 typedef struct pepper_surface   pepper_surface_t;
+typedef struct pepper_region    pepper_region_t;
 
 /* compositor */
 struct pepper_compositor
@@ -13,6 +15,7 @@ struct pepper_compositor
     char                    *socket_name;
     struct wl_display       *display;
     struct wl_list          surfaces;
+    struct wl_list          regions;
 };
 
 struct pepper_output
@@ -39,10 +42,26 @@ struct pepper_surface
     struct wl_resource  *resource;
 };
 
+struct pepper_region
+{
+    pepper_compositor_t *compositor;
+    struct wl_resource  *resource;
+    pixman_region32_t   pixman_region;
+};
+
 pepper_surface_t *
 pepper_surface_create(pepper_compositor_t *compositor,
                       struct wl_client *client,
                       struct wl_resource *resource,
                       uint32_t id);
 
+pepper_region_t *
+pepper_region_create(pepper_compositor_t *compositor,
+                      struct wl_client *client,
+                      struct wl_resource *resource,
+                      uint32_t id);
+
+void
+pepper_region_destroy(pepper_region_t *region);
+
 #endif /* PEPPER_INTERNAL_H */
diff --git a/src/region.c b/src/region.c
new file mode 100644 (file)
index 0000000..5ba2d2c
--- /dev/null
@@ -0,0 +1,84 @@
+#include "pepper-internal.h"
+
+static void
+region_resource_destroy_handler(struct wl_resource *resource)
+{
+    pepper_region_t *region = wl_resource_get_user_data(resource);
+    pepper_region_destroy(region);
+}
+
+static void
+region_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+    wl_resource_destroy(resource);
+}
+
+static void
+region_add(struct wl_client *client, struct wl_resource *resource,
+           int32_t x, int32_t y, int32_t w, int32_t h)
+{
+    pepper_region_t *region = wl_resource_get_user_data(resource);
+    pixman_region32_union_rect(&region->pixman_region, &region->pixman_region,
+                               x, y, w, h);
+}
+
+static void
+region_subtract(struct wl_client *client, struct wl_resource *resource,
+                int32_t x, int32_t y, int32_t w, int32_t h)
+{
+    pepper_region_t    *region = wl_resource_get_user_data(resource);
+    pixman_region32_t   rect;
+
+    pixman_region32_init_rect(&rect, x, y, w, h);
+    pixman_region32_subtract(&region->pixman_region, &region->pixman_region, &rect);
+    pixman_region32_fini(&rect);
+}
+
+static const struct wl_region_interface region_implementation =
+{
+    region_destroy,
+    region_add,
+    region_subtract,
+};
+
+pepper_region_t *
+pepper_region_create(pepper_compositor_t   *compositor,
+                     struct wl_client      *client,
+                     struct wl_resource    *resource,
+                     uint32_t               id)
+{
+    pepper_region_t *region;
+
+    region = (pepper_region_t *)pepper_calloc(1, sizeof(pepper_region_t));
+
+    if (!region)
+    {
+        PEPPER_ERROR("Surface memory allocation failed\n");
+        wl_resource_post_no_memory(resource);
+        return NULL;
+    }
+
+    region->compositor = compositor;
+    region->resource = wl_resource_create(client, &wl_region_interface, 1, id);
+
+    if (!region->resource)
+    {
+        PEPPER_ERROR("wl_resource_create failed\n");
+        pepper_free(region);
+        wl_resource_post_no_memory(resource);
+        pepper_free(region);
+        return NULL;
+    }
+
+    wl_resource_set_implementation(region->resource, &region_implementation,
+                                   region, region_resource_destroy_handler);
+    wl_list_insert(&compositor->regions, wl_resource_get_link(region->resource));
+
+    return region;
+}
+
+void
+pepper_region_destroy(pepper_region_t *region)
+{
+    pixman_region32_fini(&region->pixman_region);
+}