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_utils.h"
25 
26 namespace wayland {
27 namespace {
28 
region_destroy(wl_client *,wl_resource * region_resource)29 void region_destroy(wl_client*, wl_resource* region_resource) {
30   LOG(VERBOSE) << __FUNCTION__
31                << " region=" << region_resource;
32 
33   wl_resource_destroy(region_resource);
34 }
35 
region_add(wl_client *,wl_resource * region_resource,int32_t x,int32_t y,int32_t w,int32_t h)36 void region_add(wl_client*,
37                 wl_resource* region_resource,
38                 int32_t x,
39                 int32_t y,
40                 int32_t w,
41                 int32_t h) {
42   LOG(VERBOSE) << __FUNCTION__
43                << " region=" << region_resource
44                << " x=" << x
45                << " y=" << y
46                << " w=" << w
47                << " h=" << h;
48 
49   Surface::Region* region = GetUserData<Surface::Region>(region_resource);
50   region->x = x;
51   region->y = y;
52   region->w = w;
53   region->h = h;
54 }
55 
region_subtract(wl_client *,wl_resource * region_resource,int32_t x,int32_t y,int32_t w,int32_t h)56 void region_subtract(wl_client*,
57                      wl_resource* region_resource,
58                      int32_t x,
59                      int32_t y,
60                      int32_t w,
61                      int32_t h) {
62   LOG(VERBOSE) << __FUNCTION__
63                << " region=" << region_resource
64                << " x=" << x
65                << " y=" << y
66                << " w=" << w
67                << " h=" << h;
68 }
69 
70 const struct wl_region_interface region_implementation = {
71     .destroy = region_destroy,
72     .add = region_add,
73     .subtract = region_subtract,
74 };
75 
surface_destroy(wl_client *,wl_resource * surface)76 void surface_destroy(wl_client*, wl_resource* surface) {
77   LOG(VERBOSE) << __FUNCTION__
78                << " surface=" << surface;
79 }
80 
surface_attach(wl_client *,wl_resource * surface,wl_resource * buffer,int32_t x,int32_t y)81 void surface_attach(wl_client*,
82                     wl_resource* surface,
83                     wl_resource* buffer,
84                     int32_t x,
85                     int32_t y) {
86   LOG(VERBOSE) << __FUNCTION__
87                << " surface=" << surface
88                << " buffer=" << buffer
89                << " x=" << x
90                << " y=" << y;
91 
92   GetUserData<Surface>(surface)->Attach(buffer);
93 }
94 
surface_damage(wl_client *,wl_resource * surface_resource,int32_t x,int32_t y,int32_t w,int32_t h)95 void surface_damage(wl_client*,
96                     wl_resource* surface_resource,
97                     int32_t x,
98                     int32_t y,
99                     int32_t w,
100                     int32_t h) {
101   LOG(VERBOSE) << __FUNCTION__
102                << " surface=" << surface_resource
103                << " x=" << x
104                << " y=" << y
105                << " w=" << w
106                << " h=" << h;
107 }
108 
surface_frame(wl_client *,wl_resource * surface,uint32_t)109 void surface_frame(wl_client*, wl_resource* surface, uint32_t) {
110   LOG(VERBOSE) << " surface=" << surface;
111 }
112 
surface_set_opaque_region(wl_client *,wl_resource * surface_resource,wl_resource * region_resource)113 void surface_set_opaque_region(wl_client*,
114                                wl_resource* surface_resource,
115                                wl_resource* region_resource) {
116   LOG(VERBOSE) << __FUNCTION__
117                << " surface=" << surface_resource
118                << " region=" << region_resource;
119 
120   Surface* surface = GetUserData<Surface>(surface_resource);
121   Surface::Region* region = GetUserData<Surface::Region>(region_resource);
122 
123   surface->SetRegion(*region);
124 }
125 
surface_set_input_region(wl_client *,wl_resource * surface_resource,wl_resource * region_resource)126 void surface_set_input_region(wl_client*,
127                               wl_resource* surface_resource,
128                               wl_resource* region_resource) {
129   LOG(VERBOSE) << __FUNCTION__
130                << " surface=" << surface_resource
131                << " region=" << region_resource;
132 }
133 
surface_commit(wl_client *,wl_resource * surface_resource)134 void surface_commit(wl_client*, wl_resource* surface_resource) {
135   LOG(VERBOSE) << __FUNCTION__
136                << " surface=" << surface_resource;
137 
138   GetUserData<Surface>(surface_resource)->Commit();
139 }
140 
surface_set_buffer_transform(wl_client *,wl_resource * surface_resource,int32_t transform)141 void surface_set_buffer_transform(wl_client*,
142                                   wl_resource* surface_resource,
143                                   int32_t transform) {
144   LOG(VERBOSE) << __FUNCTION__
145                << " surface=" << surface_resource
146                << " transform=" << transform;
147 }
148 
surface_set_buffer_scale(wl_client *,wl_resource * surface_resource,int32_t scale)149 void surface_set_buffer_scale(wl_client*,
150                               wl_resource* surface_resource,
151                               int32_t scale) {
152   LOG(VERBOSE) << __FUNCTION__
153                << " surface=" << surface_resource
154                << " scale=" << scale;
155 }
156 
surface_damage_buffer(wl_client *,wl_resource * surface_resource,int32_t x,int32_t y,int32_t w,int32_t h)157 void surface_damage_buffer(wl_client*,
158                            wl_resource* surface_resource,
159                            int32_t x,
160                            int32_t y,
161                            int32_t w,
162                            int32_t h) {
163   LOG(VERBOSE) << __FUNCTION__
164                << " surface=" << surface_resource
165                << " x=" << x
166                << " y=" << y
167                << " w=" << w
168                << " h=" << h;
169 }
170 
171 const struct wl_surface_interface surface_implementation = {
172   .destroy = surface_destroy,
173   .attach = surface_attach,
174   .damage = surface_damage,
175   .frame = surface_frame,
176   .set_opaque_region = surface_set_opaque_region,
177   .set_input_region = surface_set_input_region,
178   .commit = surface_commit,
179   .set_buffer_transform = surface_set_buffer_transform,
180   .set_buffer_scale = surface_set_buffer_scale,
181   .damage_buffer = surface_damage_buffer,
182 };
183 
surface_destroy_resource_callback(struct wl_resource *)184 void surface_destroy_resource_callback(struct wl_resource*) {}
185 
compositor_create_surface(wl_client * client,wl_resource * compositor,uint32_t id)186 void compositor_create_surface(wl_client* client,
187                                wl_resource* compositor,
188                                uint32_t id) {
189   LOG(VERBOSE) << __FUNCTION__
190                << " compositor=" << compositor
191                << " id=" << id;
192 
193   Surface* surface = GetUserData<Surface>(compositor);
194 
195   wl_resource* surface_resource = wl_resource_create(
196       client, &wl_surface_interface, wl_resource_get_version(compositor), id);
197 
198   wl_resource_set_implementation(surface_resource, &surface_implementation,
199                                  surface, surface_destroy_resource_callback);
200 }
201 
compositor_create_region(wl_client * client,wl_resource * compositor,uint32_t id)202 void compositor_create_region(wl_client* client,
203                               wl_resource* compositor,
204                               uint32_t id) {
205   LOG(VERBOSE) << __FUNCTION__
206                << " compositor=" << compositor
207                << " id=" << id;
208 
209   std::unique_ptr<Surface::Region> region(new Surface::Region());
210 
211   wl_resource* region_resource = wl_resource_create(
212       client, &wl_region_interface, 1, id);
213 
214   wl_resource_set_implementation(region_resource, &region_implementation,
215                                  region.release(),
216                                  DestroyUserData<Surface::Region>);
217 }
218 
219 const struct wl_compositor_interface compositor_implementation = {
220     .create_surface = compositor_create_surface,
221     .create_region = compositor_create_region,
222 };
223 
224 constexpr const uint32_t kCompositorVersion = 3;
225 
compositor_destroy_resource_callback(struct wl_resource *)226 void compositor_destroy_resource_callback(struct wl_resource*) {}
227 
bind_compositor(wl_client * client,void * data,uint32_t version,uint32_t id)228 void bind_compositor(wl_client* client,
229                      void* data,
230                      uint32_t version,
231                      uint32_t id) {
232   wl_resource* resource =
233       wl_resource_create(client, &wl_compositor_interface,
234                          std::min(version, kCompositorVersion), id);
235 
236   wl_resource_set_implementation(resource, &compositor_implementation, data,
237                                  compositor_destroy_resource_callback);
238 }
239 
240 }  // namespace
241 
BindCompositorInterface(wl_display * display,Surface * surface)242 void BindCompositorInterface(wl_display* display, Surface* surface) {
243   wl_global_create(display, &wl_compositor_interface, kCompositorVersion,
244                    surface, bind_compositor);
245 }
246 
247 }  // namespace wayland
248