File: wayland_connection.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (505 lines) | stat: -rw-r--r-- 18,730 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_CONNECTION_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_CONNECTION_H_

#include <time.h>

#include <memory>
#include <ostream>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "ui/gl/gl_display.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
#include "ui/ozone/platform/wayland/host/wayland_serial_tracker.h"
#include "ui/ozone/platform/wayland/host/wayland_window_manager.h"
#include "ui/ozone/platform/wayland/host/xdg_session_manager.h"

class SkBitmap;

struct wl_cursor;
struct wl_event_queue;

namespace gfx {
class Point;
}

namespace wl {
class WaylandProxy;
}

namespace ui {

struct InputDevice;
struct KeyboardDevice;
struct TouchscreenDevice;

class GtkPrimarySelectionDeviceManager;
class OrgKdeKwinAppmenuManager;
class OrgKdeKwinIdle;
class OverlayPrioritizer;
class SinglePixelBuffer;
class WaylandBufferFactory;
class WaylandBufferManagerHost;
class WaylandClipboard;
class WaylandCursor;
class WaylandCursorBufferListener;
class WaylandCursorPosition;
class WaylandCursorShape;
class WaylandDataDeviceManager;
class WaylandDataDragController;
class WaylandEventSource;
class WaylandOutputManager;
class WaylandSeat;
class WaylandWindowDragController;
class WaylandZcrColorManager;
class WaylandZwpPointerConstraints;
class WaylandZwpPointerGestures;
class WaylandZwpRelativePointerManager;
class XdgActivation;
class XdgForeignWrapper;
class XdgSessionManager;
class ZwpIdleInhibitManager;
class ZwpPrimarySelectionDeviceManager;
class ZwpTextInputV1;
class ZwpTextInputV3;

class WaylandConnection {
 public:
  WaylandConnection();
  WaylandConnection(const WaylandConnection&) = delete;
  WaylandConnection& operator=(const WaylandConnection&) = delete;
  ~WaylandConnection();

  bool Initialize(bool use_threaded_polling = false);

  // Immediately flushes the Wayland display.
  void Flush();

  // Calls wl_display_roundtrip_queue. Might be required during initialization
  // of some objects that should block until they are initialized.
  void RoundTripQueue();

  // Sets a callback that that shutdowns the browser in case of unrecoverable
  // error. Called by WaylandEventWatcher.
  void SetShutdownCb(base::OnceCallback<void()> shutdown_cb);

  wl_compositor* compositor() const { return compositor_.get(); }
  // The server version of the compositor interface (might be higher than the
  // version binded).
  uint32_t compositor_version() const { return compositor_version_; }
  wl_subcompositor* subcompositor() const { return subcompositor_.get(); }
  wp_content_type_manager_v1* content_type_manager_v1() const {
    return content_type_manager_v1_.get();
  }
  wp_viewporter* viewporter() const { return viewporter_.get(); }
  zcr_alpha_compositing_v1* alpha_compositing() const {
    return alpha_compositing_.get();
  }
  xdg_wm_base* shell() const { return shell_.get(); }
  wp_presentation* presentation() const { return presentation_.get(); }
  zcr_keyboard_extension_v1* keyboard_extension_v1() const {
    return keyboard_extension_v1_.get();
  }
  zwp_keyboard_shortcuts_inhibit_manager_v1*
  keyboard_shortcuts_inhibit_manager_v1() const {
    return keyboard_shortcuts_inhibit_manager_v1_.get();
  }
  zwp_text_input_manager_v1* text_input_manager_v1() const {
    return text_input_manager_v1_.get();
  }
  zwp_linux_explicit_synchronization_v1* linux_explicit_synchronization_v1()
      const {
    return linux_explicit_synchronization_.get();
  }
  wp_linux_drm_syncobj_manager_v1* linux_drm_syncobj_manager_v1() const {
    return linux_drm_syncobj_manager_.get();
  }
  bool SupportsExplicitSync() const {
    return !!linux_explicit_synchronization_v1() ||
           !!linux_drm_syncobj_manager_v1();
  }
  zxdg_decoration_manager_v1* xdg_decoration_manager_v1() const {
    return xdg_decoration_manager_.get();
  }
  zcr_extended_drag_v1* extended_drag_v1() const {
    return extended_drag_v1_.get();
  }
  xdg_toplevel_drag_manager_v1* toplevel_drag_manager_v1() const {
    return xdg_toplevel_drag_manager_v1_.get();
  }

