summaryrefslogtreecommitdiff
path: root/libdecor/build
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2022-03-04 15:40:29 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2022-03-04 15:41:00 +0100
commit3718effc431f5622a23c55b254153efdfe4e72c4 (patch)
treed8a805870c6a3785022e2f52f0c3715410e29a37 /libdecor/build
parenta773fdc44bfb818f1830e9e48ba765881e68c942 (diff)
Add the Wayland platform to FLTK 1.4
Diffstat (limited to 'libdecor/build')
-rw-r--r--libdecor/build/Makefile80
-rw-r--r--libdecor/build/fl_libdecor-plugins.c348
-rw-r--r--libdecor/build/fl_libdecor.c127
3 files changed, 555 insertions, 0 deletions
diff --git a/libdecor/build/Makefile b/libdecor/build/Makefile
new file mode 100644
index 000000000..b64ac1561
--- /dev/null
+++ b/libdecor/build/Makefile
@@ -0,0 +1,80 @@
+#
+# Library Makefile for the Fast Light Tool Kit (FLTK).
+#
+# Copyright 2022 by Bill Spitzak and others.
+#
+# This library is free software. Distribution and use rights are outlined in
+# the file "COPYING" which should have been included with this file. If this
+# file is missing or damaged, see the license at:
+#
+# https://www.fltk.org/COPYING.php
+#
+# Please see the following page on how to report bugs and issues:
+#
+# https://www.fltk.org/bugs.php
+#
+
+include ../../makeinclude
+
+CFLAGS_DECOR = -I. -I../.. -I../../src -I../src -fPIC -D_GNU_SOURCE -DUSE_SYSTEM_LIBDECOR=0
+OBJECTS = fl_libdecor.o libdecor-cairo-blur.o fl_libdecor-plugins.o \
+ ../../src/xdg-decoration-protocol.o ../../src/xdg-shell-protocol.o \
+ ../../src/text-input-protocol.o cursor-settings.o os-compatibility.o
+PROTOCOLS = /usr/share/wayland-protocols
+
+all : demo egl
+
+depend:
+ : echo "libdecor/build: make depend..."
+
+fl_libdecor.o : fl_libdecor.c ../src/libdecor.c ../../src/xdg-shell-protocol.c ../../src/xdg-decoration-protocol.c ../../src/text-input-protocol.c
+ $(CC) $(CFLAGS) $(CFLAGS_DECOR) -c fl_libdecor.c -DLIBDECOR_PLUGIN_API_VERSION=1 -DLIBDECOR_PLUGIN_DIR=\"/usr/local/lib\"
+
+fl_libdecor-plugins.o : fl_libdecor-plugins.c ../src/plugins/cairo/libdecor-cairo.c
+ $(CC) $(CFLAGS) $(CFLAGS_DECOR) -c fl_libdecor-plugins.c -DLIBDECOR_PLUGIN_API_VERSION=1 -DLIBDECOR_PLUGIN_DIR=\"/usr/local/lib\"
+
+libdecor-cairo-blur.o : ../src/plugins/cairo/libdecor-cairo-blur.c
+ $(CC) $(CFLAGS_DECOR) -c ../src/plugins/cairo/libdecor-cairo-blur.c
+
+os-compatibility.o : ../src/os-compatibility.c
+ $(CC) $(CFLAGS_DECOR) -c ../src/os-compatibility.c
+
+cursor-settings.o : ../src/cursor-settings.c
+ $(CC) $(CFLAGS_DECOR) -c ../src/cursor-settings.c -DHAS_DBUS `pkg-config --cflags dbus-1`
+
+../../src/xdg-shell-protocol.c :
+ wayland-scanner private-code $(PROTOCOLS)/stable/xdg-shell/xdg-shell.xml \
+ ../../src/xdg-shell-protocol.c
+ wayland-scanner client-header $(PROTOCOLS)/stable/xdg-shell/xdg-shell.xml \
+ ../../src/xdg-shell-client-protocol.h
+
+../../src/xdg-decoration-protocol.c :
+ wayland-scanner private-code \
+ $(PROTOCOLS)/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml \
+ ../../src/xdg-decoration-protocol.c
+ wayland-scanner client-header \
+ $(PROTOCOLS)/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml \
+ ../../src/xdg-decoration-client-protocol.h
+
+../../src/text-input-protocol.c :
+ wayland-scanner private-code \
+ $(PROTOCOLS)/unstable/text-input/text-input-unstable-v3.xml \
+ ../../src/text-input-protocol.c
+ wayland-scanner client-header \
+ $(PROTOCOLS)/unstable/text-input/text-input-unstable-v3.xml \
+ ../../src/text-input-client-protocol.h
+
+demo : ../demo/demo.c $(OBJECTS)
+ $(CC) -o demo ../demo/demo.c -D_GNU_SOURCE -I../.. -I../src -I. -I../../src $(OBJECTS) $(LDLIBS) -lm -rdynamic -no-pie -Wl,--defsym=fl_libdecor_using_weston=0
+
+egl : ../demo/egl.c $(OBJECTS)
+ $(CC) -o egl ../demo/egl.c -D_GNU_SOURCE -I../.. -I../src -I. -I../../src $(OBJECTS) $(GLDLIBS) -lm -rdynamic -no-pie -Wl,--defsym=fl_libdecor_using_weston=0
+
+
+install:
+ echo "Nothing to install"
+
+uninstall:
+
+clean:
+ $(RM) *.o ../../src/xdg-*.c ../../src/xdg-*.h ../../src/xdg-*.o ../../src/text-input-* demo egl
diff --git a/libdecor/build/fl_libdecor-plugins.c b/libdecor/build/fl_libdecor-plugins.c
new file mode 100644
index 000000000..ff8d5a101
--- /dev/null
+++ b/libdecor/build/fl_libdecor-plugins.c
@@ -0,0 +1,348 @@
+//
+// Interface with the libdecor library for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2022 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+/* Support of interactions between FLTK and libdecor plugins, either dynamically
+ loaded by dlopen() or built-in FLTK.
+
+ Under USE_SYSTEM_LIBDECOR, the plugin can only be dynamically loaded.
+ Under ! USE_SYSTEM_LIBDECOR, it can be dynamically loaded from a directory
+ given in environment variable LIBDECOR_PLUGIN_DIR, or the built-in one is used.
+ */
+
+#include <dlfcn.h>
+#include <string.h>
+#include "../src/libdecor.h"
+#include "xdg-decoration-client-protocol.h"
+#include <pango/pangocairo.h>
+
+#if USE_SYSTEM_LIBDECOR
+#include "../src/libdecor-plugin.h"
+
+enum component {NONE};
+enum decoration_type {DECORATION_TYPE_NONE};
+
+struct buffer { // identical in libdecor-cairo.c and libdecor-gtk.c
+ struct wl_buffer *wl_buffer;
+ bool in_use;
+ bool is_detached;
+
+ void *data;
+ size_t data_size;
+ int width;
+ int height;
+ int scale;
+ int buffer_width;
+ int buffer_height;
+};
+
+#else // !USE_SYSTEM_LIBDECOR
+
+const struct libdecor_plugin_description *fl_libdecor_plugin_description = NULL;
+
+# ifdef HAVE_GTK
+# include <gtk/gtk.h>
+# include "../src/plugins/gtk/libdecor-gtk.c"
+# else
+# include "../src/plugins/cairo/libdecor-cairo.c"
+# undef libdecor_frame_set_min_content_size
+# endif // HAVE_GTK
+
+#endif // USE_SYSTEM_LIBDECOR
+
+
+#if USE_SYSTEM_LIBDECOR || HAVE_GTK
+/* these definitions derive from libdecor/src/plugins/cairo/libdecor-cairo.c */
+
+struct libdecor_plugin_cairo {
+ struct libdecor_plugin plugin;
+
+ struct wl_callback *globals_callback;
+ struct wl_callback *globals_callback_shm;
+
+ struct libdecor *context;
+
+ struct wl_registry *wl_registry;
+ struct wl_subcompositor *wl_subcompositor;
+ struct wl_compositor *wl_compositor;
+
+ struct wl_shm *wl_shm;
+ struct wl_callback *shm_callback;
+ bool has_argb;
+
+ struct wl_list visible_frame_list;
+ struct wl_list seat_list;
+ struct wl_list output_list;
+
+ char *cursor_theme_name;
+ int cursor_size;
+
+ PangoFontDescription *font;
+};
+
+enum composite_mode {
+ COMPOSITE_SERVER,
+ COMPOSITE_CLIENT,
+};
+
+struct border_component_cairo {
+ enum component type;
+
+ bool is_hidden;
+ bool opaque;
+
+ enum composite_mode composite_mode;
+ struct {
+ struct wl_surface *wl_surface;
+ struct wl_subsurface *wl_subsurface;
+ struct buffer *buffer;
+ struct wl_list output_list;
+ int scale;
+ } server;
+ struct {
+ cairo_surface_t *image;
+ struct border_component_cairo *parent_component;
+ } client;
+
+ struct wl_list child_components; /* border_component::link */
+ struct wl_list link; /* border_component::child_components */
+};
+
+struct libdecor_frame_cairo {
+ struct libdecor_frame frame;
+
+ struct libdecor_plugin_cairo *plugin_cairo;
+
+ int content_width;
+ int content_height;
+
+ enum decoration_type decoration_type;
+
+ enum libdecor_window_state window_state;
+
+ char *title;
+
+ enum libdecor_capabilities capabilities;
+
+ struct border_component_cairo *focus;
+ struct border_component_cairo *active;
+ struct border_component_cairo *grab;
+
+ bool shadow_showing;
+ struct border_component_cairo shadow;
+
+ struct {
+ bool is_showing;
+ struct border_component_cairo title;
+ struct border_component_cairo min;
+ struct border_component_cairo max;
+ struct border_component_cairo close;
+ } title_bar;
+
+ /* store pre-processed shadow tile */
+ cairo_surface_t *shadow_blur;
+
+ struct wl_list link;
+};
+#endif
+
+
+#if USE_SYSTEM_LIBDECOR || !HAVE_GTK
+
+/* Definitions derived from libdecor-gtk.c */
+
+typedef struct _GtkWidget GtkWidget;
+enum header_element { HDR_NONE };
+typedef enum { GTK_STATE_FLAG_NORMAL = 0 } GtkStateFlags;
+
+struct border_component_gtk {
+ enum component type;
+ struct wl_surface *wl_surface;
+ struct wl_subsurface *wl_subsurface;
+ struct buffer *buffer;
+ bool opaque;
+ struct wl_list output_list;
+ int scale;
+ struct wl_list child_components; /* border_component::link */
+ struct wl_list link; /* border_component::child_components */
+};
+
+struct header_element_data {
+ const char* name;
+ enum header_element type;
+ GtkWidget *widget;
+ GtkStateFlags state;
+};
+
+struct libdecor_frame_gtk {
+ struct libdecor_frame frame;
+ struct libdecor_plugin_gtk *plugin_gtk;
+ int content_width;
+ int content_height;
+ enum libdecor_window_state window_state;
+ enum decoration_type decoration_type;
+ char *title;
+ enum libdecor_capabilities capabilities;
+ struct border_component_gtk *active;
+ struct border_component_gtk *focus;
+ struct border_component_gtk *grab;
+ bool shadow_showing;
+ struct border_component_gtk shadow;
+ GtkWidget *window; /* offscreen window for rendering */
+ GtkWidget *header; /* header bar with widgets */
+ struct border_component_gtk headerbar;
+ struct header_element_data hdr_focus;
+ cairo_surface_t *shadow_blur;
+ struct wl_list link;
+};
+
+#endif // USE_SYSTEM_LIBDECOR || !HAVE_GTK
+
+/* these definitions are copied from libdecor/src/libdecor.c */
+
+struct libdecor_limits {
+ int min_width;
+ int min_height;
+ int max_width;
+ int max_height;
+};
+
+struct libdecor_frame_private {
+ int ref_count;
+ struct libdecor *context;
+ struct wl_surface *wl_surface;
+ struct libdecor_frame_interface *iface;
+ void *user_data;
+ struct xdg_surface *xdg_surface;
+ struct xdg_toplevel *xdg_toplevel;
+ struct zxdg_toplevel_decoration_v1 *toplevel_decoration;
+ bool pending_map;
+ struct {
+ char *app_id;
+ char *title;
+ struct libdecor_limits content_limits;
+ struct xdg_toplevel *parent;
+ } state;
+ struct libdecor_configuration *pending_configuration;
+ int content_width;
+ int content_height;
+ enum libdecor_window_state window_state;
+ enum zxdg_toplevel_decoration_v1_mode decoration_mode;
+ enum libdecor_capabilities capabilities;
+ struct libdecor_limits interactive_limits;
+ bool visible;
+};
+
+
+static unsigned char *gtk_titlebar_buffer(struct libdecor_frame *frame,
+ int *width, int *height, int *stride)
+{
+ struct libdecor_frame_gtk *lfg = (struct libdecor_frame_gtk *)frame;
+#if USE_SYSTEM_LIBDECOR || !HAVE_GTK
+ struct border_component_gtk *bc;
+#else
+ struct border_component *bc;
+#endif
+ bc = &lfg->headerbar;
+ struct buffer *buffer = bc->buffer;
+ *width = buffer->buffer_width;
+ *height = buffer->buffer_height;
+ *stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, buffer->buffer_width);
+ return (unsigned char*)buffer->data;
+}
+
+
+static unsigned char *cairo_titlebar_buffer(struct libdecor_frame *frame,
+ int *width, int *height, int *stride)
+{
+ struct libdecor_frame_cairo *lfc = (struct libdecor_frame_cairo *)frame;
+#if USE_SYSTEM_LIBDECOR || HAVE_GTK
+ struct border_component_cairo *bc = &lfc->title_bar.title;
+#else
+ struct border_component *bc = &lfc->title_bar.title;
+#endif
+ struct buffer *buffer = bc->server.buffer;
+ *width = buffer->buffer_width;
+ *height = buffer->buffer_height;
+ *stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, buffer->buffer_width);
+ return (unsigned char*)buffer->data;
+}
+
+
+/*
+ Although each plugin declares an exported global variable
+ LIBDECOR_EXPORT const struct libdecor_plugin_description libdecor_plugin_description;
+ these plugins are dlopen()'ed in libdecor.c without the RTLD_GLOBAL flag.
+ Consequently their symbols are not discovered by dlsym(RTLD_DEFAULT, "symbol-name").
+
+ Under USE_SYSTEM_LIBDECOR, we repeat the dlopen() for the same plugin
+ then dlsym() will report the address of libdecor_plugin_description.
+
+ Under !USE_SYSTEM_LIBDECOR, we compile fl_libdecor.c which modifies the dlopen()
+ to call dlsym(ld, "libdecor_plugin_description") just after the dlopen and memorizes
+ this address.
+
+ A plugin is loaded also if SSD.
+ KDE has its own size limit, similar to that of GDK plugin
+ */
+static const char *get_libdecor_plugin_description(struct libdecor_frame *frame) {
+ static const struct libdecor_plugin_description *plugin_description = NULL;
+ if (frame->priv->decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) {
+ return "Server-Side Decoration";
+ }
+ if (!plugin_description) {
+ #if USE_SYSTEM_LIBDECOR
+ char fname[PATH_MAX];
+ const char *dir = getenv("LIBDECOR_PLUGIN_DIR");
+ if (!dir) dir = LIBDECOR_PLUGIN_DIR;
+ sprintf(fname, "%s/libdecor-gtk.so", dir);
+ void *dl = dlopen(fname, RTLD_LAZY | RTLD_LOCAL);
+ if (!dl) {
+ sprintf(fname, "%s/libdecor-cairo.so", dir);
+ dl = dlopen(fname, RTLD_LAZY | RTLD_LOCAL);
+ }
+ if (dl) plugin_description = (const struct libdecor_plugin_description*)dlsym(dl, "libdecor_plugin_description");
+#else
+ plugin_description = fl_libdecor_plugin_description;
+ extern const struct libdecor_plugin_description libdecor_plugin_description;
+ if (!plugin_description) plugin_description = &libdecor_plugin_description;
+#endif
+ //if (plugin_description) puts(plugin_description->description);
+ }
+ return plugin_description ? plugin_description->description : NULL;
+}
+
+
+/*
+ FLTK-added utility function to give access to the pixel array representing
+ the titlebar of a window decorated by the cairo plugin of libdecor.
+ frame: a libdecor-defined pointer given by fl_xid(win)->frame (with Fl_Window *win);
+ *width, *height: returned assigned to the width and height in pixels of the titlebar;
+ *stride: returned assigned to the number of bytes per line of the pixel array;
+ return value: start of the pixel array, which is in BGRA order, or NULL.
+ */
+unsigned char *fl_libdecor_titlebar_buffer(struct libdecor_frame *frame,
+ int *width, int *height, int *stride)
+{
+ static const char *my_plugin = NULL;
+ if (!my_plugin) my_plugin = get_libdecor_plugin_description(frame);
+ if (my_plugin && !strcmp(my_plugin, "GTK plugin")) {
+ return gtk_titlebar_buffer(frame, width, height, stride);
+ }
+ else if (my_plugin && !strcmp(my_plugin, "libdecor plugin using Cairo")) {
+ return cairo_titlebar_buffer(frame, width, height, stride);
+ }
+ return NULL;
+}
diff --git a/libdecor/build/fl_libdecor.c b/libdecor/build/fl_libdecor.c
new file mode 100644
index 000000000..a09155566
--- /dev/null
+++ b/libdecor/build/fl_libdecor.c
@@ -0,0 +1,127 @@
+//
+// Interface with the libdecor library for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2022 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+/* Improvements to libdecor.c without modifying libdecor.c itself */
+
+#define libdecor_frame_set_minimized libdecor_frame_set_minimized_orig
+#define libdecor_new libdecor_new_orig
+#include <dlfcn.h>
+static void *dlopen_corrected(const char *, int);
+#define dlopen(A, B) dlopen_corrected(A, B)
+#include "../src/libdecor.c"
+#undef dlopen
+#undef libdecor_frame_set_minimized
+#undef libdecor_new
+
+extern bool fl_libdecor_using_weston(void);
+extern const struct libdecor_plugin_description *fl_libdecor_plugin_description;
+//#include <stdio.h>
+
+// we have a built-in plugin so don't need a fallback one
+struct libdecor_plugin *libdecor_fallback_plugin_new(struct libdecor *context) {
+ return NULL;
+}
+
+// see get_libdecor_plugin_description() explaining why this is useful
+static void *dlopen_corrected(const char *filename, int flags) {
+ static int best_priority = -1;
+ void *retval = dlopen(filename, flags);
+ if (retval) {
+ const struct libdecor_plugin_description *description =
+ (const struct libdecor_plugin_description*)dlsym(retval, "libdecor_plugin_description");
+ if (description && description->priorities->priority > best_priority) {
+ fl_libdecor_plugin_description = description;
+ best_priority = description->priorities->priority;
+ }
+ }
+ return retval;
+}
+
+
+LIBDECOR_EXPORT void libdecor_frame_set_minimized(struct libdecor_frame *frame)
+{
+ static bool done = false;
+ static bool using_weston = false;
+ if (!done) {
+ typedef bool (*ext_f)(void);
+ volatile ext_f ext = fl_libdecor_using_weston;
+ done = true;
+ if (ext) using_weston = fl_libdecor_using_weston();
+//fprintf(stderr, "fl_libdecor_using_weston=%p using_weston=%d\n", fl_libdecor_using_weston, using_weston);
+ if (using_weston) { // determine the version of the running Weston compositor
+ FILE *pipe = popen("weston --version", "r");
+ if (pipe) {
+ char line[50], *p;
+ int version = 0;
+ p = fgets(line, sizeof(line), pipe);
+ pclose(pipe);
+ if (p) p = strchr(line, ' ');
+ if (p) {
+ sscanf(p, "%d", &version);
+ // Weston version 10 has fixed the bug handled here
+ if (version >= 10) using_weston = false;
+ }
+ }
+ }
+ }
+ if (using_weston) libdecor_frame_set_visibility(frame, false);
+ libdecor_frame_set_minimized_orig(frame);
+}
+
+
+/*
+ By default, FLTK modifies libdecor's libdecor_new() function to determine the plugin as follows :
+ 1) the directory pointed by environment variable LIBDECOR_PLUGIN_DIR or, in absence of this variable,
+ by -DLIBDECOR_PLUGIN_DIR=xxx at build time is searched for a libdecor plugin;
+ 2) if this directory does not exist or contains no plugin, the built-in plugin is used.
+ * if FLTK was built with package libgtk-3-dev, the GTK plugin is used
+ * if FLTK was built without package libgtk-3-dev, the Cairo plugin is used
+
+ If FLTK was built with OPTION_USE_SYSTEM_LIBDECOR turned ON, the present modification
+ isn't compiled, so the plugin-searching algorithm of libdecor_new() in libdecor-0.so is used.
+ This corresponds to step 1) above and to use no titlebar is no plugin is found.
+
+ N.B.: only the system package is built with a meaningful value of -DLIBDECOR_PLUGIN_DIR=
+ so a plugin may be loaded that way only if FLTK was built with OPTION_USE_SYSTEM_LIBDECOR turned ON.
+
+ */
+LIBDECOR_EXPORT struct libdecor *libdecor_new(struct wl_display *wl_display, struct libdecor_interface *iface)
+{
+ struct libdecor *context;
+ context = zalloc(sizeof *context);
+ context->ref_count = 1;
+ context->iface = iface;
+ context->wl_display = wl_display;
+ context->wl_registry = wl_display_get_registry(wl_display);
+ wl_registry_add_listener(context->wl_registry, &registry_listener, context);
+ context->init_callback = wl_display_sync(context->wl_display);
+ wl_callback_add_listener(context->init_callback, &init_wl_display_callback_listener, context);
+ wl_list_init(&context->frames);
+ // attempt to dynamically load a libdecor plugin with dlopen()
+ FILE *old_stderr = stderr;
+ stderr = fopen("/dev/null", "w+"); // avoid "Couldn't open plugin directory" messages
+ if (init_plugins(context) != 0) { // attempt to load plugin by dlopen()
+ // no plug-in was found by dlopen(), use built-in plugin instead
+ // defined in the source code of the built-in plugin: libdecor-cairo.c or libdecor-gtk.c
+ extern const struct libdecor_plugin_description libdecor_plugin_description;
+ context->plugin = libdecor_plugin_description.constructor(context);
+ }
+ fclose(stderr); // restore stderr as it was before
+ stderr = old_stderr;
+
+ wl_display_flush(wl_display);
+ return context;
+}