253 lines
7.9 KiB
C++
253 lines
7.9 KiB
C++
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "host/libs/wayland/wayland_compositor.h"
|
|
|
|
#include <android-base/logging.h>
|
|
|
|
#include <wayland-server-core.h>
|
|
#include <wayland-server-protocol.h>
|
|
|
|
#include "host/libs/wayland/wayland_surface.h"
|
|
#include "host/libs/wayland/wayland_utils.h"
|
|
|
|
namespace wayland {
|
|
namespace {
|
|
|
|
void region_destroy(wl_client*, wl_resource* region_resource) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " region=" << region_resource;
|
|
|
|
wl_resource_destroy(region_resource);
|
|
}
|
|
|
|
void region_add(wl_client*,
|
|
wl_resource* region_resource,
|
|
int32_t x,
|
|
int32_t y,
|
|
int32_t w,
|
|
int32_t h) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " region=" << region_resource
|
|
<< " x=" << x
|
|
<< " y=" << y
|
|
<< " w=" << w
|
|
<< " h=" << h;
|
|
|
|
Surface::Region* region = GetUserData<Surface::Region>(region_resource);
|
|
region->x = x;
|
|
region->y = y;
|
|
region->w = w;
|
|
region->h = h;
|
|
}
|
|
|
|
void region_subtract(wl_client*,
|
|
wl_resource* region_resource,
|
|
int32_t x,
|
|
int32_t y,
|
|
int32_t w,
|
|
int32_t h) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " region=" << region_resource
|
|
<< " x=" << x
|
|
<< " y=" << y
|
|
<< " w=" << w
|
|
<< " h=" << h;
|
|
}
|
|
|
|
const struct wl_region_interface region_implementation = {
|
|
.destroy = region_destroy,
|
|
.add = region_add,
|
|
.subtract = region_subtract,
|
|
};
|
|
|
|
void surface_destroy(wl_client*, wl_resource* surface) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface;
|
|
}
|
|
|
|
void surface_attach(wl_client*,
|
|
wl_resource* surface,
|
|
wl_resource* buffer,
|
|
int32_t x,
|
|
int32_t y) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface
|
|
<< " buffer=" << buffer
|
|
<< " x=" << x
|
|
<< " y=" << y;
|
|
|
|
GetUserData<Surface>(surface)->Attach(buffer);
|
|
}
|
|
|
|
void surface_damage(wl_client*,
|
|
wl_resource* surface_resource,
|
|
int32_t x,
|
|
int32_t y,
|
|
int32_t w,
|
|
int32_t h) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource
|
|
<< " x=" << x
|
|
<< " y=" << y
|
|
<< " w=" << w
|
|
<< " h=" << h;
|
|
}
|
|
|
|
void surface_frame(wl_client*, wl_resource* surface, uint32_t) {
|
|
LOG(VERBOSE) << " surface=" << surface;
|
|
}
|
|
|
|
void surface_set_opaque_region(wl_client*,
|
|
wl_resource* surface_resource,
|
|
wl_resource* region_resource) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource
|
|
<< " region=" << region_resource;
|
|
|
|
Surface* surface = GetUserData<Surface>(surface_resource);
|
|
Surface::Region* region = GetUserData<Surface::Region>(region_resource);
|
|
|
|
surface->SetRegion(*region);
|
|
}
|
|
|
|
void surface_set_input_region(wl_client*,
|
|
wl_resource* surface_resource,
|
|
wl_resource* region_resource) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource
|
|
<< " region=" << region_resource;
|
|
}
|
|
|
|
void surface_commit(wl_client*, wl_resource* surface_resource) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource;
|
|
|
|
GetUserData<Surface>(surface_resource)->Commit();
|
|
}
|
|
|
|
void surface_set_buffer_transform(wl_client*,
|
|
wl_resource* surface_resource,
|
|
int32_t transform) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource
|
|
<< " transform=" << transform;
|
|
}
|
|
|
|
void surface_set_buffer_scale(wl_client*,
|
|
wl_resource* surface_resource,
|
|
int32_t scale) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource
|
|
<< " scale=" << scale;
|
|
}
|
|
|
|
void surface_damage_buffer(wl_client*,
|
|
wl_resource* surface_resource,
|
|
int32_t x,
|
|
int32_t y,
|
|
int32_t w,
|
|
int32_t h) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " surface=" << surface_resource
|
|
<< " x=" << x
|
|
<< " y=" << y
|
|
<< " w=" << w
|
|
<< " h=" << h;
|
|
}
|
|
|
|
const struct wl_surface_interface surface_implementation = {
|
|
.destroy = surface_destroy,
|
|
.attach = surface_attach,
|
|
.damage = surface_damage,
|
|
.frame = surface_frame,
|
|
.set_opaque_region = surface_set_opaque_region,
|
|
.set_input_region = surface_set_input_region,
|
|
.commit = surface_commit,
|
|
.set_buffer_transform = surface_set_buffer_transform,
|
|
.set_buffer_scale = surface_set_buffer_scale,
|
|
.damage_buffer = surface_damage_buffer,
|
|
};
|
|
|
|
void surface_destroy_resource_callback(struct wl_resource* surface_resource) {
|
|
Surface* surface = GetUserData<Surface>(surface_resource);
|
|
delete surface;
|
|
}
|
|
|
|
void compositor_create_surface(wl_client* client,
|
|
wl_resource* compositor,
|
|
uint32_t id) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " compositor=" << compositor
|
|
<< " id=" << id;
|
|
|
|
Surfaces* surfaces = GetUserData<Surfaces>(compositor);
|
|
Surface* surface = new Surface(*surfaces);
|
|
|
|
wl_resource* surface_resource = wl_resource_create(
|
|
client, &wl_surface_interface, wl_resource_get_version(compositor), id);
|
|
|
|
wl_resource_set_implementation(surface_resource, &surface_implementation,
|
|
surface, surface_destroy_resource_callback);
|
|
}
|
|
|
|
void compositor_create_region(wl_client* client,
|
|
wl_resource* compositor,
|
|
uint32_t id) {
|
|
LOG(VERBOSE) << __FUNCTION__
|
|
<< " compositor=" << compositor
|
|
<< " id=" << id;
|
|
|
|
std::unique_ptr<Surface::Region> region(new Surface::Region());
|
|
|
|
wl_resource* region_resource = wl_resource_create(
|
|
client, &wl_region_interface, 1, id);
|
|
|
|
wl_resource_set_implementation(region_resource, ®ion_implementation,
|
|
region.release(),
|
|
DestroyUserData<Surface::Region>);
|
|
}
|
|
|
|
const struct wl_compositor_interface compositor_implementation = {
|
|
.create_surface = compositor_create_surface,
|
|
.create_region = compositor_create_region,
|
|
};
|
|
|
|
constexpr const uint32_t kCompositorVersion = 3;
|
|
|
|
void compositor_destroy_resource_callback(struct wl_resource*) {}
|
|
|
|
void bind_compositor(wl_client* client,
|
|
void* data,
|
|
uint32_t version,
|
|
uint32_t id) {
|
|
wl_resource* resource =
|
|
wl_resource_create(client, &wl_compositor_interface,
|
|
std::min(version, kCompositorVersion), id);
|
|
|
|
wl_resource_set_implementation(resource, &compositor_implementation, data,
|
|
compositor_destroy_resource_callback);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void BindCompositorInterface(wl_display* display, Surfaces* surfaces) {
|
|
wl_global_create(display, &wl_compositor_interface, kCompositorVersion,
|
|
surfaces, bind_compositor);
|
|
}
|
|
|
|
} // namespace wayland
|