2022-02-07 15:00:02 +06:00
/*
2023-01-06 15:36:05 -05:00
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86 Box distribution .
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Program settings UI module .
2022-02-07 15:00:02 +06:00
*
*
*
* Authors : Joakim L . Gilje < jgilje @ jgilje . net >
* Cacodemon345
* Teemu Korhonen
*
2023-01-06 15:36:05 -05:00
* Copyright 2021 Joakim L . Gilje
* Copyright 2021 - 2021 Teemu Korhonen
* Copyright 2021 - 2022 Cacodemon345
2022-02-07 15:00:02 +06:00
*/
2021-12-04 21:33:04 +01:00
# include "qt_rendererstack.hpp"
# include "ui_qt_rendererstack.h"
# include "qt_hardwarerenderer.hpp"
2022-02-28 08:43:14 +02:00
# include "qt_openglrenderer.hpp"
2022-02-27 14:56:51 +02:00
# include "qt_softwarerenderer.hpp"
2022-04-21 16:32:46 +06:00
# include "qt_vulkanwindowrenderer.hpp"
2021-12-04 21:33:04 +01:00
2021-12-29 23:49:09 +06:00
# include "qt_mainwindow.hpp"
2022-02-10 15:30:39 +06:00
# include "qt_util.hpp"
2021-12-29 23:49:09 +06:00
2022-08-02 00:14:09 +06:00
# include "ui_qt_mainwindow.h"
2021-12-10 01:03:20 +06:00
# include "evdev_mouse.hpp"
2022-07-16 12:57:54 +06:00
# include <atomic>
2022-04-24 01:05:37 +06:00
# include <stdexcept>
2021-12-08 17:02:28 +06:00
# include <QScreen>
2022-04-21 16:32:48 +06:00
# include <QMessageBox>
2021-12-08 17:02:28 +06:00
2021-11-30 16:26:49 +06:00
# ifdef __APPLE__
2022-02-27 14:56:51 +02:00
# include <CoreGraphics / CoreGraphics.h>
2021-11-30 16:26:49 +06:00
# endif
2022-02-27 14:56:51 +02:00
extern " C " {
2022-07-06 01:25:39 +06:00
# include <86box/86box.h>
2022-08-14 12:28:36 +06:00
# include <86box/config.h>
2021-11-30 16:26:49 +06:00
# include <86box/plat.h>
# include <86box/video.h>
2023-08-07 18:49:58 +02:00
# include <86box/mouse.h>
2021-11-30 16:26:49 +06:00
}
2022-07-04 01:50:42 +06:00
struct mouseinputdata {
2023-01-03 15:42:57 +06:00
atomic_bool mouse_tablet_in_proximity ;
2023-08-07 18:49:58 +02:00
2023-08-07 19:59:32 +02:00
char * mouse_type ;
2022-07-04 01:50:42 +06:00
} ;
static mouseinputdata mousedata ;
2022-02-27 14:56:51 +02:00
extern MainWindow * main_window ;
2022-07-04 01:50:42 +06:00
RendererStack : : RendererStack ( QWidget * parent , int monitor_index )
2022-02-27 14:56:51 +02:00
: QStackedWidget ( parent )
, ui ( new Ui : : RendererStack )
2021-12-04 21:33:04 +01:00
{
2023-08-12 00:17:01 +02:00
# ifdef Q_OS_WINDOWS
int raw = 1 ;
# else
int raw = 0 ;
# endif
2021-12-04 21:33:04 +01:00
ui - > setupUi ( this ) ;
2021-12-15 00:37:48 +02:00
2022-07-04 01:50:42 +06:00
m_monitor_index = monitor_index ;
2022-03-11 12:03:54 +06:00
# if defined __unix__ && !defined __HAIKU__
2023-08-08 16:17:01 +02:00
char auto_mouse_type [ 16 ] ;
mousedata . mouse_type = getenv ( " EMU86BOX_MOUSE " ) ;
2023-08-08 06:51:24 +02:00
if ( ! mousedata . mouse_type | | ( mousedata . mouse_type [ 0 ] = = ' \0 ' ) | | ! stricmp ( mousedata . mouse_type , " auto " ) ) {
2022-04-20 20:54:41 -03:00
if ( QApplication : : platformName ( ) . contains ( " wayland " ) )
strcpy ( auto_mouse_type , " wayland " ) ;
2022-08-12 00:35:40 +06:00
else if ( QApplication : : platformName ( ) = = " eglfs " )
strcpy ( auto_mouse_type , " evdev " ) ;
else if ( QApplication : : platformName ( ) = = " xcb " )
strcpy ( auto_mouse_type , " xinput2 " ) ;
2022-04-20 20:54:41 -03:00
else
auto_mouse_type [ 0 ] = ' \0 ' ;
2023-08-07 19:59:32 +02:00
mousedata . mouse_type = auto_mouse_type ;
2021-12-10 01:03:20 +06:00
}
2022-04-20 20:54:41 -03:00
# ifdef WAYLAND
2023-08-08 06:51:24 +02:00
if ( ! stricmp ( mousedata . mouse_type , " wayland " ) ) {
2022-04-21 13:56:39 -03:00
wl_init ( ) ;
2022-11-19 08:49:04 -05:00
this - > mouse_capture_func = wl_mouse_capture ;
2022-04-21 13:56:39 -03:00
this - > mouse_uncapture_func = wl_mouse_uncapture ;
2022-04-26 02:16:32 +06:00
}
2022-02-27 14:56:51 +02:00
# endif
# ifdef EVDEV_INPUT
2023-08-12 00:17:01 +02:00
if ( ! stricmp ( mousedata . mouse_type , " evdev " ) ) {
2022-04-21 13:56:39 -03:00
evdev_init ( ) ;
2023-08-12 00:17:01 +02:00
raw = 0 ;
}
2022-04-25 14:51:17 +06:00
# endif
2023-08-08 06:51:24 +02:00
if ( ! stricmp ( mousedata . mouse_type , " xinput2 " ) ) {
2022-08-12 00:35:40 +06:00
extern void xinput2_init ( ) ;
extern void xinput2_exit ( ) ;
xinput2_init ( ) ;
this - > mouse_exit_func = xinput2_exit ;
}
2021-12-10 01:03:20 +06:00
# endif
2023-08-12 00:17:01 +02:00
if ( monitor_index = = 0 )
mouse_set_raw ( raw ) ;
2021-12-04 21:33:04 +01:00
}
RendererStack : : ~ RendererStack ( )
{
2024-05-04 23:36:09 +06:00
while ( QApplication : : overrideCursor ( ) )
QApplication : : restoreOverrideCursor ( ) ;
2021-12-04 21:33:04 +01:00
delete ui ;
}
2021-11-30 16:26:49 +06:00
void
qt_mouse_capture ( int on )
{
2022-02-27 14:56:51 +02:00
if ( ! on ) {
2021-11-30 16:26:49 +06:00
mouse_capture = 0 ;
2024-05-04 23:36:09 +06:00
while ( QApplication : : overrideCursor ( ) ) QApplication : : restoreOverrideCursor ( ) ;
2021-11-30 16:26:49 +06:00
# ifdef __APPLE__
CGAssociateMouseAndMouseCursorPosition ( true ) ;
# endif
return ;
}
mouse_capture = 1 ;
QApplication : : setOverrideCursor ( Qt : : BlankCursor ) ;
# ifdef __APPLE__
CGAssociateMouseAndMouseCursorPosition ( false ) ;
# endif
return ;
}
2021-12-09 00:01:22 +06:00
int ignoreNextMouseEvent = 1 ;
2022-02-27 14:56:51 +02:00
void
RendererStack : : mouseReleaseEvent ( QMouseEvent * event )
2021-11-30 16:26:49 +06:00
{
2024-01-03 00:10:41 +06:00
if ( ! dopause & & this - > geometry ( ) . contains ( m_monitor_index > = 1 ? event - > globalPos ( ) : event - > pos ( ) ) & &
2023-11-04 06:41:57 +01:00
( event - > button ( ) = = Qt : : LeftButton ) & & ! mouse_capture & &
( isMouseDown & 1 ) & & ( kbd_req_capture | | ( mouse_get_buttons ( ) ! = 0 ) ) & &
( mouse_input_mode = = 0 ) ) {
2021-12-01 01:11:06 +06:00
plat_mouse_capture ( 1 ) ;
2021-12-02 16:26:33 +06:00
this - > setCursor ( Qt : : BlankCursor ) ;
2022-02-27 14:56:51 +02:00
if ( ! ignoreNextMouseEvent )
ignoreNextMouseEvent + + ; // Avoid jumping cursor when moved.
2022-02-05 01:01:06 +05:00
isMouseDown & = ~ 1 ;
2021-11-30 16:26:49 +06:00
return ;
}
2022-10-25 17:11:45 +02:00
if ( mouse_capture & & ( event - > button ( ) = = Qt : : MiddleButton ) & & ( mouse_get_buttons ( ) < 3 ) ) {
2021-12-01 01:11:06 +06:00
plat_mouse_capture ( 0 ) ;
2021-12-02 16:26:33 +06:00
this - > setCursor ( Qt : : ArrowCursor ) ;
2022-02-05 01:01:06 +05:00
isMouseDown & = ~ 1 ;
2021-11-30 16:26:49 +06:00
return ;
}
2023-10-23 01:21:28 +02:00
if ( mouse_capture | | ( mouse_input_mode > = 1 ) ) {
2023-08-10 16:48:39 +02:00
# ifdef Q_OS_WINDOWS
2023-10-23 01:21:28 +02:00
if ( ( ( m_monitor_index > = 1 ) & & ( mouse_input_mode > = 1 ) & & mousedata . mouse_tablet_in_proximity ) | |
( ( m_monitor_index < 1 ) & & ( mouse_input_mode > = 1 ) ) )
2023-08-10 16:48:39 +02:00
# else
# ifndef __APPLE__
2023-10-23 01:21:28 +02:00
if ( ( ( m_monitor_index > = 1 ) & & ( mouse_input_mode > = 1 ) & & mousedata . mouse_tablet_in_proximity ) | |
2023-08-10 16:48:39 +02:00
( m_monitor_index < 1 ) )
# else
2023-10-23 01:21:28 +02:00
if ( ( m_monitor_index > = 1 ) & & ( mouse_input_mode > = 1 ) & & mousedata . mouse_tablet_in_proximity )
2023-08-10 16:48:39 +02:00
# endif
# endif
2023-08-07 18:49:58 +02:00
mouse_set_buttons_ex ( mouse_get_buttons_ex ( ) & ~ event - > button ( ) ) ;
2021-11-30 16:26:49 +06:00
}
2022-02-05 01:01:06 +05:00
isMouseDown & = ~ 1 ;
2021-11-30 16:26:49 +06:00
}
2022-07-16 12:57:54 +06:00
2022-02-27 14:56:51 +02:00
void
RendererStack : : mousePressEvent ( QMouseEvent * event )
2021-11-30 16:26:49 +06:00
{
2022-02-05 01:01:06 +05:00
isMouseDown | = 1 ;
2023-10-23 01:21:28 +02:00
if ( mouse_capture | | ( mouse_input_mode > = 1 ) ) {
2023-08-10 16:48:39 +02:00
# ifdef Q_OS_WINDOWS
2023-10-23 01:21:28 +02:00
if ( ( ( m_monitor_index > = 1 ) & & ( mouse_input_mode > = 1 ) & & mousedata . mouse_tablet_in_proximity ) | |
( ( m_monitor_index < 1 ) & & ( mouse_input_mode > = 1 ) ) )
2023-08-10 16:48:39 +02:00
# else
# ifndef __APPLE__
2023-10-23 01:21:28 +02:00
if ( ( ( m_monitor_index > = 1 ) & & ( mouse_input_mode > = 1 ) & & mousedata . mouse_tablet_in_proximity ) | |
2023-08-10 16:48:39 +02:00
( m_monitor_index < 1 ) )
# else
2023-10-23 01:21:28 +02:00
if ( ( m_monitor_index > = 1 ) & & ( mouse_input_mode > = 1 ) & & mousedata . mouse_tablet_in_proximity )
2023-08-10 16:48:39 +02:00
# endif
# endif
2023-08-07 18:49:58 +02:00
mouse_set_buttons_ex ( mouse_get_buttons_ex ( ) | event - > button ( ) ) ;
2021-11-30 16:26:49 +06:00
}
2021-12-02 16:26:33 +06:00
event - > accept ( ) ;
2021-11-30 16:26:49 +06:00
}
2022-07-16 12:57:54 +06:00
2022-02-27 14:56:51 +02:00
void
RendererStack : : wheelEvent ( QWheelEvent * event )
2021-11-30 16:26:49 +06:00
{
2024-11-16 18:05:45 -05:00
if ( ! mouse_capture ) {
event - > ignore ( ) ;
return ;
}
2024-09-04 00:01:03 +02:00
double numSteps = ( double ) event - > angleDelta ( ) . y ( ) / 120.0 ;
mouse_set_z ( ( int ) numSteps ) ;
event - > accept ( ) ;
2021-11-30 16:26:49 +06:00
}
2022-02-27 14:56:51 +02:00
void
RendererStack : : mouseMoveEvent ( QMouseEvent * event )
2021-11-30 16:26:49 +06:00
{
2022-02-27 14:56:51 +02:00
if ( QApplication : : platformName ( ) . contains ( " wayland " ) ) {
2021-12-02 16:26:33 +06:00
event - > accept ( ) ;
return ;
}
2022-02-27 14:56:51 +02:00
if ( ! mouse_capture ) {
event - > ignore ( ) ;
return ;
}
2022-04-08 01:51:32 +06:00
# if defined __APPLE__ || defined _WIN32
2021-11-30 16:26:49 +06:00
event - > accept ( ) ;
return ;
# else
static QPoint oldPos = QCursor : : pos ( ) ;
2022-02-27 14:56:51 +02:00
if ( ignoreNextMouseEvent ) {
oldPos = event - > pos ( ) ;
ignoreNextMouseEvent - - ;
event - > accept ( ) ;
return ;
}
2023-08-07 18:49:58 +02:00
# if defined __unix__ && !defined __HAIKU__
2023-08-07 19:59:32 +02:00
if ( ! stricmp ( mousedata . mouse_type , " wayland " ) )
2023-08-07 18:49:58 +02:00
mouse_scale ( event - > pos ( ) . x ( ) - oldPos . x ( ) , event - > pos ( ) . y ( ) - oldPos . y ( ) ) ;
# endif
2022-02-27 14:56:51 +02:00
if ( QApplication : : platformName ( ) = = " eglfs " ) {
leaveEvent ( ( QEvent * ) event ) ;
2021-12-09 00:01:22 +06:00
ignoreNextMouseEvent - - ;
}
2022-02-15 02:34:13 +06:00
QCursor : : setPos ( mapToGlobal ( QPoint ( width ( ) / 2 , height ( ) / 2 ) ) ) ;
ignoreNextMouseEvent = 2 ;
2022-02-27 14:56:51 +02:00
oldPos = event - > pos ( ) ;
2021-11-30 16:26:49 +06:00
# endif
2023-08-16 19:33:29 +02:00
}
2023-01-03 15:42:57 +06:00
void
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
RendererStack : : enterEvent ( QEnterEvent * event )
# else
RendererStack : : enterEvent ( QEvent * event )
# endif
{
2024-05-04 23:36:09 +06:00
mousedata . mouse_tablet_in_proximity = m_monitor_index + 1 ;
2023-01-03 15:42:57 +06:00
2023-10-23 01:21:28 +02:00
if ( mouse_input_mode = = 1 )
2024-07-26 20:12:10 +02:00
QApplication : : setOverrideCursor ( Qt : : BlankCursor ) ;
else if ( mouse_input_mode = = 2 )
2024-05-04 17:01:29 +06:00
QApplication : : setOverrideCursor ( Qt : : CrossCursor ) ;
2023-01-03 15:42:57 +06:00
}
2022-02-27 14:56:51 +02:00
void
RendererStack : : leaveEvent ( QEvent * event )
2021-12-08 16:27:58 +06:00
{
2023-01-03 15:42:57 +06:00
mousedata . mouse_tablet_in_proximity = 0 ;
2023-03-04 23:10:43 +06:00
2024-05-04 23:36:09 +06:00
if ( mouse_input_mode = = 1 & & QApplication : : overrideCursor ( ) ) {
while ( QApplication : : overrideCursor ( ) )
QApplication : : restoreOverrideCursor ( ) ;
}
2022-02-27 14:56:51 +02:00
if ( QApplication : : platformName ( ) . contains ( " wayland " ) ) {
2021-12-08 16:27:58 +06:00
event - > accept ( ) ;
return ;
}
2022-02-27 14:56:51 +02:00
if ( ! mouse_capture )
return ;
2022-03-11 12:03:54 +06:00
QCursor : : setPos ( mapToGlobal ( QPoint ( width ( ) / 2 , height ( ) / 2 ) ) ) ;
2021-12-08 16:27:58 +06:00
ignoreNextMouseEvent = 2 ;
event - > accept ( ) ;
}
2022-02-27 14:56:51 +02:00
void
RendererStack : : switchRenderer ( Renderer renderer )
{
2021-12-15 19:58:09 +01:00
startblit ( ) ;
2021-12-15 20:02:35 +01:00
if ( current ) {
2024-02-13 18:40:07 +05:00
rendererWindow - > finalize ( ) ;
removeWidget ( current . get ( ) ) ;
disconnect ( this , & RendererStack : : blitToRenderer , nullptr , nullptr ) ;
2022-07-29 14:46:54 +06:00
2024-02-13 18:40:07 +05:00
/* Create new renderer only after previous is destroyed! */
connect ( current . get ( ) , & QObject : : destroyed , [ this , renderer ] ( QObject * ) { createRenderer ( renderer ) ; } ) ;
2022-02-27 14:56:51 +02:00
2024-02-13 18:40:07 +05:00
current . release ( ) - > deleteLater ( ) ;
2022-02-27 14:56:51 +02:00
} else {
createRenderer ( renderer ) ;
2021-12-15 19:58:09 +01:00
}
2022-02-27 14:56:51 +02:00
}
2021-12-15 19:58:09 +01:00
2022-02-27 14:56:51 +02:00
void
RendererStack : : createRenderer ( Renderer renderer )
{
2021-12-15 19:58:09 +01:00
switch ( renderer ) {
2022-04-25 16:09:37 +06:00
default :
2022-02-27 14:56:51 +02:00
case Renderer : : Software :
{
auto sw = new SoftwareRenderer ( this ) ;
rendererWindow = sw ;
connect ( this , & RendererStack : : blitToRenderer , sw , & SoftwareRenderer : : onBlit , Qt : : QueuedConnection ) ;
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
current . reset ( sw ) ;
# else
2022-02-27 14:56:51 +02:00
current . reset ( this - > createWindowContainer ( sw , this ) ) ;
2022-03-11 12:03:54 +06:00
# endif
2022-02-27 14:56:51 +02:00
}
break ;
case Renderer : : OpenGL :
{
this - > createWinId ( ) ;
auto hw = new HardwareRenderer ( this ) ;
rendererWindow = hw ;
connect ( this , & RendererStack : : blitToRenderer , hw , & HardwareRenderer : : onBlit , Qt : : QueuedConnection ) ;
current . reset ( this - > createWindowContainer ( hw , this ) ) ;
break ;
}
case Renderer : : OpenGLES :
{
this - > createWinId ( ) ;
auto hw = new HardwareRenderer ( this , HardwareRenderer : : RenderType : : OpenGLES ) ;
rendererWindow = hw ;
connect ( this , & RendererStack : : blitToRenderer , hw , & HardwareRenderer : : onBlit , Qt : : QueuedConnection ) ;
current . reset ( this - > createWindowContainer ( hw , this ) ) ;
break ;
}
case Renderer : : OpenGL3 :
{
this - > createWinId ( ) ;
auto hw = new OpenGLRenderer ( this ) ;
rendererWindow = hw ;
connect ( this , & RendererStack : : blitToRenderer , hw , & OpenGLRenderer : : onBlit , Qt : : QueuedConnection ) ;
connect ( hw , & OpenGLRenderer : : initialized , [ = ] ( ) {
2022-04-21 16:32:48 +06:00
/* Buffers are available only after initialization. */
2022-02-27 14:56:51 +02:00
imagebufs = rendererWindow - > getBuffers ( ) ;
endblit ( ) ;
emit rendererChanged ( ) ;
} ) ;
connect ( hw , & OpenGLRenderer : : errorInitializing , [ = ] ( ) {
2022-04-21 16:32:48 +06:00
/* Renderer not could initialize, fallback to software. */
2022-03-05 02:57:57 +02:00
imagebufs = { } ;
2022-02-27 14:56:51 +02:00
QTimer : : singleShot ( 0 , this , [ this ] ( ) { switchRenderer ( Renderer : : Software ) ; } ) ;
} ) ;
current . reset ( this - > createWindowContainer ( hw , this ) ) ;
break ;
}
2022-04-25 16:09:37 +06:00
# if QT_CONFIG(vulkan)
2022-04-21 16:32:46 +06:00
case Renderer : : Vulkan :
2022-11-19 08:49:04 -05:00
{
this - > createWinId ( ) ;
VulkanWindowRenderer * hw = nullptr ;
try {
hw = new VulkanWindowRenderer ( this ) ;
} catch ( std : : runtime_error & e ) {
auto msgBox = new QMessageBox ( QMessageBox : : Critical , " 86Box " , e . what ( ) + QString ( " \n Falling back to software rendering. " ) , QMessageBox : : Ok ) ;
msgBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
msgBox - > show ( ) ;
imagebufs = { } ;
QTimer : : singleShot ( 0 , this , [ this ] ( ) { switchRenderer ( Renderer : : Software ) ; } ) ;
current . reset ( nullptr ) ;
break ;
2023-05-29 01:30:51 -04:00
}
2022-11-19 08:49:04 -05:00
rendererWindow = hw ;
connect ( this , & RendererStack : : blitToRenderer , hw , & VulkanWindowRenderer : : onBlit , Qt : : QueuedConnection ) ;
connect ( hw , & VulkanWindowRenderer : : rendererInitialized , [ = ] ( ) {
/* Buffers are available only after initialization. */
imagebufs = rendererWindow - > getBuffers ( ) ;
endblit ( ) ;
emit rendererChanged ( ) ;
} ) ;
connect ( hw , & VulkanWindowRenderer : : errorInitializing , [ = ] ( ) {
/* Renderer could not initialize, fallback to software. */
auto msgBox = new QMessageBox ( QMessageBox : : Critical , " 86Box " , QString ( " Failed to initialize Vulkan renderer. \n Falling back to software rendering. " ) , QMessageBox : : Ok ) ;
msgBox - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
msgBox - > show ( ) ;
imagebufs = { } ;
QTimer : : singleShot ( 0 , this , [ this ] ( ) { switchRenderer ( Renderer : : Software ) ; } ) ;
} ) ;
current . reset ( this - > createWindowContainer ( hw , this ) ) ;
2022-04-21 16:32:48 +06:00
break ;
2022-11-19 08:49:04 -05:00
}
2022-04-25 16:09:37 +06:00
# endif
2021-12-15 19:58:09 +01:00
}
2022-11-19 08:49:04 -05:00
if ( current . get ( ) = = nullptr )
return ;
2021-12-15 19:58:09 +01:00
current - > setFocusPolicy ( Qt : : NoFocus ) ;
2021-12-18 00:37:30 +06:00
current - > setFocusProxy ( this ) ;
2022-08-10 01:27:54 +06:00
current - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
2022-11-01 00:56:31 +06:00
current - > setStyleSheet ( " background-color: black " ) ;
2021-12-15 20:02:35 +01:00
addWidget ( current . get ( ) ) ;
2021-12-15 21:19:46 +02:00
2021-12-25 15:34:00 +06:00
this - > setStyleSheet ( " background-color: black " ) ;
2021-12-15 21:19:46 +02:00
2022-02-27 14:56:51 +02:00
currentBuf = 0 ;
2024-02-13 18:40:07 +05:00
if ( renderer ! = Renderer : : OpenGL3 & & renderer ! = Renderer : : Vulkan ) {
2022-02-27 14:56:51 +02:00
imagebufs = rendererWindow - > getBuffers ( ) ;
endblit ( ) ;
emit rendererChanged ( ) ;
}
2021-12-15 19:58:09 +01:00
}
2021-12-04 21:33:04 +01:00
// called from blitter thread
2022-02-27 14:56:51 +02:00
void
2024-02-13 18:40:07 +05:00
RendererStack : : blit ( int x , int y , int w , int h )
2021-11-30 16:26:49 +06:00
{
2024-05-03 17:02:13 +02:00
if ( ( x < 0 ) | | ( y < 0 ) | | ( w < = 0 ) | | ( h < = 0 ) | |
( w > 2048 ) | | ( h > 2048 ) | |
( monitors [ m_monitor_index ] . target_buffer = = NULL ) | | imagebufs . empty ( ) | |
std : : get < std : : atomic_flag * > ( imagebufs [ currentBuf ] ) - > test_and_set ( ) ) {
2022-07-04 01:50:42 +06:00
video_blit_complete_monitor ( m_monitor_index ) ;
2021-12-04 21:33:04 +01:00
return ;
}
sx = x ;
sy = y ;
sw = this - > w = w ;
2022-02-27 14:56:51 +02:00
sh = this - > h = h ;
uint8_t * imagebits = std : : get < uint8_t * > ( imagebufs [ currentBuf ] ) ;
for ( int y1 = y ; y1 < ( y + h ) ; y1 + + ) {
2022-04-21 16:32:46 +06:00
auto scanline = imagebits + ( y1 * rendererWindow - > getBytesPerRow ( ) ) + ( x * 4 ) ;
2022-07-04 01:50:42 +06:00
video_copy ( scanline , & ( monitors [ m_monitor_index ] . target_buffer - > line [ y1 ] [ x ] ) , w * 4 ) ;
2022-01-14 12:39:49 +06:00
}
2021-12-04 21:33:04 +01:00
2022-07-07 16:09:50 +06:00
if ( monitors [ m_monitor_index ] . mon_screenshots ) {
video_screenshot_monitor ( ( uint32_t * ) imagebits , x , y , 2048 , m_monitor_index ) ;
2021-12-04 21:33:04 +01:00
}
2022-07-04 01:50:42 +06:00
video_blit_complete_monitor ( m_monitor_index ) ;
2022-01-15 21:45:34 +02:00
emit blitToRenderer ( currentBuf , sx , sy , sw , sh ) ;
currentBuf = ( currentBuf + 1 ) % imagebufs . size ( ) ;
2021-12-04 21:33:04 +01:00
}
2022-07-05 17:57:25 +06:00
2022-11-19 08:49:04 -05:00
void
RendererStack : : closeEvent ( QCloseEvent * event )
2022-07-05 17:57:25 +06:00
{
2022-08-02 00:14:09 +06:00
if ( cpu_thread_run = = 1 | | is_quit = = 0 ) {
2022-07-14 22:16:53 -04:00
event - > accept ( ) ;
2022-08-02 00:14:09 +06:00
main_window - > ui - > actionShow_non_primary_monitors - > setChecked ( false ) ;
2022-07-14 22:16:53 -04:00
return ;
}
2022-07-05 17:57:25 +06:00
event - > ignore ( ) ;
main_window - > close ( ) ;
}
2022-11-19 08:49:04 -05:00
void
RendererStack : : changeEvent ( QEvent * event )
2022-08-14 12:28:36 +06:00
{
if ( m_monitor_index ! = 0 & & isVisible ( ) ) {
monitor_settings [ m_monitor_index ] . mon_window_maximized = isMaximized ( ) ;
config_save ( ) ;
}
}
2023-01-03 15:42:57 +06:00
bool
RendererStack : : event ( QEvent * event )
{
if ( event - > type ( ) = = QEvent : : MouseMove ) {
QMouseEvent * mouse_event = ( QMouseEvent * ) event ;
2023-08-16 19:40:05 +02:00
if ( m_monitor_index > = 1 ) {
2023-10-23 01:21:28 +02:00
if ( mouse_input_mode > = 1 ) {
2023-08-16 19:40:05 +02:00
mouse_x_abs = ( mouse_event - > localPos ( ) . x ( ) ) / ( long double ) width ( ) ;
mouse_y_abs = ( mouse_event - > localPos ( ) . y ( ) ) / ( long double ) height ( ) ;
if ( ! mouse_tablet_in_proximity )
mouse_tablet_in_proximity = mousedata . mouse_tablet_in_proximity ;
}
return QStackedWidget : : event ( event ) ;
2023-01-03 15:42:57 +06:00
}
2023-08-16 19:40:05 +02:00
# ifdef Q_OS_WINDOWS
2023-10-23 01:21:28 +02:00
if ( mouse_input_mode = = 0 ) {
2023-08-16 19:40:05 +02:00
mouse_x_abs = ( mouse_event - > localPos ( ) . x ( ) ) / ( long double ) width ( ) ;
mouse_y_abs = ( mouse_event - > localPos ( ) . y ( ) ) / ( long double ) height ( ) ;
return QStackedWidget : : event ( event ) ;
}
# endif
mouse_x_abs = ( mouse_event - > localPos ( ) . x ( ) ) / ( long double ) width ( ) ;
mouse_y_abs = ( mouse_event - > localPos ( ) . y ( ) ) / ( long double ) height ( ) ;
mouse_tablet_in_proximity = mousedata . mouse_tablet_in_proximity ;
2023-01-03 15:42:57 +06:00
}
2023-08-16 19:40:05 +02:00
2023-01-03 15:42:57 +06:00
return QStackedWidget : : event ( event ) ;
}
2023-08-11 04:45:32 +02:00
void
RendererStack : : setFocusRenderer ( )
{
if ( current )
current - > setFocus ( ) ;
}
void
RendererStack : : onResize ( int width , int height )
{
if ( rendererWindow ) {
rendererWindow - > r_monitor_index = m_monitor_index ;
rendererWindow - > onResize ( width , height ) ;
}
}