231 lines
10 KiB
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);
|
||
|
}
|