From e4495be42238fcbd6711e0c145a2a8f4570e87ff Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 28 Nov 2021 14:07:15 -0300 Subject: [PATCH 01/11] Add stripping to currently-unused Dev Jenkins preset --- .ci/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 240b72b09..55f1311d7 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -75,7 +75,7 @@ def presetSlugs = [ def presetFlags = [ 'Regular': '-t --preset=regular', 'Debug': '--preset=debug', - 'Dev': '--preset=experimental -D VNC=OFF' + 'Dev': '-t --preset=experimental -D VNC=OFF' ] def anyFailure = false From 99b3414fea7b63fb419cca8228047163e87914d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 1 Dec 2021 12:51:12 +0100 Subject: [PATCH 02/11] Update bug report template; normalize case --- .github/{FUNDING.yml => funding.yml} | 0 .github/{ISSUE_TEMPLATE => issue_template}/bug_report.md | 4 ++-- .github/{ISSUE_TEMPLATE => issue_template}/config.yml | 0 .github/{ISSUE_TEMPLATE => issue_template}/feature_request.md | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename .github/{FUNDING.yml => funding.yml} (100%) rename .github/{ISSUE_TEMPLATE => issue_template}/bug_report.md (84%) rename .github/{ISSUE_TEMPLATE => issue_template}/config.yml (100%) rename .github/{ISSUE_TEMPLATE => issue_template}/feature_request.md (100%) diff --git a/.github/FUNDING.yml b/.github/funding.yml similarity index 100% rename from .github/FUNDING.yml rename to .github/funding.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/issue_template/bug_report.md similarity index 84% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/issue_template/bug_report.md index 72fca815d..340d89500 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/issue_template/bug_report.md @@ -25,8 +25,8 @@ If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. Windows 10] - - 86Box version: [e.g. v2.06 build 2007, saying "Latest from Jenkins" isn't helpful] - - Build type: [i.e. regular, optimized, or dev] + - 86Box version: [e.g. v3.00 build 3333; saying "Latest from Jenkins" isn't helpful] + - Build information: [i.e. new/old dynarec, architecture and build type] **Additional context** Add any other context about the problem here. If you are using an Optimized build, make sure to try the regular build too before filing a bug report! diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/issue_template/config.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/config.yml rename to .github/issue_template/config.yml diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/issue_template/feature_request.md similarity index 100% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to .github/issue_template/feature_request.md From e88c91eddcebe550d8c2ae84715a17e1515d0b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 1 Dec 2021 12:54:15 +0100 Subject: [PATCH 03/11] Looks like GitHub is not consistent at case sensitivity :^) --- .github/{issue_template => ISSUE_TEMPLATE}/bug_report.md | 0 .github/{issue_template => ISSUE_TEMPLATE}/config.yml | 0 .github/{issue_template => ISSUE_TEMPLATE}/feature_request.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename .github/{issue_template => ISSUE_TEMPLATE}/bug_report.md (100%) rename .github/{issue_template => ISSUE_TEMPLATE}/config.yml (100%) rename .github/{issue_template => ISSUE_TEMPLATE}/feature_request.md (100%) diff --git a/.github/issue_template/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 100% rename from .github/issue_template/bug_report.md rename to .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/issue_template/config.yml b/.github/ISSUE_TEMPLATE/config.yml similarity index 100% rename from .github/issue_template/config.yml rename to .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/issue_template/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md similarity index 100% rename from .github/issue_template/feature_request.md rename to .github/ISSUE_TEMPLATE/feature_request.md From 55149c7866e9acd770d164667cbb63585b978327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 1 Dec 2021 18:05:17 +0100 Subject: [PATCH 04/11] Fix the Media menu not updating after mounting media --- src/win/win_ui.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 55591f7af..b6a22fe50 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -1315,9 +1315,6 @@ ui_init(int nCmdShow) if (! RegisterClassEx(&wincl)) return(2); - /* Load the Window Menu(s) from the resources. */ - menuMain = LoadMenu(hinstance, MENU_NAME); - /* Now create our main window. */ mbstowcs(title, emu_version, sizeof_w(title)); hwnd = CreateWindowEx ( @@ -1330,7 +1327,7 @@ ui_init(int nCmdShow) scrnsz_x+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* width */ scrnsz_y+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ HWND_DESKTOP, /* window is a child to desktop */ - menuMain, /* menu */ + NULL, /* no menu (yet) */ hinstance, /* Program Instance handler */ NULL); /* no Window Creation data */ hwndMain = tdconfig.hwndParent = hwnd; @@ -1380,14 +1377,10 @@ ui_init(int nCmdShow) ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height); } - /* Load the desired language, and reset all menus to their defaults */ + /* Load the desired language */ uint32_t helper_lang = lang_id; lang_id = 0; - set_language(helper_lang); - - /* Reset all menus to their defaults. */ - ResetAllMenus(); - media_menu_init(); + set_language(helper_lang); /* Make the window visible on the screen. */ ShowWindow(hwnd, nCmdShow); From 03cae5c6683033fb16d7ab0c4da8d281b0d12019 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 1 Dec 2021 18:49:53 +0100 Subject: [PATCH 05/11] Removed excess logs of the tgui9440/96x0. --- src/video/vid_tgui9440.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 579e9f93f..4c081e1a7 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -465,7 +465,6 @@ tgui_out(uint16_t addr, uint8_t val, void *p) tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; } - pclog("Linear base = %08x, size = %08x, mask = %08x\n", tgui->linear_base, tgui->linear_size, svga->decode_mask); tgui_recalcmapping(tgui); } break; @@ -1379,7 +1378,6 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } /*Other than mode stuff, this bit is undocumented*/ - pclog("TGUI ger22 = %04x, cmd = %i, hdisp = %i, svga = %i, bpp = %i\n", tgui->accel.ger22, tgui->accel.command, svga->hdisp, svga->bpp, tgui->accel.bpp); switch (tgui->accel.ger22 & 0xff) { case 0: switch (tgui->accel.ger22 >> 8) { From 3fd4f496955540216eceba20f90d610adcbc1cd7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 1 Dec 2021 15:18:36 -0300 Subject: [PATCH 06/11] Fix small detail in versioninfo --- src/win/86Box.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/86Box.rc b/src/win/86Box.rc index bf8b9cfbb..dfbcabd54 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -332,7 +332,7 @@ BEGIN VALUE "FileVersion", EMU_VERSION "\0" VALUE "InternalName", EMU_NAME "\0" VALUE "LegalCopyright", "Copyright \xa9 2007-" COPYRIGHT_YEAR " " EMU_NAME " contributors\0" - VALUE "OriginalFilename", "86box.exe\0" + VALUE "OriginalFilename", EMU_NAME ".exe\0" VALUE "ProductName", EMU_NAME "\0" VALUE "ProductVersion", EMU_VERSION "\0" END From 7f0533fc9ae5d234f90afcb79c8377e3b1e4ede7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 1 Dec 2021 20:35:29 +0100 Subject: [PATCH 07/11] Ignore status bar icon timer callback if the status bar has reset itself in between. --- src/win/win_stbar.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index c980253e0..e9c2028ad 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -60,7 +60,7 @@ HWND hwndSBAR; -int update_icons = 1; +int update_icons = 1, reset_occurred = 1; static LONG_PTR OriginalProcedure; @@ -122,12 +122,15 @@ hdd_count(int bus) void ui_sb_timer_callback(int pane) { - sb_part_icons[pane] &= ~1; + if (!(reset_occurred & 1)) { + sb_part_icons[pane] &= ~1; - if (sb_part_icons && sb_part_icons[pane]) { - SendMessage(hwndSBAR, SB_SETICON, pane, - (LPARAM)hIcon[sb_part_icons[pane]]); - } + if (sb_part_icons && sb_part_icons[pane]) { + SendMessage(hwndSBAR, SB_SETICON, pane, + (LPARAM)hIcon[sb_part_icons[pane]]); + } + } else + reset_occurred &= ~1; } @@ -152,6 +155,7 @@ ui_sb_update_icon(int tag, int active) PostMessage(hwndSBAR, SB_SETICON, found, (LPARAM)hIcon[sb_part_icons[found]]); + reset_occurred = 2; SetTimer(hwndMain, 0x8000 | found, 75, NULL); } } @@ -832,6 +836,8 @@ ui_sb_update_panes(void) } sb_ready = 1; + if (reset_occurred & 2) + reset_occurred |= 1; } From 8fb29ad031d5a65ddf8b6dc00c180f1372d66401 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 1 Dec 2021 21:06:50 +0100 Subject: [PATCH 08/11] Unfudged the status bar fix. --- src/win/win_stbar.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index e9c2028ad..17178a6bf 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -131,6 +131,8 @@ ui_sb_timer_callback(int pane) } } else reset_occurred &= ~1; + + reset_occurred &= ~2; } From a128a518650839b51bb724043a114ccc1c17f463 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 1 Dec 2021 17:32:53 -0300 Subject: [PATCH 09/11] Point readme link to v3.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a573f38f9..cfadfe55f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ However, it is also possible to use 86Box on its own with the `--vmpath`/`-P` co Downloads --------- -The latest stable version of 86Box is version 2.07, which was released on November 20, 2019, and is available from our [GitHub repository](https://github.com/86Box/86Box/releases/tag/v2.07). +The latest stable version of 86Box is **v3.0**, which was released on December 1, 2021, and is available from our [GitHub repository](https://github.com/86Box/86Box/releases/tag/v3.0). ### Automatic builds We also offer automatic builds, which are built from the latest source code and contain the latest bugfixes and improvements, but may not be as stable and/or optimized as stable builds. From 67df8cd8c6da0eccbb3acf878cc7231d5c1074af Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 1 Dec 2021 17:39:09 -0300 Subject: [PATCH 10/11] Build script: Fix strip flag being lost across MSYSTEMs --- .ci/build.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index 6cb5467f3..b0c22f671 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -190,7 +190,9 @@ then # Call build with the correct MSYSTEM. echo [-] Switching to MSYSTEM [$msys] cd "$cwd" - CHERE_INVOKING=yes MSYSTEM="$msys" bash -lc 'exec "'"$0"'" -b "'"$package_name"'" "'"$arch"'" '"$cmake_flags" + strip_arg= + [ $strip -ne 0 ] && strip_arg="-t " + CHERE_INVOKING=yes MSYSTEM="$msys" bash -lc 'exec "'"$0"'" -b "'"$package_name"'" "'"$arch"'" '"$strip_arg""$cmake_flags" exit $? fi else From fc9d73b541b5347dd00fa9b0328eec92e6b95165 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 2 Dec 2021 16:26:33 +0600 Subject: [PATCH 11/11] Wayland mouse support Fix moving items with mouse when captured on macOS --- CMakeLists.txt | 2 +- src/qt/CMakeLists.txt | 19 + src/qt/macos_event_filter.mm | 5 +- src/qt/qt_gleswidget.cpp | 14 + src/qt/qt_gleswidget.hpp | 12 + src/qt/qt_mainwindow.cpp | 20 +- src/qt/wl_mouse.cpp | 89 +++++ src/qt/wl_mouse.hpp | 5 + .../pointer-constraints-unstable-v1.xml | 339 ++++++++++++++++++ wl_protocols/relative-pointer-unstable-v1.xml | 136 +++++++ 10 files changed, 636 insertions(+), 5 deletions(-) create mode 100644 src/qt/wl_mouse.cpp create mode 100644 src/qt/wl_mouse.hpp create mode 100644 wl_protocols/pointer-constraints-unstable-v1.xml create mode 100644 wl_protocols/relative-pointer-unstable-v1.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index 64d0087e5..76f55f86c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ # Copyright 2020,2021 David Hrdlička. # -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.16) cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0079 NEW) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index b3ce7121b..9a2be5a7f 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -85,6 +85,7 @@ target_link_libraries( plat PRIVATE Qt5::Widgets + Qt5::Gui Threads::Threads ) @@ -92,10 +93,28 @@ target_link_libraries( ui PRIVATE Qt5::Widgets + Qt5::Gui Threads::Threads ) if (UNIX AND NOT APPLE) find_package(X11 REQUIRED) target_link_libraries(ui PRIVATE X11::X11) + find_package(ECM NO_MODULE) + if (ECM_FOUND) + list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + find_package(Wayland COMPONENTS Client) + if (Wayland_FOUND) + target_link_libraries(ui PRIVATE Wayland::Client) + find_package(WaylandScanner REQUIRED) + if (WaylandScanner_FOUND) + set(WL_SOURCE_VAR) + ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/relative-pointer-unstable-v1.xml BASENAME relative-pointer-unstable-v1) + ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1) + target_include_directories(ui PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) + target_sources(ui PRIVATE ${WL_SOURCE_VAR} wl_mouse.cpp) + target_compile_definitions(ui PRIVATE WAYLAND) + endif() + endif() + endif() endif() diff --git a/src/qt/macos_event_filter.mm b/src/qt/macos_event_filter.mm index 4dd7ef2ae..a3200aa8e 100644 --- a/src/qt/macos_event_filter.mm +++ b/src/qt/macos_event_filter.mm @@ -38,7 +38,10 @@ bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *mess if (eventType == "mac_generic_NSEvent") { NSEvent* event = (NSEvent*)message; - if ([event type] == NSEventTypeMouseMoved) + if ([event type] == NSEventTypeMouseMoved + || [event type] == NSEventTypeLeftMouseDragged + || [event type] == NSEventTypeRightMouseDragged + || [event type] == NSEventTypeOtherMouseDragged) { mousedata.deltax += [event deltaX]; mousedata.deltay += [event deltaY]; diff --git a/src/qt/qt_gleswidget.cpp b/src/qt/qt_gleswidget.cpp index c30e5cefa..829b484b9 100644 --- a/src/qt/qt_gleswidget.cpp +++ b/src/qt/qt_gleswidget.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "qt_gleswidget.hpp" #ifdef __APPLE__ #include @@ -43,6 +45,10 @@ void GLESWidget::qt_mouse_poll() mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; mouse_buttons = mousedata.mousebuttons; +#ifdef WAYLAND + if (wayland) + wl_mouse_poll(); +#endif #endif } @@ -75,11 +81,13 @@ void GLESWidget::mouseReleaseEvent(QMouseEvent *event) if (this->geometry().contains(event->pos()) && event->button() == Qt::LeftButton && !mouse_capture) { plat_mouse_capture(1); + this->setCursor(Qt::BlankCursor); return; } if (mouse_capture && event->button() == Qt::MiddleButton && mouse_get_buttons() < 3) { plat_mouse_capture(0); + this->setCursor(Qt::ArrowCursor); return; } if (mouse_capture) @@ -93,6 +101,7 @@ void GLESWidget::mousePressEvent(QMouseEvent *event) { mousedata.mousebuttons |= event->button(); } + event->accept(); } void GLESWidget::wheelEvent(QWheelEvent *event) { @@ -105,6 +114,11 @@ void GLESWidget::wheelEvent(QWheelEvent *event) int ignoreNextMouseEvent = 0; void GLESWidget::mouseMoveEvent(QMouseEvent *event) { + if (QApplication::platformName().contains("wayland")) + { + event->accept(); + return; + } if (!mouse_capture) { event->ignore(); return; } #ifdef __APPLE__ event->accept(); diff --git a/src/qt/qt_gleswidget.hpp b/src/qt/qt_gleswidget.hpp index 2fa8d8d67..9c7e9a6cd 100644 --- a/src/qt/qt_gleswidget.hpp +++ b/src/qt/qt_gleswidget.hpp @@ -7,6 +7,11 @@ #include #include +#include + +#ifdef WAYLAND +#include "wl_mouse.hpp" +#endif class GLESWidget : public QOpenGLWidget, protected QOpenGLFunctions { @@ -15,6 +20,7 @@ class GLESWidget : public QOpenGLWidget, protected QOpenGLFunctions private: QImage m_image{QSize(2048 + 64, 2048 + 64), QImage::Format_RGB32}; int x, y, w, h, sx, sy, sw, sh; + bool wayland = false; public: void resizeGL(int w, int h) override; void initializeGL() override; @@ -23,6 +29,12 @@ public: : QOpenGLWidget(parent), QOpenGLFunctions() { setMinimumSize(16, 16); +#ifdef WAYLAND + if (QApplication::platformName().contains("wayland")) { + wayland = true; + wl_init(); + } +#endif } ~GLESWidget() { diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index ad3a4df14..8e5b5a450 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1,5 +1,6 @@ #include "qt_mainwindow.hpp" #include "ui_qt_mainwindow.h" +#include extern "C" { #include <86box/86box.h> @@ -42,7 +43,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); video_setblit(qt_blit); - ui->glesWidget->setMouseTracking(true); + //ui->glesWidget->setMouseTracking(true); connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection); @@ -54,8 +55,21 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::setMouseCapture, this, [this](bool state) { mouse_capture = state ? 1 : 0; qt_mouse_capture(mouse_capture); - if (mouse_capture) ui->glesWidget->grabMouse(); - else ui->glesWidget->releaseMouse(); + if (mouse_capture) { + ui->glesWidget->grabMouse(); +#ifdef WAYLAND + if (QGuiApplication::platformName().contains("wayland")) { + wl_mouse_capture(this->windowHandle()); + } +#endif + } else { + ui->glesWidget->releaseMouse(); +#ifdef WAYLAND + if (QGuiApplication::platformName().contains("wayland")) { + wl_mouse_uncapture(); + } +#endif + } }); connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp new file mode 100644 index 000000000..b399dafd7 --- /dev/null +++ b/src/qt/wl_mouse.cpp @@ -0,0 +1,89 @@ +#include "wl_mouse.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include + +static zwp_relative_pointer_manager_v1* rel_manager = nullptr; +static zwp_relative_pointer_v1* rel_pointer = nullptr; +static zwp_pointer_constraints_v1* conf_pointer_interface = nullptr; +static zwp_locked_pointer_v1* conf_pointer = nullptr; + +static int rel_mouse_x = 0, rel_mouse_y = 0; + +void rel_mouse_event(void* data, zwp_relative_pointer_v1* zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) +{ + rel_mouse_x += wl_fixed_to_int(dx_real); + rel_mouse_y += wl_fixed_to_int(dy_real); +} + +extern "C" +{ + extern int mouse_x, mouse_y; +} + +void wl_mouse_poll() +{ + mouse_x = rel_mouse_x; + mouse_y = rel_mouse_y; + rel_mouse_x = 0; + rel_mouse_y = 0; +} + +static struct zwp_relative_pointer_v1_listener rel_listener = +{ + rel_mouse_event +}; + +static void +display_handle_global(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + if (!strcmp(interface, "zwp_relative_pointer_manager_v1")) + { + rel_manager = (zwp_relative_pointer_manager_v1*)wl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, version); + } + if (!strcmp(interface, "zwp_pointer_constraints_v1")) + { + conf_pointer_interface = (zwp_pointer_constraints_v1*)wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); + } +} + +static const struct wl_registry_listener registry_listener = { + display_handle_global, + nullptr +}; + +void wl_init() +{ + wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); + if (display) + { + auto registry = wl_display_get_registry(display); + if (registry) + { + wl_registry_add_listener(registry, ®istry_listener, nullptr); + wl_display_roundtrip(display); + } + } +} + +void wl_mouse_capture(QWindow *window) +{ + rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); + zwp_relative_pointer_v1_add_listener(rel_pointer, &rel_listener, nullptr); + conf_pointer = zwp_pointer_constraints_v1_lock_pointer(conf_pointer_interface, (wl_surface*)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"), nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); +} + +void wl_mouse_uncapture() +{ + zwp_locked_pointer_v1_destroy(conf_pointer); + zwp_relative_pointer_v1_destroy(rel_pointer); + rel_pointer = nullptr; + conf_pointer = nullptr; +} \ No newline at end of file diff --git a/src/qt/wl_mouse.hpp b/src/qt/wl_mouse.hpp new file mode 100644 index 000000000..73e81c208 --- /dev/null +++ b/src/qt/wl_mouse.hpp @@ -0,0 +1,5 @@ +class QWindow; +void wl_mouse_capture(QWindow* window); +void wl_mouse_uncapture(); +void wl_mouse_poll(); +void wl_init(); \ No newline at end of file diff --git a/wl_protocols/pointer-constraints-unstable-v1.xml b/wl_protocols/pointer-constraints-unstable-v1.xml new file mode 100644 index 000000000..efd64b660 --- /dev/null +++ b/wl_protocols/pointer-constraints-unstable-v1.xml @@ -0,0 +1,339 @@ + + + + + Copyright © 2014 Jonas Ådahl + Copyright © 2015 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a set of interfaces used for adding constraints to + the motion of a pointer. Possible constraints include confining pointer + motions to a given region, or locking it to its current position. + + In order to constrain the pointer, a client must first bind the global + interface "wp_pointer_constraints" which, if a compositor supports pointer + constraints, is exposed by the registry. Using the bound global object, the + client uses the request that corresponds to the type of constraint it wants + to make. See wp_pointer_constraints for more details. + + Warning! The protocol described in this file is experimental and backward + incompatible changes may be made. Backward compatible changes may be added + together with the corresponding interface version bump. Backward + incompatible changes are done by bumping the version number in the protocol + and interface names and resetting the interface version. Once the protocol + is to be declared stable, the 'z' prefix and the version number in the + protocol and interface names are removed and the interface version number is + reset. + + + + + The global interface exposing pointer constraining functionality. It + exposes two requests: lock_pointer for locking the pointer to its + position, and confine_pointer for locking the pointer to a region. + + The lock_pointer and confine_pointer requests create the objects + wp_locked_pointer and wp_confined_pointer respectively, and the client can + use these objects to interact with the lock. + + For any surface, only one lock or confinement may be active across all + wl_pointer objects of the same seat. If a lock or confinement is requested + when another lock or confinement is active or requested on the same surface + and with any of the wl_pointer objects of the same seat, an + 'already_constrained' error will be raised. + + + + + These errors can be emitted in response to wp_pointer_constraints + requests. + + + + + + + These values represent different lifetime semantics. They are passed + as arguments to the factory requests to specify how the constraint + lifetimes should be managed. + + + + A oneshot pointer constraint will never reactivate once it has been + deactivated. See the corresponding deactivation event + (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for + details. + + + + + A persistent pointer constraint may again reactivate once it has + been deactivated. See the corresponding deactivation event + (wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for + details. + + + + + + + Used by the client to notify the server that it will no longer use this + pointer constraints object. + + + + + + The lock_pointer request lets the client request to disable movements of + the virtual pointer (i.e. the cursor), effectively locking the pointer + to a position. This request may not take effect immediately; in the + future, when the compositor deems implementation-specific constraints + are satisfied, the pointer lock will be activated and the compositor + sends a locked event. + + The protocol provides no guarantee that the constraints are ever + satisfied, and does not require the compositor to send an error if the + constraints cannot ever be satisfied. It is thus possible to request a + lock that will never activate. + + There may not be another pointer constraint of any kind requested or + active on the surface for any of the wl_pointer objects of the seat of + the passed pointer when requesting a lock. If there is, an error will be + raised. See general pointer lock documentation for more details. + + The intersection of the region passed with this request and the input + region of the surface is used to determine where the pointer must be + in order for the lock to activate. It is up to the compositor whether to + warp the pointer or require some kind of user interaction for the lock + to activate. If the region is null the surface input region is used. + + A surface may receive pointer focus without the lock being activated. + + The request creates a new object wp_locked_pointer which is used to + interact with the lock as well as receive updates about its state. See + the the description of wp_locked_pointer for further information. + + Note that while a pointer is locked, the wl_pointer objects of the + corresponding seat will not emit any wl_pointer.motion events, but + relative motion events will still be emitted via wp_relative_pointer + objects of the same seat. wl_pointer.axis and wl_pointer.button events + are unaffected. + + + + + + + + + + + The confine_pointer request lets the client request to confine the + pointer cursor to a given region. This request may not take effect + immediately; in the future, when the compositor deems implementation- + specific constraints are satisfied, the pointer confinement will be + activated and the compositor sends a confined event. + + The intersection of the region passed with this request and the input + region of the surface is used to determine where the pointer must be + in order for the confinement to activate. It is up to the compositor + whether to warp the pointer or require some kind of user interaction for + the confinement to activate. If the region is null the surface input + region is used. + + The request will create a new object wp_confined_pointer which is used + to interact with the confinement as well as receive updates about its + state. See the the description of wp_confined_pointer for further + information. + + + + + + + + + + + + The wp_locked_pointer interface represents a locked pointer state. + + While the lock of this object is active, the wl_pointer objects of the + associated seat will not emit any wl_pointer.motion events. + + This object will send the event 'locked' when the lock is activated. + Whenever the lock is activated, it is guaranteed that the locked surface + will already have received pointer focus and that the pointer will be + within the region passed to the request creating this object. + + To unlock the pointer, send the destroy request. This will also destroy + the wp_locked_pointer object. + + If the compositor decides to unlock the pointer the unlocked event is + sent. See wp_locked_pointer.unlock for details. + + When unlocking, the compositor may warp the cursor position to the set + cursor position hint. If it does, it will not result in any relative + motion events emitted via wp_relative_pointer. + + If the surface the lock was requested on is destroyed and the lock is not + yet activated, the wp_locked_pointer object is now defunct and must be + destroyed. + + + + + Destroy the locked pointer object. If applicable, the compositor will + unlock the pointer. + + + + + + Set the cursor position hint relative to the top left corner of the + surface. + + If the client is drawing its own cursor, it should update the position + hint to the position of its own cursor. A compositor may use this + information to warp the pointer upon unlock in order to avoid pointer + jumps. + + The cursor position hint is double buffered. The new hint will only take + effect when the associated surface gets it pending state applied. See + wl_surface.commit for details. + + + + + + + + Set a new region used to lock the pointer. + + The new lock region is double-buffered. The new lock region will + only take effect when the associated surface gets its pending state + applied. See wl_surface.commit for details. + + For details about the lock region, see wp_locked_pointer. + + + + + + + Notification that the pointer lock of the seat's pointer is activated. + + + + + + Notification that the pointer lock of the seat's pointer is no longer + active. If this is a oneshot pointer lock (see + wp_pointer_constraints.lifetime) this object is now defunct and should + be destroyed. If this is a persistent pointer lock (see + wp_pointer_constraints.lifetime) this pointer lock may again + reactivate in the future. + + + + + + + The wp_confined_pointer interface represents a confined pointer state. + + This object will send the event 'confined' when the confinement is + activated. Whenever the confinement is activated, it is guaranteed that + the surface the pointer is confined to will already have received pointer + focus and that the pointer will be within the region passed to the request + creating this object. It is up to the compositor to decide whether this + requires some user interaction and if the pointer will warp to within the + passed region if outside. + + To unconfine the pointer, send the destroy request. This will also destroy + the wp_confined_pointer object. + + If the compositor decides to unconfine the pointer the unconfined event is + sent. The wp_confined_pointer object is at this point defunct and should + be destroyed. + + + + + Destroy the confined pointer object. If applicable, the compositor will + unconfine the pointer. + + + + + + Set a new region used to confine the pointer. + + The new confine region is double-buffered. The new confine region will + only take effect when the associated surface gets its pending state + applied. See wl_surface.commit for details. + + If the confinement is active when the new confinement region is applied + and the pointer ends up outside of newly applied region, the pointer may + warped to a position within the new confinement region. If warped, a + wl_pointer.motion event will be emitted, but no + wp_relative_pointer.relative_motion event. + + The compositor may also, instead of using the new region, unconfine the + pointer. + + For details about the confine region, see wp_confined_pointer. + + + + + + + Notification that the pointer confinement of the seat's pointer is + activated. + + + + + + Notification that the pointer confinement of the seat's pointer is no + longer active. If this is a oneshot pointer confinement (see + wp_pointer_constraints.lifetime) this object is now defunct and should + be destroyed. If this is a persistent pointer confinement (see + wp_pointer_constraints.lifetime) this pointer confinement may again + reactivate in the future. + + + + + diff --git a/wl_protocols/relative-pointer-unstable-v1.xml b/wl_protocols/relative-pointer-unstable-v1.xml new file mode 100644 index 000000000..ca6f81d12 --- /dev/null +++ b/wl_protocols/relative-pointer-unstable-v1.xml @@ -0,0 +1,136 @@ + + + + + Copyright © 2014 Jonas Ådahl + Copyright © 2015 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a set of interfaces used for making clients able to + receive relative pointer events not obstructed by barriers (such as the + monitor edge or other pointer barriers). + + To start receiving relative pointer events, a client must first bind the + global interface "wp_relative_pointer_manager" which, if a compositor + supports relative pointer motion events, is exposed by the registry. After + having created the relative pointer manager proxy object, the client uses + it to create the actual relative pointer object using the + "get_relative_pointer" request given a wl_pointer. The relative pointer + motion events will then, when applicable, be transmitted via the proxy of + the newly created relative pointer object. See the documentation of the + relative pointer interface for more details. + + Warning! The protocol described in this file is experimental and backward + incompatible changes may be made. Backward compatible changes may be added + together with the corresponding interface version bump. Backward + incompatible changes are done by bumping the version number in the protocol + and interface names and resetting the interface version. Once the protocol + is to be declared stable, the 'z' prefix and the version number in the + protocol and interface names are removed and the interface version number is + reset. + + + + + A global interface used for getting the relative pointer object for a + given pointer. + + + + + Used by the client to notify the server that it will no longer use this + relative pointer manager object. + + + + + + Create a relative pointer interface given a wl_pointer object. See the + wp_relative_pointer interface for more details. + + + + + + + + + A wp_relative_pointer object is an extension to the wl_pointer interface + used for emitting relative pointer events. It shares the same focus as + wl_pointer objects of the same seat and will only emit events when it has + focus. + + + + + + + + + Relative x/y pointer motion from the pointer of the seat associated with + this object. + + A relative motion is in the same dimension as regular wl_pointer motion + events, except they do not represent an absolute position. For example, + moving a pointer from (x, y) to (x', y') would have the equivalent + relative motion (x' - x, y' - y). If a pointer motion caused the + absolute pointer position to be clipped by for example the edge of the + monitor, the relative motion is unaffected by the clipping and will + represent the unclipped motion. + + This event also contains non-accelerated motion deltas. The + non-accelerated delta is, when applicable, the regular pointer motion + delta as it was before having applied motion acceleration and other + transformations such as normalization. + + Note that the non-accelerated delta does not represent 'raw' events as + they were read from some device. Pointer motion acceleration is device- + and configuration-specific and non-accelerated deltas and accelerated + deltas may have the same value on some devices. + + Relative motions are not coupled to wl_pointer.motion events, and can be + sent in combination with such events, but also independently. There may + also be scenarios where wl_pointer.motion is sent, but there is no + relative motion. The order of an absolute and relative motion event + originating from the same physical motion is not guaranteed. + + If the client needs button events or focus state, it can receive them + from a wl_pointer object of the same seat that the wp_relative_pointer + object is associated with. + + + + + + + + + + +