dont deadlock while receiving events
This commit is contained in:
parent
0b5710da3e
commit
7298730969
7 changed files with 134 additions and 80 deletions
|
@ -66,6 +66,12 @@
|
||||||
<arg name="tag" type="int"/>
|
<arg name="tag" type="int"/>
|
||||||
<arg name="active" type="int"/>
|
<arg name="active" type="int"/>
|
||||||
<arg name="num_clients" type="int"/>
|
<arg name="num_clients" type="int"/>
|
||||||
|
<arg name="urgent" type="int"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="frame">
|
||||||
|
<description summary="sent after all other events have been sent. allows for atomic updates.">
|
||||||
|
</description>
|
||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
</protocol>
|
</protocol>
|
||||||
|
|
46
src/bar.cpp
46
src/bar.cpp
|
@ -27,25 +27,25 @@ static QFont getFont()
|
||||||
font.setBold(fontBold);
|
font.setBold(fontBold);
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
static QFont font = getFont();
|
||||||
|
static QFontMetrics fontMetrics = QFontMetrics {font};
|
||||||
|
|
||||||
Bar::Bar(const wl_output *output)
|
Bar::Bar(const wl_output *output)
|
||||||
: _font {getFont()}
|
|
||||||
, _fontMetrics {_font}
|
|
||||||
{
|
{
|
||||||
_surface = wl_compositor_create_surface(compositor);
|
_surface.reset(wl_compositor_create_surface(compositor));
|
||||||
_layerSurface = zwlr_layer_shell_v1_get_layer_surface(wlrLayerShell,
|
_layerSurface.reset(zwlr_layer_shell_v1_get_layer_surface(wlrLayerShell,
|
||||||
_surface, nullptr, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "net.tapesoftware.Somebar");
|
_surface.get(), nullptr, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "net.tapesoftware.Somebar"));
|
||||||
zwlr_layer_surface_v1_add_listener(_layerSurface, &_layerSurfaceListener, this);
|
zwlr_layer_surface_v1_add_listener(_layerSurface.get(), &_layerSurfaceListener, this);
|
||||||
auto anchor = topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
auto anchor = topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
zwlr_layer_surface_v1_set_anchor(_layerSurface,
|
zwlr_layer_surface_v1_set_anchor(_layerSurface.get(),
|
||||||
anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
|
anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
|
||||||
|
|
||||||
auto barSize = _fontMetrics.ascent() + _fontMetrics.descent() + paddingY * 2;
|
auto barSize = fontMetrics.ascent() + fontMetrics.descent() + paddingY * 2;
|
||||||
_textY = _fontMetrics.ascent() + paddingY;
|
_textY = fontMetrics.ascent() + paddingY;
|
||||||
|
|
||||||
zwlr_layer_surface_v1_set_size(_layerSurface, 0, barSize);
|
zwlr_layer_surface_v1_set_size(_layerSurface.get(), 0, barSize);
|
||||||
zwlr_layer_surface_v1_set_exclusive_zone(_layerSurface, barSize);
|
zwlr_layer_surface_v1_set_exclusive_zone(_layerSurface.get(), barSize);
|
||||||
wl_surface_commit(_surface);
|
wl_surface_commit(_surface.get());
|
||||||
|
|
||||||
for (auto tag : tagNames) {
|
for (auto tag : tagNames) {
|
||||||
_tags.push_back({ tag, false });
|
_tags.push_back({ tag, false });
|
||||||
|
@ -54,11 +54,7 @@ Bar::Bar(const wl_output *output)
|
||||||
_status = "Status";
|
_status = "Status";
|
||||||
}
|
}
|
||||||
|
|
||||||
Bar::~Bar()
|
const wl_surface* Bar::surface() const { return _surface.get(); }
|
||||||
{
|
|
||||||
wl_surface_destroy(_surface);
|
|
||||||
zwlr_layer_surface_v1_destroy(_layerSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bar::click(int x, int)
|
void Bar::click(int x, int)
|
||||||
{
|
{
|
||||||
|
@ -75,9 +71,9 @@ void Bar::invalidate()
|
||||||
{
|
{
|
||||||
if (_invalid) return;
|
if (_invalid) return;
|
||||||
_invalid = true;
|
_invalid = true;
|
||||||
auto frame = wl_surface_frame(_surface);
|
auto frame = wl_surface_frame(_surface.get());
|
||||||
wl_callback_add_listener(frame, &_frameListener, this);
|
wl_callback_add_listener(frame, &_frameListener, this);
|
||||||
wl_surface_commit(_surface);
|
wl_surface_commit(_surface.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bar::setStatus(const QString &status)
|
void Bar::setStatus(const QString &status)
|
||||||
|
@ -88,7 +84,7 @@ void Bar::setStatus(const QString &status)
|
||||||
|
|
||||||
void Bar::layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height)
|
void Bar::layerSurfaceConfigure(uint32_t serial, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
zwlr_layer_surface_v1_ack_configure(_layerSurface, serial);
|
zwlr_layer_surface_v1_ack_configure(_layerSurface.get(), serial);
|
||||||
_bufs.emplace(width, height, WL_SHM_FORMAT_XRGB8888);
|
_bufs.emplace(width, height, WL_SHM_FORMAT_XRGB8888);
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
@ -105,7 +101,7 @@ void Bar::render()
|
||||||
auto painter = QPainter {&img};
|
auto painter = QPainter {&img};
|
||||||
_painter = &painter;
|
_painter = &painter;
|
||||||
_x = 0;
|
_x = 0;
|
||||||
painter.setFont(_font);
|
painter.setFont(font);
|
||||||
|
|
||||||
setColorScheme(colorActive);
|
setColorScheme(colorActive);
|
||||||
painter.fillRect(0, 0, img.width(), img.height(), painter.brush());
|
painter.fillRect(0, 0, img.width(), img.height(), painter.brush());
|
||||||
|
@ -115,9 +111,9 @@ void Bar::render()
|
||||||
renderStatus();
|
renderStatus();
|
||||||
|
|
||||||
_painter = nullptr;
|
_painter = nullptr;
|
||||||
wl_surface_attach(_surface, _bufs->buffer(), 0, 0);
|
wl_surface_attach(_surface.get(), _bufs->buffer(), 0, 0);
|
||||||
wl_surface_damage(_surface, 0, 0, INT_MAX, INT_MAX);
|
wl_surface_damage(_surface.get(), 0, 0, INT_MAX, INT_MAX);
|
||||||
wl_surface_commit(_surface);
|
wl_surface_commit(_surface.get());
|
||||||
_bufs->flip();
|
_bufs->flip();
|
||||||
_invalid = false;
|
_invalid = false;
|
||||||
}
|
}
|
||||||
|
@ -156,5 +152,5 @@ void Bar::renderStatus()
|
||||||
|
|
||||||
int Bar::textWidth(const QString &text)
|
int Bar::textWidth(const QString &text)
|
||||||
{
|
{
|
||||||
return _fontMetrics.size(Qt::TextSingleLine, text).width();
|
return fontMetrics.size(Qt::TextSingleLine, text).width();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,9 @@ class Bar {
|
||||||
static const zwlr_layer_surface_v1_listener _layerSurfaceListener;
|
static const zwlr_layer_surface_v1_listener _layerSurfaceListener;
|
||||||
static const wl_callback_listener _frameListener;
|
static const wl_callback_listener _frameListener;
|
||||||
|
|
||||||
wl_surface *_surface {nullptr};
|
wl_unique_ptr<wl_surface> _surface;
|
||||||
zwlr_layer_surface_v1 *_layerSurface {nullptr};
|
wl_unique_ptr<zwlr_layer_surface_v1> _layerSurface;
|
||||||
QPainter *_painter {nullptr};
|
QPainter *_painter {nullptr};
|
||||||
QFont _font;
|
|
||||||
QFontMetrics _fontMetrics;
|
|
||||||
std::optional<ShmBuffer> _bufs;
|
std::optional<ShmBuffer> _bufs;
|
||||||
int _textY, _x;
|
int _textY, _x;
|
||||||
bool _invalid {false};
|
bool _invalid {false};
|
||||||
|
@ -45,7 +43,7 @@ class Bar {
|
||||||
void invalidate();
|
void invalidate();
|
||||||
public:
|
public:
|
||||||
explicit Bar(const wl_output *output);
|
explicit Bar(const wl_output *output);
|
||||||
|
const wl_surface* surface() const;
|
||||||
void setStatus(const QString &status);
|
void setStatus(const QString &status);
|
||||||
void click(int x, int y);
|
void click(int x, int y);
|
||||||
~Bar();
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
extern wl_display *display;
|
extern wl_display *display;
|
||||||
extern wl_compositor *compositor;
|
extern wl_compositor *compositor;
|
||||||
|
@ -17,3 +19,17 @@ extern std::vector<QString> tagNames;
|
||||||
struct ColorScheme {
|
struct ColorScheme {
|
||||||
QColor fg, bg;
|
QColor fg, bg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// wayland smart pointers
|
||||||
|
template<typename T>
|
||||||
|
struct wl_deleter;
|
||||||
|
#define WL_DELETER(type, fn) template<> struct wl_deleter<type> { void operator()(type *v) { if(v) fn(v); } }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using wl_unique_ptr = std::unique_ptr<T, wl_deleter<T>>;
|
||||||
|
|
||||||
|
WL_DELETER(wl_surface, wl_surface_destroy);
|
||||||
|
WL_DELETER(zwlr_layer_surface_v1, zwlr_layer_surface_v1_destroy);
|
||||||
|
WL_DELETER(wl_buffer, wl_buffer_destroy);
|
||||||
|
WL_DELETER(wl_output, wl_output_release);
|
||||||
|
WL_DELETER(znet_tapesoftware_dwl_wm_monitor_v1, znet_tapesoftware_dwl_wm_monitor_v1_release);
|
||||||
|
|
114
src/main.cpp
114
src/main.cpp
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
struct Monitor {
|
struct Monitor {
|
||||||
uint32_t name;
|
uint32_t name;
|
||||||
wl_output *wlOutput;
|
wl_unique_ptr<wl_output> wlOutput;
|
||||||
znet_tapesoftware_dwl_wm_monitor_v1 *dwlMonitor;
|
wl_unique_ptr<znet_tapesoftware_dwl_wm_monitor_v1> dwlMonitor;
|
||||||
std::optional<Bar> bar;
|
std::optional<Bar> bar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ wl_shm *shm;
|
||||||
zwlr_layer_shell_v1 *wlrLayerShell;
|
zwlr_layer_shell_v1 *wlrLayerShell;
|
||||||
znet_tapesoftware_dwl_wm_v1 *dwlWm;
|
znet_tapesoftware_dwl_wm_v1 *dwlWm;
|
||||||
std::vector<QString> tagNames;
|
std::vector<QString> tagNames;
|
||||||
|
static bool ready;
|
||||||
static std::vector<Monitor> monitors;
|
static std::vector<Monitor> monitors;
|
||||||
static std::optional<Bar> bar;
|
|
||||||
static std::string statusFifoName;
|
static std::string statusFifoName;
|
||||||
static int statusFifoFd {-1};
|
static int statusFifoFd {-1};
|
||||||
static int statusFifoWriter {-1};
|
static int statusFifoWriter {-1};
|
||||||
|
@ -57,7 +57,7 @@ static const struct xdg_wm_base_listener xdgWmBaseListener = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PointerState {
|
struct SeatState {
|
||||||
wl_pointer *pointer;
|
wl_pointer *pointer;
|
||||||
wl_surface *cursorSurface;
|
wl_surface *cursorSurface;
|
||||||
wl_cursor_image *cursorImage;
|
wl_cursor_image *cursorImage;
|
||||||
|
@ -65,33 +65,40 @@ struct PointerState {
|
||||||
int x, y;
|
int x, y;
|
||||||
bool leftButtonClick;
|
bool leftButtonClick;
|
||||||
};
|
};
|
||||||
static PointerState pointerState;
|
static SeatState seatState;
|
||||||
|
static Bar* barFromSurface(const wl_surface *surface)
|
||||||
|
{
|
||||||
|
auto fbar = std::find_if(begin(monitors), end(monitors), [surface](const Monitor &mon) {
|
||||||
|
return mon.bar && mon.bar->surface() == surface;
|
||||||
|
});
|
||||||
|
return fbar != end(monitors) && fbar->bar ? &*fbar->bar : nullptr;
|
||||||
|
}
|
||||||
static const struct wl_pointer_listener pointerListener = {
|
static const struct wl_pointer_listener pointerListener = {
|
||||||
.enter = [](void*, wl_pointer *pointer, uint32_t serial,
|
.enter = [](void*, wl_pointer *pointer, uint32_t serial,
|
||||||
wl_surface*, wl_fixed_t x, wl_fixed_t y)
|
wl_surface *surface, wl_fixed_t x, wl_fixed_t y)
|
||||||
{
|
{
|
||||||
pointerState.focusedBar = &bar.value();
|
seatState.focusedBar = barFromSurface(surface);
|
||||||
wl_pointer_set_cursor(pointer, serial, pointerState.cursorSurface,
|
wl_pointer_set_cursor(pointer, serial, seatState.cursorSurface,
|
||||||
pointerState.cursorImage->hotspot_x, pointerState.cursorImage->hotspot_y);
|
seatState.cursorImage->hotspot_x, seatState.cursorImage->hotspot_y);
|
||||||
},
|
},
|
||||||
.leave = [](void*, wl_pointer*, uint32_t serial, wl_surface*) {
|
.leave = [](void*, wl_pointer*, uint32_t serial, wl_surface*) {
|
||||||
pointerState.focusedBar = nullptr;
|
seatState.focusedBar = nullptr;
|
||||||
},
|
},
|
||||||
.motion = [](void*, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) {
|
.motion = [](void*, wl_pointer*, uint32_t, wl_fixed_t x, wl_fixed_t y) {
|
||||||
pointerState.x = wl_fixed_to_int(x);
|
seatState.x = wl_fixed_to_int(x);
|
||||||
pointerState.y = wl_fixed_to_int(y);
|
seatState.y = wl_fixed_to_int(y);
|
||||||
},
|
},
|
||||||
.button = [](void*, wl_pointer*, uint32_t, uint32_t, uint32_t button, uint32_t pressed) {
|
.button = [](void*, wl_pointer*, uint32_t, uint32_t, uint32_t button, uint32_t pressed) {
|
||||||
if (button == BTN_LEFT) {
|
if (button == BTN_LEFT) {
|
||||||
pointerState.leftButtonClick = pressed == WL_POINTER_BUTTON_STATE_PRESSED;
|
seatState.leftButtonClick = pressed == WL_POINTER_BUTTON_STATE_PRESSED;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.axis = [](void*, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { },
|
.axis = [](void*, wl_pointer*, uint32_t, uint32_t, wl_fixed_t) { },
|
||||||
.frame = [](void*, wl_pointer*) {
|
.frame = [](void*, wl_pointer*) {
|
||||||
if (!pointerState.focusedBar) return;
|
if (!seatState.focusedBar) return;
|
||||||
if (pointerState.leftButtonClick) {
|
if (seatState.leftButtonClick) {
|
||||||
pointerState.leftButtonClick = false;
|
seatState.leftButtonClick = false;
|
||||||
pointerState.focusedBar->click(pointerState.x, pointerState.y);
|
seatState.focusedBar->click(seatState.x, seatState.y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.axis_source = [](void*, wl_pointer*, uint32_t) { },
|
.axis_source = [](void*, wl_pointer*, uint32_t) { },
|
||||||
|
@ -103,16 +110,16 @@ static wl_seat *seat;
|
||||||
static const struct wl_seat_listener seatListener = {
|
static const struct wl_seat_listener seatListener = {
|
||||||
[](void*, wl_seat*, uint32_t cap)
|
[](void*, wl_seat*, uint32_t cap)
|
||||||
{
|
{
|
||||||
if (!pointerState.pointer && WL_SEAT_CAPABILITY_POINTER) {
|
if (!seatState.pointer && WL_SEAT_CAPABILITY_POINTER) {
|
||||||
auto cursorTheme = wl_cursor_theme_load(NULL, 24, shm);
|
auto cursorTheme = wl_cursor_theme_load(NULL, 24, shm);
|
||||||
auto cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0];
|
auto cursorImage = wl_cursor_theme_get_cursor(cursorTheme, "left_ptr")->images[0];
|
||||||
pointerState.cursorImage = cursorImage;
|
seatState.cursorImage = cursorImage;
|
||||||
pointerState.cursorSurface = wl_compositor_create_surface(compositor);
|
seatState.cursorSurface = wl_compositor_create_surface(compositor);
|
||||||
wl_surface_attach(pointerState.cursorSurface,
|
wl_surface_attach(seatState.cursorSurface,
|
||||||
wl_cursor_image_get_buffer(cursorImage), 0, 0);
|
wl_cursor_image_get_buffer(cursorImage), 0, 0);
|
||||||
wl_surface_commit(pointerState.cursorSurface);
|
wl_surface_commit(seatState.cursorSurface);
|
||||||
pointerState.pointer = wl_seat_get_pointer(seat);
|
seatState.pointer = wl_seat_get_pointer(seat);
|
||||||
wl_pointer_add_listener(pointerState.pointer, &pointerListener, nullptr);
|
wl_pointer_add_listener(seatState.pointer, &pointerListener, nullptr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[](void*, wl_seat*, const char *name) { }
|
[](void*, wl_seat*, const char *name) { }
|
||||||
|
@ -125,21 +132,26 @@ static const struct znet_tapesoftware_dwl_wm_v1_listener dwlWmListener = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener {
|
static const struct znet_tapesoftware_dwl_wm_monitor_v1_listener dwlWmMonitorListener {
|
||||||
.tag = [](void*, znet_tapesoftware_dwl_wm_monitor_v1*, int tag, int active, int numClients) {
|
.tag = [](void*, znet_tapesoftware_dwl_wm_monitor_v1*, int tag, int active, int numClients, int urgent) {
|
||||||
printf("tag %s: active=%d, num_clients=%d\n", qPrintable(tagNames[tag]), active, numClients);
|
printf("tag %s: active=%d, num_clients=%d, urgent=%d\n", qPrintable(tagNames[tag]), active, numClients, urgent);
|
||||||
|
},
|
||||||
|
.frame = [](void *mv, znet_tapesoftware_dwl_wm_monitor_v1*) {
|
||||||
|
auto mon = static_cast<Monitor*>(mv);
|
||||||
|
if (!mon->bar) {
|
||||||
|
mon->bar.emplace(mon->wlOutput.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void setupOutput(Monitor &monitor) {
|
static void setupMonitor(Monitor &monitor) {
|
||||||
monitor.dwlMonitor = znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput);
|
monitor.dwlMonitor.reset(znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, monitor.wlOutput.get()));
|
||||||
znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor, &dwlWmMonitorListener, &monitor);
|
znet_tapesoftware_dwl_wm_monitor_v1_add_listener(monitor.dwlMonitor.get(), &dwlWmMonitorListener, &monitor);
|
||||||
monitor.bar.emplace(monitor.wlOutput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onOutput(int name, wl_output *output) {
|
static void onOutput(uint32_t name, wl_output *output) {
|
||||||
auto& monitor = monitors.emplace_back(name, output);
|
auto& m = monitors.emplace_back(Monitor {name, wl_unique_ptr<wl_output> {output}});
|
||||||
if (dwlWm) {
|
if (ready) {
|
||||||
setupOutput(monitor);
|
setupMonitor(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,10 +165,9 @@ static void onReady()
|
||||||
requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1");
|
requireGlobal(dwlWm, "znet_tapesoftware_dwl_wm_v1");
|
||||||
setupStatusFifo();
|
setupStatusFifo();
|
||||||
wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
|
wl_display_roundtrip(display); // roundtrip so we receive all dwl tags etc.
|
||||||
|
ready = true;
|
||||||
for (auto& monitor : monitors) {
|
for (auto& monitor : monitors) {
|
||||||
auto monitor = znet_tapesoftware_dwl_wm_v1_get_monitor(dwlWm, output);
|
setupMonitor(monitor);
|
||||||
printf("created monitor %p for output %p\n", monitor, output);
|
|
||||||
bar.emplace(output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +209,10 @@ static void onStatus()
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
auto n = read(statusFifoFd, buffer, sizeof(buffer));
|
auto n = read(statusFifoFd, buffer, sizeof(buffer));
|
||||||
auto str = QString::fromUtf8(buffer, n);
|
auto str = QString::fromUtf8(buffer, n);
|
||||||
if (bar) {
|
for (auto &monitor : monitors) {
|
||||||
bar->setStatus(str);
|
if (monitor.bar) {
|
||||||
|
monitor.bar->setStatus(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,13 +243,23 @@ static void registryHandleGlobal(void*, wl_registry *registry, uint32_t name, co
|
||||||
wl_seat_add_listener(seat, &seatListener, nullptr);
|
wl_seat_add_listener(seat, &seatListener, nullptr);
|
||||||
}
|
}
|
||||||
if (wl_output *output; reg.handle(output, wl_output_interface, 1)) {
|
if (wl_output *output; reg.handle(output, wl_output_interface, 1)) {
|
||||||
outputs.push_back(output);
|
onOutput(name, output);
|
||||||
}
|
}
|
||||||
if (reg.handle(dwlWm, znet_tapesoftware_dwl_wm_v1_interface, 1)) {
|
if (reg.handle(dwlWm, znet_tapesoftware_dwl_wm_v1_interface, 1)) {
|
||||||
znet_tapesoftware_dwl_wm_v1_add_listener(dwlWm, &dwlWmListener, nullptr);
|
znet_tapesoftware_dwl_wm_v1_add_listener(dwlWm, &dwlWmListener, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static const struct wl_registry_listener registry_listener = { registryHandleGlobal, nullptr };
|
static void registryHandleRemove(void*, wl_registry *registry, uint32_t name)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(begin(monitors), end(monitors), [name](const Monitor &m) { return m.name == name; });
|
||||||
|
if (it != end(monitors)) {
|
||||||
|
monitors.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
.global = registryHandleGlobal,
|
||||||
|
.global_remove = registryHandleRemove,
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -273,7 +296,14 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
QSocketNotifier displayReadNotifier(wl_display_get_fd(display), QSocketNotifier::Read);
|
QSocketNotifier displayReadNotifier(wl_display_get_fd(display), QSocketNotifier::Read);
|
||||||
displayReadNotifier.setEnabled(true);
|
displayReadNotifier.setEnabled(true);
|
||||||
QObject::connect(&displayReadNotifier, &QSocketNotifier::activated, [=]() { wl_display_dispatch(display); });
|
QObject::connect(&displayReadNotifier, &QSocketNotifier::activated, [=]() {
|
||||||
|
auto res = wl_display_dispatch(display);
|
||||||
|
if (res < 0) {
|
||||||
|
perror("wl_display_dispatch");
|
||||||
|
cleanup();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
displayWriteNotifier = new QSocketNotifier(wl_display_get_fd(display), QSocketNotifier::Write);
|
displayWriteNotifier = new QSocketNotifier(wl_display_get_fd(display), QSocketNotifier::Write);
|
||||||
displayWriteNotifier->setEnabled(false);
|
displayWriteNotifier->setEnabled(false);
|
||||||
QObject::connect(displayWriteNotifier, &QSocketNotifier::activated, waylandWriteReady);
|
QObject::connect(displayWriteNotifier, &QSocketNotifier::activated, waylandWriteReady);
|
||||||
|
|
|
@ -22,20 +22,21 @@ ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format)
|
||||||
close(fd);
|
close(fd);
|
||||||
for (auto i=0; i<n; i++) {
|
for (auto i=0; i<n; i++) {
|
||||||
auto offset = oneSize*i;
|
auto offset = oneSize*i;
|
||||||
auto buffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, format);
|
_buffers[i] = {
|
||||||
_buffers[i] = { ptr+offset, buffer };
|
ptr+offset,
|
||||||
|
wl_unique_ptr<wl_buffer> { wl_shm_pool_create_buffer(pool, offset, width, height, stride, format) },
|
||||||
|
};
|
||||||
}
|
}
|
||||||
wl_shm_pool_destroy(pool);
|
wl_shm_pool_destroy(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShmBuffer::~ShmBuffer()
|
ShmBuffer::~ShmBuffer()
|
||||||
{
|
{
|
||||||
munmap(_buffers[0].data, _totalSize);
|
if (_buffers[0].data) {
|
||||||
for (auto i=0; i<n; i++) {
|
munmap(_buffers[0].data, _totalSize);
|
||||||
wl_buffer_destroy(_buffers[i].buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* ShmBuffer::data() const { return _buffers[_current].data; }
|
uint8_t* ShmBuffer::data() const { return _buffers[_current].data; }
|
||||||
wl_buffer* ShmBuffer::buffer() const { return _buffers[_current].buffer; }
|
wl_buffer* ShmBuffer::buffer() const { return _buffers[_current].buffer.get(); }
|
||||||
void ShmBuffer::flip() { _current = 1-_current; }
|
void ShmBuffer::flip() { _current = 1-_current; }
|
||||||
|
|
|
@ -4,22 +4,29 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
// double buffered shm
|
// double buffered shm
|
||||||
// format is must be 32-bit
|
// format is must be 32-bit
|
||||||
class ShmBuffer {
|
class ShmBuffer {
|
||||||
struct Buf {
|
struct Buf {
|
||||||
uint8_t *data {nullptr};
|
uint8_t *data {nullptr};
|
||||||
wl_buffer *buffer {nullptr};
|
wl_unique_ptr<wl_buffer> buffer;
|
||||||
};
|
};
|
||||||
std::array<Buf, 2> _buffers;
|
std::array<Buf, 2> _buffers;
|
||||||
int _current {0};
|
int _current {0};
|
||||||
size_t _totalSize {0};
|
size_t _totalSize {0};
|
||||||
public:
|
public:
|
||||||
int width, height, stride;
|
int width, height, stride;
|
||||||
|
|
||||||
explicit ShmBuffer(int width, int height, wl_shm_format format);
|
explicit ShmBuffer(int width, int height, wl_shm_format format);
|
||||||
|
ShmBuffer(const ShmBuffer&) = delete;
|
||||||
|
ShmBuffer(ShmBuffer&&) = default;
|
||||||
|
ShmBuffer& operator=(const ShmBuffer&) = delete;
|
||||||
|
ShmBuffer& operator=(ShmBuffer&&) = default;
|
||||||
|
~ShmBuffer();
|
||||||
|
|
||||||
uint8_t* data() const;
|
uint8_t* data() const;
|
||||||
wl_buffer* buffer() const;
|
wl_buffer* buffer() const;
|
||||||
void flip();
|
void flip();
|
||||||
~ShmBuffer();
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue