summaryrefslogtreecommitdiff
path: root/src/window.cc
blob: 99b168ec1c96aca55358e7e8a6d5aac7d84dfc41 (plain)
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
#include "window.h"
#include "events.h"
#include "utils.h"
#include "vec.h"
#include "wlstate.h"
#include "xdg-shell.h"
#include <cstring>

static void wayc_surface_configure(void *data, struct xdg_surface *xdg_surface,
                                   u32 serial) {
  (void)data;
  xdg_surface_ack_configure(xdg_surface, serial);
}

static void wayc_toplevel_configure(void *data,
                                    struct xdg_toplevel *xdg_toplevel,
                                    i32 width, i32 height,
                                    struct wl_array *states) {
  (void)data;
  (void)xdg_toplevel;
  (void)width;
  (void)height;
  (void)states;
}

static void wayc_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) {
  (void)xdg_toplevel;

  struct window_s *window = (struct window_s *)data;
  wayc_notnull(window);

  struct eventloop_s *loop = window->loop;
  wayc_notnull(loop);

  struct event_s event = WAYC_EVENT_CLOSE(window);
  wayc_vec_push(&loop->events, &event);
}

static struct xdg_surface_listener WAYC_SURFACE_LISTENER = {
    wayc_surface_configure,
};

static struct xdg_toplevel_listener WAYC_TOPLEVEL_LISTENER = {
    wayc_toplevel_configure, wayc_toplevel_close, nullptr, nullptr};

bool wayc_window_init(struct window_s *window, const char *name,
                      struct eventloop_s *loop) {
  wayc_notnull(window);
  wayc_notnull(loop);
  memset(window, 0, sizeof(*window));

  struct wlstate_s *wlstate = &loop->state;

  wl_surface_t surface = wl_compositor_create_surface(wlstate->compositor);
  if (surface == nullptr)
    return false;

  xdg_surface_t xdg_surface =
      xdg_wm_base_get_xdg_surface(wlstate->wm_base, surface);
  if (xdg_surface == nullptr) {
    wl_surface_destroy(surface);
    return false;
  }

  xdg_surface_add_listener(xdg_surface, &WAYC_SURFACE_LISTENER, window);

  xdg_toplevel_t xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);
  if (xdg_toplevel == nullptr) {
    xdg_surface_destroy(xdg_surface);
    wl_surface_destroy(surface);
    return false;
  }

  xdg_toplevel_add_listener(xdg_toplevel, &WAYC_TOPLEVEL_LISTENER, window);
  xdg_toplevel_set_title(xdg_toplevel, name);

  window->surface = surface;
  window->xdg_surface = xdg_surface;
  window->xdg_toplevel = xdg_toplevel;
  window->loop = loop;
  return true;
}

void wayc_window_deinit(struct window_s *window) {
  wayc_notnull(window);

  if (window->surface == nullptr || window->xdg_surface == nullptr ||
      window->xdg_toplevel == nullptr)
    return;

  xdg_toplevel_destroy(window->xdg_toplevel);
  xdg_surface_destroy(window->xdg_surface);
  wl_surface_destroy(window->surface);

  window->xdg_toplevel = nullptr;
  window->xdg_surface = nullptr;
  window->surface = nullptr;
}