mirror of
https://github.com/fltk/fltk.git
synced 2026-02-06 00:01:57 +08:00
Add the Wayland platform to FLTK 1.4
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
Changes in FLTK 1.4.0 Released: ??? ?? 2021
|
||||
Changes in FLTK 1.4.0 Released: ??? ?? 2022
|
||||
|
||||
General Information about this Release
|
||||
|
||||
@@ -17,6 +17,8 @@ Changes in FLTK 1.4.0 Released: ??? ?? 2021
|
||||
|
||||
New Features and Extensions
|
||||
|
||||
- FLTK 1.4 introduces a new platform, Wayland, available for recent Unix
|
||||
distributions. More information in README.Wayland.txt
|
||||
- Windows platform: added support for using a manifest to set the
|
||||
application's level of DPI awareness (issue #309).
|
||||
- X11 platform: class Fl_Native_File_Chooser will run the KDE file dialog
|
||||
@@ -121,6 +123,8 @@ Changes in FLTK 1.4.0 Released: ??? ?? 2021
|
||||
|
||||
New Configuration Options (ABI Version)
|
||||
|
||||
- Configure option --enable-wayland allows to build the FLTK library for
|
||||
the new Wayland platform. The corresponding CMake option is OPTION_USE_WAYLAND.
|
||||
- The new configure option --disable-gdiplus removes the possibility to draw
|
||||
antialiased lines and curves on the Windows platform. The corresponding CMake
|
||||
option is OPTION_USE_GDIPLUS.
|
||||
|
||||
@@ -50,6 +50,24 @@ set (FL_ABI_VERSION ${OPTION_ABI_VERSION})
|
||||
if (UNIX)
|
||||
option (OPTION_CREATE_LINKS "create backwards compatibility links" OFF)
|
||||
list (APPEND FLTK_LDLIBS -lm)
|
||||
option (OPTION_USE_WAYLAND "use Wayland" OFF)
|
||||
if (OPTION_USE_WAYLAND)
|
||||
set (FLTK_USE_WAYLAND 1)
|
||||
option (OPTION_USE_SYSTEM_LIBDECOR "use libdecor from the system" OFF)
|
||||
unset (OPTION_USE_XRENDER CACHE)
|
||||
unset (OPTION_USE_XINERAMA CACHE)
|
||||
unset (OPTION_USE_XFT CACHE)
|
||||
unset (OPTION_USE_XCURSOR CACHE)
|
||||
unset (OPTION_USE_XFIXES CACHE)
|
||||
unset (OPTION_USE_PANGO CACHE)
|
||||
set (OPTION_USE_PANGO TRUE CACHE BOOL "use lib Pango")
|
||||
if (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
pkg_check_modules(SYSTEM_LIBDECOR libdecor-0)
|
||||
if (NOT SYSTEM_LIBDECOR_FOUND)
|
||||
set (OPTION_USE_SYSTEM_LIBDECOR OFF)
|
||||
endif (NOT SYSTEM_LIBDECOR_FOUND)
|
||||
endif (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
endif (OPTION_USE_WAYLAND)
|
||||
endif (UNIX)
|
||||
|
||||
if (WIN32)
|
||||
@@ -72,7 +90,7 @@ endif (APPLE)
|
||||
|
||||
# find X11 libraries and headers
|
||||
set (PATH_TO_XLIBS)
|
||||
if ((NOT APPLE OR OPTION_APPLE_X11) AND NOT WIN32)
|
||||
if ((NOT APPLE OR OPTION_APPLE_X11) AND NOT WIN32 AND NOT OPTION_USE_WAYLAND)
|
||||
include (FindX11)
|
||||
if (X11_FOUND)
|
||||
set (FLTK_USE_X11 1)
|
||||
@@ -82,7 +100,7 @@ if ((NOT APPLE OR OPTION_APPLE_X11) AND NOT WIN32)
|
||||
endif (X11_Xext_FOUND)
|
||||
get_filename_component (PATH_TO_XLIBS ${X11_X11_LIB} PATH)
|
||||
endif (X11_FOUND)
|
||||
endif ((NOT APPLE OR OPTION_APPLE_X11) AND NOT WIN32)
|
||||
endif ((NOT APPLE OR OPTION_APPLE_X11) AND NOT WIN32 AND NOT OPTION_USE_WAYLAND)
|
||||
|
||||
if (OPTION_APPLE_X11)
|
||||
if (NOT(${CMAKE_SYSTEM_VERSION} VERSION_LESS 17.0.0)) # a.k.a. macOS version ≥ 10.13
|
||||
@@ -252,6 +270,8 @@ if (OPENGL_FOUND)
|
||||
set (GLLIBS "-lglu32 -lopengl32")
|
||||
elseif (APPLE AND NOT OPTION_APPLE_X11)
|
||||
set (GLLIBS "-framework OpenGL")
|
||||
elseif (OPTION_USE_WAYLAND)
|
||||
set (GLLIBS "-lwayland-egl -lEGL -lGLU -lGL")
|
||||
else ()
|
||||
set (GLLIBS "-lGLU -lGL")
|
||||
endif (WIN32)
|
||||
@@ -481,7 +501,7 @@ if (X11_Xft_FOUND)
|
||||
endif (X11_Xft_FOUND)
|
||||
|
||||
# test option compatibility: Pango requires Xft
|
||||
if (OPTION_USE_PANGO)
|
||||
if (OPTION_USE_PANGO AND NOT OPTION_USE_WAYLAND)
|
||||
if (NOT X11_Xft_FOUND)
|
||||
message (STATUS "Pango requires Xft but Xft library or headers could not be found.")
|
||||
message (STATUS "Please install Xft development files and try again or disable OPTION_USE_PANGO.")
|
||||
@@ -493,10 +513,10 @@ if (OPTION_USE_PANGO)
|
||||
message (FATAL_ERROR "*** Aborting ***")
|
||||
endif (NOT OPTION_USE_XFT)
|
||||
endif (NOT X11_Xft_FOUND)
|
||||
endif (OPTION_USE_PANGO)
|
||||
endif (OPTION_USE_PANGO AND NOT OPTION_USE_WAYLAND)
|
||||
|
||||
#######################################################################
|
||||
if (X11_Xft_FOUND AND OPTION_USE_PANGO)
|
||||
if ((X11_Xft_FOUND OR OPTION_USE_WAYLAND) AND OPTION_USE_PANGO)
|
||||
pkg_check_modules(PANGOXFT pangoxft)
|
||||
pkg_check_modules(PANGOCAIRO pangocairo)
|
||||
pkg_check_modules(CAIRO cairo)
|
||||
@@ -553,7 +573,15 @@ if (X11_Xft_FOUND AND OPTION_USE_PANGO)
|
||||
list (APPEND FLTK_LDLIBS -lpango-1.0 -lpangoxft-1.0 -lgobject-2.0)
|
||||
endif (HAVE_LIB_PANGO AND HAVE_LIB_PANGOXFT AND HAVE_LIB_GOBJECT)
|
||||
endif (PANGOXFT_FOUND AND PANGOCAIRO_FOUND AND CAIRO_FOUND)
|
||||
endif (X11_Xft_FOUND AND OPTION_USE_PANGO)
|
||||
endif ((X11_Xft_FOUND OR OPTION_USE_WAYLAND) AND OPTION_USE_PANGO)
|
||||
|
||||
if (OPTION_USE_WAYLAND AND NOT OPTION_USE_SYSTEM_LIBDECOR)
|
||||
pkg_check_modules(GTK gtk+-3.0)
|
||||
#set (GTK_FOUND 0) #use this to get cairo titlebars rather than GTK
|
||||
if (GTK_FOUND)
|
||||
include_directories (${GTK_INCLUDE_DIRS})
|
||||
endif (GTK_FOUND)
|
||||
endif (OPTION_USE_WAYLAND AND NOT OPTION_USE_SYSTEM_LIBDECOR)
|
||||
|
||||
if (OPTION_USE_XFT)
|
||||
set (USE_XFT X11_Xft_FOUND)
|
||||
|
||||
@@ -43,6 +43,11 @@ if (WIN32)
|
||||
list (APPEND FLTK_LDLIBS -lole32 -luuid -lcomctl32 -lws2_32)
|
||||
elseif (APPLE AND NOT OPTION_APPLE_X11)
|
||||
list (APPEND FLTK_LDLIBS "-framework Cocoa")
|
||||
elseif (OPTION_USE_WAYLAND)
|
||||
list (APPEND FLTK_LDLIBS "-lwayland-cursor -lwayland-client -lxkbcommon -ldbus-1")
|
||||
if (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
list (APPEND FLTK_LDLIBS "-ldecor-0")
|
||||
endif (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
else ()
|
||||
list (APPEND FLTK_LDLIBS -lm)
|
||||
endif (WIN32)
|
||||
|
||||
@@ -37,6 +37,8 @@ class Fl_Window;
|
||||
# include "win32.H"
|
||||
# elif defined(__APPLE__)
|
||||
# include "mac.H"
|
||||
# elif defined(FLTK_USE_WAYLAND)
|
||||
# include "wayland.H"
|
||||
# elif defined(FLTK_USE_X11)
|
||||
# include "x11.H"
|
||||
# endif // _WIN32
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 by Bill Spitzak and others.
|
||||
* Copyright 2016-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
|
||||
@@ -116,6 +116,17 @@ typedef struct HGLRC__ *GLContext;
|
||||
struct dirent {char d_name[1];};
|
||||
#endif
|
||||
|
||||
#elif defined(FLTK_USE_WAYLAND)
|
||||
typedef struct fl_wld_buffer *Fl_Offscreen; /**< an offscreen drawing buffer */
|
||||
typedef struct _cairo_pattern* Fl_Bitmask;
|
||||
typedef struct flWaylandRegion* Fl_Region;
|
||||
typedef int FL_SOCKET; /**< socket or file descriptor */
|
||||
typedef void *EGLContext;
|
||||
typedef EGLContext GLContext;
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#elif defined(FLTK_USE_X11)
|
||||
|
||||
typedef unsigned long Fl_Offscreen;
|
||||
|
||||
31
FL/wayland.H
Executable file
31
FL/wayland.H
Executable file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Wayland platform header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2021 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
|
||||
//
|
||||
|
||||
#if !defined(FL_PLATFORM_H)
|
||||
# error "Never use <FL/wayland.H> directly; include <FL/platform.H> instead."
|
||||
#endif // !FL_PLATFORM_H
|
||||
|
||||
typedef struct wld_window *Window;
|
||||
|
||||
extern struct wl_display *fl_display;
|
||||
|
||||
struct flWaylandRegion {
|
||||
int count;
|
||||
struct _cairo_rectangle *rects;
|
||||
}; // a region is the union of a series of rectangles
|
||||
|
||||
#include <stdint.h>
|
||||
extern FL_EXPORT uint32_t fl_event_time;
|
||||
141
README.Wayland.txt
Normal file
141
README.Wayland.txt
Normal file
@@ -0,0 +1,141 @@
|
||||
README.Wayland.txt - Wayland platform support for FLTK
|
||||
------------------------------------------------------
|
||||
|
||||
|
||||
CONTENTS
|
||||
========
|
||||
|
||||
1 INTRODUCTION
|
||||
|
||||
2 WAYLAND SUPPORT FOR FLTK
|
||||
2.1 Configuration
|
||||
2.2 Known limitations
|
||||
|
||||
3 PLATFORM SPECIFIC NOTES
|
||||
3.1 Debian and Derivatives (like Ubuntu)
|
||||
|
||||
|
||||
1 INTRODUCTION
|
||||
==============
|
||||
|
||||
Version 1.4 of the FLTK library introduces support of the public FLTK API on
|
||||
the Wayland platform. It requires a Wayland-equipped OS which means Linux.
|
||||
Pre-existing platform-independent source code for FLTK 1.3.x should build and
|
||||
run unchanged with FLTK 1.4 and the Wayland platform.
|
||||
The code has been tested on Debian and Ubuntu with 3 distinct Wayland compositors:
|
||||
mutter (Debian's compositor), weston, and KDE.
|
||||
CJK text-input methods, as well as dead and compose keys are supported.
|
||||
|
||||
|
||||
2 WAYLAND SUPPORT FOR FLTK
|
||||
==========================
|
||||
|
||||
It is possible to have your FLTK application do all its windowing and drawing
|
||||
through the Wayland protocol on Linux systems. All graphics is done via Cairo or EGL.
|
||||
All text-drawing is done via Pango.
|
||||
|
||||
2.1 Configuration
|
||||
---------------
|
||||
|
||||
* Configure-based build can be performed as follows:
|
||||
Once after "git clone", create the configure file :
|
||||
autoconf -f
|
||||
|
||||
Prepare build with :
|
||||
./configure --enable-wayland [--enable-shared]
|
||||
|
||||
Build with :
|
||||
make
|
||||
|
||||
* CMake-based build can be performed as follows:
|
||||
cmake -S <path-to-source> -B <path-to-build> -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_WAYLAND=1
|
||||
|
||||
cd <path-to-build>; make
|
||||
|
||||
The FLTK wayland platform uses a library called libdecor which handles window decorations
|
||||
(i.e., titlebars, shade). Libdecor is bundled in the FLTK source code and FLTK uses by default
|
||||
this form of libdecor. Optionally, OPTION_USE_SYSTEM_LIBDECOR can be turned on to have FLTK
|
||||
use the system's version of libdecor which is available on recent Linux distributions (e.g.,
|
||||
Debian bookworm or more recent in packages libdecor-0-0 and libdecor-0-plugin-1-cairo).
|
||||
|
||||
2.2 Known limitations
|
||||
-------------------------------
|
||||
|
||||
* A deliberate design trait of Wayland makes application windows ignorant of their exact
|
||||
placement on screen. It's possible, though, to position a popup window relatively to another
|
||||
window. This allows FLTK to properly position menu and tooltip windows. But Fl_Window::position()
|
||||
has no effect on other top-level windows.
|
||||
|
||||
* With Wayland, there is no way to know if a window is currently minimized, nor is there any
|
||||
way to programmatically unset minimization of a window. Consequently, Fl_Window::show() of
|
||||
a minimized window has no effect.
|
||||
|
||||
* With GTK-style window titlebars, the minimum width of a window is currently set at 134 pixels.
|
||||
|
||||
* The library should support multi-display configurations in principle, but has not been
|
||||
tested in that situation.
|
||||
|
||||
* Text input methods have been tested without any understanding of the writing systems,
|
||||
so feedback on this subject would be helpful.
|
||||
|
||||
* While platform-independent source code prepared for FLTK 1.3 is expected to be compatible
|
||||
with FLTK 1.4 and the Wayland platform, X11-specific code will not compile. In particular,
|
||||
the common FLTK 1.3 construct :
|
||||
#ifdef __APPLE__
|
||||
*** macOS-specific code ***
|
||||
#elif defined(_WIN32)
|
||||
*** Windows-specific code ***
|
||||
#else
|
||||
*** X11-specific code ***
|
||||
#endif
|
||||
will choke at compile time because it exposes X11-specific code to the non-X11, Wayland
|
||||
environment. This should be written instead :
|
||||
#include <FL/fl_config.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
*** macOS-specific code ***
|
||||
#elif defined(_WIN32)
|
||||
*** Windows-specific code ***
|
||||
#elif defined(FLTK_USE_X11)
|
||||
*** X11-specific code ***
|
||||
#endif
|
||||
Moreover, the new FLTK_USE_WAYLAND preprocessor variable is available to bracket
|
||||
Wayland-specific source code.
|
||||
|
||||
|
||||
3 PLATFORM SPECIFIC NOTES
|
||||
=========================
|
||||
|
||||
The following are notes about building FLTK for the Wayland platform
|
||||
on the various supported Linux distributions.
|
||||
|
||||
3.1 Debian and Derivatives (like Ubuntu)
|
||||
----------------------------------------
|
||||
Under Debian, the Wayland platform requires version 11 (a.k.a. Bullseye) or more recent.
|
||||
Under Ubuntu, the Wayland platform is known to work with version 20.04 (focal fossa) or more recent.
|
||||
|
||||
These packages are necessary to build the FLTK library, in addition to those present
|
||||
in a basic Debian/Ubuntu distribution :
|
||||
- g++
|
||||
- gdb
|
||||
- make
|
||||
- git
|
||||
- autoconf
|
||||
- libglu1-mesa-dev
|
||||
- libpango1.0-dev
|
||||
- libwayland-dev
|
||||
- wayland-protocols
|
||||
- libdbus-1-dev
|
||||
- libxkbcommon-dev
|
||||
- libgtk-3-dev <== with this, windows get a GTK-style titlebar
|
||||
- libglew-dev <== necessary to use OpenGL version 3 or above
|
||||
- cmake <== if you plan to build with CMake
|
||||
- cmake-qt-gui <== if you plan to use the GUI of CMake
|
||||
|
||||
These further packages are necessary to run FLTK apps under the Gnome-Wayland desktop:
|
||||
- gnome
|
||||
- gnome-session-wayland
|
||||
|
||||
These packages allow to run FLTK apps under the KDE/Plasma-Wayland desktop:
|
||||
- kde-plasma-desktop
|
||||
- plasma-workspace-wayland
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Main header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2021 by Bill Spitzak and others.
|
||||
// Copyright 1998-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
|
||||
@@ -30,6 +30,9 @@
|
||||
# include <cairo-win32.h>
|
||||
#elif defined(__APPLE_QUARTZ__) // macOS
|
||||
# include <cairo-quartz.h>
|
||||
#elif defined(FLTK_USE_WAYLAND)
|
||||
# include "../src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H"
|
||||
# include "../src/drivers/Wayland/Fl_Wayland_Window_Driver.H"
|
||||
#else
|
||||
# error Cairo is not supported on this platform.
|
||||
#endif
|
||||
@@ -69,7 +72,13 @@ void Fl_Cairo_State::autolink(bool b) {
|
||||
*/
|
||||
cairo_t * Fl::cairo_make_current(Fl_Window* wi) {
|
||||
if (!wi) return NULL; // Precondition
|
||||
|
||||
cairo_t * cairo_ctxt;
|
||||
#if defined(FLTK_USE_WAYLAND)
|
||||
Window xid = fl_xid(wi);
|
||||
if (!xid->buffer) return NULL; // this may happen with GL windows
|
||||
cairo_ctxt = xid->buffer->cairo_;
|
||||
cairo_state_.cc(cairo_ctxt, false);
|
||||
#else // FLTK_USE_WAYLAND
|
||||
if (fl_gc==0) { // means remove current cc
|
||||
Fl::cairo_cc(0); // destroy any previous cc
|
||||
cairo_state_.window(0);
|
||||
@@ -82,7 +91,6 @@ cairo_t * Fl::cairo_make_current(Fl_Window* wi) {
|
||||
|
||||
cairo_state_.window(wi);
|
||||
|
||||
cairo_t * cairo_ctxt;
|
||||
#ifndef __APPLE__
|
||||
float scale = Fl::screen_scale(wi->screen_num()); // get the screen scaling factor
|
||||
#endif
|
||||
@@ -95,9 +103,11 @@ cairo_t * Fl::cairo_make_current(Fl_Window* wi) {
|
||||
#ifndef __APPLE__
|
||||
cairo_scale(cairo_ctxt, scale, scale);
|
||||
#endif
|
||||
#endif // FLTK_USE_WAYLAND
|
||||
return cairo_ctxt;
|
||||
}
|
||||
|
||||
#if !defined(FLTK_USE_WAYLAND)
|
||||
/*
|
||||
Creates transparently a cairo_surface_t object.
|
||||
gc is an HDC context in Windows, a CGContext* in Quartz, and
|
||||
@@ -176,6 +186,9 @@ cairo_t * Fl::cairo_make_current(void *gc, int W, int H) {
|
||||
cairo_surface_destroy(s);
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif // !FLTK_USE_WAYLAND
|
||||
|
||||
#else
|
||||
// just don't leave the libfltk_cairo lib empty to avoid warnings
|
||||
#include <FL/Fl_Export.H>
|
||||
|
||||
97
configure.ac
97
configure.ac
@@ -3,7 +3,7 @@ dnl the "configure" script is made from this by running GNU "autoconf"
|
||||
dnl
|
||||
dnl Configuration script for the Fast Light Tool Kit (FLTK).
|
||||
dnl
|
||||
dnl Copyright 1998-2021 by Bill Spitzak and others.
|
||||
dnl Copyright 1998-2022 by Bill Spitzak and others.
|
||||
dnl
|
||||
dnl This library is free software. Distribution and use rights are outlined in
|
||||
dnl the file "COPYING" which should have been included with this file. If this
|
||||
@@ -110,6 +110,8 @@ AC_ARG_ENABLE([localzlib], AS_HELP_STRING([--enable-localzlib], [use local ZLIB
|
||||
|
||||
AC_ARG_ENABLE([pango], AS_HELP_STRING([--enable-pango], [turn on Pango support]))
|
||||
|
||||
AC_ARG_ENABLE([wayland], AS_HELP_STRING([--enable-wayland], [turn on Wayland support]))
|
||||
|
||||
AC_ARG_ENABLE([print], AS_HELP_STRING([--disable-print], [turn off print support (X11)]))
|
||||
AS_IF([test x$enable_print = xno], [
|
||||
AC_DEFINE([FL_NO_PRINT_SUPPORT], [Disable X11 print support?])
|
||||
@@ -897,6 +899,7 @@ dnl Define OS-specific stuff...
|
||||
HLINKS=
|
||||
OSX_ONLY=:
|
||||
THREADS=
|
||||
LIBDECORDIR=""
|
||||
|
||||
AC_ARG_WITH([links], AS_HELP_STRING([--with-links], [make header links for common misspellings (default=no)]))
|
||||
|
||||
@@ -995,6 +998,64 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [
|
||||
THREADS="threads$EXEEXT"
|
||||
])
|
||||
|
||||
AS_IF([test x$enable_wayland = xyes], [
|
||||
dnl Prepare for Wayland...
|
||||
|
||||
AS_IF([test x$PKGCONFIG = x], [
|
||||
dnl pkg-config is not available, issue warning and abort...
|
||||
AC_MSG_WARN([--enable-wayland: please install pkg-config.])
|
||||
AC_MSG_ERROR([Aborting.])
|
||||
])
|
||||
|
||||
BUILD="WAYLAND"
|
||||
AC_DEFINE([FLTK_USE_WAYLAND])
|
||||
CFLAGS="$CFLAGS -DUSE_SYSTEM_LIBDECOR=0"
|
||||
CXXFLAGS="$CXXFLAGS -DUSE_SYSTEM_LIBDECOR=0"
|
||||
graphics="Wayland"
|
||||
LIBS="$LIBS $($PKGCONFIG --libs wayland-cursor) $($PKGCONFIG --libs wayland-client) $($PKGCONFIG --libs xkbcommon)"
|
||||
LIBS="$LIBS $($PKGCONFIG --libs dbus-1) -ldl"
|
||||
CXXFLAGS="$CXXFLAGS -I../libdecor/src"
|
||||
DSOFLAGS="$LIBS $DSOFLAGS"
|
||||
enable_pango=yes
|
||||
LIBDECORDIR="libdecor/build"
|
||||
LDFLAGS="$LDFLAGS -rdynamic -no-pie"
|
||||
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
AC_CHECK_HEADER([GL/gl.h], [AC_DEFINE([HAVE_GL])])
|
||||
AC_CHECK_HEADER([GL/glu.h], [
|
||||
AC_DEFINE([HAVE_GL_GLU_H])
|
||||
GLLIBS="$($PKGCONFIG --libs wayland-egl) $($PKGCONFIG --libs egl) $($PKGCONFIG --libs glu) $GLLIBS"
|
||||
])
|
||||
|
||||
dnl Check for GTK-3 ...
|
||||
gtk_found=no
|
||||
CFLAGS="$($PKGCONFIG --cflags gtk+-3.0) $CFLAGS"
|
||||
AC_CHECK_HEADERS([gtk/gtk.h], [
|
||||
CFLAGS="$CFLAGS -DHAVE_GTK"
|
||||
LIBS="$LIBS $($PKGCONFIG --libs gtk+-3.0)"
|
||||
gtk_found=yes
|
||||
])
|
||||
|
||||
dnl Check for the Pango library ...
|
||||
pango_found=no
|
||||
CFLAGS="$($PKGCONFIG --cflags pangocairo) $CFLAGS"
|
||||
CXXFLAGS="$($PKGCONFIG --cflags pangocairo) $CXXFLAGS"
|
||||
LIBS="$LIBS $($PKGCONFIG --libs pangocairo)"
|
||||
|
||||
AC_CHECK_HEADERS([pango/pangocairo.h], [
|
||||
AC_DEFINE([USE_PANGO])
|
||||
AC_DEFINE([USE_XFT])
|
||||
pango_found=yes
|
||||
])
|
||||
|
||||
dnl Early abort if Pango could not be found
|
||||
AS_IF([test x$pango_found != xyes], [
|
||||
AC_MSG_NOTICE([--enable-wayland: Pango libs and/or headers could not be found.])
|
||||
AC_MSG_ERROR([Aborting.])
|
||||
])
|
||||
|
||||
], [
|
||||
|
||||
dnl Check for X11...
|
||||
AC_PATH_XTRA
|
||||
|
||||
@@ -1016,7 +1077,7 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [
|
||||
AS_IF([test "x$x_includes" != x], [
|
||||
ac_cpp="$ac_cpp -I$x_includes"
|
||||
])
|
||||
|
||||
])
|
||||
dnl Check for OpenGL unless disabled...
|
||||
GLLIBS=
|
||||
|
||||
@@ -1217,6 +1278,8 @@ AC_SUBST([HLINKS])
|
||||
AC_SUBST([OSX_ONLY])
|
||||
AC_SUBST([THREADS])
|
||||
|
||||
AC_SUBST([LIBDECORDIR])
|
||||
|
||||
AC_SUBST([INSTALL_DESKTOP])
|
||||
AC_SUBST([UNINSTALL_DESKTOP])
|
||||
|
||||
@@ -1344,17 +1407,21 @@ AS_IF([test -n "$GCC"], [
|
||||
[AC_MSG_RESULT(no)])
|
||||
CFLAGS="$OLDCFLAGS"
|
||||
|
||||
dnl Make sure that shared libraries don't have undefined references
|
||||
# See if ld supports -no-undefined...
|
||||
AC_MSG_CHECKING([if ld supports -no-undefined])
|
||||
OLDLDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,-no-undefined"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[]])],
|
||||
[DSOFLAGS="$DSOFLAGS -Wl,-no-undefined"
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)])
|
||||
LDFLAGS="$OLDLDFLAGS"
|
||||
AS_IF([test x$enable_wayland = xyes],[
|
||||
DSOFLAGS="$DSOFLAGS -Wl,--allow-shlib-undefined"
|
||||
] , [
|
||||
dnl Make sure that shared libraries don't have undefined references
|
||||
# See if ld supports -no-undefined...
|
||||
AC_MSG_CHECKING([if ld supports -no-undefined])
|
||||
OLDLDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,-no-undefined"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]], [[]])],
|
||||
[DSOFLAGS="$DSOFLAGS -Wl,-no-undefined"
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)])
|
||||
LDFLAGS="$OLDLDFLAGS"
|
||||
])
|
||||
|
||||
# See if ld supports -Bsymbolic-functions...
|
||||
AC_MSG_CHECKING([if ld supports -Bsymbolic-functions])
|
||||
@@ -1529,7 +1596,9 @@ AS_CASE([$host_os_gui], [cygwin* | mingw*], [
|
||||
], [darwin*], [
|
||||
graphics="Quartz"
|
||||
], [*], [
|
||||
graphics="X11"
|
||||
AS_IF([test x$enable_wayland != xyes], [
|
||||
graphics="X11"
|
||||
])
|
||||
AS_IF([test x$xft_found = xyes], [
|
||||
graphics="$graphics + Xft"
|
||||
])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Tiny OpenGL v3 + glut demo program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2021 by Bill Spitzak and others.
|
||||
// Copyright 1998-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
|
||||
@@ -14,6 +14,7 @@
|
||||
// https://www.fltk.org/bugs.php
|
||||
//
|
||||
|
||||
#include <FL/Fl.H> // includes <FL/fl_config.h>
|
||||
#if defined(__APPLE__)
|
||||
# define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED 1
|
||||
# include <OpenGL/gl3.h> // defines OpenGL 3.0+ functions
|
||||
@@ -198,7 +199,10 @@ int main (int argc, char* argv[])
|
||||
glutCreateWindow("Triangle Test");
|
||||
#ifndef __APPLE__
|
||||
GLenum err = glewInit(); // defines pters to functions of OpenGL V 1.2 and above
|
||||
if (err) Fl::error("glewInit() failed returning %u", err);
|
||||
#ifdef FLTK_USE_WAYLAND
|
||||
if (err == GLEW_ERROR_NO_GLX_DISPLAY) err = GLEW_OK;
|
||||
#endif
|
||||
if (err != GLEW_OK) Fl::error("glewInit() failed returning %u", err);
|
||||
fprintf(stderr, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
|
||||
#endif
|
||||
int gl_version_major;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// Tiny OpenGL v3 demo program for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
// Copyright 1998-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
|
||||
@@ -146,6 +146,11 @@ public:
|
||||
make_current();
|
||||
#ifndef __APPLE__
|
||||
GLenum err = glewInit(); // defines pters to functions of OpenGL V 1.2 and above
|
||||
# ifdef FLTK_USE_WAYLAND
|
||||
// glewInit returns GLEW_ERROR_NO_GLX_DISPLAY with Wayland
|
||||
// see https://github.com/nigels-com/glew/issues/273
|
||||
if (err == GLEW_ERROR_NO_GLX_DISPLAY) err = GLEW_OK;
|
||||
# endif
|
||||
if (err) Fl::warning("glewInit() failed returning %u", err);
|
||||
else add_output("Using GLEW %s\n", glewGetString(GLEW_VERSION));
|
||||
#endif
|
||||
|
||||
@@ -55,4 +55,14 @@
|
||||
|
||||
#cmakedefine FLTK_USE_X11 1
|
||||
|
||||
|
||||
/*
|
||||
* FLTK_USE_WAYLAND
|
||||
*
|
||||
* Do we use Wayland for the current platform?
|
||||
*
|
||||
*/
|
||||
|
||||
#cmakedefine FLTK_USE_WAYLAND 1
|
||||
|
||||
#endif /* _FL_fl_config_h_ */
|
||||
|
||||
10
fl_config.in
10
fl_config.in
@@ -54,4 +54,14 @@
|
||||
|
||||
#undef FLTK_USE_X11
|
||||
|
||||
|
||||
/*
|
||||
* FLTK_USE_WAYLAND
|
||||
*
|
||||
* Do we use Wayland for the current platform?
|
||||
*
|
||||
*/
|
||||
|
||||
#undef FLTK_USE_WAYLAND
|
||||
|
||||
#endif /* _FL_fl_config_h_ */
|
||||
|
||||
19
libdecor/LICENSE
Normal file
19
libdecor/LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
86
libdecor/README.md
Normal file
86
libdecor/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# libdecor - A client-side decorations library for Wayland client
|
||||
|
||||
libdecor is a library that can help Wayland clients draw window
|
||||
decorations for them. It aims to provide multiple backends that implements the
|
||||
decoration drawing.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
Required:
|
||||
- `meson` >= 0.47
|
||||
- `ninja`
|
||||
- `wayland-client` >= 1.18
|
||||
- `wayland-protocols` >= 1.15
|
||||
- `wayland-cursor`
|
||||
- `cairo`
|
||||
- `pangocairo`
|
||||
|
||||
Recommended:
|
||||
- `dbus-1` (to query current cursor theme)
|
||||
|
||||
Optional
|
||||
- `egl` (to build EGL example)
|
||||
- `opengl`
|
||||
- `xkbcommon` (to build cairo demo)
|
||||
|
||||
Install via apt:
|
||||
`sudo apt install meson libwayland-dev wayland-protocols libpango1.0-dev libdbus-1-dev libegl-dev libopengl-dev libxkbcommon-dev`
|
||||
|
||||
Install via dnf:
|
||||
`sudo dnf install meson wayland-devel wayland-protocols-devel pango-devel dbus-devel mesa-libEGL-devel libglvnd-devel libxkbcommon-devel`
|
||||
|
||||
Newer meson versions can be installed via pip: `pip3 install -U meson`.
|
||||
|
||||
## Build & Install
|
||||
|
||||
### Quick Start
|
||||
|
||||
To build and run the example program:
|
||||
1. `meson build -Dinstall_demo=true && meson compile -C build`
|
||||
2. `meson devenv -C build libdecor-demo`
|
||||
|
||||
### Release Builds
|
||||
|
||||
The library and default plugins can be built and installed via:
|
||||
1. `meson build --buildtype release`
|
||||
2. `meson install -C build`
|
||||
|
||||
where `build` is the build directory that will be created during this process.
|
||||
|
||||
This will install by default to `/usr/local/`. To change this set the `prefix` during built, e.g. `meson build --buildtype release -Dprefix=$HOME/.local/`.
|
||||
|
||||
Plugins will be installed into the same directory and from thereon will be selected automatically depending on their precedence. This behaviour can be overridden at runtime by setting the environment variable `LIBDECOR_PLUGIN_DIR` and pointing it to a directory with a valid plugin.
|
||||
|
||||
### Debug and Development Builds
|
||||
|
||||
During development and when debugging, it is recommended to enable the AddressSanitizer and increase the warning level:
|
||||
1. `meson build -Dinstall_demo=true -Db_sanitize=address -Dwarning_level=3`
|
||||
2. `meson compile -C build`
|
||||
|
||||
You may have to install `libasan6` (apt) or `libasan` (dnf). Otherwise linking will fail.
|
||||
|
||||
By default `libdecor` will look for plugins in the target directory of the installation. Therefore, when running the demos directly from the `build` directory, no plugins will be found and the fallback plugin without any decorations will be used.
|
||||
|
||||
On Meson 0.58.0 and above, this can be corrected using `devenv`, i.e., to run the demo:
|
||||
|
||||
`meson devenv -C build libdecor-demo`
|
||||
|
||||
On older Meson versions, the search path for plugins can be overridden by the environment variable `LIBDECOR_PLUGIN_DIR`. To use the `cairo` plugin, point to the plugin directory:
|
||||
|
||||
`export LIBDECOR_PLUGIN_DIR=build/src/plugins/cairo/`
|
||||
|
||||
and run the demo:
|
||||
|
||||
`./build/demo/libdecor-demo`.
|
||||
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
libdecor follows the Contributor Covenant, found at:
|
||||
https://www.freedesktop.org/wiki/CodeOfConduct
|
||||
|
||||
Please conduct yourself in a respectful and civilised manner when interacting
|
||||
with community members on mailing lists, IRC, or bug trackers. The community
|
||||
represents the project as a whole, and abusive or bullying behaviour is not
|
||||
tolerated by the project.
|
||||
80
libdecor/build/Makefile
Normal file
80
libdecor/build/Makefile
Normal file
@@ -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
|
||||
348
libdecor/build/fl_libdecor-plugins.c
Normal file
348
libdecor/build/fl_libdecor-plugins.c
Normal file
@@ -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;
|
||||
}
|
||||
127
libdecor/build/fl_libdecor.c
Normal file
127
libdecor/build/fl_libdecor.c
Normal file
@@ -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, ®istry_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;
|
||||
}
|
||||
1304
libdecor/demo/demo.c
Normal file
1304
libdecor/demo/demo.c
Normal file
File diff suppressed because it is too large
Load Diff
355
libdecor/demo/egl.c
Normal file
355
libdecor/demo/egl.c
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* Copyright © 2011 Benjamin Franzke
|
||||
* Copyright © 2010 Intel Corporation
|
||||
* Copyright © 2018 Jonas Ådahl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-egl.h>
|
||||
#include <libdecor.h>
|
||||
#include <GL/gl.h>
|
||||
#include <utils.h>
|
||||
|
||||
static const size_t default_size = 200;
|
||||
|
||||
struct client {
|
||||
struct wl_display *display;
|
||||
struct wl_compositor *compositor;
|
||||
EGLDisplay egl_display;
|
||||
EGLContext egl_context;
|
||||
};
|
||||
|
||||
struct window {
|
||||
struct client *client;
|
||||
struct wl_surface *surface;
|
||||
struct libdecor_frame *frame;
|
||||
struct wl_egl_window *egl_window;
|
||||
EGLSurface egl_surface;
|
||||
int content_width;
|
||||
int content_height;
|
||||
int floating_width;
|
||||
int floating_height;
|
||||
bool open;
|
||||
bool configured;
|
||||
};
|
||||
|
||||
static void
|
||||
frame_configure(struct libdecor_frame *frame,
|
||||
struct libdecor_configuration *configuration,
|
||||
void *user_data)
|
||||
{
|
||||
struct window *window = user_data;
|
||||
struct libdecor_state *state;
|
||||
int width, height;
|
||||
|
||||
if (!libdecor_configuration_get_content_size(configuration, frame,
|
||||
&width, &height)) {
|
||||
width = window->floating_width;
|
||||
height = window->floating_height;
|
||||
}
|
||||
|
||||
window->content_width = width;
|
||||
window->content_height = height;
|
||||
|
||||
wl_egl_window_resize(window->egl_window,
|
||||
window->content_width, window->content_height,
|
||||
0, 0);
|
||||
|
||||
state = libdecor_state_new(width, height);
|
||||
libdecor_frame_commit(frame, state, configuration);
|
||||
libdecor_state_free(state);
|
||||
|
||||
/* store floating dimensions */
|
||||
if (libdecor_frame_is_floating(window->frame)) {
|
||||
window->floating_width = width;
|
||||
window->floating_height = height;
|
||||
}
|
||||
|
||||
window->configured = true;
|
||||
}
|
||||
|
||||
static void
|
||||
frame_close(struct libdecor_frame *frame,
|
||||
void *user_data)
|
||||
{
|
||||
struct window *window = user_data;
|
||||
|
||||
window->open = false;
|
||||
}
|
||||
|
||||
static void
|
||||
frame_commit(struct libdecor_frame *frame,
|
||||
void *user_data)
|
||||
{
|
||||
struct window *window = user_data;
|
||||
|
||||
eglSwapBuffers(window->client->display, window->egl_surface);
|
||||
}
|
||||
|
||||
static struct libdecor_frame_interface frame_interface = {
|
||||
frame_configure,
|
||||
frame_close,
|
||||
frame_commit,
|
||||
};
|
||||
|
||||
static void
|
||||
libdecor_error(struct libdecor *context,
|
||||
enum libdecor_error error,
|
||||
const char *message)
|
||||
{
|
||||
fprintf(stderr, "Caught error (%d): %s\n", error, message);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static struct libdecor_interface libdecor_interface = {
|
||||
libdecor_error,
|
||||
};
|
||||
|
||||
static void
|
||||
registry_global(void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
struct client *client = data;
|
||||
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
client->compositor = wl_registry_bind(wl_registry, name,
|
||||
&wl_compositor_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
registry_global_remove(void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
registry_global,
|
||||
registry_global_remove
|
||||
};
|
||||
|
||||
static bool
|
||||
setup(struct window *window)
|
||||
{
|
||||
static const EGLint config_attribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
EGLint major, minor;
|
||||
EGLint n;
|
||||
EGLConfig config;
|
||||
|
||||
window->client->egl_display =
|
||||
eglGetDisplay((EGLNativeDisplayType)window->client->display);
|
||||
|
||||
if (eglInitialize(window->client->egl_display, &major, &minor) == EGL_FALSE) {
|
||||
fprintf(stderr, "Cannot initialise EGL!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) {
|
||||
fprintf(stderr, "Cannot bind EGL API!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eglChooseConfig(window->client->egl_display,
|
||||
config_attribs,
|
||||
&config, 1, &n) == EGL_FALSE) {
|
||||
fprintf(stderr, "No matching EGL configurations!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
window->client->egl_context = eglCreateContext(window->client->egl_display,
|
||||
config, EGL_NO_CONTEXT, NULL);
|
||||
|
||||
if (window->client->egl_context == EGL_NO_CONTEXT) {
|
||||
fprintf(stderr, "No EGL context!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
window->surface = wl_compositor_create_surface(window->client->compositor);
|
||||
|
||||
window->egl_window = wl_egl_window_create(window->surface,
|
||||
default_size, default_size);
|
||||
|
||||
window->egl_surface = eglCreateWindowSurface(
|
||||
window->client->egl_display, config,
|
||||
(EGLNativeWindowType)window->egl_window,
|
||||
NULL);
|
||||
|
||||
eglMakeCurrent(window->client->egl_display, window->egl_surface,
|
||||
window->egl_surface, window->client->egl_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(struct window *window)
|
||||
{
|
||||
if (window->client->egl_display) {
|
||||
eglMakeCurrent(window->client->egl_display, EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
}
|
||||
if (window->egl_surface) {
|
||||
eglDestroySurface(window->client->egl_display, window->egl_surface);
|
||||
}
|
||||
if (window->egl_window) {
|
||||
wl_egl_window_destroy(window->egl_window);
|
||||
}
|
||||
if (window->surface) {
|
||||
wl_surface_destroy(window->surface);
|
||||
}
|
||||
if (window->client->egl_context) {
|
||||
eglDestroyContext(window->client->egl_display, window->client->egl_context);
|
||||
}
|
||||
if (window->client->egl_display) {
|
||||
eglTerminate(window->client->egl_display);
|
||||
}
|
||||
}
|
||||
|
||||
static float
|
||||
hue_to_channel(const float *const hue, const int n)
|
||||
{
|
||||
/* convert hue to rgb channels with saturation and value equal to 1
|
||||
* https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative
|
||||
*/
|
||||
const float k = fmod(n + ((*hue) * 3 / M_PI), 6);
|
||||
return 1 - MAX(0, MIN(MIN(k, 4 - k), 1));
|
||||
}
|
||||
|
||||
static void
|
||||
hue_to_rgb(const float *const hue, float (*rgb)[3])
|
||||
{
|
||||
(*rgb)[0] = hue_to_channel(hue, 5);
|
||||
(*rgb)[1] = hue_to_channel(hue, 3);
|
||||
(*rgb)[2] = hue_to_channel(hue, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
draw(struct window *window)
|
||||
{
|
||||
struct timespec tv;
|
||||
double time;
|
||||
|
||||
/* change of colour hue (HSV space) in rad/sec */
|
||||
static const float hue_change = (2 * M_PI) / 10;
|
||||
float hue;
|
||||
float rgb[3] = {0,0,0};
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &tv);
|
||||
time = tv.tv_sec + tv.tv_nsec * 1e-9;
|
||||
|
||||
hue = fmod(time * hue_change, 2 * M_PI);
|
||||
|
||||
hue_to_rgb(&hue, &rgb);
|
||||
|
||||
glClearColor(rgb[0], rgb[1], rgb[2], 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
eglSwapBuffers(window->client->egl_display, window->egl_surface);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct wl_registry *wl_registry;
|
||||
struct libdecor *context = NULL;
|
||||
struct window *window;
|
||||
struct client *client;
|
||||
int ret = EXIT_SUCCESS;
|
||||
|
||||
client = calloc(1, sizeof(struct client));
|
||||
|
||||
client->display = wl_display_connect(NULL);
|
||||
if (!client->display) {
|
||||
fprintf(stderr, "No Wayland connection\n");
|
||||
free(client);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
wl_registry = wl_display_get_registry(client->display);
|
||||
wl_registry_add_listener(wl_registry, ®istry_listener, client);
|
||||
wl_display_roundtrip(client->display);
|
||||
|
||||
window = calloc(1, sizeof(struct window));
|
||||
window->client = client;
|
||||
window->open = true;
|
||||
window->configured = false;
|
||||
window->floating_width = window->floating_height = default_size;
|
||||
|
||||
if (!setup(window)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
context = libdecor_new(client->display, &libdecor_interface);
|
||||
window->frame = libdecor_decorate(context, window->surface,
|
||||
&frame_interface, window);
|
||||
libdecor_frame_set_app_id(window->frame, "egl-demo");
|
||||
libdecor_frame_set_title(window->frame, "EGL demo");
|
||||
libdecor_frame_map(window->frame);
|
||||
|
||||
wl_display_roundtrip(client->display);
|
||||
wl_display_roundtrip(client->display);
|
||||
|
||||
/* wait for the first configure event */
|
||||
while (!window->configured) {
|
||||
if (libdecor_dispatch(context, 0) < 0) {
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
while (window->open) {
|
||||
if (libdecor_dispatch(context, 0) < 0) {
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
draw(window);
|
||||
}
|
||||
|
||||
out:
|
||||
if (context) {
|
||||
libdecor_unref(context);
|
||||
}
|
||||
cleanup(window);
|
||||
free(window);
|
||||
free(client);
|
||||
|
||||
return ret;
|
||||
}
|
||||
136
libdecor/src/cursor-settings.c
Normal file
136
libdecor/src/cursor-settings.c
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "cursor-settings.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAS_DBUS
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
static DBusMessage *
|
||||
get_setting_sync(DBusConnection *const connection,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
DBusError error;
|
||||
dbus_bool_t success;
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
message = dbus_message_new_method_call(
|
||||
"org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop",
|
||||
"org.freedesktop.portal.Settings",
|
||||
"Read");
|
||||
|
||||
success = dbus_message_append_args(message,
|
||||
DBUS_TYPE_STRING, &key,
|
||||
DBUS_TYPE_STRING, &value,
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
if (!success)
|
||||
return NULL;
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(
|
||||
connection,
|
||||
message,
|
||||
DBUS_TIMEOUT_USE_DEFAULT,
|
||||
&error);
|
||||
|
||||
dbus_message_unref(message);
|
||||
|
||||
if (dbus_error_is_set(&error))
|
||||
return NULL;
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_type(DBusMessage *const reply,
|
||||
const int type,
|
||||
void *value)
|
||||
{
|
||||
DBusMessageIter iter[3];
|
||||
|
||||
dbus_message_iter_init(reply, &iter[0]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT)
|
||||
return false;
|
||||
|
||||
dbus_message_iter_recurse(&iter[0], &iter[1]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT)
|
||||
return false;
|
||||
|
||||
dbus_message_iter_recurse(&iter[1], &iter[2]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != type)
|
||||
return false;
|
||||
|
||||
dbus_message_iter_get_basic(&iter[2], value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
libdecor_get_cursor_settings(char **theme, int *size)
|
||||
{
|
||||
static const char name[] = "org.gnome.desktop.interface";
|
||||
static const char key_theme[] = "cursor-theme";
|
||||
static const char key_size[] = "cursor-size";
|
||||
|
||||
DBusError error;
|
||||
DBusConnection *connection;
|
||||
DBusMessage *reply;
|
||||
const char *value_theme = NULL;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
|
||||
if (dbus_error_is_set(&error))
|
||||
return false;
|
||||
|
||||
reply = get_setting_sync(connection, name, key_theme);
|
||||
if (!reply)
|
||||
return false;
|
||||
|
||||
if (!parse_type(reply, DBUS_TYPE_STRING, &value_theme)) {
|
||||
dbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
*theme = strdup(value_theme);
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
reply = get_setting_sync(connection, name, key_size);
|
||||
if (!reply)
|
||||
return false;
|
||||
|
||||
if (!parse_type(reply, DBUS_TYPE_INT32, size)) {
|
||||
dbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool
|
||||
libdecor_get_cursor_settings(char **theme, int *size)
|
||||
{
|
||||
char *env_xtheme;
|
||||
char *env_xsize;
|
||||
|
||||
env_xtheme = getenv("XCURSOR_THEME");
|
||||
if (env_xtheme != NULL)
|
||||
*theme = strdup(env_xtheme);
|
||||
|
||||
env_xsize = getenv("XCURSOR_SIZE");
|
||||
if (env_xsize != NULL)
|
||||
*size = atoi(env_xsize);
|
||||
|
||||
return env_xtheme != NULL && env_xsize != NULL;
|
||||
}
|
||||
#endif
|
||||
6
libdecor/src/cursor-settings.h
Normal file
6
libdecor/src/cursor-settings.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool
|
||||
libdecor_get_cursor_settings(char **theme, int *size);
|
||||
209
libdecor/src/libdecor-fallback.c
Normal file
209
libdecor/src/libdecor-fallback.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright © 2019 Jonas Ådahl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libdecor-fallback.h"
|
||||
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
struct libdecor_plugin_fallback {
|
||||
struct libdecor_plugin plugin;
|
||||
struct libdecor *context;
|
||||
};
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_destroy(struct libdecor_plugin *plugin)
|
||||
{
|
||||
libdecor_plugin_release(plugin);
|
||||
free(plugin);
|
||||
}
|
||||
|
||||
static int
|
||||
libdecor_plugin_fallback_get_fd(struct libdecor_plugin *plugin)
|
||||
{
|
||||
struct libdecor_plugin_fallback *plugin_fallback =
|
||||
(struct libdecor_plugin_fallback *) plugin;
|
||||
struct wl_display *wl_display =
|
||||
libdecor_get_wl_display(plugin_fallback->context);
|
||||
|
||||
return wl_display_get_fd(wl_display);
|
||||
}
|
||||
|
||||
static int
|
||||
libdecor_plugin_fallback_dispatch(struct libdecor_plugin *plugin,
|
||||
int timeout)
|
||||
{
|
||||
struct libdecor_plugin_fallback *plugin_fallback =
|
||||
(struct libdecor_plugin_fallback *) plugin;
|
||||
struct wl_display *wl_display =
|
||||
libdecor_get_wl_display(plugin_fallback->context);
|
||||
struct pollfd fds[1];
|
||||
int ret;
|
||||
int dispatch_count = 0;
|
||||
|
||||
while (wl_display_prepare_read(wl_display) != 0)
|
||||
dispatch_count += wl_display_dispatch_pending(wl_display);
|
||||
|
||||
if (wl_display_flush(wl_display) < 0 &&
|
||||
errno != EAGAIN) {
|
||||
wl_display_cancel_read(wl_display);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fds[0] = (struct pollfd) { wl_display_get_fd(wl_display), POLLIN };
|
||||
|
||||
ret = poll(fds, ARRAY_SIZE (fds), timeout);
|
||||
if (ret > 0) {
|
||||
if (fds[0].revents & POLLIN) {
|
||||
wl_display_read_events(wl_display);
|
||||
dispatch_count += wl_display_dispatch_pending(wl_display);
|
||||
return dispatch_count;
|
||||
} else {
|
||||
wl_display_cancel_read(wl_display);
|
||||
return dispatch_count;
|
||||
}
|
||||
} else if (ret == 0) {
|
||||
wl_display_cancel_read(wl_display);
|
||||
return dispatch_count;
|
||||
} else {
|
||||
wl_display_cancel_read(wl_display);
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
static struct libdecor_frame *
|
||||
libdecor_plugin_fallback_frame_new(struct libdecor_plugin *plugin)
|
||||
{
|
||||
struct libdecor_frame *frame;
|
||||
|
||||
frame = zalloc(sizeof *frame);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_frame_free(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_frame_commit(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
struct libdecor_configuration *configuration)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_frame_property_changed(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_frame_translate_coordinate(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
int content_x,
|
||||
int content_y,
|
||||
int *frame_x,
|
||||
int *frame_y)
|
||||
{
|
||||
*frame_x = content_x;
|
||||
*frame_y = content_y;
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_frame_popup_grab(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
const char *seat_name)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_fallback_frame_popup_ungrab(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
const char *seat_name)
|
||||
{
|
||||
}
|
||||
|
||||
static bool
|
||||
libdecor_plugin_fallback_configuration_get_content_size(struct libdecor_plugin *plugin,
|
||||
struct libdecor_configuration *configuration,
|
||||
struct libdecor_frame *frame,
|
||||
int *content_width,
|
||||
int *content_height)
|
||||
{
|
||||
return libdecor_configuration_get_window_size(configuration,
|
||||
content_width,
|
||||
content_height);
|
||||
}
|
||||
|
||||
static bool
|
||||
libdecor_plugin_fallback_frame_get_window_size_for(
|
||||
struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
int *window_width,
|
||||
int *window_height)
|
||||
{
|
||||
*window_width = libdecor_state_get_content_width (state);
|
||||
*window_height = libdecor_state_get_content_height (state);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct libdecor_plugin_interface fallback_plugin_iface = {
|
||||
.destroy = libdecor_plugin_fallback_destroy,
|
||||
.get_fd = libdecor_plugin_fallback_get_fd,
|
||||
.dispatch = libdecor_plugin_fallback_dispatch,
|
||||
.frame_new = libdecor_plugin_fallback_frame_new,
|
||||
.frame_free = libdecor_plugin_fallback_frame_free,
|
||||
.frame_commit = libdecor_plugin_fallback_frame_commit,
|
||||
.frame_property_changed = libdecor_plugin_fallback_frame_property_changed,
|
||||
.frame_translate_coordinate =
|
||||
libdecor_plugin_fallback_frame_translate_coordinate,
|
||||
.frame_popup_grab = libdecor_plugin_fallback_frame_popup_grab,
|
||||
.frame_popup_ungrab = libdecor_plugin_fallback_frame_popup_ungrab,
|
||||
.configuration_get_content_size = libdecor_plugin_fallback_configuration_get_content_size,
|
||||
.frame_get_window_size_for = libdecor_plugin_fallback_frame_get_window_size_for,
|
||||
};
|
||||
|
||||
struct libdecor_plugin *
|
||||
libdecor_fallback_plugin_new(struct libdecor *context)
|
||||
{
|
||||
struct libdecor_plugin_fallback *plugin;
|
||||
|
||||
plugin = zalloc(sizeof *plugin);
|
||||
libdecor_plugin_init(&plugin->plugin, context, &fallback_plugin_iface);
|
||||
plugin->context = context;
|
||||
|
||||
libdecor_notify_plugin_ready(context);
|
||||
|
||||
return &plugin->plugin;
|
||||
}
|
||||
35
libdecor/src/libdecor-fallback.h
Normal file
35
libdecor/src/libdecor-fallback.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright © 2019 Jonas Ådahl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBDECOR_FALLBACK_H
|
||||
#define LIBDECOR_FALLBACK_H
|
||||
|
||||
#include "libdecor.h"
|
||||
#include "libdecor-plugin.h"
|
||||
|
||||
struct libdecor_plugin *
|
||||
libdecor_fallback_plugin_new(struct libdecor *context);
|
||||
|
||||
#endif /* LIBDECOR_FALLBACK_H */
|
||||
215
libdecor/src/libdecor-plugin.h
Normal file
215
libdecor/src/libdecor-plugin.h
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright © 2017-2018 Red Hat Inc.
|
||||
* Copyright © 2018 Jonas Ådahl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBDECOR_PLUGIN_H
|
||||
#define LIBDECOR_PLUGIN_H
|
||||
|
||||
#include "libdecor.h"
|
||||
|
||||
struct libdecor_frame_private;
|
||||
|
||||
struct libdecor_frame {
|
||||
struct libdecor_frame_private *priv;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct libdecor_plugin_private;
|
||||
|
||||
struct libdecor_plugin {
|
||||
struct libdecor_plugin_private *priv;
|
||||
};
|
||||
|
||||
typedef struct libdecor_plugin * (* libdecor_plugin_constructor)(struct libdecor *context);
|
||||
|
||||
#define LIBDECOR_PLUGIN_PRIORITY_HIGH 1000
|
||||
#define LIBDECOR_PLUGIN_PRIORITY_MEDIUM 100
|
||||
#define LIBDECOR_PLUGIN_PRIORITY_LOW 0
|
||||
|
||||
struct libdecor_plugin_priority {
|
||||
const char *desktop;
|
||||
int priority;
|
||||
};
|
||||
|
||||
enum libdecor_plugin_capabilities {
|
||||
LIBDECOR_PLUGIN_CAPABILITY_BASE = 1 << 0,
|
||||
};
|
||||
|
||||
struct libdecor_plugin_description {
|
||||
/* API version the plugin is compatible with. */
|
||||
int api_version;
|
||||
|
||||
/* Human readable string describing the plugin. */
|
||||
char *description;
|
||||
|
||||
/* A plugin has a bitmask of capabilities. The plugin loader can use this
|
||||
* to load a plugin with the right capabilities. */
|
||||
enum libdecor_plugin_capabilities capabilities;
|
||||
|
||||
/*
|
||||
* The priorities field points to a list of per desktop priorities.
|
||||
* properties[i].desktop is matched against XDG_CURRENT_DESKTOP when
|
||||
* determining what plugin to use. The last entry in the list MUST have
|
||||
* the priorities[i].desktop pointer set to NULL as a default
|
||||
* priority.
|
||||
*/
|
||||
const struct libdecor_plugin_priority *priorities;
|
||||
|
||||
/* Vfunc used for constructing a plugin instance. */
|
||||
libdecor_plugin_constructor constructor;
|
||||
};
|
||||
|
||||
struct libdecor_plugin_interface {
|
||||
void (* destroy)(struct libdecor_plugin *plugin);
|
||||
|
||||
int (* get_fd)(struct libdecor_plugin *plugin);
|
||||
int (* dispatch)(struct libdecor_plugin *plugin,
|
||||
int timeout);
|
||||
|
||||
struct libdecor_frame * (* frame_new)(struct libdecor_plugin *plugin);
|
||||
void (* frame_free)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame);
|
||||
void (* frame_commit)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
struct libdecor_configuration *configuration);
|
||||
void (*frame_property_changed)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame);
|
||||
void (* frame_translate_coordinate)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
int content_x,
|
||||
int content_y,
|
||||
int *window_x,
|
||||
int *window_y);
|
||||
void (* frame_popup_grab)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
const char *seat_name);
|
||||
void (* frame_popup_ungrab)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
const char *seat_name);
|
||||
|
||||
bool (* frame_get_window_size_for)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
int *window_width,
|
||||
int *window_height);
|
||||
|
||||
bool (* configuration_get_content_size)(struct libdecor_plugin *plugin,
|
||||
struct libdecor_configuration *configuration,
|
||||
struct libdecor_frame *frame,
|
||||
int *content_width,
|
||||
int *content_height);
|
||||
|
||||
/* Reserved */
|
||||
void (* reserved0)(void);
|
||||
void (* reserved1)(void);
|
||||
void (* reserved2)(void);
|
||||
void (* reserved3)(void);
|
||||
void (* reserved4)(void);
|
||||
void (* reserved5)(void);
|
||||
void (* reserved6)(void);
|
||||
void (* reserved7)(void);
|
||||
void (* reserved8)(void);
|
||||
void (* reserved9)(void);
|
||||
};
|
||||
|
||||
struct wl_surface *
|
||||
libdecor_frame_get_wl_surface(struct libdecor_frame *frame);
|
||||
|
||||
int
|
||||
libdecor_frame_get_content_width(struct libdecor_frame *frame);
|
||||
|
||||
int
|
||||
libdecor_frame_get_content_height(struct libdecor_frame *frame);
|
||||
|
||||
enum libdecor_window_state
|
||||
libdecor_frame_get_window_state(struct libdecor_frame *frame);
|
||||
|
||||
void
|
||||
libdecor_frame_set_window_geometry(struct libdecor_frame *frame,
|
||||
int32_t x, int32_t y,
|
||||
int32_t width, int32_t height);
|
||||
|
||||
enum libdecor_capabilities
|
||||
libdecor_frame_get_capabilities(const struct libdecor_frame *frame);
|
||||
|
||||
void
|
||||
libdecor_frame_dismiss_popup(struct libdecor_frame *frame,
|
||||
const char *seat_name);
|
||||
|
||||
void
|
||||
libdecor_frame_toplevel_commit(struct libdecor_frame *frame);
|
||||
|
||||
struct wl_display *
|
||||
libdecor_get_wl_display(struct libdecor *context);
|
||||
|
||||
void
|
||||
libdecor_notify_plugin_ready(struct libdecor *context);
|
||||
|
||||
void
|
||||
libdecor_notify_plugin_error(struct libdecor *context,
|
||||
enum libdecor_error error,
|
||||
const char *__restrict fmt,
|
||||
...);
|
||||
|
||||
int
|
||||
libdecor_state_get_content_width (struct libdecor_state *state);
|
||||
|
||||
int
|
||||
libdecor_state_get_content_height (struct libdecor_state *state);
|
||||
|
||||
enum libdecor_window_state
|
||||
libdecor_state_get_window_state(struct libdecor_state *state);
|
||||
|
||||
bool
|
||||
libdecor_configuration_get_window_size(struct libdecor_configuration *configuration,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
int
|
||||
libdecor_plugin_init(struct libdecor_plugin *plugin,
|
||||
struct libdecor *context,
|
||||
struct libdecor_plugin_interface *iface);
|
||||
|
||||
void
|
||||
libdecor_plugin_release(struct libdecor_plugin *plugin);
|
||||
|
||||
/*
|
||||
* Get the min content size as set before with libdecor_frame_set_min_content_size().
|
||||
*/
|
||||
void
|
||||
libdecor_frame_get_min_content_size(struct libdecor_frame *frame,
|
||||
int *pcontent_width,
|
||||
int *pcontent_height);
|
||||
|
||||
/*
|
||||
* Get the max content size as set before with libdecor_frame_set_max_content_size().
|
||||
*/
|
||||
void
|
||||
libdecor_frame_get_max_content_size(struct libdecor_frame *frame,
|
||||
int *pcontent_width,
|
||||
int *pcontent_height);
|
||||
|
||||
#endif /* LIBDECOR_PLUGIN_H */
|
||||
1664
libdecor/src/libdecor.c
Normal file
1664
libdecor/src/libdecor.c
Normal file
File diff suppressed because it is too large
Load Diff
521
libdecor/src/libdecor.h
Normal file
521
libdecor/src/libdecor.h
Normal file
File diff suppressed because it is too large
Load Diff
181
libdecor/src/os-compatibility.c
Normal file
181
libdecor/src/os-compatibility.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright © 2012 Collabora, Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_MEMFD_CREATE
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "os-compatibility.h"
|
||||
|
||||
#ifndef HAVE_MKOSTEMP
|
||||
static int
|
||||
set_cloexec_or_close(int fd)
|
||||
{
|
||||
long flags;
|
||||
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1)
|
||||
goto err;
|
||||
|
||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
goto err;
|
||||
|
||||
return fd;
|
||||
|
||||
err:
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
create_tmpfile_cloexec(char *tmpname)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#ifdef HAVE_MKOSTEMP
|
||||
fd = mkostemp(tmpname, O_CLOEXEC);
|
||||
if (fd >= 0)
|
||||
unlink(tmpname);
|
||||
#else
|
||||
fd = mkstemp(tmpname);
|
||||
if (fd >= 0) {
|
||||
fd = set_cloexec_or_close(fd);
|
||||
unlink(tmpname);
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int
|
||||
os_resize_anonymous_file(int fd, off_t size)
|
||||
{
|
||||
#ifdef HAVE_POSIX_FALLOCATE
|
||||
/*
|
||||
* Filesystems that do support fallocate will return EINVAL or
|
||||
* EOPNOTSUPP. In this case we need to fall back to ftruncate
|
||||
*/
|
||||
errno = posix_fallocate(fd, 0, size);
|
||||
if (errno == 0)
|
||||
return 0;
|
||||
else if (errno != EINVAL && errno != EOPNOTSUPP)
|
||||
return -1;
|
||||
#endif
|
||||
if (ftruncate(fd, size) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new, unique, anonymous file of the given size, and
|
||||
* return the file descriptor for it. The file descriptor is set
|
||||
* CLOEXEC. The file is immediately suitable for mmap()'ing
|
||||
* the given size at offset zero.
|
||||
*
|
||||
* The file should not have a permanent backing store like a disk,
|
||||
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
|
||||
*
|
||||
* The file name is deleted from the file system.
|
||||
*
|
||||
* The file is suitable for buffer sharing between processes by
|
||||
* transmitting the file descriptor over Unix sockets using the
|
||||
* SCM_RIGHTS methods.
|
||||
*
|
||||
* If the C library implements posix_fallocate(), it is used to
|
||||
* guarantee that disk space is available for the file at the
|
||||
* given size. If disk space is insufficient, errno is set to ENOSPC.
|
||||
* If posix_fallocate() is not supported, program may receive
|
||||
* SIGBUS on accessing mmap()'ed file contents instead.
|
||||
*
|
||||
* If the C library implements memfd_create(), it is used to create the
|
||||
* file purely in memory, without any backing file name on the file
|
||||
* system, and then sealing off the possibility of shrinking it. This
|
||||
* can then be checked before accessing mmap()'ed file contents, to
|
||||
* make sure SIGBUS can't happen. It also avoids requiring
|
||||
* XDG_RUNTIME_DIR.
|
||||
*/
|
||||
int
|
||||
os_create_anonymous_file(off_t size)
|
||||
{
|
||||
static const char template[] = "/libdecor-shared-XXXXXX";
|
||||
const char *path;
|
||||
char *name;
|
||||
int fd;
|
||||
|
||||
#ifdef HAVE_MEMFD_CREATE
|
||||
fd = memfd_create("libdecor", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
if (fd >= 0) {
|
||||
/* We can add this seal before calling posix_fallocate(), as
|
||||
* the file is currently zero-sized anyway.
|
||||
*
|
||||
* There is also no need to check for the return value, we
|
||||
* couldn't do anything with it anyway.
|
||||
*/
|
||||
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
path = getenv("XDG_RUNTIME_DIR");
|
||||
if (!path) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = malloc(strlen(path) + sizeof(template));
|
||||
if (!name)
|
||||
return -1;
|
||||
|
||||
strcpy(name, path);
|
||||
strcat(name, template);
|
||||
|
||||
fd = create_tmpfile_cloexec(name);
|
||||
|
||||
free(name);
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (os_resize_anonymous_file(fd, size) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
34
libdecor/src/os-compatibility.h
Normal file
34
libdecor/src/os-compatibility.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright © 2012 Collabora, Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef OS_COMPATIBILITY_H
|
||||
#define OS_COMPATIBILITY_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int
|
||||
os_create_anonymous_file(off_t size);
|
||||
|
||||
#endif /* OS_COMPATIBILITY_H */
|
||||
255
libdecor/src/plugins/cairo/libdecor-cairo-blur.c
Normal file
255
libdecor/src/plugins/cairo/libdecor-cairo-blur.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
* Copyright © 2012 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* functions 'blur_surface' and 'render_shadow' from weston project:
|
||||
* https://gitlab.freedesktop.org/wayland/weston/raw/master/shared/cairo-util.c
|
||||
*/
|
||||
|
||||
#include "libdecor-cairo-blur.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Compile-time computation of number of items in a hardcoded array.
|
||||
*
|
||||
* @param a the array being measured.
|
||||
* @return the number of items hardcoded into the array.
|
||||
*/
|
||||
#ifndef ARRAY_LENGTH
|
||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||
#endif
|
||||
|
||||
int
|
||||
blur_surface(cairo_surface_t *surface, int margin)
|
||||
{
|
||||
int32_t width, height, stride, x, y, z, w;
|
||||
uint8_t *src, *dst;
|
||||
uint32_t *s, *d, a, p;
|
||||
int i, j, k, size, half;
|
||||
uint32_t kernel[71];
|
||||
double f;
|
||||
|
||||
size = ARRAY_LENGTH(kernel);
|
||||
width = cairo_image_surface_get_width(surface);
|
||||
height = cairo_image_surface_get_height(surface);
|
||||
stride = cairo_image_surface_get_stride(surface);
|
||||
src = cairo_image_surface_get_data(surface);
|
||||
|
||||
dst = malloc(height * stride);
|
||||
if (dst == NULL)
|
||||
return -1;
|
||||
|
||||
half = size / 2;
|
||||
a = 0;
|
||||
for (i = 0; i < size; i++) {
|
||||
f = (i - half);
|
||||
kernel[i] = exp(- f * f / ARRAY_LENGTH(kernel)) * 10000;
|
||||
a += kernel[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
s = (uint32_t *) (src + i * stride);
|
||||
d = (uint32_t *) (dst + i * stride);
|
||||
for (j = 0; j < width; j++) {
|
||||
if (margin < j && j < width - margin) {
|
||||
d[j] = s[j];
|
||||
continue;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
w = 0;
|
||||
for (k = 0; k < size; k++) {
|
||||
if (j - half + k < 0 || j - half + k >= width)
|
||||
continue;
|
||||
p = s[j - half + k];
|
||||
|
||||
x += (p >> 24) * kernel[k];
|
||||
y += ((p >> 16) & 0xff) * kernel[k];
|
||||
z += ((p >> 8) & 0xff) * kernel[k];
|
||||
w += (p & 0xff) * kernel[k];
|
||||
}
|
||||
d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
s = (uint32_t *) (dst + i * stride);
|
||||
d = (uint32_t *) (src + i * stride);
|
||||
for (j = 0; j < width; j++) {
|
||||
if (margin <= i && i < height - margin) {
|
||||
d[j] = s[j];
|
||||
continue;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
w = 0;
|
||||
for (k = 0; k < size; k++) {
|
||||
if (i - half + k < 0 || i - half + k >= height)
|
||||
continue;
|
||||
s = (uint32_t *) (dst + (i - half + k) * stride);
|
||||
p = s[j];
|
||||
|
||||
x += (p >> 24) * kernel[k];
|
||||
y += ((p >> 16) & 0xff) * kernel[k];
|
||||
z += ((p >> 8) & 0xff) * kernel[k];
|
||||
w += (p & 0xff) * kernel[k];
|
||||
}
|
||||
d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a;
|
||||
}
|
||||
}
|
||||
|
||||
free(dst);
|
||||
cairo_surface_mark_dirty(surface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
render_shadow(cairo_t *cr, cairo_surface_t *surface,
|
||||
int x, int y, int width, int height, int margin, int top_margin)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_matrix_t matrix;
|
||||
int i, fx, fy, shadow_height, shadow_width;
|
||||
|
||||
cairo_set_source_rgba(cr, 0, 0, 0, 0.45);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* when fy is set, then we are working with lower corners,
|
||||
* when fx is set, then we are working with right corners
|
||||
*
|
||||
* 00 ------- 01
|
||||
* | |
|
||||
* | |
|
||||
* 10 ------- 11
|
||||
*/
|
||||
fx = i & 1;
|
||||
fy = i >> 1;
|
||||
|
||||
cairo_matrix_init_translate(&matrix,
|
||||
-x + fx * (128 - width),
|
||||
-y + fy * (128 - height));
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
|
||||
shadow_width = margin;
|
||||
shadow_height = fy ? margin : top_margin;
|
||||
|
||||
/* if the shadows together are greater than the surface, we need
|
||||
* to fix it - set the shadow size to the half of
|
||||
* the size of surface. Also handle the case when the size is
|
||||
* not divisible by 2. In that case we need one part of the
|
||||
* shadow to be one pixel greater. !fy or !fx, respectively,
|
||||
* will do the work.
|
||||
*/
|
||||
if (height < 2 * shadow_height)
|
||||
shadow_height = (height + !fy) / 2;
|
||||
|
||||
if (width < 2 * shadow_width)
|
||||
shadow_width = (width + !fx) / 2;
|
||||
|
||||
cairo_reset_clip(cr);
|
||||
cairo_rectangle(cr,
|
||||
x + fx * (width - shadow_width),
|
||||
y + fy * (height - shadow_height),
|
||||
shadow_width, shadow_height);
|
||||
cairo_clip (cr);
|
||||
cairo_mask(cr, pattern);
|
||||
}
|
||||
|
||||
|
||||
shadow_width = width - 2 * margin;
|
||||
shadow_height = top_margin;
|
||||
if (height < 2 * shadow_height)
|
||||
shadow_height = height / 2;
|
||||
|
||||
if (shadow_width > 0 && shadow_height) {
|
||||
/* Top stretch */
|
||||
cairo_matrix_init_translate(&matrix, 60, 0);
|
||||
cairo_matrix_scale(&matrix, 8.0 / width, 1);
|
||||
cairo_matrix_translate(&matrix, -x - width / 2, -y);
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
cairo_rectangle(cr, x + margin, y, shadow_width, shadow_height);
|
||||
|
||||
cairo_reset_clip(cr);
|
||||
cairo_rectangle(cr,
|
||||
x + margin, y,
|
||||
shadow_width, shadow_height);
|
||||
cairo_clip (cr);
|
||||
cairo_mask(cr, pattern);
|
||||
|
||||
/* Bottom stretch */
|
||||
cairo_matrix_translate(&matrix, 0, -height + 128);
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
|
||||
cairo_reset_clip(cr);
|
||||
cairo_rectangle(cr, x + margin, y + height - margin,
|
||||
shadow_width, margin);
|
||||
cairo_clip (cr);
|
||||
cairo_mask(cr, pattern);
|
||||
}
|
||||
|
||||
shadow_width = margin;
|
||||
if (width < 2 * shadow_width)
|
||||
shadow_width = width / 2;
|
||||
|
||||
shadow_height = height - margin - top_margin;
|
||||
|
||||
/* if height is smaller than sum of margins,
|
||||
* then the shadow is already done by the corners */
|
||||
if (shadow_height > 0 && shadow_width) {
|
||||
/* Left stretch */
|
||||
cairo_matrix_init_translate(&matrix, 0, 60);
|
||||
cairo_matrix_scale(&matrix, 1, 8.0 / height);
|
||||
cairo_matrix_translate(&matrix, -x, -y - height / 2);
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
cairo_reset_clip(cr);
|
||||
cairo_rectangle(cr, x, y + top_margin,
|
||||
shadow_width, shadow_height);
|
||||
cairo_clip (cr);
|
||||
cairo_mask(cr, pattern);
|
||||
|
||||
/* Right stretch */
|
||||
cairo_matrix_translate(&matrix, -width + 128, 0);
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
cairo_rectangle(cr, x + width - shadow_width, y + top_margin,
|
||||
shadow_width, shadow_height);
|
||||
cairo_reset_clip(cr);
|
||||
cairo_clip (cr);
|
||||
cairo_mask(cr, pattern);
|
||||
}
|
||||
|
||||
cairo_pattern_destroy(pattern);
|
||||
cairo_reset_clip(cr);
|
||||
}
|
||||
10
libdecor/src/plugins/cairo/libdecor-cairo-blur.h
Normal file
10
libdecor/src/plugins/cairo/libdecor-cairo-blur.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
int
|
||||
blur_surface(cairo_surface_t *surface, int margin);
|
||||
|
||||
void
|
||||
render_shadow(cairo_t *cr, cairo_surface_t *surface,
|
||||
int x, int y, int width, int height, int margin, int top_margin);
|
||||
2824
libdecor/src/plugins/cairo/libdecor-cairo.c
Normal file
2824
libdecor/src/plugins/cairo/libdecor-cairo.c
Normal file
File diff suppressed because it is too large
Load Diff
176
libdecor/src/plugins/dummy/libdecor-dummy.c
Normal file
176
libdecor/src/plugins/dummy/libdecor-dummy.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright © 2021 Jonas Ådahl
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libdecor-plugin.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdlib.h>
|
||||
#include <wayland-cursor.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
struct libdecor_plugin_dummy {
|
||||
struct libdecor_plugin plugin;
|
||||
struct libdecor *context;
|
||||
};
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_destroy(struct libdecor_plugin *plugin)
|
||||
{
|
||||
struct libdecor_plugin_dummy *plugin_dummy =
|
||||
(struct libdecor_plugin_dummy *) plugin;
|
||||
|
||||
free(plugin_dummy);
|
||||
}
|
||||
|
||||
static struct libdecor_frame *
|
||||
libdecor_plugin_dummy_frame_new(struct libdecor_plugin *plugin)
|
||||
{
|
||||
struct libdecor_frame *frame;
|
||||
|
||||
frame = zalloc(sizeof *frame);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_frame_free(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_frame_commit(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
struct libdecor_configuration *configuration)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_frame_property_changed(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_frame_translate_coordinate(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
int content_x,
|
||||
int content_y,
|
||||
int *frame_x,
|
||||
int *frame_y)
|
||||
{
|
||||
*frame_x = content_x;
|
||||
*frame_y = content_y;
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_frame_popup_grab(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
const char *seat_name)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
libdecor_plugin_dummy_frame_popup_ungrab(struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
const char *seat_name)
|
||||
{
|
||||
}
|
||||
|
||||
static bool
|
||||
libdecor_plugin_dummy_configuration_get_content_size(
|
||||
struct libdecor_plugin *plugin,
|
||||
struct libdecor_configuration *configuration,
|
||||
struct libdecor_frame *frame,
|
||||
int *content_width,
|
||||
int *content_height)
|
||||
{
|
||||
return libdecor_configuration_get_window_size(configuration,
|
||||
content_width,
|
||||
content_height);
|
||||
}
|
||||
|
||||
static bool
|
||||
libdecor_plugin_dummy_frame_get_window_size_for(
|
||||
struct libdecor_plugin *plugin,
|
||||
struct libdecor_frame *frame,
|
||||
struct libdecor_state *state,
|
||||
int *window_width,
|
||||
int *window_height)
|
||||
{
|
||||
*window_width = libdecor_state_get_content_width (state);
|
||||
*window_height = libdecor_state_get_content_height (state);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct libdecor_plugin_interface dummy_plugin_iface = {
|
||||
.destroy = libdecor_plugin_dummy_destroy,
|
||||
|
||||
.frame_new = libdecor_plugin_dummy_frame_new,
|
||||
.frame_free = libdecor_plugin_dummy_frame_free,
|
||||
.frame_commit = libdecor_plugin_dummy_frame_commit,
|
||||
.frame_property_changed = libdecor_plugin_dummy_frame_property_changed,
|
||||
.frame_translate_coordinate =
|
||||
libdecor_plugin_dummy_frame_translate_coordinate,
|
||||
.frame_popup_grab = libdecor_plugin_dummy_frame_popup_grab,
|
||||
.frame_popup_ungrab = libdecor_plugin_dummy_frame_popup_ungrab,
|
||||
|
||||
.configuration_get_content_size =
|
||||
libdecor_plugin_dummy_configuration_get_content_size,
|
||||
.frame_get_window_size_for =
|
||||
libdecor_plugin_dummy_frame_get_window_size_for,
|
||||
};
|
||||
|
||||
static struct libdecor_plugin *
|
||||
libdecor_plugin_new(struct libdecor *context)
|
||||
{
|
||||
struct libdecor_plugin_dummy *plugin_dummy;
|
||||
|
||||
plugin_dummy = zalloc(sizeof *plugin_dummy);
|
||||
plugin_dummy->plugin.iface = &dummy_plugin_iface;
|
||||
plugin_dummy->context = context;
|
||||
|
||||
libdecor_notify_plugin_ready(context);
|
||||
|
||||
return &plugin_dummy->plugin;
|
||||
}
|
||||
|
||||
static struct libdecor_plugin_priority priorities[] = {
|
||||
{ NULL, LIBDECOR_PLUGIN_PRIORITY_LOW }
|
||||
};
|
||||
|
||||
LIBDECOR_EXPORT const struct libdecor_plugin_description
|
||||
libdecor_plugin_description = {
|
||||
.api_version = LIBDECOR_PLUGIN_API_VERSION,
|
||||
.description = "dummy libdecor plugin",
|
||||
.priorities = priorities,
|
||||
.constructor = libdecor_plugin_new,
|
||||
};
|
||||
2762
libdecor/src/plugins/gtk/libdecor-gtk.c
Normal file
2762
libdecor/src/plugins/gtk/libdecor-gtk.c
Normal file
File diff suppressed because it is too large
Load Diff
48
libdecor/src/utils.h
Normal file
48
libdecor/src/utils.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#ifndef ARRAY_LENGTH
|
||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
static inline void *
|
||||
zalloc(size_t size)
|
||||
{
|
||||
return calloc(1, size);
|
||||
}
|
||||
|
||||
#endif /* UTILS_H */
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Make include file for the Fast Light Tool Kit (FLTK).
|
||||
#
|
||||
# Copyright 1998-2021 by Bill Spitzak and others.
|
||||
# Copyright 1998-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
|
||||
@@ -24,7 +24,7 @@ FL_ABI_VERSION = @FL_ABI_VERSION@
|
||||
|
||||
FLTK_VERSION = @FLTK_VERSION@
|
||||
|
||||
# FLTK configuration options: BUILD = { WIN | OSX | X11 | XFT }
|
||||
# FLTK configuration options: BUILD = { WIN | OSX | X11 | XFT | WAYLAND }
|
||||
|
||||
BUILD = @BUILD@
|
||||
|
||||
@@ -105,6 +105,9 @@ FLTKCAIROOPTION = @FLTKCAIROOPTION@
|
||||
LINKSHARED = @DSOLINK@ @LINKSHARED@ $(IMAGELIBS) $(CAIROLIBS)
|
||||
IMAGELIBS = -L../lib @IMAGELIBS@
|
||||
|
||||
# optional extra build step for libdecor:
|
||||
LIBDECORDIR = @LIBDECORDIR@
|
||||
|
||||
# image libraries to build...
|
||||
IMAGEDIRS = @JPEG@ @ZLIB@ @PNG@
|
||||
CAIRODIR = @CAIRODIR@
|
||||
|
||||
@@ -195,10 +195,11 @@ if (FLTK_USE_X11)
|
||||
# X11 (including APPLE with X11)
|
||||
|
||||
set (DRIVER_FILES
|
||||
drivers/Posix/Fl_Posix_System_Driver.cxx
|
||||
drivers/Posix/Fl_Posix_Printer_Driver.cxx
|
||||
drivers/X11/Fl_X11_Screen_Driver.cxx
|
||||
drivers/X11/Fl_X11_Window_Driver.cxx
|
||||
drivers/Posix/Fl_Posix_System_Driver.cxx
|
||||
drivers/Unix/Fl_Unix_System_Driver.cxx
|
||||
drivers/X11/Fl_X11_System_Driver.cxx
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
|
||||
@@ -241,6 +242,25 @@ if (FLTK_USE_X11)
|
||||
drivers/Xlib/Fl_Font.H
|
||||
)
|
||||
|
||||
elseif (OPTION_USE_WAYLAND)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set (DRIVER_FILES
|
||||
drivers/Posix/Fl_Posix_System_Driver.cxx
|
||||
drivers/Posix/Fl_Posix_Printer_Driver.cxx
|
||||
drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
|
||||
drivers/Wayland/Fl_Wayland_Window_Driver.cxx
|
||||
drivers/Wayland/Fl_Wayland_System_Driver.cxx
|
||||
drivers/Unix/Fl_Unix_System_Driver.cxx
|
||||
drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
|
||||
drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
|
||||
drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx
|
||||
drivers/Wayland/Fl_wayland.cxx
|
||||
drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
|
||||
Fl_Native_File_Chooser_FLTK.cxx
|
||||
Fl_Native_File_Chooser_GTK.cxx
|
||||
Fl_Native_File_Chooser_Kdialog.cxx
|
||||
)
|
||||
|
||||
elseif (APPLE)
|
||||
|
||||
# Apple Quartz
|
||||
@@ -353,6 +373,8 @@ set (GL_DRIVER_FILES
|
||||
)
|
||||
if (FLTK_USE_X11)
|
||||
set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/X11/Fl_X11_Gl_Window_Driver.cxx)
|
||||
elseif (OPTION_USE_WAYLAND)
|
||||
set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx)
|
||||
elseif (APPLE)
|
||||
set (GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx)
|
||||
elseif (WIN32)
|
||||
@@ -410,6 +432,40 @@ if (FLTK_USE_X11)
|
||||
endif (NOT USE_XFT)
|
||||
endif (FLTK_USE_X11)
|
||||
|
||||
if (OPTION_USE_WAYLAND)
|
||||
pkg_check_modules(DBUS dbus-1)
|
||||
include_directories(${DBUS_INCLUDE_DIRS})
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_CURRENT_BINARY_DIR} -fPIC -D_GNU_SOURCE -DHAS_DBUS")
|
||||
if (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_SYSTEM_LIBDECOR")
|
||||
get_filename_component(PATH_TO_SHARED_LIBS ${HAVE_LIB_PANGO} DIRECTORY)
|
||||
set (LIBDECOR_PLUGIN_DIR "\\\"${PATH_TO_SHARED_LIBS}/libdecor/plugins-1\\\" " )
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLIBDECOR_PLUGIN_DIR=${LIBDECOR_PLUGIN_DIR} ")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_SYSTEM_LIBDECOR")
|
||||
else()
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}/../libdecor/src -DLIBDECOR_PLUGIN_API_VERSION=1 -DLIBDECOR_PLUGIN_DIR=\\\"/usr/local/lib\\\" ")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_SYSTEM_LIBDECOR=0")
|
||||
endif (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
|
||||
if (GTK_FOUND)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_GTK")
|
||||
endif (GTK_FOUND)
|
||||
|
||||
list (APPEND CFILES
|
||||
xutf8/keysym2Ucs.c
|
||||
scandir_posix.c
|
||||
../libdecor/src/cursor-settings.c
|
||||
../libdecor/build/fl_libdecor-plugins.c
|
||||
)
|
||||
if (NOT OPTION_USE_SYSTEM_LIBDECOR)
|
||||
list (APPEND CFILES
|
||||
../libdecor/build/fl_libdecor.c
|
||||
../libdecor/src/os-compatibility.c
|
||||
../libdecor/src/plugins/cairo/libdecor-cairo-blur.c
|
||||
)
|
||||
endif (NOT OPTION_USE_SYSTEM_LIBDECOR)
|
||||
endif (OPTION_USE_WAYLAND)
|
||||
|
||||
if (WIN32)
|
||||
list (APPEND CFILES
|
||||
scandir_win32.c
|
||||
@@ -495,6 +551,52 @@ if (USE_XFT)
|
||||
endif (LIB_fontconfig)
|
||||
endif (USE_XFT)
|
||||
|
||||
if (OPTION_USE_WAYLAND)
|
||||
add_custom_command(
|
||||
OUTPUT xdg-shell-protocol.c xdg-shell-client-protocol.h
|
||||
COMMAND wayland-scanner private-code /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.c
|
||||
COMMAND wayland-scanner client-header /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h
|
||||
DEPENDS /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml
|
||||
VERBATIM
|
||||
)
|
||||
list (APPEND STATIC_FILES "xdg-shell-protocol.c")
|
||||
list (APPEND SHARED_FILES "xdg-shell-protocol.c")
|
||||
if (NOT OPTION_USE_SYSTEM_LIBDECOR)
|
||||
add_custom_command(
|
||||
OUTPUT xdg-decoration-protocol.c xdg-decoration-client-protocol.h
|
||||
COMMAND wayland-scanner private-code /usr/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml xdg-decoration-protocol.c
|
||||
COMMAND wayland-scanner client-header /usr/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml xdg-decoration-client-protocol.h
|
||||
DEPENDS /usr/share/wayland-protocols/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
|
||||
VERBATIM
|
||||
)
|
||||
list (APPEND STATIC_FILES "xdg-decoration-protocol.c")
|
||||
list (APPEND SHARED_FILES "xdg-decoration-protocol.c")
|
||||
endif (NOT OPTION_USE_SYSTEM_LIBDECOR)
|
||||
add_custom_command(
|
||||
OUTPUT text-input-protocol.c text-input-client-protocol.h
|
||||
COMMAND wayland-scanner private-code /usr/share/wayland-protocols/unstable/text-input/text-input-unstable-v3.xml text-input-protocol.c
|
||||
COMMAND wayland-scanner client-header /usr/share/wayland-protocols/unstable/text-input/text-input-unstable-v3.xml text-input-client-protocol.h
|
||||
DEPENDS /usr/share/wayland-protocols/unstable/text-input/text-input-unstable-v3.xml
|
||||
VERBATIM
|
||||
)
|
||||
list (APPEND STATIC_FILES "text-input-protocol.c")
|
||||
list (APPEND SHARED_FILES "text-input-protocol.c")
|
||||
|
||||
if (OPTION_USE_GL)
|
||||
list (APPEND OPTIONAL_LIBS "-lwayland-egl -lEGL")
|
||||
endif (OPTION_USE_GL)
|
||||
if (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
list (APPEND OPTIONAL_LIBS "-ldecor-0")
|
||||
endif (OPTION_USE_SYSTEM_LIBDECOR)
|
||||
list (APPEND OPTIONAL_LIBS "-lwayland-cursor -lwayland-client -lxkbcommon -ldl -ldbus-1")
|
||||
if (GTK_FOUND)
|
||||
list (APPEND OPTIONAL_LIBS ${GTK_LDFLAGS} )
|
||||
endif (GTK_FOUND)
|
||||
if (NOT OPTION_BUILD_SHARED_LIBS)
|
||||
list (APPEND OPTIONAL_LIBS "-no-pie")
|
||||
endif (NOT OPTION_BUILD_SHARED_LIBS)
|
||||
endif (OPTION_USE_WAYLAND)
|
||||
|
||||
#######################################################################
|
||||
|
||||
FL_ADD_LIBRARY (fltk STATIC "${STATIC_FILES}")
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include "Fl_System_Driver.H"
|
||||
#include "Fl_Window_Driver.H"
|
||||
#include <FL/Fl_Menu_Window.H>
|
||||
#include <FL/Fl_Menu_.H>
|
||||
#include <FL/fl_draw.H>
|
||||
@@ -116,10 +117,13 @@ public:
|
||||
|
||||
// each vertical menu has one of these:
|
||||
class menuwindow : public Fl_Menu_Window {
|
||||
friend class Fl_Window_Driver;
|
||||
friend class Fl_Menu_Item;
|
||||
void draw();
|
||||
void drawentry(const Fl_Menu_Item*, int i, int erase);
|
||||
int handle_part1(int);
|
||||
int handle_part2(int e, int ret);
|
||||
static Fl_Window *parent_;
|
||||
public:
|
||||
menutitle* title;
|
||||
int handle(int);
|
||||
@@ -141,6 +145,12 @@ public:
|
||||
int is_inside(int x, int y);
|
||||
};
|
||||
|
||||
Fl_Window *menuwindow::parent_ = NULL;
|
||||
|
||||
Fl_Window *Fl_Window_Driver::menu_parent() {
|
||||
return menuwindow::parent_;
|
||||
}
|
||||
|
||||
extern char fl_draw_shortcut;
|
||||
|
||||
/**
|
||||
@@ -293,7 +303,7 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
int tx = X, ty = Y;
|
||||
|
||||
Fl::screen_work_area(scr_x, scr_y, scr_w, scr_h);
|
||||
Fl_Window_Driver::driver(this)->menu_window_area(scr_x, scr_y, scr_w, scr_h);
|
||||
if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w;
|
||||
|
||||
end();
|
||||
@@ -439,14 +449,14 @@ void menuwindow::autoscroll(int n) {
|
||||
int Y = y()+Fl::box_dx(box())+2+n*itemheight;
|
||||
|
||||
int xx, ww;
|
||||
Fl::screen_work_area(xx, scr_y, ww, scr_h);
|
||||
Fl_Window_Driver::driver(this)->menu_window_area(xx, scr_y, ww, scr_h);
|
||||
if (Y <= scr_y) Y = scr_y-Y+10;
|
||||
else {
|
||||
Y = Y+itemheight-scr_h-scr_y;
|
||||
if (Y < 0) return;
|
||||
Y = -Y-10;
|
||||
}
|
||||
Fl_Menu_Window::position(x(), y()+Y);
|
||||
Fl_Window_Driver::driver(this)->reposition_menu_window(x(), y()+Y);
|
||||
// y(y()+Y); // don't wait for response from X
|
||||
}
|
||||
|
||||
@@ -885,6 +895,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
|
||||
|
||||
button = pbutton;
|
||||
if (pbutton && pbutton->window()) {
|
||||
menuwindow::parent_ = pbutton->top_window();
|
||||
for (Fl_Window* w = pbutton->window(); w; w = w->window()) {
|
||||
X += w->x();
|
||||
Y += w->y();
|
||||
@@ -892,6 +903,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
|
||||
} else {
|
||||
X += Fl::event_x_root()-Fl::event_x();
|
||||
Y += Fl::event_y_root()-Fl::event_y();
|
||||
menuwindow::parent_ = Fl::first_window();
|
||||
}
|
||||
menuwindow mw(this, X, Y, W, H, initial_item, title, menubar);
|
||||
Fl::grab(mw);
|
||||
@@ -991,7 +1003,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
|
||||
int dy = n->y()-nY;
|
||||
int dx = n->x()-nX;
|
||||
int waX, waY, waW, waH;
|
||||
Fl::screen_work_area(waX, waY, waW, waH, X, Y);
|
||||
Fl_Window_Driver::driver(n)->menu_window_area(waX, waY, waW, waH, Fl::screen_num(X, Y));
|
||||
for (int menu = 0; menu <= pp.menu_number; menu++) {
|
||||
menuwindow* tt = pp.p[menu];
|
||||
int nx = tt->x()+dx; if (nx < waX) {nx = waX; dx = -tt->x() + waX;}
|
||||
@@ -1030,6 +1042,7 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
|
||||
while (pp.nummenus>1) delete pp.p[--pp.nummenus];
|
||||
mw.hide();
|
||||
Fl::grab(0);
|
||||
menuwindow::parent_ = NULL;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
@@ -772,7 +772,7 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper()
|
||||
Fl_Event_Dispatch old_dispatch = Fl::event_dispatch();
|
||||
// prevent FLTK from processing any event
|
||||
Fl::event_dispatch(fnfc_dispatch);
|
||||
|
||||
void *control = ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(NULL);
|
||||
gint response_id = GTK_RESPONSE_NONE;
|
||||
fl_g_signal_connect_data(gtkw_ptr, "response", G_CALLBACK(run_response_handler), &response_id, NULL, (GConnectFlags) 0);
|
||||
while (response_id == GTK_RESPONSE_NONE) { // loop that shows the GTK dialog window
|
||||
@@ -836,6 +836,7 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper()
|
||||
while (fl_gtk_events_pending ()) fl_gtk_main_iteration ();
|
||||
|
||||
Fl::event_dispatch(old_dispatch);
|
||||
if (control) ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(control);
|
||||
|
||||
return result;
|
||||
} // fl_gtk_chooser_wrapper
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <FL/Fl_Native_File_Chooser.H>
|
||||
#include "Fl_Native_File_Chooser_Kdialog.H"
|
||||
#include "Fl_Window_Driver.H"
|
||||
#include "drivers/Unix/Fl_Unix_System_Driver.H"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -129,12 +130,14 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() {
|
||||
Fl_Event_Dispatch old_dispatch = Fl::event_dispatch();
|
||||
// prevent FLTK from processing any event
|
||||
Fl::event_dispatch(fnfc_dispatch);
|
||||
void *control = ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(NULL);
|
||||
// run event loop until pipe finishes
|
||||
while (data.fd >= 0) Fl::wait();
|
||||
Fl::remove_fd(fileno(pipe));
|
||||
pclose(pipe);
|
||||
// return to previous event processing by FLTK
|
||||
Fl::event_dispatch(old_dispatch);
|
||||
if (control) ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(control);
|
||||
if (data.all_files) {
|
||||
// process text received from pipe
|
||||
if (data.all_files[strlen(data.all_files)-1] == '\n') data.all_files[strlen(data.all_files)-1] = 0;
|
||||
|
||||
@@ -184,6 +184,12 @@ public:
|
||||
int /*dest_x*/, int /*dest_y*/,
|
||||
void (*)(void*, int,int,int,int), void*) { return 0; }
|
||||
static inline Fl_Window_Driver* driver(const Fl_Window *win) {return win->pWindowDriver;}
|
||||
|
||||
// --- support for menu windows
|
||||
// the default implementation of next 2 members is most probably enough
|
||||
virtual void reposition_menu_window(int x, int y);
|
||||
virtual void menu_window_area(int &X, int &Y, int &W, int &H, int nscreen = -1);
|
||||
static Fl_Window *menu_parent();
|
||||
};
|
||||
|
||||
#endif // FL_WINDOW_DRIVER_H
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/platform.H>
|
||||
#include "Fl_Screen_Driver.H"
|
||||
|
||||
extern void fl_throw_focus(Fl_Widget *o);
|
||||
|
||||
@@ -247,6 +248,17 @@ void Fl_Window_Driver::resize_after_scale_change(int ns, float old_f, float new_
|
||||
is_a_rescale_ = false;
|
||||
}
|
||||
|
||||
void Fl_Window_Driver::reposition_menu_window(int x, int y) {
|
||||
if (y != pWindow->y() || x != pWindow->x()) pWindow->Fl_Widget::position(x, y);
|
||||
}
|
||||
|
||||
void Fl_Window_Driver::menu_window_area(int &X, int &Y, int &W, int &H, int nscreen) {
|
||||
int mx, my;
|
||||
Fl_Screen_Driver *scr_driver = Fl::screen_driver();
|
||||
if (nscreen < 0) nscreen = scr_driver->get_mouse(mx, my);
|
||||
scr_driver->screen_work_area(X, Y, W, H, nscreen);
|
||||
}
|
||||
|
||||
/**
|
||||
\}
|
||||
\endcond
|
||||
|
||||
289
src/Fl_x.cxx
289
src/Fl_x.cxx
@@ -78,155 +78,16 @@ static bool have_xfixes = false;
|
||||
# include <X11/extensions/Xrender.h>
|
||||
# endif
|
||||
|
||||
# if USE_POLL
|
||||
# include <poll.h>
|
||||
# else
|
||||
# define POLLIN 1
|
||||
# endif /* USE_POLL */
|
||||
|
||||
extern Fl_Widget *fl_selection_requestor;
|
||||
|
||||
static void open_display_i(Display *d); // open display (internal)
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Hack to speed up bg box drawing - aka "boxcheat":
|
||||
// If the boxtype of a window is a filled rectangle, we can make the
|
||||
// redisplay *look* faster by using X's background pixel erasing.
|
||||
// This is done by setting a flag when the window is shown for the first time.
|
||||
|
||||
// Note to FLTK devs:
|
||||
// This can cause unexpected behavior, for instance if the box() or
|
||||
// color() of a window is changed after show(), and it does presumably not
|
||||
// have much effect on current systems (compared to 1998).
|
||||
// It is also fragile WRT checking the box type if any other scheme than
|
||||
// the default scheme is loaded.
|
||||
// Hence this is disabled since FLTK 1.4.0 (AlbrechtS Feb 02, 2022)
|
||||
|
||||
// Note to FLTK users:
|
||||
// You may define ENABLE_BOXCHEAT to use it anyway but please tell the
|
||||
// FLTK devs why you believe that you need it. Should we re-enable it?
|
||||
|
||||
#ifdef ENABLE_BOXCHEAT
|
||||
static int fl_background_pixel = -1;
|
||||
static inline int can_boxcheat(Fl_Boxtype b) {
|
||||
return (b == 1 || ((b & 2) && b <= 15));
|
||||
}
|
||||
#endif // (ENABLE_BOXCHEAT)
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// interface to poll/select call:
|
||||
|
||||
# if USE_POLL
|
||||
|
||||
# include <poll.h>
|
||||
static pollfd *pollfds = 0;
|
||||
|
||||
# else
|
||||
# if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
# endif /* HAVE_SYS_SELECT_H */
|
||||
|
||||
// The following #define is only needed for HP-UX 9.x and earlier:
|
||||
//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
|
||||
|
||||
static fd_set fdsets[3];
|
||||
static int maxfd;
|
||||
# define POLLIN 1
|
||||
# define POLLOUT 4
|
||||
# define POLLERR 8
|
||||
|
||||
# endif /* USE_POLL */
|
||||
|
||||
static int nfds = 0;
|
||||
static int fd_array_size = 0;
|
||||
struct FD {
|
||||
# if !USE_POLL
|
||||
int fd;
|
||||
short events;
|
||||
# endif
|
||||
void (*cb)(int, void*);
|
||||
void* arg;
|
||||
};
|
||||
|
||||
static FD *fd = 0;
|
||||
|
||||
void Fl_X11_System_Driver::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
|
||||
remove_fd(n,events);
|
||||
int i = nfds++;
|
||||
if (i >= fd_array_size) {
|
||||
FD *temp;
|
||||
fd_array_size = 2*fd_array_size+1;
|
||||
|
||||
if (!fd) temp = (FD*)malloc(fd_array_size*sizeof(FD));
|
||||
else temp = (FD*)realloc(fd, fd_array_size*sizeof(FD));
|
||||
|
||||
if (!temp) return;
|
||||
fd = temp;
|
||||
|
||||
# if USE_POLL
|
||||
pollfd *tpoll;
|
||||
|
||||
if (!pollfds) tpoll = (pollfd*)malloc(fd_array_size*sizeof(pollfd));
|
||||
else tpoll = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd));
|
||||
|
||||
if (!tpoll) return;
|
||||
pollfds = tpoll;
|
||||
# endif
|
||||
}
|
||||
fd[i].cb = cb;
|
||||
fd[i].arg = v;
|
||||
# if USE_POLL
|
||||
pollfds[i].fd = n;
|
||||
pollfds[i].events = events;
|
||||
# else
|
||||
fd[i].fd = n;
|
||||
fd[i].events = events;
|
||||
if (events & POLLIN) FD_SET(n, &fdsets[0]);
|
||||
if (events & POLLOUT) FD_SET(n, &fdsets[1]);
|
||||
if (events & POLLERR) FD_SET(n, &fdsets[2]);
|
||||
if (n > maxfd) maxfd = n;
|
||||
# endif
|
||||
}
|
||||
|
||||
void Fl_X11_System_Driver::add_fd(int n, void (*cb)(int, void*), void* v) {
|
||||
add_fd(n, POLLIN, cb, v);
|
||||
}
|
||||
|
||||
void Fl_X11_System_Driver::remove_fd(int n, int events) {
|
||||
int i,j;
|
||||
# if !USE_POLL
|
||||
maxfd = -1; // recalculate maxfd on the fly
|
||||
# endif
|
||||
for (i=j=0; i<nfds; i++) {
|
||||
# if USE_POLL
|
||||
if (pollfds[i].fd == n) {
|
||||
int e = pollfds[i].events & ~events;
|
||||
if (!e) continue; // if no events left, delete this fd
|
||||
pollfds[j].events = e;
|
||||
}
|
||||
# else
|
||||
if (fd[i].fd == n) {
|
||||
int e = fd[i].events & ~events;
|
||||
if (!e) continue; // if no events left, delete this fd
|
||||
fd[i].events = e;
|
||||
}
|
||||
if (fd[i].fd > maxfd) maxfd = fd[i].fd;
|
||||
# endif
|
||||
// move it down in the array if necessary:
|
||||
if (j<i) {
|
||||
fd[j] = fd[i];
|
||||
# if USE_POLL
|
||||
pollfds[j] = pollfds[i];
|
||||
# endif
|
||||
}
|
||||
j++;
|
||||
}
|
||||
nfds = j;
|
||||
# if !USE_POLL
|
||||
if (events & POLLIN) FD_CLR(n, &fdsets[0]);
|
||||
if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
|
||||
if (events & POLLERR) FD_CLR(n, &fdsets[2]);
|
||||
# endif
|
||||
}
|
||||
|
||||
void Fl_X11_System_Driver::remove_fd(int n) {
|
||||
remove_fd(n, -1);
|
||||
}
|
||||
|
||||
extern int fl_send_system_handlers(void *e);
|
||||
|
||||
@@ -255,10 +116,6 @@ static void do_queued_events() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// these pointers are set by the Fl::lock() function:
|
||||
static void nothing() {}
|
||||
void (*fl_lock_function)() = nothing;
|
||||
void (*fl_unlock_function)() = nothing;
|
||||
|
||||
// This is never called with time_to_wait < 0.0:
|
||||
// It should return negative on error, 0 if nothing happens before
|
||||
@@ -269,69 +126,13 @@ int Fl_X11_System_Driver::poll_or_select_with_delay(double time_to_wait) {
|
||||
// unnecessarily and thus cause the file descriptor to not be ready,
|
||||
// so we must check for already-read events:
|
||||
if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;}
|
||||
|
||||
# if !USE_POLL
|
||||
fd_set fdt[3];
|
||||
fdt[0] = fdsets[0];
|
||||
fdt[1] = fdsets[1];
|
||||
fdt[2] = fdsets[2];
|
||||
# endif
|
||||
int n;
|
||||
|
||||
fl_unlock_function();
|
||||
|
||||
if (time_to_wait < 2147483.648) {
|
||||
# if USE_POLL
|
||||
n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
|
||||
# else
|
||||
timeval t;
|
||||
t.tv_sec = int(time_to_wait);
|
||||
t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
|
||||
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
|
||||
# endif
|
||||
} else {
|
||||
# if USE_POLL
|
||||
n = ::poll(pollfds, nfds, -1);
|
||||
# else
|
||||
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
|
||||
# endif
|
||||
}
|
||||
|
||||
fl_lock_function();
|
||||
|
||||
if (n > 0) {
|
||||
for (int i=0; i<nfds; i++) {
|
||||
# if USE_POLL
|
||||
if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
|
||||
# else
|
||||
int f = fd[i].fd;
|
||||
short revents = 0;
|
||||
if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
|
||||
if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
|
||||
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
|
||||
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
return n;
|
||||
return Fl_Unix_System_Driver::poll_or_select_with_delay(time_to_wait);
|
||||
}
|
||||
|
||||
// just like Fl_X11_System_Driver::poll_or_select_with_delay(0.0) except no callbacks are done:
|
||||
int Fl_X11_System_Driver::poll_or_select() {
|
||||
if (XQLength(fl_display)) return 1;
|
||||
if (!nfds) return 0; // nothing to select or poll
|
||||
# if USE_POLL
|
||||
return ::poll(pollfds, nfds, 0);
|
||||
# else
|
||||
timeval t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 0;
|
||||
fd_set fdt[3];
|
||||
fdt[0] = fdsets[0];
|
||||
fdt[1] = fdsets[1];
|
||||
fdt[2] = fdsets[2];
|
||||
return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
|
||||
# endif
|
||||
return Fl_Unix_System_Driver::poll_or_select();
|
||||
}
|
||||
|
||||
// replace \r\n by \n
|
||||
@@ -883,28 +684,6 @@ static void read_int(uchar *c, int& i) {
|
||||
i |= (*(++c))<<24;
|
||||
}
|
||||
|
||||
// turn BMP image FLTK produced by create_bmp() back to Fl_RGB_Image
|
||||
static Fl_RGB_Image *own_bmp_to_RGB(char *bmp) {
|
||||
int w, h;
|
||||
read_int((uchar*)bmp + 18, w);
|
||||
read_int((uchar*)bmp + 22, h);
|
||||
int R=(3*w+3)/4 * 4; // the number of bytes per row, rounded up to multiple of 4
|
||||
bmp += 54;
|
||||
uchar *data = new uchar[w*h*3];
|
||||
uchar *p = data;
|
||||
for (int i = h-1; i >= 0; i--) {
|
||||
char *s = bmp + i * R;
|
||||
for (int j = 0; j < w; j++) {
|
||||
*p++=s[2];
|
||||
*p++=s[1];
|
||||
*p++=s[0];
|
||||
s+=3;
|
||||
}
|
||||
}
|
||||
Fl_RGB_Image *img = new Fl_RGB_Image(data, w, h, 3);
|
||||
img->alloc_array = 1;
|
||||
return img;
|
||||
}
|
||||
|
||||
// Call this when a "paste" operation happens:
|
||||
void Fl_X11_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const char *type) {
|
||||
@@ -918,7 +697,7 @@ void Fl_X11_Screen_Driver::paste(Fl_Widget &receiver, int clipboard, const char
|
||||
Fl::e_length = fl_selection_length[clipboard];
|
||||
if (!Fl::e_text) Fl::e_text = (char *)"";
|
||||
} else if (clipboard == 1 && type == Fl::clipboard_image && fl_selection_type[1] == type) {
|
||||
Fl::e_clipboard_data = own_bmp_to_RGB(fl_selection_buffer[1]);
|
||||
Fl::e_clipboard_data = Fl_Unix_System_Driver::own_bmp_to_RGB(fl_selection_buffer[1]);
|
||||
Fl::e_clipboard_type = Fl::clipboard_image;
|
||||
} else return;
|
||||
int retval = receiver.handle(FL_PASTE);
|
||||
@@ -1074,53 +853,12 @@ static void write_int(unsigned char **cp, int i) {
|
||||
*cp = c;
|
||||
}
|
||||
|
||||
static unsigned char *create_bmp(const unsigned char *data, int W, int H, int *return_size){
|
||||
int R=(3*W+3)/4 * 4; // the number of bytes per row, rounded up to multiple of 4
|
||||
int s=H*R;
|
||||
int fs=14+40+s;
|
||||
unsigned char *b=new unsigned char[fs];
|
||||
unsigned char *c=b;
|
||||
// BMP header
|
||||
*c++='B';
|
||||
*c++='M';
|
||||
write_int(&c,fs);
|
||||
write_int(&c,0);
|
||||
write_int(&c,14+40);
|
||||
// DIB header:
|
||||
write_int(&c,40);
|
||||
write_int(&c,W);
|
||||
write_int(&c,H);
|
||||
write_short(&c,1);
|
||||
write_short(&c,24);//bits ber pixel
|
||||
write_int(&c,0);//RGB
|
||||
write_int(&c,s);
|
||||
write_int(&c,0);// horizontal resolution
|
||||
write_int(&c,0);// vertical resolution
|
||||
write_int(&c,0);//number of colors. 0 -> 1<<bits_per_pixel
|
||||
write_int(&c,0);
|
||||
// Pixel data
|
||||
data+=3*W*H;
|
||||
for (int y=0;y<H;++y){
|
||||
data-=3*W;
|
||||
const unsigned char *s=data;
|
||||
unsigned char *p=c;
|
||||
for (int x=0;x<W;++x){
|
||||
*p++=s[2];
|
||||
*p++=s[1];
|
||||
*p++=s[0];
|
||||
s+=3;
|
||||
}
|
||||
c+=R;
|
||||
}
|
||||
*return_size = fs;
|
||||
return b;
|
||||
}
|
||||
|
||||
// takes a raw RGB image and puts it in the copy/paste buffer
|
||||
void Fl_X11_Screen_Driver::copy_image(const unsigned char *data, int W, int H, int clipboard){
|
||||
if (!data || W <= 0 || H <= 0) return;
|
||||
delete[] fl_selection_buffer[clipboard];
|
||||
fl_selection_buffer[clipboard] = (char *) create_bmp(data,W,H,&fl_selection_length[clipboard]);
|
||||
fl_selection_buffer[clipboard] = (char *) Fl_Unix_System_Driver::create_bmp(data,W,H,&fl_selection_length[clipboard]);
|
||||
fl_selection_buffer_length[clipboard] = fl_selection_length[clipboard];
|
||||
fl_i_own_selection[clipboard] = 1;
|
||||
fl_selection_type[clipboard] = Fl::clipboard_image;
|
||||
@@ -3182,13 +2920,6 @@ int Fl_X11_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int ho
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// returns pointer to the filename, or null if name ends with '/'
|
||||
const char *Fl_X11_System_Driver::filename_name(const char *name) {
|
||||
const char *p,*q;
|
||||
if (!name) return (0);
|
||||
for (p=q=name; *p;) if (*p++ == '/') q = p;
|
||||
return q;
|
||||
}
|
||||
|
||||
void Fl_X11_Window_Driver::label(const char *name, const char *iname) {
|
||||
if (shown() && !parent()) {
|
||||
|
||||
45
src/Makefile
45
src/Makefile
@@ -206,6 +206,8 @@ GLCPPFILES_X11 = drivers/X11/Fl_X11_Gl_Window_Driver.cxx
|
||||
GLCPPFILES_XFT = $(GLCPPFILES_X11)
|
||||
GLCPPFILES_WIN = drivers/WinAPI/Fl_WinAPI_Gl_Window_Driver.cxx
|
||||
|
||||
GLCPPFILES_WAYLAND = drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
|
||||
|
||||
GLCPPFILES += $(GLCPPFILES_$(BUILD))
|
||||
|
||||
# the following file currently doesn't contribute code to GLCPPFILES
|
||||
@@ -263,6 +265,7 @@ XLIBCPPFILES = \
|
||||
drivers/X11/Fl_X11_Window_Driver.cxx \
|
||||
drivers/X11/Fl_X11_Screen_Driver.cxx \
|
||||
drivers/Posix/Fl_Posix_System_Driver.cxx \
|
||||
drivers/Unix/Fl_Unix_System_Driver.cxx \
|
||||
drivers/X11/Fl_X11_System_Driver.cxx \
|
||||
drivers/Posix/Fl_Posix_Printer_Driver.cxx \
|
||||
Fl_x.cxx \
|
||||
@@ -271,6 +274,25 @@ XLIBCPPFILES = \
|
||||
Fl_Native_File_Chooser_GTK.cxx\
|
||||
Fl_Native_File_Chooser_Kdialog.cxx \
|
||||
Fl_get_key.cxx
|
||||
|
||||
# These C++ files are used under condition: BUILD_WAYLAND
|
||||
WLCPPFILES = \
|
||||
drivers/Posix/Fl_Posix_Printer_Driver.cxx \
|
||||
Fl_Native_File_Chooser_FLTK.cxx \
|
||||
Fl_Native_File_Chooser_GTK.cxx \
|
||||
Fl_Native_File_Chooser_Kdialog.cxx \
|
||||
drivers/Posix/Fl_Posix_System_Driver.cxx \
|
||||
drivers/Unix/Fl_Unix_System_Driver.cxx \
|
||||
drivers/Wayland/Fl_Wayland_System_Driver.cxx \
|
||||
drivers/Wayland/Fl_Wayland_Screen_Driver.cxx \
|
||||
drivers/Wayland/Fl_Wayland_Window_Driver.cxx \
|
||||
drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx \
|
||||
drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx \
|
||||
drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx \
|
||||
drivers/Wayland/Fl_wayland.cxx
|
||||
|
||||
|
||||
# fl_dnd_x.cxx Fl_Native_File_Chooser_GTK.cxx
|
||||
|
||||
# This C file is used under condition: BUILD_X11
|
||||
XLIBCFILES = \
|
||||
@@ -290,6 +312,15 @@ XLIBFONTFILES = \
|
||||
XLIBXFTFILES = \
|
||||
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx \
|
||||
drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
|
||||
|
||||
# This C file is used under condition: BUILD_WAYLAND
|
||||
WLCFILES = \
|
||||
xutf8/keysym2Ucs.c \
|
||||
scandir_posix.c
|
||||
|
||||
# These C++ files are used under condition: BUILD_WAYLAND
|
||||
WLXFTFILES = \
|
||||
drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
|
||||
|
||||
# These C++ files are used under condition: BUILD_GDI
|
||||
GDICPPFILES = \
|
||||
@@ -325,7 +356,7 @@ FLTKFLAGS = -DFL_LIBRARY
|
||||
include ../makeinclude
|
||||
|
||||
# makeinclude has set this variable:
|
||||
# BUILD = {WIN|X11|XFT|OSX}
|
||||
# BUILD = {WIN|X11|XFT|OSX|WAYLAND}
|
||||
|
||||
MMFILES_OSX = $(OBJCPPFILES)
|
||||
MMFILES = $(MMFILES_$(BUILD))
|
||||
@@ -336,6 +367,8 @@ CPPFILES_OSX = $(QUARTZCPPFILES)
|
||||
CPPFILES_XFT = $(XLIBCPPFILES) $(XLIBXFTFILES)
|
||||
CPPFILES_X11 = $(XLIBCPPFILES) $(XLIBFONTFILES)
|
||||
|
||||
CPPFILES_WAYLAND = $(WLCPPFILES) $(WLXFTFILES)
|
||||
|
||||
CPPFILES_WIN = $(GDICPPFILES)
|
||||
|
||||
CPPFILES += $(CPPFILES_$(BUILD))
|
||||
@@ -344,12 +377,21 @@ CPPFILES += $(CPPFILES_$(BUILD))
|
||||
CFILES_X11 = $(XLIBCFILES) $(XLIBXCFILES)
|
||||
CFILES_XFT = $(XLIBCFILES)
|
||||
|
||||
CFILES_WAYLAND = $(WLCFILES)
|
||||
EXTRA_OBJECTS_WAYLAND = ../libdecor/build/fl_libdecor.o ../libdecor/build/libdecor-cairo-blur.o \
|
||||
../libdecor/build/fl_libdecor-plugins.o \
|
||||
xdg-decoration-protocol.o xdg-shell-protocol.o text-input-protocol.o \
|
||||
../libdecor/build/cursor-settings.o ../libdecor/build/os-compatibility.o
|
||||
EXTRA_CXXFLAGS_WAYLAND = -I.
|
||||
|
||||
CFILES_WIN = $(GDICFILES)
|
||||
|
||||
CFILES += $(CFILES_$(BUILD))
|
||||
CXXFLAGS += $(EXTRA_CXXFLAGS_$(BUILD))
|
||||
|
||||
|
||||
OBJECTS = $(MMFILES:.mm=.o) $(CPPFILES:.cxx=.o) $(CFILES:.c=.o) $(UTF8CFILES:.c=.o)
|
||||
OBJECTS += $(EXTRA_OBJECTS_$(BUILD))
|
||||
GLOBJECTS = $(GLCPPFILES:.cxx=.o)
|
||||
FLOBJECTS = $(FLCPPFILES:.cxx=.o)
|
||||
IMGOBJECTS = $(IMGCPPFILES:.cxx=.o)
|
||||
@@ -619,6 +661,7 @@ clean:
|
||||
-$(RM) drivers/WinAPI/*.o
|
||||
-$(RM) drivers/X11/*.o
|
||||
-$(RM) drivers/Xlib/*.o
|
||||
-$(RM) drivers/Wayland/*.o
|
||||
-$(RM) $(DSONAME) $(FLDSONAME) $(GLDSONAME) $(IMGDSONAME) \
|
||||
$(LIBNAME) $(FLLIBNAME) $(GLLIBNAME) \
|
||||
$(IMGLIBNAME) \
|
||||
|
||||
57
src/drivers/Unix/Fl_Unix_System_Driver.H
Normal file
57
src/drivers/Unix/Fl_Unix_System_Driver.H
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Definition of Wayland system driver
|
||||
// for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 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
|
||||
//
|
||||
|
||||
#ifndef FL_NIX_SYSTEM_DRIVER_H
|
||||
#define FL_NIX_SYSTEM_DRIVER_H
|
||||
|
||||
#include "../Posix/Fl_Posix_System_Driver.H"
|
||||
class Fl_RGB_Image;
|
||||
|
||||
class FL_EXPORT Fl_Unix_System_Driver : public Fl_Posix_System_Driver {
|
||||
public:
|
||||
Fl_Unix_System_Driver() : Fl_Posix_System_Driver() {
|
||||
}
|
||||
virtual int clocale_snprintf(char *output, size_t output_size, const char *format, va_list args);
|
||||
virtual int clocale_sscanf(const char *input, const char *format, va_list args);
|
||||
virtual int clocale_printf(FILE *output, const char *format, va_list args);
|
||||
virtual int filename_list(const char *d, dirent ***list,
|
||||
int (*sort)(struct dirent **, struct dirent **),
|
||||
char *errmsg=NULL, int errmsg_sz=0);
|
||||
virtual int open_uri(const char *uri, char *msg, int msglen);
|
||||
virtual int use_tooltip_timeout_condition() {return 1;}
|
||||
virtual int file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, int lname, Fl_File_Icon *icon);
|
||||
virtual void newUUID(char *uuidBuffer);
|
||||
virtual char *preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor,
|
||||
const char *application);
|
||||
virtual int preferences_need_protection_check() {return 1;}
|
||||
virtual int utf8locale();
|
||||
virtual const char *filename_name(const char *buf);
|
||||
virtual void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0);
|
||||
virtual void add_fd(int fd, Fl_FD_Handler cb, void* = 0);
|
||||
virtual void remove_fd(int, int when);
|
||||
virtual void remove_fd(int);
|
||||
double wait(double time_to_wait);
|
||||
int ready();
|
||||
// 3 additional virtual members
|
||||
virtual int poll_or_select_with_delay(double time_to_wait);
|
||||
virtual int poll_or_select();
|
||||
virtual void *control_maximize_button(void *data);
|
||||
static unsigned char *create_bmp(const unsigned char *data, int W, int H, int *return_size);
|
||||
static Fl_RGB_Image *own_bmp_to_RGB(char *bmp);
|
||||
};
|
||||
|
||||
#endif /* FL_NIX_SYSTEM_DRIVER_H */
|
||||
960
src/drivers/Unix/Fl_Unix_System_Driver.cxx
Normal file
960
src/drivers/Unix/Fl_Unix_System_Driver.cxx
Normal file
File diff suppressed because it is too large
Load Diff
33
src/drivers/Wayland/Fl_Font.H
Normal file
33
src/drivers/Wayland/Fl_Font.H
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Font definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021 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
|
||||
//
|
||||
|
||||
#ifndef FL_FONT_
|
||||
#define FL_FONT_
|
||||
|
||||
#include <config.h>
|
||||
#include "Fl_Wayland_Graphics_Driver.H"
|
||||
|
||||
class Fl_Wayland_Font_Descriptor : public Fl_Font_Descriptor {
|
||||
public:
|
||||
Fl_Wayland_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
||||
FL_EXPORT ~Fl_Wayland_Font_Descriptor();
|
||||
PangoFontDescription *fontref;
|
||||
int **width; // array of arrays of character widths
|
||||
};
|
||||
|
||||
extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table
|
||||
|
||||
#endif // FL_FONT_
|
||||
74
src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
Normal file
74
src/drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copy-to-clipboard code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2021 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 <config.h>
|
||||
#include <FL/Fl_Copy_Surface.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include "Fl_Wayland_Graphics_Driver.H"
|
||||
#include "Fl_Wayland_Screen_Driver.H"
|
||||
#include "Fl_Wayland_Window_Driver.H"
|
||||
#include <FL/platform.H>
|
||||
|
||||
class Fl_Wayland_Copy_Surface_Driver : public Fl_Copy_Surface_Driver {
|
||||
friend class Fl_Copy_Surface_Driver;
|
||||
Fl_Image_Surface *img_surf;
|
||||
protected:
|
||||
Fl_Wayland_Copy_Surface_Driver(int w, int h);
|
||||
~Fl_Wayland_Copy_Surface_Driver();
|
||||
void set_current();
|
||||
void translate(int x, int y);
|
||||
void untranslate();
|
||||
};
|
||||
|
||||
|
||||
Fl_Copy_Surface_Driver *Fl_Copy_Surface_Driver::newCopySurfaceDriver(int w, int h)
|
||||
{
|
||||
return new Fl_Wayland_Copy_Surface_Driver(w, h);
|
||||
}
|
||||
|
||||
|
||||
Fl_Wayland_Copy_Surface_Driver::Fl_Wayland_Copy_Surface_Driver(int w, int h) : Fl_Copy_Surface_Driver(w, h) {
|
||||
int os_scale = (fl_window ? fl_window->scale : 1);
|
||||
img_surf = new Fl_Image_Surface(w * os_scale, h * os_scale);
|
||||
driver(img_surf->driver());
|
||||
driver()->scale(os_scale);
|
||||
}
|
||||
|
||||
|
||||
Fl_Wayland_Copy_Surface_Driver::~Fl_Wayland_Copy_Surface_Driver() {
|
||||
Fl_RGB_Image *rgb = img_surf->image();
|
||||
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
||||
scr_driver->copy_image(rgb->array, rgb->data_w(), rgb->data_h());
|
||||
delete rgb;
|
||||
delete img_surf;
|
||||
driver(NULL);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Copy_Surface_Driver::set_current() {
|
||||
Fl_Surface_Device::set_current();
|
||||
((Fl_Wayland_Graphics_Driver*)driver())->activate(img_surf->offscreen(), driver()->scale());
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Copy_Surface_Driver::translate(int x, int y) {
|
||||
((Fl_Wayland_Graphics_Driver*)driver())->ps_translate(x, y);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Copy_Surface_Driver::untranslate() {
|
||||
((Fl_Wayland_Graphics_Driver*)driver())->ps_untranslate();
|
||||
}
|
||||
401
src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
Normal file
401
src/drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx
Normal file
@@ -0,0 +1,401 @@
|
||||
//
|
||||
// Class Fl_Wayland_Gl_Window_Driver for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2021-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 <config.h>
|
||||
#if HAVE_GL
|
||||
#include <FL/platform.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
#include "../../Fl_Gl_Choice.H"
|
||||
#include "../../Fl_Screen_Driver.H"
|
||||
#include "Fl_Wayland_Window_Driver.H"
|
||||
#include "Fl_Wayland_Graphics_Driver.H"
|
||||
#include "../../Fl_Gl_Window_Driver.H"
|
||||
#include <wayland-egl.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <FL/gl.h>
|
||||
|
||||
/* Implementation note about OpenGL drawing on the Wayland platform
|
||||
|
||||
After eglCreateWindowSurface() with attributes {EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER, EGL_NONE},
|
||||
eglQueryContext() reports that EGL_RENDER_BUFFER equals EGL_BACK_BUFFER.
|
||||
This experiment suggests that the platform only supports double-buffer drawing.
|
||||
Consequently, FL_DOUBLE is enforced in all Fl_Gl_Window::mode_ values under Wayland.
|
||||
*/
|
||||
|
||||
class Fl_Wayland_Gl_Window_Driver : public Fl_Gl_Window_Driver {
|
||||
friend class Fl_Gl_Window_Driver;
|
||||
bool egl_resize_in_progress;
|
||||
protected:
|
||||
Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win);
|
||||
virtual float pixels_per_unit();
|
||||
virtual void make_current_before();
|
||||
virtual int mode_(int m, const int *a);
|
||||
virtual void swap_buffers();
|
||||
virtual void resize(int is_a_resize, int w, int h);
|
||||
virtual char swap_type();
|
||||
virtual Fl_Gl_Choice *find(int m, const int *alistp);
|
||||
virtual GLContext create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer = 0);
|
||||
virtual void set_gl_context(Fl_Window* w, GLContext context);
|
||||
virtual void delete_gl_context(GLContext);
|
||||
virtual void make_overlay_current();
|
||||
virtual void redraw_overlay();
|
||||
virtual void waitGL();
|
||||
virtual void gl_start();
|
||||
virtual Fl_RGB_Image* capture_gl_rectangle(int x, int y, int w, int h);
|
||||
char *alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs);
|
||||
public:
|
||||
static EGLDisplay egl_display;
|
||||
static EGLint configs_count;
|
||||
static struct wl_event_queue *gl_event_queue;
|
||||
void init();
|
||||
struct wl_egl_window *egl_window;
|
||||
EGLSurface egl_surface;
|
||||
};
|
||||
|
||||
// Describes crap needed to create a GLContext.
|
||||
class Fl_Wayland_Gl_Choice : public Fl_Gl_Choice {
|
||||
friend class Fl_Wayland_Gl_Window_Driver;
|
||||
private:
|
||||
EGLConfig egl_conf;
|
||||
public:
|
||||
Fl_Wayland_Gl_Choice(int m, const int *alistp, Fl_Gl_Choice *n) : Fl_Gl_Choice(m, alistp, n) {
|
||||
egl_conf = 0;
|
||||
}
|
||||
};
|
||||
|
||||
EGLDisplay Fl_Wayland_Gl_Window_Driver::egl_display = EGL_NO_DISPLAY;
|
||||
EGLint Fl_Wayland_Gl_Window_Driver::configs_count = 0;
|
||||
struct wl_event_queue *Fl_Wayland_Gl_Window_Driver::gl_event_queue = NULL;
|
||||
|
||||
|
||||
Fl_Wayland_Gl_Window_Driver::Fl_Wayland_Gl_Window_Driver(Fl_Gl_Window *win) : Fl_Gl_Window_Driver(win) {
|
||||
if (egl_display == EGL_NO_DISPLAY) init();
|
||||
egl_window = NULL;
|
||||
egl_surface = NULL;
|
||||
egl_resize_in_progress = false;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::init() {
|
||||
EGLint major, minor;
|
||||
|
||||
if (!fl_display) Fl::screen_driver()->open_display();
|
||||
egl_display = eglGetDisplay((EGLNativeDisplayType) fl_display);
|
||||
if (egl_display == EGL_NO_DISPLAY) {
|
||||
Fl::fatal("Can't create egl display\n");
|
||||
}
|
||||
|
||||
if (eglInitialize(egl_display, &major, &minor) != EGL_TRUE) {
|
||||
Fl::fatal("Can't initialise egl display\n");
|
||||
}
|
||||
//printf("EGL major: %d, minor %d\n", major, minor);
|
||||
|
||||
eglGetConfigs(egl_display, NULL, 0, &configs_count);
|
||||
//printf("EGL has %d configs\n", configs_count);
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
gl_event_queue = wl_display_create_queue(fl_display);
|
||||
}
|
||||
|
||||
|
||||
char *Fl_Wayland_Gl_Window_Driver::alpha_mask_for_string(const char *str, int n, int w, int h, Fl_Fontsize fs)
|
||||
{
|
||||
// write str to a bitmap just big enough
|
||||
Window save_win = fl_window;
|
||||
fl_window = NULL;
|
||||
Fl_Image_Surface *surf = new Fl_Image_Surface(w, h);
|
||||
fl_window = save_win;
|
||||
Fl_Font f=fl_font();
|
||||
Fl_Surface_Device::push_current(surf);
|
||||
fl_color(FL_BLACK);
|
||||
fl_rectf(0, 0, w, h);
|
||||
fl_color(FL_WHITE);
|
||||
fl_font(f, fs);
|
||||
fl_draw(str, n, 0, fl_height() - fl_descent());
|
||||
// get the R channel only of the bitmap
|
||||
char *alpha_buf = new char[w*h], *r = alpha_buf, *q;
|
||||
for (int i = 0; i < h; i++) {
|
||||
q = (char*)surf->offscreen()->draw_buffer + i * surf->offscreen()->stride;
|
||||
for (int j = 0; j < w; j++) {
|
||||
*r++ = *q;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
Fl_Surface_Device::pop_current();
|
||||
delete surf;
|
||||
return alpha_buf;
|
||||
}
|
||||
|
||||
|
||||
Fl_Gl_Choice *Fl_Wayland_Gl_Window_Driver::find(int m, const int *alistp)
|
||||
{
|
||||
m |= FL_DOUBLE;
|
||||
Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)Fl_Gl_Window_Driver::find_begin(m, alistp);
|
||||
if (g) return g;
|
||||
|
||||
EGLint n;
|
||||
EGLint config_attribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_DEPTH_SIZE, 0, // set at 11
|
||||
EGL_SAMPLE_BUFFERS, 0, // set at 13
|
||||
EGL_STENCIL_SIZE, 0, // set at 15
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
if (m & FL_DEPTH) config_attribs[11] = 1;
|
||||
if (m & FL_MULTISAMPLE) config_attribs[13] = 1;
|
||||
if (m & FL_STENCIL) config_attribs[15] = 1;
|
||||
|
||||
static EGLConfig *configs = (void**)calloc(configs_count, sizeof(EGLConfig));
|
||||
eglChooseConfig(egl_display, config_attribs, configs, configs_count, &n);
|
||||
if (n == 0 && (m & FL_MULTISAMPLE)) {
|
||||
config_attribs[13] = 0;
|
||||
eglChooseConfig(egl_display, config_attribs, configs, configs_count, &n);
|
||||
}
|
||||
if (n == 0) {
|
||||
Fl::fatal("failed to choose an EGL config\n");
|
||||
}
|
||||
|
||||
g = new Fl_Wayland_Gl_Choice(m, alistp, first);
|
||||
/*for (int i = 0; i < n; i++) {
|
||||
EGLint size;
|
||||
eglGetConfigAttrib(egl_display, configs[i], EGL_BUFFER_SIZE, &size);
|
||||
printf("Buffer size for config %d is %d\n", i, size);
|
||||
eglGetConfigAttrib(egl_display, configs[i], EGL_RED_SIZE, &size);
|
||||
printf("Red size for config %d is %d\n", i, size);
|
||||
// just choose the first one
|
||||
g->egl_conf = configs[i];
|
||||
break;
|
||||
}*/
|
||||
// just choose the first config
|
||||
g->egl_conf = configs[0];
|
||||
first = g;
|
||||
return g;
|
||||
}
|
||||
|
||||
|
||||
GLContext Fl_Wayland_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
|
||||
GLContext shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
|
||||
static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||
GLContext ctx = (GLContext)eglCreateContext(egl_display, ((Fl_Wayland_Gl_Choice*)g)->egl_conf, shared_ctx?shared_ctx:EGL_NO_CONTEXT, context_attribs);
|
||||
//fprintf(stderr, "eglCreateContext=%p shared_ctx=%p\n", ctx, shared_ctx);
|
||||
if (ctx)
|
||||
add_context(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
|
||||
struct wld_window *win = fl_xid(w);
|
||||
if (!win || !egl_surface) return;
|
||||
if (context != cached_context || w != cached_window) {
|
||||
cached_context = context;
|
||||
cached_window = w;
|
||||
if (eglMakeCurrent(egl_display, egl_surface, egl_surface, (EGLContext)context)) {
|
||||
//fprintf(stderr, "EGLContext %p made current\n", context);
|
||||
} else {
|
||||
Fl::error("eglMakeCurrent() failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::delete_gl_context(GLContext context) {
|
||||
if (cached_context == context) {
|
||||
cached_context = 0;
|
||||
cached_window = 0;
|
||||
}
|
||||
//EGLBoolean b =
|
||||
eglDestroyContext(egl_display, context);
|
||||
//fprintf(stderr,"EGL context %p destroyed %s\n", context, b==EGL_TRUE?"successfully":"w/ error");
|
||||
//b =
|
||||
eglDestroySurface(egl_display, egl_surface);
|
||||
//fprintf(stderr,"EGLSurface %p destroyed %s\n", egl_surface, b==EGL_TRUE?"successfully":"w/ error");
|
||||
egl_surface = NULL;
|
||||
wl_egl_window_destroy(egl_window);
|
||||
egl_window = NULL;
|
||||
del_context(context);
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::make_overlay_current() {
|
||||
//fprintf(stderr, "make_overlay_current\n");
|
||||
glDrawBuffer(GL_FRONT);
|
||||
}
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::redraw_overlay() {
|
||||
//fprintf(stderr, "redraw_overlay\n");
|
||||
pWindow->redraw();
|
||||
}
|
||||
|
||||
|
||||
Fl_Gl_Window_Driver *Fl_Gl_Window_Driver::newGlWindowDriver(Fl_Gl_Window *w)
|
||||
{
|
||||
return new Fl_Wayland_Gl_Window_Driver(w);
|
||||
}
|
||||
|
||||
|
||||
static void gl_frame_ready(void *data, struct wl_callback *cb, uint32_t time) {
|
||||
*(bool*)data = true;
|
||||
}
|
||||
|
||||
|
||||
static const struct wl_callback_listener gl_surface_frame_listener = {
|
||||
.done = gl_frame_ready,
|
||||
};
|
||||
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::make_current_before() {
|
||||
if (!egl_window) {
|
||||
struct wld_window *win = fl_xid(pWindow);
|
||||
struct wl_surface *surface = win->wl_surface;
|
||||
egl_window = wl_egl_window_create(surface, pWindow->pixel_w(), pWindow->pixel_h());
|
||||
if (egl_window == EGL_NO_SURFACE) {
|
||||
Fl::fatal("Can't create egl window with wl_egl_window_create()\n");
|
||||
} else {
|
||||
//fprintf(stderr, "Created egl window=%p\n", egl_window);
|
||||
}
|
||||
Fl_Wayland_Gl_Choice *g = (Fl_Wayland_Gl_Choice*)this->g();
|
||||
egl_surface = eglCreateWindowSurface(egl_display, g->egl_conf, egl_window, NULL);
|
||||
//fprintf(stderr, "Created egl surface=%p at scale=%d\n", egl_surface, win->scale);
|
||||
wl_surface_set_buffer_scale(surface, win->scale);
|
||||
if (Fl_Wayland_Screen_Driver::compositor == Fl_Wayland_Screen_Driver::WESTON) {
|
||||
bool done = false;
|
||||
struct wl_callback *callback = wl_surface_frame(surface);
|
||||
wl_surface_commit(surface);
|
||||
wl_callback_add_listener(callback, &gl_surface_frame_listener, &done);
|
||||
while (!done) wl_display_dispatch(fl_display);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float Fl_Wayland_Gl_Window_Driver::pixels_per_unit()
|
||||
{
|
||||
int ns = Fl_Window_Driver::driver(pWindow)->screen_num();
|
||||
int wld_scale = pWindow->shown() ? fl_xid(pWindow)->scale : 1;
|
||||
return wld_scale * Fl::screen_driver()->scale(ns);
|
||||
}
|
||||
|
||||
|
||||
int Fl_Wayland_Gl_Window_Driver::mode_(int m, const int *a) {
|
||||
mode(m | FL_DOUBLE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::swap_buffers() {
|
||||
if (overlay()) {
|
||||
static bool overlay_buffer = true;
|
||||
int wo = pWindow->pixel_w(), ho = pWindow->pixel_h();
|
||||
GLint matrixmode;
|
||||
GLfloat pos[4];
|
||||
glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
|
||||
glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); // save original glRasterPos
|
||||
glMatrixMode(GL_PROJECTION); // save proj/model matrices
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glScalef(2.0f/wo, 2.0f/ho, 1.0f);
|
||||
glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of Gl_Window
|
||||
glRasterPos2i(0,0); // set glRasterPos to bottom left corner
|
||||
{
|
||||
// Emulate overlay by doing copypixels
|
||||
glReadBuffer(overlay_buffer?GL_BACK:GL_FRONT);
|
||||
glDrawBuffer(overlay_buffer?GL_FRONT:GL_BACK);
|
||||
overlay_buffer = ! overlay_buffer;
|
||||
glCopyPixels(0, 0, wo, ho, GL_COLOR);
|
||||
}
|
||||
glPopMatrix(); // GL_MODELVIEW // restore model/proj matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(matrixmode);
|
||||
glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos
|
||||
if (!overlay_buffer) return; // don't call eglSwapBuffers until overlay has been drawn
|
||||
}
|
||||
|
||||
if (egl_surface) {
|
||||
//eglSwapInterval(egl_display, 0); // doesn't sem to have any effect in this context
|
||||
if (!egl_resize_in_progress) {
|
||||
while (wl_display_prepare_read(fl_display) != 0) {
|
||||
wl_display_dispatch_pending(fl_display);
|
||||
}
|
||||
wl_display_read_events(fl_display);
|
||||
wl_display_dispatch_queue_pending(fl_display, gl_event_queue);
|
||||
}
|
||||
egl_resize_in_progress = false;
|
||||
eglSwapBuffers(Fl_Wayland_Gl_Window_Driver::egl_display, egl_surface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Fl_Wayland_Gl_Plugin : public Fl_Wayland_Plugin {
|
||||
public:
|
||||
Fl_Wayland_Gl_Plugin() : Fl_Wayland_Plugin(name()) { }
|
||||
virtual const char *name() { return "gl.wayland.fltk.org"; }
|
||||
virtual void do_swap(Fl_Window *w) {
|
||||
Fl_Gl_Window_Driver *gldr = Fl_Gl_Window_Driver::driver(w->as_gl_window());
|
||||
if (gldr->overlay() == w) gldr->swap_buffers();
|
||||
}
|
||||
virtual void invalidate(Fl_Window *w) {
|
||||
w->as_gl_window()->valid(0);
|
||||
}
|
||||
};
|
||||
|
||||
static Fl_Wayland_Gl_Plugin Gl_Overlay_Plugin;
|
||||
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::resize(int is_a_resize, int W, int H) {
|
||||
if (!egl_window) return;
|
||||
struct wld_window *win = fl_xid(pWindow);
|
||||
float f = Fl::screen_scale(pWindow->screen_num());
|
||||
W = (W * win->scale) * f;
|
||||
H = (H * win->scale) * f;
|
||||
int W2, H2;
|
||||
wl_egl_window_get_attached_size(egl_window, &W2, &H2);
|
||||
if (W2 != W || H2 != H) {
|
||||
wl_egl_window_resize(egl_window, W, H, 0, 0);
|
||||
//fprintf(stderr, "Fl_Wayland_Gl_Window_Driver::resize to %dx%d\n", W, H);
|
||||
egl_resize_in_progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
char Fl_Wayland_Gl_Window_Driver::swap_type() {
|
||||
return copy;
|
||||
}
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::waitGL() {
|
||||
}
|
||||
|
||||
void Fl_Wayland_Gl_Window_Driver::gl_start() {
|
||||
}
|
||||
|
||||
|
||||
Fl_RGB_Image* Fl_Wayland_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int w, int h) {
|
||||
Fl_Surface_Device::push_current(Fl_Display_Device::display_device());
|
||||
Fl_RGB_Image *rgb = Fl_Gl_Window_Driver::capture_gl_rectangle(x, y, w, h);
|
||||
Fl_Surface_Device::pop_current();
|
||||
return rgb;
|
||||
}
|
||||
|
||||
#endif // HAVE_GL
|
||||
158
src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
Normal file
158
src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
Normal file
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// Definition of class Fl_Wayland_Graphics_Driver.
|
||||
//
|
||||
// Copyright 2021-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
|
||||
//
|
||||
|
||||
/**
|
||||
\file Fl_Wayland_Graphics_Driver.H
|
||||
\brief Definition of Wayland graphics driver.
|
||||
*/
|
||||
|
||||
#ifndef FL_WAYLAND_GRAPHICS_DRIVER_H
|
||||
#define FL_WAYLAND_GRAPHICS_DRIVER_H
|
||||
|
||||
|
||||
/* Implementation note about buffers FLTK uses to support display graphics under Wayland.
|
||||
|
||||
Each window is associated to an FLTK-defined object of type struct wld_window
|
||||
containing itself an FLTK-defined struct fl_wld_buffer object holding all graphics data.
|
||||
Among members of this latter structure are:
|
||||
- struct wl_buffer wl_buffer
|
||||
is a Wayland-defined type for a graphics buffer able to be attached to a wl_surface;
|
||||
- void *data
|
||||
points to the beginning of the memory zone where wl_buffer stores its graphics data;
|
||||
- unsigned char *draw_buffer
|
||||
contains a graphics buffer to which all Cairo drawings are directed;
|
||||
draw_buffer and data both have the same organization called CAIRO_FORMAT_ARGB32 in Cairo parlance
|
||||
and WL_SHM_FORMAT_ARGB8888 in Wayland parlance which means BGRA byte order.
|
||||
- int width
|
||||
gives the pixel width of the graphics buffer;
|
||||
- int stride
|
||||
gives the stride of this buffer;
|
||||
- size_t data_size
|
||||
gives the total buffer size in bytes (thus, data_size / stride gives the buffer height);
|
||||
- bool draw_buffer_needs_commit
|
||||
is TRUE when draw_buffer has been modified and needs being committed for display, and
|
||||
FALSE after having been committed but before having been modified;
|
||||
- struct wl_callback *cb
|
||||
is used to synchronize drawing with the compositor during progressive drawing.
|
||||
|
||||
When a graphics scene is to be committed, the data_size bytes of draw_buffer are copied by memcpy()
|
||||
starting at data, and wl_buffer is attached to the wl_surface which is committed for display
|
||||
by wl_surface_commit(). Finally, draw_buffer_needs_commit is set to FALSE.
|
||||
|
||||
All drawing functions have Cairo write to draw_buffer and turn draw_buffer_needs_commit to TRUE.
|
||||
*/
|
||||
|
||||
|
||||
#include "../Cairo/Fl_Cairo_Graphics_Driver.H"
|
||||
#include <cairo/cairo.h>
|
||||
#include <stdint.h> // for uint32_t
|
||||
typedef struct _PangoLayout PangoLayout;
|
||||
|
||||
struct fl_wld_buffer {
|
||||
struct wl_buffer *wl_buffer;
|
||||
void *data;
|
||||
size_t data_size; // of wl_buffer and draw_buffer
|
||||
int stride;
|
||||
int width;
|
||||
unsigned char *draw_buffer;
|
||||
struct wl_callback *cb;
|
||||
bool draw_buffer_needs_commit;
|
||||
cairo_t *cairo_;
|
||||
PangoLayout *pango_layout_;
|
||||
};
|
||||
struct wld_window;
|
||||
|
||||
class FL_EXPORT Fl_Wayland_Graphics_Driver : public Fl_Cairo_Graphics_Driver {
|
||||
private:
|
||||
struct fl_wld_buffer *buffer_;
|
||||
PangoLayout *dummy_pango_layout_; // used to measure text width before showing a window
|
||||
int linestyle_;
|
||||
void draw_cached_pattern_(Fl_Image *img, cairo_pattern_t *pat, int X, int Y, int W, int H, int cx, int cy);
|
||||
public:
|
||||
Fl_Wayland_Graphics_Driver();
|
||||
~Fl_Wayland_Graphics_Driver();
|
||||
static const uint32_t wld_format;
|
||||
static const cairo_format_t cairo_format;
|
||||
void activate(struct fl_wld_buffer *buffer, float scale);
|
||||
void font(Fl_Font fnum, Fl_Fontsize s);
|
||||
Fl_Font font() { return Fl_Graphics_Driver::font(); }
|
||||
void draw(const char* s, int nBytes, int x, int y) { draw(s, nBytes, float(x), float(y)); }
|
||||
void draw(const char* s, int nBytes, float x, float y);
|
||||
void draw(int angle, const char *str, int n, int x, int y);
|
||||
void rtl_draw(const char* str, int n, int x, int y);
|
||||
int height();
|
||||
int descent();
|
||||
double width(const char *str, int n);
|
||||
double width(unsigned c);
|
||||
void text_extents(const char* txt, int n, int& dx, int& dy, int& w, int& h);
|
||||
int not_clipped(int x, int y, int w, int h);
|
||||
int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
|
||||
void restore_clip();
|
||||
void clip_region(Fl_Region r);
|
||||
void line_style(int style, int width=0, char* dashes=0);
|
||||
Fl_Region XRectangleRegion(int x, int y, int w, int h);
|
||||
void add_rectangle_to_region(Fl_Region r, int X, int Y, int W, int H);
|
||||
void XDestroyRegion(Fl_Region r);
|
||||
void set_color(Fl_Color i, unsigned c);
|
||||
Fl_Font set_fonts(const char* pattern_name);
|
||||
const char *font_name(int num);
|
||||
void font_name(int num, const char *name);
|
||||
const char* get_font_name(Fl_Font fnum, int* ap);
|
||||
int get_font_sizes(Fl_Font fnum, int*& sizep);
|
||||
void point(int x, int y);
|
||||
void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy);
|
||||
void draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD);
|
||||
void curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
void begin_points();
|
||||
void end_points();
|
||||
void transformed_vertex(double x, double y);
|
||||
void draw_rgb(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void cache(Fl_RGB_Image *rgb);
|
||||
void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_);
|
||||
void draw_bitmap(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void cache(Fl_Bitmap *img);
|
||||
void delete_bitmask(Fl_Bitmask bm);
|
||||
void cache(Fl_Pixmap *pxm);
|
||||
void draw_pixmap(Fl_Pixmap *rgb,int XP, int YP, int WP, int HP, int cx, int cy);
|
||||
void uncache_pixmap(fl_uintptr_t p);
|
||||
void overlay_rect(int x, int y, int w , int h);
|
||||
static void init_built_in_fonts();
|
||||
static struct fl_wld_buffer *create_shm_buffer(int width, int height);
|
||||
static void buffer_release(struct wld_window *window);
|
||||
static void buffer_commit(struct wld_window *window);
|
||||
static void cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format);
|
||||
void line(int x1, int y1, int x2, int y2);
|
||||
void line(int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void xyline(int x, int y, int x1);
|
||||
void xyline(int x, int y, int x1, int y2);
|
||||
void xyline(int x, int y, int x1, int y2, int x3);
|
||||
void yxline(int x, int y, int y1);
|
||||
void yxline(int x, int y, int y1, int x2);
|
||||
void yxline(int x, int y, int y1, int x2, int y3);
|
||||
void loop(int x0, int y0, int x1, int y1, int x2, int y2);
|
||||
void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void rect(int x, int y, int w, int h);
|
||||
void rectf(int x, int y, int w, int h);
|
||||
void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
|
||||
void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void end_loop();
|
||||
void end_line();
|
||||
void end_polygon();
|
||||
void set_spot(int font, int height, int x, int y, int w, int h, Fl_Window *win);
|
||||
void reset_spot();
|
||||
};
|
||||
|
||||
#endif // FL_WAYLAND_GRAPHICS_DRIVER_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user