summaryrefslogtreecommitdiff
path: root/libdecor/build/fl_libdecor.c
blob: c7105bd8561c66243d178230a84dccbbd7782e0f (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
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
142
143
144
145
//
// Interface with the libdecor library for the Fast Light Tool Kit (FLTK).
//
// Copyright 2022-2024 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 */
#if ! USE_SYSTEM_LIBDECOR

#include <dlfcn.h>
#include <stdlib.h>
static void *dlopen_corrected(const char *, int);
#define dlopen(A, B) dlopen_corrected(A, B)
#include "fl_libdecor.h"
#undef libdecor_new
#define libdecor_new libdecor_new_orig
#undef libdecor_frame_set_minimized
#define libdecor_frame_set_minimized libdecor_frame_set_minimized_orig
#include "../src/libdecor.c"
#undef dlopen
#undef libdecor_frame_set_minimized
#undef libdecor_new
#define libdecor_new fl_libdecor_new
#define libdecor_frame_set_minimized fl_libdecor_frame_set_minimized

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;
}


void fl_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 FLTK_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 FLTK_USE_SYSTEM_LIBDECOR turned ON.
 
 */
struct libdecor *fl_libdecor_new(struct wl_display *wl_display, const 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()
  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;
#if HAVE_GTK
    bool gdk_caution = false;
    if (getenv("GDK_BACKEND") && strcmp(getenv("GDK_BACKEND"), "x11") == 0) {
      // Environment variable GDK_BACKEND=x11 makes the .constructor below fail
      // for the built-in GTK plugin and then FLTK crashes (#1029).
      // Temporarily unset GDK_BACKEND to prevent that.
      gdk_caution = true;
      unsetenv("GDK_BACKEND");
    }
#endif
    context->plugin = libdecor_plugin_description.constructor(context);
#if HAVE_GTK
    if (gdk_caution) putenv("GDK_BACKEND=x11");
#endif
 }

  wl_display_flush(wl_display);
  return context;
}

#endif //! USE_SYSTEM_LIBDECOR