10 static const struct wl_region_interface region_impl;
12 static void region_handle_resource_destroy(struct wl_resource *resource);
15 ds_region_add(struct wl_client *client, uint32_t version, uint32_t id)
17 struct wl_resource *resource;
18 pixman_region32_t *region;
20 region = calloc(1, sizeof *region);
22 wl_client_post_no_memory(client);
26 pixman_region32_init(region);
28 resource = wl_resource_create(client, &wl_region_interface, version, id);
31 wl_client_post_no_memory(client);
35 wl_resource_set_implementation(resource, ®ion_impl, region,
36 region_handle_resource_destroy);
40 ds_region_from_resource(struct wl_resource *resource)
42 assert(wl_resource_instance_of(resource, &wl_region_interface,
44 return wl_resource_get_user_data(resource);
48 ds_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
49 enum wl_output_transform transform, int width, int height)
51 pixman_box32_t *src_rects, *dst_rects;
54 if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
55 pixman_region32_copy(dst, src);
59 src_rects = pixman_region32_rectangles(src, &nrects);
60 dst_rects = malloc(nrects * sizeof *dst_rects);
64 for (i = 0; i < nrects; i++) {
67 ds_err("Unkown transform value(%d)", transform);
68 case WL_OUTPUT_TRANSFORM_NORMAL:
69 dst_rects[i].x1 = src_rects[i].x1;
70 dst_rects[i].y1 = src_rects[i].y1;
71 dst_rects[i].x2 = src_rects[i].x2;
72 dst_rects[i].y2 = src_rects[i].y2;
74 case WL_OUTPUT_TRANSFORM_90:
75 dst_rects[i].x1 = height - src_rects[i].y2;
76 dst_rects[i].y1 = src_rects[i].x1;
77 dst_rects[i].x2 = height - src_rects[i].y1;
78 dst_rects[i].y2 = src_rects[i].x2;
80 case WL_OUTPUT_TRANSFORM_180:
81 dst_rects[i].x1 = width - src_rects[i].x2;
82 dst_rects[i].y1 = height - src_rects[i].y2;
83 dst_rects[i].x2 = width - src_rects[i].x1;
84 dst_rects[i].y2 = height - src_rects[i].y1;
86 case WL_OUTPUT_TRANSFORM_270:
87 dst_rects[i].x1 = src_rects[i].y1;
88 dst_rects[i].y1 = width - src_rects[i].x2;
89 dst_rects[i].x2 = src_rects[i].y2;
90 dst_rects[i].y2 = width - src_rects[i].x1;
92 case WL_OUTPUT_TRANSFORM_FLIPPED:
93 dst_rects[i].x1 = width - src_rects[i].x2;
94 dst_rects[i].y1 = src_rects[i].y1;
95 dst_rects[i].x2 = width - src_rects[i].x1;
96 dst_rects[i].y2 = src_rects[i].y2;
98 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
99 dst_rects[i].x1 = src_rects[i].y1;
100 dst_rects[i].y1 = src_rects[i].x1;
101 dst_rects[i].x2 = src_rects[i].y2;
102 dst_rects[i].y2 = src_rects[i].x2;
104 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
105 dst_rects[i].x1 = src_rects[i].x1;
106 dst_rects[i].y1 = height - src_rects[i].y2;
107 dst_rects[i].x2 = src_rects[i].x2;
108 dst_rects[i].y2 = height - src_rects[i].y1;
110 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
111 dst_rects[i].x1 = height - src_rects[i].y2;
112 dst_rects[i].y1 = width - src_rects[i].x2;
113 dst_rects[i].x2 = height - src_rects[i].y1;
114 dst_rects[i].y2 = width - src_rects[i].x1;
119 pixman_region32_fini(dst);
120 pixman_region32_init_rects(dst, dst_rects, nrects);
125 ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src,
126 float scale_x, float scale_y)
128 pixman_box32_t *src_rects, *dst_rects;
131 if (scale_x == 1.0 && scale_y == 1.0)
132 pixman_region32_copy(dst, src);
134 src_rects = pixman_region32_rectangles(src, &nrects);
135 dst_rects = malloc(nrects * sizeof *dst_rects);
139 for (i = 0; i < nrects; i++) {
140 dst_rects[i].x1 = floor(src_rects[i].x1 * scale_x);
141 dst_rects[i].x2 = ceil(src_rects[i].x2 * scale_x);
142 dst_rects[i].y1 = floor(src_rects[i].y1 * scale_y);
143 dst_rects[i].y2 = ceil(src_rects[i].y2 * scale_y);
146 pixman_region32_fini(dst);
147 pixman_region32_init_rects(dst, dst_rects, nrects);
152 ds_region_scale(pixman_region32_t *dst, pixman_region32_t *src, float scale)
154 ds_region_scale_xy(dst, src, scale, scale);
158 region_destroy(struct wl_client *client, struct wl_resource *resource)
160 wl_resource_destroy(resource);
164 region_add(struct wl_client *client, struct wl_resource *resource,
165 int32_t x, int32_t y, int32_t width, int32_t height)
167 pixman_region32_t *region = wl_resource_get_user_data(resource);
168 pixman_region32_union_rect(region, region, x, y, width, height);
172 region_subtract(struct wl_client *client, struct wl_resource *resource,
173 int32_t x, int32_t y, int32_t width, int32_t height)
175 pixman_region32_t *region = wl_resource_get_user_data(resource);
176 pixman_region32_t rect;
178 pixman_region32_union_rect(region, region, x, y, width, height);
179 pixman_region32_init_rect(&rect, x, y, width, height);
180 pixman_region32_subtract(region, region, &rect);
181 pixman_region32_fini(&rect);
184 static const struct wl_region_interface region_impl =
186 .destroy = region_destroy,
188 .subtract = region_subtract,
192 region_handle_resource_destroy(struct wl_resource *resource)
194 pixman_region32_t *region = wl_resource_get_user_data(resource);
195 pixman_region32_fini(region);