// Copyright 2019 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/zcr_stylus.h" #include #include "components/exo/pointer.h" #include "components/exo/pointer_stylus_delegate.h" #include "components/exo/touch.h" #include "components/exo/touch_stylus_delegate.h" #include "components/exo/wayland/server_util.h" namespace exo { namespace wayland { namespace { //////////////////////////////////////////////////////////////////////////////// // zcr_touch_stylus_v2 interface: class WaylandTouchStylusDelegate : public TouchStylusDelegate { public: WaylandTouchStylusDelegate(wl_resource* resource, Touch* touch) : resource_(resource), touch_(touch) { touch_->SetStylusDelegate(this); } ~WaylandTouchStylusDelegate() override { if (touch_ != nullptr) touch_->SetStylusDelegate(nullptr); } void OnTouchDestroying(Touch* touch) override { touch_ = nullptr; } void OnTouchTool(int touch_id, ui::EventPointerType type) override { uint wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_TOUCH; if (type == ui::EventPointerType::kPen) wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_PEN; else if (type == ui::EventPointerType::kEraser) wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_ERASER; zcr_touch_stylus_v2_send_tool(resource_, touch_id, wayland_type); } void OnTouchForce(base::TimeTicks time_stamp, int touch_id, float force) override { zcr_touch_stylus_v2_send_force(resource_, TimeTicksToMilliseconds(time_stamp), touch_id, wl_fixed_from_double(force)); } void OnTouchTilt(base::TimeTicks time_stamp, int touch_id, const gfx::Vector2dF& tilt) override { zcr_touch_stylus_v2_send_tilt( resource_, TimeTicksToMilliseconds(time_stamp), touch_id, wl_fixed_from_double(tilt.x()), wl_fixed_from_double(tilt.y())); } private: wl_resource* resource_; Touch* touch_; DISALLOW_COPY_AND_ASSIGN(WaylandTouchStylusDelegate); }; void touch_stylus_destroy(wl_client* client, wl_resource* resource) { wl_resource_destroy(resource); } const struct zcr_touch_stylus_v2_interface touch_stylus_implementation = { touch_stylus_destroy}; //////////////////////////////////////////////////////////////////////////////// // zcr_pointer_stylus_v2 interface: class WaylandPointerStylusDelegate : public PointerStylusDelegate { public: WaylandPointerStylusDelegate(wl_resource* resource, Pointer* pointer) : resource_(resource), pointer_(pointer) { pointer_->SetStylusDelegate(this); } WaylandPointerStylusDelegate(const WaylandPointerStylusDelegate&) = delete; const WaylandPointerStylusDelegate& operator=( const WaylandPointerStylusDelegate&) = delete; ~WaylandPointerStylusDelegate() override { if (pointer_ != nullptr) pointer_->SetStylusDelegate(nullptr); } void OnPointerDestroying(Pointer* pointer_) override { pointer_ = nullptr; } void OnPointerToolChange(ui::EventPointerType type) override { uint wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_NONE; if (type == ui::EventPointerType::kTouch) wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_TOUCH; else if (type == ui::EventPointerType::kPen) wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_PEN; else if (type == ui::EventPointerType::kEraser) wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_ERASER; zcr_pointer_stylus_v2_send_tool(resource_, wayland_type); supports_force_ = false; supports_tilt_ = false; } void OnPointerForce(base::TimeTicks time_stamp, float force) override { // Set the force as 0 if the current tool previously reported a valid // force, but is now reporting a NaN value indicating that force is not // supported. if (std::isnan(force)) { if (supports_force_) force = 0; else return; } supports_force_ = true; zcr_pointer_stylus_v2_send_force(resource_, TimeTicksToMilliseconds(time_stamp), wl_fixed_from_double(force)); } void OnPointerTilt(base::TimeTicks time_stamp, const gfx::Vector2dF& tilt) override { if (!supports_tilt_ && tilt.IsZero()) return; supports_tilt_ = true; zcr_pointer_stylus_v2_send_tilt( resource_, TimeTicksToMilliseconds(time_stamp), wl_fixed_from_double(tilt.x()), wl_fixed_from_double(tilt.y())); } private: wl_resource* resource_; Pointer* pointer_; bool supports_force_ = false; bool supports_tilt_ = false; }; void pointer_stylus_destroy(wl_client* client, wl_resource* resource) { wl_resource_destroy(resource); } const struct zcr_pointer_stylus_v2_interface pointer_stylus_implementation = { pointer_stylus_destroy}; //////////////////////////////////////////////////////////////////////////////// // zcr_stylus_v2 interface: void stylus_get_touch_stylus(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* touch_resource) { Touch* touch = GetUserDataAs(touch_resource); if (touch->HasStylusDelegate()) { wl_resource_post_error( resource, ZCR_STYLUS_V2_ERROR_TOUCH_STYLUS_EXISTS, "touch has already been associated with a stylus object"); return; } wl_resource* stylus_resource = wl_resource_create(client, &zcr_touch_stylus_v2_interface, wl_resource_get_version(resource), id); SetImplementation( stylus_resource, &touch_stylus_implementation, std::make_unique(stylus_resource, touch)); } void stylus_get_pointer_stylus(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* pointer_resource) { Pointer* pointer = GetUserDataAs(pointer_resource); if (pointer->HasStylusDelegate()) { wl_resource_post_error( resource, ZCR_STYLUS_V2_ERROR_POINTER_STYLUS_EXISTS, "pointer has already been associated with a stylus object"); return; } wl_resource* stylus_resource = wl_resource_create(client, &zcr_pointer_stylus_v2_interface, wl_resource_get_version(resource), id); SetImplementation( stylus_resource, &pointer_stylus_implementation, std::make_unique(stylus_resource, pointer)); } const struct zcr_stylus_v2_interface stylus_v2_implementation = { stylus_get_touch_stylus, stylus_get_pointer_stylus}; } // namespace void bind_stylus_v2(wl_client* client, void* data, uint32_t version, uint32_t id) { wl_resource* resource = wl_resource_create(client, &zcr_stylus_v2_interface, version, id); wl_resource_set_implementation(resource, &stylus_v2_implementation, data, nullptr); } } // namespace wayland } // namespace exo