diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,6 +275,12 @@ ) set(HAVE_LIBCAP ${Libcap_FOUND}) +find_package(epoll) +set_package_properties(epoll PROPERTIES DESCRIPTION "I/O event notification facility" + TYPE OPTIONAL + PURPOSE "Needed for running kwin_wayland" +) + include(ECMQMLModules) ecm_find_qmlmodule(QtQuick 2.3) ecm_find_qmlmodule(QtQuick.Controls 1.2) @@ -341,6 +347,7 @@ add_feature_info("linux/vt.h" HAVE_LINUX_VT_H "Required for virtual terminal support under wayland") + check_include_file("linux/fb.h" HAVE_LINUX_FB_H) add_feature_info("linux/fb.h" HAVE_LINUX_FB_H @@ -518,7 +525,7 @@ ) endif() -if (HAVE_LINUX_VT_H) +if (HAVE_LINUX_VT_H OR HAVE_epoll) set(kwin_KDEINIT_SRCS ${kwin_KDEINIT_SRCS} virtual_terminal.cpp @@ -633,6 +640,13 @@ target_link_libraries(kwin kwinglutils ${epoxy_LIBRARY}) +if (epoll_FOUND) + # Link against epoll if it is provided by a library rather than the kernel + if (epoll_LIBRARIES) + target_link_libraries(kwin ${kwinLibs} ${epoll_LIBRARIES}) + endif() +endif() + kf5_add_kdeinit_executable(kwin_x11 main_x11.cpp) target_link_libraries(kdeinit_kwin_x11 kwin KF5::Crash Qt5::X11Extras) diff --git a/cmake/modules/Findepoll.cmake b/cmake/modules/Findepoll.cmake new file mode 100644 --- /dev/null +++ b/cmake/modules/Findepoll.cmake @@ -0,0 +1,78 @@ +#.rest: +# FindEpoll +# -------------- +# +# Try to find epoll or epoll-shim on this system. This finds: +# - some shim on Unix like systems (FreeBSD), or +# - the kernel's epoll on Linux systems. +# +# This will define the following variables: +# +# ``epoll_FOUND`` +# True if epoll is available +# ``epoll_LIBRARIES`` +# This has to be passed to target_link_libraries() +# ``epoll_INCLUDE_DIRS`` +# This has to be passed to target_include_directories() +# +# On Linux, the libraries and include directories are empty, +# even though epoll_FOUND may be set to TRUE. This is because +# no special includes or libraries are needed. On other systems +# these may be needed to use epoll. + +#============================================================================= +# Copyright 2019 Tobias C. Berner +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +find_path(epoll_INCLUDE_DIRS sys/epoll.h PATH_SUFFIXES libepoll-shim) + +if(epoll_INCLUDE_DIRS) +# On Linux there is no library to link against, on the BSDs there is. +# On the BSD's, epoll is implemented through a library, libepoll-shim. + if( CMAKE_SYSTEM_NAME MATCHES "Linux") + set(epoll_FOUND TRUE) + set(epoll_LIBRARIES "") + set(epoll_INCLUDE_DIRS "") + else() + find_library(epoll_LIBRARIES NAMES epoll-shim) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(epoll + FOUND_VAR + epoll_FOUND + REQUIRED_VARS + epoll_LIBRARIES + epoll_INCLUDE_DIRS + ) + mark_as_advanced(epoll_LIBRARIES epoll_INCLUDE_DIRS) + include(FeatureSummary) + set_package_properties(epoll PROPERTIES + URL "https://github.com/FreeBSDDesktop/epoll-shim" + DESCRIPTION "small epoll implementation using kqueue" + ) + endif() +else() + set(epoll_FOUND FALSE) +endif() + +mark_as_advanced(epoll_LIBRARIES epoll_INCLUDE_DIRS) diff --git a/udev.cpp b/udev.cpp --- a/udev.cpp +++ b/udev.cpp @@ -139,6 +139,9 @@ if (!m_udev) { return UdevDevice::Ptr(); } +#if defined(Q_OS_FREEBSD) + return deviceFromSyspath("/dev/dri/card0"); +#else UdevEnumerate enumerate(this); enumerate.addMatch(UdevEnumerate::Match::SubSystem, "drm"); enumerate.addMatch(UdevEnumerate::Match::SysName, "card[0-9]*"); @@ -154,6 +157,7 @@ } return false; }); +#endif } UdevDevice::Ptr Udev::virtualGpu() diff --git a/virtual_terminal.cpp b/virtual_terminal.cpp --- a/virtual_terminal.cpp +++ b/virtual_terminal.cpp @@ -25,18 +25,23 @@ // Qt #include #include +#if defined(Q_OS_LINUX) // linux #include #include #include +#include +#elif defined(Q_OS_FREEBSD) +// FreeBSD +#include +#endif // system #include #include #include #include #include #include -#include #define RELEASE_SIGNAL SIGUSR1 #define ACQUISITION_SIGNAL SIGUSR2 @@ -80,9 +85,11 @@ if (fstat(fd, &st) == -1) { return false; } +#if defined(Q_OS_LINUX) if (major(st.st_rdev) != TTY_MAJOR || minor (st.st_rdev) <= 0 || minor(st.st_rdev) >= 64) { return false; } +#endif return true; } @@ -95,7 +102,11 @@ // error condition return; } +#if defined(Q_OS_FREEBSD) + QString ttyName = QStringLiteral("/dev/ttyv%1").arg(vtNr); +#else QString ttyName = QStringLiteral("/dev/tty%1").arg(vtNr); +#endif m_vt = open(ttyName.toUtf8().constData(), O_RDWR|O_CLOEXEC|O_NONBLOCK); if (m_vt < 0) {