  zxdg_output_manager_v1* xdg_output_manager_v1() const {
    return xdg_output_manager_.get();
  }

  wp_fractional_scale_manager_v1* fractional_scale_manager_v1() const {
    return fractional_scale_manager_v1_.get();
  }

  xdg_toplevel_icon_manager_v1* toplevel_icon_manager_v1() const {
    return toplevel_icon_manager_v1_.get();
  }

  void SetPlatformCursor(wl_cursor* cursor_data, int buffer_scale);

  void SetCursorBufferListener(WaylandCursorBufferListener* listener);

  void SetCursorBitmap(const std::vector<SkBitmap>& bitmaps,
                       const gfx::Point& hotspot_in_dips,
                       int buffer_scale);

  WaylandEventSource* event_source() const { return event_source_.get(); }

  WaylandSeat* seat() const { return seat_.get(); }

  WaylandClipboard* clipboard() const { return clipboard_.get(); }

  WaylandOutputManager* wayland_output_manager() const {
    return output_manager_.get();
  }

  // Returns the cursor position, which may be null.
  WaylandCursorPosition* wayland_cursor_position() const {
    return cursor_position_.get();
  }

  WaylandBufferManagerHost* buffer_manager_host() const {
    return buffer_manager_host_.get();
  }

  WaylandZcrColorManager* zcr_color_manager() const {
    return zcr_color_manager_.get();
  }

  WaylandCursorShape* wayland_cursor_shape() const {
    return cursor_shape_.get();
  }

  WaylandWindowManager* window_manager() { return &window_manager_; }

  WaylandBufferFactory* buffer_factory() const { return buffer_factory_.get(); }

  WaylandDataDeviceManager* data_device_manager() const {
    return data_device_manager_.get();
  }

  GtkPrimarySelectionDeviceManager* gtk_primary_selection_device_manager()
      const {
    return gtk_primary_selection_device_manager_.get();
  }

  OrgKdeKwinAppmenuManager* org_kde_kwin_appmenu_manager() const {
    return org_kde_kwin_appmenu_manager_.get();
  }

  OrgKdeKwinIdle* org_kde_kwin_idle() { return org_kde_kwin_idle_.get(); }

  ZwpPrimarySelectionDeviceManager* zwp_primary_selection_device_manager()
      const {
    return zwp_primary_selection_device_manager_.get();
  }

  ZwpTextInputV1* EnsureTextInputV1();
  ZwpTextInputV3* EnsureTextInputV3();
  bool SupportsTextInputFocus() const { return !!text_input_v3_; }

  WaylandDataDragController* data_drag_controller() const {
    return data_drag_controller_.get();
  }

  WaylandWindowDragController* window_drag_controller() const {
    return window_drag_controller_.get();
  }

  WaylandZwpPointerConstraints* zwp_pointer_constraints() const {
    return zwp_pointer_constraints_.get();
  }

  WaylandZwpPointerGestures* zwp_pointer_gestures() const {
    return zwp_pointer_gestures_.get();
  }

  WaylandZwpRelativePointerManager* zwp_relative_pointer_manager() const {
    return zwp_relative_pointer_manager_.get();
  }

  const XdgActivation* xdg_activation() const { return xdg_activation_.get(); }

  XdgForeignWrapper* xdg_foreign() const { return xdg_foreign_.get(); }

  ZwpIdleInhibitManager* zwp_idle_inhibit_manager() const {
    return zwp_idle_inhibit_manager_.get();
  }

  OverlayPrioritizer* overlay_prioritizer() const {
    return overlay_prioritizer_.get();
  }

