├── .gitignore ├── .gitmodules ├── CMake ├── FindChck.cmake ├── FindDRM.cmake ├── FindDbus.cmake ├── FindEGL.cmake ├── FindElogind.cmake ├── FindGBM.cmake ├── FindGLESv2.cmake ├── FindLibInput.cmake ├── FindMath.cmake ├── FindPixman.cmake ├── FindSystemd.cmake ├── FindUdev.cmake ├── FindWayland.cmake ├── FindWaylandProtocols.cmake ├── FindX11.cmake ├── FindXCB.cmake ├── FindXKBCommon.cmake ├── GCCCompatibleCompilerOptions.cmake ├── Wayland.cmake ├── subproject.cmake └── test.cmake ├── CMakeLists.txt ├── CONTRIBUTING.rst ├── LICENSE ├── README.rst ├── example ├── CMakeLists.txt └── example.c ├── include └── wlc │ ├── defines.h │ ├── geometry.h │ ├── wlc-render.h │ ├── wlc-wayland.h │ └── wlc.h ├── lib └── CMakeLists.txt ├── man └── man3 │ └── wlc_view_get_pid.3 ├── protos ├── CMakeLists.txt └── test-extension.xml ├── shared └── os-compatibility.h ├── src ├── CMakeLists.txt ├── FindWlc.cmake ├── compositor │ ├── compositor.c │ ├── compositor.h │ ├── output.c │ ├── output.h │ ├── seat │ │ ├── data.c │ │ ├── data.h │ │ ├── keyboard.c │ │ ├── keyboard.h │ │ ├── keymap.c │ │ ├── keymap.h │ │ ├── pointer.c │ │ ├── pointer.h │ │ ├── seat.c │ │ ├── seat.h │ │ ├── touch.c │ │ └── touch.h │ ├── shell │ │ ├── custom-shell.c │ │ ├── custom-shell.h │ │ ├── shell.c │ │ ├── shell.h │ │ ├── xdg-shell.c │ │ └── xdg-shell.h │ ├── view.c │ └── view.h ├── extended │ ├── wlc-render.c │ └── wlc-wayland.c ├── internal.h ├── macros.h ├── platform │ ├── backend │ │ ├── backend.c │ │ ├── backend.h │ │ ├── drm.c │ │ ├── drm.h │ │ ├── wayland.c │ │ ├── wayland.h │ │ ├── x11.c │ │ └── x11.h │ ├── context │ │ ├── context.c │ │ ├── context.h │ │ ├── egl.c │ │ └── egl.h │ └── render │ │ ├── gles2.c │ │ ├── gles2.h │ │ ├── render.c │ │ └── render.h ├── resources │ ├── resources.c │ ├── resources.h │ └── types │ │ ├── buffer.c │ │ ├── buffer.h │ │ ├── data-source.c │ │ ├── data-source.h │ │ ├── region.c │ │ ├── region.h │ │ ├── shell-surface.c │ │ ├── shell-surface.h │ │ ├── surface.c │ │ ├── surface.h │ │ ├── xdg-popup.h │ │ ├── xdg-positioner.c │ │ ├── xdg-positioner.h │ │ ├── xdg-toplevel.c │ │ └── xdg-toplevel.h ├── session │ ├── dbus.c │ ├── dbus.h │ ├── fd.c │ ├── fd.h │ ├── logind.c │ ├── logind.h │ ├── tty.c │ ├── tty.h │ ├── udev.c │ └── udev.h ├── visibility.h ├── wlc.c ├── wlc.pc.in └── xwayland │ ├── selection.c │ ├── xutil.h │ ├── xwayland.c │ ├── xwayland.h │ ├── xwm.c │ └── xwm.h ├── tests ├── CMakeLists.txt ├── client.h ├── fullscreen.c ├── resources.c └── wl-extension.c └── uncrustify.conf /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/chck"] 2 | path = lib/chck 3 | url = git://github.com/Cloudef/chck.git 4 | branch = master 5 | [submodule "protos/wayland-protocols"] 6 | path = protos/wayland-protocols 7 | url = git://anongit.freedesktop.org/wayland/wayland-protocols 8 | -------------------------------------------------------------------------------- /CMake/FindChck.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindChck 3 | # ------- 4 | # 5 | # Find chck library 6 | # 7 | # Try to find chck library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # CHCK_FOUND - True if chck is available 12 | # CHCK_INCLUDE_DIRS - Include directories for chck 13 | # CHCK_LIBRARIES - List of libraries for chck 14 | # CHCK_DEFINITIONS - List of definitions for chck 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | unset(CHCK_INCLUDE_DIRS CACHE) 27 | unset(CHCK_LIBRARIES CACHE) 28 | 29 | include(FeatureSummary) 30 | set_package_properties(chck PROPERTIES 31 | URL "https://github.com/Cloudef/chck/" 32 | DESCRIPTION "Collection of C utilities (Shared linking not recommended)") 33 | 34 | find_package(PkgConfig) 35 | pkg_check_modules(PC_CHCK QUIET chck) 36 | find_path(CHCK_INCLUDE_DIRS NAMES chck/macros.h HINTS ${PC_CHCK_INCLUDE_DIRS}) 37 | 38 | set(libraries 39 | chck-atlas 40 | chck-buffer 41 | chck-dl 42 | chck-fs 43 | chck-lut 44 | chck-pool 45 | chck-sjis 46 | chck-string 47 | chck-tqueue 48 | chck-unicode 49 | chck-xdg) 50 | 51 | unset(libs) 52 | foreach(lib ${libraries}) 53 | find_library(CHCK_LIBRARIES_${lib} NAMES ${lib} HINTS ${PC_CHCK_LIBRARY_DIRS}) 54 | list(APPEND libs ${CHCK_LIBRARIES_${lib}}) 55 | mark_as_advanced(CHCK_LIBRARIES_${lib}) 56 | unset(CHCK_LIBRARIES_${lib} CACHE) 57 | endforeach (lib ${libraries}) 58 | 59 | set(CHCK_LIBRARIES ${libs} CACHE FILEPATH "Path to chck libraries" FORCE) 60 | set(CHCK_DEFINITIONS ${PC_CHCK_CFLAGS_OTHER}) 61 | 62 | include(FindPackageHandleStandardArgs) 63 | find_package_handle_standard_args(chck DEFAULT_MSG CHCK_LIBRARIES CHCK_INCLUDE_DIRS) 64 | mark_as_advanced(CHCK_LIBRARIES CHCK_INCLUDE_DIRS CHCK_DEFINITIONS) 65 | unset(libs) 66 | -------------------------------------------------------------------------------- /CMake/FindDRM.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindDRM 3 | # ------- 4 | # 5 | # Find DRM library 6 | # 7 | # Try to find DRM library on UNIX systems. The following values are defined 8 | # 9 | # :: 10 | # 11 | # DRM_FOUND - True if drm is available 12 | # DRM_INCLUDE_DIRS - Include directories for drm 13 | # DRM_LIBRARIES - List of libraries for drm 14 | # DRM_DEFINITIONS - List of definitions for drm 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(DRM PROPERTIES 28 | URL "http://dri.freedesktop.org/" 29 | DESCRIPTION "Kernel module that gives direct hardware access to DRI clients") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_DRM QUIET libdrm) 33 | find_library(DRM_LIBRARIES NAMES drm HINTS ${PC_DRM_LIBRARY_DIRS}) 34 | find_path(DRM_INCLUDE_DIRS NAMES drm.h PATH_SUFFIXES libdrm drm HINTS ${PC_DRM_INCLUDE_DIRS}) 35 | 36 | set(DRM_DEFINITIONS ${PC_DRM_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(DRM DEFAULT_MSG DRM_INCLUDE_DIRS DRM_LIBRARIES) 40 | mark_as_advanced(DRM_INCLUDE_DIRS DRM_LIBRARIES DRM_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /CMake/FindDbus.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindDbus 3 | # ----------- 4 | # 5 | # Find Dbus library 6 | # 7 | # Try to find Dbus library on UNIX systems. The following values are defined 8 | # 9 | # :: 10 | # 11 | # DBUS_FOUND - True if dbus is available 12 | # DBUS_INCLUDE_DIRS - Include directories for dbus 13 | # DBUS_LIBRARIES - List of libraries for dbus 14 | # DBUS_DEFINITIONS - List of definitions for dbus 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(Dbus PROPERTIES 28 | URL "http://www.freedesktop.org/wiki/Software/dbus/" 29 | DESCRIPTION "Message bus system") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_DBUS QUIET dbus-1) 33 | find_path(DBUS_SYSTEM_INCLUDES dbus/dbus.h PATH_SUFFIXES dbus-1.0) 34 | find_path(DBUS_LIB_INCLUDES dbus/dbus-arch-deps.h HINTS ${PC_DBUS_INCLUDE_DIRS} ${CMAKE_LIBRARY_PATH}/dbus-1.0/include ${CMAKE_SYSTEM_LIBRARY_PATH}/dbus-1.0/include) 35 | find_library(DBUS_LIBRARIES NAMES dbus-1 HINTS ${PC_DBUS_LIBRARY_DIRS}) 36 | 37 | set(DBUS_INCLUDE_DIRS ${DBUS_SYSTEM_INCLUDES} ${DBUS_LIB_INCLUDES}) 38 | set(DBUS_DEFINITIONS ${PC_DBUS_CFLAGS_OTHER}) 39 | 40 | include(FindPackageHandleStandardArgs) 41 | find_package_handle_standard_args(DBUS DEFAULT_MSG DBUS_INCLUDE_DIRS DBUS_LIBRARIES) 42 | mark_as_advanced(DBUS_INCLUDE_DIRS DBUS_LIBRARIES DBUS_SYSTEM_INCLUDES DBUS_LIB_INCLUDES DBUS_DEFINITIONS) 43 | -------------------------------------------------------------------------------- /CMake/FindEGL.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindEGL 3 | # ------- 4 | # 5 | # Find EGL library 6 | # 7 | # Try to find EGL library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # EGL_FOUND - True if egl is available 12 | # EGL_INCLUDE_DIRS - Include directories for egl 13 | # EGL_LIBRARIES - List of libraries for egl 14 | # EGL_DEFINITIONS - List of definitions for egl 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(EGL PROPERTIES 28 | URL "http://www.khronos.org/egl/" 29 | DESCRIPTION "Native Platform Interface") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_EGL QUIET egl) 33 | find_library(EGL_LIBRARIES NAMES egl EGL HINTS ${PC_EGL_LIBRARY_DIRS}) 34 | find_path(EGL_INCLUDE_DIRS NAMES EGL/egl.h HINTS ${PC_EGL_INCLUDE_DIRS}) 35 | 36 | set(EGL_DEFINITIONS ${PC_EGL_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(EGL DEFAULT_MSG EGL_LIBRARIES EGL_INCLUDE_DIRS) 40 | mark_as_advanced(EGL_INCLUDE_DIRS EGL_LIBRARIES EGL_DEFINITIONS) 41 | 42 | -------------------------------------------------------------------------------- /CMake/FindElogind.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindElogind 3 | # ------- 4 | # 5 | # Find Elogind library 6 | # 7 | # Try to find Elogind library on UNIX systems. The following values are defined 8 | # 9 | # :: 10 | # 11 | # ELOGIND_FOUND - True if Elogind is available 12 | # ELOGIND_INCLUDE_DIRS - Include directories for Elogind 13 | # ELOGIND_LIBRARIES - List of libraries for Elogind 14 | # ELOGIND_DEFINITIONS - List of definitions for Elogind 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(Elogind PROPERTIES 28 | URL "https://github.com/elogind/elogind" 29 | DESCRIPTION "Elogind User, Seat and Session Manager") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_ELOGIND QUIET libelogind) 33 | find_library(ELOGIND_LIBRARIES NAMES elogind ${PC_ELOGIND_LIBRARY_DIRS}) 34 | find_path(ELOGIND_INCLUDE_DIRS elogind/sd-login.h HINTS ${PC_ELOGIND_INCLUDE_DIRS}) 35 | 36 | set(ELOGIND_DEFINITIONS ${PC_ELOGIND_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(ELOGIND DEFAULT_MSG ELOGIND_INCLUDE_DIRS ELOGIND_LIBRARIES) 40 | mark_as_advanced(ELOGIND_INCLUDE_DIRS ELOGIND_LIBRARIES ELOGIND_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /CMake/FindGBM.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindGBM 3 | # ------- 4 | # 5 | # Find GBM library 6 | # 7 | # Try to find GBM library on UNIX systems. The following values are defined 8 | # 9 | # :: 10 | # 11 | # GBM_FOUND - True if gbm is available 12 | # GBM_INCLUDE_DIRS - Include directories for gbm 13 | # GBM_LIBRARIES - List of libraries for gbm 14 | # GBM_DEFINITIONS - List of definitions for gbm 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | set_package_properties(GBM PROPERTIES 27 | URL "http://www.mesa3d.org/" 28 | DESCRIPTION "Generic buffer manager") 29 | 30 | find_package(PkgConfig) 31 | pkg_check_modules(PC_GBM QUIET gbm) 32 | find_library(GBM_LIBRARIES NAMES gbm HINTS ${PC_GBM_LIBRARY_DIRS}) 33 | find_path(GBM_INCLUDE_DIRS gbm.h HINTS ${PC_GBM_INCLUDE_DIRS}) 34 | 35 | set(GBM_DEFINITIONS ${PC_GBM_CFLAGS_OTHER}) 36 | 37 | include(FindPackageHandleStandardArgs) 38 | find_package_handle_standard_args(GBM DEFAULT_MSG GBM_INCLUDE_DIRS GBM_LIBRARIES) 39 | mark_as_advanced(GBM_INCLUDE_DIRS GBM_LIBRARIES GBM_DEFINITIONS) 40 | -------------------------------------------------------------------------------- /CMake/FindGLESv2.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindGLESv2 3 | # ------- 4 | # 5 | # Find GLESv2 library 6 | # 7 | # Try to find GLESv2 library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # GLESv2_FOUND - True if glesv2 is available 12 | # GLESv2_INCLUDE_DIRS - Include directories for glesv2 13 | # GLESv2_LIBRARIES - List of libraries for glesv2 14 | # GLESv2_DEFINITIONS - List of definitions for glesv2 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(GLESv2 PROPERTIES 28 | URL "https://www.khronos.org/opengles/" 29 | DESCRIPTION "The Standard for Embedded Accelerated 3D Graphics") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_GLES2 QUIET glesv2) 33 | find_library(GLESv2_LIBRARIES NAMES GLESv2 ${PC_GLES2_LIBRARY_DIRS}) 34 | find_path(GLESv2_INCLUDE_DIRS NAMES GLES2/gl2.h HINTS ${PC_GLES2_INCLUDE_DIRS}) 35 | 36 | set(GLESv2_DEFINITIONS ${PC_GLES2_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(GLESv2 DEFAULT_MSG GLESv2_LIBRARIES GLESv2_INCLUDE_DIRS) 40 | mark_as_advanced(GLESv2_INCLUDE_DIRS GLESv2_LIBRARIES GLESv2_DEFINITIONS) 41 | 42 | -------------------------------------------------------------------------------- /CMake/FindLibInput.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindLibInput 3 | # ------- 4 | # 5 | # Find LibInput library 6 | # 7 | # Try to find LibInpu library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # LIBINPUT_FOUND - True if libinput is available 12 | # LIBINPUT_INCLUDE_DIRS - Include directories for libinput 13 | # LIBINPUT_LIBRARIES - List of libraries for libinput 14 | # LIBINPUT_DEFINITIONS - List of definitions for libinput 15 | # 16 | # and also the following more fine grained variables 17 | # 18 | # :: 19 | # 20 | # LIBINPUT_VERSION 21 | # LIBINPUT_VERSION_MAJOR 22 | # LIBINPUT_VERSION_MINOR 23 | # LIBINPUT_VERSION_MICRO 24 | # 25 | #============================================================================= 26 | # Copyright (c) 2015 Jari Vetoniemi 27 | # 28 | # Distributed under the OSI-approved BSD License (the "License"); 29 | # 30 | # This software is distributed WITHOUT ANY WARRANTY; without even the 31 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 32 | # See the License for more information. 33 | #============================================================================= 34 | 35 | include(FeatureSummary) 36 | set_package_properties(LibInput PROPERTIES 37 | URL "http://freedesktop.org/wiki/Software/libinput/" 38 | DESCRIPTION "Library to handle input devices") 39 | 40 | find_package(PkgConfig) 41 | pkg_check_modules(PC_INPUT QUIET libinput) 42 | find_library(LIBINPUT_LIBRARIES NAMES input HINTS ${PC_INPUT_LIBRARY_DIRS}) 43 | find_path(LIBINPUT_INCLUDE_DIRS libinput.h HINTS ${PC_INPUT_INCLUDE_DIRS}) 44 | 45 | set(LIBINPUT_VERSION ${PC_INPUT_VERSION}) 46 | string(REPLACE "." ";" VERSION_LIST "${PC_INPUT_VERSION}") 47 | 48 | LIST(LENGTH VERSION_LIST n) 49 | if (n EQUAL 3) 50 | list(GET VERSION_LIST 0 LIBINPUT_VERSION_MAJOR) 51 | list(GET VERSION_LIST 1 LIBINPUT_VERSION_MINOR) 52 | list(GET VERSION_LIST 2 LIBINPUT_VERSION_MICRO) 53 | else () 54 | set(LIBINPUT_VERSION "9999.9999.9999") 55 | set(LIBINPUT_VERSION_MAJOR 9999) 56 | set(LIBINPUT_VERSION_MINOR 9999) 57 | set(LIBINPUT_VERSION_MICRO 9999) 58 | message(WARNING "Could not detect libinput version, assuming you have recent one") 59 | endif () 60 | 61 | # This is compatible with libinput-version.h that exists in upstream 62 | # but isn't in distribution (probably forgotten) 63 | set(LIBINPUT_DEFINITIONS ${PC_INPUT_CFLAGS_OTHER} 64 | -DLIBINPUT_VERSION=\"${LIBINPUT_VERSION}\" 65 | -DLIBINPUT_VERSION_MAJOR=${LIBINPUT_VERSION_MAJOR} 66 | -DLIBINPUT_VERSION_MINOR=${LIBINPUT_VERSION_MINOR} 67 | -DLIBINPUT_VERSION_MICRO=${LIBINPUT_VERSION_MICRO}) 68 | 69 | include(FindPackageHandleStandardArgs) 70 | find_package_handle_standard_args(LIBINPUT DEFAULT_MSG LIBINPUT_INCLUDE_DIRS LIBINPUT_LIBRARIES) 71 | mark_as_advanced(LIBINPUT_INCLUDE_DIRS LIBINPUT_LIBRARIES LIBINPUT_DEFINITIONS 72 | LIBINPUT_VERSION LIBINPUT_VERSION_MAJOR LIBINPUT_VERSION_MICRO LIBINPUT_VERSION_MINOR) 73 | -------------------------------------------------------------------------------- /CMake/FindMath.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindMath 3 | # ------- 4 | # 5 | # Find standard C math library 6 | # 7 | # Try to find standard C math library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # MATH_FOUND - True if math is available 12 | # MATH_LIBRARY - Library for math 13 | # 14 | #============================================================================= 15 | # Copyright (c) 2015 Jari Vetoniemi 16 | # 17 | # Distributed under the OSI-approved BSD License (the "License"); 18 | # 19 | # This software is distributed WITHOUT ANY WARRANTY; without even the 20 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 | # See the License for more information. 22 | #============================================================================= 23 | 24 | set_package_properties(Math PROPERTIES 25 | DESCRIPTION "Standard C math library") 26 | 27 | find_library(MATH_LIBRARY m) 28 | include(FindPackageHandleStandardArgs) 29 | find_package_handle_standard_args(MATH DEFAULT_MSG MATH_LIBRARY) 30 | mark_as_advanced(MATH_LIBRARY) 31 | -------------------------------------------------------------------------------- /CMake/FindPixman.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindPixman 3 | # ------- 4 | # 5 | # Find Pixman library 6 | # 7 | # Try to find Pixman library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # PIXMAN_FOUND - True if Pixman is available 12 | # PIXMAN_INCLUDE_DIRS - Include directories for Pixman 13 | # PIXMAN_LIBRARIES - List of libraries for Pixman 14 | # PIXMAN_DEFINITIONS - List of definitions for Pixman 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(Pixman PROPERTIES 28 | URL "http://pixman.org/" 29 | DESCRIPTION "Low-level software library for pixel manipulation") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_PIXMAN QUIET pixman-1) 33 | find_library(PIXMAN_LIBRARIES NAMES pixman-1 HINTS ${PC_PIXMAN_LIBRARY_DIRS}) 34 | find_path(PIXMAN_INCLUDE_DIRS NAMES pixman.h PATH_SUFFIXES pixman-1 HINTS ${PC_PIXMAN_INCLUDE_DIRS}) 35 | 36 | set(PIXMAN_DEFINITIONS ${PC_PIXMAN_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(PIXMAN DEFAULT_MSG PIXMAN_LIBRARIES PIXMAN_INCLUDE_DIRS) 40 | mark_as_advanced(PIXMAN_INCLUDE_DIRS PIXMAN_LIBRARIES PIXMAN_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /CMake/FindSystemd.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindSystemd 3 | # ------- 4 | # 5 | # Find Systemd library 6 | # 7 | # Try to find Systemd library on UNIX systems. The following values are defined 8 | # 9 | # :: 10 | # 11 | # SYSTEMD_FOUND - True if Systemd is available 12 | # SYSTEMD_INCLUDE_DIRS - Include directories for Systemd 13 | # SYSTEMD_LIBRARIES - List of libraries for Systemd 14 | # SYSTEMD_DEFINITIONS - List of definitions for Systemd 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(Systemd PROPERTIES 28 | URL "http://freedesktop.org/wiki/Software/systemd/" 29 | DESCRIPTION "System and Service Manager") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_SYSTEMD QUIET libsystemd) 33 | find_library(SYSTEMD_LIBRARIES NAMES systemd ${PC_SYSTEMD_LIBRARY_DIRS}) 34 | find_path(SYSTEMD_INCLUDE_DIRS systemd/sd-login.h HINTS ${PC_SYSTEMD_INCLUDE_DIRS}) 35 | 36 | set(SYSTEMD_DEFINITIONS ${PC_SYSTEMD_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(SYSTEMD DEFAULT_MSG SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES) 40 | mark_as_advanced(SYSTEMD_INCLUDE_DIRS SYSTEMD_LIBRARIES SYSTEMD_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /CMake/FindUdev.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindUdev 3 | # ------- 4 | # 5 | # Find udev library 6 | # 7 | # Try to find udev library on UNIX systems. The following values are defined 8 | # 9 | # :: 10 | # 11 | # UDEV_FOUND - True if udev is available 12 | # UDEV_INCLUDE_DIRS - Include directories for udev 13 | # UDEV_LIBRARIES - List of libraries for udev 14 | # UDEV_DEFINITIONS - List of definitions for udev 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(Udev PROPERTIES 28 | URL "https://www.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html" 29 | DESCRIPTION "Device manager for the Linux kernel") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_UDEV QUIET libudev) 33 | find_library(UDEV_LIBRARIES NAMES udev HINTS ${PC_UDEV_LIBRARY_DIRS}) 34 | find_path(UDEV_INCLUDE_DIRS libudev.h HINTS ${PC_UDEV_INCLUDE_DIRS}) 35 | 36 | set(UDEV_DEFINITIONS ${PC_UDEV_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(UDEV DEFAULT_MSG UDEV_INCLUDE_DIRS UDEV_LIBRARIES) 40 | mark_as_advanced(UDEV_INCLUDE_DIRS UDEV_LIBRARIES UDEV_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /CMake/FindWayland.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindWayland 3 | # ----------- 4 | # 5 | # Find Wayland installation 6 | # 7 | # Try to find Wayland. The following values are defined 8 | # 9 | # :: 10 | # 11 | # WAYLAND_FOUND - True if Wayland is found 12 | # WAYLAND_LIBRARIES - Link these to use Wayland 13 | # WAYLAND_INCLUDE_DIRS - Include directories for Wayland 14 | # WAYLAND_DEFINITIONS - Compiler flags for using Wayland 15 | # 16 | # and also the following more fine grained variables: 17 | # 18 | # :: 19 | # 20 | # WAYLAND_CLIENT_FOUND, WAYLAND_CLIENT_INCLUDE_DIRS, WAYLAND_CLIENT_LIBRARIES 21 | # WAYLAND_SERVER_FOUND, WAYLAND_SERVER_INCLUDE_DIRS, WAYLAND_SERVER_LIBRARIES 22 | # WAYLAND_EGL_FOUND, WAYLAND_EGL_INCLUDE_DIRS, WAYLAND_EGL_LIBRARIES 23 | # 24 | #============================================================================= 25 | # Copyright (c) 2015 Jari Vetoniemi 26 | # 2013 Martin Gräßlin 27 | # 28 | # Distributed under the OSI-approved BSD License (the "License"); 29 | # 30 | # This software is distributed WITHOUT ANY WARRANTY; without even the 31 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 32 | # See the License for more information. 33 | #============================================================================= 34 | 35 | include(FeatureSummary) 36 | set_package_properties(Wayland PROPERTIES 37 | URL "http://wayland.freedesktop.org/" 38 | DESCRIPTION "Protocol for implementing compositors") 39 | 40 | find_package(PkgConfig) 41 | pkg_check_modules(PC_WAYLAND QUIET wayland-client>=1.7 wayland-server>=1.7 wayland-egl) 42 | 43 | find_library(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PC_WAYLAND_LIBRARY_DIRS}) 44 | find_library(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PC_WAYLAND_LIBRARY_DIRS}) 45 | find_library(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PC_WAYLAND_LIBRARY_DIRS}) 46 | 47 | find_path(WAYLAND_CLIENT_INCLUDE_DIRS NAMES wayland-client.h HINTS ${PC_WAYLAND_INCLUDE_DIRS}) 48 | find_path(WAYLAND_SERVER_INCLUDE_DIRS NAMES wayland-server.h HINTS ${PC_WAYLAND_INCLUDE_DIRS}) 49 | find_path(WAYLAND_EGL_INCLUDE_DIRS NAMES wayland-egl.h HINTS ${PC_WAYLAND_INCLUDE_DIRS}) 50 | 51 | set(WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIRS} ${WAYLAND_SERVER_INCLUDE_DIRS} ${WAYLAND_EGL_INCLUDE_DIRS}) 52 | set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES}) 53 | set(WAYLAND_DEFINITIONS ${PC_WAYLAND_CFLAGS}) 54 | 55 | list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIRS) 56 | 57 | include(FindPackageHandleStandardArgs) 58 | find_package_handle_standard_args(WAYLAND_CLIENT DEFAULT_MSG WAYLAND_CLIENT_LIBRARIES WAYLAND_CLIENT_INCLUDE_DIRS) 59 | find_package_handle_standard_args(WAYLAND_SERVER DEFAULT_MSG WAYLAND_SERVER_LIBRARIES WAYLAND_SERVER_INCLUDE_DIRS) 60 | find_package_handle_standard_args(WAYLAND_EGL DEFAULT_MSG WAYLAND_EGL_LIBRARIES WAYLAND_EGL_INCLUDE_DIRS) 61 | find_package_handle_standard_args(WAYLAND DEFAULT_MSG WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIRS) 62 | 63 | mark_as_advanced( 64 | WAYLAND_INCLUDE_DIRS WAYLAND_LIBRARIES 65 | WAYLAND_CLIENT_INCLUDE_DIRS WAYLAND_CLIENT_LIBRARIES 66 | WAYLAND_SERVER_INCLUDE_DIRS WAYLAND_SERVER_LIBRARIES 67 | WAYLAND_EGL_INCLUDE_DIRS WAYLAND_EGL_LIBRARIES 68 | WAYLAND_DEFINITIONS 69 | ) 70 | -------------------------------------------------------------------------------- /CMake/FindWaylandProtocols.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindWaylandProtocols 3 | # ------- 4 | # 5 | # Find wayland protocol description files 6 | # 7 | # Try to find wayland protocol files. The following values are defined 8 | # 9 | # :: 10 | # 11 | # WAYLANDPROTOCOLS_FOUND - True if wayland protocol files are available 12 | # WAYLANDPROTOCOLS_PATH - Path to wayland protocol files 13 | # 14 | #============================================================================= 15 | # Copyright (c) 2015 Jari Vetoniemi 16 | # 17 | # Distributed under the OSI-approved BSD License (the "License"); 18 | # 19 | # This software is distributed WITHOUT ANY WARRANTY; without even the 20 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 | # See the License for more information. 22 | #============================================================================= 23 | 24 | include(FeatureSummary) 25 | set_package_properties(WaylandProtocols PROPERTIES 26 | URL "https://cgit.freedesktop.org/wayland/wayland-protocols" 27 | DESCRIPTION "Wayland protocol development") 28 | 29 | unset(WAYLANDPROTOCOLS_PATH) 30 | 31 | find_package(PkgConfig) 32 | if (PKG_CONFIG_FOUND) 33 | execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols 34 | OUTPUT_VARIABLE WAYLANDPROTOCOLS_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) 35 | endif () 36 | 37 | include(FindPackageHandleStandardArgs) 38 | find_package_handle_standard_args(WaylandProtocols DEFAULT_MSG WAYLANDPROTOCOLS_PATH) 39 | mark_as_advanced(WAYLANDPROTOCOLS_PATH) 40 | -------------------------------------------------------------------------------- /CMake/FindX11.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindX11 3 | # ------- 4 | # 5 | # Find X11 libraries 6 | # 7 | # Tries to find X11 libraries on unix systems. 8 | # 9 | # - Be sure to set the COMPONENTS to the components you want to link to 10 | # - The X11_LIBRARIES variable is set ONLY to your COMPONENTS list 11 | # - To use only a specific component check the X11_LIBRARIES_${COMPONENT} variable 12 | # 13 | # The following values are defined 14 | # 15 | # :: 16 | # 17 | # X11_FOUND - True if X11 is available 18 | # X11_INCLUDE_DIRS - Include directories for X11 19 | # X11_LIBRARIES - List of libraries for X11 20 | # X11_DEFINITIONS - List of definitions for X11 21 | # 22 | #============================================================================= 23 | # Copyright (c) 2015 Jari Vetoniemi 24 | # 25 | # Distributed under the OSI-approved BSD License (the "License"); 26 | # 27 | # This software is distributed WITHOUT ANY WARRANTY; without even the 28 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 29 | # See the License for more information. 30 | #============================================================================= 31 | 32 | include(FeatureSummary) 33 | set_package_properties(X11 PROPERTIES 34 | URL "http://www.x.org/" 35 | DESCRIPTION "Open source implementation of the X Window System") 36 | 37 | find_package(PkgConfig) 38 | pkg_check_modules(PC_X11 QUIET X11 ${X11_FIND_COMPONENTS}) 39 | 40 | find_library(X11_LIBRARIES X11 HINTS ${PC_X11_LIBRARY_DIRS}) 41 | find_path(X11_INCLUDE_DIRS X11/Xlib.h PATH_SUFFIXES X11 HINTS ${PC_X11_INCLUDE_DIRS}) 42 | 43 | foreach(COMPONENT ${X11_FIND_COMPONENTS}) 44 | find_library(X11_LIBRARIES_${COMPONENT} ${COMPONENT} HINTS ${PC_X11_LIBRARY_DIRS}) 45 | list(APPEND X11_LIBRARIES ${X11_LIBRARIES_${COMPONENT}}) 46 | mark_as_advanced(X11_LIBRARIES_${COMPONENT}) 47 | endforeach(COMPONENT ${X11_FIND_COMPONENTS}) 48 | 49 | set(X11_DEFINITIONS ${PC_X11_CFLAGS_OTHER}) 50 | 51 | include(FindPackageHandleStandardArgs) 52 | find_package_handle_standard_args(X11 DEFAULT_MSG X11_LIBRARIES X11_INCLUDE_DIRS) 53 | mark_as_advanced(X11_INCLUDE_DIRS X11_LIBRARIES X11_DEFINITIONS) 54 | -------------------------------------------------------------------------------- /CMake/FindXCB.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindXCB 3 | # ------- 4 | # 5 | # Find XCB libraries 6 | # 7 | # Tries to find xcb libraries on unix systems. 8 | # 9 | # - Be sure to set the COMPONENTS to the components you want to link to 10 | # - The XCB_LIBRARIES variable is set ONLY to your COMPONENTS list 11 | # - To use only a specific component check the XCB_LIBRARIES_${COMPONENT} variable 12 | # 13 | # The following values are defined 14 | # 15 | # :: 16 | # 17 | # XCB_FOUND - True if xcb is available 18 | # XCB_INCLUDE_DIRS - Include directories for xcb 19 | # XCB_LIBRARIES - List of libraries for xcb 20 | # XCB_DEFINITIONS - List of definitions for xcb 21 | # 22 | #============================================================================= 23 | # Copyright (c) 2015 Jari Vetoniemi 24 | # 25 | # Distributed under the OSI-approved BSD License (the "License"); 26 | # 27 | # This software is distributed WITHOUT ANY WARRANTY; without even the 28 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 29 | # See the License for more information. 30 | #============================================================================= 31 | 32 | include(FeatureSummary) 33 | set_package_properties(XCB PROPERTIES 34 | URL "http://xcb.freedesktop.org/" 35 | DESCRIPTION "X protocol C-language Binding") 36 | 37 | find_package(PkgConfig) 38 | pkg_check_modules(PC_XCB QUIET xcb ${XCB_FIND_COMPONENTS}) 39 | 40 | find_library(XCB_LIBRARIES xcb HINTS ${PC_XCB_LIBRARY_DIRS}) 41 | find_path(XCB_INCLUDE_DIRS xcb/xcb.h PATH_SUFFIXES xcb HINTS ${PC_XCB_INCLUDE_DIRS}) 42 | 43 | foreach(COMPONENT ${XCB_FIND_COMPONENTS}) 44 | find_library(XCB_LIBRARIES_${COMPONENT} ${COMPONENT} HINTS ${PC_XCB_LIBRARY_DIRS}) 45 | list(APPEND XCB_LIBRARIES ${XCB_LIBRARIES_${COMPONENT}}) 46 | mark_as_advanced(XCB_LIBRARIES_${COMPONENT}) 47 | endforeach(COMPONENT ${XCB_FIND_COMPONENTS}) 48 | 49 | set(XCB_DEFINITIONS ${PC_XCB_CFLAGS_OTHER}) 50 | 51 | include(FindPackageHandleStandardArgs) 52 | find_package_handle_standard_args(XCB DEFAULT_MSG XCB_LIBRARIES XCB_INCLUDE_DIRS) 53 | mark_as_advanced(XCB_INCLUDE_DIRS XCB_LIBRARIES XCB_DEFINITIONS) 54 | -------------------------------------------------------------------------------- /CMake/FindXKBCommon.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindXKBCommon 3 | # ------- 4 | # 5 | # Find XKBCommon library 6 | # 7 | # Try to find XKBCommon library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # XKBCOMMON_FOUND - True if XKBCommon is available 12 | # XKBCOMMON_INCLUDE_DIRS - Include directories for XKBCommon 13 | # XKBCOMMON_LIBRARIES - List of libraries for XKBCommon 14 | # XKBCOMMON_DEFINITIONS - List of definitions for XKBCommon 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(XKBCommon PROPERTIES 28 | URL "http://xkbcommon.org/" 29 | DESCRIPTION "Library to handle keyboard descriptions") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_XKBCOMMON QUIET xkbcommon) 33 | find_path(XKBCOMMON_INCLUDE_DIRS NAMES xkbcommon/xkbcommon.h HINTS ${PC_XKBCOMMON_INCLUDE_DIRS}) 34 | find_library(XKBCOMMON_LIBRARIES NAMES xkbcommon HINTS ${PC_XKBCOMMON_LIBRARY_DIRS}) 35 | 36 | set(XKBCOMMON_DEFINITIONS ${PC_XKBCOMMON_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(XKBCOMMON DEFAULT_MSG XKBCOMMON_LIBRARIES XKBCOMMON_INCLUDE_DIRS) 40 | mark_as_advanced(XKBCOMMON_LIBRARIES XKBCOMMON_INCLUDE_DIRS XKBCOMMON_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /CMake/GCCCompatibleCompilerOptions.cmake: -------------------------------------------------------------------------------- 1 | include(CheckCCompilerFlag) 2 | 3 | # Add list of compiler warnings 4 | # Every warning gets checked with check_c_compiler_flags 5 | function(add_compiler_warnings) 6 | foreach (flag ${ARGN}) 7 | check_c_compiler_flag(${flag} ok) 8 | if (ok) 9 | add_compile_options(${flag}) 10 | endif () 11 | endforeach () 12 | endfunction () 13 | 14 | # Create new ${EXE,MODULE,SHARED}_LINKER_FLAGS build type for list of linker flags 15 | # Every linker flag gets checked with check_c_compiler_flag 16 | function(create_custom_linker_flags name) 17 | set(ldflags) 18 | foreach (flag ${ARGN}) 19 | check_c_compiler_flag(-Wl,${flag} ok) 20 | if (ok) 21 | if (ldflags) 22 | set(ldflags "${ldflags},${flag}") 23 | else () 24 | set(ldflags "-Wl,${flag}") 25 | endif () 26 | endif () 27 | endforeach () 28 | 29 | string(TOUPPER ${name} upper) 30 | set(CMAKE_EXE_LINKER_FLAGS_${upper} "${ldflags}" CACHE STRING "${name} exe linker flags" FORCE) 31 | set(CMAKE_MODULE_LINKER_FLAGS_${upper} "${ldflags}" CACHE STRING "${name} module linker flags" FORCE) 32 | set(CMAKE_SHARED_LINKER_FLAGS_${upper} "${ldflags}" CACHE STRING "${name} shared linker flags" FORCE) 33 | mark_as_advanced(CMAKE_EXE_LINKER_FLAGS_${upper} CMAKE_SHARED_LINKER_FLAGS_${upper} CMAKE_MODULE_LINKER_FLAGS_${upper}) 34 | endfunction () 35 | 36 | # Create new {C,CXX}_FLAGS build type for list of compiler flags 37 | # Every compiler flag gets checked with check_c_compiler_flag 38 | function(create_custom_compiler_flags name) 39 | set(cflags) 40 | foreach (flag ${ARGN}) 41 | check_c_compiler_flag(${flag} ok) 42 | if (ok) 43 | if (cflags) 44 | set(cflags "${cflags} ${flag}") 45 | else () 46 | set(cflags "${flag}") 47 | endif () 48 | endif () 49 | endforeach () 50 | 51 | string(TOUPPER ${name} upper) 52 | set(CMAKE_C_FLAGS_${upper} "${cflags}" CACHE STRING "${name} C flags" FORCE) 53 | set(CMAKE_CXX_FLAGS_${upper} "${cflags}" CACHE STRING "${name} CXX flags" FORCE) 54 | mark_as_advanced(CMAKE_CXX_FLAGS_${upper} CMAKE_C_FLAGS_${upper}) 55 | endfunction () 56 | -------------------------------------------------------------------------------- /CMake/Wayland.cmake: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # Copyright (C) 2012-2013 Pier Luigi Fiorini 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions 7 | # are met: 8 | # 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # 12 | # * Redistributions in binary form must reproduce the above copyright 13 | # notice, this list of conditions and the following disclaimer in the 14 | # documentation and/or other materials provided with the distribution. 15 | # 16 | # * Neither the name of Pier Luigi Fiorini nor the names of his 17 | # contributors may be used to endorse or promote products derived 18 | # from this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | #============================================================================= 32 | 33 | find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner) 34 | 35 | # wayland_add_protocol_client(outfiles inputfile basename) 36 | function(WAYLAND_ADD_PROTOCOL_CLIENT _sources _protocol _basename) 37 | if(NOT WAYLAND_SCANNER_EXECUTABLE) 38 | message(FATAL "The wayland-scanner executable has not been found on your system. You must install it.") 39 | endif() 40 | 41 | get_filename_component(_infile ${_protocol} ABSOLUTE) 42 | set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-client-protocol.h") 43 | set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-protocol.c") 44 | 45 | add_custom_command(OUTPUT "${_client_header}" 46 | COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header < ${_infile} > ${_client_header} 47 | DEPENDS ${_infile} VERBATIM) 48 | 49 | add_custom_command(OUTPUT "${_code}" 50 | COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code < ${_infile} > ${_code} 51 | DEPENDS ${_infile} VERBATIM) 52 | 53 | list(APPEND ${_sources} "${_client_header}" "${_code}") 54 | set(${_sources} ${${_sources}} PARENT_SCOPE) 55 | endfunction() 56 | 57 | # wayland_add_protocol_server(outfiles inputfile basename) 58 | function(WAYLAND_ADD_PROTOCOL_SERVER _sources _protocol _basename) 59 | if(NOT WAYLAND_SCANNER_EXECUTABLE) 60 | message(FATAL "The wayland-scanner executable has not been found on your system. You must install it.") 61 | endif() 62 | 63 | get_filename_component(_infile ${_protocol} ABSOLUTE) 64 | set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-server-protocol.h") 65 | set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-protocol.c") 66 | 67 | add_custom_command(OUTPUT "${_server_header}" 68 | COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header < ${_infile} > ${_server_header} 69 | DEPENDS ${_infile} VERBATIM) 70 | 71 | add_custom_command(OUTPUT "${_code}" 72 | COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code < ${_infile} > ${_code} 73 | DEPENDS ${_infile} VERBATIM) 74 | 75 | list(APPEND ${_sources} "${_server_header}" "${_code}") 76 | set(${_sources} ${${_sources}} PARENT_SCOPE) 77 | endfunction() 78 | -------------------------------------------------------------------------------- /CMake/subproject.cmake: -------------------------------------------------------------------------------- 1 | # subproject.cmake: 2 | # 3 | # Builds another dependant CMake project, unless the project was already built or installed systemwide. 4 | # 5 | # It does this by first checking if project exists systemwide and uses that. 6 | # If not, it checks if the project was already included and if it was, it does nothing. 7 | # If both of the above are not true, another CMake project is build. 8 | # 9 | # Usually the subprojects are git submodules on git repository, so packagers can avoid linking subprojects and 10 | # instead always use systemwide libraries, by not downloading submodules. This will normally cause build to fail 11 | # if systemwide package was not found. 12 | # 13 | # Developers can control this behaviour with -DSOURCE_=ON|OFF option. It's usually useful to have 14 | # local development versions of everything when developing, and this option makes sure nothing is linked against 15 | # systemwide libraries. 16 | # 17 | # If subprojects are being linked locally, and subprojects include subprojects that were already included. 18 | # They will not include the subproject again. Instead they link against the already compiled subprojects. 19 | # 20 | # This is convenient for development, but not so covenient if you need to have different versions of submodules 21 | # in-tree for some reason. Rather than doing that I just suggest updating the codebase to work with same library versions. 22 | 23 | function(add_subproject name) 24 | if(ARGC GREATER 1) 25 | set(package_name ${ARGV1}) 26 | else() 27 | set(package_name ${name}) 28 | endif() 29 | 30 | if(TARGET ${name}) 31 | message("Subproject ${name} already included, skipping") 32 | else() 33 | find_package(${package_name} QUIET) 34 | string(TOUPPER ${package_name} upper) 35 | if(NOT SOURCE_${upper} AND ${upper}_FOUND) 36 | message("Found ${package_name} on system") 37 | else() 38 | message("Adding ${name} as subdirectory") 39 | add_subdirectory(${name} EXCLUDE_FROM_ALL) 40 | endif() 41 | endif() 42 | endfunction() 43 | -------------------------------------------------------------------------------- /CMake/test.cmake: -------------------------------------------------------------------------------- 1 | # Wraps add_test 2 | # Fixes win32 .exe extensions on mingw at least 3 | # Uses CTEST_EXEC_WITH variable which you can set to for example valgrind to run tests with valgrind. 4 | # Also uses CTEST_OUTPUT_DIRECTORY to set global output directory 5 | 6 | function(add_test_ex target) 7 | add_test(${target} ${CTEST_EXEC_WITH} "${CTEST_OUTPUT_DIRECTORY}/${target}${CMAKE_EXECUTABLE_SUFFIX}") 8 | endfunction() 9 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.1) 2 | PROJECT(wlc VERSION 0.0.10 LANGUAGES C) 3 | set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/CMake") 4 | 5 | # Subprojects 6 | include(subproject) 7 | add_subdirectory(lib) 8 | 9 | # CPack 10 | set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") 11 | set(CPACK_GENERATOR "7Z") 12 | set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") 13 | set(CPACK_PACKAGE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pkg") 14 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Wayland compositor library") 15 | set(CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION ON) 16 | 17 | # Includes 18 | include(CheckFunctionExists) 19 | include(GNUInstallDirs) 20 | include(FeatureSummary) 21 | include(CPack) 22 | include(CTest) 23 | include(test) 24 | 25 | # Options 26 | OPTION(WLC_X11_BACKEND_SUPPORT "Build X11 backend" ON) 27 | OPTION(WLC_XWAYLAND_SUPPORT "Support XWayland applications" ON) 28 | OPTION(WLC_WAYLAND_BACKEND_SUPPORT "Build Wayland backend" ON) 29 | OPTION(WLC_BUILD_STATIC "Build wlc as static library" OFF) 30 | OPTION(WLC_BUILD_EXAMPLES "Build wlc examples" ON) 31 | OPTION(WLC_BUILD_TESTS "Build wlc tests" ON) 32 | 33 | add_feature_info(X11Backend WLC_X11_BACKEND_SUPPORT "Compile X11 backend") 34 | add_feature_info(XWaylandSupport WLC_XWAYLAND_SUPPORT "Compile support for XWayland") 35 | add_feature_info(WaylandBackend WLC_WAYLAND_BACKEND_SUPPORT "Compile Wayland backend") 36 | add_feature_info(Static WLC_BUILD_STATIC "Compile as static library") 37 | add_feature_info(Examples WLC_BUILD_EXAMPLES "Compile example programs") 38 | add_feature_info(Tests WLC_BUILD_TESTS "Compile tests") 39 | 40 | # Find all required packages by various parts of the toolkit 41 | find_package(Math REQUIRED) 42 | find_package(Wayland REQUIRED) 43 | find_package(Pixman REQUIRED) 44 | find_package(XKBCommon REQUIRED) 45 | find_package(Udev REQUIRED) 46 | find_package(LibInput REQUIRED) 47 | find_package(WaylandProtocols REQUIRED) 48 | 49 | if (WLC_X11_BACKEND_SUPPORT) 50 | find_package(X11 REQUIRED COMPONENTS X11-xcb Xfixes) 51 | set_package_properties(X11 PROPERTIES TYPE REQUIRED PURPOSE "Enables X11 backend") 52 | find_package(XCB REQUIRED COMPONENTS xcb-ewmh xcb-composite xcb-xkb xcb-image xcb-xfixes) 53 | set_package_properties(XCB PROPERTIES TYPE REQUIRED PURPOSE "Enables Xwayland and X11 backend") 54 | if (X11_FOUND AND XCB_FOUND) 55 | set(ENABLE_X11_BACKEND YES) 56 | endif () 57 | endif () 58 | 59 | if (WLC_XWAYLAND_SUPPORT) 60 | if (NOT XCB_FOUND) 61 | find_package(XCB REQUIRED COMPONENTS xcb-ewmh xcb-composite xcb-xkb xcb-image xcb-xfixes) 62 | set_package_properties(XCB PROPERTIES TYPE REQUIRED PURPOSE "Enables Xwayland and X11 backend") 63 | endif () 64 | if (XCB_FOUND) 65 | set(ENABLE_XWAYLAND_SUPPORT YES) 66 | endif () 67 | endif () 68 | 69 | find_package(GLESv2 REQUIRED) 70 | set_package_properties(GLESv2 PROPERTIES TYPE REQUIRED PURPOSE "Enables OpenGL renderer") 71 | find_package(EGL REQUIRED) 72 | set_package_properties(EGL PROPERTIES TYPE REQUIRED PURPOSE "Enables EGL context") 73 | find_package(DRM REQUIRED) 74 | set_package_properties(DRM PROPERTIES TYPE REQUIRED PURPOSE "Enables DRM backend") 75 | find_package(GBM REQUIRED) 76 | set_package_properties(GBM PROPERTIES TYPE REQUIRED PURPOSE "Enables DRM backend") 77 | 78 | # Optional 79 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 80 | find_package(Dbus) 81 | set_package_properties(Dbus PROPERTIES TYPE RECOMMENDED PURPOSE "Enables logind support") 82 | find_package(Systemd) 83 | set_package_properties(Systemd PROPERTIES TYPE RECOMMENDED PURPOSE "Enables logind support") 84 | find_package(Elogind) 85 | set_package_properties(Elogind PROPERTIES TYPE RECOMMENDED PURPOSE "Enables logind support") 86 | endif () 87 | 88 | if (NOT WLC_BUILD_STATIC) 89 | set(BUILD_SHARED_LIBS ON) 90 | endif () 91 | 92 | # Compiler options 93 | include(GCCCompatibleCompilerOptions) 94 | 95 | if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) 96 | set(ldflags -O1 --sort-common --as-needed -z,relro -z,now) 97 | endif () 98 | 99 | check_c_compiler_flag(-fstack-protector-strong has_fstack_protector_strong) 100 | if (has_fstack_protector_strong) 101 | list(APPEND cflags -fstack-protector-strong -fstack-check --param ssp-buffer-size=4) 102 | else () 103 | list(APPEND cflags -fstack-protector-all -fstack-check --param ssp-buffer-size=4) 104 | endif () 105 | 106 | create_custom_linker_flags(Upstream ${ldflags}) 107 | create_custom_compiler_flags(Upstream -g -O2 ${cflags}) 108 | 109 | add_compiler_warnings(-Wall -Wextra -Wno-variadic-macros -Wno-long-long -Wformat=2 -Winit-self -Wfloat-equal -Wcast-align -Wpointer-arith -Wmissing-prototypes -Wno-nonnull-compare) 110 | 111 | if (CMAKE_C_COMPILER_ID MATCHES "Clang") 112 | add_compiler_warnings(-Wno-pointer-bool-conversion -Wno-missing-field-initializers -Wno-missing-braces) 113 | endif () 114 | 115 | # -std=c99 -fpic -fpie -D_DEFAULT_SOURCE 116 | set(CMAKE_C_STANDARD 99) 117 | set(CMAKE_C_STANDARD_REQUIRED ON) 118 | set(CMAKE_C_EXTENSIONS OFF) 119 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 120 | add_definitions(-D_DEFAULT_SOURCE) 121 | 122 | check_function_exists(mkostemp mkostemp_exists) 123 | if (mkostemp_exists) 124 | add_definitions(-D_GNU_SOURCE -DHAVE_MKOSTEMP=1) 125 | else () 126 | add_definitions(-D_DEFAULT_SOURCE -DHAVE_MKOSTEMP=0) 127 | endif () 128 | 129 | check_function_exists(posix_fallocate posix_fallocate_exists) 130 | if (posix_fallocate_exists) 131 | add_definitions(-DHAVE_POSIX_FALLOCATE=1) 132 | endif () 133 | 134 | include_directories(shared) 135 | add_subdirectory(protos) 136 | add_subdirectory(src) 137 | 138 | if (WLC_BUILD_EXAMPLES) 139 | add_subdirectory(example) 140 | endif () 141 | 142 | if (WLC_BUILD_TESTS) 143 | add_subdirectory(tests) 144 | endif () 145 | 146 | if ("${CMAKE_PROJECT_NAME}" STREQUAL "${PROJECT_NAME}") 147 | feature_summary(WHAT ALL) 148 | endif () 149 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | HOW TO CONTRIBUTE 2 | ----------------- 3 | 4 | Look at the project issues list for things to do. 5 | If you are planning contributing code that does not fix issue, visit the project IRC channel first or discuss in a new feature issue. 6 | 7 | Include clear description in comment, what your commit does. 8 | If it fixes issue, include issue code in the description. 9 | 10 | Eventually some testing guidelines will be added, but for now there is none. 11 | 12 | If you have questions or need help, visit the project IRC channel. 13 | 14 | MAKING CHANGES 15 | -------------- 16 | 17 | - Fork the repository. 18 | - Create branch for your feature. 19 | - Follow the code style guidelines below and make changes. 20 | - Open PR against master. 21 | - When your PR is approved, squash your commits into one if they aren't already. 22 | - PR gets merged. 23 | 24 | CODE STYLE 25 | ---------- 26 | 27 | Project uses the C99 standard, avoid GNU and other unportable extensions. 28 | Use C99 standard types. (stdbool, stdint) 29 | 30 | 3 spaces indentation, no tabs. Unix newlines (LF), UTF8 files and no BOM. 31 | 32 | Variable declarations should be done where the variables are first used. 33 | Do not put variable declarations top of the function like in ANSI C, this is pointless. 34 | 35 | Asserts are encouraged, use them whenever it makes sense. 36 | When validating function arguments (user input), put the asserts at top of the function. 37 | This helps others to immediately see what is not valid input for the function. 38 | 39 | Avoid useless comments in code. Code should be clear enough to understand without comments. 40 | If something is hard to explain with comment, or you are not sure of something, the code probably could be simplified. 41 | Comments are there when something has good reason to be explained. 42 | 43 | Do not use typedef without a good reason. See Linux kernel's `Chapter 5 Typedefs `_ 44 | 45 | Use const whenever variable should not change. 46 | 47 | Use static always when symbol should not be exposed outside, do not use static inside functions unless really needed. 48 | 49 | Use newline after type name in function declarations. For function prototypes, just keep them one line. 50 | 51 | Single line conditionals are allowed, however if the conditional contains else, it should be bracketed. 52 | 53 | Avoid unnecessary whitespace and newlines. 54 | 55 | Put opening brace on same line for anything except function declarations and cases. 56 | 57 | Do not put spaces around parenthesis, with exception of open parenthesis for keyword (if, while, for) 58 | 59 | Put spaces around arithmetic operators. (1+2 -> 1 + 2) 60 | 61 | Put spaces after colons. (a,b,c -> a, b, c) 62 | 63 | Get familiar with the utility functions included in `chck `_, especially the chck_string and chck_pool. 64 | Any useful generic utility function should be contributed there. 65 | 66 | .. code:: c 67 | 68 | #include 69 | #include 70 | 71 | #if INDENT_CPP 72 | # define EXPLAIN "Put # always leftmost and indent with spaces after it" 73 | #endif 74 | 75 | enum type { 76 | WHITE, 77 | GRAY, 78 | BLACK, 79 | }; 80 | 81 | struct foo { 82 | bool bar; 83 | enum type type; 84 | }; 85 | 86 | bool prototype(int32_t foo); 87 | 88 | /** 89 | * Function comment block. 90 | * Most editors do this formatting automatically. 91 | * 92 | * Always use static when the function is not supposed to be exposed outside. 93 | */ 94 | static bool 95 | declaration(int32_t foo) 96 | { 97 | // User input assertation. 98 | // In this case we document developer, foo must be between -32 and 32. 99 | assert(foo > -32 && foo < 32); 100 | 101 | bool bar = false; 102 | 103 | // Single line ifs are allowed 104 | if (foo == 1) 105 | bar = true; 106 | 107 | // However if you must use else, use braces 108 | if ((foo + bar) * ~foo == 4) { 109 | foo = 8; 110 | } else { 111 | bar = false; 112 | } 113 | 114 | if (foo == 8) 115 | goto error; 116 | 117 | // Pointer operators (star, reference) should be next to variable. 118 | void *baf = NULL, *baz = NULL; 119 | 120 | return bar; 121 | 122 | // Labels are aligned to left 123 | error: 124 | return false; 125 | } 126 | 127 | 128 | UNCRUSTIFY 129 | ---------- 130 | 131 | The repository contains `Uncrustify `_ configuration 132 | for automatic styling of source code. While it does good job overall, there are few pitfalls. 133 | 134 | The most common one is that it thinks anything with operators after cast is arithmetic. 135 | 136 | .. code:: c 137 | 138 | // formats this 139 | static int foo = (bar)~0; 140 | 141 | // to this 142 | static int foo = (bar) ~0; 143 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jari Vetoniemi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | DEPRECATION NOTICE 2 | ------------------ 3 | 4 | wlc is officially deprecated. Interested users are encouraged to use `wlroots `_ instead. 5 | 6 | FEATURES 7 | -------- 8 | 9 | +------------------+-----------------------+ 10 | | Backends | DRM, X11, Wayland | 11 | +------------------+-----------------------+ 12 | | Renderers | EGL, GLESv2 | 13 | +------------------+-----------------------+ 14 | | Buffer API | GBM, EGL streams | 15 | +------------------+-----------------------+ 16 | | TTY session | logind, legacy (suid) | 17 | +------------------+-----------------------+ 18 | | Input | libinput, xkb | 19 | +------------------+-----------------------+ 20 | | Monitor | Multi-monitor, DPMS | 21 | +------------------+-----------------------+ 22 | | Hotplugging | udev | 23 | +------------------+-----------------------+ 24 | | Xwayland | Supported | 25 | +------------------+-----------------------+ 26 | | Clipboard | Partially working | 27 | +------------------+-----------------------+ 28 | | Drag'n'Drop | Not implemented | 29 | +------------------+-----------------------+ 30 | 31 | EXAMPLE 32 | ------- 33 | 34 | .. code:: c 35 | 36 | // For more functional example see example/example.c 37 | 38 | #include 39 | #include 40 | 41 | static bool 42 | view_created(wlc_handle view) 43 | { 44 | wlc_view_set_mask(view, wlc_output_get_mask(wlc_view_get_output(view))); 45 | wlc_view_bring_to_front(view); 46 | wlc_view_focus(view); 47 | return true; 48 | } 49 | 50 | static void 51 | view_focus(wlc_handle view, bool focus) 52 | { 53 | wlc_view_set_state(view, WLC_BIT_ACTIVATED, focus); 54 | } 55 | 56 | int 57 | main(int argc, char *argv[]) 58 | { 59 | wlc_set_view_created_cb(view_created); 60 | wlc_set_view_focus_cb(view_focus); 61 | 62 | if (!wlc_init()) 63 | return EXIT_FAILURE; 64 | 65 | wlc_run(); 66 | return EXIT_SUCCESS; 67 | } 68 | 69 | ENV VARIABLES 70 | ------------- 71 | 72 | ``wlc`` reads the following env variables. 73 | 74 | +-----------------------+-----------------------------------------------------+ 75 | | ``WLC_DRM_DEVICE`` | Device to use in DRM mode. (card0 default) | 76 | +-----------------------+-----------------------------------------------------+ 77 | | ``WLC_BUFFER_API`` | Force buffer API to ``GBM`` or ``EGL``. | 78 | +-----------------------+-----------------------------------------------------+ 79 | | ``WLC_SHM`` | Set 1 to force EGL clients to use shared memory. | 80 | +-----------------------+-----------------------------------------------------+ 81 | | ``WLC_OUTPUTS`` | Number of fake outputs in X11/Wayland mode. | 82 | +-----------------------+-----------------------------------------------------+ 83 | | ``WLC_XWAYLAND`` | Set 0 to disable Xwayland. | 84 | +-----------------------+-----------------------------------------------------+ 85 | | ``WLC_LIBINPUT`` | Set 1 to force libinput. (Even on X11/Wayland) | 86 | +-----------------------+-----------------------------------------------------+ 87 | | ``WLC_REPEAT_DELAY`` | Keyboard repeat delay. | 88 | +-----------------------+-----------------------------------------------------+ 89 | | ``WLC_REPEAT_RATE`` | Keyboard repeat rate. | 90 | +-----------------------+-----------------------------------------------------+ 91 | | ``WLC_DEBUG`` | Enable debug channels (comma separated) | 92 | +-----------------------+-----------------------------------------------------+ 93 | 94 | KEYBOARD LAYOUT 95 | --------------- 96 | 97 | You can set your preferred keyboard layout using ``XKB_DEFAULT_LAYOUT``. 98 | 99 | See xkb documentation for more details. 100 | 101 | RUNNING ON TTY 102 | -------------- 103 | 104 | If you have ``logind``, you don't have to do anything. 105 | 106 | Without ``logind`` you need to suid your binary to root user. 107 | The permissions will be dropped runtime. 108 | 109 | BUFFER API 110 | ---------- 111 | 112 | ``wlc`` supports both ``GBM`` and ``EGL`` streams buffer APIs. The buffer API is auto-detected based on the driver used by the DRM device. 113 | 114 | - ``GBM`` is supported by most GPU drivers except the NVIDIA proprietary driver. 115 | - ``EGL`` is only supported by the NVIDIA proprietary. If you have a NVIDIA GPU using the proprietary driver you need to enable DRM KMS using the ``nvidia-drm.modeset=1`` kernel parameter. 116 | 117 | You can force a given buffer API by setting the ``WLC_BUFFER_API`` environment variable to ``GBM`` or ``EGL``. 118 | 119 | ISSUES 120 | ------ 121 | 122 | Submit issues on this repo if you are developing with ``wlc``. 123 | 124 | As a user of compositor, report issues to their corresponding issue trackers. 125 | 126 | BUILDING 127 | -------- 128 | 129 | You will need following makedepends: 130 | 131 | - cmake 132 | - git 133 | 134 | And the following depends: 135 | 136 | - pixman 137 | - wayland 1.7+ 138 | - wayland-protocols 1.7+ [1] 139 | - libxkbcommon 140 | - udev 141 | - libinput 142 | - libx11 (X11-xcb, Xfixes) 143 | - libxcb (xcb-ewmh, xcb-composite, xcb-xkb, xcb-image, xcb-xfixes) 144 | - libgbm (usually provided by mesa in most distros) 145 | - libdrm 146 | - libEGL (GPU drivers and mesa provide this) 147 | - libGLESv2 (GPU drivers and mesa provide this) 148 | 149 | 1: Also bundled as submodule. To build from submodule use -DSOURCE_WLPROTO=ON. 150 | 151 | And optionally: 152 | 153 | - dbus (for logind support) 154 | - systemd (for logind support) 155 | 156 | For weston-terminal and other wayland clients for testing, you might also want to build weston from git. 157 | 158 | You can build bootstrapped version of ``wlc`` with the following steps. 159 | 160 | .. code:: sh 161 | 162 | git submodule update --init --recursive # - initialize and fetch submodules 163 | mkdir target && cd target # - create build target directory 164 | cmake -DCMAKE_BUILD_TYPE=Upstream .. # - run CMake 165 | make # - compile 166 | 167 | # You can now run (Ctrl-Esc to quit) 168 | ./example/example 169 | 170 | PACKAGING 171 | --------- 172 | 173 | For now you can look at the `AUR recipe `_ for a example. 174 | 175 | Releases are signed with `B22DA89A `_ and published `on GitHub `_. 176 | 177 | All 0.0.x releases are considered unstable. 178 | 179 | CONTRIBUTING 180 | ------------ 181 | 182 | See the `CONTRIBUTING `_ for more information. 183 | 184 | BINDINGS 185 | -------- 186 | 187 | - `ocaml-wlc `_ - OCaml (experimental) 188 | - `go-wlc `_ - Go 189 | - `rust-wlc `_ - Rust 190 | - `wlc.rs `_ - Rust 191 | - `jwlc `_ - Java - work in progress 192 | 193 | SOFTWARE USING WLC 194 | ------------------ 195 | 196 | - `orbment `_ - Modular Wayland compositor 197 | - `ocaml-loliwm `_ - Translation of loliwm to OCaml 198 | - `sway `_ - i3-compatible window manager for Wayland 199 | - `way-cooler `_ - customizeable window manager written in Rust 200 | - `fireplace `_ - Modular wayland window manager written in Rust 201 | 202 | SIMILAR SOFTWARE 203 | ---------------- 204 | 205 | - `ewlc `_ - A separately maintained fork of wlc 206 | - `swc `_ - A library for making a simple Wayland compositor 207 | - `libwlb `_ - A Wayland back-end library 208 | - `libweston `_ - Weston as a library 209 | -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${WLC_INCLUDE_DIRS} 3 | ${CHCK_INCLUDE_DIRS} 4 | ${XKBCOMMON_INCLUDE_DIRS} 5 | ) 6 | add_executable(example example.c) 7 | target_link_libraries(example PRIVATE ${WLC_LIBRARIES}) 8 | -------------------------------------------------------------------------------- /include/wlc/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_DEFINES_H_ 2 | #define _WLC_DEFINES_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | #if __GNUC__ 11 | # define WLC_NONULL __attribute__((nonnull)) 12 | # define WLC_NONULLV(...) __attribute__((nonnull(__VA_ARGS__))) 13 | # define WLC_PURE __attribute__((pure)) 14 | # define WLC_CONST __attribute__((const)) 15 | # define WLC_DEPRECATED __attribute__((deprecated)) 16 | #else 17 | # define WLC_NONULL 18 | # define WLC_NONULLV 19 | # define WLC_PURE 20 | # define WLC_CONST 21 | # define WLC_DEPRECATED 22 | #endif 23 | 24 | /** printf format specifiers. */ 25 | #define PRIoWLC PRIoPTR 26 | #define PRIuWLC PRIuPTR 27 | #define PRIxWLC PRIxPTR 28 | #define PRIXWLC PRIXPTR 29 | 30 | typedef uintptr_t wlc_handle; 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif /* _WLC_DEFINES_H_ */ 37 | -------------------------------------------------------------------------------- /include/wlc/geometry.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_GEOMETRY_H_ 2 | #define _WLC_GEOMETRY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifndef MIN 15 | # define MIN(a, b) ((a) < (b) ? (a) : (b)) 16 | #endif 17 | 18 | #ifndef MAX 19 | # define MAX(a, b) ((a) > (b) ? (a) : (b)) 20 | #endif 21 | 22 | /** Fixed 2D point */ 23 | struct wlc_point { 24 | int32_t x, y; 25 | }; 26 | 27 | /** wlc_origin is depreacted in favor of wlc_point */ 28 | #define wlc_origin wlc_point __attribute__((deprecated("wlc_origin is deprecated, use wlc_point instead"))) 29 | 30 | /** Fixed 2D size */ 31 | struct wlc_size { 32 | uint32_t w, h; 33 | }; 34 | 35 | /** Fixed 2D point, size pair */ 36 | struct wlc_geometry { 37 | struct wlc_point origin; 38 | struct wlc_size size; 39 | }; 40 | 41 | static const struct wlc_point wlc_origin_zero = { 0, 0 }; 42 | static const struct wlc_point wlc_point_zero = { 0, 0 }; 43 | static const struct wlc_size wlc_size_zero = { 0, 0 }; 44 | static const struct wlc_geometry wlc_geometry_zero = { { 0, 0 }, { 0, 0 } }; 45 | 46 | WLC_NONULL static inline void 47 | wlc_point_min(const struct wlc_point *a, const struct wlc_point *b, struct wlc_point *out) 48 | { 49 | assert(a && b && out); 50 | out->x = MIN(a->x, b->x); 51 | out->y = MIN(a->y, b->y); 52 | } 53 | 54 | WLC_NONULL static inline void 55 | wlc_point_max(const struct wlc_point *a, const struct wlc_point *b, struct wlc_point *out) 56 | { 57 | assert(a && b && out); 58 | out->x = MAX(a->x, b->x); 59 | out->y = MAX(a->y, b->y); 60 | } 61 | 62 | WLC_NONULL static inline void 63 | wlc_size_min(const struct wlc_size *a, const struct wlc_size *b, struct wlc_size *out) 64 | { 65 | assert(a && b && out); 66 | out->w = MIN(a->w, b->w); 67 | out->h = MIN(a->h, b->h); 68 | } 69 | 70 | WLC_NONULL static inline void 71 | wlc_size_max(const struct wlc_size *a, const struct wlc_size *b, struct wlc_size *out) 72 | { 73 | assert(a && b && out); 74 | out->w = MAX(a->w, b->w); 75 | out->h = MAX(a->h, b->h); 76 | } 77 | 78 | WLC_NONULL WLC_PURE static inline bool 79 | wlc_point_equals(const struct wlc_point *a, const struct wlc_point *b) 80 | { 81 | assert(a && b); 82 | return !memcmp(a, b, sizeof(struct wlc_point)); 83 | } 84 | 85 | WLC_NONULL WLC_PURE static inline bool 86 | wlc_size_equals(const struct wlc_size *a, const struct wlc_size *b) 87 | { 88 | assert(a && b); 89 | return !memcmp(a, b, sizeof(struct wlc_size)); 90 | } 91 | 92 | WLC_NONULL WLC_PURE static inline bool 93 | wlc_geometry_equals(const struct wlc_geometry *a, const struct wlc_geometry *b) 94 | { 95 | assert(a && b); 96 | return !memcmp(a, b, sizeof(struct wlc_geometry)); 97 | } 98 | 99 | WLC_NONULL WLC_PURE static inline bool 100 | wlc_geometry_contains(const struct wlc_geometry *a, const struct wlc_geometry *b) 101 | { 102 | assert(a && b); 103 | return (a->origin.x <= b->origin.x && a->origin.y <= b->origin.y && 104 | a->origin.x + (int32_t)a->size.w >= b->origin.x + (int32_t)b->size.w && a->origin.y + (int32_t)a->size.h >= b->origin.y + (int32_t)b->size.h); 105 | } 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | 111 | #endif /* _WLC_GEOMETRY_H_ */ 112 | -------------------------------------------------------------------------------- /include/wlc/wlc-render.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_RENDER_H_ 2 | #define _WLC_RENDER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | /** 13 | * The functions in this file provide some basic rendering capabilities. 14 | * *_render(), *_read(), *_write() functions should only be called during post/pre render callbacks. 15 | * wlc_output_schedule_render() is exception and may be used to force wlc to render new frame (causing callbacks to trigger). 16 | * 17 | * For more advanced drawing you should directly use GLES2. 18 | * This is not documented as it's currently relying on the implementation details of wlc. 19 | */ 20 | 21 | /** Allowed pixel formats. */ 22 | enum wlc_pixel_format { 23 | WLC_RGBA8888, 24 | }; 25 | 26 | /** 27 | * Write pixel data with the specific format to output's framebuffer. 28 | * If the geometry is out of bounds, it will be automaticall clamped. 29 | */ 30 | WLC_NONULL void wlc_pixels_write(enum wlc_pixel_format format, const struct wlc_geometry *geometry, const void *data); 31 | 32 | /** 33 | * Read pixel data from output's framebuffer. 34 | * If the geometry is out of bounds, it will be automatically clamped. 35 | * Potentially clamped geometry will be stored in out_geometry, to indicate width / height of the returned data. 36 | */ 37 | WLC_NONULL void wlc_pixels_read(enum wlc_pixel_format format, const struct wlc_geometry *geometry, struct wlc_geometry *out_geometry, void *out_data); 38 | 39 | /** Renders surface. */ 40 | WLC_NONULL void wlc_surface_render(wlc_resource surface, const struct wlc_geometry *geometry); 41 | 42 | /** 43 | * Schedules output for rendering next frame. If output was already scheduled this is no-op, 44 | * if output is currently rendering, it will render immediately after. 45 | */ 46 | void wlc_output_schedule_render(wlc_handle output); 47 | 48 | /** 49 | * Adds frame callbacks of the given surface for the next output frame. 50 | * It applies recursively to all subsurfaces. 51 | * Useful when the compositor creates custom animations which require disabling internal rendering, 52 | * but still need to update the surface textures (for ex. video players). 53 | */ 54 | void wlc_surface_flush_frame_callbacks(wlc_resource surface); 55 | 56 | /** Enabled renderers */ 57 | enum wlc_renderer { 58 | WLC_RENDERER_GLES2, 59 | WLC_NO_RENDERER 60 | }; 61 | 62 | /** Returns currently active renderer on the given output */ 63 | enum wlc_renderer wlc_output_get_renderer(wlc_handle output); 64 | 65 | enum wlc_surface_format { 66 | SURFACE_RGB, 67 | SURFACE_RGBA, 68 | SURFACE_EGL, 69 | SURFACE_Y_UV, 70 | SURFACE_Y_U_V, 71 | SURFACE_Y_XUXV, 72 | }; 73 | 74 | /** 75 | * Fills out_textures[] with the textures of a surface. Returns false if surface is invalid. 76 | * Array must have at least 3 elements and should be refreshed at each frame. 77 | * Note that these are not only OpenGL textures but rather render-specific. 78 | * For more info what they are check the renderer's source code */ 79 | bool wlc_surface_get_textures(wlc_resource surface, uint32_t out_textures[3], enum wlc_surface_format *out_format); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | #endif /* _WLC_RENDER_H_ */ 86 | -------------------------------------------------------------------------------- /include/wlc/wlc-wayland.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_WAYLAND_H_ 2 | #define _WLC_WAYLAND_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | typedef uintptr_t wlc_resource; 13 | 14 | struct wl_resource; 15 | struct wl_display; 16 | 17 | /** Returns Wayland display. */ 18 | struct wl_display* wlc_get_wl_display(void); 19 | 20 | /** Returns view handle from wl_surface resource. */ 21 | WLC_NONULL wlc_handle wlc_handle_from_wl_surface_resource(struct wl_resource *resource); 22 | 23 | /** Returns output handle from wl_output resource. */ 24 | WLC_NONULL wlc_handle wlc_handle_from_wl_output_resource(struct wl_resource *resource); 25 | 26 | /** Returns internal wlc surface from wl_surface resource. */ 27 | WLC_NONULL wlc_resource wlc_resource_from_wl_surface_resource(struct wl_resource *resource); 28 | 29 | /** Get surface size. */ 30 | const struct wlc_size* wlc_surface_get_size(wlc_resource surface); 31 | 32 | /** Return wl_surface resource from internal wlc surface. */ 33 | struct wl_resource* wlc_surface_get_wl_resource(wlc_resource surface); 34 | 35 | /** 36 | * Turns wl_surface into a wlc view. Returns 0 on failure. This will also trigger view.created callback as any view would. 37 | * For the extra arguments see details of wl_resource_create and wl_resource_set_implementation. 38 | * The extra arguments may be set NULL, if you are not implementing Wayland interface for the surface role. 39 | */ 40 | wlc_handle wlc_view_from_surface(wlc_resource surface, struct wl_client *client, const struct wl_interface *interface, const void *implementation, uint32_t version, uint32_t id, void *userdata); 41 | 42 | /** Returns internal wlc surface from view handle */ 43 | wlc_resource wlc_view_get_surface(wlc_handle view); 44 | 45 | /** Returns a list of the subsurfaces of the given surface */ 46 | const wlc_resource* wlc_surface_get_subsurfaces(wlc_resource parent, size_t *out_size); 47 | 48 | /** Returns the size of a subsurface and its position relative to parent */ 49 | void wlc_get_subsurface_geometry(wlc_resource surface, struct wlc_geometry *out_geometry); 50 | 51 | /** Returns wl_client from view handle */ 52 | struct wl_client* wlc_view_get_wl_client(wlc_handle view); 53 | 54 | /** Returns surface role resource from view handle. Return value will be NULL if the view was not assigned role or created with wlc_view_create_from_surface(). */ 55 | struct wl_resource* wlc_view_get_role(wlc_handle view); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* _WLC_WAYLAND_H_ */ 62 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_compile_options(-fvisibility=hidden) 2 | 3 | set(CHCK_BUILD_STATIC ON CACHE STRING "Build chck statically if not found systemwide" FORCE) 4 | set(CHCK_BUILD_TESTS OFF CACHE STRING "Do not build chck tests" FORCE) 5 | add_subproject(chck Chck) 6 | -------------------------------------------------------------------------------- /man/man3/wlc_view_get_pid.3: -------------------------------------------------------------------------------- 1 | .TH WLC_VIEW_GET_PID 3 2016-07-29 WLC "WLC Core API Functions" 2 | 3 | .SH NAME 4 | wlc_view_get_pid - get the process id for a given view 5 | 6 | .SH SYNOPSIS 7 | .B #include 8 | 9 | .BI "pid_t wlc_view_get_pid(wlc_handle "view ");" 10 | 11 | .SS Wayland protocol requirements: 12 | .RS 13 | .BR wlc_view_get_pid (): 14 | xdg_shell 15 | .RE 16 | 17 | .SH DESCRIPTION 18 | .BR wlc_view_get_pid () 19 | can be used to acquire the process id of a given 20 | .I view. 21 | 22 | .SH RETURN VALUE 23 | .BR wlc_view_get_pid () 24 | returns the process id for 25 | .I view 26 | if it is available. Returns 0 (not a valid pid) if it is not. For X11 27 | views this requires the application set the __NET_WM_PID property. 28 | 29 | .SH ALSO SEE 30 | The XDG Shell protocol extension 31 | .UR http://cgit.freedesktop.org/wayland/weston/tree/protocol/xdg-shell.xml 32 | .UE 33 | -------------------------------------------------------------------------------- /protos/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(Wayland) 2 | 3 | if (WAYLANDPROTOCOLS_FOUND AND NOT SOURCE_WLPROTO) 4 | set(prefix "${WAYLANDPROTOCOLS_PATH}") 5 | else () 6 | set(prefix "wayland-protocols") 7 | endif () 8 | 9 | include_directories( 10 | ${WAYLAND_SERVER_INCLUDE_DIRS} 11 | ) 12 | 13 | set(protos 14 | "${prefix}/unstable/xdg-shell/xdg-shell-unstable-v6") 15 | 16 | foreach(proto ${protos}) 17 | add_feature_info(${proto} proto "Protocol extension") 18 | get_filename_component(base ${proto} NAME) 19 | wayland_add_protocol_server(src "${proto}.xml" ${base}) 20 | list(APPEND sources ${src}) 21 | endforeach() 22 | 23 | set_source_files_properties(${sources} PROPERTIES GENERATED ON) 24 | add_library(wlc-protos STATIC ${sources}) 25 | 26 | set(test_protos 27 | test-extension) 28 | 29 | foreach(proto ${test_protos}) 30 | wayland_add_protocol_server(src "${proto}.xml" ${proto}) 31 | wayland_add_protocol_client(src "${proto}.xml" ${proto}) 32 | list(APPEND test_sources ${src}) 33 | endforeach() 34 | 35 | set_source_files_properties(${test_sources} PROPERTIES GENERATED ON) 36 | add_library(wlc-tests-protos STATIC ${test_sources}) 37 | -------------------------------------------------------------------------------- /protos/test-extension.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Allows setting background surface. 5 | This is example interface, weston tree contains more fully featured desktop-shell interface. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /shared/os-compatibility.h: -------------------------------------------------------------------------------- 1 | #ifndef __wlc_os_compatibility_h__ 2 | #define __wlc_os_compatibility_h__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if !HAVE_MKOSTEMP 12 | static int 13 | set_cloexec_or_close(int fd) 14 | { 15 | if (fd == -1) 16 | return -1; 17 | 18 | long flags; 19 | if ((flags = fcntl(fd, F_GETFD)) == -1) 20 | goto err; 21 | 22 | if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) 23 | goto err; 24 | 25 | return fd; 26 | 27 | err: 28 | close(fd); 29 | return -1; 30 | } 31 | #endif 32 | 33 | static int 34 | create_tmpfile_cloexec(char *tmpname) 35 | { 36 | int fd; 37 | 38 | #if HAVE_MKOSTEMP 39 | if ((fd = mkostemp(tmpname, O_CLOEXEC)) >= 0) 40 | unlink(tmpname); 41 | #else 42 | if ((fd = mkstemp(tmpname)) >= 0) { 43 | fd = set_cloexec_or_close(fd); 44 | unlink(tmpname); 45 | } 46 | #endif 47 | 48 | return fd; 49 | } 50 | 51 | static int 52 | os_create_anonymous_file(off_t size) 53 | { 54 | static const char template[] = "/wlc-shared-XXXXXX"; 55 | 56 | const char *path = getenv("XDG_RUNTIME_DIR"); 57 | if (chck_cstr_is_empty(path)) 58 | return -1; 59 | 60 | struct chck_string name = {0}; 61 | if (!chck_string_set_format(&name, "%s%s%s", path, (chck_cstr_ends_with(path, "/") ? "" : "/"), template)) 62 | return -1; 63 | 64 | int fd = create_tmpfile_cloexec(name.data); 65 | chck_string_release(&name); 66 | 67 | if (fd < 0) 68 | return -1; 69 | 70 | int ret; 71 | #if HAVE_POSIX_FALLOCATE 72 | if ((ret = posix_fallocate(fd, 0, size)) != 0) { 73 | close(fd); 74 | errno = ret; 75 | return -1; 76 | } 77 | #else 78 | if ((ret = ftruncate(fd, size)) < 0) { 79 | close(fd); 80 | return -1; 81 | } 82 | #endif 83 | 84 | return fd; 85 | } 86 | 87 | #endif /* __wlc_os_compatibility_h__ */ 88 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_definitions( 2 | -DWL_HIDE_DEPRECATED 3 | ${WAYLAND_DEFINITIONS} 4 | ${PIXMAN_DEFINITIONS} 5 | ${GBM_DEFINITIONS} 6 | ${DRM_DEFINITIONS} 7 | ${XKBCOMMON_DEFINITIONS} 8 | ${EGL_DEFINITIONS} 9 | ${GLESv2_DEFINITIONS} 10 | ${UDEV_DEFINITIONS} 11 | ${LIBINPUT_DEFINITIONS} 12 | ) 13 | 14 | include_directories( 15 | ${CMAKE_CURRENT_SOURCE_DIR} 16 | ${PROJECT_BINARY_DIR}/protos 17 | ${PROJECT_SOURCE_DIR}/include 18 | ${CHCK_INCLUDE_DIRS} 19 | ${WAYLAND_SERVER_INCLUDE_DIRS} 20 | ${PIXMAN_INCLUDE_DIRS} 21 | ${GBM_INCLUDE_DIRS} 22 | ${DRM_INCLUDE_DIRS} 23 | ${XKBCOMMON_INCLUDE_DIRS} 24 | ${EGL_INCLUDE_DIRS} 25 | ${GLESv2_INCLUDE_DIRS} 26 | ${UDEV_INCLUDE_DIRS} 27 | ${LIBINPUT_INCLUDE_DIRS} 28 | ) 29 | 30 | set(sources 31 | compositor/compositor.c 32 | compositor/output.c 33 | compositor/seat/data.c 34 | compositor/seat/keyboard.c 35 | compositor/seat/keymap.c 36 | compositor/seat/pointer.c 37 | compositor/seat/seat.c 38 | compositor/seat/touch.c 39 | compositor/shell/shell.c 40 | compositor/shell/xdg-shell.c 41 | compositor/shell/custom-shell.c 42 | compositor/view.c 43 | platform/backend/backend.c 44 | platform/backend/drm.c 45 | platform/context/context.c 46 | platform/context/egl.c 47 | platform/render/gles2.c 48 | platform/render/render.c 49 | resources/resources.c 50 | resources/types/buffer.c 51 | resources/types/data-source.c 52 | resources/types/region.c 53 | resources/types/shell-surface.c 54 | resources/types/surface.c 55 | resources/types/xdg-toplevel.c 56 | resources/types/xdg-positioner.c 57 | session/fd.c 58 | session/tty.c 59 | session/udev.c 60 | wlc.c 61 | extended/wlc-wayland.c 62 | extended/wlc-render.c 63 | ) 64 | 65 | if (ENABLE_X11_BACKEND OR ENABLE_XWAYLAND_SUPPORT) 66 | add_definitions(${XCB_DEFINITIONS}) 67 | include_directories(${XCB_INCLUDE_DIRS}) 68 | list(APPEND libs ${XCB_LIBRARIES}) 69 | endif () 70 | 71 | if (ENABLE_X11_BACKEND) 72 | add_definitions(-DENABLE_X11_BACKEND) 73 | include_directories(${X11_INCLUDE_DIR}) 74 | list(APPEND sources platform/backend/x11.c) 75 | list(APPEND libs ${X11_LIBRARIES}) 76 | endif () 77 | 78 | if (ENABLE_XWAYLAND_SUPPORT) 79 | add_definitions(-DENABLE_XWAYLAND) 80 | list(APPEND sources xwayland/xwayland.c xwayland/xwm.c xwayland/selection.c) 81 | endif () 82 | 83 | if (DBUS_FOUND) 84 | add_definitions(-DDBUS_DISABLE_DEPRECATED ${DBUS_DEFINITIONS}) 85 | include_directories(${DBUS_INCLUDE_DIRS}) 86 | list(APPEND sources session/dbus.c) 87 | list(APPEND libs ${DBUS_LIBRARIES}) 88 | endif () 89 | 90 | if (SYSTEMD_FOUND) 91 | add_definitions(${SYSTEMD_DEFINITIONS}) 92 | include_directories(${SYSTEMD_INCLUDE_DIRS}) 93 | 94 | if (DBUS_FOUND) 95 | add_definitions(-DHAS_LOGIND) 96 | list(APPEND sources session/logind.c) 97 | list(APPEND libs ${SYSTEMD_LIBRARIES}) 98 | else () 99 | message("Dbus was not found, so logind is disabled") 100 | endif () 101 | endif () 102 | 103 | if (ELOGIND_FOUND) 104 | add_definitions(${ELOGIND_DEFINITIONS}) 105 | include_directories(${ELOGIND_INCLUDE_DIRS}) 106 | 107 | if (DBUS_FOUND) 108 | add_definitions(-DHAS_LOGIND) 109 | list(APPEND sources session/logind.c) 110 | list(APPEND libs ${ELOGIND_LIBRARIES}) 111 | else () 112 | message("Dbus was not found, so logind is disabled") 113 | endif () 114 | endif () 115 | 116 | if (WLC_WAYLAND_BACKEND_SUPPORT) 117 | add_definitions(-DENABLE_WAYLAND_BACKEND) 118 | include_directories(${WAYLAND_CLIENT_INCLUDE_DIRS}) 119 | include_directories(${WAYLAND_EGL_INCLUDE_DIRS}) 120 | list(APPEND sources platform/backend/wayland.c) 121 | list(APPEND libs ${WAYLAND_CLIENT_LIBRARIES}) 122 | list(APPEND libs ${WAYLAND_EGL_LIBRARIES}) 123 | endif () 124 | 125 | foreach (src ${sources}) 126 | set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS -DWLC_FILE=\\\"${src}\\\") 127 | endforeach () 128 | 129 | add_compile_options(-fvisibility=hidden) 130 | add_library(wlc-object OBJECT ${sources}) 131 | add_dependencies(wlc-object wlc-protos) 132 | 133 | if (WLC_BUILD_STATIC) 134 | add_library(wlc STATIC $) 135 | else () 136 | add_definitions(-DWLC_BUILD_SHARED) 137 | add_library(wlc SHARED $) 138 | endif () 139 | 140 | target_link_libraries(wlc 141 | PRIVATE 142 | wlc-protos 143 | ${CHCK_LIBRARIES} 144 | ${WAYLAND_SERVER_LIBRARIES} 145 | ${PIXMAN_LIBRARIES} 146 | ${XKBCOMMON_LIBRARIES} 147 | ${LIBINPUT_LIBRARIES} 148 | ${UDEV_LIBRARIES} 149 | ${GLESv2_LIBRARIES} 150 | ${EGL_LIBRARIES} 151 | ${DRM_LIBRARIES} 152 | ${GBM_LIBRARIES} 153 | ${MATH_LIBRARY} 154 | ${CMAKE_DL_LIBS} 155 | ${libs} 156 | ) 157 | 158 | # Combine wlc-tests for tests, it's static so it has all symbols visible 159 | add_library(wlc-tests STATIC $) 160 | target_link_libraries(wlc-tests 161 | PRIVATE 162 | wlc-protos 163 | ${CHCK_LIBRARIES} 164 | ${WAYLAND_SERVER_LIBRARIES} 165 | ${PIXMAN_LIBRARIES} 166 | ${XKBCOMMON_LIBRARIES} 167 | ${LIBINPUT_LIBRARIES} 168 | ${UDEV_LIBRARIES} 169 | ${GLESv2_LIBRARIES} 170 | ${EGL_LIBRARIES} 171 | ${DRM_LIBRARIES} 172 | ${GBM_LIBRARIES} 173 | ${MATH_LIBRARY} 174 | ${CMAKE_DL_LIBS} 175 | ${libs} 176 | ) 177 | 178 | # Parse soversion 179 | string(REGEX MATCHALL "[0-9]+" VERSION_COMPONENTS ${PROJECT_VERSION}) 180 | list(GET VERSION_COMPONENTS 0 SOVERSION) 181 | set_target_properties(wlc PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${SOVERSION}) 182 | 183 | # Set helpful variables for add_subdirectory build 184 | set(WLC_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" ${XKBCOMMON_INCLUDE_DIRS} ${LIBINPUT_INCLUDE_DIRS} CACHE STRING "Include directories of wlc" FORCE) 185 | set(WLC_LIBRARIES wlc ${XKBCOMMON_LIBRARIES} ${LIBINPUT_LIBRARIES} CACHE STRING "Libraries needed for wlc" FORCE) 186 | mark_as_advanced(WLC_DEFINITIONS WLC_INCLUDE_DIRS WLC_LIBRARIES) 187 | 188 | # Add pkgconfig 189 | configure_file(wlc.pc.in wlc.pc @ONLY) 190 | 191 | # Install rules 192 | install(TARGETS wlc DESTINATION "${CMAKE_INSTALL_LIBDIR}") 193 | install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/wlc" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 194 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/wlc.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 195 | -------------------------------------------------------------------------------- /src/FindWlc.cmake: -------------------------------------------------------------------------------- 1 | #.rst: 2 | # FindWlc 3 | # ------- 4 | # 5 | # Find wlc library 6 | # 7 | # Try to find wlc library. The following values are defined 8 | # 9 | # :: 10 | # 11 | # WLC_FOUND - True if wlc is available 12 | # WLC_INCLUDE_DIRS - Include directories for wlc 13 | # WLC_LIBRARIES - List of libraries for wlc 14 | # WLC_DEFINITIONS - List of definitions for wlc 15 | # 16 | #============================================================================= 17 | # Copyright (c) 2015 Jari Vetoniemi 18 | # 19 | # Distributed under the OSI-approved BSD License (the "License"); 20 | # 21 | # This software is distributed WITHOUT ANY WARRANTY; without even the 22 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 | # See the License for more information. 24 | #============================================================================= 25 | 26 | include(FeatureSummary) 27 | set_package_properties(wlc PROPERTIES 28 | URL "https://github.com/Cloudef/wlc/" 29 | DESCRIPTION "Wayland compositor library") 30 | 31 | find_package(PkgConfig) 32 | pkg_check_modules(PC_WLC QUIET wlc) 33 | find_path(WLC_INCLUDE_DIRS NAMES wlc/wlc.h HINTS ${PC_WLC_INCLUDE_DIRS}) 34 | find_library(WLC_LIBRARIES NAMES wlc HINTS ${PC_WLC_LIBRARY_DIRS}) 35 | 36 | set(WLC_DEFINITIONS ${PC_WLC_CFLAGS_OTHER}) 37 | 38 | include(FindPackageHandleStandardArgs) 39 | find_package_handle_standard_args(wlc DEFAULT_MSG WLC_LIBRARIES WLC_INCLUDE_DIRS) 40 | mark_as_advanced(WLC_LIBRARIES WLC_INCLUDE_DIRS WLC_DEFINITIONS) 41 | -------------------------------------------------------------------------------- /src/compositor/compositor.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_COMPOSITOR_H_ 2 | #define _WLC_COMPOSITOR_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "seat/seat.h" 9 | #include "shell/shell.h" 10 | #include "shell/xdg-shell.h" 11 | #include "shell/custom-shell.h" 12 | #include "xwayland/xwm.h" 13 | #include "resources/resources.h" 14 | #include "platform/backend/backend.h" 15 | 16 | struct wlc_view; 17 | struct wlc_surface; 18 | 19 | struct wlc_compositor { 20 | struct wlc_backend backend; 21 | struct wlc_seat seat; 22 | struct wlc_shell shell; 23 | struct wlc_xdg_shell xdg_shell; 24 | struct wlc_custom_shell custom_shell; 25 | struct wlc_xwm xwm; 26 | struct wlc_source outputs, views, surfaces, subsurfaces, regions; 27 | 28 | struct { 29 | wlc_handle output; 30 | } active; 31 | 32 | struct { 33 | struct wl_global *compositor; 34 | struct wl_global *subcompositor; 35 | } wl; 36 | 37 | struct { 38 | struct wl_listener activate; 39 | struct wl_listener terminate; 40 | struct wl_listener xwayland; 41 | struct wl_listener surface; 42 | struct wl_listener output; 43 | struct wl_listener focus; 44 | } listener; 45 | 46 | struct { 47 | wlc_handle *outputs; 48 | } tmp; 49 | 50 | struct { 51 | struct wl_event_source *idle; 52 | enum { 53 | IDLE, 54 | ACTIVATING, 55 | DEACTIVATING, 56 | } tty; 57 | int vt; 58 | bool terminating, ready; 59 | } state; 60 | }; 61 | 62 | WLC_NONULL bool wlc_compositor_is_good(struct wlc_compositor *compositor); 63 | WLC_NONULL struct wlc_view* wlc_compositor_view_for_surface(struct wlc_compositor *compositor, struct wlc_surface *surface); 64 | void wlc_compositor_terminate(struct wlc_compositor *compositor); 65 | void wlc_compositor_release(struct wlc_compositor *compositor); 66 | WLC_NONULL bool wlc_compositor(struct wlc_compositor *compositor); 67 | 68 | #endif /* _WLC_COMPOSITOR_H_ */ 69 | -------------------------------------------------------------------------------- /src/compositor/output.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_OUTPUT_H_ 2 | #define _WLC_OUTPUT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "platform/backend/backend.h" 9 | #include "platform/context/context.h" 10 | #include "platform/render/render.h" 11 | #include "resources/resources.h" 12 | #include "internal.h" 13 | 14 | struct wl_global; 15 | struct wlc_surface; 16 | struct wlc_buffer; 17 | struct timespec; 18 | 19 | enum output_link { 20 | LINK_BELOW, 21 | LINK_ABOVE, 22 | }; 23 | 24 | struct wlc_output_mode { 25 | int32_t refresh; 26 | int32_t width, height; 27 | uint32_t flags; // WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED 28 | }; 29 | 30 | struct wlc_output_information { 31 | struct chck_iter_pool modes; 32 | struct chck_string name, make, model; 33 | int32_t x, y; 34 | int32_t physical_width, physical_height; 35 | int32_t subpixel; 36 | uint32_t connector_id; 37 | uint32_t crtc_id; 38 | enum wl_output_transform transform; 39 | enum wlc_connector_type connector; 40 | }; 41 | 42 | struct wlc_output { 43 | struct wlc_source resources; 44 | struct wlc_size mode, resolution, virtual; 45 | struct wlc_output_information information; 46 | struct wlc_backend_surface bsurface; 47 | struct wlc_context context; 48 | struct wlc_render render; 49 | 50 | // XXX: maybe we can use source later and provide move semantics (for views)? 51 | struct chck_iter_pool surfaces, views, mutable; 52 | struct chck_iter_pool callbacks, visible; 53 | 54 | // Pixel blit buffer size of current resolution 55 | // Used to do visibility checks 56 | bool *blit; 57 | 58 | // Scale of the output 59 | // Affects virtual resolution by dividing with the scale 60 | uint32_t scale; 61 | 62 | struct { 63 | struct wl_event_source *idle; 64 | } timer; 65 | 66 | struct { 67 | struct wl_global *output; 68 | } wl; 69 | 70 | // FIXME: replace with better system 71 | struct { 72 | struct wlc_backend_surface bsurface; 73 | bool terminate; 74 | bool sleep; 75 | } task; 76 | 77 | struct { 78 | float ims; 79 | uint32_t frame_time; 80 | bool pending, scheduled, activity, sleeping; 81 | bool background_visible; 82 | bool created; 83 | } state; 84 | 85 | struct { 86 | uint32_t mode; 87 | uint32_t mask; 88 | } active; 89 | }; 90 | 91 | WLC_NONULL bool wlc_output_information(struct wlc_output_information *info); 92 | void wlc_output_information_release(struct wlc_output_information *info); 93 | WLC_NONULL bool wlc_output_information_add_mode(struct wlc_output_information *info, struct wlc_output_mode *mode); 94 | 95 | WLC_NONULLV(2) void wlc_output_finish_frame(struct wlc_output *output, const struct timespec *ts); 96 | void wlc_output_schedule_repaint(struct wlc_output *output); 97 | WLC_NONULLV(2) bool wlc_output_surface_attach(struct wlc_output *output, struct wlc_surface *surface, struct wlc_buffer *buffer); 98 | WLC_NONULLV(2) void wlc_output_surface_destroy(struct wlc_output *output, struct wlc_surface *surface); 99 | bool wlc_output_set_backend_surface(struct wlc_output *output, struct wlc_backend_surface *surface); 100 | void wlc_output_set_information(struct wlc_output *output, struct wlc_output_information *info); 101 | WLC_NONULLV(2) void wlc_output_unlink_view(struct wlc_output *output, struct wlc_view *view); 102 | WLC_NONULLV(2) void wlc_output_link_view(struct wlc_output *output, struct wlc_view *view, enum output_link link, struct wlc_view *other); 103 | void wlc_output_terminate(struct wlc_output *output); 104 | void wlc_output_release(struct wlc_output *output); 105 | WLC_NONULL bool wlc_output(struct wlc_output *output); 106 | 107 | void wlc_output_focus_ptr(struct wlc_output *output); 108 | void wlc_output_set_sleep_ptr(struct wlc_output *output, bool sleep); 109 | void wlc_output_set_gamma_ptr(struct wlc_output *output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); 110 | WLC_NONULLV(2) bool wlc_output_set_resolution_ptr(struct wlc_output *output, const struct wlc_size *resolution, uint32_t scale); 111 | void wlc_output_set_mask_ptr(struct wlc_output *output, uint32_t mask); 112 | WLC_NONULLV(2) void wlc_output_get_pixels_ptr(struct wlc_output *output, bool (*pixels)(const struct wlc_size *size, uint8_t *rgba, void *arg), void *arg); 113 | bool wlc_output_set_views_ptr(struct wlc_output *output, const wlc_handle *views, size_t memb); 114 | const wlc_handle* wlc_output_get_views_ptr(struct wlc_output *output, size_t *out_memb); 115 | wlc_handle* wlc_output_get_mutable_views_ptr(struct wlc_output *output, size_t *out_memb); 116 | 117 | /** for wlc-render.h */ 118 | WLC_NONULL void wlc_output_render_surface(struct wlc_output *output, struct wlc_surface *surface, const struct wlc_geometry *geometry, struct chck_iter_pool *callbacks); 119 | struct wlc_output* wlc_get_rendering_output(void); 120 | 121 | #endif /* _WLC_OUTPUT_H_ */ 122 | -------------------------------------------------------------------------------- /src/compositor/seat/data.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_DATA_DEVICE_MANAGER_H_ 2 | #define _WLC_DATA_DEVICE_MANAGER_H_ 3 | 4 | #include 5 | #include 6 | #include "resources/resources.h" 7 | #include "resources/types/data-source.h" 8 | 9 | struct wl_global; 10 | 11 | struct wlc_data_device_manager { 12 | struct wlc_source sources, devices, offers; 13 | struct wlc_seat *seat; 14 | 15 | struct { 16 | struct wl_global *manager; 17 | } wl; 18 | 19 | struct wlc_data_source *source; 20 | }; 21 | 22 | WLC_NONULLV(1) void wlc_data_device_manager_offer(struct wlc_data_device_manager *device, struct wl_client *client); 23 | void wlc_data_device_manager_release(struct wlc_data_device_manager *manager); 24 | WLC_NONULL bool wlc_data_device_manager(struct wlc_data_device_manager *manager, struct wlc_seat *seat); 25 | 26 | void wlc_data_device_manager_set_source(struct wlc_data_device_manager *manager, struct wlc_data_source *source); 27 | void wlc_data_device_manager_set_custom_selection(struct wlc_data_device_manager *manager, void *data, 28 | const char *const *types, size_t types_count, void (*send)(void *data, const char *type, int fd)); 29 | 30 | #endif /* _WLC_DATA_DEVICE_MANAGER_H_ */ 31 | -------------------------------------------------------------------------------- /src/compositor/seat/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_KEYBOARD_H_ 2 | #define _WLC_KEYBOARD_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "resources/resources.h" 9 | 10 | enum wl_keyboard_key_state; 11 | 12 | struct wl_list; 13 | struct wl_resource; 14 | struct xkb_state; 15 | struct wlc_keymap; 16 | struct wlc_view; 17 | struct wlc_client; 18 | struct wlc_modifiers; 19 | 20 | struct wlc_keyboard { 21 | struct wlc_keymap *keymap; 22 | struct wlc_source resources; 23 | struct chck_iter_pool keys; 24 | 25 | struct { 26 | struct wl_event_source *repeat; 27 | } timer; 28 | 29 | struct { 30 | struct chck_iter_pool resources; 31 | wlc_handle view; 32 | } focused; 33 | 34 | struct { 35 | uint32_t depressed; 36 | uint32_t latched; 37 | uint32_t locked; 38 | uint32_t group; 39 | } mods; 40 | 41 | // for interface calls (public) 42 | struct wlc_modifiers modifiers; 43 | 44 | struct { 45 | uint32_t delay, rate; 46 | } repeat; 47 | 48 | struct { 49 | struct xkb_state *xkb, *sym; 50 | bool repeat, repeating, focused; 51 | } state; 52 | }; 53 | 54 | WLC_NONULLV(1) uint32_t wlc_keyboard_get_keysym_for_key_ptr(struct wlc_keyboard *keyboard, uint32_t key, const struct wlc_modifiers *modifiers); 55 | WLC_NONULLV(1) uint32_t wlc_keyboard_get_utf32_for_key_ptr(struct wlc_keyboard *keyboard, uint32_t key, const struct wlc_modifiers *modifiers); 56 | 57 | WLC_NONULLV(1) void wlc_keyboard_update_modifiers(struct wlc_keyboard *keyboard, struct libinput_device *device); 58 | WLC_NONULL bool wlc_keyboard_request_key(struct wlc_keyboard *keyboard, uint32_t time, const struct wlc_modifiers *mods, uint32_t key, enum wl_keyboard_key_state state); 59 | WLC_NONULL bool wlc_keyboard_update(struct wlc_keyboard *keyboard, uint32_t key, enum wl_keyboard_key_state state); 60 | WLC_NONULL void wlc_keyboard_key(struct wlc_keyboard *keyboard, uint32_t time, uint32_t key, enum wl_keyboard_key_state state); 61 | WLC_NONULLV(1) void wlc_keyboard_focus(struct wlc_keyboard *keyboard, struct wlc_view *view); 62 | WLC_NONULLV(1) bool wlc_keyboard_set_keymap(struct wlc_keyboard *keyboard, struct wlc_keymap *keymap); 63 | void wlc_keyboard_release(struct wlc_keyboard *keyboard); 64 | WLC_NONULL bool wlc_keyboard(struct wlc_keyboard *keyboard, struct wlc_keymap *keymap); 65 | 66 | #endif /* _WLC_KEYBOARD_H_ */ 67 | -------------------------------------------------------------------------------- /src/compositor/seat/keymap.c: -------------------------------------------------------------------------------- 1 | #include "os-compatibility.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "internal.h" 7 | #include "keymap.h" 8 | 9 | const char *WLC_MOD_NAMES[WLC_MOD_LAST] = { 10 | XKB_MOD_NAME_SHIFT, 11 | XKB_MOD_NAME_CAPS, 12 | XKB_MOD_NAME_CTRL, 13 | XKB_MOD_NAME_ALT, 14 | "Mod2", 15 | "Mod3", 16 | XKB_MOD_NAME_LOGO, 17 | "Mod5", 18 | }; 19 | 20 | const char *WLC_LED_NAMES[WLC_LED_LAST] = { 21 | XKB_LED_NAME_NUM, 22 | XKB_LED_NAME_CAPS, 23 | XKB_LED_NAME_SCROLL 24 | }; 25 | 26 | WLC_PURE uint32_t 27 | wlc_keymap_get_mod_mask(struct wlc_keymap *keymap, uint32_t in) 28 | { 29 | assert(keymap); 30 | 31 | uint32_t mods = 0; 32 | for (uint32_t i = 0; i < WLC_MOD_LAST; ++i) { 33 | if (keymap->mods[i] != XKB_MOD_INVALID && (in & (1 << keymap->mods[i]))) 34 | mods |= (1 << i); 35 | } 36 | 37 | return mods; 38 | } 39 | 40 | uint32_t 41 | wlc_keymap_get_led_mask(struct wlc_keymap *keymap, struct xkb_state *xkb) 42 | { 43 | assert(keymap && xkb); 44 | 45 | uint32_t leds = 0; 46 | for (uint32_t i = 0; i < WLC_LED_LAST; ++i) { 47 | if (xkb_state_led_index_is_active(xkb, keymap->leds[i])) 48 | leds |= (1 << i); 49 | } 50 | 51 | return leds; 52 | } 53 | 54 | void 55 | wlc_keymap_release(struct wlc_keymap *keymap) 56 | { 57 | if (!keymap) 58 | return; 59 | 60 | if (keymap->keymap) 61 | xkb_map_unref(keymap->keymap); 62 | 63 | if (keymap->area) 64 | munmap(keymap->area, keymap->size); 65 | 66 | if (keymap->fd >= 0) 67 | close(keymap->fd); 68 | 69 | *keymap = (struct wlc_keymap){0}; 70 | keymap->fd = -1; 71 | } 72 | 73 | bool 74 | wlc_keymap(struct wlc_keymap *keymap, const struct xkb_rule_names *names, enum xkb_keymap_compile_flags flags) 75 | { 76 | assert(keymap); 77 | memset(keymap, 0, sizeof(struct wlc_keymap)); 78 | 79 | char *keymap_str = NULL; 80 | 81 | struct xkb_context *context; 82 | if (!(context = xkb_context_new(XKB_CONTEXT_NO_FLAGS))) 83 | goto context_fail; 84 | 85 | if (!(keymap->keymap = xkb_map_new_from_names(context, names, flags))) 86 | goto keymap_fail; 87 | 88 | xkb_context_unref(context); 89 | context = NULL; 90 | 91 | if (!(keymap_str = xkb_map_get_as_string(keymap->keymap))) 92 | goto string_fail; 93 | 94 | keymap->size = strlen(keymap_str) + 1; 95 | if ((keymap->fd = os_create_anonymous_file(keymap->size)) < 0) 96 | goto file_fail; 97 | 98 | if (!(keymap->area = mmap(NULL, keymap->size, PROT_READ | PROT_WRITE, MAP_SHARED, keymap->fd, 0))) 99 | goto mmap_fail; 100 | 101 | for (uint32_t i = 0; i < WLC_MOD_LAST; ++i) 102 | keymap->mods[i] = xkb_map_mod_get_index(keymap->keymap, WLC_MOD_NAMES[i]); 103 | 104 | for (uint32_t i = 0; i < WLC_LED_LAST; ++i) 105 | keymap->leds[i] = xkb_map_led_get_index(keymap->keymap, WLC_LED_NAMES[i]); 106 | 107 | keymap->format = WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1; 108 | memcpy(keymap->area, keymap_str, keymap->size - 1); 109 | free(keymap_str); 110 | return keymap; 111 | 112 | context_fail: 113 | wlc_log(WLC_LOG_WARN, "Failed to create xkb context"); 114 | goto fail; 115 | keymap_fail: 116 | wlc_log(WLC_LOG_WARN, "Failed to get xkb keymap"); 117 | goto fail; 118 | string_fail: 119 | wlc_log(WLC_LOG_WARN, "Failed to get keymap as string"); 120 | goto fail; 121 | file_fail: 122 | wlc_log(WLC_LOG_WARN, "Failed to create file for keymap"); 123 | goto fail; 124 | mmap_fail: 125 | wlc_log(WLC_LOG_WARN, "Failed to mmap keymap"); 126 | fail: 127 | free(keymap_str); 128 | xkb_context_unref(context); 129 | wlc_keymap_release(keymap); 130 | return NULL; 131 | } 132 | -------------------------------------------------------------------------------- /src/compositor/seat/keymap.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_KEYMAP_H_ 2 | #define _WLC_KEYMAP_H_ 3 | 4 | #include 5 | #include 6 | 7 | struct xkb_keymap; 8 | struct xkb_rule_names; 9 | enum xkb_keymap_compile_flags; 10 | 11 | enum wlc_modifier { 12 | WLC_MOD_SHIFT, 13 | WLC_MOD_CAPS, 14 | WLC_MOD_CTRL, 15 | WLC_MOD_ALT, 16 | WLC_MOD_MOD2, 17 | WLC_MOD_MOD3, 18 | WLC_MOD_LOGO, 19 | WLC_MOD_MOD5, 20 | WLC_MOD_LAST 21 | }; 22 | 23 | enum wlc_led { 24 | WLC_LED_NUM, 25 | WLC_LED_CAPS, 26 | WLC_LED_SCROLL, 27 | WLC_LED_LAST 28 | }; 29 | 30 | const char *WLC_MOD_NAMES[WLC_MOD_LAST]; 31 | const char *WLC_LED_NAMES[WLC_LED_LAST]; 32 | 33 | struct wlc_keymap { 34 | struct xkb_keymap *keymap; 35 | char *area; 36 | uint32_t format; 37 | uint32_t size; 38 | int32_t fd; 39 | xkb_mod_index_t mods[WLC_MOD_LAST]; 40 | xkb_led_index_t leds[WLC_LED_LAST]; 41 | }; 42 | 43 | WLC_NONULL uint32_t wlc_keymap_get_mod_mask(struct wlc_keymap *keymap, uint32_t in); 44 | WLC_NONULL uint32_t wlc_keymap_get_led_mask(struct wlc_keymap *keymap, struct xkb_state *xkb); 45 | void wlc_keymap_release(struct wlc_keymap *keymap); 46 | WLC_NONULL bool wlc_keymap(struct wlc_keymap *keymap, const struct xkb_rule_names *names, enum xkb_keymap_compile_flags flags); 47 | 48 | #endif /* _WLC_KEYMAP_H_ */ 49 | -------------------------------------------------------------------------------- /src/compositor/seat/pointer.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_POINTER_H_ 2 | #define _WLC_POINTER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "resources/resources.h" 8 | 9 | enum grab_action { 10 | WLC_GRAB_ACTION_NONE, 11 | WLC_GRAB_ACTION_MOVE, 12 | WLC_GRAB_ACTION_RESIZE 13 | }; 14 | 15 | enum wl_pointer_button_state; 16 | enum wl_pointer_axis; 17 | enum wl_touch_type; 18 | enum wlc_touch_type; 19 | 20 | struct wlc_render; 21 | struct wlc_surface; 22 | struct wlc_view; 23 | 24 | // We want to store internally for sub-pixel precision 25 | // Events to wlc goes as wlc_point though. 26 | // May need to change that. 27 | struct wlc_pointer_origin { 28 | double x, y; 29 | }; 30 | 31 | struct wlc_focused_surface { 32 | wlc_resource id; 33 | struct wlc_point offset; 34 | }; 35 | 36 | struct wlc_pointer { 37 | struct wlc_source resources; 38 | struct wlc_pointer_origin pos; 39 | struct wlc_point tip; 40 | 41 | wlc_resource surface; 42 | 43 | struct { 44 | struct chck_iter_pool resources; 45 | struct wlc_focused_surface surface; 46 | wlc_handle view; 47 | } focused; 48 | 49 | struct { 50 | struct wl_listener render; 51 | } listener; 52 | }; 53 | 54 | WLC_NONULLV(1) void wlc_pointer_focus(struct wlc_pointer *pointer, struct wlc_surface *surface, struct wlc_pointer_origin *out_pos); 55 | WLC_NONULL void wlc_pointer_button(struct wlc_pointer *pointer, uint32_t time, uint32_t button, enum wl_pointer_button_state state); 56 | WLC_NONULL void wlc_pointer_scroll(struct wlc_pointer *pointer, uint32_t time, uint8_t axis_bits, double amount[2]); 57 | WLC_NONULL void wlc_pointer_motion(struct wlc_pointer *pointer, uint32_t time, bool pass); 58 | WLC_NONULLV(1) void wlc_pointer_set_surface(struct wlc_pointer *pointer, struct wlc_surface *surface, const struct wlc_point *tip); 59 | void wlc_pointer_release(struct wlc_pointer *pointer); 60 | WLC_NONULL bool wlc_pointer(struct wlc_pointer *pointer); 61 | 62 | const struct wl_pointer_interface* wlc_pointer_implementation(void); 63 | 64 | #endif /* _WLC_POINTER_H_ */ 65 | -------------------------------------------------------------------------------- /src/compositor/seat/seat.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_SEAT_H_ 2 | #define _WLC_SEAT_H_ 3 | 4 | #include 5 | #include 6 | #include "data.h" 7 | #include "keymap.h" 8 | #include "keyboard.h" 9 | #include "pointer.h" 10 | #include "touch.h" 11 | 12 | struct wl_global; 13 | 14 | struct wlc_seat { 15 | struct wlc_data_device_manager manager; 16 | struct wlc_keymap keymap; 17 | struct wlc_keyboard keyboard; 18 | struct wlc_pointer pointer; 19 | struct wlc_touch touch; 20 | 21 | struct { 22 | struct wl_global *seat; 23 | } wl; 24 | 25 | struct { 26 | struct wl_listener input; 27 | struct wl_listener focus; 28 | struct wl_listener surface; 29 | } listener; 30 | }; 31 | 32 | void wlc_seat_release(struct wlc_seat *seat); 33 | bool wlc_seat(struct wlc_seat *seat); 34 | 35 | #endif /* _WLC_SEAT_H_ */ 36 | -------------------------------------------------------------------------------- /src/compositor/seat/touch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "touch.h" 5 | #include "internal.h" 6 | #include "macros.h" 7 | #include "compositor/compositor.h" 8 | #include "compositor/view.h" 9 | #include "compositor/output.h" 10 | 11 | static struct wlc_output* 12 | active_output(struct wlc_touch *touch) 13 | { 14 | struct wlc_seat *seat; 15 | struct wlc_compositor *compositor; 16 | except((seat = wl_container_of(touch, seat, touch)) && (compositor = wl_container_of(seat, compositor, seat))); 17 | return convert_from_wlc_handle(compositor->active.output, "output"); 18 | } 19 | 20 | static bool 21 | view_visible(struct wlc_view *view, uint32_t mask) 22 | { 23 | if (!view) 24 | return false; 25 | 26 | return (view->mask & mask); 27 | } 28 | 29 | wlc_handle 30 | view_under_touch(struct wlc_touch *touch, const struct wlc_point *pos) 31 | { 32 | assert(pos); 33 | struct wlc_output *output = active_output(touch); 34 | 35 | if (!output) { 36 | touch->focus = 0; 37 | return 0; 38 | } 39 | 40 | wlc_handle *h; 41 | chck_iter_pool_for_each_reverse(&output->views, h) { 42 | struct wlc_view *view; 43 | if (!(view = convert_from_wlc_handle(*h, "view")) || !view_visible(view, output->active.mask)) 44 | continue; 45 | 46 | struct wlc_geometry b; 47 | wlc_view_get_bounds(view, &b, NULL); 48 | if (pos->x >= b.origin.x && pos->x <= b.origin.x + (int32_t)b.size.w && 49 | pos->y >= b.origin.y && pos->y <= b.origin.y + (int32_t)b.size.h) { 50 | touch->focus = *h; 51 | return touch->focus; 52 | } 53 | } 54 | 55 | touch->focus = 0; 56 | return 0; 57 | } 58 | 59 | void 60 | wlc_touch_touch(struct wlc_touch *touch, uint32_t time, enum wlc_touch_type type, int32_t slot, const struct wlc_point *pos) 61 | { 62 | assert(touch); 63 | 64 | struct wlc_view *focused = convert_from_wlc_handle(touch->focus, "view"); 65 | if (focused == NULL) 66 | return; 67 | 68 | struct wl_client *client; 69 | struct wl_resource *surface; 70 | if (!(surface = wl_resource_from_wlc_resource(focused->surface, "surface")) || !(client = wl_resource_get_client(surface))) 71 | return; 72 | 73 | wlc_resource *r; 74 | chck_pool_for_each(&touch->resources.pool, r) { 75 | struct wl_resource *wr; 76 | if (!(wr = wl_resource_from_wlc_resource(*r, "touch")) || wl_resource_get_client(wr) != client) 77 | continue; 78 | 79 | switch (type) { 80 | case WLC_TOUCH_DOWN: 81 | { 82 | uint32_t serial = wl_display_next_serial(wlc_display()); 83 | wl_touch_send_down(wr, serial, time, surface, slot, wl_fixed_from_int(pos->x), wl_fixed_from_int(pos->y)); 84 | } 85 | break; 86 | 87 | case WLC_TOUCH_UP: 88 | { 89 | uint32_t serial = wl_display_next_serial(wlc_display()); 90 | wl_touch_send_up(wr, serial, time, slot); 91 | } 92 | break; 93 | 94 | case WLC_TOUCH_MOTION: 95 | wl_touch_send_motion(wr, time, slot, wl_fixed_from_int(pos->x), wl_fixed_from_int(pos->y)); 96 | break; 97 | 98 | case WLC_TOUCH_FRAME: 99 | wl_touch_send_frame(wr); 100 | break; 101 | 102 | case WLC_TOUCH_CANCEL: 103 | wl_touch_send_cancel(wr); 104 | break; 105 | } 106 | } 107 | } 108 | 109 | void 110 | wlc_touch_release(struct wlc_touch *touch) 111 | { 112 | if (!touch) 113 | return; 114 | 115 | wlc_source_release(&touch->resources); 116 | memset(touch, 0, sizeof(struct wlc_touch)); 117 | } 118 | 119 | bool 120 | wlc_touch(struct wlc_touch *touch) 121 | { 122 | assert(touch); 123 | memset(touch, 0, sizeof(struct wlc_touch)); 124 | return wlc_source(&touch->resources, "touch", NULL, NULL, 32, sizeof(struct wlc_resource)); 125 | } 126 | -------------------------------------------------------------------------------- /src/compositor/seat/touch.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_TOUCH_H_ 2 | #define _WLC_TOUCH_H_ 3 | 4 | #include 5 | #include "resources/resources.h" 6 | 7 | enum wlc_touch_type; 8 | struct wlc_point; 9 | 10 | struct wlc_touch { 11 | struct wlc_source resources; 12 | wlc_handle focus; 13 | }; 14 | 15 | WLC_NONULL void wlc_touch_touch(struct wlc_touch *touch, uint32_t time, enum wlc_touch_type type, int32_t slot, const struct wlc_point *pos); 16 | void wlc_touch_release(struct wlc_touch *touch); 17 | WLC_NONULL bool wlc_touch(struct wlc_touch *touch); 18 | wlc_handle view_under_touch(struct wlc_touch *touch, const struct wlc_point *pos); 19 | 20 | #endif /* _WLC_TOUCH_H_ */ 21 | -------------------------------------------------------------------------------- /src/compositor/shell/custom-shell.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "visibility.h" 5 | #include "internal.h" 6 | #include "custom-shell.h" 7 | #include "compositor/compositor.h" 8 | #include "compositor/view.h" 9 | #include "resources/types/surface.h" 10 | 11 | // XXX: We do not currently expose compositor to public API. 12 | // So we use static variable here for some public api functions. 13 | // 14 | // Never use this variable anywhere else. 15 | static struct wlc_custom_shell *_g_custom_shell; 16 | 17 | WLC_API wlc_handle 18 | wlc_view_from_surface(wlc_resource surface, struct wl_client *client, const struct wl_interface *interface, const void *implementation, uint32_t version, uint32_t id, void *userdata) 19 | { 20 | assert(_g_custom_shell); 21 | 22 | struct wlc_surface *s; 23 | if (!(s = convert_from_wlc_resource(surface, "surface"))) 24 | return 0; 25 | 26 | wlc_resource r = 0; 27 | if (client || interface || implementation) { 28 | assert(client && interface && implementation); 29 | 30 | if (!(r = wlc_resource_create(&_g_custom_shell->surfaces, client, interface, version, version, id))) 31 | return 0; 32 | 33 | wlc_resource_implement(r, implementation, userdata); 34 | } 35 | 36 | struct wlc_surface_event ev = { .attach = { .type = WLC_CUSTOM_SURFACE, .role = r }, .surface = s, .type = WLC_SURFACE_EVENT_REQUEST_VIEW_ATTACH }; 37 | wl_signal_emit(&wlc_system_signals()->surface, &ev); 38 | return s->view; 39 | } 40 | 41 | void 42 | wlc_custom_shell_release(struct wlc_custom_shell *custom_shell) 43 | { 44 | if (!custom_shell) 45 | return; 46 | 47 | wlc_source_release(&custom_shell->surfaces); 48 | *custom_shell = (struct wlc_custom_shell){0}; 49 | } 50 | 51 | bool 52 | wlc_custom_shell(struct wlc_custom_shell *custom_shell) 53 | { 54 | assert(custom_shell); 55 | *custom_shell = (struct wlc_custom_shell){0}; 56 | 57 | if (!wlc_source(&custom_shell->surfaces, "custom-surface", NULL, NULL, 32, sizeof(struct wlc_resource))) 58 | goto fail; 59 | 60 | _g_custom_shell = custom_shell; 61 | return custom_shell; 62 | 63 | fail: 64 | wlc_custom_shell_release(custom_shell); 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /src/compositor/shell/custom-shell.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_CUSTOM_SHELL_H_ 2 | #define _WLC_CUSTOM_SHELL_H_ 3 | 4 | #include "resources/resources.h" 5 | 6 | struct wlc_custom_shell { 7 | struct wlc_source surfaces; 8 | }; 9 | 10 | void wlc_custom_shell_release(struct wlc_custom_shell *custom_shell); 11 | WLC_NONULL bool wlc_custom_shell(struct wlc_custom_shell *custom_shell); 12 | 13 | #endif /* _WLC_CUSTOM_SHELL_H_ */ 14 | -------------------------------------------------------------------------------- /src/compositor/shell/shell.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "internal.h" 6 | #include "macros.h" 7 | #include "shell.h" 8 | #include "resources/resources.h" 9 | #include "resources/types/shell-surface.h" 10 | 11 | static void 12 | wl_cb_shell_get_shell_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource) 13 | { 14 | struct wlc_shell *shell; 15 | struct wlc_surface *surface; 16 | if (!(shell = wl_resource_get_user_data(resource)) || !(surface = convert_from_wl_resource(surface_resource, "surface"))) 17 | return; 18 | 19 | wlc_resource r; 20 | if (!(r = wlc_resource_create(&shell->surfaces, client, &wl_shell_surface_interface, wl_resource_get_version(resource), 1, id))) 21 | return; 22 | 23 | wlc_resource_implement(r, wlc_shell_surface_implementation(), NULL); 24 | 25 | struct wlc_surface_event ev = { .attach = { .type = WLC_SHELL_SURFACE, .role = r }, .surface = surface, .type = WLC_SURFACE_EVENT_REQUEST_VIEW_ATTACH }; 26 | wl_signal_emit(&wlc_system_signals()->surface, &ev); 27 | } 28 | 29 | static const struct wl_shell_interface wl_shell_implementation = { 30 | .get_shell_surface = wl_cb_shell_get_shell_surface 31 | }; 32 | 33 | static void 34 | wl_shell_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) 35 | { 36 | struct wl_resource *resource; 37 | if (!(resource = wl_resource_create_checked(client, &wl_shell_interface, version, 1, id))) 38 | return; 39 | 40 | wl_resource_set_implementation(resource, &wl_shell_implementation, data, NULL); 41 | } 42 | 43 | void 44 | wlc_shell_release(struct wlc_shell *shell) 45 | { 46 | if (!shell) 47 | return; 48 | 49 | if (shell->wl.shell) 50 | wl_global_destroy(shell->wl.shell); 51 | 52 | wlc_source_release(&shell->surfaces); 53 | memset(shell, 0, sizeof(struct wlc_shell)); 54 | } 55 | 56 | bool 57 | wlc_shell(struct wlc_shell *shell) 58 | { 59 | assert(shell); 60 | memset(shell, 0, sizeof(struct wlc_shell)); 61 | 62 | if (!(shell->wl.shell = wl_global_create(wlc_display(), &wl_shell_interface, 1, shell, wl_shell_bind))) 63 | goto shell_interface_fail; 64 | 65 | if (!wlc_source(&shell->surfaces, "shell-surface", NULL, NULL, 32, sizeof(struct wlc_resource))) 66 | goto fail; 67 | 68 | return true; 69 | 70 | shell_interface_fail: 71 | wlc_log(WLC_LOG_WARN, "Failed to bind shell interface"); 72 | fail: 73 | wlc_shell_release(shell); 74 | return false; 75 | } 76 | -------------------------------------------------------------------------------- /src/compositor/shell/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_SHELL_H_ 2 | #define _WLC_SHELL_H_ 3 | 4 | #include "resources/resources.h" 5 | 6 | struct wlc_shell { 7 | struct wlc_source surfaces; 8 | 9 | struct { 10 | struct wl_global *shell; 11 | } wl; 12 | }; 13 | 14 | void wlc_shell_release(struct wlc_shell *shell); 15 | WLC_NONULL bool wlc_shell(struct wlc_shell *shell); 16 | 17 | #endif /* _WLC_SHELL_H_ */ 18 | -------------------------------------------------------------------------------- /src/compositor/shell/xdg-shell.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XDG_SHELL_H_ 2 | #define _WLC_XDG_SHELL_H_ 3 | 4 | #include "resources/resources.h" 5 | 6 | struct wlc_xdg_shell { 7 | struct wlc_source surfaces, toplevels, popups, positioners; 8 | 9 | struct { 10 | struct wl_global *xdg_shell; 11 | } wl; 12 | }; 13 | 14 | void wlc_xdg_shell_release(struct wlc_xdg_shell *xdg_shell); 15 | WLC_NONULL bool wlc_xdg_shell(struct wlc_xdg_shell *xdg_shell); 16 | 17 | #endif /* _WLC_XDG_SHELL_H_ */ 18 | -------------------------------------------------------------------------------- /src/compositor/view.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_VIEW_H_ 2 | #define _WLC_VIEW_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "xwayland/xwm.h" 11 | #include "resources/resources.h" 12 | 13 | enum output_link; 14 | struct wlc_surface; 15 | struct wlc_x11_window; 16 | 17 | enum wlc_view_ack { 18 | ACK_NONE, 19 | ACK_PENDING, 20 | ACK_NEXT_COMMIT 21 | }; 22 | 23 | struct wlc_view_state { 24 | struct wlc_geometry geometry; 25 | uint32_t edges, state; 26 | }; 27 | 28 | struct wlc_view_surface_state { 29 | struct wlc_geometry visible; 30 | }; 31 | 32 | struct wlc_view { 33 | struct wlc_x11_window x11; 34 | struct wlc_view_state pending; 35 | struct wlc_view_state commit; 36 | struct wlc_view_surface_state surface_pending; 37 | struct wlc_view_surface_state surface_commit; 38 | struct chck_iter_pool wl_state; 39 | 40 | wlc_handle parent; 41 | wlc_resource surface; 42 | wlc_resource shell_surface; 43 | wlc_resource xdg_surface; 44 | wlc_resource xdg_toplevel; 45 | wlc_resource xdg_popup; 46 | wlc_resource custom_surface; 47 | 48 | struct { 49 | struct chck_string app_id; 50 | struct chck_string title; 51 | struct chck_string _instance; 52 | struct chck_string _class; 53 | pid_t pid; 54 | enum wl_shell_surface_fullscreen_method fullscreen_mode; 55 | bool minimized; 56 | } data; 57 | 58 | uint32_t type; 59 | uint32_t mask; 60 | 61 | struct { 62 | bool created; 63 | } state; 64 | }; 65 | 66 | static inline bool 67 | is_x11_view(struct wlc_view *view) 68 | { 69 | return wlc_x11_is_valid_window(&view->x11); 70 | } 71 | 72 | WLC_NONULL void wlc_view_update(struct wlc_view *view); 73 | WLC_NONULL void wlc_view_map(struct wlc_view *view); 74 | WLC_NONULL void wlc_view_unmap(struct wlc_view *view); 75 | WLC_NONULL void wlc_view_commit_state(struct wlc_view *view, struct wlc_view_state *pending, struct wlc_view_state *out); 76 | WLC_NONULL void wlc_view_ack_surface_attach(struct wlc_view *view, struct wlc_surface *surface); 77 | WLC_NONULLV(1,2) void wlc_view_get_bounds(struct wlc_view *view, struct wlc_geometry *out_bounds, struct wlc_geometry *out_visible); 78 | WLC_NONULL bool wlc_view_get_opaque(struct wlc_view *view, struct wlc_geometry *out_opaque); 79 | WLC_NONULL void wlc_view_get_input(struct wlc_view *view, struct wlc_geometry *out_input); 80 | WLC_NONULL bool wlc_view_request_geometry(struct wlc_view *view, const struct wlc_geometry *r); 81 | bool wlc_view_request_state(struct wlc_view *view, enum wlc_view_state_bit state, bool toggle); 82 | void wlc_view_set_surface(struct wlc_view *view, struct wlc_surface *surface); 83 | struct wl_client* wlc_view_get_client_ptr(struct wlc_view *view); 84 | void wlc_view_release(struct wlc_view *view); 85 | WLC_NONULL bool wlc_view(struct wlc_view *view); 86 | 87 | void wlc_view_send_to_other(struct wlc_view *view, enum output_link link, struct wlc_view *other); 88 | void wlc_view_send_to(struct wlc_view *view, enum output_link link); 89 | void wlc_view_focus_ptr(struct wlc_view *view); 90 | void wlc_view_close_ptr(struct wlc_view *view); 91 | struct wlc_output* wlc_view_get_output_ptr(struct wlc_view *view); 92 | void wlc_view_set_output_ptr(struct wlc_view *view, struct wlc_output *output); 93 | void wlc_view_send_to_back_ptr(struct wlc_view *view); 94 | void wlc_view_send_below_ptr(struct wlc_view *view, struct wlc_view *other); 95 | void wlc_view_bring_above_ptr(struct wlc_view *view, struct wlc_view *other); 96 | void wlc_view_bring_to_front_ptr(struct wlc_view *view); 97 | void wlc_view_set_mask_ptr(struct wlc_view *view, uint32_t mask); 98 | WLC_NONULLV(3) void wlc_view_set_geometry_ptr(struct wlc_view *view, uint32_t edges, const struct wlc_geometry *geometry); 99 | void wlc_view_set_type_ptr(struct wlc_view *view, enum wlc_view_type_bit type, bool toggle); 100 | void wlc_view_set_state_ptr(struct wlc_view *view, enum wlc_view_state_bit state, bool toggle); 101 | void wlc_view_set_parent_ptr(struct wlc_view *view, struct wlc_view *parent); 102 | void wlc_view_set_minimized_ptr(struct wlc_view *view, bool minimized); 103 | void wlc_view_set_title_ptr(struct wlc_view *view, const char *title, size_t length); 104 | void wlc_view_set_instance_ptr(struct wlc_view *view, const char *instance_, size_t length); 105 | void wlc_view_set_class_ptr(struct wlc_view *view, const char *class_, size_t length); 106 | void wlc_view_set_app_id_ptr(struct wlc_view *view, const char *app_id); 107 | void wlc_view_set_pid_ptr(struct wlc_view *view, pid_t pid); 108 | bool wlc_view_is_minimized_ptr(struct wlc_view *view); 109 | 110 | #endif /* _WLC_VIEW_H_ */ 111 | -------------------------------------------------------------------------------- /src/extended/wlc-render.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "visibility.h" 3 | #include "resources/types/surface.h" 4 | #include "compositor/output.h" 5 | #include "compositor/view.h" 6 | #include "platform/render/render.h" 7 | #include 8 | 9 | WLC_API void 10 | wlc_surface_render(wlc_resource surface, const struct wlc_geometry *geometry) 11 | { 12 | assert(geometry); 13 | 14 | struct wlc_output *o; 15 | if (!(o = wlc_get_rendering_output())) 16 | return; 17 | 18 | wlc_output_render_surface(o, convert_from_wlc_resource(surface, "surface"), geometry, &o->callbacks); 19 | } 20 | 21 | WLC_API void 22 | wlc_pixels_write(enum wlc_pixel_format format, const struct wlc_geometry *geometry, const void *data) 23 | { 24 | assert(geometry && data); 25 | 26 | struct wlc_output *o; 27 | if (!(o = wlc_get_rendering_output())) 28 | return; 29 | 30 | wlc_render_write_pixels(&o->render, &o->context, format, geometry, data); 31 | } 32 | 33 | WLC_API void 34 | wlc_pixels_read(enum wlc_pixel_format format, const struct wlc_geometry *geometry, struct wlc_geometry *out_geometry, void *out_data) 35 | { 36 | assert(geometry && out_geometry && out_data); 37 | 38 | struct wlc_output *o; 39 | if (!(o = wlc_get_rendering_output())) 40 | return; 41 | 42 | wlc_render_read_pixels(&o->render, &o->context, format, geometry, out_geometry, out_data); 43 | } 44 | 45 | WLC_API void 46 | wlc_output_schedule_render(wlc_handle output) 47 | { 48 | struct wlc_output *o; 49 | if (!(o = convert_from_wlc_handle(output, "output"))) 50 | return; 51 | 52 | wlc_output_schedule_repaint(o); 53 | } 54 | 55 | WLC_API enum wlc_renderer 56 | wlc_output_get_renderer(wlc_handle output) 57 | { 58 | struct wlc_output *o; 59 | if (!(o = convert_from_wlc_handle(output, "output"))) 60 | return WLC_NO_RENDERER; 61 | 62 | return o->render.api.renderer_type; 63 | } 64 | 65 | WLC_API bool 66 | wlc_surface_get_textures(wlc_resource surface, uint32_t out_textures[], enum wlc_surface_format *out_format) 67 | { 68 | struct wlc_surface *surf; 69 | if (!(surf = convert_from_wlc_resource(surface, "surface"))) 70 | return false; 71 | 72 | memcpy(out_textures, surf->textures, 3 * sizeof(surf->textures[0])); 73 | *out_format = surf->format; 74 | return true; 75 | } 76 | 77 | static void 78 | surface_flush_frame_callbacks_recursive(struct wlc_surface *surface, struct wlc_output *output) 79 | { 80 | wlc_resource *r; 81 | chck_iter_pool_for_each(&surface->commit.frame_cbs, r) 82 | chck_iter_pool_push_back(&output->callbacks, r); 83 | chck_iter_pool_flush(&surface->commit.frame_cbs); 84 | 85 | wlc_resource *sub; 86 | struct wlc_surface *subsurface; 87 | chck_iter_pool_for_each(&surface->subsurface_list, sub) 88 | if ((subsurface = convert_from_wlc_resource(*sub, "surface"))) 89 | surface_flush_frame_callbacks_recursive(subsurface, output); 90 | } 91 | 92 | WLC_API void 93 | wlc_surface_flush_frame_callbacks(wlc_resource surface) 94 | { 95 | struct wlc_surface *surf; 96 | struct wlc_output *output; 97 | if (!(surf = convert_from_wlc_resource(surface, "surface")) || 98 | !(output = convert_from_wlc_handle(surf->output, "output"))) { 99 | return; 100 | } 101 | 102 | surface_flush_frame_callbacks_recursive(surf, output); 103 | 104 | struct wlc_view *v; 105 | if ((v = convert_from_wlc_handle(surf->parent_view, "view"))) 106 | wlc_view_commit_state(v, &v->pending, &v->commit); 107 | } 108 | -------------------------------------------------------------------------------- /src/extended/wlc-wayland.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "visibility.h" 3 | #include "resources/types/surface.h" 4 | #include "compositor/output.h" 5 | #include "compositor/view.h" 6 | #include 7 | 8 | WLC_API WLC_PURE struct wl_display* 9 | wlc_get_wl_display(void) 10 | { 11 | return wlc_display(); 12 | } 13 | 14 | WLC_API wlc_handle 15 | wlc_handle_from_wl_surface_resource(struct wl_resource *resource) 16 | { 17 | assert(resource); 18 | const struct wlc_surface *surface = convert_from_wl_resource(resource, "surface"); 19 | return (surface ? surface->view : 0); 20 | } 21 | 22 | WLC_API wlc_handle 23 | wlc_handle_from_wl_output_resource(struct wl_resource *resource) 24 | { 25 | assert(resource); 26 | return (wlc_handle)wl_resource_get_user_data(resource); 27 | } 28 | 29 | WLC_API wlc_resource 30 | wlc_resource_from_wl_surface_resource(struct wl_resource *resource) 31 | { 32 | assert(resource); 33 | return wlc_resource_from_wl_resource(resource); 34 | } 35 | 36 | WLC_API const struct wlc_size* 37 | wlc_surface_get_size(wlc_resource surface) 38 | { 39 | struct wlc_surface *s = convert_from_wlc_resource(surface, "surface"); 40 | return (s ? &s->size : NULL); 41 | } 42 | 43 | WLC_API struct wl_resource* 44 | wlc_surface_get_wl_resource(wlc_resource surface) 45 | { 46 | return wl_resource_from_wlc_resource(surface, "surface"); 47 | } 48 | 49 | WLC_API struct wl_resource* 50 | wlc_view_get_role(wlc_handle view) 51 | { 52 | const struct wlc_view *v = convert_from_wlc_handle(view, "view"); 53 | return (v ? wl_resource_from_wlc_resource(v->custom_surface, "custom-surface") : 0); 54 | } 55 | 56 | WLC_API wlc_resource 57 | wlc_view_get_surface(wlc_handle view) 58 | { 59 | const struct wlc_view *v = convert_from_wlc_handle(view, "view"); 60 | return (v ? v->surface : 0); 61 | } 62 | 63 | WLC_API const wlc_resource* 64 | wlc_surface_get_subsurfaces(wlc_resource parent, size_t *out_size) 65 | { 66 | struct wlc_surface *surf = convert_from_wlc_resource(parent, "surface"); 67 | return (surf ? chck_iter_pool_to_c_array(&surf->subsurface_list, out_size) : NULL); 68 | } 69 | 70 | WLC_API void 71 | wlc_get_subsurface_geometry(wlc_resource surface, struct wlc_geometry *out_geometry) 72 | { 73 | assert(out_geometry); 74 | *out_geometry = (struct wlc_geometry) {0}; 75 | 76 | struct wlc_surface *surf; 77 | if (!(surf = convert_from_wlc_resource(surface, "surface"))) 78 | return; 79 | 80 | out_geometry->origin = surf->commit.subsurface_position; 81 | out_geometry->size = surf->size; 82 | } 83 | 84 | WLC_API struct wl_client* 85 | wlc_view_get_wl_client(wlc_handle view) 86 | { 87 | return wlc_view_get_client_ptr(convert_from_wlc_handle(view, "view")); 88 | } 89 | -------------------------------------------------------------------------------- /src/macros.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_MACROS_H_ 2 | #define _WLC_MACROS_H_ 3 | 4 | /** fatal stub implementation of wayland interface method. */ 5 | #define STUB(x) { \ 6 | wlc_log(WLC_LOG_WARN, "%s @ line %d is not implemented", __PRETTY_FUNCTION__, __LINE__); \ 7 | wl_resource_post_error(x, WL_DISPLAY_ERROR_INVALID_METHOD, "%s @ line %d is not implemented", __PRETTY_FUNCTION__, __LINE__); \ 8 | } 9 | 10 | /** non-fatal stub implementation of wayland interface method. */ 11 | #define STUBL(x) { \ 12 | (void)x; \ 13 | wlc_log(WLC_LOG_WARN, "%s @ line %d is not implemented", __PRETTY_FUNCTION__, __LINE__); \ 14 | } 15 | 16 | /** length macro for statically initialized data. */ 17 | #define LENGTH(x) (sizeof(x) / sizeof(x)[0]) 18 | 19 | #ifndef static_assert 20 | # define static_assert_x(x, y) typedef char static_assertion_##y[(x) ? 1 : -1] 21 | #else 22 | // C11, but we default to C99 for now in cmake 23 | # define static_assert_x(x, y) static_assert(x, #y) 24 | #endif 25 | 26 | #define except(x) if (!(x)) { wlc_log(WLC_LOG_ERROR, "assertion failed: %s", #x); abort(); } 27 | 28 | #endif /* _WLC_MACROS_H_ */ 29 | -------------------------------------------------------------------------------- /src/platform/backend/backend.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "internal.h" 5 | #include "backend.h" 6 | #include "drm.h" 7 | 8 | #ifdef ENABLE_WAYLAND_BACKEND 9 | # include "wayland.h" 10 | #endif 11 | 12 | #ifdef ENABLE_X11_BACKEND 13 | # include "x11.h" 14 | #endif 15 | 16 | bool 17 | wlc_backend_surface(struct wlc_backend_surface *surface, void (*destructor)(struct wlc_backend_surface*), size_t internal_size) 18 | { 19 | assert(surface); 20 | memset(surface, 0, sizeof(struct wlc_backend_surface)); 21 | 22 | if (internal_size > 0 && !(surface->internal = calloc(1, internal_size))) 23 | return false; 24 | 25 | surface->api.terminate = destructor; 26 | surface->internal_size = internal_size; 27 | return true; 28 | } 29 | 30 | void 31 | wlc_backend_surface_release(struct wlc_backend_surface *surface) 32 | { 33 | if (!surface) 34 | return; 35 | 36 | if (surface->api.terminate) 37 | surface->api.terminate(surface); 38 | 39 | if (surface->internal_size > 0 && surface->internal) 40 | free(surface->internal); 41 | 42 | memset(surface, 0, sizeof(struct wlc_backend_surface)); 43 | } 44 | 45 | uint32_t 46 | wlc_backend_update_outputs(struct wlc_backend *backend, struct chck_pool *outputs) 47 | { 48 | assert(backend); 49 | 50 | if (!backend->api.update_outputs) 51 | return 0; 52 | 53 | return backend->api.update_outputs(outputs); 54 | } 55 | 56 | void 57 | wlc_backend_release(struct wlc_backend *backend) 58 | { 59 | if (!backend) 60 | return; 61 | 62 | if (backend->api.terminate) 63 | backend->api.terminate(); 64 | 65 | memset(backend, 0, sizeof(struct wlc_backend)); 66 | } 67 | 68 | bool 69 | wlc_backend(struct wlc_backend *backend) 70 | { 71 | assert(backend); 72 | memset(backend, 0, sizeof(struct wlc_backend)); 73 | 74 | bool (*init[])(struct wlc_backend*) = { 75 | #ifdef ENABLE_WAYLAND_BACKEND 76 | wlc_wayland, 77 | #endif 78 | #ifdef ENABLE_X11_BACKEND 79 | wlc_x11, 80 | #endif 81 | wlc_drm, 82 | NULL 83 | }; 84 | 85 | enum wlc_backend_type types[] = { 86 | #ifdef ENABLE_WAYLAND_BACKEND 87 | WLC_BACKEND_WAYLAND, 88 | #endif 89 | #ifdef ENABLE_X11_BACKEND 90 | WLC_BACKEND_X11, 91 | #endif 92 | WLC_BACKEND_DRM, 93 | }; 94 | 95 | for (uint32_t i = 0; init[i]; ++i) { 96 | if (init[i](backend)) { 97 | backend->type = types[i]; 98 | return true; 99 | } 100 | } 101 | 102 | wlc_log(WLC_LOG_WARN, "Could not initialize any backend"); 103 | return false; 104 | } 105 | -------------------------------------------------------------------------------- /src/platform/backend/backend.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_BACKEND_H_ 2 | #define _WLC_BACKEND_H_ 3 | 4 | #include 5 | #include 6 | #include "EGL/egl.h" 7 | 8 | struct chck_pool; 9 | 10 | struct wlc_backend_surface { 11 | void *internal; 12 | size_t internal_size; 13 | EGLNativeDisplayType display; 14 | EGLNativeWindowType window; 15 | EGLint display_type; 16 | int drm_fd; 17 | bool use_egldevice; 18 | 19 | struct { 20 | WLC_NONULL void (*terminate)(struct wlc_backend_surface *surface); 21 | WLC_NONULL void (*sleep)(struct wlc_backend_surface *surface, bool sleep); 22 | WLC_NONULL bool (*page_flip)(struct wlc_backend_surface *surface); 23 | WLC_NONULL void (*set_gamma)(struct wlc_backend_surface *bsurface, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); 24 | WLC_NONULL uint16_t (*get_gamma_size)(struct wlc_backend_surface *bsurface); 25 | } api; 26 | }; 27 | 28 | struct wlc_backend { 29 | enum wlc_backend_type type; 30 | 31 | struct { 32 | WLC_NONULL uint32_t (*update_outputs)(struct chck_pool *outputs); 33 | void (*terminate)(void); 34 | } api; 35 | }; 36 | 37 | WLC_NONULL bool wlc_backend_surface(struct wlc_backend_surface *surface, void (*destructor)(struct wlc_backend_surface*), size_t internal_size); 38 | void wlc_backend_surface_release(struct wlc_backend_surface *surface); 39 | 40 | WLC_NONULL uint32_t wlc_backend_update_outputs(struct wlc_backend *backend, struct chck_pool *outputs); 41 | void wlc_backend_release(struct wlc_backend *backend); 42 | WLC_NONULL bool wlc_backend(struct wlc_backend *backend); 43 | 44 | #endif /* _WLC_BACKEND_H_ */ 45 | -------------------------------------------------------------------------------- /src/platform/backend/drm.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_DRM_H_ 2 | #define _WLC_DRM_H_ 3 | 4 | #include 5 | 6 | struct wlc_backend; 7 | 8 | bool wlc_drm(struct wlc_backend *backend); 9 | 10 | #endif /* _WLC_DRM_H_ */ 11 | -------------------------------------------------------------------------------- /src/platform/backend/wayland.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_WAYLAND_H_ 2 | #define _WLC_WAYLAND_H_ 3 | 4 | #include 5 | 6 | struct wlc_backend; 7 | 8 | bool wlc_wayland(struct wlc_backend *backend); 9 | 10 | #endif /* _WLC_WAYLAND_H_ */ 11 | -------------------------------------------------------------------------------- /src/platform/backend/x11.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_X11_H_ 2 | #define _WLC_X11_H_ 3 | 4 | #include 5 | 6 | struct wlc_backend; 7 | 8 | bool wlc_x11(struct wlc_backend *backend); 9 | 10 | #endif /* _WLC_X11_H_ */ 11 | -------------------------------------------------------------------------------- /src/platform/context/context.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "internal.h" 5 | #include "context.h" 6 | #include "egl.h" 7 | 8 | void* 9 | wlc_context_get_proc_address(struct wlc_context *context, const char *procname) 10 | { 11 | assert(context && procname); 12 | 13 | if (!context->api.get_proc_address) 14 | return NULL; 15 | 16 | return context->api.get_proc_address(context->context, procname); 17 | } 18 | 19 | EGLBoolean 20 | wlc_context_query_buffer(struct wlc_context *context, struct wl_resource *buffer, EGLint attribute, EGLint *value) 21 | { 22 | assert(context && buffer); 23 | 24 | if (!context->api.query_buffer) 25 | return EGL_FALSE; 26 | 27 | return context->api.query_buffer(context->context, buffer, attribute, value); 28 | } 29 | 30 | EGLImageKHR 31 | wlc_context_create_image(struct wlc_context *context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) 32 | { 33 | assert(context && buffer); 34 | 35 | if (!context->api.create_image) 36 | return 0; 37 | 38 | return context->api.create_image(context->context, target, buffer, attrib_list); 39 | } 40 | 41 | EGLBoolean 42 | wlc_context_destroy_image(struct wlc_context *context, EGLImageKHR image) 43 | { 44 | assert(context && image); 45 | 46 | if (!context->api.destroy_image) 47 | return EGL_FALSE; 48 | 49 | return context->api.destroy_image(context->context, image); 50 | } 51 | 52 | bool 53 | wlc_context_bind(struct wlc_context *context) 54 | { 55 | assert(context); 56 | 57 | if (!context->api.bind || !context->api.bind(context->context)) 58 | goto fail; 59 | 60 | return true; 61 | 62 | fail: 63 | wlc_log(WLC_LOG_ERROR, "Failed to bind context"); 64 | return false; 65 | } 66 | 67 | bool 68 | wlc_context_bind_to_wl_display(struct wlc_context *context, struct wl_display *display) 69 | { 70 | assert(context); 71 | 72 | if (!context->api.bind_to_wl_display) 73 | return false; 74 | 75 | return context->api.bind_to_wl_display(context->context, display); 76 | } 77 | 78 | void 79 | wlc_context_swap(struct wlc_context *context, struct wlc_backend_surface *bsurface) 80 | { 81 | assert(context); 82 | 83 | if (context->api.swap) 84 | context->api.swap(context->context, bsurface); 85 | } 86 | 87 | void 88 | wlc_context_release(struct wlc_context *context) 89 | { 90 | if (!context) 91 | return; 92 | 93 | if (context->api.terminate) 94 | context->api.terminate(context->context); 95 | 96 | memset(context, 0, sizeof(struct wlc_context)); 97 | } 98 | 99 | bool 100 | wlc_context(struct wlc_context *context, struct wlc_backend_surface *surface) 101 | { 102 | assert(surface); 103 | memset(context, 0, sizeof(struct wlc_context)); 104 | 105 | void* (*constructor[])(struct wlc_backend_surface*, struct wlc_context_api*) = { 106 | wlc_egl, 107 | NULL 108 | }; 109 | 110 | for (uint32_t i = 0; constructor[i]; ++i) { 111 | if ((context->context = constructor[i](surface, &context->api))) 112 | return true; 113 | } 114 | 115 | wlc_log(WLC_LOG_WARN, "Could not initialize any context"); 116 | return false; 117 | } 118 | -------------------------------------------------------------------------------- /src/platform/context/context.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_CONTEXT_H_ 2 | #define _WLC_CONTEXT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct wl_display; 9 | struct wlc_backend_surface; 10 | struct ctx; 11 | 12 | struct wlc_context_api { 13 | WLC_NONULL void (*terminate)(struct ctx *context); 14 | WLC_NONULL bool (*bind)(struct ctx *context); 15 | WLC_NONULL bool (*bind_to_wl_display)(struct ctx *context, struct wl_display *display); 16 | WLC_NONULL void (*swap)(struct ctx *context, struct wlc_backend_surface *bsurface); 17 | WLC_NONULL void* (*get_proc_address)(struct ctx *context, const char *procname); 18 | 19 | // EGL 20 | WLC_NONULL EGLBoolean (*query_buffer)(struct ctx *context, struct wl_resource *buffer, EGLint attribute, EGLint *value); 21 | WLC_NONULL EGLImageKHR (*create_image)(struct ctx *context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); 22 | WLC_NONULL EGLBoolean (*destroy_image)(struct ctx *context, EGLImageKHR image); 23 | }; 24 | 25 | struct wlc_context { 26 | void *context; // internal surface context (EGL, etc) 27 | struct wlc_context_api api; 28 | }; 29 | 30 | WLC_NONULL void* wlc_context_get_proc_address(struct wlc_context *context, const char *procname); 31 | WLC_NONULL EGLBoolean wlc_context_query_buffer(struct wlc_context *context, struct wl_resource *buffer, EGLint attribute, EGLint *value); 32 | WLC_NONULL EGLImageKHR wlc_context_create_image(struct wlc_context *context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); 33 | WLC_NONULL EGLBoolean wlc_context_destroy_image(struct wlc_context *context, EGLImageKHR image); 34 | WLC_NONULL bool wlc_context_bind(struct wlc_context *context); 35 | WLC_NONULL bool wlc_context_bind_to_wl_display(struct wlc_context *context, struct wl_display *display); 36 | WLC_NONULL void wlc_context_swap(struct wlc_context *context, struct wlc_backend_surface *bsurface); 37 | void wlc_context_release(struct wlc_context *context); 38 | WLC_NONULL bool wlc_context(struct wlc_context *context, struct wlc_backend_surface *bsurface); 39 | 40 | #endif /* _WLC_CONTEXT_H_ */ 41 | -------------------------------------------------------------------------------- /src/platform/context/egl.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_EGL_H_ 2 | #define _WLC_EGL_H_ 3 | 4 | #include 5 | #include 6 | 7 | struct wlc_context_api; 8 | struct wlc_backend_surface; 9 | 10 | EGLDeviceEXT get_egl_device(void); 11 | 12 | void* wlc_egl(struct wlc_backend_surface *bsurface, struct wlc_context_api *api); 13 | 14 | #endif /* _WLC_EGL_H_ */ 15 | -------------------------------------------------------------------------------- /src/platform/render/gles2.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_GLES2_H_ 2 | #define _WLC_GLES2_H_ 3 | 4 | struct wlc_render_api; 5 | 6 | void* wlc_gles2(struct wlc_render_api *api); 7 | 8 | #endif /* _WLC_GLES2_H_ */ 9 | -------------------------------------------------------------------------------- /src/platform/render/render.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "internal.h" 4 | #include "platform/context/context.h" 5 | #include "render.h" 6 | #include "gles2.h" 7 | 8 | void 9 | wlc_render_resolution(struct wlc_render *render, struct wlc_context *bound, const struct wlc_size *mode, const struct wlc_size *resolution, uint32_t scale) 10 | { 11 | assert(render && bound && mode && resolution); 12 | 13 | if (!render->api.resolution || !wlc_context_bind(bound)) 14 | return; 15 | 16 | render->api.resolution(render->render, mode, resolution, scale); 17 | } 18 | 19 | void 20 | wlc_render_surface_destroy(struct wlc_render *render, struct wlc_context *bound, struct wlc_surface *surface) 21 | { 22 | assert(render && bound && surface); 23 | 24 | if (!render->api.surface_destroy || !wlc_context_bind(bound)) 25 | return; 26 | 27 | render->api.surface_destroy(render->render, bound, surface); 28 | } 29 | 30 | bool 31 | wlc_render_surface_attach(struct wlc_render *render, struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer) 32 | { 33 | assert(render && bound && surface); 34 | 35 | if (!render->api.surface_attach || !wlc_context_bind(bound)) 36 | return false; 37 | 38 | return render->api.surface_attach(render->render, bound, surface, buffer); 39 | } 40 | 41 | void 42 | wlc_render_view_paint(struct wlc_render *render, struct wlc_context *bound, struct wlc_view *view) 43 | { 44 | assert(render && view); 45 | 46 | if (!render->api.view_paint || !wlc_context_bind(bound)) 47 | return; 48 | 49 | render->api.view_paint(render->render, view); 50 | } 51 | 52 | void 53 | wlc_render_surface_paint(struct wlc_render *render, struct wlc_context *bound, struct wlc_surface *surface, const struct wlc_geometry *geometry) 54 | { 55 | assert(render); 56 | 57 | if (!render->api.surface_paint || !wlc_context_bind(bound)) 58 | return; 59 | 60 | render->api.surface_paint(render->render, surface, geometry); 61 | } 62 | 63 | void 64 | wlc_render_pointer_paint(struct wlc_render *render, struct wlc_context *bound, const struct wlc_point *pos) 65 | { 66 | assert(render); 67 | 68 | if (!render->api.pointer_paint || !wlc_context_bind(bound)) 69 | return; 70 | 71 | render->api.pointer_paint(render->render, pos); 72 | } 73 | 74 | void 75 | wlc_render_read_pixels(struct wlc_render *render, struct wlc_context *bound, enum wlc_pixel_format format, const struct wlc_geometry *geometry, struct wlc_geometry *out_geometry, void *out_data) 76 | { 77 | assert(render); 78 | 79 | if (!render->api.read_pixels || !wlc_context_bind(bound)) 80 | return; 81 | 82 | render->api.read_pixels(render->render, format, geometry, out_geometry, out_data); 83 | } 84 | 85 | void 86 | wlc_render_write_pixels(struct wlc_render *render, struct wlc_context *bound, enum wlc_pixel_format format, const struct wlc_geometry *geometry, const void *data) 87 | { 88 | assert(render); 89 | 90 | if (!render->api.write_pixels || !wlc_context_bind(bound)) 91 | return; 92 | 93 | render->api.write_pixels(render->render, format, geometry, data); 94 | } 95 | 96 | void 97 | wlc_render_flush_fakefb(struct wlc_render *render, struct wlc_context *bound) 98 | { 99 | assert(render); 100 | 101 | if (!render->api.flush_fakefb || !wlc_context_bind(bound)) 102 | return; 103 | 104 | render->api.flush_fakefb(render->render); 105 | } 106 | 107 | void 108 | wlc_render_clear(struct wlc_render *render, struct wlc_context *bound) 109 | { 110 | assert(render); 111 | 112 | if (!render->api.clear || !wlc_context_bind(bound)) 113 | return; 114 | 115 | render->api.clear(render->render); 116 | } 117 | 118 | void 119 | wlc_render_release(struct wlc_render *render, struct wlc_context *bound) 120 | { 121 | assert(render); 122 | 123 | if (render->api.terminate) { 124 | if (!wlc_context_bind(bound)) 125 | return; 126 | 127 | render->api.terminate(render->render); 128 | } 129 | 130 | memset(render, 0, sizeof(struct wlc_render)); 131 | } 132 | 133 | bool 134 | wlc_render(struct wlc_render *render, struct wlc_context *context) 135 | { 136 | assert(render && context); 137 | memset(render, 0, sizeof(struct wlc_render)); 138 | 139 | if (!wlc_context_bind(context)) 140 | return NULL; 141 | 142 | void* (*constructor[])(struct wlc_render_api*) = { 143 | wlc_gles2, 144 | NULL 145 | }; 146 | 147 | for (uint32_t i = 0; constructor[i]; ++i) { 148 | if ((render->render = constructor[i](&render->api))) 149 | return true; 150 | } 151 | 152 | wlc_log(WLC_LOG_WARN, "Could not initialize any rendering backend"); 153 | wlc_render_release(render, context); 154 | return false; 155 | } 156 | -------------------------------------------------------------------------------- /src/platform/render/render.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_RENDER_API_H_ 2 | #define _WLC_RENDER_API_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "resources/resources.h" 8 | 9 | struct wlc_context; 10 | struct wlc_surface; 11 | struct wlc_buffer; 12 | struct wlc_view; 13 | struct wlc_output; 14 | struct wlc_render; 15 | struct wlc_point; 16 | struct wlc_geometry; 17 | struct ctx; 18 | 19 | struct wlc_render_api { 20 | enum wlc_renderer renderer_type; 21 | WLC_NONULL void (*terminate)(struct ctx *render); 22 | WLC_NONULL void (*resolution)(struct ctx *render, const struct wlc_size *mode, const struct wlc_size *resolution, uint32_t scale); 23 | WLC_NONULL void (*surface_destroy)(struct ctx *render, struct wlc_context *bound, struct wlc_surface *surface); 24 | WLC_NONULLV(1,2,3) bool (*surface_attach)(struct ctx *render, struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer); 25 | WLC_NONULL void (*view_paint)(struct ctx *render, struct wlc_view *view); 26 | WLC_NONULL void (*surface_paint)(struct ctx *render, struct wlc_surface *surface, const struct wlc_geometry *geometry); 27 | WLC_NONULL void (*pointer_paint)(struct ctx *render, const struct wlc_point *pos); 28 | WLC_NONULL void (*read_pixels)(struct ctx *render, enum wlc_pixel_format format, const struct wlc_geometry *geometry, struct wlc_geometry *out_geometry, void *out_data); 29 | WLC_NONULL void (*write_pixels)(struct ctx *render, enum wlc_pixel_format format, const struct wlc_geometry *geometry, const void *data); 30 | WLC_NONULL void (*flush_fakefb)(struct ctx *render); 31 | WLC_NONULL void (*clear)(struct ctx *render); 32 | }; 33 | 34 | struct wlc_render { 35 | void *render; // internal renderer context (OpenGL, etc) 36 | struct wlc_render_api api; 37 | }; 38 | 39 | WLC_NONULL void wlc_render_resolution(struct wlc_render *render, struct wlc_context *bound, const struct wlc_size *mode, const struct wlc_size *resolution, uint32_t scale); 40 | WLC_NONULL void wlc_render_surface_destroy(struct wlc_render *render, struct wlc_context *bound, struct wlc_surface *surface); 41 | WLC_NONULLV(1,2,3) bool wlc_render_surface_attach(struct wlc_render *render, struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer); 42 | WLC_NONULL void wlc_render_view_paint(struct wlc_render *render, struct wlc_context *bound, struct wlc_view *view); 43 | WLC_NONULL void wlc_render_surface_paint(struct wlc_render *render, struct wlc_context *bound, struct wlc_surface *surface, const struct wlc_geometry *geometry); 44 | WLC_NONULL void wlc_render_pointer_paint(struct wlc_render *render, struct wlc_context *bound, const struct wlc_point *pos); 45 | WLC_NONULL void wlc_render_read_pixels(struct wlc_render *render, struct wlc_context *bound, enum wlc_pixel_format format, const struct wlc_geometry *geometry, struct wlc_geometry *out_geometry, void *out_data); 46 | WLC_NONULL void wlc_render_write_pixels(struct wlc_render *render, struct wlc_context *bound, enum wlc_pixel_format format, const struct wlc_geometry *geometry, const void *data); 47 | WLC_NONULL void wlc_render_flush_fakefb(struct wlc_render *render, struct wlc_context *bound); // only relevant to GLES2 48 | WLC_NONULL void wlc_render_clear(struct wlc_render *render, struct wlc_context *bound); 49 | void wlc_render_release(struct wlc_render *render, struct wlc_context *context); 50 | WLC_NONULL bool wlc_render(struct wlc_render *render, struct wlc_context *context); 51 | 52 | #endif /* _WLC_RENDER_API_H_ */ 53 | -------------------------------------------------------------------------------- /src/resources/resources.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_RESOURCES_H_ 2 | #define _WLC_RESOURCES_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef uintptr_t wlc_resource; 11 | 12 | /** Storage for handles / resources. */ 13 | struct wlc_source { 14 | const char *name; 15 | struct chck_pool pool; 16 | bool (*constructor)(); 17 | void (*destructor)(); 18 | }; 19 | 20 | /** Use this empty struct for resources that don't need their own container. */ 21 | struct wlc_resource {}; 22 | 23 | /** Generic destructor that can be passed to various wl interface implementations. */ 24 | WLC_NONULL static inline void 25 | wlc_cb_resource_destructor(struct wl_client *client, struct wl_resource *resource) 26 | { 27 | (void)client; 28 | wl_resource_destroy(resource); 29 | } 30 | 31 | /** Helper for creating wayland resources with version support check. */ 32 | WLC_NONULL struct wl_resource* wl_resource_create_checked(struct wl_client *client, const struct wl_interface *interface, uint32_t version, uint32_t supported, uint32_t id); 33 | 34 | /** Init resource management */ 35 | bool wlc_resources_init(void); 36 | 37 | /** Terminate resource management */ 38 | void wlc_resources_terminate(void); 39 | 40 | /** 41 | * Initialize source. 42 | * name should be type name of the handle/resource source will be carrying. 43 | * grow defines the reallocation step for source. 44 | * member defines the size of item the source will be carrying. 45 | */ 46 | WLC_NONULLV(1,2) bool wlc_source(struct wlc_source *source, const char *name, bool (*constructor)(), void (*destructor)(), size_t grow, size_t member); 47 | 48 | /** 49 | * Release source and all the handles/resources it contains. 50 | */ 51 | void wlc_source_release(struct wlc_source *source); 52 | 53 | /** Converts pointer back to handle, use the convert_to_ macros instead. */ 54 | wlc_handle convert_to_handle(void *ptr, size_t size); 55 | 56 | /** 57 | * Create new wlc_handle into given source pool. 58 | * wlc handles are types that are not tied to wayland resource. 59 | * For example wlc_view and wlc_output. 60 | */ 61 | WLC_NONULL void* wlc_handle_create(struct wlc_source *source); 62 | 63 | /** 64 | * Convert from wlc_handle back to the pointer. 65 | * name should be same as the name in source, otherwise NULL is returned. 66 | */ 67 | void* convert_from_wlc_handle(wlc_handle handle, const char *name, size_t line, const char *file, const char *function); 68 | #define convert_from_wlc_handle(x, y) convert_from_wlc_handle(x, y, __LINE__, WLC_FILE, __func__) 69 | 70 | /** 71 | * Convert pointer back to wlc_handle. 72 | * NOTE: The sizeof(*x), use this only when compiler can know the size. 73 | * void *ptr, won't work. 74 | */ 75 | #define convert_to_wlc_handle(x) convert_to_handle(x, sizeof(*x)) 76 | 77 | /** 78 | * Release wlc_handle. 79 | */ 80 | void wlc_handle_release(wlc_handle handle); 81 | 82 | /** 83 | * Create new wlc_resource into given source pool. 84 | * wlc_resources are types that are tied to wayland resource. 85 | * Thus their lifetime is also dictated by the wayland resource. 86 | * 87 | * Implementation for these types should go in resources/types/ 88 | */ 89 | WLC_NONULL wlc_resource wlc_resource_create(struct wlc_source *source, struct wl_client *client, const struct wl_interface *interface, uint32_t version, uint32_t supported, uint32_t id); 90 | 91 | /** Create new wlc_resource from existing wayland resource. */ 92 | WLC_NONULL wlc_resource wlc_resource_create_from(struct wlc_source *source, struct wl_resource *resource); 93 | 94 | /** Implement wlc_resource. */ 95 | void wlc_resource_implement(wlc_resource resource, const void *implementation, void *userdata); 96 | 97 | /** Convert to wlc_resource from wayland resource. */ 98 | wlc_resource wlc_resource_from_wl_resource(struct wl_resource *resource); 99 | 100 | /** Convert to wayland resource from wlc_resource. */ 101 | struct wl_resource* wl_resource_from_wlc_resource(wlc_resource resource, const char *name, size_t line, const char *file, const char *function); 102 | #define wl_resource_from_wlc_resource(x, y) wl_resource_from_wlc_resource(x, y, __LINE__, WLC_FILE, __func__) 103 | 104 | /** Get wayland resource for client from source. */ 105 | WLC_NONULL struct wl_resource* wl_resource_for_client(struct wlc_source *source, struct wl_client *client); 106 | 107 | /** Convert to pointer from wlc_resource. */ 108 | void* convert_from_wlc_resource(wlc_resource resource, const char *name, size_t line, const char *file, const char *function); 109 | #define convert_from_wlc_resource(x, y) convert_from_wlc_resource(x, y, __LINE__, WLC_FILE, __func__) 110 | 111 | /** Convert to pointer from wayland resource. */ 112 | void* convert_from_wl_resource(struct wl_resource *resource, const char *name, size_t line, const char *file, const char *function); 113 | #define convert_from_wl_resource(x, y) convert_from_wl_resource(x, y, __LINE__, WLC_FILE, __func__) 114 | 115 | /** 116 | * Convert to wlc_resource from pointer. 117 | * NOTE: The sizeof(*x), use this only when compiler can know the size. 118 | * void *ptr, won't work. 119 | */ 120 | #define convert_to_wlc_resource(x) (wlc_resource)convert_to_handle(x, sizeof(*x)) 121 | 122 | /** 123 | * Convert to wayland resource from pointer. 124 | * NOTE: The sizeof(*x), use this only when compiler can know the size. 125 | * void *ptr, won't work. 126 | */ 127 | #define convert_to_wl_resource(x, y) wl_resource_from_wlc_resource((wlc_resource)convert_to_handle(x, sizeof(*x)), y) 128 | 129 | /** 130 | * Invalidate the wayland resource for the wlc_resource. 131 | * only wlc_buffer uses this right now, since it needs to release the wayland resource in queue. 132 | */ 133 | void wlc_resource_invalidate(wlc_resource resource); 134 | 135 | /** Release resource. */ 136 | void wlc_resource_release(wlc_resource resource); 137 | 138 | /** Release pointer to wlc_handle, useful for chck__for_each_call mainly. */ 139 | static inline void 140 | wlc_handle_release_ptr(wlc_handle *handle) 141 | { 142 | wlc_handle_release(*handle); 143 | } 144 | 145 | /** Release pointer to wlc_resource, useful for chck__for_each_call mainly. */ 146 | static inline void 147 | wlc_resource_release_ptr(wlc_resource *resource) 148 | { 149 | wlc_resource_release(*resource); 150 | } 151 | 152 | #endif /* _WLC_RESOURCES_H_ */ 153 | -------------------------------------------------------------------------------- /src/resources/types/buffer.c: -------------------------------------------------------------------------------- 1 | #include "buffer.h" 2 | #include 3 | #include 4 | #include "surface.h" 5 | 6 | void 7 | wlc_buffer_dispose(struct wlc_buffer *buffer) 8 | { 9 | if (!buffer) 10 | return; 11 | 12 | if (buffer->references && --buffer->references > 0) 13 | return; 14 | 15 | wlc_resource_release(convert_to_wlc_resource(buffer)); 16 | } 17 | 18 | wlc_resource 19 | wlc_buffer_use(struct wlc_buffer *buffer) 20 | { 21 | if (!buffer) 22 | return 0; 23 | 24 | buffer->references++; 25 | return convert_to_wlc_resource(buffer); 26 | } 27 | 28 | void 29 | wlc_buffer_release(struct wlc_buffer *buffer) 30 | { 31 | if (!buffer) 32 | return; 33 | 34 | struct wlc_surface *surface; 35 | if ((surface = convert_from_wlc_resource(buffer->surface, "surface"))) { 36 | if (surface->commit.buffer == convert_to_wlc_resource(buffer)) 37 | surface->commit.buffer = 0; 38 | if (surface->pending.buffer == convert_to_wlc_resource(buffer)) 39 | surface->pending.buffer = 0; 40 | } 41 | 42 | struct wl_resource *resource; 43 | if ((resource = convert_to_wl_resource(buffer, "buffer"))) { 44 | wlc_resource_invalidate(convert_to_wlc_resource(buffer)); 45 | wl_resource_queue_event(resource, WL_BUFFER_RELEASE); 46 | } 47 | } 48 | 49 | bool 50 | wlc_buffer(struct wlc_buffer *buffer) 51 | { 52 | assert(buffer); 53 | buffer->y_inverted = true; 54 | return true; 55 | } 56 | -------------------------------------------------------------------------------- /src/resources/types/buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_BUFFER_H_ 2 | #define _WLC_BUFFER_H_ 3 | 4 | #include 5 | #include 6 | #include "resources/resources.h" 7 | 8 | struct wl_shm_buffer; 9 | 10 | struct wlc_buffer { 11 | struct wlc_size size; 12 | wlc_resource surface; 13 | 14 | union { 15 | struct wl_shm_buffer *shm_buffer; 16 | void *legacy_buffer; 17 | }; 18 | 19 | uint16_t references; 20 | bool y_inverted; 21 | }; 22 | 23 | void wlc_buffer_dispose(struct wlc_buffer *buffer); 24 | wlc_resource wlc_buffer_use(struct wlc_buffer *buffer); 25 | void wlc_buffer_release(struct wlc_buffer *buffer); 26 | WLC_NONULL bool wlc_buffer(struct wlc_buffer *buffer); 27 | 28 | #endif /* _WLC_BUFFER_H_ */ 29 | -------------------------------------------------------------------------------- /src/resources/types/data-source.c: -------------------------------------------------------------------------------- 1 | #include "data-source.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | wlc_data_source_release(struct wlc_data_source *source) 8 | { 9 | if (!source) 10 | return; 11 | 12 | chck_iter_pool_for_each_call(&source->types, chck_string_release); 13 | chck_iter_pool_release(&source->types); 14 | } 15 | 16 | bool 17 | wlc_data_source(struct wlc_data_source *source, const struct wlc_data_source_impl *impl) 18 | { 19 | assert(source); 20 | source->impl = impl; 21 | return chck_iter_pool(&source->types, 32, 0, sizeof(struct chck_string)); 22 | } 23 | -------------------------------------------------------------------------------- /src/resources/types/data-source.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_DATA_SOURCE_H_ 2 | #define _WLC_DATA_SOURCE_H_ 3 | 4 | #include 5 | #include 6 | 7 | struct wlc_data_source; 8 | struct wlc_data_source_impl { 9 | void (*send)(struct wlc_data_source *data_source, const char *type, int fd); 10 | void (*accept)(struct wlc_data_source *data_source, const char *type); 11 | void (*cancel)(struct wlc_data_source *data_source); 12 | void (*dnd_finished)(struct wlc_data_source *data_source); 13 | }; 14 | 15 | struct wlc_data_source { 16 | struct chck_iter_pool types; 17 | uint32_t prf_dnd_action; // preferred 18 | uint32_t dst_dnd_actions; 19 | uint32_t src_dnd_actions; 20 | const struct wlc_data_source_impl *impl; 21 | }; 22 | 23 | void wlc_data_source_release(struct wlc_data_source *source); 24 | WLC_NONULL bool wlc_data_source(struct wlc_data_source *source, const struct wlc_data_source_impl *impl); 25 | 26 | #endif /* _WLC_DATA_SOURCE_ */ 27 | -------------------------------------------------------------------------------- /src/resources/types/region.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "region.h" 6 | #include "macros.h" 7 | #include "resources/resources.h" 8 | 9 | static void 10 | wl_cb_region_add(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) 11 | { 12 | (void)client; 13 | 14 | struct wlc_region *region; 15 | if (!(region = convert_from_wl_resource(resource, "region"))) 16 | return; 17 | 18 | pixman_region32_union_rect(®ion->region, ®ion->region, x, y, width, height); 19 | } 20 | 21 | static void 22 | wl_cb_region_subtract(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) 23 | { 24 | (void)client; 25 | 26 | struct wlc_region *region; 27 | if (!(region = convert_from_wl_resource(resource, "region"))) 28 | return; 29 | 30 | pixman_region32_t rect; 31 | pixman_region32_init_rect(&rect, x, y, width, height); 32 | pixman_region32_subtract(®ion->region, ®ion->region, &rect); 33 | pixman_region32_fini(&rect); 34 | } 35 | 36 | void 37 | wlc_region_release(struct wlc_region *region) 38 | { 39 | if (!region) 40 | return; 41 | 42 | pixman_region32_fini(®ion->region); 43 | } 44 | 45 | WLC_CONST const struct wl_region_interface* 46 | wlc_region_implementation(void) 47 | { 48 | static const struct wl_region_interface wl_region_implementation = { 49 | .destroy = wlc_cb_resource_destructor, 50 | .add = wl_cb_region_add, 51 | .subtract = wl_cb_region_subtract, 52 | }; 53 | 54 | return &wl_region_implementation; 55 | } 56 | -------------------------------------------------------------------------------- /src/resources/types/region.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_REGION_H_ 2 | #define _WLC_REGION_H_ 3 | 4 | #include 5 | #include 6 | 7 | struct wlc_region { 8 | pixman_region32_t region; 9 | }; 10 | 11 | void wlc_region_release(struct wlc_region *region); 12 | 13 | const struct wl_region_interface* wlc_region_implementation(void); 14 | 15 | #endif /* _WLC_REGION_H_ */ 16 | -------------------------------------------------------------------------------- /src/resources/types/shell-surface.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "shell-surface.h" 5 | #include "surface.h" 6 | #include "internal.h" 7 | #include "macros.h" 8 | #include "compositor/view.h" 9 | #include "compositor/output.h" 10 | #include "compositor/seat/seat.h" 11 | #include "compositor/seat/pointer.h" 12 | 13 | static void 14 | wl_cb_shell_surface_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial) 15 | { 16 | (void)client, (void)serial; 17 | 18 | struct wlc_view *view; 19 | struct wlc_surface *surface; 20 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view")) || 21 | !(surface = convert_from_wlc_resource(view->surface, "surface"))) 22 | return; 23 | 24 | STUBL(resource); 25 | } 26 | 27 | static void 28 | wl_cb_shell_surface_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) 29 | { 30 | (void)client, (void)resource, (void)serial; 31 | 32 | struct wlc_seat *seat; 33 | if (!(seat = wl_resource_get_user_data(seat_resource))) 34 | return; 35 | 36 | if (!seat->pointer.focused.view) 37 | return; 38 | 39 | wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") requested move", seat->pointer.focused.view); 40 | const struct wlc_point o = { seat->pointer.pos.x, seat->pointer.pos.y }; 41 | WLC_INTERFACE_EMIT(view.request.move, seat->pointer.focused.view, &o); 42 | } 43 | 44 | static void 45 | wl_cb_shell_surface_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) 46 | { 47 | (void)client, (void)resource, (void)serial; 48 | 49 | struct wlc_seat *seat; 50 | if (!(seat = wl_resource_get_user_data(seat_resource))) 51 | return; 52 | 53 | if (!seat->pointer.focused.view) 54 | return; 55 | 56 | wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") requested resize", seat->pointer.focused.view); 57 | const struct wlc_point o = { seat->pointer.pos.x, seat->pointer.pos.y }; 58 | WLC_INTERFACE_EMIT(view.request.resize, seat->pointer.focused.view, edges, &o); 59 | } 60 | 61 | static void 62 | wl_cb_shell_surface_set_toplevel(struct wl_client *client, struct wl_resource *resource) 63 | { 64 | (void)client; 65 | 66 | struct wlc_view *view; 67 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 68 | return; 69 | 70 | if (!wlc_view_request_state(view, WLC_BIT_FULLSCREEN, false)) 71 | return; 72 | 73 | view->data.fullscreen_mode = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; 74 | } 75 | 76 | static void 77 | wl_cb_shell_surface_set_transient(struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent_resource, int32_t x, int32_t y, uint32_t flags) 78 | { 79 | (void)client, (void)flags; 80 | 81 | struct wlc_view *view; 82 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 83 | return; 84 | 85 | struct wlc_surface *surface = (parent_resource ? convert_from_wl_resource(parent_resource, "surface") : NULL); 86 | wlc_view_set_parent_ptr(view, (surface ? convert_from_wlc_handle(surface->view, "view") : NULL)); 87 | view->pending.geometry.origin = (struct wlc_point){ x, y }; 88 | } 89 | 90 | static void 91 | wl_cb_shell_surface_set_fullscreen(struct wl_client *client, struct wl_resource *resource, uint32_t method, uint32_t framerate, struct wl_resource *output_resource) 92 | { 93 | (void)client, (void)method, (void)framerate; 94 | 95 | struct wlc_view *view; 96 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 97 | return; 98 | 99 | if (!wlc_view_request_state(view, WLC_BIT_FULLSCREEN, true)) 100 | return; 101 | 102 | struct wlc_output *output; 103 | if (output_resource && ((output = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(output_resource), "output")))) 104 | wlc_view_set_output_ptr(view, output); 105 | 106 | view->data.fullscreen_mode = method; 107 | } 108 | 109 | static void 110 | wl_cb_shell_surface_set_popup(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial, struct wl_resource *parent_resource, int32_t x, int32_t y, uint32_t flags) 111 | { 112 | (void)client, (void)seat, (void)serial, (void)flags; 113 | 114 | struct wlc_view *view; 115 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 116 | return; 117 | 118 | wlc_view_set_type_ptr(view, WLC_BIT_POPUP, true); 119 | struct wlc_surface *surface = (parent_resource ? convert_from_wl_resource(parent_resource, "surface") : NULL); 120 | wlc_view_set_parent_ptr(view, (surface ? convert_from_wlc_handle(surface->view, "view") : NULL)); 121 | view->pending.geometry.origin = (struct wlc_point){ x, y }; 122 | 123 | } 124 | 125 | static void 126 | wl_cb_shell_surface_set_maximized(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource) 127 | { 128 | (void)client; 129 | 130 | struct wlc_view *view; 131 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 132 | return; 133 | 134 | if (!wlc_view_request_state(view, WLC_BIT_MAXIMIZED, true)) 135 | return; 136 | 137 | struct wlc_output *output; 138 | if (output_resource && ((output = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(output_resource), "output")))) 139 | wlc_view_set_output_ptr(view, output); 140 | } 141 | 142 | static void 143 | wl_cb_shell_surface_set_title(struct wl_client *client, struct wl_resource *resource, const char *title) 144 | { 145 | (void)client; 146 | wlc_view_set_title_ptr(convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"), title, strlen(title)); 147 | } 148 | 149 | static void 150 | wl_cb_shell_surface_set_class(struct wl_client *client, struct wl_resource *resource, const char *class_) 151 | { 152 | (void)client; 153 | wlc_view_set_class_ptr(convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"), class_, strlen(class_)); 154 | } 155 | 156 | WLC_CONST const struct wl_shell_surface_interface* 157 | wlc_shell_surface_implementation(void) 158 | { 159 | static const struct wl_shell_surface_interface wl_shell_surface_implementation = { 160 | .pong = wl_cb_shell_surface_pong, 161 | .move = wl_cb_shell_surface_move, 162 | .resize = wl_cb_shell_surface_resize, 163 | .set_toplevel = wl_cb_shell_surface_set_toplevel, 164 | .set_transient = wl_cb_shell_surface_set_transient, 165 | .set_fullscreen = wl_cb_shell_surface_set_fullscreen, 166 | .set_popup = wl_cb_shell_surface_set_popup, 167 | .set_maximized = wl_cb_shell_surface_set_maximized, 168 | .set_title = wl_cb_shell_surface_set_title, 169 | .set_class = wl_cb_shell_surface_set_class, 170 | }; 171 | 172 | return &wl_shell_surface_implementation; 173 | } 174 | -------------------------------------------------------------------------------- /src/resources/types/shell-surface.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_SHELL_SURFACE_H_ 2 | #define _WLC_SHELL_SURFACE_H_ 3 | 4 | #include 5 | 6 | const struct wl_shell_surface_interface* wlc_shell_surface_implementation(void); 7 | 8 | #endif /* _WLC_SHELL_SURFACE_H_ */ 9 | -------------------------------------------------------------------------------- /src/resources/types/surface.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_SURFACE_H_ 2 | #define _WLC_SURFACE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "resources/resources.h" 11 | 12 | struct wlc_buffer; 13 | struct wlc_output; 14 | struct wlc_view; 15 | 16 | struct wlc_surface_state { 17 | struct chck_iter_pool frame_cbs; 18 | pixman_region32_t opaque; 19 | pixman_region32_t input; 20 | pixman_region32_t damage; 21 | struct wlc_point offset; 22 | struct wlc_point subsurface_position; 23 | wlc_resource buffer; 24 | int32_t scale; 25 | enum wl_output_transform transform; 26 | bool attached; 27 | }; 28 | 29 | struct wlc_coordinate_scale { 30 | double w, h; 31 | }; 32 | 33 | struct wlc_surface { 34 | struct wlc_source buffers, callbacks; 35 | struct wlc_surface_state pending; 36 | struct wlc_surface_state commit; 37 | struct wlc_size size; 38 | struct wlc_coordinate_scale coordinate_transform; 39 | 40 | /* Parent surface for subsurface interface */ 41 | wlc_resource parent; 42 | 43 | /* list of subsurfaces */ 44 | struct chck_iter_pool subsurface_list; 45 | 46 | /* Set if this surface is bind to view */ 47 | wlc_handle view; 48 | 49 | /* The view this surface belongs to, e.g also subsurfaces */ 50 | wlc_handle parent_view; 51 | 52 | /* Current output the surface is attached to */ 53 | wlc_handle output; 54 | 55 | /** 56 | * "Texture" as we use OpenGL terminology, but can be id to anything. 57 | * Managed by the renderer. 58 | */ 59 | uint32_t textures[3]; 60 | 61 | /** 62 | * Images, contains hw surfaces that can be anything (For example EGL KHR Images in EGL/gles2 renderer). 63 | * Managed by the renderer. 64 | */ 65 | void *images[3]; 66 | 67 | enum wlc_surface_format format; 68 | 69 | bool synchronized, parent_synchronized; 70 | }; 71 | 72 | WLC_NONULLV(2,3) bool wlc_surface_get_opaque(struct wlc_surface *surface, const struct wlc_point *offset, struct wlc_geometry *out_opaque); 73 | WLC_NONULLV(2,3) void wlc_surface_get_input(struct wlc_surface *surface, const struct wlc_point *offset, struct wlc_geometry *out_input); 74 | struct wlc_buffer* wlc_surface_get_buffer(struct wlc_surface *surface); 75 | void wlc_surface_attach_to_view(struct wlc_surface *surface, struct wlc_view *view); 76 | bool wlc_surface_attach_to_output(struct wlc_surface *surface, struct wlc_output *output, struct wlc_buffer *buffer); 77 | void wlc_surface_set_parent(struct wlc_surface *surface, struct wlc_surface *parent); 78 | void wlc_surface_invalidate(struct wlc_surface *surface); 79 | void wlc_surface_release(struct wlc_surface *surface); 80 | void wlc_surface_commit(struct wlc_surface *surface); 81 | WLC_NONULL bool wlc_surface(struct wlc_surface *surface); 82 | 83 | const struct wl_surface_interface* wlc_surface_implementation(void); 84 | 85 | #endif /* _WLC_SURFACE_H_ */ 86 | -------------------------------------------------------------------------------- /src/resources/types/xdg-popup.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XDG_POPUP_H_ 2 | #define _WLC_XDG_POPUP_H_ 3 | 4 | #include "resources/types/xdg-positioner.h" 5 | 6 | struct wlc_xdg_popup { 7 | struct wlc_xdg_positioner* xdg_positioner; 8 | }; 9 | 10 | #endif /* _WLC_XDG_POPUP_H_ */ 11 | -------------------------------------------------------------------------------- /src/resources/types/xdg-positioner.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xdg-positioner.h" 4 | #include "internal.h" 5 | #include "macros.h" 6 | 7 | static void 8 | wlc_xdg_positioner_protocol_set_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height) 9 | { 10 | (void)client; 11 | struct wlc_xdg_positioner *positioner; 12 | if (!(positioner = wl_resource_get_user_data(resource))) 13 | return; 14 | 15 | if (width < 1 || height < 1) { 16 | wl_resource_post_error(resource, 17 | ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, 18 | "width and height must be positives and non-zero"); 19 | return; 20 | } 21 | positioner->size.w = width; 22 | positioner->size.h = height; 23 | positioner->flags |= WLC_XDG_POSITIONER_HAS_SIZE; 24 | } 25 | 26 | static void 27 | wlc_xdg_positioner_protocol_set_anchor_rect(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) 28 | { 29 | (void)client; 30 | struct wlc_xdg_positioner *positioner; 31 | if (!(positioner = wl_resource_get_user_data(resource))) 32 | return; 33 | 34 | if (width < 1 || height < 1) { 35 | wl_resource_post_error(resource, 36 | ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, 37 | "width and height must be positives and non-zero"); 38 | return; 39 | } 40 | positioner->anchor_rect.origin.x = x; 41 | positioner->anchor_rect.origin.y = y; 42 | positioner->anchor_rect.size.w = width; 43 | positioner->anchor_rect.size.h = height; 44 | positioner->flags |= WLC_XDG_POSITIONER_HAS_ANCHOR_RECT; 45 | } 46 | 47 | static void 48 | wlc_xdg_positioner_protocol_set_anchor(struct wl_client *client, struct wl_resource *resource, enum zxdg_positioner_v6_anchor anchor) 49 | { 50 | (void)client; 51 | struct wlc_xdg_positioner *positioner; 52 | if (!(positioner = wl_resource_get_user_data(resource))) 53 | return; 54 | 55 | if (((anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP ) && 56 | (anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM)) || 57 | ((anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT) && 58 | (anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT))) { 59 | wl_resource_post_error(resource, 60 | ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, 61 | "same-axis values are not allowed"); 62 | return; 63 | } 64 | 65 | positioner->anchor = WLC_BIT_ANCHOR_NONE; 66 | if (anchor & ZXDG_POSITIONER_V6_ANCHOR_TOP) positioner->anchor |= WLC_BIT_ANCHOR_TOP; 67 | if (anchor & ZXDG_POSITIONER_V6_ANCHOR_BOTTOM) positioner->anchor |= WLC_BIT_ANCHOR_BOTTOM; 68 | if (anchor & ZXDG_POSITIONER_V6_ANCHOR_LEFT) positioner->anchor |= WLC_BIT_ANCHOR_LEFT; 69 | if (anchor & ZXDG_POSITIONER_V6_ANCHOR_RIGHT) positioner->anchor |= WLC_BIT_ANCHOR_RIGHT; 70 | } 71 | 72 | static void 73 | wlc_xdg_positioner_protocol_set_gravity(struct wl_client *client, struct wl_resource *resource, enum zxdg_positioner_v6_gravity gravity) 74 | { 75 | (void)client; 76 | struct wlc_xdg_positioner *positioner; 77 | if (!(positioner = wl_resource_get_user_data(resource))) 78 | return; 79 | 80 | if (((gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP) && 81 | (gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM)) || 82 | ((gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT) && 83 | (gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT))) { 84 | wl_resource_post_error(resource, 85 | ZXDG_POSITIONER_V6_ERROR_INVALID_INPUT, 86 | "same-axis values are not allowed"); 87 | return; 88 | } 89 | 90 | positioner->gravity = WLC_BIT_GRAVITY_NONE; 91 | if (gravity & ZXDG_POSITIONER_V6_GRAVITY_TOP) positioner->gravity |= WLC_BIT_GRAVITY_TOP; 92 | if (gravity & ZXDG_POSITIONER_V6_GRAVITY_BOTTOM) positioner->gravity |= WLC_BIT_GRAVITY_BOTTOM; 93 | if (gravity & ZXDG_POSITIONER_V6_GRAVITY_LEFT) positioner->gravity |= WLC_BIT_GRAVITY_LEFT; 94 | if (gravity & ZXDG_POSITIONER_V6_GRAVITY_RIGHT) positioner->gravity |= WLC_BIT_GRAVITY_RIGHT; 95 | } 96 | 97 | static void 98 | wlc_xdg_positioner_protocol_set_constraint_adjustment(struct wl_client *client, struct wl_resource *resource, enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment) 99 | { 100 | (void)client; 101 | struct wlc_xdg_positioner *positioner; 102 | if (!(positioner = wl_resource_get_user_data(resource))) 103 | return; 104 | 105 | positioner->constraint_adjustment = WLC_BIT_CONSTRAINT_ADJUSTMENT_NONE; 106 | if (constraint_adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X) positioner->constraint_adjustment |= WLC_BIT_CONSTRAINT_ADJUSTMENT_SLIDE_X; 107 | if (constraint_adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y) positioner->constraint_adjustment |= WLC_BIT_CONSTRAINT_ADJUSTMENT_SLIDE_Y; 108 | if (constraint_adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X) positioner->constraint_adjustment |= WLC_BIT_CONSTRAINT_ADJUSTMENT_FLIP_X; 109 | if (constraint_adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y) positioner->constraint_adjustment |= WLC_BIT_CONSTRAINT_ADJUSTMENT_FLIP_Y; 110 | if (constraint_adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X) positioner->constraint_adjustment |= WLC_BIT_CONSTRAINT_ADJUSTMENT_RESIZE_X; 111 | if (constraint_adjustment & ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y) positioner->constraint_adjustment |= WLC_BIT_CONSTRAINT_ADJUSTMENT_RESIZE_Y; 112 | } 113 | 114 | static void 115 | wlc_xdg_positioner_protocol_set_offset(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y) 116 | { 117 | (void)client; 118 | struct wlc_xdg_positioner *positioner; 119 | if (!(positioner = wl_resource_get_user_data(resource))) 120 | return; 121 | 122 | positioner->offset.x = x; 123 | positioner->offset.y = y; 124 | } 125 | 126 | WLC_CONST const struct zxdg_positioner_v6_interface* 127 | wlc_xdg_positioner_implementation(void) 128 | { 129 | static const struct zxdg_positioner_v6_interface zxdg_positioner_v6_implementation = { 130 | .destroy = wlc_cb_resource_destructor, 131 | .set_size = wlc_xdg_positioner_protocol_set_size, 132 | .set_anchor_rect = wlc_xdg_positioner_protocol_set_anchor_rect, 133 | .set_anchor = wlc_xdg_positioner_protocol_set_anchor, 134 | .set_gravity = wlc_xdg_positioner_protocol_set_gravity, 135 | .set_constraint_adjustment = wlc_xdg_positioner_protocol_set_constraint_adjustment, 136 | .set_offset = wlc_xdg_positioner_protocol_set_offset, 137 | }; 138 | 139 | return &zxdg_positioner_v6_implementation; 140 | } -------------------------------------------------------------------------------- /src/resources/types/xdg-positioner.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XDG_POSITIONER_H_ 2 | #define _WLC_XDG_POSITIONER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "wayland-xdg-shell-unstable-v6-server-protocol.h" 8 | 9 | const struct zxdg_positioner_v6_interface* wlc_xdg_positioner_implementation(void); 10 | 11 | enum wlc_xdg_positioner_flags { 12 | WLC_XDG_POSITIONER_HAS_SIZE = 1<<1, 13 | WLC_XDG_POSITIONER_HAS_ANCHOR_RECT = 1<<2, 14 | // offset, anchor and rest has default values 15 | }; 16 | 17 | struct wlc_xdg_positioner { 18 | enum wlc_xdg_positioner_flags flags; 19 | struct wlc_size size; 20 | struct wlc_point offset; 21 | struct wlc_geometry anchor_rect; 22 | enum wlc_positioner_anchor_bit anchor; 23 | enum wlc_positioner_gravity_bit gravity; 24 | enum wlc_positioner_constraint_adjustment_bit constraint_adjustment; 25 | }; 26 | 27 | #endif /* _WLC_XDG_POSITIONER_H_ */ 28 | -------------------------------------------------------------------------------- /src/resources/types/xdg-toplevel.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "xdg-toplevel.h" 4 | #include "internal.h" 5 | #include "macros.h" 6 | #include "compositor/view.h" 7 | #include "compositor/output.h" 8 | #include "compositor/seat/seat.h" 9 | #include "compositor/seat/pointer.h" 10 | #include "resources/types/surface.h" 11 | 12 | static void 13 | xdg_cb_toplevel_set_parent(struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent_resource) 14 | { 15 | (void)client; 16 | 17 | struct wlc_view *view; 18 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 19 | return; 20 | 21 | struct wlc_view *parent = (parent_resource ? convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(parent_resource), "view") : NULL); 22 | wlc_view_set_parent_ptr(view, parent); 23 | } 24 | 25 | static void 26 | xdg_cb_toplevel_set_title(struct wl_client *client, struct wl_resource *resource, const char *title) 27 | { 28 | (void)client; 29 | wlc_view_set_title_ptr(convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"), title, strlen(title)); 30 | } 31 | 32 | static void 33 | xdg_cb_toplevel_set_app_id(struct wl_client *client, struct wl_resource *resource, const char *app_id) 34 | { 35 | (void)client; 36 | wlc_view_set_app_id_ptr(convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"), app_id); 37 | } 38 | 39 | static void 40 | xdg_cb_toplevel_show_window_menu(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial, int32_t x, int32_t y) 41 | { 42 | (void)client, (void)resource, (void)seat, (void)serial, (void)x, (void)y; 43 | STUBL(resource); 44 | } 45 | 46 | static void 47 | xdg_cb_toplevel_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) 48 | { 49 | (void)client, (void)resource, (void)serial; 50 | 51 | struct wlc_seat *seat; 52 | if (!(seat = wl_resource_get_user_data(seat_resource))) 53 | return; 54 | 55 | if (!seat->pointer.focused.view) 56 | return; 57 | 58 | wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") requested move", seat->pointer.focused.view); 59 | const struct wlc_point o = { seat->pointer.pos.x, seat->pointer.pos.y }; 60 | WLC_INTERFACE_EMIT(view.request.move, seat->pointer.focused.view, &o); 61 | } 62 | 63 | static void 64 | xdg_cb_toplevel_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) 65 | { 66 | (void)client, (void)resource, (void)serial; 67 | 68 | struct wlc_seat *seat; 69 | if (!(seat = wl_resource_get_user_data(seat_resource))) 70 | return; 71 | 72 | if (!seat->pointer.focused.view) 73 | return; 74 | 75 | wlc_dlog(WLC_DBG_REQUEST, "(%" PRIuWLC ") requested resize", seat->pointer.focused.view); 76 | const struct wlc_point o = { seat->pointer.pos.x, seat->pointer.pos.y }; 77 | WLC_INTERFACE_EMIT(view.request.resize, seat->pointer.focused.view, edges, &o); 78 | } 79 | 80 | static void 81 | xdg_cb_toplevel_set_max_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height) 82 | { 83 | (void)client, (void)resource, (void)width, (void)height; 84 | } 85 | 86 | static void 87 | xdg_cb_toplevel_set_min_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height) 88 | { 89 | (void)client, (void)resource, (void)width, (void)height; 90 | } 91 | 92 | static void 93 | xdg_cb_toplevel_set_maximized(struct wl_client *client, struct wl_resource *resource) 94 | { 95 | (void)client; 96 | 97 | struct wlc_view *view; 98 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 99 | return; 100 | 101 | wlc_view_request_state(view, WLC_BIT_MAXIMIZED, true); 102 | } 103 | 104 | static void 105 | xdg_cb_toplevel_unset_maximized(struct wl_client *client, struct wl_resource *resource) 106 | { 107 | (void)client; 108 | 109 | struct wlc_view *view; 110 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 111 | return; 112 | 113 | wlc_view_request_state(view, WLC_BIT_MAXIMIZED, false); 114 | } 115 | 116 | static void 117 | xdg_cb_toplevel_set_fullscreen(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource) 118 | { 119 | (void)client; 120 | 121 | struct wlc_view *view; 122 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 123 | return; 124 | 125 | if (!wlc_view_request_state(view, WLC_BIT_FULLSCREEN, true)) 126 | return; 127 | 128 | struct wlc_output *output; 129 | if (output_resource && ((output = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(output_resource), "output")))) 130 | wlc_view_set_output_ptr(view, output); 131 | } 132 | 133 | static void 134 | xdg_cb_toplevel_unset_fullscreen(struct wl_client *client, struct wl_resource *resource) 135 | { 136 | (void)client; 137 | 138 | struct wlc_view *view; 139 | if (!(view = convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"))) 140 | return; 141 | 142 | wlc_view_request_state(view, WLC_BIT_FULLSCREEN, false); 143 | } 144 | 145 | static void 146 | xdg_cb_toplevel_set_minimized(struct wl_client *client, struct wl_resource *resource) 147 | { 148 | (void)client; 149 | wlc_view_set_minimized_ptr(convert_from_wlc_handle((wlc_handle)wl_resource_get_user_data(resource), "view"), true); 150 | } 151 | 152 | WLC_CONST const struct zxdg_toplevel_v6_interface* 153 | wlc_xdg_toplevel_implementation(void) 154 | { 155 | static const struct zxdg_toplevel_v6_interface zxdg_toplevel_v6_implementation = { 156 | .destroy = wlc_cb_resource_destructor, 157 | .set_parent = xdg_cb_toplevel_set_parent, 158 | .set_title = xdg_cb_toplevel_set_title, 159 | .set_app_id = xdg_cb_toplevel_set_app_id, 160 | .show_window_menu = xdg_cb_toplevel_show_window_menu, 161 | .move = xdg_cb_toplevel_move, 162 | .resize = xdg_cb_toplevel_resize, 163 | .set_max_size = xdg_cb_toplevel_set_max_size, 164 | .set_min_size = xdg_cb_toplevel_set_min_size, 165 | .set_maximized = xdg_cb_toplevel_set_maximized, 166 | .unset_maximized = xdg_cb_toplevel_unset_maximized, 167 | .set_fullscreen = xdg_cb_toplevel_set_fullscreen, 168 | .unset_fullscreen = xdg_cb_toplevel_unset_fullscreen, 169 | .set_minimized = xdg_cb_toplevel_set_minimized 170 | }; 171 | 172 | return &zxdg_toplevel_v6_implementation; 173 | } 174 | -------------------------------------------------------------------------------- /src/resources/types/xdg-toplevel.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XDG_TOPLEVEL_H_ 2 | #define _WLC_XDG_TOPLEVEL_H_ 3 | 4 | #include 5 | #include "wayland-xdg-shell-unstable-v6-server-protocol.h" 6 | 7 | const struct zxdg_toplevel_v6_interface* wlc_xdg_toplevel_implementation(void); 8 | 9 | #endif /* _WLC_XDG_TOPLEVEL_H_ */ 10 | -------------------------------------------------------------------------------- /src/session/dbus.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_DBUS_H_ 2 | #define _WLC_DBUS_H_ 3 | 4 | #include 5 | #include 6 | #include "internal.h" 7 | 8 | struct wl_event_loop; 9 | struct wl_event_source; 10 | 11 | WLC_NONULL WLC_LOG_ATTR(2, 3) bool wlc_dbus_add_match(DBusConnection *c, const char *format, ...); 12 | WLC_NONULL bool wlc_dbus_add_match_signal(DBusConnection *c, const char *sender, const char *iface, const char *member, const char *path); 13 | WLC_NONULL WLC_LOG_ATTR(2, 3) void wlc_dbus_remove_match(DBusConnection *c, const char *format, ...); 14 | WLC_NONULL void wlc_dbus_remove_match_signal(DBusConnection *c, const char *sender, const char *iface, const char *member, const char *path); 15 | 16 | WLC_NONULL void wlc_dbus_close(DBusConnection *c, struct wl_event_source *ctx); 17 | WLC_NONULL bool wlc_dbus_open(struct wl_event_loop *loop, DBusBusType bus, DBusConnection **out, struct wl_event_source **ctx_out); 18 | 19 | #endif /* _WLC_DBUS_H_ */ 20 | -------------------------------------------------------------------------------- /src/session/fd.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_FD_H_ 2 | #define _WLC_FD_H_ 3 | 4 | #include 5 | 6 | enum wlc_fd_type { 7 | WLC_FD_INPUT, 8 | WLC_FD_DRM, 9 | WLC_FD_LAST 10 | }; 11 | 12 | // Use these functions to control tty. 13 | // Reason is that for vt's which we don't have session on, we need root permissions to switch. 14 | bool wlc_fd_activate(void); 15 | bool wlc_fd_deactivate(void); 16 | bool wlc_fd_activate_vt(int vt); 17 | 18 | WLC_NONULL int wlc_fd_open(const char *path, int flags, enum wlc_fd_type type); 19 | void wlc_fd_close(int fd); 20 | void wlc_fd_terminate(void); 21 | void wlc_fd_init(bool has_logind); 22 | 23 | #endif /* _WLC_FD_H_ */ 24 | -------------------------------------------------------------------------------- /src/session/logind.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_LOGIND_H_ 2 | #define _WLC_LOGIND_H_ 3 | 4 | #if HAS_LOGIND 5 | 6 | /** Use wlc_fd_open instead, it automatically calls this if logind is used. */ 7 | WLC_NONULL int wlc_logind_open(const char *path, int flags); 8 | 9 | /** Use wlc_fd_close instead, it automatically calls this if logind is used. */ 10 | void wlc_logind_close(int fd); 11 | 12 | /** Check if logind is available. */ 13 | bool wlc_logind_available(void); 14 | 15 | void wlc_logind_terminate(void); 16 | WLC_NONULL int wlc_logind_init(const char *seat_id); 17 | 18 | #else 19 | 20 | /** For convenience. */ 21 | static inline bool 22 | wlc_logind_available(void) 23 | { 24 | return false; 25 | } 26 | 27 | #endif 28 | 29 | #endif /* _WLC_LOGIND_H_ */ 30 | -------------------------------------------------------------------------------- /src/session/tty.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "internal.h" 10 | #include "tty.h" 11 | 12 | #if defined(__linux__) 13 | # define TTY_BASENAME "/dev/tty" 14 | # define TTY_0 "/dev/tty0" 15 | # include 16 | # include 17 | # include 18 | # include 19 | #elif defined(__FreeBSD__) 20 | # include 21 | # include 22 | # include 23 | # define TTY_BASENAME "/dev/ttyv" 24 | # define TTY_0 "/dev/ttyv0" 25 | # define TTY_MAJOR 0 26 | #endif 27 | 28 | #ifndef KDSKBMUTE 29 | # define KDSKBMUTE 0x4B51 30 | #endif 31 | 32 | /** 33 | * XXX: Use pam for session control, when no logind? 34 | */ 35 | 36 | static struct { 37 | struct { 38 | long kb_mode; 39 | int vt; 40 | #ifdef __FreeBSD__ 41 | struct termios term; 42 | #endif 43 | } old_state; 44 | int tty, vt; 45 | } wlc = { 46 | .old_state = {0}, 47 | .tty = -1, 48 | .vt = 0, 49 | }; 50 | 51 | static int 52 | find_vt(const char *vt_string, bool *out_replace_vt) 53 | { 54 | assert(out_replace_vt); 55 | 56 | if (vt_string) { 57 | int vt; 58 | if (chck_cstr_to_i32(vt_string, &vt)) { 59 | *out_replace_vt = true; 60 | return vt; 61 | } else { 62 | wlc_log(WLC_LOG_WARN, "Invalid vt '%s', trying to find free vt", vt_string); 63 | } 64 | } 65 | 66 | int tty0_fd; 67 | if ((tty0_fd = open(TTY_0, O_RDWR | O_CLOEXEC)) < 0) 68 | die("Could not open %s to find free vt", TTY_0); 69 | 70 | int vt; 71 | if (ioctl(tty0_fd, VT_OPENQRY, &vt) != 0) 72 | die("Could not find free vt"); 73 | 74 | close(tty0_fd); 75 | return vt; 76 | } 77 | 78 | static int 79 | open_tty(int vt) 80 | { 81 | char tty_name[64]; 82 | #if defined(__FreeBSD__) 83 | // /dev/ttyvX index is zero-based, vt index starts from 1... 84 | snprintf(tty_name, sizeof tty_name, "%s%d", TTY_BASENAME, vt-1); 85 | #else 86 | snprintf(tty_name, sizeof tty_name, "%s%d", TTY_BASENAME, vt); 87 | #endif 88 | 89 | /* check if we are running on the desired vt */ 90 | if (ttyname(STDIN_FILENO) && chck_cstreq(tty_name, ttyname(STDIN_FILENO))) { 91 | wlc_log(WLC_LOG_INFO, "Running on vt %d (fd %d)", vt, STDIN_FILENO); 92 | return STDIN_FILENO; 93 | } 94 | 95 | int fd; 96 | if ((fd = open(tty_name, O_RDWR | O_NOCTTY | O_CLOEXEC)) < 0) 97 | die("Could not open %s", tty_name); 98 | 99 | wlc_log(WLC_LOG_INFO, "Running on vt %d (fd %d)", vt, fd); 100 | return fd; 101 | } 102 | 103 | static bool 104 | setup_tty(int fd, int vt, bool replace_vt) 105 | { 106 | if (fd < 0) 107 | return false; 108 | 109 | #if defined(__FreeBSD__) 110 | wlc.vt = vt; 111 | #else 112 | struct stat st; 113 | if (fstat(fd, &st) == -1) 114 | die("Could not stat tty fd"); 115 | wlc.vt = minor(st.st_rdev); 116 | if (major(st.st_rdev) != TTY_MAJOR || wlc.vt == 0) 117 | die("Not a valid vt"); 118 | #endif 119 | 120 | if (!replace_vt) { 121 | int kd_mode; 122 | if (ioctl(fd, KDGETMODE, &kd_mode) == -1) 123 | die("Could not get vt%d mode", wlc.vt); 124 | 125 | if (kd_mode != KD_TEXT) 126 | die("vt%d is already in graphics mode (%d). Is another display server running?", wlc.vt, kd_mode); 127 | } 128 | 129 | #if defined(__FreeBSD__) 130 | ioctl(fd, VT_GETACTIVE, &wlc.old_state.vt); 131 | #else 132 | struct vt_stat state; 133 | if (ioctl(fd, VT_GETSTATE, &state) == -1) 134 | die("Could not get current vt"); 135 | wlc.old_state.vt = state.v_active; 136 | #endif 137 | 138 | if (ioctl(fd, VT_ACTIVATE, wlc.vt) == -1) 139 | die("Could not activate vt%d", wlc.vt); 140 | 141 | if (ioctl(fd, VT_WAITACTIVE, wlc.vt) == -1) 142 | die("Could not wait for vt%d to become active", wlc.vt); 143 | 144 | if (ioctl(fd, KDGKBMODE, &wlc.old_state.kb_mode) == -1) 145 | die("Could not get keyboard mode"); 146 | 147 | // vt will be restored from now on 148 | wlc.tty = fd; 149 | 150 | #if defined(__FreeBSD__) 151 | if (ioctl(fd, KDSKBMODE, K_CODE) == -1) { 152 | wlc_tty_terminate(); 153 | die("Could not set keyboard mode to K_CODE"); 154 | } 155 | /* Put the tty into raw mode */ 156 | struct termios tios; 157 | if (tcgetattr(fd, &tios)) 158 | die("Failed to get terminal attribute"); 159 | memcpy(&wlc.old_state.term, &tios, sizeof(tios)); 160 | cfmakeraw(&tios); 161 | if (tcsetattr(fd, TCSANOW, &tios)) 162 | die("Failed to set terminal attribute"); 163 | #else 164 | if (ioctl(fd, KDSKBMUTE, 1) == -1 && ioctl(fd, KDSKBMODE, K_OFF) == -1) { 165 | wlc_tty_terminate(); 166 | die("Could not set keyboard mode to K_OFF"); 167 | } 168 | #endif 169 | 170 | if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) { 171 | wlc_tty_terminate(); 172 | die("Could not set console mode to KD_GRAPHICS"); 173 | } 174 | 175 | struct vt_mode mode = { 176 | .mode = VT_PROCESS, 177 | .relsig = SIGUSR1, 178 | .acqsig = SIGUSR2, 179 | #if defined(__FreeBSD__) 180 | .frsig = SIGIO, /* not used, but has to be set anyway */ 181 | #endif 182 | }; 183 | 184 | if (ioctl(fd, VT_SETMODE, &mode) == -1) { 185 | wlc_tty_terminate(); 186 | die("Could not set vt%d mode", wlc.vt); 187 | } 188 | 189 | return true; 190 | } 191 | 192 | static void 193 | sigusr_handler(int signal) 194 | { 195 | switch (signal) { 196 | case SIGUSR1: 197 | wlc_log(WLC_LOG_INFO, "SIGUSR1"); 198 | wlc_set_active(false); 199 | break; 200 | case SIGUSR2: 201 | wlc_log(WLC_LOG_INFO, "SIGUSR2"); 202 | wlc_set_active(true); 203 | break; 204 | } 205 | } 206 | 207 | // Do not call this function directly! 208 | // Use wlc_fd_activate instead. 209 | bool 210 | wlc_tty_activate(void) 211 | { 212 | wlc_log(WLC_LOG_INFO, "Activating tty"); 213 | return (ioctl(wlc.tty, VT_RELDISP, VT_ACKACQ) != -1); 214 | } 215 | 216 | // Do not call this function directly! 217 | // Use wlc_fd_deactivate instead. 218 | bool 219 | wlc_tty_deactivate(void) 220 | { 221 | wlc_log(WLC_LOG_INFO, "Releasing tty"); 222 | return (ioctl(wlc.tty, VT_RELDISP, 1) != -1); 223 | } 224 | 225 | // Do not call this function directly! 226 | // Use wlc_fd_activate_vt instead. 227 | bool 228 | wlc_tty_activate_vt(int vt) 229 | { 230 | if (wlc.tty < 0 || vt == wlc.vt) 231 | return false; 232 | 233 | wlc_log(WLC_LOG_INFO, "Activate vt: %d", vt); 234 | return (ioctl(wlc.tty, VT_ACTIVATE, vt) != -1); 235 | } 236 | 237 | WLC_PURE int 238 | wlc_tty_get_vt(void) 239 | { 240 | return wlc.vt; 241 | } 242 | 243 | void 244 | wlc_tty_terminate(void) 245 | { 246 | if (wlc.tty >= 0) { 247 | // The ACTIVATE / WAITACTIVE may be potentially bad here. 248 | // However, we need to make sure the vt we initially opened is also active on cleanup. 249 | // We can't make sure this is synchronized due to unclean exits. 250 | if (ioctl(wlc.tty, VT_ACTIVATE, wlc.vt) != -1 && ioctl(wlc.tty, VT_WAITACTIVE, wlc.vt) != -1) { 251 | wlc_log(WLC_LOG_INFO, "Restoring vt %d (0x%lx) (fd %d)", wlc.vt, wlc.old_state.kb_mode, wlc.tty); 252 | 253 | #if defined(__FreeBSD__) 254 | if (ioctl(wlc.tty, KDSKBMODE, wlc.old_state.kb_mode) == -1) 255 | #else 256 | if (ioctl(wlc.tty, KDSKBMUTE, 0) == -1 && 257 | ioctl(wlc.tty, KDSKBMODE, wlc.old_state.kb_mode) == -1 && 258 | ioctl(wlc.tty, KDSKBMODE, K_UNICODE) == -1) 259 | #endif 260 | wlc_log(WLC_LOG_ERROR, "Failed to restore vt%d KDSKBMODE", wlc.vt); 261 | 262 | if (ioctl(wlc.tty, KDSETMODE, KD_TEXT) == -1) 263 | wlc_log(WLC_LOG_ERROR, "Failed to restore vt%d mode to KD_TEXT", wlc.vt); 264 | 265 | struct vt_mode mode = { .mode = VT_AUTO }; 266 | if (ioctl(wlc.tty, VT_SETMODE, &mode) == -1) 267 | wlc_log(WLC_LOG_ERROR, "Failed to restore vt%d mode to VT_AUTO", wlc.vt); 268 | } else { 269 | wlc_log(WLC_LOG_ERROR, "Failed to activate vt%d for restoration", wlc.vt); 270 | } 271 | 272 | if (ioctl(wlc.tty, VT_ACTIVATE, wlc.old_state.vt) == -1) 273 | wlc_log(WLC_LOG_ERROR, "Failed to switch back to vt%d", wlc.old_state.vt); 274 | 275 | close(wlc.tty); 276 | } 277 | 278 | memset(&wlc, 0, sizeof(wlc)); 279 | wlc.tty = -1; 280 | } 281 | 282 | void 283 | wlc_tty_init(int vt) 284 | { 285 | if (wlc.tty >= 0) 286 | return; 287 | 288 | // if vt was forced (logind) or if XDG_VTNR was valid vt (checked by find_vt) 289 | // we skip the text mode check for current vt. 290 | bool replace_vt = (vt > 0); 291 | 292 | if (!vt && !(vt = find_vt(getenv("XDG_VTNR"), &replace_vt))) 293 | die("Could not find vt"); 294 | 295 | if (!setup_tty(open_tty(vt), vt, replace_vt)) 296 | die("Could not open tty with vt%d", vt); 297 | 298 | struct sigaction action = { 299 | .sa_handler = sigusr_handler 300 | }; 301 | 302 | sigaction(SIGUSR1, &action, NULL); 303 | sigaction(SIGUSR2, &action, NULL); 304 | } 305 | -------------------------------------------------------------------------------- /src/session/tty.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_TTY_H_ 2 | #define _WLC_TTY_H_ 3 | 4 | // Do not call these functions directly! 5 | // Use the fd.h counterparts instead. 6 | bool wlc_tty_activate(void); 7 | bool wlc_tty_deactivate(void); 8 | bool wlc_tty_activate_vt(int vt); 9 | 10 | void wlc_tty_setup_signal_handlers(void); 11 | int wlc_tty_get_vt(void); 12 | void wlc_tty_terminate(void); 13 | void wlc_tty_init(int vt); 14 | 15 | #endif /* _WLC_TTY_H_ */ 16 | -------------------------------------------------------------------------------- /src/session/udev.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_UDEV_H_ 2 | #define _WLC_UDEV_H_ 3 | 4 | #include 5 | 6 | bool wlc_input_has_init(void); 7 | void wlc_input_terminate(void); 8 | bool wlc_input_init(void); 9 | void wlc_udev_terminate(void); 10 | bool wlc_udev_init(void); 11 | 12 | #endif /* _WLC_UDEV_H_ */ 13 | -------------------------------------------------------------------------------- /src/visibility.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_VISIBLITY_H_ 2 | #define _WLC_VISIBLITY_H_ 3 | 4 | #if defined _WIN32 || defined __CYGWIN__ 5 | # define WLC_HELPER_DLL_EXPORT __declspec(dllexport) 6 | #else 7 | # if __GNUC__ >= 4 8 | # define WLC_HELPER_DLL_EXPORT __attribute__((visibility("default"))) 9 | # else 10 | # define WLC_HELPER_DLL_EXPORT 11 | # endif 12 | #endif 13 | 14 | #ifdef WLC_BUILD_SHARED 15 | # define WLC_API WLC_HELPER_DLL_EXPORT 16 | #else 17 | # define WLC_API 18 | #endif 19 | 20 | #endif /* _WLC_VISIBILITY_H_ */ 21 | -------------------------------------------------------------------------------- /src/wlc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ 4 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ 5 | 6 | Name: @PROJECT_NAME@ 7 | Description: Wayland compositor library 8 | Version: @PROJECT_VERSION@ 9 | Requires: xkbcommon libinput 10 | Requires.private: pixman-1 libudev wayland-server 11 | Libs: -L${libdir} -lwlc 12 | Libs.private: -lm -ldl 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /src/xwayland/xutil.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XATOMS_H_ 2 | #define _WLC_XATOMS_H_ 3 | 4 | #include 5 | #include 6 | 7 | enum atom_name { 8 | WL_SURFACE_ID, 9 | WM_DELETE_WINDOW, 10 | WM_TAKE_FOCUS, 11 | WM_PROTOCOLS, 12 | WM_NORMAL_HINTS, 13 | MOTIF_WM_HINTS, 14 | TEXT, 15 | UTF8_STRING, 16 | CLIPBOARD, 17 | CLIPBOARD_MANAGER, 18 | TARGETS, 19 | PRIMARY, 20 | WM_S0, 21 | STRING, 22 | WLC_SELECTION, 23 | NET_WM_S0, 24 | NET_WM_PID, 25 | NET_WM_NAME, 26 | NET_WM_STATE, 27 | NET_WM_STATE_FULLSCREEN, 28 | NET_WM_STATE_MODAL, 29 | NET_WM_STATE_ABOVE, 30 | NET_SUPPORTED, 31 | NET_SUPPORTING_WM_CHECK, 32 | NET_WM_WINDOW_TYPE, 33 | NET_WM_WINDOW_TYPE_DESKTOP, 34 | NET_WM_WINDOW_TYPE_DOCK, 35 | NET_WM_WINDOW_TYPE_TOOLBAR, 36 | NET_WM_WINDOW_TYPE_MENU, 37 | NET_WM_WINDOW_TYPE_UTILITY, 38 | NET_WM_WINDOW_TYPE_SPLASH, 39 | NET_WM_WINDOW_TYPE_DIALOG, 40 | NET_WM_WINDOW_TYPE_DROPDOWN_MENU, 41 | NET_WM_WINDOW_TYPE_POPUP_MENU, 42 | NET_WM_WINDOW_TYPE_TOOLTIP, 43 | NET_WM_WINDOW_TYPE_NOTIFICATION, 44 | NET_WM_WINDOW_TYPE_COMBO, 45 | NET_WM_WINDOW_TYPE_DND, 46 | NET_WM_WINDOW_TYPE_NORMAL, 47 | ATOM_LAST 48 | }; 49 | 50 | #define XCB_CALL(xwm, x) xcb_call(xwm, __PRETTY_FUNCTION__, __LINE__, x) 51 | bool xcb_call(struct wlc_xwm *xwm, const char *func, uint32_t line, xcb_void_cookie_t cookie); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/xwayland/xwayland.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XWAYLAND_H_ 2 | #define _WLC_XWAYLAND_H_ 3 | 4 | #include 5 | 6 | #ifdef ENABLE_XWAYLAND 7 | 8 | struct wl_client* wlc_xwayland_get_client(void); 9 | int wlc_xwayland_get_fd(void); 10 | bool wlc_xwayland_init(void); 11 | void wlc_xwayland_terminate(void); 12 | 13 | #else 14 | 15 | static inline bool 16 | wlc_xwayland_init(void) 17 | { 18 | return false; 19 | } 20 | 21 | static inline void 22 | wlc_xwayland_terminate(void) 23 | { 24 | } 25 | 26 | #endif 27 | 28 | #endif /* _WLC_XWAYLAND_H_ */ 29 | -------------------------------------------------------------------------------- /src/xwayland/xwm.h: -------------------------------------------------------------------------------- 1 | #ifndef _WLC_XWM_H_ 2 | #define _WLC_XWM_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include "compositor/seat/seat.h" 10 | #include "resources/types/data-source.h" 11 | #include "resources/types/surface.h" 12 | 13 | enum wlc_view_state_bit; 14 | 15 | #ifdef ENABLE_XWAYLAND 16 | #include 17 | 18 | struct wlc_x11_window { 19 | uint32_t id; // xcb_window_t 20 | uint32_t surface_id; 21 | struct wlc_xwm *xwm; 22 | bool override_redirect; 23 | bool has_utf8_title; 24 | bool has_delete_window; 25 | bool has_alpha; 26 | bool hidden; // HACK: used by output.c to hide invisible windows 27 | bool paired; // is this window paired to wlc_view? 28 | }; 29 | 30 | WLC_NONULL static inline bool 31 | wlc_x11_is_valid_window(struct wlc_x11_window *w) 32 | { 33 | return w->id; 34 | } 35 | 36 | WLC_NONULL static inline bool 37 | wlc_x11_is_window_hidden(struct wlc_x11_window *w) 38 | { 39 | return w->hidden; 40 | } 41 | 42 | WLC_NONULL static inline void 43 | wlc_x11_set_window_hidden(struct wlc_x11_window *w, bool hidden) 44 | { 45 | w->hidden = hidden; 46 | } 47 | 48 | struct wlc_xwm_selection { 49 | xcb_window_t clipboard_owner; 50 | xcb_window_t data_requestor; 51 | xcb_atom_t data_request_property; 52 | xcb_atom_t data_request_target; 53 | struct wl_listener listener; 54 | const xcb_query_extension_reply_t *xfixes; 55 | struct wlc_data_source data_source; 56 | struct wl_event_source *data_event_source; 57 | int send_fd; 58 | const char *send_type; 59 | int recv_fd; 60 | }; 61 | 62 | struct wlc_xwm { 63 | struct wl_event_source *event_source; 64 | struct chck_hash_table paired, unpaired; 65 | struct wlc_seat *seat; 66 | struct wlc_xwm_selection selection; 67 | 68 | xcb_connection_t *connection; 69 | xcb_screen_t *screen; 70 | 71 | xcb_atom_t atoms[200]; // XXX 72 | xcb_window_t window, focus; 73 | xcb_cursor_t cursor; 74 | 75 | struct { 76 | struct wl_listener surface; 77 | } listener; 78 | }; 79 | 80 | WLC_NONULL void wlc_x11_window_set_surface_format(struct wlc_surface *surface, struct wlc_x11_window *win); 81 | WLC_NONULL void wlc_x11_window_configure(struct wlc_x11_window *win, const struct wlc_geometry *g); 82 | WLC_NONULL void wlc_x11_window_set_state(struct wlc_x11_window *win, enum wlc_view_state_bit state, bool toggle); 83 | WLC_NONULL bool wlc_x11_window_set_active(struct wlc_x11_window *win, bool active); 84 | WLC_NONULL void wlc_x11_window_close(struct wlc_x11_window *win); 85 | 86 | WLC_NONULL bool wlc_xwm(struct wlc_xwm *xwm, struct wlc_seat *seat); 87 | void wlc_xwm_release(struct wlc_xwm *xwm); 88 | 89 | WLC_NONULL bool wlc_xwm_selection_init(struct wlc_xwm *xwm); 90 | WLC_NONULL void wlc_xwm_selection_release(struct wlc_xwm *xwm); 91 | WLC_NONULL bool wlc_xwm_selection_handle_event(struct wlc_xwm *xwm, xcb_generic_event_t *event); 92 | 93 | #else /* !ENABLE_XWAYLAND */ 94 | 95 | struct wlc_x11_window {}; 96 | struct wlc_xwm {}; 97 | 98 | WLC_NONULL static inline bool 99 | wlc_x11_is_valid_window(struct wlc_x11_window *w) 100 | { 101 | (void)w; 102 | return false; 103 | } 104 | 105 | WLC_NONULL static inline bool 106 | wlc_x11_is_window_hidden(struct wlc_x11_window *w) 107 | { 108 | (void)w; 109 | return false; 110 | } 111 | 112 | WLC_NONULL static inline void 113 | wlc_x11_set_window_hidden(struct wlc_x11_window *w, bool hidden) 114 | { 115 | (void)w; 116 | (void)hidden; 117 | } 118 | 119 | WLC_NONULL static inline void 120 | wlc_x11_window_set_surface_format(struct wlc_surface *surface, struct wlc_x11_window *win) 121 | { 122 | (void)surface; 123 | (void)win; 124 | } 125 | 126 | WLC_NONULL static inline void 127 | wlc_x11_window_configure(struct wlc_x11_window *win, const struct wlc_geometry *g) 128 | { 129 | (void)win; 130 | (void)g; 131 | } 132 | 133 | WLC_NONULL static inline void 134 | wlc_x11_window_set_state(struct wlc_x11_window *win, enum wlc_view_state_bit state, bool toggle) 135 | { 136 | (void)win; 137 | (void)state; 138 | (void)toggle; 139 | } 140 | 141 | WLC_NONULL static inline bool 142 | wlc_x11_window_set_active(struct wlc_x11_window *win, bool active) 143 | { 144 | (void)win; 145 | (void)active; 146 | return false; 147 | } 148 | 149 | WLC_NONULL static inline void 150 | wlc_x11_window_close(struct wlc_x11_window *win) 151 | { 152 | (void)win; 153 | } 154 | 155 | WLC_NONULL static inline bool 156 | wlc_xwm(struct wlc_xwm *xwm, struct wlc_seat *seat) 157 | { 158 | (void)xwm; 159 | (void)seat; 160 | return true; 161 | } 162 | 163 | static inline void 164 | wlc_xwm_release(struct wlc_xwm *xwm) 165 | { 166 | (void)xwm; 167 | } 168 | 169 | #endif /* ENABLE_XWAYLAND */ 170 | 171 | #endif /* _WLC_XWM_H_ */ 172 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(tests 2 | resources) 3 | 4 | # FIXME: disabling compositor tests until we have headless backend 5 | # wl-extension 6 | # fullscreen) 7 | 8 | include_directories( 9 | ${PROJECT_SOURCE_DIR}/src 10 | ${PROJECT_BINARY_DIR}/protos 11 | ${WAYLAND_SERVER_INCLUDE_DIRS} 12 | ${WAYLAND_CLIENT_INCLUDE_DIRS} 13 | ${XKBCOMMON_INCLUDE_DIRS} 14 | ${WLC_INCLUDE_DIRS} 15 | ${CHCK_INCLUDE_DIRS} 16 | ) 17 | foreach (test ${tests}) 18 | set_source_files_properties(${test}.c PROPERTIES COMPILE_FLAGS -DWLC_FILE="\\\"${test}.c\\\"") 19 | add_executable(${test}-test ${test}.c) 20 | target_link_libraries(${test}-test PRIVATE wlc-tests wlc-tests-protos ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES}) 21 | add_test_ex(${test}-test) 22 | endforeach() 23 | -------------------------------------------------------------------------------- /tests/fullscreen.c: -------------------------------------------------------------------------------- 1 | #include "client.h" 2 | 3 | static struct compositor_test compositor; 4 | static bool fullscreen_state_requested = false; 5 | static bool view_moved_to_output = false; 6 | 7 | static int 8 | client_main(void) 9 | { 10 | struct client_test client; 11 | client_test_create(&client, "fullscreen", 320, 320); 12 | surface_create(&client); 13 | shell_surface_create(&client); 14 | client_test_roundtrip(&client); 15 | client_test_roundtrip(&client); 16 | 17 | struct output *o; 18 | assert((o = chck_iter_pool_get(&client.outputs, 0))); 19 | wl_shell_surface_set_fullscreen(client.view.ssurface, 0, 0, o->output); 20 | wl_surface_commit(client.view.surface); 21 | while (wl_display_dispatch(client.display) != -1); 22 | return client_test_end(&client); 23 | } 24 | 25 | static void 26 | view_move_to_output(wlc_handle view, wlc_handle from_output, wlc_handle to_output) 27 | { 28 | (void)view; 29 | assert(from_output != to_output); 30 | view_moved_to_output = true; 31 | 32 | if (fullscreen_state_requested) 33 | signal_client(&compositor); 34 | 35 | } 36 | 37 | static void 38 | view_request_state(wlc_handle view, enum wlc_view_state_bit state, bool toggle) 39 | { 40 | (void)view; 41 | if (state == WLC_BIT_FULLSCREEN && toggle) 42 | fullscreen_state_requested = true; 43 | 44 | wlc_view_set_state(view, state, toggle); 45 | 46 | if (view_moved_to_output) 47 | signal_client(&compositor); 48 | } 49 | 50 | static void 51 | compositor_ready(void) 52 | { 53 | compositor_test_fork_client(&compositor, client_main); 54 | } 55 | 56 | static int 57 | compositor_main(void) 58 | { 59 | wlc_set_view_move_to_output_cb(view_move_to_output); 60 | wlc_set_view_request_state_cb(view_request_state); 61 | wlc_set_compositor_ready_cb(compositor_ready); 62 | 63 | // This causes nouveau to hang at quit. 64 | // Comment out until headless backend is added. 65 | // setenv("WLC_OUTPUTS", "2", true); 66 | view_moved_to_output = true; 67 | 68 | compositor_test_create(&compositor, "fullscreen"); 69 | wlc_run(); 70 | 71 | assert(fullscreen_state_requested); 72 | assert(view_moved_to_output); 73 | return compositor_test_end(&compositor); 74 | } 75 | 76 | int 77 | main(void) 78 | { 79 | return compositor_main(); 80 | } 81 | -------------------------------------------------------------------------------- /tests/resources.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "resources/resources.h" 4 | 5 | #undef NDEBUG 6 | #include 7 | 8 | static bool constructor_called = false; 9 | static bool destructor_called = false; 10 | 11 | static void 12 | destructor(void *ptr) 13 | { 14 | assert(ptr); 15 | destructor_called = true; 16 | } 17 | 18 | static bool 19 | constructor(void *ptr) 20 | { 21 | assert(ptr); 22 | return (constructor_called = true); 23 | } 24 | 25 | struct contains_source { 26 | uint8_t padding[3]; 27 | struct wlc_source source; 28 | uint8_t padding2[3]; 29 | }; 30 | 31 | static void 32 | destructor2(struct contains_source *ptr) 33 | { 34 | assert(ptr); 35 | wlc_source_release(&ptr->source); 36 | } 37 | 38 | static bool 39 | constructor2(struct contains_source *ptr) 40 | { 41 | assert(ptr); 42 | assert(wlc_source(&ptr->source, "test2", constructor, destructor, 1, sizeof(struct wlc_resource))); 43 | return true; 44 | } 45 | 46 | int 47 | main(void) 48 | { 49 | // TEST: Basic source and handle creation 50 | { 51 | assert(wlc_resources_init()); 52 | 53 | struct wlc_source source; 54 | assert(wlc_source(&source, "test", constructor, destructor, 1, sizeof(struct wlc_resource))); 55 | 56 | struct wlc_resource *ptr; 57 | assert(!constructor_called); 58 | assert((ptr = wlc_handle_create(&source))); 59 | assert(constructor_called); 60 | assert(source.pool.items.count == 1); 61 | 62 | wlc_handle handle; 63 | #pragma GCC diagnostic ignored "-Wpointer-arith" 64 | assert(!convert_to_wlc_handle(NULL)); 65 | #pragma GCC diagnostic warning "-Wpointer-arith" 66 | assert((handle = convert_to_wlc_handle(ptr))); 67 | assert(!convert_from_wlc_handle(handle, "invalid")); 68 | assert(convert_from_wlc_handle(handle, "test") == ptr); 69 | 70 | const char *test = "foobar"; 71 | wlc_handle_set_user_data(handle, test); 72 | assert(wlc_handle_get_user_data(handle) == test); 73 | 74 | assert(!destructor_called); 75 | wlc_handle_release(handle); 76 | assert(destructor_called); 77 | assert(!convert_from_wlc_handle(handle, "invalid")); 78 | assert(!convert_from_wlc_handle(handle, "test")); 79 | assert(!wlc_handle_get_user_data(handle)); 80 | assert(source.pool.items.count == 0); 81 | 82 | wlc_source_release(&source); 83 | wlc_resources_terminate(); 84 | } 85 | 86 | // TEST: Handle invalidation on source release 87 | { 88 | assert(wlc_resources_init()); 89 | 90 | struct wlc_source source; 91 | assert(wlc_source(&source, "test", constructor, destructor, 1, sizeof(struct wlc_resource))); 92 | 93 | struct wlc_resource *ptr; 94 | assert((ptr = wlc_handle_create(&source))); 95 | assert(source.pool.items.count == 1); 96 | 97 | wlc_handle handle; 98 | assert((handle = convert_to_wlc_handle(ptr))); 99 | 100 | assert(!(destructor_called = false)); 101 | wlc_source_release(&source); 102 | assert(destructor_called); 103 | 104 | assert(source.pool.items.count == 0); 105 | assert(!convert_from_wlc_handle(handle, "test")); 106 | 107 | wlc_resources_terminate(); 108 | } 109 | 110 | // TEST: Handle invalidation on resources termination 111 | { 112 | assert(wlc_resources_init()); 113 | 114 | struct wlc_source source; 115 | assert(wlc_source(&source, "test", constructor, destructor, 1, sizeof(struct wlc_resource))); 116 | 117 | struct wlc_resource *ptr; 118 | assert((ptr = wlc_handle_create(&source))); 119 | assert(source.pool.items.count == 1); 120 | 121 | wlc_handle handle; 122 | assert((handle = convert_to_wlc_handle(ptr))); 123 | 124 | assert(!(destructor_called = false)); 125 | wlc_resources_terminate(); 126 | assert(destructor_called); 127 | 128 | assert(!convert_from_wlc_handle(handle, "test")); 129 | wlc_source_release(&source); 130 | } 131 | 132 | // TEST: Relocation of source inside container of handle, when the handle's source changes location 133 | { 134 | assert(wlc_resources_init()); 135 | 136 | struct wlc_source source; 137 | assert(wlc_source(&source, "test", constructor2, destructor2, 1, sizeof(struct contains_source))); 138 | 139 | struct contains_source *ptr; 140 | assert((ptr = wlc_handle_create(&source))); 141 | assert(source.pool.items.count == 1); 142 | void *original_source = &ptr->source; 143 | 144 | wlc_handle handle; 145 | assert((handle = convert_to_wlc_handle(ptr))); 146 | 147 | struct wlc_resource *ptr2; 148 | assert((ptr2 = wlc_handle_create(&ptr->source))); 149 | 150 | wlc_handle handle2; 151 | assert((handle2 = convert_to_wlc_handle(ptr2))); 152 | assert(convert_from_wlc_handle(handle2, "test2") == ptr2); 153 | 154 | // Play with heap until realloc does not return linear memory anymore 155 | { 156 | void *original = source.pool.items.buffer; 157 | do { 158 | void *garbage; 159 | assert((garbage = malloc(1024))); 160 | assert(wlc_handle_create(&source)); 161 | free(garbage); 162 | } while (original == source.pool.items.buffer); 163 | } 164 | 165 | // So this should be true 166 | assert(ptr = convert_from_wlc_handle(handle, "test")); 167 | assert(original_source != &ptr->source); 168 | 169 | wlc_resources_terminate(); 170 | 171 | assert(!convert_from_wlc_handle(handle2, "test2")); 172 | wlc_source_release(&source); 173 | } 174 | 175 | // TEST: Benchmark (many insertions, and removal expanding from center) 176 | { 177 | assert(wlc_resources_init()); 178 | 179 | struct container { 180 | wlc_handle self; 181 | }; 182 | 183 | struct wlc_source source; 184 | assert(wlc_source(&source, "test", constructor, destructor, 1024, sizeof(struct container))); 185 | 186 | wlc_handle first = 0; 187 | const uint32_t iters = 0xFFFFF; 188 | for (uint32_t i = 0; i < iters; ++i) { 189 | struct container *ptr = wlc_handle_create(&source); 190 | ptr->self = convert_to_wlc_handle(ptr); 191 | if (!first) first = ptr->self; 192 | assert(convert_from_wlc_handle(first, "test")); 193 | } 194 | assert(source.pool.items.count == iters); 195 | 196 | for (uint32_t i = iters / 2, d = iters / 2; i < iters; ++i, --d) { 197 | assert(((struct container*)convert_from_wlc_handle(i + 1, "test"))->self == i + 1); 198 | assert(((struct container*)convert_from_wlc_handle(d + 1, "test"))->self == d + 1); 199 | wlc_handle_release(i + 1); 200 | wlc_handle_release(d + 1); 201 | } 202 | assert(source.pool.items.count == 0); 203 | 204 | assert(!convert_from_wlc_handle(first, "test")); 205 | wlc_source_release(&source); 206 | wlc_resources_terminate(); 207 | } 208 | 209 | // TODO: Needs test for wlc_resource. 210 | // For this we need to start compositor and some clients, or dummy the wl_resource struct. 211 | // (Latter probably better) 212 | 213 | return EXIT_SUCCESS; 214 | } 215 | -------------------------------------------------------------------------------- /tests/wl-extension.c: -------------------------------------------------------------------------------- 1 | #include "wayland-test-extension-client-protocol.h" 2 | #include "client.h" 3 | #include 4 | #include 5 | #include "wayland-test-extension-server-protocol.h" 6 | 7 | static struct compositor_test compositor; 8 | static bool background_was_set = false; 9 | static bool background_was_rendered = true; 10 | 11 | static int 12 | client_main(void) 13 | { 14 | struct client_test client; 15 | client_test_create(&client, "wl-extension", 320, 320); 16 | surface_create(&client); 17 | client_test_roundtrip(&client); 18 | struct output *o; 19 | assert((o = chck_iter_pool_get(&client.outputs, 0))); 20 | background_set_background(client.background, o->output, client.view.surface); 21 | while (wl_display_dispatch(client.display) != -1); 22 | return client_test_end(&client); 23 | } 24 | 25 | static void 26 | set_background(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output, struct wl_resource *surface) 27 | { 28 | (void)client, (void)resource; 29 | assert(wlc_handle_from_wl_output_resource(output)); 30 | assert(wlc_resource_from_wl_surface_resource(surface)); 31 | wlc_handle_set_user_data(wlc_handle_from_wl_output_resource(output), (void*)wlc_resource_from_wl_surface_resource(surface)); 32 | background_was_set = true; 33 | } 34 | 35 | static struct background_interface background_implementation = { 36 | .set_background = set_background, 37 | }; 38 | 39 | static void 40 | background_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id) 41 | { 42 | (void)data; 43 | 44 | if (version > 1) { 45 | // Unsupported version 46 | return; 47 | } 48 | 49 | struct wl_resource *resource; 50 | if (!(resource = wl_resource_create(client, &background_interface, version, id))) { 51 | wl_client_post_no_memory(client); 52 | return; 53 | } 54 | 55 | wl_resource_set_implementation(resource, &background_implementation, NULL, NULL); 56 | } 57 | 58 | static void 59 | output_render_pre(wlc_handle output) 60 | { 61 | wlc_resource surface; 62 | if (!(surface = (wlc_resource)wlc_handle_get_user_data(output))) 63 | return; 64 | 65 | wlc_surface_render(surface, &(struct wlc_geometry){ wlc_origin_zero, *wlc_output_get_resolution(output) }); 66 | 67 | background_was_rendered = true; 68 | signal_client(&compositor); 69 | } 70 | 71 | static void 72 | compositor_ready(void) 73 | { 74 | // XXX: This is broken. 75 | // We can't use fork due to it inherting internal timerfd's 76 | // and causing havok. If we want to use fork for simplicity 77 | // we need to do that in main for both client / compositor 78 | // and signal with signalfd for example. 79 | compositor_test_fork_client(&compositor, client_main); 80 | } 81 | 82 | static int 83 | compositor_main(void) 84 | { 85 | wlc_set_output_render_pre_cb(output_render_pre); 86 | wlc_set_compositor_ready_cb(compositor_ready); 87 | 88 | compositor_test_create(&compositor, "wl-extension"); 89 | 90 | if (!wl_global_create(wlc_get_wl_display(), &background_interface, 1, NULL, background_bind)) 91 | return EXIT_FAILURE; 92 | 93 | wlc_run(); 94 | assert(background_was_set); 95 | return compositor_test_end(&compositor); 96 | } 97 | 98 | int 99 | main(void) 100 | { 101 | return compositor_main(); 102 | } 103 | -------------------------------------------------------------------------------- /uncrustify.conf: -------------------------------------------------------------------------------- 1 | # Uncrustify 0.61 2 | # Generated from wlc source 3 | newlines = lf 4 | tok_split_gte = false 5 | utf8_bom = remove 6 | utf8_force = true 7 | indent_columns = 3 8 | indent_with_tabs = 0 9 | indent_braces = false 10 | indent_braces_no_func = false 11 | indent_braces_no_struct = false 12 | indent_brace_parent = false 13 | indent_else_if = false 14 | indent_var_def_cont = false 15 | indent_func_def_force_col1 = false 16 | indent_func_call_param = false 17 | indent_func_def_param = false 18 | indent_func_proto_param = false 19 | indent_func_param_double = false 20 | indent_relative_single_line_comments = false 21 | indent_switch_case = indent_columns 22 | indent_col1_comment = true 23 | indent_label = 1 24 | indent_access_spec = 1 25 | indent_access_spec_body = false 26 | indent_paren_nl = false 27 | indent_comma_paren = false 28 | indent_bool_paren = false 29 | indent_first_bool_expr = false 30 | indent_square_nl = false 31 | indent_preserve_sql = false 32 | indent_align_assign = true 33 | sp_arith = force 34 | sp_assign = force 35 | sp_assign_default = force 36 | sp_before_assign = force 37 | sp_after_assign = force 38 | sp_enum_assign = force 39 | sp_pp_concat = ignore 40 | sp_bool = force 41 | sp_compare = force 42 | sp_inside_paren = remove 43 | sp_paren_paren = remove 44 | sp_paren_brace = remove 45 | sp_before_ptr_star = force 46 | sp_before_unnamed_ptr_star = remove 47 | sp_between_ptr_star = remove 48 | sp_after_ptr_star = remove 49 | sp_after_ptr_star_func = force 50 | sp_after_type = force 51 | sp_before_sparen = force 52 | sp_inside_sparen = remove 53 | sp_after_sparen = force 54 | sp_sparen_brace = force 55 | sp_before_semi = remove 56 | sp_before_semi_for = remove 57 | sp_after_semi = add 58 | sp_after_semi_for = force 59 | sp_before_square = remove 60 | sp_before_squares = remove 61 | sp_inside_square = remove 62 | sp_after_comma = force 63 | sp_before_comma = remove 64 | sp_paren_comma = force 65 | sp_before_case_colon = remove 66 | # buggy with (type){ ... } 67 | # sp_after_cast = remove 68 | sp_inside_paren_cast = remove 69 | sp_sizeof_paren = remove 70 | sp_inside_braces = ignore 71 | sp_inside_braces_empty = remove 72 | sp_type_func = force 73 | sp_func_proto_paren = remove 74 | sp_func_def_paren = remove 75 | sp_inside_fparens = remove 76 | sp_inside_fparen = remove 77 | sp_func_call_paren = remove 78 | sp_func_call_paren_empty = remove 79 | sp_attribute_paren = remove 80 | sp_defined_paren = remove 81 | sp_else_brace = force 82 | sp_brace_else = force 83 | sp_word_brace = add 84 | sp_word_brace_ns = add 85 | sp_before_nl_cont = add 86 | sp_cond_colon = force 87 | sp_cond_question = force 88 | sp_cond_ternary_short = remove 89 | sp_cmt_cpp_start = add 90 | align_keep_tabs = false 91 | align_with_tabs = false 92 | align_on_tabstop = false 93 | align_number_left = false 94 | align_keep_extra_space = false 95 | align_func_params = false 96 | align_same_func_call_params = false 97 | nl_assign_leave_one_liners = true 98 | nl_start_of_file = remove 99 | nl_end_of_file = force 100 | nl_end_of_file_min = 1 101 | nl_fcall_brace = remove 102 | nl_enum_brace = remove 103 | nl_struct_brace = remove 104 | nl_union_brace = remove 105 | nl_if_brace = remove 106 | nl_brace_else = remove 107 | nl_elseif_brace = remove 108 | nl_else_brace = remove 109 | nl_else_if = remove 110 | nl_for_brace = remove 111 | nl_while_brace = remove 112 | nl_do_brace = remove 113 | nl_brace_while = remove 114 | nl_switch_brace = remove 115 | nl_multi_line_cond = false 116 | nl_multi_line_define = false 117 | nl_before_case = false 118 | nl_after_case = false 119 | nl_case_colon_brace = force 120 | nl_func_type_name = force 121 | nl_func_proto_type_name = remove 122 | nl_func_paren = remove 123 | nl_func_def_paren = remove 124 | nl_func_decl_start = remove 125 | nl_func_def_start = remove 126 | nl_func_decl_args = remove 127 | nl_func_def_args = remove 128 | nl_func_decl_end = remove 129 | nl_func_def_end = remove 130 | nl_func_decl_empty = remove 131 | nl_func_def_empty = remove 132 | nl_fdef_brace = force 133 | nl_return_expr = remove 134 | nl_after_semicolon = remove 135 | nl_max = 2 136 | nl_before_block_comment = 1 137 | nl_before_c_comment = 1 138 | nl_before_cpp_comment = 1 139 | nl_after_struct = 1 140 | eat_blanks_after_open_brace = true 141 | eat_blanks_before_close_brace = true 142 | mod_full_brace_do = force 143 | mod_remove_extra_semicolon = true 144 | mod_case_brace = remove 145 | mod_remove_empty_return = true 146 | cmt_convert_tab_to_spaces = true 147 | cmt_star_cont = true 148 | --------------------------------------------------------------------------------