commit 117c1c7f2764c08ea35e1f3d839af2b6fb2b3e11
parent 4b5d2a86499fb1f96f5699f1655f11380d83e97c
Author: Michael Forney <mforney@mforney.org>
Date: Fri, 14 Jun 2013 01:33:02 -0700
Implement regions
Diffstat:
5 files changed, 115 insertions(+), 3 deletions(-)
diff --git a/Makefile.am b/Makefile.am
@@ -12,6 +12,7 @@ libswc_la_SOURCES = \
output.c output.h \
buffer.c buffer.h \
surface.c surface.h \
+ region.c region.h \
renderer.c renderer.h \
seat.c seat.h \
mode.c mode.h \
diff --git a/compositor.c b/compositor.c
@@ -214,6 +214,17 @@ static void create_surface(struct wl_client * client,
static void create_region(struct wl_client * client,
struct wl_resource * resource, uint32_t id)
{
+ struct swc_region * region;
+
+ region = malloc(sizeof *region);
+
+ if (!region)
+ {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ swc_region_initialize(region, client, id);
}
struct wl_compositor_interface compositor_implementation = {
diff --git a/region.c b/region.c
@@ -0,0 +1,64 @@
+#include "region.h"
+
+#include <stdlib.h>
+
+static void destroy_region_resource(struct wl_resource * resource)
+{
+ struct swc_region * region;
+
+ region = resource->data;
+ swc_region_finish(region);
+
+ free(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 width, int32_t height)
+{
+ struct swc_region * region = resource->data;
+
+ pixman_region32_union_rect(®ion->region, ®ion->region,
+ x, y, width, height);
+}
+
+static void region_subtract(struct wl_client * client,
+ struct wl_resource * resource,
+ int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ struct swc_region * region = resource->data;
+ pixman_region32_t operand;
+
+ pixman_region32_init_rect(&operand, x, y, width, height);
+ pixman_region32_subtract(®ion->region, ®ion->region, &operand);
+}
+
+static const struct wl_region_interface region_implementation = {
+ .destroy = ®ion_destroy,
+ .add = ®ion_add,
+ .subtract = ®ion_subtract
+};
+
+bool swc_region_initialize(struct swc_region * region, struct wl_client * client,
+ uint32_t id)
+{
+ pixman_region32_init(®ion->region);
+
+ region->resource = wl_client_add_object(client, &wl_region_interface,
+ ®ion_implementation, id, region);
+ wl_resource_set_destructor(region->resource, &destroy_region_resource);
+
+ return true;
+}
+
+void swc_region_finish(struct swc_region * region)
+{
+ pixman_region32_fini(®ion->region);
+}
+
diff --git a/region.h b/region.h
@@ -0,0 +1,20 @@
+#ifndef SWC_REGION_H
+#define SWC_REGION_H 1
+
+#include <stdbool.h>
+#include <pixman.h>
+#include <wayland-server.h>
+
+struct swc_region
+{
+ struct wl_resource * resource;
+ pixman_region32_t region;
+};
+
+bool swc_region_initialize(struct swc_region * region, struct wl_client * client,
+ uint32_t id);
+
+void swc_region_finish(struct swc_region * region);
+
+#endif
+
diff --git a/surface.c b/surface.c
@@ -1,5 +1,6 @@
#include "surface.h"
#include "event.h"
+#include "region.h"
#include <stdio.h>
@@ -102,17 +103,30 @@ void swc_surface_set_opaque_region(struct wl_client * client,
if (region_resource)
{
+ struct swc_region * region = region_resource->data;
+
+ pixman_region32_copy(&surface->pending.state.opaque, ®ion->region);
}
else
- {
- }
+ pixman_region32_clear(&surface->pending.state.opaque);
}
void swc_surface_set_input_region(struct wl_client * client,
struct wl_resource * resource,
- struct wl_resource * region)
+ struct wl_resource * region_resource)
{
+ struct swc_surface * surface = resource->data;
+
printf("surface_set_input_region\n");
+
+ if (region_resource)
+ {
+ struct swc_region * region = region_resource->data;
+
+ pixman_region32_copy(&surface->pending.state.input, ®ion->region);
+ }
+ else
+ pixman_region32_clear(&surface->pending.state.input);
}
void swc_surface_commit(struct wl_client * client,
@@ -145,6 +159,8 @@ void swc_surface_commit(struct wl_client * client,
/* Reset pending state */
pixman_region32_clear(&surface->pending.state.damage);
+ pixman_region32_clear(&surface->pending.state.opaque);
+ pixman_region32_clear(&surface->pending.state.input);
surface->pending.state.buffer = surface->state.buffer;
wl_list_init(&surface->pending.state.frame_callbacks);