diff --git a/CMakeLists.txt b/CMakeLists.txt index 61f4ee2c15..badb492beb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1366,21 +1366,12 @@ status("") status(" GUI: " "${OPENCV_HIGHGUI_BUILTIN_BACKEND}") if(WITH_WAYLAND OR HAVE_WAYLAND) - if(HAVE_WAYLAND_CLIENT) - status(" Wayland Client:" "YES (ver ${WAYLAND_CLIENT_VERSION})") - endif() - if(HAVE_WAYLAND_CURSOR) - status(" Wayland Cursor:" "YES (ver ${WAYLAND_CURSOR_VERSION})") - endif() - if(HAVE_WAYLAND_PROTOCOL) - status(" Wayland Protocol:" "YES (ver ${WAYLAND_PROTOCOL_VERSION})") - endif() - if(HAVE_WAYLAND_EGL) - status(" Wayland EGL:" "YES (ver ${WAYLAND_EGL_VERSION})") - endif() - if(HAVE_XKBCOMMON) - status(" Xkbcommon:" "YES (ver ${XKBCOMMON_VERSION})") - endif() + status(" Wayland:" HAVE_WAYLAND THEN "(Experimental) YES" ELSE "NO") + status(" Wayland Client:" HAVE_WAYLAND_CLIENT THEN "YES (ver ${WAYLAND_CLIENT_VERSION})" ELSE "NO") + status(" Wayland Cursor:" HAVE_WAYLAND_CURSOR THEN "YES (ver ${WAYLAND_CURSOR_VERSION})" ELSE "NO") + status(" Wayland Protocols:" HAVE_WAYLAND_PROTOCOLS THEN "YES (ver ${WAYLAND_PROTOCOLS_VERSION})" ELSE "NO") + status(" Xkbcommon:" HAVE_XKBCOMMON THEN "YES (ver ${XKBCOMMON_VERSION})" ELSE "NO") + status(" Wayland EGL(Option):" HAVE_WAYLAND_EGL THEN "YES (ver ${WAYLAND_EGL_VERSION})" ELSE "NO") endif() if(WITH_QT OR HAVE_QT) diff --git a/doc/tutorials/app/highgui_wayland_ubuntu.markdown b/doc/tutorials/app/highgui_wayland_ubuntu.markdown new file mode 100644 index 0000000000..2b8020ad19 --- /dev/null +++ b/doc/tutorials/app/highgui_wayland_ubuntu.markdown @@ -0,0 +1,106 @@ +Using Wayland highgui-backend in Ubuntu {#tutorial_wayland_ubuntu} +======================================= + +@tableofcontents + +@prev_tutorial{tutorial_intelperc} + +| | | +| -: | :- | +| Original author | Kumataro | +| Compatibility | OpenCV >= 4.10 | +| ^ | Ubuntu 24.04 | + +Goal +----- +This tutorial is to use Wayland highgui-backend in Ubuntu 24.04. + +Wayland highgui-backend is experimental implementation. + +Setup +----- +- Setup Ubuntu 24.04. +- `sudo apt install build-essential git cmake` to build OpenCV. +- `sudo apt install libwayland-dev wayland-protocols libxkbcommon-dev` to enable Wayland highgui-backend. +- (Option) `sudo apt install ninja-build` (or remove `-GNinja` option for cmake command). +- (Option) `sudo apt install libwayland-egl1` to enable Wayland EGL library. + +Get OpenCV from GitHub +---------------------- + +```bash +mkdir work +cd work +git clone --depth=1 https://github.com/opencv/opencv.git +``` + +@note +`--depth=1` option is to limit downloading commits. If you want to see more commit history, please remove this option. + +Build/Install OpenCV with Wayland highgui-backend +------------------------------------------------- + +Run `cmake` with `-DWITH_WAYLAND=ON` option to configure OpenCV. + +```bash +cmake -S opencv -B build4-main -DWITH_WAYLAND=ON -GNinja +``` + +If succeeded, Wayland Client/Cursor/Protocols and Xkbcommon versions are shown. Wayland EGL is option. + +```plaintext +-- +-- GUI: Wayland +-- Wayland: (Experimental) YES +-- Wayland Client: YES (ver 1.22.0) +-- Wayland Cursor: YES (ver 1.22.0) +-- Wayland Protocols: YES (ver 1.34) +-- Xkbcommon: YES (ver 1.6.0) +-- Wayland EGL(Option): YES (ver 18.1.0) +-- GTK+: NO +-- VTK support: NO +``` + +Run `cmake --build` to build, and `sudo cmake --install` to install into your system. + +```bash +cmake --build build4-main +sudo cmake --install build4-main +sudo ldconfig +``` + +Simple Application to try Wayland highgui-backend +------------------------------------------------- +Try this code, so you can see name of currentUIFrramework() and OpenCV logo window with Wayland highgui-backend. + + +```bash +// g++ main.cpp -o a.out -I /usr/local/include/opencv4 -lopencv_core -lopencv_highgui -lopencv_imgcodecs +#include +#include +#include +#include +#include + +int main(void) +{ + std::cout << "cv::currentUIFramework() returns " << cv::currentUIFramework() << std::endl; + + cv::Mat src; + src = cv::imread("opencv-logo.png"); + + cv::namedWindow("src"); + + int key = 0; + do + { + cv::imshow("src", src ); + key = cv::waitKey(50); + } while( key != 'q' ); + return 0; +} +``` + +Limitation/Known problem +------------------------ +- cv::moveWindow() is not implementated. ( See. https://github.com/opencv/opencv/issues/25478 ) diff --git a/doc/tutorials/app/intelperc.markdown b/doc/tutorials/app/intelperc.markdown index 132074faa3..574bfc9e6a 100644 --- a/doc/tutorials/app/intelperc.markdown +++ b/doc/tutorials/app/intelperc.markdown @@ -4,6 +4,7 @@ Using Creative Senz3D and other Intel RealSense SDK compatible depth sensors {#t @tableofcontents @prev_tutorial{tutorial_orbbec_astra} +@next_tutorial{tutorial_wayland_ubuntu} ![hardwares](images/realsense.jpg) diff --git a/doc/tutorials/app/table_of_content_app.markdown b/doc/tutorials/app/table_of_content_app.markdown index 8e05dfaf07..6671f6b541 100644 --- a/doc/tutorials/app/table_of_content_app.markdown +++ b/doc/tutorials/app/table_of_content_app.markdown @@ -8,3 +8,4 @@ Application utils (highgui, imgcodecs, videoio modules) {#tutorial_table_of_cont - @subpage tutorial_kinect_openni - @subpage tutorial_orbbec_astra - @subpage tutorial_intelperc +- @subpage tutorial_wayland_ubuntu diff --git a/modules/highgui/cmake/detect_wayland.cmake b/modules/highgui/cmake/detect_wayland.cmake index 24e70d1b85..7fcb5bd7a9 100644 --- a/modules/highgui/cmake/detect_wayland.cmake +++ b/modules/highgui/cmake/detect_wayland.cmake @@ -9,7 +9,7 @@ macro(ocv_wayland_generate protocol_file output_file) list(APPEND WAYLAND_PROTOCOL_SOURCES ${output_file}.h ${output_file}.c) endmacro() -ocv_clear_vars(HAVE_WAYLAND_CLIENT HAVE_WAYLAND_CURSOR HAVE_XKBCOMMON HAVE_WAYLAND_PROTOCOLS) +ocv_clear_vars(HAVE_WAYLAND_CLIENT HAVE_WAYLAND_CURSOR HAVE_XKBCOMMON HAVE_WAYLAND_PROTOCOLS HAVE_WAYLAND_EGL) if(WITH_WAYLAND) ocv_check_modules(WAYLAND_CLIENT wayland-client) if(WAYLAND_CLIENT_FOUND) @@ -32,4 +32,10 @@ if(WITH_WAYLAND) if(HAVE_WAYLAND_CLIENT AND HAVE_WAYLAND_CURSOR AND HAVE_XKBCOMMON AND HAVE_WAYLAND_PROTOCOLS) set(HAVE_WAYLAND TRUE) endif() + + # WAYLAND_EGL is option + ocv_check_modules(WAYLAND_EGL wayland-egl) + if(WAYLAND_EGL_FOUND) + set(HAVE_WAYLAND_EGL ON) + endif() endif() diff --git a/modules/highgui/src/window_wayland.cpp b/modules/highgui/src/window_wayland.cpp index 61a2f0e17a..ca2811ffe2 100644 --- a/modules/highgui/src/window_wayland.cpp +++ b/modules/highgui/src/window_wayland.cpp @@ -231,7 +231,13 @@ private: &handle_pointer_motion, &handle_pointer_button, &handle_pointer_axis, &handle_pointer_frame, &handle_pointer_axis_source, &handle_pointer_axis_stop, - &handle_pointer_axis_discrete + &handle_pointer_axis_discrete, +#if WL_POINTER_AXIS_VALUE120_SINCE_VERSION >= 8 + &handle_axis_value120, +#endif +#if WL_POINTER_AXIS_RELATIVE_DIRECTION_SINCE_VERSION >= 9 + &handle_axis_relative_direction, +#endif }; cv_wl_window *focus_window_{}; @@ -277,6 +283,27 @@ private: CV_UNUSED(axis); CV_UNUSED(discrete); } + +#if WL_POINTER_AXIS_VALUE120_SINCE_VERSION >= 8 + static void + handle_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120) { + CV_UNUSED(data); + CV_UNUSED(wl_pointer); + CV_UNUSED(axis); + CV_UNUSED(value120); + } +#endif + +#if WL_POINTER_AXIS_RELATIVE_DIRECTION_SINCE_VERSION >= 9 + static void + handle_axis_relative_direction(void *data, struct wl_pointer *wl_pointer, uint32_t axis, uint32_t direction) { + CV_UNUSED(data); + CV_UNUSED(wl_pointer); + CV_UNUSED(axis); + CV_UNUSED(direction); + } +#endif + }; class cv_wl_keyboard { @@ -695,7 +722,13 @@ private: }; struct xdg_toplevel *xdg_toplevel_; struct xdg_toplevel_listener xdgtop_listener_{ - &handle_toplevel_configure, &handle_toplevel_close + &handle_toplevel_configure, &handle_toplevel_close, +#if XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION >= 4 + &handle_toplevel_configure_bounds, +#endif +#if XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION >= 5 + &handle_toplevel_wm_capabilities, +#endif }; bool wait_for_configure_ = true; @@ -742,6 +775,27 @@ private: static void handle_toplevel_close(void *data, struct xdg_toplevel *surface); +#if XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION >= 4 + static void + handle_toplevel_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height) + { + CV_UNUSED(data); + CV_UNUSED(xdg_toplevel); + CV_UNUSED(width); + CV_UNUSED(height); + } +#endif + +#if XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION >= 5 + static void + handle_toplevel_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel, struct wl_array *capabilities) + { + CV_UNUSED(data); + CV_UNUSED(xdg_toplevel); + CV_UNUSED(capabilities); + } +#endif + static void handle_frame_callback(void *data, struct wl_callback *cb, uint32_t time); };