• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
surface_attach(wl_client *,wl_resource * surface,wl_resource * buffer,int32_t x,int32_t y)82 void surface_attach(wl_client*,
83                     wl_resource* surface,
84                     wl_resource* buffer,
85                     int32_t x,
86                     int32_t y) {
87   LOG(VERBOSE) << __FUNCTION__
88                << " surface=" << surface
89                << " buffer=" << buffer
90                << " x=" << x
91                << " y=" << y;
92 
93   GetUserData<Surface>(surface)->Attach(buffer);
94 }
95 
surface_damage(wl_client *,wl_resource * surface_resource,int32_t x,int32_t y,int32_t w,int32_t h)96 void surface_damage(wl_client*,
97                     wl_resource* surface_resource,
98                     int32_t x,
99                     int32_t y,
100                     int32_t w,
101                     int32_t h) {
102   LOG(VERBOSE) << __FUNCTION__
103                << " surface=" << surface_resource
104                << " x=" << x
105                << " y=" << y
106                << " w=" << w
107                << " h=" << h;
108 }
109 
surface_frame(wl_client *,wl_resource * surface,uint32_t)110 void surface_frame(wl_client*, wl_resource* surface, uint32_t) {
111   LOG(VERBOSE) << " surface=" << surface;
112 }
113 
surface_set_opaque_region(wl_client *,wl_resource * surface_resource,wl_resource * region_resource)114 void surface_set_opaque_region(wl_client*,
115                                wl_resource* surface_resource,
116                                wl_resource* region_resource) {
117   LOG(VERBOSE) << __FUNCTION__
118                << " surface=" << surface_resource
119                << " region=" << region_resource;
120 
121   Surface* surface = GetUserData<Surface>(surface_resource);
122   Surface::Region* region = GetUserData<Surface::Region>(region_resource);
123 
124   surface->SetRegion(*region);
125 }
126 
surface_set_input_region(wl_client *,wl_resource * surface_resource,wl_resource * region_resource)127 void surface_set_input_region(wl_client*,
128                               wl_resource* surface_resource,
129                               wl_resource* region_resource) {
130   LOG(VERBOSE) << __FUNCTION__
131                << " surface=" << surface_resource
132                << " region=" << region_resource;
133 }
134 
surface_commit(wl_client *,wl_resource * surface_resource)135 void surface_commit(wl_client*, wl_resource* surface_resource) {
136   LOG(VERBOSE) << __FUNCTION__
137                << " surface=" << surface_resource;
138 
139   GetUserData<Surface>(surface_resource)->Commit();
140 }
141 
surface_set_buffer_transform(wl_client *,wl_resource * surface_resource,int32_t transform)142 void surface_set_buffer_transform(wl_client*,
143                                   wl_resource* surface_resource,
144                                   int32_t transform) {
145   LOG(VERBOSE) << __FUNCTION__
146                << " surface=" << surface_resource
147                << " transform=" << transform;
148 }
149 
surface_set_buffer_scale(wl_client *,wl_resource * surface_resource,int32_t scale)150 void surface_set_buffer_scale(wl_client*,
151                               wl_resource* surface_resource,
152                               int32_t scale) {
153   LOG(VERBOSE) << __FUNCTION__
154                << " surface=" << surface_resource
155                << " scale=" << scale;
156 }
157 
surface_damage_buffer(wl_client *,wl_resource * surface_resource,int32_t x,int32_t y,int32_t w,int32_t h)158 void surface_damage_buffer(wl_client*,
159                            wl_resource* surface_resource,
160                            int32_t x,
161                            int32_t y,
162                            int32_t w,
163                            int32_t h) {
164   LOG(VERBOSE) << __FUNCTION__
165                << " surface=" << surface_resource
166                << " x=" << x
167                << " y=" << y
168                << " w=" << w
169                << " h=" << h;
170 }
171 
172 const struct wl_surface_interface surface_implementation = {
173   .destroy = surface_destroy,
174   .attach = surface_attach,
175   .damage = surface_damage,
176   .frame = surface_frame,
177   .set_opaque_region = surface_set_opaque_region,
178   .set_input_region = surface_set_input_region,
179   .commit = surface_commit,
180   .set_buffer_transform = surface_set_buffer_transform,
181   .set_buffer_scale = surface_set_buffer_scale,
182   .damage_buffer = surface_damage_buffer,
183 };
184 
surface_destroy_resource_callback(struct wl_resource *)185 void surface_destroy_resource_callback(struct wl_resource*) {}
186 
compositor_create_surface(wl_client * client,wl_resource * compositor,uint32_t id)187 void compositor_create_surface(wl_client* client,
188                                wl_resource* compositor,
189                                uint32_t id) {
190   LOG(VERBOSE) << __FUNCTION__
191                << " compositor=" << compositor
192                << " id=" << id;
193 
194   // Wayland seems to use a single global id space for all objects.
195   static std::atomic<std::uint32_t> sNextDisplayId{0};
196   uint32_t display_id = sNextDisplayId++;
197 
198   Surfaces* surfaces = GetUserData<Surfaces>(compositor);
199   Surface* surface = surfaces->GetOrCreateSurface(display_id);
200 
201   wl_resource* surface_resource = wl_resource_create(
202       client, &wl_surface_interface, wl_resource_get_version(compositor), id);
203 
204   wl_resource_set_implementation(surface_resource, &surface_implementation,
205                                  surface, surface_destroy_resource_callback);
206 }
207 
compositor_create_region(wl_client * client,wl_resource * compositor,uint32_t id)208 void compositor_create_region(wl_client* client,
209                               wl_resource* compositor,
210                               uint32_t id) {
211   LOG(VERBOSE) << __FUNCTION__
212                << " compositor=" << compositor
213                << " id=" << id;
214 
215   std::unique_ptr<Surface::Region> region(new Surface::Region());
216 
217   wl_resource* region_resource = wl_resource_create(
218       client, &wl_region_interface, 1, id);
219 
220   wl_resource_set_implementation(region_resource, &region_implementation,
221                                  region.release(),
222                                  DestroyUserData<Surface::Region>);
223 }
224 
225 const struct wl_compositor_interface compositor_implementation = {
226     .create_surface = compositor_create_surface,
227     .create_region = compositor_create_region,
228 };
229 
230 constexpr const uint32_t kCompositorVersion = 3;
231 
compositor_destroy_resource_callback(struct wl_resource *)232 void compositor_destroy_resource_callback(struct wl_resource*) {}
233 
bind_compositor(wl_client * client,void * data,uint32_t version,uint32_t id)234 void bind_compositor(wl_client* client,
235                      void* data,
236                      uint32_t version,
237                      uint32_t id) {
238   wl_resource* resource =
239       wl_resource_create(client, &wl_compositor_interface,
240                          std::min(version, kCompositorVersion), id);
241 
242   wl_resource_set_implementation(resource, &compositor_implementation, data,
243                                  compositor_destroy_resource_callback);
244 }
245 
246 }  // namespace
247 
BindCompositorInterface(wl_display * display,Surfaces * surfaces)248 void BindCompositorInterface(wl_display* display, Surfaces* surfaces) {
249   wl_global_create(display, &wl_compositor_interface, kCompositorVersion,
250                    surfaces, bind_compositor);
251 }
252 
253 }  // namespace wayland
254