zwp_pointer_constraints.cc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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/zwp_pointer_constraints.h"
  5. #include <pointer-constraints-unstable-v1-server-protocol.h>
  6. #include <wayland-server-core.h>
  7. #include <wayland-server-protocol-core.h>
  8. #include <cstdarg>
  9. #include <memory>
  10. #include "components/exo/pointer.h"
  11. #include "components/exo/pointer_constraint_delegate.h"
  12. #include "components/exo/wayland/server_util.h"
  13. #include "third_party/skia/include/core/SkRegion.h"
  14. namespace exo {
  15. namespace wayland {
  16. namespace {
  17. // Implements a PointerConstraintDelegate in terms of the zwp_locked_pointer
  18. // Wayland protocol.
  19. //
  20. // Lifetime note: The underlying Wayland protocol gives control over this
  21. // object's lifetime to the client. However, it's possible that its
  22. // dependencies could be destroyed prior to the client destroying it.
  23. // At this point we consider the object "defunct" and its |surface_| member
  24. // to be potentially dangling. |pointer_| is correctly nulled when appropriate.
  25. class WaylandPointerConstraintDelegate : public PointerConstraintDelegate {
  26. public:
  27. WaylandPointerConstraintDelegate(wl_resource* constraint_resource,
  28. Surface* surface,
  29. Pointer* pointer,
  30. SkRegion* region,
  31. uint32_t lifetime)
  32. : constraint_resource_(constraint_resource),
  33. pointer_(pointer),
  34. surface_(surface),
  35. is_persistent_(lifetime ==
  36. ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT) {
  37. pointer->ConstrainPointer(this);
  38. }
  39. ~WaylandPointerConstraintDelegate() override {
  40. if (pointer_) {
  41. pointer_->OnPointerConstraintDelegateDestroying(this);
  42. pointer_ = nullptr;
  43. }
  44. }
  45. // PointerConstraintDelegate::
  46. void OnConstraintActivated() override { SendLocked(); }
  47. void OnAlreadyConstrained() override {
  48. wl_resource_post_error(
  49. constraint_resource_,
  50. ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
  51. "A pointer constraint was already requested for this wl_pointer "
  52. "on this wl_surface.");
  53. }
  54. void OnConstraintBroken() override { SendUnlocked(); }
  55. bool IsPersistent() override { return is_persistent_; }
  56. Surface* GetConstrainedSurface() override { return surface_; }
  57. void OnDefunct() override { pointer_ = nullptr; }
  58. private:
  59. // Inform the client of the state of the lock.
  60. void SendLocked() {
  61. VLOG(1) << "send_locked(" << constraint_resource_ << ")";
  62. zwp_locked_pointer_v1_send_locked(constraint_resource_);
  63. }
  64. void SendUnlocked() {
  65. VLOG(1) << "send_unlocked(" << constraint_resource_ << ")";
  66. zwp_locked_pointer_v1_send_unlocked(constraint_resource_);
  67. }
  68. wl_resource* const constraint_resource_;
  69. Pointer* pointer_;
  70. Surface* const surface_;
  71. bool is_persistent_;
  72. };
  73. ////////////////////////////////////////////////////////////////////////////////
  74. // zwp_locked_pointer
  75. void locked_pointer_destroy(wl_client* client, wl_resource* resource) {
  76. VLOG(1) << "locked_pointer_destroy(" << client << ", " << resource << ")";
  77. wl_resource_destroy(resource);
  78. }
  79. void locked_pointer_set_cursor_position_hint(wl_client* client,
  80. wl_resource* resource,
  81. wl_fixed_t surface_x,
  82. wl_fixed_t surface_y) {
  83. // Not supported.
  84. }
  85. void locked_pointer_set_region(wl_client* client,
  86. wl_resource* resource,
  87. wl_resource* region_resource) {
  88. // Not supported.
  89. }
  90. const struct zwp_locked_pointer_v1_interface locked_pointer_implementation = {
  91. locked_pointer_destroy, locked_pointer_set_cursor_position_hint,
  92. locked_pointer_set_region};
  93. ////////////////////////////////////////////////////////////////////////////////
  94. // zwp_confined_pointer
  95. void confined_pointer_destroy(wl_client* client, wl_resource* resource) {
  96. wl_resource_destroy(resource);
  97. }
  98. void confined_pointer_set_region(wl_client* client,
  99. wl_resource* resource,
  100. wl_resource* region_resource) {
  101. // Not supported.
  102. }
  103. const struct zwp_confined_pointer_v1_interface confined_pointer_implementation =
  104. {
  105. confined_pointer_destroy,
  106. confined_pointer_set_region,
  107. };
  108. ////////////////////////////////////////////////////////////////////////////////
  109. // zwp_pointer_constraints
  110. void pointer_constraints_destroy(wl_client* client, wl_resource* resource) {
  111. VLOG(1) << "pointer_constraints_destroy(" << client << ", " << resource
  112. << ")";
  113. wl_resource_destroy(resource);
  114. }
  115. void pointer_constraints_lock_pointer(wl_client* client,
  116. wl_resource* resource,
  117. uint32_t id,
  118. wl_resource* surface_resource,
  119. wl_resource* pointer_resource,
  120. wl_resource* region_resource,
  121. uint32_t lifetime) {
  122. Surface* surface = GetUserDataAs<Surface>(surface_resource);
  123. Pointer* pointer = GetUserDataAs<Pointer>(pointer_resource);
  124. SkRegion* region =
  125. region_resource ? GetUserDataAs<SkRegion>(region_resource) : nullptr;
  126. VLOG(1) << "lock_pointer(" << client << ", " << resource << "; Surface "
  127. << surface << " @ window '"
  128. << (surface && surface->window() ? surface->window()->GetTitle()
  129. : base::EmptyString16())
  130. << "', "
  131. << "Pointer " << pointer << ")";
  132. wl_resource* locked_pointer_resource =
  133. wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
  134. SetImplementation(
  135. locked_pointer_resource, &locked_pointer_implementation,
  136. std::make_unique<WaylandPointerConstraintDelegate>(
  137. locked_pointer_resource, surface, pointer, region, lifetime));
  138. }
  139. void pointer_constraints_confine_pointer(wl_client* client,
  140. wl_resource* resource,
  141. uint32_t id,
  142. wl_resource* surface_resource,
  143. wl_resource* pointer_resource,
  144. wl_resource* region_resource,
  145. uint32_t lifetime) {
  146. // Confined pointer is not currently supported.
  147. wl_resource* confined_pointer_resource =
  148. wl_resource_create(client, &zwp_confined_pointer_v1_interface, 1, id);
  149. SetImplementation<int>(confined_pointer_resource,
  150. &confined_pointer_implementation, nullptr);
  151. }
  152. const struct zwp_pointer_constraints_v1_interface
  153. pointer_constraints_implementation = {pointer_constraints_destroy,
  154. pointer_constraints_lock_pointer,
  155. pointer_constraints_confine_pointer};
  156. } // namespace
  157. void bind_pointer_constraints(wl_client* client,
  158. void* data,
  159. uint32_t version,
  160. uint32_t id) {
  161. wl_resource* resource = wl_resource_create(
  162. client, &zwp_pointer_constraints_v1_interface, version, id);
  163. wl_resource_set_implementation(resource, &pointer_constraints_implementation,
  164. data, nullptr);
  165. }
  166. } // namespace wayland
  167. } // namespace exo