zcr_stylus.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/exo/wayland/zcr_stylus.h"
  5. #include <stylus-unstable-v2-server-protocol.h>
  6. #include "components/exo/pointer.h"
  7. #include "components/exo/pointer_stylus_delegate.h"
  8. #include "components/exo/touch.h"
  9. #include "components/exo/touch_stylus_delegate.h"
  10. #include "components/exo/wayland/server_util.h"
  11. namespace exo {
  12. namespace wayland {
  13. namespace {
  14. ////////////////////////////////////////////////////////////////////////////////
  15. // zcr_touch_stylus_v2 interface:
  16. class WaylandTouchStylusDelegate : public TouchStylusDelegate {
  17. public:
  18. WaylandTouchStylusDelegate(wl_resource* resource, Touch* touch)
  19. : resource_(resource), touch_(touch) {
  20. touch_->SetStylusDelegate(this);
  21. }
  22. WaylandTouchStylusDelegate(const WaylandTouchStylusDelegate&) = delete;
  23. WaylandTouchStylusDelegate& operator=(const WaylandTouchStylusDelegate&) =
  24. delete;
  25. ~WaylandTouchStylusDelegate() override {
  26. if (touch_ != nullptr)
  27. touch_->SetStylusDelegate(nullptr);
  28. }
  29. void OnTouchDestroying(Touch* touch) override { touch_ = nullptr; }
  30. void OnTouchTool(int touch_id, ui::EventPointerType type) override {
  31. uint wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_TOUCH;
  32. if (type == ui::EventPointerType::kPen)
  33. wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_PEN;
  34. else if (type == ui::EventPointerType::kEraser)
  35. wayland_type = ZCR_TOUCH_STYLUS_V2_TOOL_TYPE_ERASER;
  36. zcr_touch_stylus_v2_send_tool(resource_, touch_id, wayland_type);
  37. }
  38. void OnTouchForce(base::TimeTicks time_stamp,
  39. int touch_id,
  40. float force) override {
  41. zcr_touch_stylus_v2_send_force(resource_,
  42. TimeTicksToMilliseconds(time_stamp),
  43. touch_id, wl_fixed_from_double(force));
  44. }
  45. void OnTouchTilt(base::TimeTicks time_stamp,
  46. int touch_id,
  47. const gfx::Vector2dF& tilt) override {
  48. zcr_touch_stylus_v2_send_tilt(
  49. resource_, TimeTicksToMilliseconds(time_stamp), touch_id,
  50. wl_fixed_from_double(tilt.x()), wl_fixed_from_double(tilt.y()));
  51. }
  52. private:
  53. wl_resource* resource_;
  54. Touch* touch_;
  55. };
  56. void touch_stylus_destroy(wl_client* client, wl_resource* resource) {
  57. wl_resource_destroy(resource);
  58. }
  59. const struct zcr_touch_stylus_v2_interface touch_stylus_implementation = {
  60. touch_stylus_destroy};
  61. ////////////////////////////////////////////////////////////////////////////////
  62. // zcr_pointer_stylus_v2 interface:
  63. class WaylandPointerStylusDelegate : public PointerStylusDelegate {
  64. public:
  65. WaylandPointerStylusDelegate(wl_resource* resource, Pointer* pointer)
  66. : resource_(resource), pointer_(pointer) {
  67. pointer_->SetStylusDelegate(this);
  68. }
  69. WaylandPointerStylusDelegate(const WaylandPointerStylusDelegate&) = delete;
  70. const WaylandPointerStylusDelegate& operator=(
  71. const WaylandPointerStylusDelegate&) = delete;
  72. ~WaylandPointerStylusDelegate() override {
  73. if (pointer_ != nullptr)
  74. pointer_->SetStylusDelegate(nullptr);
  75. }
  76. void OnPointerDestroying(Pointer* pointer) override { pointer_ = nullptr; }
  77. void OnPointerToolChange(ui::EventPointerType type) override {
  78. uint wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_NONE;
  79. if (type == ui::EventPointerType::kTouch)
  80. wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_TOUCH;
  81. else if (type == ui::EventPointerType::kPen)
  82. wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_PEN;
  83. else if (type == ui::EventPointerType::kEraser)
  84. wayland_type = ZCR_POINTER_STYLUS_V2_TOOL_TYPE_ERASER;
  85. zcr_pointer_stylus_v2_send_tool(resource_, wayland_type);
  86. supports_force_ = false;
  87. supports_tilt_ = false;
  88. }
  89. void OnPointerForce(base::TimeTicks time_stamp, float force) override {
  90. // Set the force as 0 if the current tool previously reported a valid
  91. // force, but is now reporting a NaN value indicating that force is not
  92. // supported.
  93. if (std::isnan(force)) {
  94. if (supports_force_)
  95. force = 0;
  96. else
  97. return;
  98. }
  99. supports_force_ = true;
  100. zcr_pointer_stylus_v2_send_force(resource_,
  101. TimeTicksToMilliseconds(time_stamp),
  102. wl_fixed_from_double(force));
  103. }
  104. void OnPointerTilt(base::TimeTicks time_stamp,
  105. const gfx::Vector2dF& tilt) override {
  106. if (!supports_tilt_ && tilt.IsZero())
  107. return;
  108. supports_tilt_ = true;
  109. zcr_pointer_stylus_v2_send_tilt(
  110. resource_, TimeTicksToMilliseconds(time_stamp),
  111. wl_fixed_from_double(tilt.x()), wl_fixed_from_double(tilt.y()));
  112. }
  113. private:
  114. wl_resource* resource_;
  115. Pointer* pointer_;
  116. bool supports_force_ = false;
  117. bool supports_tilt_ = false;
  118. };
  119. void pointer_stylus_destroy(wl_client* client, wl_resource* resource) {
  120. wl_resource_destroy(resource);
  121. }
  122. const struct zcr_pointer_stylus_v2_interface pointer_stylus_implementation = {
  123. pointer_stylus_destroy};
  124. ////////////////////////////////////////////////////////////////////////////////
  125. // zcr_stylus_v2 interface:
  126. void stylus_get_touch_stylus(wl_client* client,
  127. wl_resource* resource,
  128. uint32_t id,
  129. wl_resource* touch_resource) {
  130. Touch* touch = GetUserDataAs<Touch>(touch_resource);
  131. if (touch->HasStylusDelegate()) {
  132. wl_resource_post_error(
  133. resource, ZCR_STYLUS_V2_ERROR_TOUCH_STYLUS_EXISTS,
  134. "touch has already been associated with a stylus object");
  135. return;
  136. }
  137. wl_resource* stylus_resource =
  138. wl_resource_create(client, &zcr_touch_stylus_v2_interface,
  139. wl_resource_get_version(resource), id);
  140. SetImplementation(
  141. stylus_resource, &touch_stylus_implementation,
  142. std::make_unique<WaylandTouchStylusDelegate>(stylus_resource, touch));
  143. }
  144. void stylus_get_pointer_stylus(wl_client* client,
  145. wl_resource* resource,
  146. uint32_t id,
  147. wl_resource* pointer_resource) {
  148. Pointer* pointer = GetUserDataAs<Pointer>(pointer_resource);
  149. if (pointer->HasStylusDelegate()) {
  150. wl_resource_post_error(
  151. resource, ZCR_STYLUS_V2_ERROR_POINTER_STYLUS_EXISTS,
  152. "pointer has already been associated with a stylus object");
  153. return;
  154. }
  155. wl_resource* stylus_resource =
  156. wl_resource_create(client, &zcr_pointer_stylus_v2_interface,
  157. wl_resource_get_version(resource), id);
  158. SetImplementation(
  159. stylus_resource, &pointer_stylus_implementation,
  160. std::make_unique<WaylandPointerStylusDelegate>(stylus_resource, pointer));
  161. }
  162. const struct zcr_stylus_v2_interface stylus_v2_implementation = {
  163. stylus_get_touch_stylus, stylus_get_pointer_stylus};
  164. } // namespace
  165. void bind_stylus_v2(wl_client* client,
  166. void* data,
  167. uint32_t version,
  168. uint32_t id) {
  169. wl_resource* resource =
  170. wl_resource_create(client, &zcr_stylus_v2_interface, version, id);
  171. wl_resource_set_implementation(resource, &stylus_v2_implementation, data,
  172. nullptr);
  173. }
  174. } // namespace wayland
  175. } // namespace exo