blob: 4e2f8f51a83eb34d9b8a87b35c8719a83b7b4b8f [file] [log] [blame]
/*
* 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, &region_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