1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "host/libs/wayland/wayland_compositor.h"
18
19 #include <android-base/logging.h>
20
21 #include <wayland-server-core.h>
22 #include <wayland-server-protocol.h>
23
24 #include "host/libs/wayland/wayland_surface.h"
25 #include "host/libs/wayland/wayland_utils.h"
26
27 namespace wayland {
28 namespace {
29
region_destroy(wl_client *,wl_resource * region_resource)30 void region_destroy(wl_client*, wl_resource* region_resource) {
31 LOG(VERBOSE) << __FUNCTION__
32 << " region=" << region_resource;
33
34 wl_resource_destroy(region_resource);
35 }
36
region_add(wl_client *,wl_resource * region_resource,int32_t x,int32_t y,int32_t w,int32_t h)37 void region_add(wl_client*,
38 wl_resource* region_resource,
39 int32_t x,
40 int32_t y,
41 int32_t w,
42 int32_t h) {
43 LOG(VERBOSE) << __FUNCTION__
44 << " region=" << region_resource
45 << " x=" << x
46 << " y=" << y
47 << " w=" << w
48 << " h=" << h;
49
50 Surface::Region* region = GetUserData<Surface::Region>(region_resource);
51 region->x = x;
52 region->y = y;
53 region->w = w;
54 region->h = h;
55 }
56
region_subtract(wl_client *,wl_resource * region_resource,int32_t x,int32_t y,int32_t w,int32_t h)57 void region_subtract(wl_client*,
58 wl_resource* region_resource,
59 int32_t x,
60 int32_t y,
61 int32_t w,
62 int32_t h) {
63 LOG(VERBOSE) << __FUNCTION__
64 << " region=" << region_resource
65 << " x=" << x
66 << " y=" << y
67 << " w=" << w
68 << " h=" << h;
69 }
70
71 const struct wl_region_interface region_implementation = {
72 .destroy = region_destroy,
73 .add = region_add,
74 .subtract = region_subtract,
75 };
76
surface_destroy(wl_client *,wl_resource * surface)77 void surface_destroy(wl_client*, wl_resource* surface) {
78 LOG(VERBOSE) << __FUNCTION__
79 << " surface=" << surface;
80
81 delete GetUserData<Surface>(surface);
82 }
83
surface_attach(wl_client *,wl_resource * surface,wl_resource * buffer,int32_t x,int32_t y)84 void surface_attach(wl_client*,
85 wl_resource* surface,
86 wl_resource* buffer,
87 int32_t x,
88 int32_t y) {
89 LOG(VERBOSE) << __FUNCTION__
90 << " surface=" << surface
91 << " buffer=" << buffer
92 << " x=" << x
93 << " y=" << y;
94
95 GetUserData<Surface>(surface)->Attach(buffer);
96 }
97
surface_damage(wl_client *,wl_resource * surface_resource,int32_t x,int32_t y,int32_t w,int32_t h)98 void surface_damage(wl_client*,
99 wl_resource* surface_resource,
100 int32_t x,
101 int32_t y,
102 int32_t w,
103 int32_t h) {
104 LOG(VERBOSE) << __FUNCTION__
105 << " surface=" << surface_resource
106 << " x=" << x
107 << " y=" << y
108 << " w=" << w
109 << " h=" << h;
110 }
111
surface_frame(wl_client *,wl_resource * surface,uint32_t)112 void surface_frame(wl_client*, wl_resource* surface, uint32_t) {
113 LOG(VERBOSE) << " surface=" << surface;
114 }
115
surface_set_opaque_region(wl_client *,wl_resource * surface_resource,wl_resource * region_resource)116 void surface_set_opaque_region(wl_client*,
117 wl_resource* surface_resource,
118 wl_resource* region_resource) {
119 LOG(VERBOSE) << __FUNCTION__
120 << " surface=" << surface_resource
121 << " region=" << region_resource;
122
123 Surface* surface = GetUserData<Surface>(surface_resource);
124 Surface::Region* region = GetUserData<Surface::Region>(region_resource);
125
126 surface->SetRegion(*region);
127 }
128
surface_set_input_region(wl_client *,wl_resource * surface_resource,wl_resource * region_resource)129 void surface_set_input_region(wl_client*,
130 wl_resource* surface_resource,
131 wl_resource* region_resource) {
132 LOG(VERBOSE) << __FUNCTION__
133 << " surface=" << surface_resource
134 << " region=" << region_resource;
135 }
136
surface_commit(wl_client *,wl_resource * surface_resource)137 void surface_commit(wl_client*, wl_resource* surface_resource) {
138 LOG(VERBOSE) << __FUNCTION__
139 << " surface=" << surface_resource;
140
141 GetUserData<Surface>(surface_resource)->Commit();
142 }
143
surface_set_buffer_transform(wl_client *,wl_resource * surface_resource,int32_t transform)144 void surface_set_buffer_transform(wl_client*,
145 wl_resource* surface_resource,
146 int32_t transform) {
147 LOG(VERBOSE) << __FUNCTION__
148 << " surface=" << surface_resource
149 << " transform=" << transform;
150 }
151
surface_set_buffer_scale(wl_client *,wl_resource * surface_resource,int32_t scale)152 void surface_set_buffer_scale(wl_client*,
153 wl_resource* surface_resource,
154 int32_t scale) {
155 LOG(VERBOSE) << __FUNCTION__
156 << " surface=" << surface_resource
157 << " scale=" << scale;
158 }
159
surface_damage_buffer(wl_client *,wl_resource * surface_resource,int32_t x,int32_t y,int32_t w,int32_t h)160 void surface_damage_buffer(wl_client*,
161 wl_resource* surface_resource,
162 int32_t x,
163 int32_t y,
164 int32_t w,
165 int32_t h) {
166 LOG(VERBOSE) << __FUNCTION__
167 << " surface=" << surface_resource
168 << " x=" << x
169 << " y=" << y
170 << " w=" << w
171 << " h=" << h;
172 }
173
174 const struct wl_surface_interface surface_implementation = {
175 .destroy = surface_destroy,
176 .attach = surface_attach,
177 .damage = surface_damage,
178 .frame = surface_frame,
179 .set_opaque_region = surface_set_opaque_region,
180 .set_input_region = surface_set_input_region,
181 .commit = surface_commit,
182 .set_buffer_transform = surface_set_buffer_transform,
183 .set_buffer_scale = surface_set_buffer_scale,
184 .damage_buffer = surface_damage_buffer,
185 };
186
surface_destroy_resource_callback(struct wl_resource *)187 void surface_destroy_resource_callback(struct wl_resource*) {}
188
compositor_create_surface(wl_client * client,wl_resource * compositor,uint32_t id)189 void compositor_create_surface(wl_client* client,
190 wl_resource* compositor,
191 uint32_t id) {
192 LOG(VERBOSE) << __FUNCTION__
193 << " compositor=" << compositor
194 << " id=" << id;
195
196 Surfaces* surfaces = GetUserData<Surfaces>(compositor);
197 Surface* surface = new Surface(*surfaces);
198
199 wl_resource* surface_resource = wl_resource_create(
200 client, &wl_surface_interface, wl_resource_get_version(compositor), id);
201
202 wl_resource_set_implementation(surface_resource, &surface_implementation,
203 surface, surface_destroy_resource_callback);
204 }
205
compositor_create_region(wl_client * client,wl_resource * compositor,uint32_t id)206 void compositor_create_region(wl_client* client,
207 wl_resource* compositor,
208 uint32_t id) {
209 LOG(VERBOSE) << __FUNCTION__
210 << " compositor=" << compositor
211 << " id=" << id;
212
213 std::unique_ptr<Surface::Region> region(new Surface::Region());
214
215 wl_resource* region_resource = wl_resource_create(
216 client, &wl_region_interface, 1, id);
217
218 wl_resource_set_implementation(region_resource, ®ion_implementation,
219 region.release(),
220 DestroyUserData<Surface::Region>);
221 }
222
223 const struct wl_compositor_interface compositor_implementation = {
224 .create_surface = compositor_create_surface,
225 .create_region = compositor_create_region,
226 };
227
228 constexpr const uint32_t kCompositorVersion = 3;
229
compositor_destroy_resource_callback(struct wl_resource *)230 void compositor_destroy_resource_callback(struct wl_resource*) {}
231
bind_compositor(wl_client * client,void * data,uint32_t version,uint32_t id)232 void bind_compositor(wl_client* client,
233 void* data,
234 uint32_t version,
235 uint32_t id) {
236 wl_resource* resource =
237 wl_resource_create(client, &wl_compositor_interface,
238 std::min(version, kCompositorVersion), id);
239
240 wl_resource_set_implementation(resource, &compositor_implementation, data,
241 compositor_destroy_resource_callback);
242 }
243
244 } // namespace
245
BindCompositorInterface(wl_display * display,Surfaces * surfaces)246 void BindCompositorInterface(wl_display* display, Surfaces* surfaces) {
247 wl_global_create(display, &wl_compositor_interface, kCompositorVersion,
248 surfaces, bind_compositor);
249 }
250
251 } // namespace wayland
252