keyrouter: Fix wrong return value
[platform/core/uifw/libds-tizen.git] / src / libds / region.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <pixman.h>
5
6 #include "libds/log.h"
7
8 #include "region.h"
9
10 static const struct wl_region_interface region_impl;
11
12 static void region_handle_resource_destroy(struct wl_resource *resource);
13
14 void
15 ds_region_add(struct wl_client *client, uint32_t version, uint32_t id)
16 {
17     struct wl_resource *resource;
18     pixman_region32_t *region;
19
20     region = calloc(1, sizeof *region);
21     if (!region) {
22         wl_client_post_no_memory(client);
23         return;
24     }
25
26     pixman_region32_init(region);
27
28     resource = wl_resource_create(client, &wl_region_interface, version, id);
29     if (!resource) {
30         free(region);
31         wl_client_post_no_memory(client);
32         return;
33     }
34
35     wl_resource_set_implementation(resource, &region_impl, region,
36             region_handle_resource_destroy);
37 }
38
39 pixman_region32_t *
40 ds_region_from_resource(struct wl_resource *resource)
41 {
42     assert(wl_resource_instance_of(resource, &wl_region_interface,
43                 &region_impl));
44     return wl_resource_get_user_data(resource);
45 }
46
47 void
48 ds_region_transform(pixman_region32_t *dst, pixman_region32_t *src,
49         enum wl_output_transform transform, int width, int height)
50 {
51     pixman_box32_t *src_rects, *dst_rects;
52     int nrects, i;
53
54     if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
55         pixman_region32_copy(dst, src);
56         return;
57     }
58
59     src_rects = pixman_region32_rectangles(src, &nrects);
60     dst_rects = malloc(nrects * sizeof *dst_rects);
61     if (!dst_rects)
62         return;
63
64     for (i = 0; i < nrects; i++) {
65         switch (transform) {
66             default:
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;
73                 break; 
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;
79                 break;
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;
85                 break;
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;
91                 break;
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;
97                 break;
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;
103                 break;
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;
109                 break;
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;
115                 break;
116        }
117     }
118
119     pixman_region32_fini(dst);
120     pixman_region32_init_rects(dst, dst_rects, nrects);
121     free(dst_rects);
122 }
123
124 void
125 ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src,
126         float scale_x, float scale_y)
127 {
128     pixman_box32_t *src_rects, *dst_rects;
129     int nrects, i;
130
131     if (scale_x == 1.0 && scale_y == 1.0)
132         pixman_region32_copy(dst, src);
133
134     src_rects = pixman_region32_rectangles(src, &nrects);
135     dst_rects = malloc(nrects * sizeof *dst_rects);
136     if (!dst_rects)
137         return;
138
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);
144     }
145
146     pixman_region32_fini(dst);
147     pixman_region32_init_rects(dst, dst_rects, nrects);
148     free(dst_rects);
149 }
150
151 void
152 ds_region_scale(pixman_region32_t *dst, pixman_region32_t *src, float scale)
153 {
154     ds_region_scale_xy(dst, src, scale, scale);
155 }
156
157 static void
158 region_destroy(struct wl_client *client, struct wl_resource *resource)
159 {
160     wl_resource_destroy(resource);
161 }
162
163 static void
164 region_add(struct wl_client *client, struct wl_resource *resource,
165         int32_t x, int32_t y, int32_t width, int32_t height)
166 {
167     pixman_region32_t *region = wl_resource_get_user_data(resource);
168     pixman_region32_union_rect(region, region, x, y, width, height);
169 }
170
171 static void
172 region_subtract(struct wl_client *client, struct wl_resource *resource,
173         int32_t x, int32_t y, int32_t width, int32_t height)
174 {
175     pixman_region32_t *region = wl_resource_get_user_data(resource);
176     pixman_region32_t rect;
177
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);
182 }
183
184 static const struct wl_region_interface region_impl =
185 {
186     .destroy = region_destroy,
187     .add = region_add,
188     .subtract = region_subtract,
189 };
190
191 static void
192 region_handle_resource_destroy(struct wl_resource *resource)
193 {
194     pixman_region32_t *region = wl_resource_get_user_data(resource);
195     pixman_region32_fini(region);
196     free(region);
197 }