  SinglePixelBuffer* single_pixel_buffer() const {
    return single_pixel_buffer_.get();
  }

  XdgSessionManager* session_manager() { return session_manager_.get(); }

  // Returns whether protocols that support setting window geometry are
  // available.
  bool SupportsSetWindowGeometry() const;

  // Returns true when there an active outgoing drag-and-drop session.
  bool IsDragInProgress() const;

  // Returns true if a wl_keyboard is available.
  bool IsKeyboardAvailable() const;

  // Creates a new wl_surface.
  wl::Object<wl_surface> CreateSurface();

  // base::TimeTicks::Now() in posix uses CLOCK_MONOTONIC, wp_presentation
  // timestamps are in clk_id sent in wp_presentation.clock_id event. This
  // converts wp_presentation timestamp to base::TimeTicks.
  // The approximation relies on presentation timestamp to be close to current
  // time. The further it is from current time and the bigger the speed
  // difference between the two clock domains, the bigger the conversion error.
  // Conversion error due to system load is biased and unbounded.
  base::TimeTicks ConvertPresentationTime(uint32_t tv_sec_hi,
                                          uint32_t tv_sec_lo,
                                          uint32_t tv_nsec);

  const std::vector<std::pair<std::string, uint32_t>>& available_globals()
      const {
    return available_globals_;
  }

  bool supports_viewporter_surface_scaling() const {
    return supports_viewporter_surface_scaling_;
  }

  void set_supports_viewporter_surface_scaling(bool enabled) {
    supports_viewporter_surface_scaling_ = enabled;
  }

  bool UsePerSurfaceScaling() const;
  bool IsUiScaleEnabled() const;
  bool ShouldUseOverlayDelegation() const;

  wl::SerialTracker& serial_tracker() { return serial_tracker_; }

  void DumpState(std::ostream& out) const;

  bool UseImplicitSyncInterop() const;

  bool SupportsSessionManagement() const;

  // Returns a sync callback, which is invoked when the server has processed all
  // pending events prior to this sync point.
  struct wl_callback* GetSyncCallback();

  gl::EGLDisplayPlatform GetNativeDisplay();

  struct wl_registry* GetRegistry();

 private:
  friend class WaylandConnectionTestApi;

  // All global Wayland objects are friends of the Wayland connection.
  // Conceptually, this is correct: globals are owned by the connection and are
  // accessed via it, so they are essentially parts of it.  Also this friendship
  // makes it possible to avoid exposing setters for all those global objects:
  // these setters would only be needed by the globals but would be visible to
  // everyone.
  friend class FractionalScaleManager;
  friend class GtkPrimarySelectionDeviceManager;
  friend class OrgKdeKwinAppmenuManager;
  friend class OrgKdeKwinIdle;
  friend class OverlayPrioritizer;
  friend class SinglePixelBuffer;
  friend class ToplevelIconManager;
  friend class WaylandDataDeviceManager;
  friend class WaylandOutput;
  friend class WaylandSeat;
  friend class WaylandZwpPointerConstraints;
  friend class WaylandZwpPointerGestures;
  friend class WaylandZwpRelativePointerManager;
  friend class WaylandZcrColorManager;
  friend class WaylandCursorShape;
  friend class XdgActivation;
  friend class XdgForeignWrapper;
  friend class XdgSessionManager;
  friend class ZwpIdleInhibitManager;
  friend class ZwpPrimarySelectionDeviceManager;

  // A correct display must be chosen when creating objects or calling
  // roundtrips. That is, all the methods that deal with polling, pulling event
  // queues, etc, must use original display. All the other methods that create
  // various wayland objects must use |display_wrapper_| so that the new objects
  // are associated with the correct event queue. See the comment below about
  // the |event_queue_|.
  wl_display* display() const { return display_.get(); }
  wl_display* display_wrapper() const {
    return reinterpret_cast<wl_display*>(wrapped_display_.get());
  }

