Skip to content

Commit

Permalink
Wayland support in VSTGUI
Browse files Browse the repository at this point in the history
  • Loading branch information
jwolffpsl committed Nov 22, 2023
1 parent fb7060c commit 34aa8da
Show file tree
Hide file tree
Showing 15 changed files with 1,864 additions and 36 deletions.
120 changes: 120 additions & 0 deletions vstgui/cmake/modules/FindWayland.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# This file is part of VSTGUI. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
# Originally written and contributed to VSTGUI by PreSonus Software Ltd.

include_guard (GLOBAL)

find_package (PkgConfig)
pkg_check_modules (PKG_WAYLAND QUIET wayland-client)

set (WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})

# Find wayland libraries / includes
# When cross-compiling, these libraries and headers need to be found for the target architecture.
find_path (WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS} ONLY_CMAKE_FIND_ROOT_PATH)
mark_as_advanced (WAYLAND_CLIENT_INCLUDE_DIR)

if ("client" IN_LIST Wayland_FIND_COMPONENTS)
find_library (WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
find_library (WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
endif ()

if ("egl" IN_LIST Wayland_FIND_COMPONENTS)
find_library (WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
endif ()

if ("server" IN_LIST Wayland_FIND_COMPONENTS)
find_library (WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
endif ()

if ("protocols" IN_LIST Wayland_FIND_COMPONENTS)

# Find wayland-scanner
find_program (WAYLAND_SCANNER NAMES "wayland-scanner")
if (NOT WAYLAND_SCANNER)
find_program (WAYLAND_SCANNER NAMES wayland-scanner)
endif ()
mark_as_advanced (WAYLAND_SCANNER)

# Generate extra protocol headers

find_path (XDG_DIR NAMES "stable/xdg-shell/xdg-shell.xml" HINTS "/usr/share/wayland-protocols")
mark_as_advanced (XDG_DIR)

set (protocols
"stable/xdg-shell/xdg-shell.xml"
#"staging/xdg-activation/xdg-activation-v1.xml"
#"unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
#"unstable/xdg-foreign/xdg-foreign-unstable-v1.xml"
#"unstable/xdg-foreign/xdg-foreign-unstable-v2.xml"
#"unstable/text-input/text-input-unstable-v3.xml"
)

set (WAYLAND_PROTOCOLS_DIR "${CMAKE_BINARY_DIR}/wayland-protocols" CACHE PATH "Directory for generated wayland protocol headers and source files")
file (MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR})

foreach (protocol ${protocols})

get_filename_component (protocol_name "${protocol}" NAME_WLE)

# Generate client header
set (header "${WAYLAND_PROTOCOLS_DIR}/${protocol_name}-client-protocol.h")
if (NOT EXISTS "${XDG_DIR}/${protocol}")
message (WARNING "Unknown Wayland protocol: ${protocol_name}")
file (WRITE "${header}" "")
continue ()
endif ()

add_custom_command (OUTPUT ${header}
COMMAND /bin/sh -c "${WAYLAND_SCANNER} client-header < ${XDG_DIR}/${protocol} > \"${header}\""
DEPENDS ${XDG_DIR}/${protocol}
VERBATIM USES_TERMINAL
)
list (APPEND protocol_headers ${header})

# Generate server header
set (header "${WAYLAND_PROTOCOLS_DIR}/${protocol_name}-server-protocol.h")

add_custom_command (OUTPUT ${header}
COMMAND /bin/sh -c "${WAYLAND_SCANNER} server-header < ${XDG_DIR}/${protocol} > \"${header}\""
DEPENDS ${XDG_DIR}/${protocol}
VERBATIM USES_TERMINAL
)
list (APPEND protocol_headers ${header})

# Generate source file
set (sourcefile "${WAYLAND_PROTOCOLS_DIR}/${protocol_name}-protocol.c")
add_custom_command (OUTPUT ${sourcefile}
COMMAND /bin/sh -c "${WAYLAND_SCANNER} private-code < ${XDG_DIR}/${protocol} > \"${sourcefile}\""
DEPENDS ${XDG_DIR}/${protocol}
VERBATIM USES_TERMINAL
)
list (APPEND protocol_source_files "${sourcefile}")
endforeach ()

add_library (wayland_protocols OBJECT ${protocol_headers} ${protocol_source_files} ${CMAKE_CURRENT_LIST_FILE})

set_target_properties (wayland_protocols PROPERTIES
USE_FOLDERS ON
FOLDER libs
)

endif ()

# Set result variables
set (WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES})

set (WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_PROTOCOLS_DIR})
list (REMOVE_DUPLICATES WAYLAND_INCLUDE_DIRS)

if (TARGET wayland_protocols)
list (APPEND WAYLAND_LIBRARIES wayland_protocols)
target_include_directories (wayland_protocols PUBLIC ${WAYLAND_INCLUDE_DIRS})
endif ()

include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (Wayland
FOUND_VAR WAYLAND_FOUND
REQUIRED_VARS WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIRS
)
15 changes: 14 additions & 1 deletion vstgui/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ set(${target}_common_sources
platform/platform_macos.h
platform/platform_win32.h
platform/platform_x11.h
platform/platform_wayland.h
platform/std_unorderedmap.h
platform/common/fileresourceinputstream.cpp
platform/common/fileresourceinputstream.h
Expand Down Expand Up @@ -318,6 +319,12 @@ set(${target}_linux_sources
platform/linux/x11timer.h
platform/linux/x11utils.cpp
platform/linux/x11utils.h
platform/linux/waylandframe.cpp
platform/linux/waylandframe.h
platform/linux/waylandplatform.cpp
platform/linux/waylandplatform.h
platform/linux/waylandutils.cpp
platform/linux/waylandutils.h
platform/linux/linuxfactory.cpp
platform/linux/linuxfactory.h
)
Expand All @@ -336,11 +343,17 @@ endif()
# Linux
if(LINUX)
set(${target}_sources ${${target}_common_sources} ${${target}_linux_sources})

find_package (Wayland REQUIRED COMPONENTS client protocols)
endif()

##########################################################################################
add_library(${target} STATIC ${${target}_sources})

find_path (presonusinterfaces_dir NAMES ipslviewrendering.h HINTS ${SDK_ROOT}/presonus)

target_include_directories (${target} PRIVATE ${presonusinterfaces_dir} ${SDK_ROOT})

target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS})
vstgui_set_cxx_version(${target} 17)
vstgui_source_group_by_folder(${target})
Expand All @@ -352,7 +365,7 @@ if(LINUX)
target_include_directories(${target} PRIVATE ${CAIRO_INCLUDE_DIRS})
target_include_directories(${target} PRIVATE ${PANGO_INCLUDE_DIRS})
target_include_directories(${target} PRIVATE ${FONTCONFIG_INCLUDE_DIRS})
target_link_libraries(${target} PRIVATE ${LINUX_LIBRARIES})
target_link_libraries(${target} PRIVATE ${LINUX_LIBRARIES} ${WAYLAND_LIBRARIES})
endif()

if(CMAKE_HOST_APPLE)
Expand Down
28 changes: 14 additions & 14 deletions vstgui/lib/cframe.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This file is part of VSTGUI. It is subject to the license terms
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE

Expand Down Expand Up @@ -73,7 +73,7 @@ struct CFrame::Impl
CView* focusView {nullptr};
CView* activeFocusView {nullptr};
CollectInvalidRects* collectInvalidRects {nullptr};

ViewList mouseViews;
ModalViewSessionStack modalViewSessionStack;
DispatchList<CView*> windowActiveStateChangeViews;
Expand Down Expand Up @@ -121,9 +121,9 @@ struct CFrame::Impl
// CFrame Implementation
//-----------------------------------------------------------------------------
/*! @class CFrame
It creates a platform dependend view object.
It creates a platform dependend view object.
On Mac OS X it is a HIView or NSView.\n
On Mac OS X it is a HIView or NSView.\n
On Windows it's a WS_CHILD Window.
*/
Expand Down Expand Up @@ -156,7 +156,7 @@ void CFrame::beforeDelete ()
{
DebugPrint ("Warning: Scale Factor Changed Listeners are not cleaned up correctly.\n If you register a change listener you must also unregister it !\n");
}

if (!pImpl->mouseObservers.empty ())
{
DebugPrint ("Warning: Mouse Observers are not cleaned up correctly.\n If you register a mouse oberver you must also unregister it !\n");
Expand All @@ -175,10 +175,10 @@ void CFrame::beforeDelete ()
}

setViewFlag (kIsAttached, false);

