~sircmpwn/xrgears

ref: 04a78fdd25967ed8f104e5c0b1e0589588d6c776 xrgears/vitamin-k/window/vikWindowWaylandXDG.hpp -rw-r--r-- 4.0 KiB
04a78fdd — Lubosz Sarnecki overlay: fix validation warnings. 4 years ago
                                                                                
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
/*
 * vitamin-k
 *
 * Copyright 2017-2018 Collabora Ltd.
 *
 * Authors: Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
 * SPDX-License-Identifier: MIT
 */

#pragma once

#include <string.h>
#include <stdio.h>

#include <poll.h>

#include <vulkan/vulkan.h>
#include <string>

#include "../../xdg-shell/xdg-shell-unstable-v6-client-protocol.h"

#include "vikWindowWayland.hpp"
#include "../system/vikLog.hpp"

namespace vik {
class WindowWaylandXDG : public WindowWayland {
  zxdg_shell_v6 *shell = nullptr;
  zxdg_surface_v6 *xdg_surface = nullptr;
  zxdg_toplevel_v6 *xdg_toplevel = nullptr;
  SwapChainVkComplex swap_chain;

 public:
  explicit WindowWaylandXDG(Settings *s) : WindowWayland(s) {
    name = "wayland-xdg";
  }

  ~WindowWaylandXDG() {}

  // Return -1 on failure.
  int init() {
    display = wl_display_connect(NULL);
    if (!display)
      return -1;

    wl_registry *registry = wl_display_get_registry(display);
    wl_registry_add_listener(registry, &registry_listener, this);

    /* Round-trip to get globals */
    wl_display_roundtrip(display);

    /* We don't need this anymore */
    wl_registry_destroy(registry);

    surface = wl_compositor_create_surface(compositor);

    vik_log_f_if(!shell,
                 "Compositor is missing unstable zxdg_shell_v6 support");

    xdg_surface = zxdg_shell_v6_get_xdg_surface(shell, surface);

    zxdg_surface_v6_add_listener(xdg_surface, &xdg_surface_listener, this);

    xdg_toplevel = zxdg_surface_v6_get_toplevel(xdg_surface);

    zxdg_toplevel_v6_add_listener(xdg_toplevel, &xdg_toplevel_listener, this);

    update_window_title("vkcube");

    wl_surface_commit(surface);

    return 0;
  }

  void update_window_title(const std::string& title) {
    zxdg_toplevel_v6_set_title(xdg_toplevel, title.c_str());
  }

  void registry_global(wl_registry *registry, uint32_t name,
                       const char *interface) {
    if (strcmp(interface, "wl_compositor") == 0) {
      compositor = (wl_compositor*)
          wl_registry_bind(registry, name, &wl_compositor_interface, 1);
    } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
      shell = (zxdg_shell_v6*)
          wl_registry_bind(registry, name, &zxdg_shell_v6_interface, 1);
      zxdg_shell_v6_add_listener(shell, &xdg_shell_listener, this);
    } else if (strcmp(interface, "wl_seat") == 0) {
      seat = (wl_seat*)
          wl_registry_bind(registry, name, &wl_seat_interface, 1);
      wl_seat_add_listener(seat, &seat_listener, this);
    } else if (strcmp(interface, "wl_output") == 0) {
      wl_output* _output = (wl_output*)
          wl_registry_bind(registry, name, &wl_output_interface, 2);
      wl_output_add_listener(_output, &output_listener, this);
    }
  }

  void fullscreen() {
    fullscreen(current_display()->output);
  }

  void fullscreen(wl_output *output) {
    zxdg_toplevel_v6_set_fullscreen(xdg_toplevel, output);
    wl_surface_commit(surface);
  }

  static void _xdg_surface_configure_cb(void *data, zxdg_surface_v6 *surface,
                                        uint32_t serial) {
    zxdg_surface_v6_ack_configure(surface, serial);
  }

  static void _xdg_toplevel_configure_cb(void *data, zxdg_toplevel_v6 *toplevel,
                                         int32_t width, int32_t height,
                                         struct wl_array *states) {
    WindowWaylandXDG *self = reinterpret_cast<WindowWaylandXDG *>(data);
    self->configure(width, height);
  }

  const zxdg_surface_v6_listener xdg_surface_listener = {
    _xdg_surface_configure_cb,
  };

  const zxdg_toplevel_v6_listener xdg_toplevel_listener = {
    _xdg_toplevel_configure_cb,
    _xdg_toplevel_close_cb,
  };

  const zxdg_shell_v6_listener xdg_shell_listener = {
    _xdg_shell_ping_cb,
  };

  static void _xdg_shell_ping_cb(void *data, zxdg_shell_v6 *shell,
                                 uint32_t serial) {
    zxdg_shell_v6_pong(shell, serial);
  }

  // unused callbacks

  static void _xdg_toplevel_close_cb(void *data, zxdg_toplevel_v6 *toplevel) {}
};
}  // namespace vik