  void RegisterGlobalObjectFactory(const char* interface_name,
                                   wl::GlobalObjectFactory factory);

  // Returns true if the required wl_globals are announced by the server.
  bool WlGlobalsReady() const;

  // Updates InputDevice structures in Chrome. Currently, Wayland doesn't
  // support such, so the devices are derived from the connected interfaces.
  // Also, currently, Wayland doesn't expose InputDeviceType so marked as
  // UNKNOWN.
  // TODO(crbug.com/40254071): We need further investigation and proper design
  // how to model these input devices.
  void UpdateInputDevices();
  std::vector<InputDevice> CreateMouseDevices() const;
  std::vector<KeyboardDevice> CreateKeyboardDevices() const;
  std::vector<TouchscreenDevice> CreateTouchscreenDevices() const;

  // Updates cursor related objects in this instance.
  void UpdateCursor();

  // Initialize data-related objects if required protocol objects are already
  // in place, i.e: wl_seat and wl_data_device_manager.
  void CreateDataObjectsIfReady();

  // wl_registry_listener callbacks:
  static void OnGlobal(void* data,
                       wl_registry* registry,
                       uint32_t name,
                       const char* interface,
                       uint32_t version);
  static void OnGlobalRemove(void* data, wl_registry* registry, uint32_t name);

  // xdg_wm_base_listener callbacks:
  static void OnPing(void* data, xdg_wm_base* shell, uint32_t serial);

  // wp_presentation_listener callbacks:
  static void OnClockId(void* data,
                        wp_presentation* presentation,
                        uint32_t clk_id);

  void HandleGlobal(wl_registry* registry,
                    uint32_t name,
                    const char* interface,
                    uint32_t version);

  base::flat_map<std::string, wl::GlobalObjectFactory> global_object_factories_;

  uint32_t compositor_version_ = 0;
  wl::Object<wl_display> display_;
  // `event_queue_` must be declared before `wrapped_display_`, so that the
  // latter is destroyed first. This prevents libwayland warnings about the
  // queue being destroyed while the proxy is still attached.
  wl::Object<wl_event_queue> event_queue_;
  // A non-default display that Ozone/Wayland uses for event dispatching
  // (a non-default `event_queue_` is created using this display). This is
  // necessary to avoid any possible deadlocks (in case of API's misuse. See
  // https://crrev.com/c/2844573 for more context) or to avoid cases when other
  // clients' events are consumed (such as GTK and others) if both Ozone/Wayland
  // and those clients use the default display returned by |wl_display_connect|.
  wl::Object<wl_proxy> wrapped_display_;
  wl::Object<wl_registry> registry_;
  wl::Object<wl_compositor> compositor_;
  wl::Object<wl_subcompositor> subcompositor_;
  wl::Object<xdg_wm_base> shell_;
  wl::Object<wp_content_type_manager_v1> content_type_manager_v1_;
  wl::Object<wp_presentation> presentation_;
  wl::Object<wp_viewporter> viewporter_;
  wl::Object<zcr_alpha_compositing_v1> alpha_compositing_;
  wl::Object<zcr_keyboard_extension_v1> keyboard_extension_v1_;
  wl::Object<zwp_keyboard_shortcuts_inhibit_manager_v1>
      keyboard_shortcuts_inhibit_manager_v1_;
  wl::Object<zwp_text_input_manager_v1> text_input_manager_v1_;
  wl::Object<zwp_text_input_manager_v3> text_input_manager_v3_;
  wl::Object<zwp_linux_explicit_synchronization_v1>
      linux_explicit_synchronization_;
  bool enable_linux_drm_syncobj_for_testing_ = false;
  wl::Object<wp_linux_drm_syncobj_manager_v1> linux_drm_syncobj_manager_;
  wl::Object<zxdg_decoration_manager_v1> xdg_decoration_manager_;
  wl::Object<zcr_extended_drag_v1> extended_drag_v1_;
  wl::Object<::xdg_toplevel_drag_manager_v1> xdg_toplevel_drag_manager_v1_;
  wl::Object<zxdg_output_manager_v1> xdg_output_manager_;
  wl::Object<wp_fractional_scale_manager_v1> fractional_scale_manager_v1_;
  wl::Object<xdg_toplevel_icon_manager_v1> toplevel_icon_manager_v1_;

