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, &region_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