|
|
|
@ -28,20 +28,20 @@
|
|
|
|
|
|
|
|
|
|
#ifdef BUILD_WAYLAND
|
|
|
|
|
#include <wayland-client.h>
|
|
|
|
|
//#include "wayland.h"
|
|
|
|
|
#include <pango/pangocairo.h>
|
|
|
|
|
#include <pango/pangofc-fontmap.h>
|
|
|
|
|
// #include "wayland.h"
|
|
|
|
|
#include <cairo.h>
|
|
|
|
|
#include <fontconfig/fontconfig.h>
|
|
|
|
|
#include <pango/pangocairo.h>
|
|
|
|
|
#include <pango/pangofc-fontmap.h>
|
|
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <sys/epoll.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <sys/timerfd.h>
|
|
|
|
|
|
|
|
|
|
#include <wayland-client-protocol.h>
|
|
|
|
|
#include <xdg-shell-client-protocol.h>
|
|
|
|
|
#include <wlr-layer-shell-client-protocol.h>
|
|
|
|
|
#include <xdg-shell-client-protocol.h>
|
|
|
|
|
|
|
|
|
|
#endif /* BUILD_WAYLAND */
|
|
|
|
|
|
|
|
|
@ -50,8 +50,8 @@
|
|
|
|
|
|
|
|
|
|
#include "conky.h"
|
|
|
|
|
#include "display-wayland.hh"
|
|
|
|
|
#include "llua.h"
|
|
|
|
|
#include "gui.h"
|
|
|
|
|
#include "llua.h"
|
|
|
|
|
#ifdef BUILD_X11
|
|
|
|
|
#include "x11.h"
|
|
|
|
|
#endif
|
|
|
|
@ -64,20 +64,15 @@
|
|
|
|
|
/* TODO: cleanup global namespace */
|
|
|
|
|
#ifdef BUILD_WAYLAND
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
set_cloexec_or_close(int fd)
|
|
|
|
|
{
|
|
|
|
|
static int set_cloexec_or_close(int fd) {
|
|
|
|
|
long flags;
|
|
|
|
|
|
|
|
|
|
if (fd == -1)
|
|
|
|
|
return -1;
|
|
|
|
|
if (fd == -1) return -1;
|
|
|
|
|
|
|
|
|
|
flags = fcntl(fd, F_GETFD);
|
|
|
|
|
if (flags == -1)
|
|
|
|
|
goto err;
|
|
|
|
|
if (flags == -1) goto err;
|
|
|
|
|
|
|
|
|
|
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
|
|
|
|
goto err;
|
|
|
|
|
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) goto err;
|
|
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
|
|
|
|
|
@ -86,15 +81,12 @@ err:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
create_tmpfile_cloexec(char *tmpname)
|
|
|
|
|
{
|
|
|
|
|
static int create_tmpfile_cloexec(char *tmpname) {
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_MKOSTEMP
|
|
|
|
|
fd = mkostemp(tmpname, O_CLOEXEC);
|
|
|
|
|
if (fd >= 0)
|
|
|
|
|
unlink(tmpname);
|
|
|
|
|
if (fd >= 0) unlink(tmpname);
|
|
|
|
|
#else
|
|
|
|
|
fd = mkstemp(tmpname);
|
|
|
|
|
if (fd >= 0) {
|
|
|
|
@ -127,9 +119,7 @@ create_tmpfile_cloexec(char *tmpname)
|
|
|
|
|
* If posix_fallocate() is not supported, program may receive
|
|
|
|
|
* SIGBUS on accessing mmap()'ed file contents instead.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
os_create_anonymous_file(off_t size)
|
|
|
|
|
{
|
|
|
|
|
static int os_create_anonymous_file(off_t size) {
|
|
|
|
|
static const char templ[] = "/weston-shared-XXXXXX";
|
|
|
|
|
const char *path;
|
|
|
|
|
char *name;
|
|
|
|
@ -142,9 +132,8 @@ os_create_anonymous_file(off_t size)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name = static_cast<char*>(malloc(strlen(path) + sizeof(templ)));
|
|
|
|
|
if (!name)
|
|
|
|
|
return -1;
|
|
|
|
|
name = static_cast<char *>(malloc(strlen(path) + sizeof(templ)));
|
|
|
|
|
if (!name) return -1;
|
|
|
|
|
|
|
|
|
|
strcpy(name, path);
|
|
|
|
|
strcat(name, templ);
|
|
|
|
@ -153,8 +142,7 @@ os_create_anonymous_file(off_t size)
|
|
|
|
|
|
|
|
|
|
free(name);
|
|
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
if (fd < 0) return -1;
|
|
|
|
|
ret = posix_fallocate(fd, 0, size);
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
close(fd);
|
|
|
|
@ -189,12 +177,7 @@ struct pango_font {
|
|
|
|
|
} metrics;
|
|
|
|
|
int font_alpha;
|
|
|
|
|
|
|
|
|
|
pango_font()
|
|
|
|
|
: desc(nullptr),
|
|
|
|
|
metrics({0, 0}),
|
|
|
|
|
font_alpha(0xffff)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
pango_font() : desc(nullptr), metrics({0, 0}), font_alpha(0xffff) {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static std::vector<pango_font> pango_fonts; /* indexed by selected_font */
|
|
|
|
@ -235,11 +218,11 @@ static void wayland_create_window() {
|
|
|
|
|
#ifdef OWN_WINDOW
|
|
|
|
|
if (own_window.get(*state)) {
|
|
|
|
|
if (fixed_pos == 0) {
|
|
|
|
|
//XMoveWindow(display, window.window, window.x, window.y);
|
|
|
|
|
//TODO
|
|
|
|
|
// XMoveWindow(display, window.window, window.x, window.y);
|
|
|
|
|
// TODO
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//set_transparent_background(window.window);
|
|
|
|
|
// set_transparent_background(window.window);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -255,7 +238,8 @@ namespace {
|
|
|
|
|
#ifdef BUILD_WAYLAND
|
|
|
|
|
conky::display_output_wayland wayland_output;
|
|
|
|
|
#else
|
|
|
|
|
conky::disabled_display_output wayland_output_disabled("wayland", "BUILD_WAYLAND");
|
|
|
|
|
conky::disabled_display_output wayland_output_disabled("wayland",
|
|
|
|
|
"BUILD_WAYLAND");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
@ -265,7 +249,8 @@ namespace priv {} // namespace priv
|
|
|
|
|
|
|
|
|
|
#ifdef BUILD_WAYLAND
|
|
|
|
|
|
|
|
|
|
display_output_wayland::display_output_wayland() : display_output_base("wayland") {
|
|
|
|
|
display_output_wayland::display_output_wayland()
|
|
|
|
|
: display_output_base("wayland") {
|
|
|
|
|
is_graphical = true;
|
|
|
|
|
priority = 2;
|
|
|
|
|
}
|
|
|
|
@ -297,7 +282,7 @@ struct window {
|
|
|
|
|
cairo_surface_t *cairo_surface;
|
|
|
|
|
cairo_t *cr;
|
|
|
|
|
PangoLayout *layout;
|
|
|
|
|
PangoContext* pango_context;
|
|
|
|
|
PangoContext *pango_context;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
@ -306,46 +291,36 @@ struct {
|
|
|
|
|
struct wl_shm *shm;
|
|
|
|
|
struct wl_surface *surface;
|
|
|
|
|
struct wl_seat *seat;
|
|
|
|
|
/* struct wl_pointer *pointer;*/
|
|
|
|
|
/* struct wl_pointer *pointer;*/
|
|
|
|
|
struct wl_output *output;
|
|
|
|
|
struct xdg_wm_base *shell;
|
|
|
|
|
struct zwlr_layer_shell_v1 *layer_shell;
|
|
|
|
|
} wl_globals;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
|
|
|
|
|
{
|
|
|
|
|
static void xdg_wm_base_ping(void *data, struct xdg_wm_base *shell,
|
|
|
|
|
uint32_t serial) {
|
|
|
|
|
xdg_wm_base_pong(shell, serial);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
|
|
|
|
/*.ping =*/ &xdg_wm_base_ping,
|
|
|
|
|
/*.ping =*/&xdg_wm_base_ping,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void output_geometry(void *data, struct wl_output *wl_output, int32_t x,
|
|
|
|
|
int32_t y, int32_t physical_width,
|
|
|
|
|
int32_t physical_height, int32_t subpixel,
|
|
|
|
|
const char *make, const char *model,
|
|
|
|
|
int32_t transform) {}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y,
|
|
|
|
|
int32_t physical_width, int32_t physical_height,
|
|
|
|
|
int32_t subpixel, const char *make, const char *model,
|
|
|
|
|
int32_t transform)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
|
|
|
|
|
int32_t width, int32_t height, int32_t refresh)
|
|
|
|
|
{}
|
|
|
|
|
static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
|
|
|
|
|
int32_t width, int32_t height, int32_t refresh) {}
|
|
|
|
|
|
|
|
|
|
#ifdef WL_OUTPUT_DONE_SINCE_VERSION
|
|
|
|
|
static void
|
|
|
|
|
output_done(void *data, struct wl_output *wl_output)
|
|
|
|
|
{}
|
|
|
|
|
static void output_done(void *data, struct wl_output *wl_output) {}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WL_OUTPUT_SCALE_SINCE_VERSION
|
|
|
|
|
void
|
|
|
|
|
output_scale(void *data, struct wl_output *wl_output, int32_t factor)
|
|
|
|
|
{
|
|
|
|
|
void output_scale(void *data, struct wl_output *wl_output, int32_t factor) {
|
|
|
|
|
/* For now, assume we have one output and adopt its scale unconditionally. */
|
|
|
|
|
/* We should also re-render immediately when scale changes. */
|
|
|
|
|
global_window->scale = factor;
|
|
|
|
@ -353,110 +328,101 @@ output_scale(void *data, struct wl_output *wl_output, int32_t factor)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
|
|
|
|
static void
|
|
|
|
|
output_name(void *data, struct wl_output *wl_output, const char *name)
|
|
|
|
|
{}
|
|
|
|
|
static void output_name(void *data, struct wl_output *wl_output,
|
|
|
|
|
const char *name) {}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef WL_OUTPUT_DESCRIPTION_SINCE_VERSION
|
|
|
|
|
static void
|
|
|
|
|
output_description(void *data, struct wl_output *wl_output,
|
|
|
|
|
const char *description)
|
|
|
|
|
{}
|
|
|
|
|
static void output_description(void *data, struct wl_output *wl_output,
|
|
|
|
|
const char *description) {}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
const struct wl_output_listener output_listener = {
|
|
|
|
|
/*.geometry =*/ output_geometry,
|
|
|
|
|
/*.mode =*/ output_mode,
|
|
|
|
|
#ifdef WL_OUTPUT_DONE_SINCE_VERSION
|
|
|
|
|
/*.done =*/ output_done,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef WL_OUTPUT_SCALE_SINCE_VERSION
|
|
|
|
|
/*.scale =*/ &output_scale,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
|
|
|
|
/*.name =*/ &output_name,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef WL_OUTPUT_DESCRIPTION_SINCE_VERSION
|
|
|
|
|
/*.description =*/ &output_description,
|
|
|
|
|
#endif
|
|
|
|
|
/*.geometry =*/output_geometry,
|
|
|
|
|
/*.mode =*/output_mode,
|
|
|
|
|
#ifdef WL_OUTPUT_DONE_SINCE_VERSION
|
|
|
|
|
/*.done =*/output_done,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef WL_OUTPUT_SCALE_SINCE_VERSION
|
|
|
|
|
/*.scale =*/&output_scale,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
|
|
|
|
|
/*.name =*/&output_name,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef WL_OUTPUT_DESCRIPTION_SINCE_VERSION
|
|
|
|
|
/*.description =*/&output_description,
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
|
|
|
|
|
const char *interface, uint32_t version) {
|
|
|
|
|
if(strcmp(interface, "wl_compositor") == 0) {
|
|
|
|
|
wl_globals.compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name,
|
|
|
|
|
&wl_compositor_interface, 3));
|
|
|
|
|
} else if(strcmp(interface, "wl_shm") == 0) {
|
|
|
|
|
wl_globals.shm = static_cast<wl_shm*>(wl_registry_bind(registry, name, &wl_shm_interface, 1));
|
|
|
|
|
} else if(strcmp(interface, "wl_seat") == 0) {
|
|
|
|
|
wl_globals.seat = static_cast<wl_seat*>(wl_registry_bind(registry, name,
|
|
|
|
|
&wl_seat_interface, 1));
|
|
|
|
|
} else if(strcmp(interface, "wl_output") == 0) {
|
|
|
|
|
wl_globals.output = static_cast<wl_output*>(wl_registry_bind(registry, name, &wl_output_interface, 2));
|
|
|
|
|
void registry_handle_global(void *data, struct wl_registry *registry,
|
|
|
|
|
uint32_t name, const char *interface,
|
|
|
|
|
uint32_t version) {
|
|
|
|
|
if (strcmp(interface, "wl_compositor") == 0) {
|
|
|
|
|
wl_globals.compositor = static_cast<wl_compositor *>(
|
|
|
|
|
wl_registry_bind(registry, name, &wl_compositor_interface, 3));
|
|
|
|
|
} else if (strcmp(interface, "wl_shm") == 0) {
|
|
|
|
|
wl_globals.shm = static_cast<wl_shm *>(
|
|
|
|
|
wl_registry_bind(registry, name, &wl_shm_interface, 1));
|
|
|
|
|
} else if (strcmp(interface, "wl_seat") == 0) {
|
|
|
|
|
wl_globals.seat = static_cast<wl_seat *>(
|
|
|
|
|
wl_registry_bind(registry, name, &wl_seat_interface, 1));
|
|
|
|
|
} else if (strcmp(interface, "wl_output") == 0) {
|
|
|
|
|
wl_globals.output = static_cast<wl_output *>(
|
|
|
|
|
wl_registry_bind(registry, name, &wl_output_interface, 2));
|
|
|
|
|
wl_output_add_listener(wl_globals.output, &output_listener, nullptr);
|
|
|
|
|
} else if(strcmp(interface, "xdg_wm_base") == 0) {
|
|
|
|
|
wl_globals.shell = static_cast<xdg_wm_base*>(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1));
|
|
|
|
|
} else if (strcmp(interface, "xdg_wm_base") == 0) {
|
|
|
|
|
wl_globals.shell = static_cast<xdg_wm_base *>(
|
|
|
|
|
wl_registry_bind(registry, name, &xdg_wm_base_interface, 1));
|
|
|
|
|
xdg_wm_base_add_listener(wl_globals.shell, &xdg_wm_base_listener, nullptr);
|
|
|
|
|
} else if(strcmp(interface, "zwlr_layer_shell_v1") == 0) {
|
|
|
|
|
wl_globals.layer_shell = static_cast<zwlr_layer_shell_v1*>(wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1));
|
|
|
|
|
} else if (strcmp(interface, "zwlr_layer_shell_v1") == 0) {
|
|
|
|
|
wl_globals.layer_shell = static_cast<zwlr_layer_shell_v1 *>(
|
|
|
|
|
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void registry_handle_global_remove(void *data, struct wl_registry *registry,
|
|
|
|
|
uint32_t name) {}
|
|
|
|
|
|
|
|
|
|
static const struct wl_registry_listener registry_listener = {
|
|
|
|
|
registry_handle_global,
|
|
|
|
|
registry_handle_global_remove
|
|
|
|
|
};
|
|
|
|
|
registry_handle_global, registry_handle_global_remove};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *layer_surface,
|
|
|
|
|
uint32_t serial, uint32_t width, uint32_t height)
|
|
|
|
|
{
|
|
|
|
|
static void layer_surface_configure(void *data,
|
|
|
|
|
struct zwlr_layer_surface_v1 *layer_surface,
|
|
|
|
|
uint32_t serial, uint32_t width,
|
|
|
|
|
uint32_t height) {
|
|
|
|
|
zwlr_layer_surface_v1_ack_configure(layer_surface, serial);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *layer_surface)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
static void layer_surface_closed(void *data,
|
|
|
|
|
struct zwlr_layer_surface_v1 *layer_surface) {}
|
|
|
|
|
|
|
|
|
|
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
|
|
|
|
/*.configure =*/ &layer_surface_configure,
|
|
|
|
|
/*.closed =*/ &layer_surface_closed,
|
|
|
|
|
/*.configure =*/&layer_surface_configure,
|
|
|
|
|
/*.closed =*/&layer_surface_closed,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct window *
|
|
|
|
|
window_create(struct wl_surface* surface, struct wl_shm* shm, int width, int height);
|
|
|
|
|
struct window *window_create(struct wl_surface *surface, struct wl_shm *shm,
|
|
|
|
|
int width, int height);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_resize(struct window *window, int width, int height);
|
|
|
|
|
void window_resize(struct window *window, int width, int height);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_allocate_buffer(struct window *window);
|
|
|
|
|
void window_allocate_buffer(struct window *window);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_destroy(struct window *window);
|
|
|
|
|
void window_destroy(struct window *window);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_commit_buffer(struct window *window);
|
|
|
|
|
void window_commit_buffer(struct window *window);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_get_width_height(struct window *window, int *w, int *h);
|
|
|
|
|
void window_get_width_height(struct window *window, int *w, int *h);
|
|
|
|
|
|
|
|
|
|
void window_layer_surface_set_size(struct window *window) {
|
|
|
|
|
zwlr_layer_surface_v1_set_size(global_window->layer_surface, global_window->rectangle.width, global_window->rectangle.height);
|
|
|
|
|
zwlr_layer_surface_v1_set_size(global_window->layer_surface,
|
|
|
|
|
global_window->rectangle.width,
|
|
|
|
|
global_window->rectangle.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool display_output_wayland::initialize() {
|
|
|
|
|
epoll_fd = epoll_create1(0);
|
|
|
|
|
if(epoll_fd < 0) {
|
|
|
|
|
if (epoll_fd < 0) {
|
|
|
|
|
perror("conky: epoll_create");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -471,15 +437,18 @@ bool display_output_wayland::initialize() {
|
|
|
|
|
|
|
|
|
|
wl_display_roundtrip(global_display);
|
|
|
|
|
|
|
|
|
|
struct wl_surface *surface = wl_compositor_create_surface(wl_globals.compositor);
|
|
|
|
|
struct wl_surface *surface =
|
|
|
|
|
wl_compositor_create_surface(wl_globals.compositor);
|
|
|
|
|
global_window = window_create(surface, wl_globals.shm, 1, 1);
|
|
|
|
|
global_window->scale = 1;
|
|
|
|
|
window_allocate_buffer(global_window);
|
|
|
|
|
|
|
|
|
|
global_window->layer_surface = zwlr_layer_shell_v1_get_layer_surface(wl_globals.layer_shell,
|
|
|
|
|
global_window->surface, nullptr, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "conky_namespace");
|
|
|
|
|
global_window->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
|
|
|
|
wl_globals.layer_shell, global_window->surface, nullptr,
|
|
|
|
|
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "conky_namespace");
|
|
|
|
|
window_layer_surface_set_size(global_window);
|
|
|
|
|
zwlr_layer_surface_v1_add_listener(global_window->layer_surface, &layer_surface_listener, nullptr);
|
|
|
|
|
zwlr_layer_surface_v1_add_listener(global_window->layer_surface,
|
|
|
|
|
&layer_surface_listener, nullptr);
|
|
|
|
|
|
|
|
|
|
wl_surface_set_buffer_scale(global_window->surface, global_window->scale);
|
|
|
|
|
wl_surface_commit(global_window->surface);
|
|
|
|
@ -489,15 +458,14 @@ bool display_output_wayland::initialize() {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef void (*display_global_handler_t)(struct display *display,
|
|
|
|
|
uint32_t name,
|
|
|
|
|
typedef void (*display_global_handler_t)(struct display *display, uint32_t name,
|
|
|
|
|
const char *interface,
|
|
|
|
|
uint32_t version, void *data);
|
|
|
|
|
typedef void (*display_output_handler_t)(struct output *output, void *data);
|
|
|
|
|
|
|
|
|
|
bool display_output_wayland::shutdown() { return false; }
|
|
|
|
|
|
|
|
|
|
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
|
|
|
|
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
|
|
|
|
|
|
|
|
|
|
static bool added = false;
|
|
|
|
|
|
|
|
|
@ -506,16 +474,15 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
wl_display_dispatch_pending(global_display);
|
|
|
|
|
wl_display_flush(global_display);
|
|
|
|
|
|
|
|
|
|
if (t < 0.0) {
|
|
|
|
|
t = 0.0;
|
|
|
|
|
}
|
|
|
|
|
if (t < 0.0) { t = 0.0; }
|
|
|
|
|
int ms = t * 1000;
|
|
|
|
|
|
|
|
|
|
/* add fd to epoll set the first time around */
|
|
|
|
|
if (!added) {
|
|
|
|
|
ep[0].events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLET;
|
|
|
|
|
ep[0].data.ptr = nullptr;
|
|
|
|
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, wl_display_get_fd(global_display), &ep[0]) == -1) {
|
|
|
|
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, wl_display_get_fd(global_display),
|
|
|
|
|
&ep[0]) == -1) {
|
|
|
|
|
perror("conky: epoll_ctl: add");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -542,7 +509,6 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
if (ep_count == 0) { update_text(); }
|
|
|
|
|
|
|
|
|
|
if (need_to_update != 0) {
|
|
|
|
|
|
|
|
|
|
need_to_update = 0;
|
|
|
|
|
selected_font = 0;
|
|
|
|
|
update_text_area();
|
|
|
|
@ -556,10 +522,8 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
int fixed_size = 0;
|
|
|
|
|
|
|
|
|
|
/* resize window if it isn't right size */
|
|
|
|
|
if ((fixed_size == 0) &&
|
|
|
|
|
(text_width + 2 * border_total != width ||
|
|
|
|
|
if ((fixed_size == 0) && (text_width + 2 * border_total != width ||
|
|
|
|
|
text_height + 2 * border_total != height)) {
|
|
|
|
|
|
|
|
|
|
/* clamp text_width to configured maximum */
|
|
|
|
|
if (maximum_width.get(*state)) {
|
|
|
|
|
int mw = global_window->scale * maximum_width.get(*state);
|
|
|
|
@ -576,13 +540,13 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
text_height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* move window if it isn't in right position */
|
|
|
|
|
#ifdef POSITION
|
|
|
|
|
/* move window if it isn't in right position */
|
|
|
|
|
#ifdef POSITION
|
|
|
|
|
if ((fixed_pos == 0) && (window.x != wx || window.y != wy)) {
|
|
|
|
|
//XMoveWindow(display, window.window, window.x, window.y);
|
|
|
|
|
// XMoveWindow(display, window.window, window.x, window.y);
|
|
|
|
|
changed++;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* update struts */
|
|
|
|
|
if (changed != 0) {
|
|
|
|
@ -593,20 +557,24 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
|
|
|
|
|
switch (text_alignment.get(*state)) {
|
|
|
|
|
case TOP_LEFT:
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
|
|
|
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case TOP_RIGHT:
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
|
|
|
|
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case TOP_MIDDLE: {
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case BOTTOM_LEFT:
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
|
|
|
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case BOTTOM_RIGHT:
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
|
|
|
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
|
|
|
|
break;
|
|
|
|
|
case BOTTOM_MIDDLE: {
|
|
|
|
|
anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
|
|
|
@ -627,7 +595,9 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
|
|
|
|
|
if (anchor != -1) {
|
|
|
|
|
zwlr_layer_surface_v1_set_anchor(global_window->layer_surface, anchor);
|
|
|
|
|
zwlr_layer_surface_v1_set_margin(global_window->layer_surface, gap_y.get(*state), gap_x.get(*state), gap_y.get(*state), gap_x.get(*state));
|
|
|
|
|
zwlr_layer_surface_v1_set_margin(global_window->layer_surface,
|
|
|
|
|
gap_y.get(*state), gap_x.get(*state),
|
|
|
|
|
gap_y.get(*state), gap_x.get(*state));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -680,8 +650,7 @@ bool display_output_wayland::main_loop_wait(double t) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::sigterm_cleanup() {
|
|
|
|
|
}
|
|
|
|
|
void display_output_wayland::sigterm_cleanup() {}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::cleanup() {
|
|
|
|
|
if (global_window != nullptr) {
|
|
|
|
@ -702,7 +671,8 @@ void display_output_wayland::set_foreground_color(long c) {
|
|
|
|
|
uint8_t b = current_color >> 8;
|
|
|
|
|
uint8_t a = current_color;
|
|
|
|
|
if (global_window->cr) {
|
|
|
|
|
cairo_set_source_rgba(global_window->cr, r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
|
|
|
|
cairo_set_source_rgba(global_window->cr, r / 255.0, g / 255.0, b / 255.0,
|
|
|
|
|
a / 255.0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -711,12 +681,13 @@ int display_output_wayland::calc_text_width(const char *s) {
|
|
|
|
|
size_t slen = strlen(s);
|
|
|
|
|
pango_layout_set_text(window->layout, s, slen);
|
|
|
|
|
PangoRectangle margin_rect;
|
|
|
|
|
pango_layout_set_font_description(window->layout, pango_fonts[selected_font].desc);
|
|
|
|
|
pango_layout_set_font_description(window->layout,
|
|
|
|
|
pango_fonts[selected_font].desc);
|
|
|
|
|
pango_layout_get_pixel_extents(window->layout, nullptr, &margin_rect);
|
|
|
|
|
return margin_rect.width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void adjust_coords(int& x, int& y) {
|
|
|
|
|
static void adjust_coords(int &x, int &y) {
|
|
|
|
|
x -= text_start_x;
|
|
|
|
|
y -= text_start_y;
|
|
|
|
|
int border = get_border_total();
|
|
|
|
@ -724,7 +695,8 @@ static void adjust_coords(int& x, int& y) {
|
|
|
|
|
y += border;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::draw_string_at(int x, int y, const char *s, int w) {
|
|
|
|
|
void display_output_wayland::draw_string_at(int x, int y, const char *s,
|
|
|
|
|
int w) {
|
|
|
|
|
struct window *window = global_window;
|
|
|
|
|
y -= pango_fonts[selected_font].metrics.ascent;
|
|
|
|
|
adjust_coords(x, y);
|
|
|
|
@ -734,7 +706,8 @@ void display_output_wayland::draw_string_at(int x, int y, const char *s, int w)
|
|
|
|
|
uint8_t g = current_color >> 16;
|
|
|
|
|
uint8_t b = current_color >> 8;
|
|
|
|
|
unsigned int a = pango_fonts[selected_font].font_alpha;
|
|
|
|
|
cairo_set_source_rgba(global_window->cr, r / 255.0, g / 255.0, b / 255.0, a / 65535.);
|
|
|
|
|
cairo_set_source_rgba(global_window->cr, r / 255.0, g / 255.0, b / 255.0,
|
|
|
|
|
a / 65535.);
|
|
|
|
|
cairo_move_to(window->cr, x, y);
|
|
|
|
|
pango_cairo_show_layout(window->cr, window->layout);
|
|
|
|
|
cairo_restore(window->cr);
|
|
|
|
@ -743,7 +716,7 @@ void display_output_wayland::draw_string_at(int x, int y, const char *s, int w)
|
|
|
|
|
void display_output_wayland::set_line_style(int w, bool solid) {
|
|
|
|
|
struct window *window = global_window;
|
|
|
|
|
static double dashes[2] = {1.0, 1.0};
|
|
|
|
|
if(solid)
|
|
|
|
|
if (solid)
|
|
|
|
|
cairo_set_dash(window->cr, nullptr, 0, 0);
|
|
|
|
|
else
|
|
|
|
|
cairo_set_dash(window->cr, dashes, 2, 0);
|
|
|
|
@ -753,10 +726,8 @@ void display_output_wayland::set_line_style(int w, bool solid) {
|
|
|
|
|
void display_output_wayland::set_dashes(char *s) {
|
|
|
|
|
struct window *window = global_window;
|
|
|
|
|
size_t len = strlen(s);
|
|
|
|
|
double* dashes = new double[len];
|
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
|
|
|
dashes[i] = s[i];
|
|
|
|
|
}
|
|
|
|
|
double *dashes = new double[len];
|
|
|
|
|
for (size_t i = 0; i < len; i++) { dashes[i] = s[i]; }
|
|
|
|
|
cairo_set_dash(window->cr, dashes, len, 0);
|
|
|
|
|
delete[] dashes;
|
|
|
|
|
}
|
|
|
|
@ -797,7 +768,8 @@ void display_output_wayland::fill_rect(int x, int y, int w, int h) {
|
|
|
|
|
do_rect(x, y, w, h, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::draw_arc(int x, int y, int w, int h, int a1, int a2) {
|
|
|
|
|
void display_output_wayland::draw_arc(int x, int y, int w, int h, int a1,
|
|
|
|
|
int a2) {
|
|
|
|
|
struct window *window = global_window;
|
|
|
|
|
adjust_coords(x, y);
|
|
|
|
|
cairo_save(window->cr);
|
|
|
|
@ -811,14 +783,12 @@ void display_output_wayland::draw_arc(int x, int y, int w, int h, int a1, int a2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::move_win(int x, int y) {
|
|
|
|
|
//window.x = x;
|
|
|
|
|
//window.y = y;
|
|
|
|
|
//TODO
|
|
|
|
|
// window.x = x;
|
|
|
|
|
// window.y = y;
|
|
|
|
|
// TODO
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int display_output_wayland::dpi_scale(int value) {
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
int display_output_wayland::dpi_scale(int value) { return value; }
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::end_draw_stuff() {
|
|
|
|
|
window_commit_buffer(global_window);
|
|
|
|
@ -826,7 +796,7 @@ void display_output_wayland::end_draw_stuff() {
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::clear_text(int exposures) {
|
|
|
|
|
struct window *window = global_window;
|
|
|
|
|
cairo_save (window->cr);
|
|
|
|
|
cairo_save(window->cr);
|
|
|
|
|
long color = 0;
|
|
|
|
|
#ifdef OWN_WINDOW
|
|
|
|
|
color = background_colour.get(*state);
|
|
|
|
@ -844,50 +814,46 @@ void display_output_wayland::clear_text(int exposures) {
|
|
|
|
|
uint8_t g = color >> 16;
|
|
|
|
|
uint8_t b = color >> 8;
|
|
|
|
|
uint8_t a = color;
|
|
|
|
|
cairo_set_source_rgba (window->cr, r / 255.0, g / 255.0, b / 255.0, a / 255.);
|
|
|
|
|
cairo_set_operator (window->cr, CAIRO_OPERATOR_SOURCE);
|
|
|
|
|
cairo_paint (window->cr);
|
|
|
|
|
cairo_restore (window->cr);
|
|
|
|
|
cairo_set_source_rgba(window->cr, r / 255.0, g / 255.0, b / 255.0, a / 255.);
|
|
|
|
|
cairo_set_operator(window->cr, CAIRO_OPERATOR_SOURCE);
|
|
|
|
|
cairo_paint(window->cr);
|
|
|
|
|
cairo_restore(window->cr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int display_output_wayland::font_height(unsigned int f) {
|
|
|
|
|
if (pango_fonts.size() == 0) {
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
if (pango_fonts.size() == 0) { return 2; }
|
|
|
|
|
assert(f < pango_fonts.size());
|
|
|
|
|
return pango_fonts[f].metrics.ascent + pango_fonts[f].metrics.descent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int display_output_wayland::font_ascent(unsigned int f) {
|
|
|
|
|
if (pango_fonts.size() == 0) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (pango_fonts.size() == 0) { return 1; }
|
|
|
|
|
assert(f < pango_fonts.size());
|
|
|
|
|
return pango_fonts[f].metrics.ascent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int display_output_wayland::font_descent(unsigned int f) {
|
|
|
|
|
if (pango_fonts.size() == 0) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (pango_fonts.size() == 0) { return 1; }
|
|
|
|
|
assert(f < pango_fonts.size());
|
|
|
|
|
return pango_fonts[f].metrics.descent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::setup_fonts(void) {
|
|
|
|
|
/* Nothing to do here */
|
|
|
|
|
}
|
|
|
|
|
void display_output_wayland::setup_fonts(void) { /* Nothing to do here */ }
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::set_font(unsigned int f) {
|
|
|
|
|
assert(f < pango_fonts.size());
|
|
|
|
|
if (pango_fonts.size() > f && pango_fonts[f].desc != nullptr) {
|
|
|
|
|
pango_layout_set_font_description(global_window->layout, pango_fonts[f].desc);
|
|
|
|
|
pango_layout_set_font_description(global_window->layout,
|
|
|
|
|
pango_fonts[f].desc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void display_output_wayland::free_fonts(bool utf8) {
|
|
|
|
|
for (auto &font : pango_fonts) {
|
|
|
|
|
if (font.desc != nullptr) { pango_font_description_free(font.desc); font.desc = nullptr; }
|
|
|
|
|
if (font.desc != nullptr) {
|
|
|
|
|
pango_font_description_free(font.desc);
|
|
|
|
|
font.desc = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pango_fonts.clear();
|
|
|
|
|
}
|
|
|
|
@ -898,18 +864,25 @@ void display_output_wayland::load_fonts(bool utf8) {
|
|
|
|
|
for (unsigned int i = 0; i < fonts.size(); i++) {
|
|
|
|
|
auto &font = fonts[i];
|
|
|
|
|
auto &pango_font_entry = pango_fonts[i];
|
|
|
|
|
FcPattern* fc_pattern = FcNameParse(reinterpret_cast<const unsigned char*>(font.name.c_str()));
|
|
|
|
|
pango_font_entry.desc = pango_fc_font_description_from_pattern(fc_pattern, true);
|
|
|
|
|
FcPattern *fc_pattern =
|
|
|
|
|
FcNameParse(reinterpret_cast<const unsigned char *>(font.name.c_str()));
|
|
|
|
|
pango_font_entry.desc =
|
|
|
|
|
pango_fc_font_description_from_pattern(fc_pattern, true);
|
|
|
|
|
|
|
|
|
|
// Handle pixel size ourselves because pango_fc_font_description_from_pattern does not
|
|
|
|
|
// Handle pixel size ourselves because
|
|
|
|
|
// pango_fc_font_description_from_pattern does not
|
|
|
|
|
double pixel_size = -1;
|
|
|
|
|
if (FcPatternGetDouble (fc_pattern, FC_PIXEL_SIZE, 0, &pixel_size) == FcResultMatch) {
|
|
|
|
|
pango_font_description_set_absolute_size(pango_font_entry.desc, pixel_size * PANGO_SCALE);
|
|
|
|
|
if (FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &pixel_size) ==
|
|
|
|
|
FcResultMatch) {
|
|
|
|
|
pango_font_description_set_absolute_size(pango_font_entry.desc,
|
|
|
|
|
pixel_size * PANGO_SCALE);
|
|
|
|
|
}
|
|
|
|
|
FcPatternDestroy(fc_pattern);
|
|
|
|
|
|
|
|
|
|
PangoFont* pango_font = pango_context_load_font(global_window->pango_context, pango_font_entry.desc);
|
|
|
|
|
PangoFontMetrics* font_metrics = pango_font_get_metrics(pango_font, nullptr);
|
|
|
|
|
PangoFont *pango_font = pango_context_load_font(
|
|
|
|
|
global_window->pango_context, pango_font_entry.desc);
|
|
|
|
|
PangoFontMetrics *font_metrics =
|
|
|
|
|
pango_font_get_metrics(pango_font, nullptr);
|
|
|
|
|
auto ascent = pango_font_metrics_get_ascent(font_metrics) / PANGO_SCALE;
|
|
|
|
|
auto descent = pango_font_metrics_get_descent(font_metrics) / PANGO_SCALE;
|
|
|
|
|
pango_font_metrics_unref(font_metrics);
|
|
|
|
@ -920,7 +893,6 @@ void display_output_wayland::load_fonts(bool utf8) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct shm_pool {
|
|
|
|
|
struct wl_shm_pool *pool;
|
|
|
|
|
size_t size;
|
|
|
|
@ -935,40 +907,33 @@ struct shm_surface_data {
|
|
|
|
|
|
|
|
|
|
static const cairo_user_data_key_t shm_surface_data_key = {0};
|
|
|
|
|
|
|
|
|
|
struct wl_buffer *
|
|
|
|
|
get_buffer_from_cairo_surface(cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
struct wl_buffer *get_buffer_from_cairo_surface(cairo_surface_t *surface) {
|
|
|
|
|
struct shm_surface_data *data;
|
|
|
|
|
|
|
|
|
|
data = static_cast<struct shm_surface_data *>(cairo_surface_get_user_data(surface, &shm_surface_data_key));
|
|
|
|
|
data = static_cast<struct shm_surface_data *>(
|
|
|
|
|
cairo_surface_get_user_data(surface, &shm_surface_data_key));
|
|
|
|
|
|
|
|
|
|
return data->buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
shm_pool_destroy(struct shm_pool *pool);
|
|
|
|
|
static void shm_pool_destroy(struct shm_pool *pool);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
shm_surface_data_destroy(void *p)
|
|
|
|
|
{
|
|
|
|
|
static void shm_surface_data_destroy(void *p) {
|
|
|
|
|
struct shm_surface_data *data = static_cast<struct shm_surface_data *>(p);
|
|
|
|
|
wl_buffer_destroy(data->buffer);
|
|
|
|
|
if (data->pool)
|
|
|
|
|
shm_pool_destroy(data->pool);
|
|
|
|
|
if (data->pool) shm_pool_destroy(data->pool);
|
|
|
|
|
|
|
|
|
|
delete data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct wl_shm_pool *
|
|
|
|
|
make_shm_pool(struct wl_shm *shm, int size, void **data)
|
|
|
|
|
{
|
|
|
|
|
static struct wl_shm_pool *make_shm_pool(struct wl_shm *shm, int size,
|
|
|
|
|
void **data) {
|
|
|
|
|
struct wl_shm_pool *pool;
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
fd = os_create_anonymous_file(size);
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
|
|
|
|
|
size);
|
|
|
|
|
fprintf(stderr, "creating a buffer file for %d B failed: %m\n", size);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -986,13 +951,10 @@ make_shm_pool(struct wl_shm *shm, int size, void **data)
|
|
|
|
|
return pool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct shm_pool *
|
|
|
|
|
shm_pool_create(struct wl_shm *shm, size_t size)
|
|
|
|
|
{
|
|
|
|
|
static struct shm_pool *shm_pool_create(struct wl_shm *shm, size_t size) {
|
|
|
|
|
struct shm_pool *pool = new struct shm_pool;
|
|
|
|
|
|
|
|
|
|
if (!pool)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!pool) return NULL;
|
|
|
|
|
|
|
|
|
|
pool->pool = make_shm_pool(shm, size, &pool->data);
|
|
|
|
|
if (!pool->pool) {
|
|
|
|
@ -1006,46 +968,37 @@ shm_pool_create(struct wl_shm *shm, size_t size)
|
|
|
|
|
return pool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
shm_pool_allocate(struct shm_pool *pool, size_t size, int *offset)
|
|
|
|
|
{
|
|
|
|
|
if (pool->used + size > pool->size)
|
|
|
|
|
return NULL;
|
|
|
|
|
static void *shm_pool_allocate(struct shm_pool *pool, size_t size,
|
|
|
|
|
int *offset) {
|
|
|
|
|
if (pool->used + size > pool->size) return NULL;
|
|
|
|
|
|
|
|
|
|
*offset = pool->used;
|
|
|
|
|
pool->used += size;
|
|
|
|
|
|
|
|
|
|
return (char *) pool->data + *offset;
|
|
|
|
|
return (char *)pool->data + *offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* destroy the pool. this does not unmap the memory though */
|
|
|
|
|
static void
|
|
|
|
|
shm_pool_destroy(struct shm_pool *pool)
|
|
|
|
|
{
|
|
|
|
|
static void shm_pool_destroy(struct shm_pool *pool) {
|
|
|
|
|
munmap(pool->data, pool->size);
|
|
|
|
|
wl_shm_pool_destroy(pool->pool);
|
|
|
|
|
delete pool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
stride_for_shm_surface(struct rectangle *rect, int scale) {
|
|
|
|
|
return cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, rect->width * scale);
|
|
|
|
|
static int stride_for_shm_surface(struct rectangle *rect, int scale) {
|
|
|
|
|
return cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
|
|
|
|
|
rect->width * scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
data_length_for_shm_surface(struct rectangle *rect, int scale) {
|
|
|
|
|
static int data_length_for_shm_surface(struct rectangle *rect, int scale) {
|
|
|
|
|
int stride;
|
|
|
|
|
|
|
|
|
|
stride = stride_for_shm_surface(rect, scale);
|
|
|
|
|
return stride * rect->height * scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_surface_t *
|
|
|
|
|
create_shm_surface_from_pool(void *none,
|
|
|
|
|
struct rectangle *rectangle,
|
|
|
|
|
struct shm_pool *pool,
|
|
|
|
|
int scale)
|
|
|
|
|
{
|
|
|
|
|
static cairo_surface_t *create_shm_surface_from_pool(
|
|
|
|
|
void *none, struct rectangle *rectangle, struct shm_pool *pool, int scale) {
|
|
|
|
|
struct shm_surface_data *data;
|
|
|
|
|
uint32_t format;
|
|
|
|
|
cairo_surface_t *surface;
|
|
|
|
@ -1054,12 +1007,11 @@ create_shm_surface_from_pool(void *none,
|
|
|
|
|
void *map;
|
|
|
|
|
|
|
|
|
|
data = new struct shm_surface_data;
|
|
|
|
|
if (data == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (data == NULL) return NULL;
|
|
|
|
|
|
|
|
|
|
cairo_format = CAIRO_FORMAT_ARGB32; /*or CAIRO_FORMAT_RGB16_565 who knows??*/
|
|
|
|
|
|
|
|
|
|
stride = stride_for_shm_surface (rectangle, scale);
|
|
|
|
|
stride = stride_for_shm_surface(rectangle, scale);
|
|
|
|
|
length = data_length_for_shm_surface(rectangle, scale);
|
|
|
|
|
data->pool = NULL;
|
|
|
|
|
map = shm_pool_allocate(pool, length, &offset);
|
|
|
|
@ -1069,39 +1021,36 @@ create_shm_surface_from_pool(void *none,
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
surface = cairo_image_surface_create_for_data (static_cast<unsigned char*>(map),
|
|
|
|
|
cairo_format,
|
|
|
|
|
rectangle->width * scale,
|
|
|
|
|
rectangle->height * scale,
|
|
|
|
|
stride);
|
|
|
|
|
surface = cairo_image_surface_create_for_data(
|
|
|
|
|
static_cast<unsigned char *>(map), cairo_format, rectangle->width * scale,
|
|
|
|
|
rectangle->height * scale, stride);
|
|
|
|
|
|
|
|
|
|
cairo_surface_set_user_data(surface, &shm_surface_data_key,
|
|
|
|
|
data, shm_surface_data_destroy);
|
|
|
|
|
cairo_surface_set_user_data(surface, &shm_surface_data_key, data,
|
|
|
|
|
shm_surface_data_destroy);
|
|
|
|
|
|
|
|
|
|
format = WL_SHM_FORMAT_ARGB8888; /*or WL_SHM_FORMAT_RGB565*/
|
|
|
|
|
|
|
|
|
|
data->buffer = wl_shm_pool_create_buffer(pool->pool, offset,
|
|
|
|
|
rectangle->width * scale,
|
|
|
|
|
rectangle->height * scale,
|
|
|
|
|
stride, format);
|
|
|
|
|
data->buffer =
|
|
|
|
|
wl_shm_pool_create_buffer(pool->pool, offset, rectangle->width * scale,
|
|
|
|
|
rectangle->height * scale, stride, format);
|
|
|
|
|
|
|
|
|
|
return surface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_allocate_buffer(struct window *window) {
|
|
|
|
|
void window_allocate_buffer(struct window *window) {
|
|
|
|
|
assert(window->shm != nullptr);
|
|
|
|
|
struct shm_pool *pool;
|
|
|
|
|
pool = shm_pool_create(window->shm,
|
|
|
|
|
data_length_for_shm_surface(&window->rectangle, window->scale));
|
|
|
|
|
pool = shm_pool_create(window->shm, data_length_for_shm_surface(
|
|
|
|
|
&window->rectangle, window->scale));
|
|
|
|
|
if (!pool) {
|
|
|
|
|
fprintf(stderr, "could not allocate shm pool\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window->cairo_surface =
|
|
|
|
|
create_shm_surface_from_pool(window->shm, &window->rectangle, pool, window->scale);
|
|
|
|
|
cairo_surface_set_device_scale(window->cairo_surface, window->scale, window->scale);
|
|
|
|
|
window->cairo_surface = create_shm_surface_from_pool(
|
|
|
|
|
window->shm, &window->rectangle, pool, window->scale);
|
|
|
|
|
cairo_surface_set_device_scale(window->cairo_surface, window->scale,
|
|
|
|
|
window->scale);
|
|
|
|
|
|
|
|
|
|
if (!window->cairo_surface) {
|
|
|
|
|
shm_pool_destroy(pool);
|
|
|
|
@ -1114,12 +1063,13 @@ window_allocate_buffer(struct window *window) {
|
|
|
|
|
|
|
|
|
|
/* make sure we destroy the pool when the surface is destroyed */
|
|
|
|
|
struct shm_surface_data *data;
|
|
|
|
|
data = static_cast<struct shm_surface_data *>(cairo_surface_get_user_data(window->cairo_surface, &shm_surface_data_key));
|
|
|
|
|
data = static_cast<struct shm_surface_data *>(cairo_surface_get_user_data(
|
|
|
|
|
window->cairo_surface, &shm_surface_data_key));
|
|
|
|
|
data->pool = pool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct window *
|
|
|
|
|
window_create(struct wl_surface* surface, struct wl_shm* shm, int width, int height) {
|
|
|
|
|
struct window *window_create(struct wl_surface *surface, struct wl_shm *shm,
|
|
|
|
|
int width, int height) {
|
|
|
|
|
struct window *window;
|
|
|
|
|
window = new struct window;
|
|
|
|
|
|
|
|
|
@ -1140,8 +1090,7 @@ window_create(struct wl_surface* surface, struct wl_shm* shm, int width, int hei
|
|
|
|
|
return window;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_free_buffer(struct window* window) {
|
|
|
|
|
void window_free_buffer(struct window *window) {
|
|
|
|
|
cairo_surface_destroy(window->cairo_surface);
|
|
|
|
|
cairo_destroy(window->cr);
|
|
|
|
|
g_object_unref(window->layout);
|
|
|
|
@ -1152,8 +1101,7 @@ window_free_buffer(struct window* window) {
|
|
|
|
|
window->pango_context = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_destroy(struct window *window) {
|
|
|
|
|
void window_destroy(struct window *window) {
|
|
|
|
|
window_free_buffer(window);
|
|
|
|
|
zwlr_layer_surface_v1_destroy(window->layer_surface);
|
|
|
|
|
wl_surface_attach(window->surface, nullptr, 0, 0);
|
|
|
|
@ -1164,8 +1112,7 @@ window_destroy(struct window *window) {
|
|
|
|
|
delete window;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_resize(struct window *window, int width, int height) {
|
|
|
|
|
void window_resize(struct window *window, int width, int height) {
|
|
|
|
|
window_free_buffer(window);
|
|
|
|
|
window->rectangle.width = width;
|
|
|
|
|
window->rectangle.height = height;
|
|
|
|
@ -1173,21 +1120,19 @@ window_resize(struct window *window, int width, int height) {
|
|
|
|
|
window_layer_surface_set_size(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_commit_buffer(struct window *window) {
|
|
|
|
|
void window_commit_buffer(struct window *window) {
|
|
|
|
|
assert(window->cairo_surface != nullptr);
|
|
|
|
|
wl_surface_set_buffer_scale(global_window->surface, global_window->scale);
|
|
|
|
|
wl_surface_attach(window->surface, get_buffer_from_cairo_surface(window->cairo_surface), 0, 0);
|
|
|
|
|
/* repaint all the pixels in the surface, change size to only repaint changed area*/
|
|
|
|
|
wl_surface_damage(window->surface, window->rectangle.x,
|
|
|
|
|
window->rectangle.y,
|
|
|
|
|
window->rectangle.width,
|
|
|
|
|
window->rectangle.height);
|
|
|
|
|
wl_surface_attach(window->surface,
|
|
|
|
|
get_buffer_from_cairo_surface(window->cairo_surface), 0, 0);
|
|
|
|
|
/* repaint all the pixels in the surface, change size to only repaint changed
|
|
|
|
|
* area*/
|
|
|
|
|
wl_surface_damage(window->surface, window->rectangle.x, window->rectangle.y,
|
|
|
|
|
window->rectangle.width, window->rectangle.height);
|
|
|
|
|
wl_surface_commit(window->surface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
window_get_width_height(struct window *window, int *w, int *h) {
|
|
|
|
|
void window_get_width_height(struct window *window, int *w, int *h) {
|
|
|
|
|
*w = window->rectangle.width;
|
|
|
|
|
*h = window->rectangle.height;
|
|
|
|
|
}
|
|
|
|
|