delete pImpl;
pImpl = nullptr;

CViewContainer::beforeDelete ();
}

Expand All @@ -203,7 +203,7 @@ void CFrame::close ()
//-----------------------------------------------------------------------------
bool CFrame::open (void* systemWin, PlatformType systemWindowType, IPlatformFrameConfig* config)
{
if (!systemWin || isAttached ())
if ((!systemWin && systemWindowType != PlatformType::kWaylandSurface) || isAttached ())
return false;

pImpl->platformFrame = getPlatformFactory ().createFrame (this, getViewSize (), systemWin,
Expand All @@ -216,7 +216,7 @@ bool CFrame::open (void* systemWin, PlatformType systemWindowType, IPlatformFram
CollectInvalidRects cir (this);

attached (this);

setParentView (nullptr);

invalid ();
Expand All @@ -236,7 +236,7 @@ bool CFrame::attached (CView* parent)

for (const auto& pV : getChildren ())
pV->attached (this);

return true;
}
return false;
Expand Down Expand Up @@ -685,7 +685,7 @@ void CFrame::dispatchMouseUpEvent (MouseUpEvent& event)
{
auto transformedMousePosition = event.mousePosition;
getTransform ().inverse ().transform (transformedMousePosition);

auto f = finally ([this] () { setMouseDownView (nullptr); });

callMouseObserverOtherMouseEvent (event);
Expand Down Expand Up @@ -950,7 +950,7 @@ bool CFrame::setModalView (CView* pView)
endLegacyModalViewSession ();
else
pImpl->legacyModalViewSessionID = beginModalViewSession (pView);

return true;
}

Expand Down Expand Up @@ -1226,11 +1226,11 @@ void CFrame::setFocusView (CView *pView)
}
if (pImpl->focusView && pImpl->focusView->wantsFocus ())
pImpl->focusView->takeFocus ();

pImpl->focusViewObservers.forEach ([&] (IFocusViewObserver* observer) {
observer->onFocusViewChanged (this, pImpl->focusView, pOldFocusView);
});

recursion = false;
}

Expand Down
10 changes: 4 additions & 6 deletions vstgui/lib/platform/iplatformframecallback.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This file is part of VSTGUI. It is subject to the license terms
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE

Expand All @@ -20,6 +20,7 @@ enum class PlatformType : int32_t {
kHWNDTopLevel, // Windows HWDN Top Level (non child)
kX11EmbedWindowID, // X11 XID
kGdkWindow, // GdkWindow
kWaylandSurface, // Wayland Surface

kDefaultNative = -1
};
Expand All @@ -30,11 +31,8 @@ enum class PlatformType : int32_t {
class IPlatformFrameCallback
{
public:
virtual ~IPlatformFrameCallback () = default;
virtual bool platformDrawRect (CDrawContext* context, const CRect& rect) = 0;

virtual void platformDrawRects (const PlatformGraphicsDeviceContextPtr& context,
double scaleFactor, const std::vector<CRect>& rects) = 0;

virtual void platformOnEvent (Event& event) = 0;

virtual DragOperation platformOnDragEnter (DragEventData data) = 0;
Expand All @@ -44,7 +42,7 @@ class IPlatformFrameCallback

virtual void platformOnActivate (bool state) = 0;
virtual void platformOnWindowActivate (bool state) = 0;

virtual void platformScaleFactorChanged (double newScaleFactor) = 0;

#if VSTGUI_TOUCH_EVENT_HANDLING
Expand Down
5 changes: 5 additions & 0 deletions vstgui/lib/platform/linux/linuxfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "cairogradient.h"
#include "cairographicscontext.h"
#include "x11frame.h"
#include "waylandframe.h"
#include "../iplatformframecallback.h"
#include "../common/fileresourceinputstream.h"
#include "../iplatformresourceinputstream.h"
Expand Down Expand Up @@ -95,6 +96,10 @@ PlatformFramePtr LinuxFactory::createFrame (IPlatformFrameCallback* frame, const
auto x11Parent = reinterpret_cast<XID> (parent);
return makeOwned<X11::Frame> (frame, size, x11Parent, config);
}
else if (parentType == PlatformType::kWaylandSurface)
{
return makeOwned<Wayland::Frame> (frame, size, config);
}
return nullptr;
}

Expand Down
Loading

0 comments on commit 34aa8da

Please sign in to comment.