blob: 80c2f2bfc018f6c6e5abacf7fb68f1d89baab605 [file] [log] [blame]
// Copyright 2018 The Chromium 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 "components/exo/wayland/wl_seat.h"
#include <wayland-server-core.h>
#include <wayland-server-protocol-core.h>
#include "components/exo/pointer.h"
#include "components/exo/touch.h"
#include "components/exo/wayland/serial_tracker.h"
#include "components/exo/wayland/server_util.h"
#include "components/exo/wayland/wayland_pointer_delegate.h"
#include "components/exo/wayland/wayland_touch_delegate.h"
#include "ui/base/buildflags.h"
#if defined(OS_CHROMEOS)
#include "components/exo/keyboard.h"
#include "components/exo/wayland/wayland_keyboard_delegate.h"
#endif // defined(OS_CHROMEOS)
namespace exo {
namespace wayland {
namespace {
////////////////////////////////////////////////////////////////////////////////
// wl_pointer_interface:
void pointer_set_cursor(wl_client* client,
wl_resource* resource,
uint32_t serial,
wl_resource* surface_resource,
int32_t hotspot_x,
int32_t hotspot_y) {
GetUserDataAs<Pointer>(resource)->SetCursor(
surface_resource ? GetUserDataAs<Surface>(surface_resource) : nullptr,
gfx::Point(hotspot_x, hotspot_y));
}
void pointer_release(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
const struct wl_pointer_interface pointer_implementation = {pointer_set_cursor,
pointer_release};
#if defined(OS_CHROMEOS)
////////////////////////////////////////////////////////////////////////////////
// wl_keyboard_interface:
#if BUILDFLAG(USE_XKBCOMMON)
void keyboard_release(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
const struct wl_keyboard_interface keyboard_implementation = {keyboard_release};
#endif // BUILDFLAG(USE_XKBCOMMON)
#endif // defined(OS_CHROMEOS)
////////////////////////////////////////////////////////////////////////////////
// wl_touch_interface:
void touch_release(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
const struct wl_touch_interface touch_implementation = {touch_release};
////////////////////////////////////////////////////////////////////////////////
// wl_seat_interface:
void seat_get_pointer(wl_client* client, wl_resource* resource, uint32_t id) {
auto* data = GetUserDataAs<WaylandSeat>(resource);
wl_resource* pointer_resource = wl_resource_create(
client, &wl_pointer_interface, wl_resource_get_version(resource), id);
SetImplementation(
pointer_resource, &pointer_implementation,
std::make_unique<Pointer>(
new WaylandPointerDelegate(pointer_resource, data->serial_tracker),
data->seat));
}
void seat_get_keyboard(wl_client* client, wl_resource* resource, uint32_t id) {
#if defined(OS_CHROMEOS)
#if BUILDFLAG(USE_XKBCOMMON)
auto* data = GetUserDataAs<WaylandSeat>(resource);
uint32_t version = wl_resource_get_version(resource);
wl_resource* keyboard_resource =
wl_resource_create(client, &wl_keyboard_interface, version, id);
WaylandKeyboardDelegate* delegate =
new WaylandKeyboardDelegate(keyboard_resource, data->serial_tracker);
std::unique_ptr<Keyboard> keyboard =
std::make_unique<Keyboard>(delegate, data->seat);
keyboard->AddObserver(delegate);
SetImplementation(keyboard_resource, &keyboard_implementation,
std::move(keyboard));
// TODO(reveman): Keep repeat info synchronized with chromium and the host OS.
if (version >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
wl_keyboard_send_repeat_info(keyboard_resource, 40, 500);
#else
NOTIMPLEMENTED();
#endif // BUILDFLAG(USE_XKBCOMMON)
#else
NOTIMPLEMENTED();
#endif // defined(OS_CHROMEOS)
}
void seat_get_touch(wl_client* client, wl_resource* resource, uint32_t id) {
auto* data = GetUserDataAs<WaylandSeat>(resource);
wl_resource* touch_resource = wl_resource_create(
client, &wl_touch_interface, wl_resource_get_version(resource), id);
SetImplementation(
touch_resource, &touch_implementation,
std::make_unique<Touch>(
new WaylandTouchDelegate(touch_resource, data->serial_tracker),
data->seat));
}
void seat_release(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
const struct wl_seat_interface seat_implementation = {
seat_get_pointer, seat_get_keyboard, seat_get_touch, seat_release};
} // namespace
void bind_seat(wl_client* client, void* data, uint32_t version, uint32_t id) {
wl_resource* resource = wl_resource_create(
client, &wl_seat_interface, std::min(version, kWlSeatVersion), id);
wl_resource_set_implementation(resource, &seat_implementation, data, nullptr);
if (version >= WL_SEAT_NAME_SINCE_VERSION)
wl_seat_send_name(resource, "default");
uint32_t capabilities = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH;
#if defined(OS_CHROMEOS) && BUILDFLAG(USE_XKBCOMMON)
capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
#endif // defined(OS_CHROMEOS) && BUILDFLAG(USE_XKBCOMMON)
wl_seat_send_capabilities(resource, capabilities);
}
} // namespace wayland
} // namespace exo