  // Manages Wayland windows.
  WaylandWindowManager window_manager_{this};

  // Event source instance. Must be declared before input objects so it
  // outlives them so thus being able to properly handle their destruction.
  std::unique_ptr<WaylandEventSource> event_source_;

  // Factory that wraps all the supported wayland objects that are provide
  // capabilities to create wl_buffers.
  std::unique_ptr<WaylandBufferFactory> buffer_factory_;

  std::unique_ptr<WaylandCursor> cursor_;
  std::unique_ptr<WaylandDataDeviceManager> data_device_manager_;
  std::unique_ptr<WaylandOutputManager> output_manager_;
  std::unique_ptr<WaylandCursorPosition> cursor_position_;
  std::unique_ptr<WaylandZcrColorManager> zcr_color_manager_;
  std::unique_ptr<WaylandCursorShape> cursor_shape_;
  std::unique_ptr<WaylandZwpPointerConstraints> zwp_pointer_constraints_;
  std::unique_ptr<WaylandZwpRelativePointerManager>
      zwp_relative_pointer_manager_;
  std::unique_ptr<WaylandZwpPointerGestures> zwp_pointer_gestures_;
  std::unique_ptr<WaylandSeat> seat_;
  std::unique_ptr<WaylandBufferManagerHost> buffer_manager_host_;
  std::unique_ptr<XdgActivation> xdg_activation_;
  std::unique_ptr<XdgForeignWrapper> xdg_foreign_;
  std::unique_ptr<ZwpIdleInhibitManager> zwp_idle_inhibit_manager_;
  std::unique_ptr<OverlayPrioritizer> overlay_prioritizer_;
  std::unique_ptr<SinglePixelBuffer> single_pixel_buffer_;

  // Clipboard-related objects. |clipboard_| must be declared after all
  // DeviceManager instances it depends on, otherwise tests may crash with
  // UAFs while attempting to access already destroyed manager pointers.
  std::unique_ptr<GtkPrimarySelectionDeviceManager>
      gtk_primary_selection_device_manager_;
  std::unique_ptr<ZwpPrimarySelectionDeviceManager>
      zwp_primary_selection_device_manager_;
  std::unique_ptr<ZwpTextInputV1> text_input_v1_;
  std::unique_ptr<ZwpTextInputV3> text_input_v3_;
  std::unique_ptr<WaylandClipboard> clipboard_;

  // Objects specific to KDE Plasma desktop environment.
  std::unique_ptr<OrgKdeKwinAppmenuManager> org_kde_kwin_appmenu_manager_;
  std::unique_ptr<OrgKdeKwinIdle> org_kde_kwin_idle_;

  std::unique_ptr<WaylandDataDragController> data_drag_controller_;
  std::unique_ptr<WaylandWindowDragController> window_drag_controller_;

  std::unique_ptr<XdgSessionManager> session_manager_;

  // Describes the clock domain that wp_presentation timestamps are in.
  uint32_t presentation_clk_id_ = CLOCK_MONOTONIC;

  // Allows input emulation access some data of objects that Wayland holds.
  // For example, wl_surface and others. It's only created when platform window
  // test config is set.
  std::unique_ptr<wl::WaylandProxy> wayland_proxy_;

  raw_ptr<WaylandCursorBufferListener> listener_ = nullptr;

  // This is set if wp_viewporter may be used to instruct the compositor to
  // properly scale fractional scaled surfaces.
  bool supports_viewporter_surface_scaling_ = false;

  wl::SerialTracker serial_tracker_;

  // Global Wayland interfaces available in the current session, with their
  // versions.
  std::vector<std::pair<std::string, uint32_t>> available_globals_;
};

}  // namespace ui

#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_CONNECTION_H_