pH/sommelier/sommelier-pointer-constraints.c

231 lines
10 KiB
C

// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sommelier.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client-protocol.h>
#include <wayland-client.h>
#include <wayland-server-core.h>
#include "pointer-constraints-unstable-v1-server-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
#define SL_HOST_OBJECT(NAME, INTERFACE) \
struct sl_host_##NAME { \
struct sl_context* ctx; \
struct wl_resource* resource; \
struct INTERFACE* proxy; \
}; \
static void sl_destroy_host_##NAME(struct wl_resource* resource) { \
struct sl_host_##NAME* host = wl_resource_get_user_data(resource); \
INTERFACE##_destroy(host->proxy); \
wl_resource_set_user_data(resource, NULL); \
free(host); \
} \
static void sl_##NAME##_destroy(struct wl_client* client, \
struct wl_resource* resource) { \
wl_resource_destroy(resource); \
}
SL_HOST_OBJECT(pointer_constraints, zwp_pointer_constraints_v1);
SL_HOST_OBJECT(locked_pointer, zwp_locked_pointer_v1);
SL_HOST_OBJECT(confined_pointer, zwp_confined_pointer_v1);
static void sl_locked_pointer_locked(
void* data, struct zwp_locked_pointer_v1* locked_pointer) {
struct sl_host_locked_pointer* host =
zwp_locked_pointer_v1_get_user_data(locked_pointer);
zwp_locked_pointer_v1_send_locked(host->resource);
}
static void sl_locked_pointer_unlocked(
void* data, struct zwp_locked_pointer_v1* locked_pointer) {
struct sl_host_locked_pointer* host =
zwp_locked_pointer_v1_get_user_data(locked_pointer);
zwp_locked_pointer_v1_send_unlocked(host->resource);
}
static void sl_locked_pointer_set_cursor_position_hint(
struct wl_client* client,
struct wl_resource* resource,
wl_fixed_t surface_x,
wl_fixed_t surface_y) {
struct sl_host_locked_pointer* host = wl_resource_get_user_data(resource);
zwp_locked_pointer_v1_set_cursor_position_hint(host->proxy, surface_x,
surface_y);
}
static void sl_locked_pointer_set_region(struct wl_client* client,
struct wl_resource* resource,
struct wl_resource* region) {
struct sl_host_locked_pointer* host = wl_resource_get_user_data(resource);
struct sl_host_region* host_region =
region ? wl_resource_get_user_data(region) : NULL;
zwp_locked_pointer_v1_set_region(host->proxy,
host_region ? host_region->proxy : NULL);
}
static struct zwp_locked_pointer_v1_listener sl_locked_pointer_listener = {
sl_locked_pointer_locked,
sl_locked_pointer_unlocked,
};
static struct zwp_locked_pointer_v1_interface sl_locked_pointer_implementation =
{sl_locked_pointer_destroy, sl_locked_pointer_set_cursor_position_hint,
sl_locked_pointer_set_region};
static void sl_confined_pointer_confined(
void* data, struct zwp_confined_pointer_v1* confined_pointer) {
struct sl_host_confined_pointer* host =
zwp_confined_pointer_v1_get_user_data(confined_pointer);
zwp_confined_pointer_v1_send_confined(host->resource);
}
static void sl_confined_pointer_unconfined(
void* data, struct zwp_confined_pointer_v1* confined_pointer) {
struct sl_host_confined_pointer* host =
zwp_confined_pointer_v1_get_user_data(confined_pointer);
zwp_confined_pointer_v1_send_unconfined(host->resource);
}
static void sl_confined_pointer_set_region(struct wl_client* client,
struct wl_resource* resource,
struct wl_resource* region) {
struct sl_host_confined_pointer* host = wl_resource_get_user_data(resource);
struct sl_host_region* host_region =
region ? wl_resource_get_user_data(region) : NULL;
zwp_confined_pointer_v1_set_region(host->proxy,
host_region ? host_region->proxy : NULL);
}
static struct zwp_confined_pointer_v1_listener sl_confined_pointer_listener = {
sl_confined_pointer_confined,
sl_confined_pointer_unconfined,
};
static struct zwp_confined_pointer_v1_interface
sl_confined_pointer_implementation = {
sl_confined_pointer_destroy,
sl_confined_pointer_set_region,
};
static void sl_pointer_constraints_lock_pointer(struct wl_client* client,
struct wl_resource* resource,
uint32_t id,
struct wl_resource* surface,
struct wl_resource* pointer,
struct wl_resource* region,
uint32_t lifetime) {
struct sl_host_pointer_constraints* host =
wl_resource_get_user_data(resource);
struct wl_resource* locked_pointer_resource =
wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
struct sl_host_locked_pointer* locked_pointer_host;
struct sl_host_surface* host_surface = wl_resource_get_user_data(surface);
struct sl_host_pointer* host_pointer = wl_resource_get_user_data(pointer);
struct sl_host_region* host_region =
region ? wl_resource_get_user_data(region) : NULL;
locked_pointer_host = malloc(sizeof(struct sl_host_locked_pointer));
assert(locked_pointer_host);
locked_pointer_host->resource = locked_pointer_resource;
locked_pointer_host->ctx = host->ctx;
locked_pointer_host->proxy = zwp_pointer_constraints_v1_lock_pointer(
host->ctx->pointer_constraints->internal, host_surface->proxy,
host_pointer->proxy, host_region ? host_region->proxy : NULL, lifetime);
wl_resource_set_implementation(
locked_pointer_resource, &sl_locked_pointer_implementation,
locked_pointer_host, sl_destroy_host_locked_pointer);
zwp_locked_pointer_v1_set_user_data(locked_pointer_host->proxy,
locked_pointer_host);
zwp_locked_pointer_v1_add_listener(locked_pointer_host->proxy,
&sl_locked_pointer_listener,
locked_pointer_host);
}
static void sl_pointer_constraints_confine_pointer(struct wl_client* client,
struct wl_resource* resource,
uint32_t id,
struct wl_resource* surface,
struct wl_resource* pointer,
struct wl_resource* region,
uint32_t lifetime) {
struct sl_host_pointer_constraints* host =
wl_resource_get_user_data(resource);
struct wl_resource* confined_pointer_resource =
wl_resource_create(client, &zwp_confined_pointer_v1_interface, 1, id);
struct sl_host_confined_pointer* confined_pointer_host;
struct sl_host_surface* host_surface = wl_resource_get_user_data(surface);
struct sl_host_pointer* host_pointer = wl_resource_get_user_data(pointer);
struct sl_host_region* host_region =
region ? wl_resource_get_user_data(region) : NULL;
confined_pointer_host = malloc(sizeof(struct sl_host_confined_pointer));
assert(confined_pointer_host);
confined_pointer_host->resource = confined_pointer_resource;
confined_pointer_host->ctx = host->ctx;
confined_pointer_host->proxy = zwp_pointer_constraints_v1_confine_pointer(
host->ctx->pointer_constraints->internal, host_surface->proxy,
host_pointer->proxy, host_region ? host_region->proxy : NULL, lifetime);
wl_resource_set_implementation(
confined_pointer_resource, &sl_confined_pointer_implementation,
confined_pointer_host, sl_destroy_host_confined_pointer);
zwp_confined_pointer_v1_set_user_data(confined_pointer_host->proxy,
confined_pointer_host);
zwp_confined_pointer_v1_add_listener(confined_pointer_host->proxy,
&sl_confined_pointer_listener,
confined_pointer_host);
}
static struct zwp_pointer_constraints_v1_interface
sl_pointer_constraints_implementation = {
sl_pointer_constraints_destroy,
sl_pointer_constraints_lock_pointer,
sl_pointer_constraints_confine_pointer,
};
static void sl_bind_host_pointer_constraints(struct wl_client* client,
void* data,
uint32_t version,
uint32_t id) {
struct sl_context* ctx = (struct sl_context*)data;
struct sl_pointer_constraints* pointer_constraints = ctx->pointer_constraints;
struct sl_host_pointer_constraints* host =
malloc(sizeof(struct sl_host_pointer_constraints));
assert(host);
host->ctx = ctx;
host->resource =
wl_resource_create(client, &zwp_pointer_constraints_v1_interface, 1, id);
wl_resource_set_implementation(host->resource,
&sl_pointer_constraints_implementation, host,
sl_destroy_host_pointer_constraints);
host->proxy = wl_registry_bind(wl_display_get_registry(ctx->display),
pointer_constraints->id,
&zwp_pointer_constraints_v1_interface,
wl_resource_get_version(host->resource));
zwp_pointer_constraints_v1_set_user_data(host->proxy, host);
}
struct sl_global* sl_pointer_constraints_global_create(struct sl_context* ctx) {
return sl_global_create(ctx, &zwp_pointer_constraints_v1_interface, 1, ctx,
sl_bind_host_pointer_constraints);
}