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
* Main window module .
2022-02-07 15:00:02 +06:00
*
*
*
2023-01-06 15:36:05 -05:00
* Authors : Joakim L . Gilje < jgilje @ jgilje . net >
2022-02-07 15:00:02 +06:00
* Cacodemon345
* Teemu Korhonen
2022-02-07 15:35:15 +06:00
* dob205
2022-02-07 15:00:02 +06:00
*
2023-01-06 15:36:05 -05:00
* Copyright 2021 Joakim L . Gilje
* Copyright 2021 - 2022 Cacodemon345
* Copyright 2021 - 2022 Teemu Korhonen
* Copyright 2022 dob205
2022-02-07 15:00:02 +06:00
*/
2022-07-05 15:32:50 +06:00
# include <QDebug>
2021-11-25 10:20:56 +01:00
# include "qt_mainwindow.hpp"
# include "ui_qt_mainwindow.h"
2021-12-12 01:16:27 +06:00
# include "qt_specifydimensions.h"
2021-12-12 16:22:35 +06:00
# include "qt_soundgain.hpp"
2021-12-28 16:47:10 +06:00
# include "qt_progsettings.hpp"
2022-05-23 17:29:45 +06:00
# include "qt_mcadevicelist.hpp"
2021-12-12 01:16:27 +06:00
2021-12-27 16:32:03 +06:00
# include "qt_rendererstack.hpp"
2022-01-30 22:13:41 +02:00
# include "qt_renderercommon.hpp"
2021-12-27 16:32:03 +06:00
2021-11-25 10:20:56 +01:00
extern " C " {
# include <86box/86box.h>
# include <86box/config.h>
2021-11-30 16:26:49 +06:00
# include <86box/keyboard.h>
2021-11-25 10:20:56 +01:00
# include <86box/plat.h>
2022-07-09 13:51:12 +06:00
# include <86box/ui.h>
2023-02-01 17:17:56 +01:00
# ifdef DISCORD
# include <86box / discord.h>
# endif
2022-07-12 14:41:38 +06:00
# include <86box/device.h>
2021-11-30 16:26:49 +06:00
# include <86box/video.h>
2023-01-03 15:42:57 +06:00
# include <86box/mouse.h>
2022-06-04 14:15:31 +06:00
# include <86box/machine.h>
2021-12-09 11:55:28 +01:00
# include <86box/vid_ega.h>
2021-12-09 20:10:23 +01:00
# include <86box/version.h>
2023-05-29 01:30:51 -04:00
#if 0
# include <86box/acpi.h> /* Requires timer.h include, which conflicts with Qt headers */
# endif
2023-02-06 01:39:34 +06:00
extern atomic_int acpi_pwrbut_pressed ;
extern int acpi_enabled ;
2022-02-04 15:19:18 +06:00
2022-08-03 13:05:21 +06:00
# ifdef USE_VNC
2022-11-19 08:49:04 -05:00
# include <86box / vnc.h>
2022-08-03 13:05:21 +06:00
# endif
2022-11-19 08:49:04 -05:00
extern int qt_nvr_save ( void ) ;
2022-02-12 17:31:28 +02:00
2022-02-04 15:19:18 +06:00
# ifdef MTR_ENABLED
2022-11-19 08:49:04 -05:00
# include <minitrace / minitrace.h>
2022-02-04 15:19:18 +06:00
# endif
2021-11-25 10:20:56 +01:00
} ;
2021-12-06 10:41:14 +01:00
# include <QGuiApplication>
2021-11-25 10:20:56 +01:00
# include <QWindow>
# include <QTimer>
2021-11-29 17:25:31 +01:00
# include <QThread>
2021-11-25 10:20:56 +01:00
# include <QKeyEvent>
2021-11-29 12:25:27 +01:00
# include <QMessageBox>
2021-12-05 15:57:46 +06:00
# include <QFocusEvent>
2021-12-09 16:27:53 +06:00
# include <QApplication>
# include <QPushButton>
# include <QDesktopServices>
# include <QUrl>
2022-07-10 11:41:02 +06:00
# include <QMenuBar>
2021-12-12 01:16:27 +06:00
# include <QCheckBox>
2021-12-18 01:03:05 +06:00
# include <QActionGroup>
2021-12-27 14:25:18 +02:00
# include <QOpenGLContext>
2021-12-30 23:36:49 +06:00
# include <QScreen>
2022-01-13 09:28:38 +02:00
# include <QString>
2022-08-09 15:35:32 +06:00
# include <QDir>
2022-12-29 00:50:50 +06:00
# include <QSysInfo>
2022-11-03 21:58:54 +06:00
# if QT_CONFIG(vulkan)
2022-11-19 08:49:04 -05:00
# include <QVulkanInstance>
# include <QVulkanFunctions>
2022-11-03 21:58:54 +06:00
# endif
2021-11-25 10:20:56 +01:00
2021-11-30 16:26:49 +06:00
# include <array>
2021-12-06 10:41:14 +01:00
# include <unordered_map>
2021-11-30 16:26:49 +06:00
2021-11-25 10:20:56 +01:00
# include "qt_settings.hpp"
2021-11-30 22:06:41 +01:00
# include "qt_machinestatus.hpp"
2021-12-03 11:38:00 +01:00
# include "qt_mediamenu.hpp"
2022-02-10 15:30:39 +06:00
# include "qt_util.hpp"
2021-11-30 16:26:49 +06:00
2022-03-11 12:03:54 +06:00
# if defined __unix__ && !defined __HAIKU__
2023-04-08 17:58:55 -03:00
# ifndef Q_OS_MACOS
# include "evdev_keyboard.hpp"
# endif
2023-04-07 22:33:53 -03:00
# ifdef XKBCOMMON
# include "xkbcommon_keyboard.hpp"
# ifdef XKBCOMMON_X11
# include "xkbcommon_x11_keyboard.hpp"
# endif
2023-04-08 00:31:25 -03:00
# ifdef WAYLAND
# include "xkbcommon_wl_keyboard.hpp"
# endif
2022-11-19 08:49:04 -05:00
# endif
# include <X11 / Xlib.h>
# include <X11 / keysym.h>
# undef KeyPress
# undef KeyRelease
2021-11-30 16:26:49 +06:00
# endif
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
2023-04-09 17:48:13 -03:00
# include "cocoa_keyboard.hpp"
2022-03-19 23:06:17 +00:00
// The namespace is required to avoid clashing typedefs; we only use this
// header for its #defines anyway.
namespace IOKit {
2022-11-19 08:49:04 -05:00
# include <IOKit / hidsystem / IOLLEvent.h>
2022-03-19 23:06:17 +00:00
}
# endif
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
2022-11-19 08:49:04 -05:00
# include <os / AppKit.h>
# include <os / InterfaceKit.h>
2023-04-09 18:08:03 -03:00
# include "be_keyboard.hpp"
2022-03-11 12:03:54 +06:00
2022-11-19 08:49:04 -05:00
extern MainWindow * main_window ;
2022-03-11 12:03:54 +06:00
2022-11-19 08:49:04 -05:00
filter_result
keyb_filter ( BMessage * message , BHandler * * target , BMessageFilter * filter )
2022-03-11 12:03:54 +06:00
{
if ( message - > what = = B_KEY_DOWN | | message - > what = = B_KEY_UP
2022-11-19 08:49:04 -05:00
| | message - > what = = B_UNMAPPED_KEY_DOWN | | message - > what = = B_UNMAPPED_KEY_UP ) {
2022-03-11 12:03:54 +06:00
int key_state = 0 , key_scancode = 0 ;
key_state = message - > what = = B_KEY_DOWN | | message - > what = = B_UNMAPPED_KEY_DOWN ;
message - > FindInt32 ( " key " , & key_scancode ) ;
QGuiApplication : : postEvent ( main_window , new QKeyEvent ( key_state ? QEvent : : KeyPress : QEvent : : KeyRelease , 0 , QGuiApplication : : keyboardModifiers ( ) , key_scancode , 0 , 0 ) ) ;
2022-11-19 08:49:04 -05:00
if ( key_scancode = = 0x68 & & key_state ) {
2022-03-11 12:03:54 +06:00
QGuiApplication : : postEvent ( main_window , new QKeyEvent ( QEvent : : KeyRelease , 0 , QGuiApplication : : keyboardModifiers ( ) , key_scancode , 0 , 0 ) ) ;
}
}
return B_DISPATCH_MESSAGE ;
}
2022-11-19 08:49:04 -05:00
static BMessageFilter * filter ;
2022-03-11 12:03:54 +06:00
# endif
2022-11-19 08:49:04 -05:00
std : : atomic < bool > blitDummied { false } ;
2022-08-01 00:28:15 +02:00
2022-11-19 08:49:04 -05:00
extern void qt_mouse_capture ( int ) ;
2022-07-03 01:07:13 +06:00
extern " C " void qt_blit ( int x , int y , int w , int h , int monitor_index ) ;
2021-11-25 10:20:56 +01:00
2022-11-19 08:49:04 -05:00
extern MainWindow * main_window ;
2022-08-10 01:27:54 +06:00
2022-11-19 08:49:04 -05:00
MainWindow : : MainWindow ( QWidget * parent )
: QMainWindow ( parent )
, ui ( new Ui : : MainWindow )
2021-11-25 10:20:56 +01:00
{
2022-11-19 08:49:04 -05:00
mm = std : : make_shared < MediaMenu > ( this ) ;
2021-12-03 11:38:00 +01:00
MediaMenu : : ptr = mm ;
2022-11-19 08:49:04 -05:00
status = std : : make_unique < MachineStatus > ( this ) ;
2021-11-25 10:20:56 +01:00
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
filter = new BMessageFilter ( B_PROGRAMMED_DELIVERY , B_ANY_SOURCE , keyb_filter ) ;
2022-11-19 08:49:04 -05:00
( ( BWindow * ) this - > winId ( ) ) - > AddFilter ( filter ) ;
2022-03-11 12:03:54 +06:00
# endif
2022-01-20 20:19:18 +02:00
setUnifiedTitleAndToolBarOnMac ( true ) ;
2022-11-19 08:49:04 -05:00
extern MainWindow * main_window ;
2022-08-03 13:05:21 +06:00
main_window = this ;
2021-11-25 10:20:56 +01:00
ui - > setupUi ( this ) ;
2021-12-04 21:33:04 +01:00
ui - > stackedWidget - > setMouseTracking ( true ) ;
2021-12-12 01:16:27 +06:00
statusBar ( ) - > setVisible ( ! hide_status_bar ) ;
2022-01-10 19:15:07 +02:00
statusBar ( ) - > setStyleSheet ( " QStatusBar::item {border: None; } QStatusBar QLabel { margin-right: 2px; margin-bottom: 1px; } " ) ;
2022-10-31 13:30:19 +06:00
this - > centralWidget ( ) - > setStyleSheet ( " background-color: black; " ) ;
2022-01-09 17:00:16 +02:00
ui - > toolBar - > setVisible ( ! hide_tool_bar ) ;
2022-11-11 21:58:42 +06:00
# ifdef _WIN32
ui - > toolBar - > setBackgroundRole ( QPalette : : Light ) ;
# endif
2022-07-04 01:50:42 +06:00
renderers [ 0 ] . reset ( nullptr ) ;
2022-01-13 08:33:29 +02:00
auto toolbar_spacer = new QWidget ( ) ;
toolbar_spacer - > setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
ui - > toolBar - > addWidget ( toolbar_spacer ) ;
2022-01-22 22:02:57 +02:00
auto toolbar_label = new QLabel ( ) ;
2022-01-13 08:33:29 +02:00
ui - > toolBar - > addWidget ( toolbar_label ) ;
2022-02-07 12:16:07 +06:00
# ifdef RELEASE_BUILD
this - > setWindowIcon ( QIcon ( " :/settings/win/icons/86Box-green.ico " ) ) ;
# elif defined ALPHA_BUILD
2022-02-07 20:31:56 +06:00
this - > setWindowIcon ( QIcon ( " :/settings/win/icons/86Box-red.ico " ) ) ;
2022-02-07 12:16:07 +06:00
# elif defined BETA_BUILD
2021-12-09 16:27:53 +06:00
this - > setWindowIcon ( QIcon ( " :/settings/win/icons/86Box-yellow.ico " ) ) ;
2022-02-07 12:16:07 +06:00
# else
this - > setWindowIcon ( QIcon ( " :/settings/win/icons/86Box-gray.ico " ) ) ;
# endif
2021-12-24 01:57:26 +06:00
this - > setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint , vid_resize ! = 1 ) ;
this - > setWindowFlag ( Qt : : WindowMaximizeButtonHint , vid_resize = = 1 ) ;
2021-12-09 16:27:53 +06:00
2022-02-10 16:55:38 +06:00
QString vmname ( vm_name ) ;
2022-11-19 08:49:04 -05:00
if ( vmname . at ( vmname . size ( ) - 1 ) = = ' " ' | | vmname . at ( vmname . size ( ) - 1 ) = = ' \' ' )
vmname . truncate ( vmname . size ( ) - 1 ) ;
2022-02-10 16:55:38 +06:00
this - > setWindowTitle ( QString ( " %1 - %2 %3 " ) . arg ( vmname , EMU_NAME , EMU_VERSION_FULL ) ) ;
2022-01-13 08:33:29 +02:00
2023-01-03 15:42:57 +06:00
connect ( this , & MainWindow : : hardResetCompleted , this , [ this ] ( ) {
ui - > actionMCA_devices - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_MCA ) ) ;
QApplication : : setOverrideCursor ( Qt : : ArrowCursor ) ;
ui - > menuTablet_tool - > menuAction ( ) - > setVisible ( mouse_mode > = 1 ) ;
} ) ;
2021-11-29 17:25:31 +01:00
connect ( this , & MainWindow : : showMessageForNonQtThread , this , & MainWindow : : showMessage_ , Qt : : BlockingQueuedConnection ) ;
2021-11-29 12:25:27 +01:00
2022-11-19 08:49:04 -05:00
connect ( this , & MainWindow : : setTitle , this , [ this , toolbar_label ] ( const QString & title ) {
if ( dopause & & ! hide_tool_bar ) {
2022-02-13 07:03:37 +05:00
toolbar_label - > setText ( toolbar_label - > text ( ) + tr ( " - PAUSED " ) ) ;
2022-02-13 00:36:47 +06:00
return ;
}
2022-01-13 08:33:29 +02:00
if ( ! hide_tool_bar )
2022-02-20 02:26:27 -05:00
# ifdef _WIN32
2022-01-13 08:33:29 +02:00
toolbar_label - > setText ( title ) ;
2022-01-14 20:25:17 +02:00
# else
{
/* get the percentage and mouse message, TODO: refactor ui_window_title() */
auto parts = title . split ( " - " ) ;
2022-02-05 02:04:32 +06:00
if ( parts . size ( ) > = 2 ) {
if ( parts . size ( ) < 5 )
toolbar_label - > setText ( parts [ 1 ] ) ;
else
toolbar_label - > setText ( QString ( " %1 - %2 " ) . arg ( parts [ 1 ] , parts . last ( ) ) ) ;
}
2022-01-14 20:25:17 +02:00
}
# endif
2022-10-09 14:54:40 -04:00
ui - > actionPause - > setChecked ( false ) ;
ui - > actionPause - > setCheckable ( false ) ;
2021-12-14 20:30:09 +01:00
} ) ;
2021-12-01 15:55:41 +06:00
connect ( this , & MainWindow : : getTitleForNonQtThread , this , & MainWindow : : getTitle_ , Qt : : BlockingQueuedConnection ) ;
2021-12-12 01:16:27 +06:00
connect ( this , & MainWindow : : updateMenuResizeOptions , [ this ] ( ) {
ui - > actionResizable_window - > setEnabled ( vid_resize ! = 2 ) ;
ui - > actionResizable_window - > setChecked ( vid_resize = = 1 ) ;
ui - > menuWindow_scale_factor - > setEnabled ( vid_resize = = 0 ) ;
} ) ;
connect ( this , & MainWindow : : updateWindowRememberOption , [ this ] ( ) {
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
} ) ;
emit updateMenuResizeOptions ( ) ;
2022-02-03 16:55:32 +06:00
connect ( this , & MainWindow : : pollMouse , ui - > stackedWidget , & RendererStack : : mousePoll , Qt : : DirectConnection ) ;
2021-11-25 10:20:56 +01:00
2021-11-30 16:26:49 +06:00
connect ( this , & MainWindow : : setMouseCapture , this , [ this ] ( bool state ) {
2021-11-25 10:20:56 +01:00
mouse_capture = state ? 1 : 0 ;
2021-11-30 16:26:49 +06:00
qt_mouse_capture ( mouse_capture ) ;
2021-12-02 16:26:33 +06:00
if ( mouse_capture ) {
2021-12-29 23:49:09 +06:00
this - > grabKeyboard ( ) ;
2022-04-21 13:56:39 -03:00
if ( ui - > stackedWidget - > mouse_capture_func )
ui - > stackedWidget - > mouse_capture_func ( this - > windowHandle ( ) ) ;
2021-12-02 16:26:33 +06:00
} else {
2021-12-29 23:49:09 +06:00
this - > releaseKeyboard ( ) ;
2022-04-21 13:56:39 -03:00
if ( ui - > stackedWidget - > mouse_uncapture_func )
ui - > stackedWidget - > mouse_uncapture_func ( ) ;
2021-12-02 16:26:33 +06:00
}
2021-11-25 10:20:56 +01:00
} ) ;
2022-03-16 18:19:44 +02:00
connect ( qApp , & QGuiApplication : : applicationStateChanged , [ this ] ( Qt : : ApplicationState state ) {
if ( mouse_capture & & state ! = Qt : : ApplicationState : : ApplicationActive )
emit setMouseCapture ( false ) ;
} ) ;
2021-11-25 10:20:56 +01:00
connect ( this , & MainWindow : : resizeContents , this , [ this ] ( int w , int h ) {
2022-07-16 12:57:35 +06:00
if ( shownonce ) {
2022-11-19 08:49:04 -05:00
if ( resizableonce = = false )
ui - > stackedWidget - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2022-07-16 12:57:35 +06:00
resizableonce = true ;
}
2022-07-04 17:54:38 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_resize ! = 1 ) {
2022-03-23 16:00:36 +06:00
w = ( w / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) ) ;
2022-02-20 02:26:27 -05:00
2022-03-23 16:00:36 +06:00
int modifiedHeight = ( h / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) )
2022-01-09 17:00:16 +02:00
+ menuBar ( ) - > height ( )
+ ( statusBar ( ) - > height ( ) * ! hide_status_bar )
+ ( ui - > toolBar - > height ( ) * ! hide_tool_bar ) ;
2022-02-20 02:26:27 -05:00
2022-12-19 22:52:17 +06:00
ui - > stackedWidget - > resize ( w , ( h / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) ) ) ;
2022-02-11 00:52:25 +06:00
setFixedSize ( w , modifiedHeight ) ;
2021-12-05 20:51:59 +01:00
}
2021-11-25 10:20:56 +01:00
} ) ;
2022-11-19 08:49:04 -05:00
connect ( this , & MainWindow : : resizeContentsMonitor , this , [ this ] ( int w , int h , int monitor_index ) {
2022-07-04 17:54:38 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_resize ! = 1 ) {
2022-07-05 14:09:14 +06:00
qDebug ( ) < < " Resize " ;
2022-07-04 17:54:38 +06:00
w = ( w / ( ! dpi_scale ? util : : screenOfWidget ( renderers [ monitor_index ] . get ( ) ) - > devicePixelRatio ( ) : 1. ) ) ;
int modifiedHeight = ( h / ( ! dpi_scale ? util : : screenOfWidget ( renderers [ monitor_index ] . get ( ) ) - > devicePixelRatio ( ) : 1. ) ) ;
renderers [ monitor_index ] - > setFixedSize ( w , modifiedHeight ) ;
}
} ) ;
2021-12-29 23:49:09 +06:00
connect ( ui - > menubar , & QMenuBar : : triggered , this , [ this ] {
2021-11-25 10:20:56 +01:00
config_save ( ) ;
2022-11-19 08:49:04 -05:00
if ( QApplication : : activeWindow ( ) = = this ) {
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > setFocusRenderer ( ) ;
2021-12-29 23:49:09 +06:00
}
2021-11-25 10:20:56 +01:00
} ) ;
2021-11-30 22:06:41 +01:00
connect ( this , & MainWindow : : updateStatusBarPanes , this , [ this ] {
2021-12-14 00:31:55 +06:00
refreshMediaMenu ( ) ;
2021-11-30 22:06:41 +01:00
} ) ;
2021-12-03 11:38:00 +01:00
connect ( this , & MainWindow : : updateStatusBarPanes , this , & MainWindow : : refreshMediaMenu ) ;
2021-12-14 00:31:55 +06:00
connect ( this , & MainWindow : : updateStatusBarTip , status . get ( ) , & MachineStatus : : updateTip ) ;
2022-03-17 16:31:14 -03:00
connect ( this , & MainWindow : : statusBarMessage , status . get ( ) , & MachineStatus : : message , Qt : : QueuedConnection ) ;
2021-11-28 20:49:05 +01:00
2021-11-25 10:20:56 +01:00
ui - > actionKeyboard_requires_capture - > setChecked ( kbd_req_capture ) ;
ui - > actionRight_CTRL_is_left_ALT - > setChecked ( rctrl_is_lalt ) ;
2021-12-12 01:16:27 +06:00
ui - > actionResizable_window - > setChecked ( vid_resize = = 1 ) ;
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
2021-12-06 21:58:41 +01:00
ui - > menuWindow_scale_factor - > setEnabled ( vid_resize = = 0 ) ;
2021-12-12 01:16:27 +06:00
ui - > actionHiDPI_scaling - > setChecked ( dpi_scale ) ;
ui - > actionHide_status_bar - > setChecked ( hide_status_bar ) ;
2022-01-09 17:00:16 +02:00
ui - > actionHide_tool_bar - > setChecked ( hide_tool_bar ) ;
2022-07-10 11:41:02 +06:00
ui - > actionShow_non_primary_monitors - > setChecked ( show_second_monitors ) ;
2021-12-12 01:16:27 +06:00
ui - > actionUpdate_status_bar_icons - > setChecked ( update_icons ) ;
2022-01-09 01:04:59 +06:00
ui - > actionEnable_Discord_integration - > setChecked ( enable_discord ) ;
2022-08-10 01:27:54 +06:00
ui - > actionApply_fullscreen_stretch_mode_when_maximized - > setChecked ( video_fullscreen_scale_maximized ) ;
2021-12-24 16:31:36 +06:00
2023-02-01 17:17:56 +01:00
# ifndef DISCORD
ui - > actionEnable_Discord_integration - > setVisible ( false ) ;
# endif
2021-12-24 16:31:36 +06:00
# if defined Q_OS_WINDOWS || defined Q_OS_MACOS
/* Make the option visible only if ANGLE is loaded. */
ui - > actionHardware_Renderer_OpenGL_ES - > setVisible ( QOpenGLContext : : openGLModuleType ( ) = = QOpenGLContext : : LibGLES ) ;
2022-11-19 08:49:04 -05:00
if ( QOpenGLContext : : openGLModuleType ( ) ! = QOpenGLContext : : LibGLES & & vid_api = = 2 )
vid_api = 1 ;
2021-12-24 16:31:36 +06:00
# endif
2022-03-01 13:31:19 +06:00
ui - > actionHardware_Renderer_OpenGL - > setVisible ( QOpenGLContext : : openGLModuleType ( ) ! = QOpenGLContext : : LibGLES ) ;
2022-11-19 08:49:04 -05:00
if ( QOpenGLContext : : openGLModuleType ( ) = = QOpenGLContext : : LibGLES & & vid_api = = 1 )
vid_api = 0 ;
2021-12-24 16:31:36 +06:00
2022-03-11 12:03:54 +06:00
if ( ( QApplication : : platformName ( ) . contains ( " eglfs " ) | | QApplication : : platformName ( ) = = " haiku " ) ) {
2022-11-19 08:49:04 -05:00
if ( vid_api > = 1 )
fprintf ( stderr , " OpenGL renderers are unsupported on %s. \n " , QApplication : : platformName ( ) . toUtf8 ( ) . data ( ) ) ;
2021-12-24 16:31:36 +06:00
vid_api = 0 ;
2022-03-11 12:03:54 +06:00
ui - > actionHardware_Renderer_OpenGL - > setVisible ( false ) ;
ui - > actionHardware_Renderer_OpenGL_ES - > setVisible ( false ) ;
2022-04-21 16:32:46 +06:00
ui - > actionVulkan - > setVisible ( false ) ;
2022-03-11 12:03:54 +06:00
ui - > actionOpenGL_3_0_Core - > setVisible ( false ) ;
2021-12-24 16:31:36 +06:00
}
2022-06-22 16:36:38 +06:00
# if !defined Q_OS_WINDOWS
ui - > actionDirect3D_9 - > setVisible ( false ) ;
2022-11-19 08:49:04 -05:00
if ( vid_api = = 5 )
vid_api = 0 ;
2022-06-22 16:36:38 +06:00
# endif
2022-02-27 14:56:51 +02:00
2022-08-03 13:05:21 +06:00
# ifndef USE_VNC
2022-11-19 08:49:04 -05:00
if ( vid_api = = 6 )
vid_api = 0 ;
2022-08-03 13:05:21 +06:00
ui - > actionVNC - > setVisible ( false ) ;
# endif
2022-11-03 21:58:54 +06:00
# if QT_CONFIG(vulkan)
bool vulkanAvailable = false ;
{
QVulkanInstance instance ;
instance . setApiVersion ( QVersionNumber ( 1 , 0 ) ) ;
if ( instance . create ( ) ) {
uint32_t physicalDevices = 0 ;
instance . functions ( ) - > vkEnumeratePhysicalDevices ( instance . vkInstance ( ) , & physicalDevices , nullptr ) ;
if ( physicalDevices ! = 0 ) {
vulkanAvailable = true ;
}
}
}
if ( ! vulkanAvailable )
2022-04-25 16:09:37 +06:00
# endif
2022-11-03 21:58:54 +06:00
{
2022-11-19 08:49:04 -05:00
if ( vid_api = = 4 )
vid_api = 0 ;
2022-11-03 21:58:54 +06:00
ui - > actionVulkan - > setVisible ( false ) ;
}
2022-04-25 16:09:37 +06:00
2022-11-19 08:49:04 -05:00
QActionGroup * actGroup = nullptr ;
2022-02-27 14:56:51 +02:00
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionSoftware_Renderer ) ;
actGroup - > addAction ( ui - > actionHardware_Renderer_OpenGL ) ;
actGroup - > addAction ( ui - > actionHardware_Renderer_OpenGL_ES ) ;
2021-12-27 16:32:03 +06:00
actGroup - > addAction ( ui - > actionOpenGL_3_0_Core ) ;
2022-04-21 16:32:46 +06:00
actGroup - > addAction ( ui - > actionVulkan ) ;
2022-06-22 16:36:38 +06:00
actGroup - > addAction ( ui - > actionDirect3D_9 ) ;
2022-08-03 13:05:21 +06:00
actGroup - > addAction ( ui - > actionVNC ) ;
2022-02-27 14:56:51 +02:00
actGroup - > setExclusive ( true ) ;
2022-11-19 08:49:04 -05:00
connect ( actGroup , & QActionGroup : : triggered , [ this ] ( QAction * action ) {
2022-02-27 14:56:51 +02:00
vid_api = action - > property ( " vid_api " ) . toInt ( ) ;
2022-08-03 13:05:21 +06:00
# ifdef USE_VNC
if ( vnc_enabled & & vid_api ! = 6 ) {
startblit ( ) ;
vnc_enabled = 0 ;
vnc_close ( ) ;
video_setblit ( qt_blit ) ;
endblit ( ) ;
}
# endif
2022-07-05 00:21:30 +06:00
RendererStack : : Renderer newVidApi = RendererStack : : Renderer : : Software ;
2022-11-19 08:49:04 -05:00
switch ( vid_api ) {
case 0 :
2022-08-03 13:05:21 +06:00
newVidApi = RendererStack : : Renderer : : Software ;
2022-11-19 08:49:04 -05:00
break ;
case 1 :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : OpenGL ;
2022-11-19 08:49:04 -05:00
break ;
case 2 :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : OpenGLES ;
2022-11-19 08:49:04 -05:00
break ;
case 3 :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : OpenGL3 ;
2022-11-19 08:49:04 -05:00
break ;
case 4 :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : Vulkan ;
2022-11-19 08:49:04 -05:00
break ;
case 5 :
2023-05-29 01:30:51 -04:00
newVidApi = RendererStack : : Renderer : : Direct3D9 ;
2022-11-19 08:49:04 -05:00
break ;
# ifdef USE_VNC
case 6 :
{
newVidApi = RendererStack : : Renderer : : Software ;
startblit ( ) ;
vnc_enabled = vnc_init ( nullptr ) ;
endblit ( ) ;
}
2022-08-03 13:05:21 +06:00
# endif
2022-02-27 14:56:51 +02:00
}
2022-07-05 00:21:30 +06:00
ui - > stackedWidget - > switchRenderer ( newVidApi ) ;
2022-11-19 08:49:04 -05:00
if ( ! show_second_monitors )
return ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] )
renderers [ i ] - > switchRenderer ( newVidApi ) ;
2022-07-05 00:21:30 +06:00
}
2022-02-27 14:56:51 +02:00
} ) ;
connect ( ui - > stackedWidget , & RendererStack : : rendererChanged , [ this ] ( ) {
ui - > actionRenderer_options - > setVisible ( ui - > stackedWidget - > hasOptions ( ) ) ;
} ) ;
/* Trigger initial renderer switch */
for ( auto action : actGroup - > actions ( ) )
if ( action - > property ( " vid_api " ) . toInt ( ) = = vid_api ) {
action - > setChecked ( true ) ;
emit actGroup - > triggered ( action ) ;
break ;
}
2021-12-06 21:58:41 +01:00
switch ( scale ) {
2022-11-19 08:49:04 -05:00
case 0 :
ui - > action0_5x - > setChecked ( true ) ;
break ;
case 1 :
ui - > action1x - > setChecked ( true ) ;
break ;
case 2 :
ui - > action1_5x - > setChecked ( true ) ;
break ;
case 3 :
ui - > action2x - > setChecked ( true ) ;
break ;
case 4 :
ui - > action3x - > setChecked ( true ) ;
break ;
case 5 :
ui - > action4x - > setChecked ( true ) ;
break ;
case 6 :
ui - > action5x - > setChecked ( true ) ;
break ;
case 7 :
ui - > action6x - > setChecked ( true ) ;
break ;
case 8 :
ui - > action7x - > setChecked ( true ) ;
break ;
case 9 :
ui - > action8x - > setChecked ( true ) ;
break ;
2021-12-06 21:58:41 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > action0_5x ) ;
actGroup - > addAction ( ui - > action1x ) ;
actGroup - > addAction ( ui - > action1_5x ) ;
actGroup - > addAction ( ui - > action2x ) ;
2022-11-01 11:53:49 -07:00
actGroup - > addAction ( ui - > action3x ) ;
actGroup - > addAction ( ui - > action4x ) ;
actGroup - > addAction ( ui - > action5x ) ;
actGroup - > addAction ( ui - > action6x ) ;
actGroup - > addAction ( ui - > action7x ) ;
actGroup - > addAction ( ui - > action8x ) ;
2021-12-06 22:02:18 +01:00
switch ( video_filter_method ) {
2022-11-19 08:49:04 -05:00
case 0 :
ui - > actionNearest - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionLinear - > setChecked ( true ) ;
break ;
2021-12-06 22:02:18 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionNearest ) ;
actGroup - > addAction ( ui - > actionLinear ) ;
2021-12-07 13:47:42 +01:00
switch ( video_fullscreen_scale ) {
2022-11-19 08:49:04 -05:00
case FULLSCR_SCALE_FULL :
ui - > actionFullScreen_stretch - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_43 :
ui - > actionFullScreen_43 - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_KEEPRATIO :
ui - > actionFullScreen_keepRatio - > setChecked ( true ) ;
break ;
case FULLSCR_SCALE_INT :
ui - > actionFullScreen_int - > setChecked ( true ) ;
break ;
2021-12-07 13:47:42 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionFullScreen_stretch ) ;
actGroup - > addAction ( ui - > actionFullScreen_43 ) ;
actGroup - > addAction ( ui - > actionFullScreen_keepRatio ) ;
actGroup - > addAction ( ui - > actionFullScreen_int ) ;
2021-12-08 15:12:21 +01:00
switch ( video_grayscale ) {
2022-11-19 08:49:04 -05:00
case 0 :
ui - > actionRGB_Color - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionRGB_Grayscale - > setChecked ( true ) ;
break ;
case 2 :
ui - > actionAmber_monitor - > setChecked ( true ) ;
break ;
case 3 :
ui - > actionGreen_monitor - > setChecked ( true ) ;
break ;
case 4 :
ui - > actionWhite_monitor - > setChecked ( true ) ;
break ;
2021-12-08 15:12:21 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionRGB_Grayscale ) ;
actGroup - > addAction ( ui - > actionAmber_monitor ) ;
actGroup - > addAction ( ui - > actionGreen_monitor ) ;
actGroup - > addAction ( ui - > actionWhite_monitor ) ;
actGroup - > addAction ( ui - > actionRGB_Color ) ;
2021-12-08 15:17:33 +01:00
switch ( video_graytype ) {
2022-11-19 08:49:04 -05:00
case 0 :
ui - > actionBT601_NTSC_PAL - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionBT709_HDTV - > setChecked ( true ) ;
break ;
case 2 :
ui - > actionAverage - > setChecked ( true ) ;
break ;
2021-12-08 15:17:33 +01:00
}
2021-12-18 01:03:05 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionBT601_NTSC_PAL ) ;
actGroup - > addAction ( ui - > actionBT709_HDTV ) ;
actGroup - > addAction ( ui - > actionAverage ) ;
2021-12-09 11:55:28 +01:00
if ( force_43 > 0 ) {
ui - > actionForce_4_3_display_ratio - > setChecked ( true ) ;
}
if ( enable_overscan > 0 ) {
ui - > actionCGA_PCjr_Tandy_EGA_S_VGA_overscan - > setChecked ( true ) ;
}
if ( vid_cga_contrast > 0 ) {
ui - > actionChange_contrast_for_monochrome_display - > setChecked ( true ) ;
}
2021-12-04 21:33:04 +01:00
2022-01-08 00:53:45 +06:00
# ifdef Q_OS_MACOS
ui - > actionCtrl_Alt_Del - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionTake_screenshot - > setShortcutVisibleInContextMenu ( true ) ;
# endif
2022-11-19 08:49:04 -05:00
if ( ! vnc_enabled )
video_setblit ( qt_blit ) ;
2022-01-12 20:12:47 +02:00
2022-02-04 15:19:18 +06:00
# ifdef MTR_ENABLED
{
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setVisible ( true ) ;
ui - > actionEnd_trace - > setVisible ( true ) ;
ui - > actionBegin_trace - > setShortcut ( QKeySequence ( Qt : : Key_Control + Qt : : Key_T ) ) ;
ui - > actionEnd_trace - > setShortcut ( QKeySequence ( Qt : : Key_Control + Qt : : Key_T ) ) ;
ui - > actionEnd_trace - > setDisabled ( true ) ;
2022-11-19 08:49:04 -05:00
static auto init_trace = [ & ] {
2022-02-04 15:19:18 +06:00
mtr_init ( " trace.json " ) ;
mtr_start ( ) ;
} ;
2022-11-19 08:49:04 -05:00
static auto shutdown_trace = [ & ] {
2022-02-04 15:19:18 +06:00
mtr_stop ( ) ;
mtr_shutdown ( ) ;
} ;
2022-11-19 08:49:04 -05:00
# ifdef Q_OS_MACOS
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionEnd_trace - > setShortcutVisibleInContextMenu ( true ) ;
2022-11-19 08:49:04 -05:00
# endif
2022-02-04 15:19:18 +06:00
static bool trace = false ;
2022-11-19 08:49:04 -05:00
connect ( ui - > actionBegin_trace , & QAction : : triggered , this , [ this ] {
if ( trace )
return ;
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setDisabled ( true ) ;
ui - > actionEnd_trace - > setDisabled ( false ) ;
2022-02-04 15:19:18 +06:00
init_trace ( ) ;
trace = true ;
} ) ;
2022-11-19 08:49:04 -05:00
connect ( ui - > actionEnd_trace , & QAction : : triggered , this , [ this ] {
if ( ! trace )
return ;
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setDisabled ( false ) ;
ui - > actionEnd_trace - > setDisabled ( true ) ;
2022-02-04 15:19:18 +06:00
shutdown_trace ( ) ;
trace = false ;
} ) ;
}
# endif
2022-02-09 00:47:05 +06:00
2022-02-10 00:50:37 +06:00
setContextMenuPolicy ( Qt : : PreventContextMenu ) ;
2022-07-04 01:50:42 +06:00
connect ( this , & MainWindow : : initRendererMonitor , this , & MainWindow : : initRendererMonitorSlot ) ;
connect ( this , & MainWindow : : initRendererMonitorForNonQtThread , this , & MainWindow : : initRendererMonitorSlot , Qt : : BlockingQueuedConnection ) ;
connect ( this , & MainWindow : : destroyRendererMonitor , this , & MainWindow : : destroyRendererMonitorSlot ) ;
connect ( this , & MainWindow : : destroyRendererMonitorForNonQtThread , this , & MainWindow : : destroyRendererMonitorSlot , Qt : : BlockingQueuedConnection ) ;
2022-07-30 00:09:09 +06:00
# ifdef Q_OS_MACOS
2022-11-19 08:49:04 -05:00
QTimer : : singleShot ( 0 , this , [ this ] ( ) {
for ( auto curObj : this - > menuBar ( ) - > children ( ) ) {
if ( qobject_cast < QMenu * > ( curObj ) ) {
auto menu = qobject_cast < QMenu * > ( curObj ) ;
menu - > setSeparatorsCollapsible ( false ) ;
for ( auto curObj2 : menu - > children ( ) ) {
if ( qobject_cast < QMenu * > ( curObj2 ) ) {
auto menu2 = qobject_cast < QMenu * > ( curObj2 ) ;
menu2 - > setSeparatorsCollapsible ( false ) ;
}
}
}
}
} ) ;
2022-07-30 00:09:09 +06:00
# endif
2023-01-03 15:42:57 +06:00
actGroup = new QActionGroup ( this ) ;
actGroup - > addAction ( ui - > actionCursor_Puck ) ;
actGroup - > addAction ( ui - > actionPen ) ;
if ( tablet_tool_type = = 1 ) {
ui - > actionPen - > setChecked ( true ) ;
} else {
ui - > actionCursor_Puck - > setChecked ( true ) ;
}
2023-04-07 22:33:53 -03:00
2023-04-08 00:31:25 -03:00
# ifdef XKBCOMMON
# ifdef XKBCOMMON_X11
2023-04-07 22:33:53 -03:00
if ( QApplication : : platformName ( ) . contains ( " xcb " ) )
xkbcommon_x11_init ( ) ;
2023-04-08 00:31:25 -03:00
else
# endif
# ifdef WAYLAND
if ( QApplication : : platformName ( ) . contains ( " wayland " ) )
xkbcommon_wl_init ( ) ;
else
# endif
{ }
2023-04-07 22:33:53 -03:00
# endif
2021-11-25 10:20:56 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : closeEvent ( QCloseEvent * event )
{
2022-03-10 23:14:13 +02:00
if ( mouse_capture ) {
event - > ignore ( ) ;
return ;
}
2022-11-19 08:49:04 -05:00
if ( confirm_exit & & confirm_exit_cmdl & & cpu_thread_run ) {
2022-01-07 16:21:40 +06:00
QMessageBox questionbox ( QMessageBox : : Icon : : Question , " 86Box " , tr ( " Are you sure you want to exit 86Box? " ) , QMessageBox : : Yes | QMessageBox : : No , this ) ;
2022-11-19 08:49:04 -05:00
QCheckBox * chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
2021-12-12 01:16:27 +06:00
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! confirm_exit ) ;
2022-02-27 14:56:51 +02:00
2021-12-12 01:16:27 +06:00
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
confirm_exit = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
if ( questionbox . result ( ) = = QMessageBox : : No ) {
confirm_exit = true ;
event - > ignore ( ) ;
return ;
}
}
if ( window_remember ) {
window_w = ui - > stackedWidget - > width ( ) ;
window_h = ui - > stackedWidget - > height ( ) ;
if ( ! QApplication : : platformName ( ) . contains ( " wayland " ) ) {
window_x = this - > geometry ( ) . x ( ) ;
window_y = this - > geometry ( ) . y ( ) ;
}
2022-07-05 16:40:04 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( renderers [ i ] ) {
monitor_settings [ i ] . mon_window_w = renderers [ i ] - > geometry ( ) . width ( ) ;
monitor_settings [ i ] . mon_window_h = renderers [ i ] - > geometry ( ) . height ( ) ;
2022-11-19 08:49:04 -05:00
if ( QApplication : : platformName ( ) . contains ( " wayland " ) )
continue ;
2022-07-05 16:40:04 +06:00
monitor_settings [ i ] . mon_window_x = renderers [ i ] - > geometry ( ) . x ( ) ;
monitor_settings [ i ] . mon_window_y = renderers [ i ] - > geometry ( ) . y ( ) ;
}
}
2021-12-12 01:16:27 +06:00
}
2022-04-21 16:32:48 +06:00
2022-04-21 13:56:39 -03:00
if ( ui - > stackedWidget - > mouse_exit_func )
ui - > stackedWidget - > mouse_exit_func ( ) ;
2022-04-21 16:32:48 +06:00
2022-04-24 00:58:08 +06:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Software ) ;
2022-07-05 16:40:04 +06:00
qt_nvr_save ( ) ;
config_save ( ) ;
2022-05-04 13:13:03 +06:00
QApplication : : processEvents ( ) ;
2022-07-05 16:40:04 +06:00
cpu_thread_run = 0 ;
2021-12-12 01:16:27 +06:00
event - > accept ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : initRendererMonitorSlot ( int monitor_index )
2022-07-04 01:50:42 +06:00
{
2022-11-19 08:49:04 -05:00
auto & secondaryRenderer = this - > renderers [ monitor_index ] ;
2022-07-04 01:50:42 +06:00
secondaryRenderer . reset ( new RendererStack ( nullptr , monitor_index ) ) ;
if ( secondaryRenderer ) {
2022-11-19 08:49:04 -05:00
connect ( secondaryRenderer . get ( ) , & RendererStack : : rendererChanged , this , [ this , monitor_index ] {
2022-07-04 01:50:42 +06:00
this - > renderers [ monitor_index ] - > show ( ) ;
} ) ;
2022-07-05 17:57:25 +06:00
secondaryRenderer - > setWindowFlags ( Qt : : CustomizeWindowHint | Qt : : WindowTitleHint | Qt : : WindowCloseButtonHint ) ;
2022-07-04 01:50:42 +06:00
secondaryRenderer - > setWindowTitle ( QObject : : tr ( " 86Box Monitor # " ) + QString : : number ( monitor_index + 1 ) ) ;
2022-07-05 16:40:04 +06:00
2022-07-04 01:50:42 +06:00
if ( vid_resize = = 2 ) {
secondaryRenderer - > setFixedSize ( fixed_size_x , fixed_size_y ) ;
}
secondaryRenderer - > setWindowIcon ( this - > windowIcon ( ) ) ;
2022-07-10 11:41:02 +06:00
if ( show_second_monitors ) {
secondaryRenderer - > show ( ) ;
if ( window_remember ) {
secondaryRenderer - > setGeometry ( monitor_settings [ monitor_index ] . mon_window_x < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_x ,
2022-11-19 08:49:04 -05:00
monitor_settings [ monitor_index ] . mon_window_y < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_y ,
monitor_settings [ monitor_index ] . mon_window_w > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_w ,
monitor_settings [ monitor_index ] . mon_window_h > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_h ) ;
2022-07-10 11:41:02 +06:00
}
2022-08-14 12:28:36 +06:00
if ( monitor_settings [ monitor_index ] . mon_window_maximized ) {
secondaryRenderer - > showMaximized ( ) ;
}
2022-11-19 08:49:04 -05:00
secondaryRenderer - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2023-03-04 23:10:43 +06:00
secondaryRenderer - > setMouseTracking ( true ) ;
2022-07-10 11:41:02 +06:00
}
2023-03-04 23:10:43 +06:00
connect ( this , & MainWindow : : pollMouse , secondaryRenderer . get ( ) , & RendererStack : : mousePoll , Qt : : DirectConnection ) ;
2022-07-04 01:50:42 +06:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : destroyRendererMonitorSlot ( int monitor_index )
2022-07-04 01:50:42 +06:00
{
if ( this - > renderers [ monitor_index ] ) {
2022-07-05 14:09:14 +06:00
if ( window_remember ) {
monitor_settings [ monitor_index ] . mon_window_w = renderers [ monitor_index ] - > geometry ( ) . width ( ) ;
monitor_settings [ monitor_index ] . mon_window_h = renderers [ monitor_index ] - > geometry ( ) . height ( ) ;
monitor_settings [ monitor_index ] . mon_window_x = renderers [ monitor_index ] - > geometry ( ) . x ( ) ;
monitor_settings [ monitor_index ] . mon_window_y = renderers [ monitor_index ] - > geometry ( ) . y ( ) ;
}
config_save ( ) ;
2022-07-04 01:50:42 +06:00
this - > renderers [ monitor_index ] . release ( ) - > deleteLater ( ) ;
2023-01-26 14:29:40 +06:00
ui - > stackedWidget - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-04 01:50:42 +06:00
}
}
2022-11-19 08:49:04 -05:00
MainWindow : : ~ MainWindow ( )
{
2021-11-25 10:20:56 +01:00
delete ui ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : showEvent ( QShowEvent * event )
{
if ( shownonce )
return ;
2021-12-24 01:57:26 +06:00
shownonce = true ;
2022-08-01 17:36:46 +06:00
if ( window_remember ) {
2022-11-19 08:49:04 -05:00
if ( window_w = = 0 )
window_w = 320 ;
if ( window_h = = 0 )
window_h = 200 ;
2022-08-01 17:36:46 +06:00
}
2021-12-12 01:16:27 +06:00
if ( window_remember & & ! QApplication : : platformName ( ) . contains ( " wayland " ) ) {
2022-02-09 16:45:57 +06:00
setGeometry ( window_x , window_y , window_w , window_h + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2021-12-12 01:16:27 +06:00
}
if ( vid_resize = = 2 ) {
2022-11-19 08:49:04 -05:00
setFixedSize ( fixed_size_x , fixed_size_y + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2022-01-09 17:00:16 +02:00
2022-07-04 01:50:42 +06:00
monitors [ 0 ] . mon_scrnsz_x = fixed_size_x ;
monitors [ 0 ] . mon_scrnsz_y = fixed_size_y ;
2021-12-12 01:16:27 +06:00
}
2022-07-11 20:52:04 +06:00
if ( window_remember & & vid_resize = = 1 ) {
ui - > stackedWidget - > setFixedSize ( window_w , window_h ) ;
2022-07-12 17:28:05 +06:00
QApplication : : processEvents ( ) ;
this - > adjustSize ( ) ;
2022-07-11 20:52:04 +06:00
}
2022-11-01 00:56:31 +06:00
if ( start_in_fullscreen ) {
start_in_fullscreen = 0 ;
QTimer : : singleShot ( 0 , ui - > actionFullscreen , & QAction : : trigger ) ;
}
2021-12-12 01:16:27 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionKeyboard_requires_capture_triggered ( )
{
2021-11-25 10:20:56 +01:00
kbd_req_capture ^ = 1 ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRight_CTRL_is_left_ALT_triggered ( )
{
2021-11-25 10:20:56 +01:00
rctrl_is_lalt ^ = 1 ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHard_Reset_triggered ( )
{
if ( confirm_reset ) {
2022-01-07 16:41:57 +06:00
QMessageBox questionbox ( QMessageBox : : Icon : : Question , " 86Box " , tr ( " Are you sure you want to hard reset the emulated machine? " ) , QMessageBox : : NoButton , this ) ;
2022-07-11 03:26:55 +02:00
questionbox . addButton ( tr ( " Reset " ) , QMessageBox : : AcceptRole ) ;
questionbox . addButton ( tr ( " Don't reset " ) , QMessageBox : : RejectRole ) ;
2022-01-07 16:41:57 +06:00
QCheckBox * chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! confirm_reset ) ;
2022-02-27 14:56:51 +02:00
2022-01-07 16:41:57 +06:00
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
confirm_reset = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
2022-11-19 08:49:04 -05:00
if ( questionbox . result ( ) = = QDialog : : Accepted ) {
2022-01-07 16:41:57 +06:00
confirm_reset = true ;
return ;
}
}
config_changed = 2 ;
2021-11-25 10:20:56 +01:00
pc_reset_hard ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionCtrl_Alt_Del_triggered ( )
{
2021-11-25 10:20:56 +01:00
pc_send_cad ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionCtrl_Alt_Esc_triggered ( )
{
2021-11-25 10:20:56 +01:00
pc_send_cae ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionPause_triggered ( )
{
2021-11-25 10:20:56 +01:00
plat_pause ( dopause ^ 1 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionExit_triggered ( )
{
2021-11-25 10:20:56 +01:00
close ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionSettings_triggered ( )
{
2021-12-01 14:50:49 +06:00
int currentPause = dopause ;
plat_pause ( 1 ) ;
Settings settings ( this ) ;
settings . setModal ( true ) ;
settings . setWindowModality ( Qt : : WindowModal ) ;
2021-11-25 10:20:56 +01:00
settings . exec ( ) ;
switch ( settings . result ( ) ) {
2022-11-19 08:49:04 -05:00
case QDialog : : Accepted :
/*
pc_reset_hard_close ( ) ;
settings . save ( ) ;
config_changed = 2 ;
pc_reset_hard_init ( ) ;
*/
settings . save ( ) ;
config_changed = 2 ;
pc_reset_hard ( ) ;
break ;
case QDialog : : Rejected :
break ;
2021-11-25 10:20:56 +01:00
}
2021-12-01 14:50:49 +06:00
plat_pause ( currentPause ) ;
2021-11-25 10:20:56 +01:00
}
2023-04-09 19:26:56 -03:00
void
MainWindow : : processKeyboardInput ( bool down , uint32_t keycode )
2021-11-30 16:26:49 +06:00
{
2023-04-09 19:26:56 -03:00
# if defined(Q_OS_WINDOWS) /* non-raw input */
keycode & = 0xffff ;
2022-03-19 23:06:17 +00:00
# elif defined(Q_OS_MACOS)
2023-04-09 19:26:56 -03:00
keycode = ( keycode < 127 ) ? cocoa_keycodes [ keycode ] : 0 ;
2022-03-11 12:03:54 +06:00
# elif defined(__HAIKU__)
2023-04-09 19:26:56 -03:00
keycode = be_keycodes [ keycode ] ;
2021-11-30 16:26:49 +06:00
# else
2023-04-07 22:33:53 -03:00
# ifdef XKBCOMMON
2023-04-08 18:58:26 -03:00
if ( xkbcommon_keymap )
2023-04-09 19:26:56 -03:00
keycode = xkbcommon_translate ( keycode ) ;
2023-04-08 18:58:26 -03:00
else
2023-04-08 17:58:55 -03:00
# endif
# ifdef EVDEV_KEYBOARD_HPP
2023-04-09 19:26:56 -03:00
keycode = evdev_translate ( keycode - 8 ) ;
2023-04-08 18:58:26 -03:00
# else
2023-04-09 19:26:56 -03:00
keycode = 0 ;
2023-04-07 22:33:53 -03:00
# endif
2021-11-30 16:26:49 +06:00
# endif
2023-04-09 19:26:56 -03:00
/* Apply special cases. */
switch ( keycode ) {
2023-04-09 19:49:25 -03:00
case 0x54 : /* Alt + Print Screen (special case, i.e. evdev SELECTIVE_SCREENSHOT) */
/* Send Alt as well. */
if ( down ) {
keyboard_input ( down , 0x38 ) ;
} else {
keyboard_input ( down , keycode ) ;
keycode = 0x38 ;
}
break ;
2023-06-26 21:27:37 -03:00
case 0x80 . . . 0xff : /* regular break codes */
2023-04-11 11:58:11 -03:00
case 0x10b : /* Microsoft scroll up normal */
2023-06-26 21:27:37 -03:00
case 0x180 . . . 0x1ff : /* E0 break codes (including Microsoft scroll down normal) */
/* This key uses a break code as make. Send it manually, only on press. */
2023-04-11 11:58:11 -03:00
if ( down ) {
2023-06-26 21:27:37 -03:00
if ( keycode & 0x100 )
keyboard_send ( 0xe0 ) ;
2023-04-11 11:58:11 -03:00
keyboard_send ( keycode & 0xff ) ;
}
return ;
2023-04-09 19:26:56 -03:00
case 0x11d : /* Right Ctrl */
if ( rctrl_is_lalt )
keycode = 0x38 ; /* map to Left Alt */
break ;
case 0x137 : /* Print Screen */
if ( keyboard_recv ( 0x38 ) | | keyboard_recv ( 0x138 ) ) { /* Alt+ */
keycode = 0x54 ;
} else if ( down ) {
keyboard_input ( down , 0x12a ) ;
} else {
keyboard_input ( down , keycode ) ;
keycode = 0x12a ;
}
break ;
case 0x145 : /* Pause */
if ( keyboard_recv ( 0x1d ) | | keyboard_recv ( 0x11d ) ) { /* Ctrl+ */
keycode = 0x146 ;
} else {
keyboard_input ( down , 0xe11d ) ;
keycode & = 0x00ff ;
}
break ;
}
keyboard_input ( down , keycode ) ;
2021-11-30 16:26:49 +06:00
}
2021-11-25 10:20:56 +01:00
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
// These modifiers are listed as "device-dependent" in IOLLEvent.h, but
// that's followed up with "(really?)". It's the only way to distinguish
// left and right modifiers with Qt 6 on macOS, so let's just roll with it.
static std : : unordered_map < uint32_t , uint16_t > mac_modifiers_to_xt = {
2022-11-19 08:49:04 -05:00
{ NX_DEVICELCTLKEYMASK , 0x1D } ,
{ NX_DEVICELSHIFTKEYMASK , 0x2A } ,
{ NX_DEVICERSHIFTKEYMASK , 0x36 } ,
{ NX_DEVICELCMDKEYMASK , 0x15B } ,
{ NX_DEVICERCMDKEYMASK , 0x15C } ,
{ NX_DEVICELALTKEYMASK , 0x38 } ,
{ NX_DEVICERALTKEYMASK , 0x138 } ,
{ NX_DEVICE_ALPHASHIFT_STATELESS_MASK , 0x3A } ,
{ NX_DEVICERCTLKEYMASK , 0x11D } ,
2022-03-19 23:06:17 +00:00
} ;
2023-04-10 12:57:42 -03:00
static bool mac_iso_swap = false ;
2022-03-19 23:06:17 +00:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : processMacKeyboardInput ( bool down , const QKeyEvent * event )
{
2022-03-19 23:06:17 +00:00
// Per QTBUG-69608 (https://bugreports.qt.io/browse/QTBUG-69608),
// QKeyEvents QKeyEvents for presses/releases of modifiers on macOS give
// nativeVirtualKey() == 0 (at least in Qt 6). Handle this by manually
// processing the nativeModifiers(). We need to check whether the key() is
// a known modifier because because kVK_ANSI_A is also 0, so the
// nativeVirtualKey() == 0 condition is ambiguous...
if ( event - > nativeVirtualKey ( ) = = 0
& & ( event - > key ( ) = = Qt : : Key_Shift
| | event - > key ( ) = = Qt : : Key_Control
| | event - > key ( ) = = Qt : : Key_Meta
| | event - > key ( ) = = Qt : : Key_Alt
| | event - > key ( ) = = Qt : : Key_AltGr
| | event - > key ( ) = = Qt : : Key_CapsLock ) ) {
// We only process one modifier at a time since events from Qt seem to
// always be non-coalesced (NX_NONCOALESCEDMASK is always set).
uint32_t changed_modifiers = last_modifiers ^ event - > nativeModifiers ( ) ;
2022-11-19 08:49:04 -05:00
for ( auto const & pair : mac_modifiers_to_xt ) {
2022-03-19 23:06:17 +00:00
if ( changed_modifiers & pair . first ) {
last_modifiers ^ = pair . first ;
keyboard_input ( down , pair . second ) ;
return ;
}
}
// Caps Lock seems to be delivered as a single key press event when
// enabled and a single key release event when disabled, so we can't
// detect Caps Lock being held down; just send an infinitesimally-long
// press and release as a compromise.
//
// The event also doesn't get delivered if you turn Caps Lock off after
// turning it on when the window isn't focused. Doing better than this
// probably requires bypassing Qt input processing.
//
// It's possible that other lock keys get delivered in this way, but
// standard Apple keyboards don't have them, so this is untested.
if ( event - > key ( ) = = Qt : : Key_CapsLock ) {
2023-04-09 19:26:56 -03:00
keyboard_input ( 1 , 0x3a ) ;
keyboard_input ( 0 , 0x3a ) ;
2022-03-19 23:06:17 +00:00
}
} else {
2023-04-10 12:57:42 -03:00
/* Apple ISO keyboards are notorious for swapping ISO_Section and ANSI_Grave
on * some * layouts and / or models . While macOS can sort this mess out at
keymap level , it still provides applications with unfiltered , ambiguous
keycodes , so we have to disambiguate them by making some bold assumptions
about the user ' s keyboard layout based on the OS - provided key mappings . */
auto nvk = event - > nativeVirtualKey ( ) ;
if ( ( nvk = = 0x0a ) | | ( nvk = = 0x32 ) ) {
/* Flaws:
- Layouts with ` ~ on ISO_Section are partially detected due to a conflict with ANSI
- Czech and Slovak are not detected as they have < > ANSI_Grave and \ | ISO_Section ( differing from PC actually )
- Italian is partially detected due to \ | conflicting with Brazilian
- Romanian third level ANSI_Grave is unknown
- Russian clusters < > , plusminus and paragraph into a four - level ANSI_Grave , with the aforementioned ` ~ on ISO_Section */
auto key = event - > key ( ) ;
if ( ( nvk = = 0x32 ) & & ( /* system reports ANSI_Grave for ISO_Section keys: */
( key = = Qt : : Key_Less ) | | ( key = = Qt : : Key_Greater ) | | /* Croatian, French, German, Icelandic, Italian, Norwegian, Portuguese, Spanish, Spanish Latin America, Turkish Q */
( key = = Qt : : Key_Ugrave ) | | /* French Canadian */
( key = = Qt : : Key_Icircumflex ) | | /* Romanian */
( key = = Qt : : Key_Iacute ) | | /* Hungarian */
( key = = Qt : : Key_BracketLeft ) | | ( key = = Qt : : Key_BracketRight ) | | /* Russian upper two levels */
( key = = Qt : : Key_W ) /* Turkish F */
) )
mac_iso_swap = true ;
else if ( ( nvk = = 0x0a ) & & ( /* system reports ISO_Section for ANSI_Grave keys: */
( key = = Qt : : Key_paragraph ) | | ( key = = Qt : : Key_plusminus ) | | /* Arabic, British, Bulgarian, Danish shifted, Dutch, Greek, Hebrew, Hungarian shifted, International English, Norwegian shifted, Portuguese, Russian lower two levels, Swiss unshifted, Swedish unshifted, Turkish F */
( key = = Qt : : Key_At ) | | ( key = = Qt : : Key_NumberSign ) | | /* Belgian, French */
( key = = Qt : : Key_Apostrophe ) | | /* Brazilian unshifted */
( key = = Qt : : Key_QuoteDbl ) | | /* Brazilian shifted, Turkish Q unshifted */
( key = = Qt : : Key_QuoteLeft ) | | /* Croatian (right quote unknown) */
( key = = Qt : : Key_Dollar ) | | /* Danish unshifted */
2023-04-10 15:21:14 -03:00
( key = = Qt : : Key_AsciiCircum ) | | ( key = = 0x1ffffff ) | | /* German unshifted (0x1ffffff according to one tester), Polish unshifted */
2023-04-10 12:57:42 -03:00
( key = = Qt : : Key_degree ) | | /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */
( key = = Qt : : Key_0 ) | | /* Hungarian unshifted */
( key = = Qt : : Key_diaeresis ) | | /* Icelandic shifted */
( key = = Qt : : Key_acute ) | | /* Norwegian unshifted */
( key = = Qt : : Key_Asterisk ) | | /* Polish shifted */
( key = = Qt : : Key_masculine ) | | ( key = = Qt : : Key_ordfeminine ) | | /* Spanish (masculine unconfirmed) */
( key = = Qt : : Key_Eacute ) | | /* Turkish Q shifted */
( key = = Qt : : Key_Slash ) /* French Canadian unshifted, Ukrainian shifted */
) )
mac_iso_swap = true ;
2023-04-10 15:21:14 -03:00
#if 0
2023-04-10 12:57:42 -03:00
if ( down ) {
QMessageBox questionbox ( QMessageBox : : Icon : : Information , QString ( " Mac key swap test " ) , QString ( " nativeVirtualKey 0x%1 \n nativeScanCode 0x%2 \n key 0x%3 \n mac_iso_swap %4 " ) . arg ( nvk , 0 , 16 ) . arg ( event - > nativeScanCode ( ) , 0 , 16 ) . arg ( key , 0 , 16 ) . arg ( mac_iso_swap ? " yes " : " no " ) , QMessageBox : : Ok , this ) ;
questionbox . exec ( ) ;
}
2023-04-10 15:21:14 -03:00
# endif
2023-04-10 12:57:42 -03:00
if ( mac_iso_swap )
nvk = ( nvk = = 0x0a ) ? 0x32 : 0x0a ;
}
processKeyboardInput ( down , nvk ) ;
2022-03-19 23:06:17 +00:00
}
}
# endif
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullscreen_triggered ( )
{
2021-11-30 21:26:51 +01:00
if ( video_fullscreen > 0 ) {
2021-12-23 17:05:11 +06:00
showNormal ( ) ;
2022-11-19 08:49:04 -05:00
if ( vid_api = = 5 )
QTimer : : singleShot ( 0 , this , [ this ] ( ) { ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Direct3D9 ) ; } ) ;
2021-12-09 19:48:56 +01:00
ui - > menubar - > show ( ) ;
2022-11-19 08:49:04 -05:00
if ( ! hide_status_bar )
ui - > statusbar - > show ( ) ;
if ( ! hide_tool_bar )
ui - > toolBar - > show ( ) ;
2021-11-30 21:26:51 +01:00
video_fullscreen = 0 ;
2021-12-25 15:28:48 +06:00
if ( vid_resize ! = 1 ) {
2022-07-13 20:39:29 +06:00
emit resizeContents ( vid_resize = = 2 ? fixed_size_x : monitors [ 0 ] . mon_scrnsz_x , vid_resize = = 2 ? fixed_size_y : monitors [ 0 ] . mon_scrnsz_y ) ;
2021-12-25 15:28:48 +06:00
}
2021-11-30 21:26:51 +01:00
} else {
2022-11-19 08:49:04 -05:00
if ( video_fullscreen_first ) {
2022-03-16 18:19:44 +02:00
bool wasCaptured = mouse_capture = = 1 ;
2022-02-13 07:09:30 +05:00
QMessageBox questionbox ( QMessageBox : : Icon : : Information , tr ( " Entering fullscreen mode " ) , tr ( " Press Ctrl+Alt+PgDn to return to windowed mode. " ) , QMessageBox : : Ok , this ) ;
2022-11-19 08:49:04 -05:00
QCheckBox * chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
2022-01-12 01:09:43 +06:00
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! video_fullscreen_first ) ;
2022-02-27 14:56:51 +02:00
2022-01-12 01:09:43 +06:00
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
video_fullscreen_first = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
config_save ( ) ;
2022-03-16 18:19:44 +02:00
2022-07-30 14:38:02 +06:00
/* (re-capture mouse after dialog). */
2022-03-16 18:19:44 +02:00
if ( wasCaptured )
emit setMouseCapture ( true ) ;
2022-01-12 01:09:43 +06:00
}
2022-02-27 14:56:51 +02:00
video_fullscreen = 1 ;
2021-12-25 15:28:48 +06:00
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-12-09 19:48:56 +01:00
ui - > menubar - > hide ( ) ;
ui - > statusbar - > hide ( ) ;
2022-01-09 17:00:16 +02:00
ui - > toolBar - > hide ( ) ;
2022-10-30 23:29:23 +06:00
ui - > stackedWidget - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-11-30 21:26:51 +01:00
showFullScreen ( ) ;
2022-11-19 08:49:04 -05:00
if ( vid_api = = 5 )
QTimer : : singleShot ( 0 , this , [ this ] ( ) { ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Direct3D9 ) ; } ) ;
2021-11-30 21:26:51 +01:00
}
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > onResize ( width ( ) , height ( ) ) ;
2021-11-25 10:20:56 +01:00
}
2021-11-29 17:25:31 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : getTitle_ ( wchar_t * title )
2021-12-01 15:55:41 +06:00
{
this - > windowTitle ( ) . toWCharArray ( title ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : getTitle ( wchar_t * title )
2021-12-01 15:55:41 +06:00
{
if ( QThread : : currentThread ( ) = = this - > thread ( ) ) {
getTitle_ ( title ) ;
} else {
emit getTitleForNonQtThread ( title ) ;
}
}
2022-11-19 08:49:04 -05:00
bool
MainWindow : : eventFilter ( QObject * receiver , QEvent * event )
2021-12-05 15:57:46 +06:00
{
2022-03-21 15:28:43 +06:00
if ( ! dopause & & ( mouse_capture | | ! kbd_req_capture ) ) {
if ( event - > type ( ) = = QEvent : : Shortcut ) {
2022-11-19 08:49:04 -05:00
auto shortcutEvent = ( QShortcutEvent * ) event ;
2022-03-21 15:28:43 +06:00
if ( shortcutEvent - > key ( ) = = ui - > actionExit - > shortcut ( ) ) {
event - > accept ( ) ;
return true ;
}
}
2021-12-05 15:57:46 +06:00
if ( event - > type ( ) = = QEvent : : KeyPress ) {
event - > accept ( ) ;
2022-03-16 18:19:44 +02:00
this - > keyPressEvent ( ( QKeyEvent * ) event ) ;
2021-12-05 15:57:46 +06:00
return true ;
}
if ( event - > type ( ) = = QEvent : : KeyRelease ) {
event - > accept ( ) ;
2022-03-16 18:19:44 +02:00
this - > keyReleaseEvent ( ( QKeyEvent * ) event ) ;
2021-12-05 15:57:46 +06:00
return true ;
}
}
2021-12-06 21:26:17 +01:00
2022-03-16 18:19:44 +02:00
if ( receiver = = this ) {
2022-02-04 15:19:18 +06:00
static auto curdopause = dopause ;
2022-03-16 18:19:44 +02:00
if ( event - > type ( ) = = QEvent : : WindowBlocked ) {
curdopause = dopause ;
plat_pause ( 1 ) ;
emit setMouseCapture ( false ) ;
} else if ( event - > type ( ) = = QEvent : : WindowUnblocked ) {
plat_pause ( curdopause ) ;
}
2022-02-04 15:19:18 +06:00
}
2022-03-16 18:19:44 +02:00
2021-12-05 15:57:46 +06:00
return QMainWindow : : eventFilter ( receiver , event ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : refreshMediaMenu ( )
{
2021-12-03 11:38:00 +01:00
mm - > refresh ( ui - > menuMedia ) ;
2021-12-14 00:31:55 +06:00
status - > refresh ( ui - > statusbar ) ;
2022-06-04 14:15:31 +06:00
ui - > actionMCA_devices - > setVisible ( machine_has_bus ( machine , MACHINE_BUS_MCA ) ) ;
2023-02-06 01:39:34 +06:00
ui - > actionACPI_Shutdown - > setEnabled ( ! ! acpi_enabled ) ;
2021-12-03 11:38:00 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : showMessage ( int flags , const QString & header , const QString & message )
{
2021-11-29 17:25:31 +01:00
if ( QThread : : currentThread ( ) = = this - > thread ( ) ) {
2022-07-09 13:51:12 +06:00
showMessage_ ( flags , header , message ) ;
2021-11-29 17:25:31 +01:00
} else {
2022-07-09 13:51:12 +06:00
emit showMessageForNonQtThread ( flags , header , message ) ;
2021-11-29 17:25:31 +01:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : showMessage_ ( int flags , const QString & header , const QString & message )
{
2021-11-29 17:25:31 +01:00
QMessageBox box ( QMessageBox : : Warning , header , message , QMessageBox : : NoButton , this ) ;
2022-07-09 13:51:12 +06:00
if ( flags & ( MBX_FATAL ) ) {
box . setIcon ( QMessageBox : : Critical ) ;
2022-11-19 08:49:04 -05:00
} else if ( ! ( flags & ( MBX_ERROR | MBX_WARNING ) ) ) {
2022-07-09 13:51:12 +06:00
box . setIcon ( QMessageBox : : Warning ) ;
}
2021-12-10 15:36:55 +06:00
box . setTextFormat ( Qt : : TextFormat : : RichText ) ;
2021-11-29 17:25:31 +01:00
box . exec ( ) ;
2022-11-19 08:49:04 -05:00
if ( cpu_thread_run = = 0 )
QApplication : : exit ( - 1 ) ;
2021-11-29 17:25:31 +01:00
}
2021-11-30 16:26:49 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : keyPressEvent ( QKeyEvent * event )
2021-11-30 16:26:49 +06:00
{
2022-11-19 08:49:04 -05:00
if ( send_keyboard_input & & ! ( kbd_req_capture & & ! mouse_capture ) ) {
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
2023-04-09 16:36:36 -03:00
processMacKeyboardInput ( true , event ) ;
2021-11-30 16:26:49 +06:00
# else
2023-04-09 19:26:56 -03:00
processKeyboardInput ( true , event - > nativeScanCode ( ) ) ;
2023-04-09 16:36:36 -03:00
# endif
2021-12-09 20:59:50 +02:00
}
2021-11-30 21:29:58 +01:00
2023-04-13 22:47:42 +02:00
if ( ! fs_off_signal & & ( video_fullscreen > 0 ) & & keyboard_isfsexit ( ) )
2023-04-13 23:00:01 +02:00
fs_off_signal = true ;
2021-11-30 21:29:58 +01:00
2023-04-13 22:47:42 +02:00
if ( ! fs_on_signal & & ( video_fullscreen = = 0 ) & & keyboard_isfsenter ( ) )
2023-04-13 23:00:01 +02:00
fs_on_signal = true ;
2023-04-13 22:47:42 +02:00
if ( keyboard_ismsexit ( ) )
2021-11-30 21:29:58 +01:00
plat_mouse_capture ( 0 ) ;
2022-08-23 16:32:38 +06:00
if ( ( video_fullscreen > 0 ) & & ( keyboard_recv ( 0x1D ) | | keyboard_recv ( 0x11D ) ) ) {
2022-11-19 08:49:04 -05:00
if ( keyboard_recv ( 0x57 ) )
ui - > actionTake_screenshot - > trigger ( ) ;
else if ( keyboard_recv ( 0x58 ) )
pc_send_cad ( ) ;
2022-08-23 16:32:38 +06:00
}
2021-12-05 15:57:46 +06:00
event - > accept ( ) ;
2021-11-30 16:26:49 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : blitToWidget ( int x , int y , int w , int h , int monitor_index )
2021-12-02 00:47:02 +06:00
{
2022-07-04 01:50:42 +06:00
if ( monitor_index > = 1 ) {
2022-11-19 08:49:04 -05:00
if ( ! blitDummied & & renderers [ monitor_index ] & & renderers [ monitor_index ] - > isVisible ( ) )
renderers [ monitor_index ] - > blit ( x , y , w , h ) ;
else
video_blit_complete_monitor ( monitor_index ) ;
} else
ui - > stackedWidget - > blit ( x , y , w , h ) ;
2021-12-02 00:47:02 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : keyReleaseEvent ( QKeyEvent * event )
2021-11-30 16:26:49 +06:00
{
2022-08-23 16:32:38 +06:00
if ( event - > key ( ) = = Qt : : Key_Pause ) {
2022-09-03 02:28:00 +06:00
if ( keyboard_recv ( 0x38 ) & & keyboard_recv ( 0x138 ) ) {
plat_pause ( dopause ^ 1 ) ;
}
2022-08-23 16:32:38 +06:00
}
2023-04-13 22:47:42 +02:00
2023-06-26 21:17:50 -03:00
if ( fs_off_signal & & ( video_fullscreen > 0 ) & & keyboard_isfsexit ( ) ) {
2023-04-13 22:47:42 +02:00
ui - > actionFullscreen - > trigger ( ) ;
2023-04-13 23:00:01 +02:00
fs_off_signal = false ;
2023-04-13 22:47:42 +02:00
}
2023-06-26 21:17:50 -03:00
if ( fs_on_signal & & ( video_fullscreen = = 0 ) & & keyboard_isfsenter ( ) ) {
2023-04-13 22:47:42 +02:00
ui - > actionFullscreen - > trigger ( ) ;
2023-04-13 23:00:01 +02:00
fs_on_signal = false ;
2023-04-13 22:47:42 +02:00
}
2021-12-09 20:59:50 +02:00
if ( ! send_keyboard_input )
return ;
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
processMacKeyboardInput ( false , event ) ;
2021-11-30 16:26:49 +06:00
# else
2023-04-09 19:26:56 -03:00
processKeyboardInput ( false , event - > nativeScanCode ( ) ) ;
2021-11-30 16:26:49 +06:00
# endif
}
2021-12-04 21:33:04 +01:00
2022-11-19 08:49:04 -05:00
QSize
MainWindow : : getRenderWidgetSize ( )
2021-12-12 01:16:27 +06:00
{
return ui - > stackedWidget - > size ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : focusInEvent ( QFocusEvent * event )
2021-12-05 15:57:46 +06:00
{
2021-12-31 16:47:49 +06:00
this - > grabKeyboard ( ) ;
2021-12-05 15:57:46 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : focusOutEvent ( QFocusEvent * event )
2021-12-05 15:57:46 +06:00
{
this - > releaseKeyboard ( ) ;
2021-12-05 20:51:59 +01:00
}
2021-12-06 21:26:17 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionResizable_window_triggered ( bool checked )
{
2021-12-06 21:26:17 +01:00
if ( checked ) {
vid_resize = 1 ;
2021-12-24 01:57:26 +06:00
setWindowFlag ( Qt : : WindowMaximizeButtonHint ) ;
setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint , false ) ;
2021-12-06 21:26:17 +01:00
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( monitors [ i ] . target_buffer ) {
renderers [ i ] - > setWindowFlag ( Qt : : WindowMaximizeButtonHint ) ;
renderers [ i ] - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
}
}
2021-12-06 21:26:17 +01:00
} else {
vid_resize = 0 ;
2021-12-24 01:57:26 +06:00
setWindowFlag ( Qt : : WindowMaximizeButtonHint , false ) ;
setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( monitors [ i ] . target_buffer ) {
2022-07-05 16:40:04 +06:00
renderers [ i ] - > setWindowFlag ( Qt : : WindowMaximizeButtonHint , false ) ;
2022-07-05 00:21:30 +06:00
emit resizeContentsMonitor ( monitors [ i ] . mon_scrnsz_x , monitors [ i ] . mon_scrnsz_y , i ) ;
}
}
2021-12-06 21:26:17 +01:00
}
2021-12-24 01:57:26 +06:00
show ( ) ;
2022-11-19 08:49:04 -05:00
ui - > menuWindow_scale_factor - > setEnabled ( ! checked ) ;
2022-07-04 01:50:42 +06:00
emit resizeContents ( monitors [ 0 ] . mon_scrnsz_x , monitors [ 0 ] . mon_scrnsz_y ) ;
2022-11-19 08:49:04 -05:00
ui - > stackedWidget - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-07-10 17:06:16 +06:00
if ( monitors [ i ] . target_buffer & & show_second_monitors ) {
renderers [ i ] - > show ( ) ;
2022-11-19 08:49:04 -05:00
renderers [ i ] - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-05 00:21:30 +06:00
QApplication : : processEvents ( ) ;
}
}
2021-12-06 21:26:17 +01:00
}
2021-12-06 21:45:40 +01:00
static void
2022-11-19 08:49:04 -05:00
video_toggle_option ( QAction * action , int * val )
2021-12-06 21:45:40 +01:00
{
startblit ( ) ;
* val ^ = 1 ;
2021-12-08 15:12:21 +01:00
video_copy = ( video_grayscale | | invert_display ) ? video_transform_copy : memcpy ;
2021-12-06 21:45:40 +01:00
action - > setChecked ( * val > 0 ? true : false ) ;
endblit ( ) ;
config_save ( ) ;
2022-12-19 13:30:51 +06:00
reset_screen_size ( ) ;
2021-12-06 21:45:40 +01:00
device_force_redraw ( ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 0 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( monitors [ i ] . target_buffer )
video_force_resize_set_monitor ( 1 , i ) ;
2022-07-05 00:21:30 +06:00
}
2021-12-06 21:45:40 +01:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionInverted_VGA_monitor_triggered ( )
{
2021-12-06 21:45:40 +01:00
video_toggle_option ( ui - > actionInverted_VGA_monitor , & invert_display ) ;
}
2021-12-06 21:58:41 +01:00
2022-11-19 08:49:04 -05:00
static void
update_scaled_checkboxes ( Ui : : MainWindow * ui , QAction * selected )
{
2021-12-06 21:58:41 +01:00
ui - > action0_5x - > setChecked ( ui - > action0_5x = = selected ) ;
ui - > action1x - > setChecked ( ui - > action1x = = selected ) ;
ui - > action1_5x - > setChecked ( ui - > action1_5x = = selected ) ;
ui - > action2x - > setChecked ( ui - > action2x = = selected ) ;
2022-11-01 11:53:49 -07:00
ui - > action3x - > setChecked ( ui - > action3x = = selected ) ;
ui - > action4x - > setChecked ( ui - > action4x = = selected ) ;
ui - > action5x - > setChecked ( ui - > action5x = = selected ) ;
ui - > action6x - > setChecked ( ui - > action6x = = selected ) ;
ui - > action7x - > setChecked ( ui - > action7x = = selected ) ;
ui - > action8x - > setChecked ( ui - > action8x = = selected ) ;
2021-12-06 21:58:41 +01:00
reset_screen_size ( ) ;
device_force_redraw ( ) ;
2022-07-05 00:21:30 +06:00
for ( int i = 0 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( monitors [ i ] . target_buffer )
video_force_resize_set_monitor ( 1 , i ) ;
2022-07-05 00:21:30 +06:00
}
2021-12-06 21:58:41 +01:00
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action0_5x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 0 ;
update_scaled_checkboxes ( ui , ui - > action0_5x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action1x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 1 ;
update_scaled_checkboxes ( ui , ui - > action1x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action1_5x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 2 ;
update_scaled_checkboxes ( ui , ui - > action1_5x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action2x_triggered ( )
{
2021-12-06 21:58:41 +01:00
scale = 3 ;
update_scaled_checkboxes ( ui , ui - > action2x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action3x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 4 ;
update_scaled_checkboxes ( ui , ui - > action3x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action4x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 5 ;
update_scaled_checkboxes ( ui , ui - > action4x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action5x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 6 ;
update_scaled_checkboxes ( ui , ui - > action5x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action6x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 7 ;
update_scaled_checkboxes ( ui , ui - > action6x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action7x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 8 ;
update_scaled_checkboxes ( ui , ui - > action7x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_action8x_triggered ( )
{
2022-11-01 11:53:49 -07:00
scale = 9 ;
update_scaled_checkboxes ( ui , ui - > action8x ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionNearest_triggered ( )
{
2021-12-06 22:02:18 +01:00
video_filter_method = 0 ;
ui - > actionLinear - > setChecked ( false ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionLinear_triggered ( )
{
2021-12-06 22:02:18 +01:00
video_filter_method = 1 ;
ui - > actionNearest - > setChecked ( false ) ;
}
2021-12-07 13:47:42 +01:00
2022-11-19 08:49:04 -05:00
static void
update_fullscreen_scale_checkboxes ( Ui : : MainWindow * ui , QAction * selected )
{
2021-12-07 13:47:42 +01:00
ui - > actionFullScreen_stretch - > setChecked ( ui - > actionFullScreen_stretch = = selected ) ;
ui - > actionFullScreen_43 - > setChecked ( ui - > actionFullScreen_43 = = selected ) ;
ui - > actionFullScreen_keepRatio - > setChecked ( ui - > actionFullScreen_keepRatio = = selected ) ;
ui - > actionFullScreen_int - > setChecked ( ui - > actionFullScreen_int = = selected ) ;
2022-08-10 01:27:54 +06:00
{
2021-12-07 13:47:42 +01:00
auto widget = ui - > stackedWidget - > currentWidget ( ) ;
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > onResize ( widget - > width ( ) , widget - > height ( ) ) ;
2021-12-07 13:47:42 +01:00
}
2022-08-10 01:27:54 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( main_window - > renderers [ i ] )
main_window - > renderers [ i ] - > onResize ( main_window - > renderers [ i ] - > width ( ) , main_window - > renderers [ i ] - > height ( ) ) ;
2022-08-10 01:27:54 +06:00
}
2021-12-07 13:47:42 +01:00
device_force_redraw ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_stretch_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_FULL ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_stretch ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_43_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_43 ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_43 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_keepRatio_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_keepRatio ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionFullScreen_int_triggered ( )
{
2021-12-07 13:47:42 +01:00
video_fullscreen_scale = FULLSCR_SCALE_INT ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_int ) ;
}
2022-11-19 08:49:04 -05:00
static void
update_greyscale_checkboxes ( Ui : : MainWindow * ui , QAction * selected , int value )
{
2021-12-08 15:12:21 +01:00
ui - > actionRGB_Color - > setChecked ( ui - > actionRGB_Color = = selected ) ;
ui - > actionRGB_Grayscale - > setChecked ( ui - > actionRGB_Grayscale = = selected ) ;
ui - > actionAmber_monitor - > setChecked ( ui - > actionAmber_monitor = = selected ) ;
ui - > actionGreen_monitor - > setChecked ( ui - > actionGreen_monitor = = selected ) ;
ui - > actionWhite_monitor - > setChecked ( ui - > actionWhite_monitor = = selected ) ;
startblit ( ) ;
video_grayscale = value ;
2022-11-19 08:49:04 -05:00
video_copy = ( video_grayscale | | invert_display ) ? video_transform_copy : memcpy ;
2021-12-08 15:12:21 +01:00
endblit ( ) ;
device_force_redraw ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRGB_Color_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionRGB_Color , 0 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRGB_Grayscale_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionRGB_Grayscale , 1 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAmber_monitor_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionAmber_monitor , 2 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionGreen_monitor_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionGreen_monitor , 3 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionWhite_monitor_triggered ( )
{
2021-12-08 15:12:21 +01:00
update_greyscale_checkboxes ( ui , ui - > actionWhite_monitor , 4 ) ;
}
2021-12-08 15:17:33 +01:00
2022-11-19 08:49:04 -05:00
static void
update_greyscale_type_checkboxes ( Ui : : MainWindow * ui , QAction * selected , int value )
{
2021-12-08 15:17:33 +01:00
ui - > actionBT601_NTSC_PAL - > setChecked ( ui - > actionBT601_NTSC_PAL = = selected ) ;
ui - > actionBT709_HDTV - > setChecked ( ui - > actionBT709_HDTV = = selected ) ;
ui - > actionAverage - > setChecked ( ui - > actionAverage = = selected ) ;
video_graytype = value ;
device_force_redraw ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionBT601_NTSC_PAL_triggered ( )
{
2021-12-08 15:17:33 +01:00
update_greyscale_type_checkboxes ( ui , ui - > actionBT601_NTSC_PAL , 0 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionBT709_HDTV_triggered ( )
{
2021-12-08 15:17:33 +01:00
update_greyscale_type_checkboxes ( ui , ui - > actionBT709_HDTV , 1 ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAverage_triggered ( )
{
2021-12-08 15:17:33 +01:00
update_greyscale_type_checkboxes ( ui , ui - > actionAverage , 2 ) ;
}
2021-12-09 20:59:50 +02:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAbout_Qt_triggered ( )
2021-12-09 16:27:53 +06:00
{
QApplication : : aboutQt ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionAbout_86Box_triggered ( )
2021-12-09 16:27:53 +06:00
{
QMessageBox msgBox ;
msgBox . setTextFormat ( Qt : : RichText ) ;
2023-01-18 15:57:59 +05:00
QString versioninfo ;
2021-12-09 20:10:23 +01:00
# ifdef EMU_GIT_HASH
2023-01-18 15:57:59 +05:00
versioninfo = QString ( " [%1] " ) . arg ( EMU_GIT_HASH ) ;
2021-12-09 20:10:23 +01:00
# endif
2023-01-18 15:57:59 +05:00
# ifdef USE_DYNAREC
# ifdef USE_NEW_DYNAREC
# define DYNAREC_STR "new dynarec"
# else
# define DYNAREC_STR "old dynarec"
# endif
# else
# define DYNAREC_STR "no dynarec"
2021-12-09 20:10:23 +01:00
# endif
2023-01-18 15:57:59 +05:00
versioninfo . append ( QString ( " [%1, %2] " ) . arg ( QSysInfo : : buildCpuArchitecture ( ) , tr ( DYNAREC_STR ) ) ) ;
msgBox . setText ( QString ( " <b>%3%1%2</b> " ) . arg ( EMU_VERSION_FULL , versioninfo , tr ( " 86Box v " ) ) ) ;
2022-01-07 16:41:57 +06:00
msgBox . setInformativeText ( tr ( " An emulator of old computers \n \n Authors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others. \n \n Released under the GNU General Public License version 2 or later. See LICENSE for more information. " ) ) ;
2021-12-09 16:27:53 +06:00
msgBox . setWindowTitle ( " About 86Box " ) ;
msgBox . addButton ( " OK " , QMessageBox : : ButtonRole : : AcceptRole ) ;
2022-02-15 20:44:13 -03:00
auto webSiteButton = msgBox . addButton ( EMU_SITE , QMessageBox : : ButtonRole : : HelpRole ) ;
2022-11-19 08:49:04 -05:00
webSiteButton - > connect ( webSiteButton , & QPushButton : : released , [ ] ( ) {
2022-02-15 20:44:13 -03:00
QDesktopServices : : openUrl ( QUrl ( " https:// " EMU_SITE ) ) ;
2021-12-09 16:27:53 +06:00
} ) ;
2022-02-07 12:30:56 +06:00
# ifdef RELEASE_BUILD
msgBox . setIconPixmap ( QIcon ( " :/settings/win/icons/86Box-green.ico " ) . pixmap ( 32 , 32 ) ) ;
# elif defined ALPHA_BUILD
2022-02-07 20:31:56 +06:00
msgBox . setIconPixmap ( QIcon ( " :/settings/win/icons/86Box-red.ico " ) . pixmap ( 32 , 32 ) ) ;
2022-02-07 12:30:56 +06:00
# elif defined BETA_BUILD
2021-12-09 16:27:53 +06:00
msgBox . setIconPixmap ( QIcon ( " :/settings/win/icons/86Box-yellow.ico " ) . pixmap ( 32 , 32 ) ) ;
2022-02-07 12:30:56 +06:00
# else
msgBox . setIconPixmap ( QIcon ( " :/settings/win/icons/86Box-gray.ico " ) . pixmap ( 32 , 32 ) ) ;
# endif
2022-02-06 01:50:30 +06:00
msgBox . setWindowFlags ( Qt : : Dialog | Qt : : CustomizeWindowHint | Qt : : WindowTitleHint | Qt : : WindowCloseButtonHint ) ;
2021-12-09 16:27:53 +06:00
msgBox . exec ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionDocumentation_triggered ( )
2021-12-09 16:27:53 +06:00
{
2022-11-19 08:49:04 -05:00
QDesktopServices : : openUrl ( QUrl ( EMU_DOCS_URL ) ) ;
2021-12-09 16:27:53 +06:00
}
2021-12-09 19:36:35 +01:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered ( )
{
2021-12-09 11:55:28 +01:00
update_overscan = 1 ;
video_toggle_option ( ui - > actionCGA_PCjr_Tandy_EGA_S_VGA_overscan , & enable_overscan ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionChange_contrast_for_monochrome_display_triggered ( )
{
2021-12-09 11:55:28 +01:00
vid_cga_contrast ^ = 1 ;
cgapal_rebuild ( ) ;
config_save ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionForce_4_3_display_ratio_triggered ( )
{
2021-12-09 11:55:28 +01:00
video_toggle_option ( ui - > actionForce_4_3_display_ratio , & force_43 ) ;
}
2021-12-09 21:02:10 +02:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRemember_size_and_position_triggered ( )
2021-12-12 01:16:27 +06:00
{
window_remember ^ = 1 ;
window_w = ui - > stackedWidget - > width ( ) ;
window_h = ui - > stackedWidget - > height ( ) ;
if ( ! QApplication : : platformName ( ) . contains ( " wayland " ) ) {
window_x = geometry ( ) . x ( ) ;
window_y = geometry ( ) . y ( ) ;
}
2022-07-05 16:40:04 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
if ( window_remember & & renderers [ i ] ) {
monitor_settings [ i ] . mon_window_w = renderers [ i ] - > geometry ( ) . width ( ) ;
monitor_settings [ i ] . mon_window_h = renderers [ i ] - > geometry ( ) . height ( ) ;
monitor_settings [ i ] . mon_window_x = renderers [ i ] - > geometry ( ) . x ( ) ;
monitor_settings [ i ] . mon_window_y = renderers [ i ] - > geometry ( ) . y ( ) ;
}
}
2021-12-12 01:16:27 +06:00
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionSpecify_dimensions_triggered ( )
2021-12-12 01:16:27 +06:00
{
SpecifyDimensions dialog ( this ) ;
dialog . setWindowModality ( Qt : : WindowModal ) ;
dialog . exec ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHiDPI_scaling_triggered ( )
2021-12-12 01:16:27 +06:00
{
dpi_scale ^ = 1 ;
ui - > actionHiDPI_scaling - > setChecked ( dpi_scale ) ;
2022-07-04 01:50:42 +06:00
emit resizeContents ( monitors [ 0 ] . mon_scrnsz_x , monitors [ 0 ] . mon_scrnsz_y ) ;
2022-07-06 01:25:39 +06:00
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] )
emit resizeContentsMonitor ( monitors [ i ] . mon_scrnsz_x , monitors [ i ] . mon_scrnsz_y , i ) ;
2022-07-06 01:25:39 +06:00
}
2021-12-12 01:16:27 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHide_status_bar_triggered ( )
2021-12-12 01:16:27 +06:00
{
2022-07-30 14:38:02 +06:00
auto w = ui - > stackedWidget - > width ( ) ;
auto h = ui - > stackedWidget - > height ( ) ;
2021-12-12 01:16:27 +06:00
hide_status_bar ^ = 1 ;
ui - > actionHide_status_bar - > setChecked ( hide_status_bar ) ;
statusBar ( ) - > setVisible ( ! hide_status_bar ) ;
2022-01-09 17:00:16 +02:00
if ( vid_resize > = 2 ) {
2022-11-19 08:49:04 -05:00
setFixedSize ( fixed_size_x , fixed_size_y + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2022-01-09 17:00:16 +02:00
} else {
int vid_resize_orig = vid_resize ;
2022-11-19 08:49:04 -05:00
vid_resize = 0 ;
2022-07-30 14:38:02 +06:00
emit resizeContents ( w , h ) ;
2022-01-09 17:00:16 +02:00
vid_resize = vid_resize_orig ;
2022-11-19 08:49:04 -05:00
if ( vid_resize = = 1 )
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2022-01-09 17:00:16 +02:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionHide_tool_bar_triggered ( )
2022-01-09 17:00:16 +02:00
{
2022-07-30 14:38:02 +06:00
auto w = ui - > stackedWidget - > width ( ) ;
auto h = ui - > stackedWidget - > height ( ) ;
2022-01-09 17:00:16 +02:00
hide_tool_bar ^ = 1 ;
ui - > actionHide_tool_bar - > setChecked ( hide_tool_bar ) ;
ui - > toolBar - > setVisible ( ! hide_tool_bar ) ;
if ( vid_resize > = 2 ) {
2022-11-19 08:49:04 -05:00
setFixedSize ( fixed_size_x , fixed_size_y + menuBar ( ) - > height ( ) + ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) ) + ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2022-01-09 17:00:16 +02:00
} else {
2021-12-12 01:16:27 +06:00
int vid_resize_orig = vid_resize ;
2022-11-19 08:49:04 -05:00
vid_resize = 0 ;
2022-07-30 14:38:02 +06:00
emit resizeContents ( w , h ) ;
2021-12-12 01:16:27 +06:00
vid_resize = vid_resize_orig ;
2022-11-19 08:49:04 -05:00
if ( vid_resize = = 1 )
setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-12-12 01:16:27 +06:00
}
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionUpdate_status_bar_icons_triggered ( )
2021-12-12 01:16:27 +06:00
{
update_icons ^ = 1 ;
ui - > actionUpdate_status_bar_icons - > setChecked ( update_icons ) ;
2022-12-09 22:13:15 +02:00
/* Prevent icons staying when disabled during activity. */
status - > clearActivity ( ) ;
2021-12-12 01:16:27 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionTake_screenshot_triggered ( )
2021-12-12 01:16:27 +06:00
{
startblit ( ) ;
2022-07-07 16:09:50 +06:00
for ( int i = 0 ; i < MONITORS_NUM ; i + + )
monitors [ i ] . mon_screenshots + + ;
2021-12-12 01:16:27 +06:00
endblit ( ) ;
device_force_redraw ( ) ;
}
2021-12-12 16:22:35 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionSound_gain_triggered ( )
2021-12-12 16:22:35 +06:00
{
SoundGain gain ( this ) ;
gain . exec ( ) ;
}
2021-12-12 14:12:11 +02:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : setSendKeyboardInput ( bool enabled )
2021-12-09 20:59:50 +02:00
{
send_keyboard_input = enabled ;
2021-12-18 01:03:05 +06:00
}
2021-12-27 16:32:03 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : updateUiPauseState ( )
{
2022-10-29 09:09:30 -04:00
auto pause_icon = dopause ? QIcon ( " :/menuicons/win/icons/run.ico " ) : QIcon ( " :/menuicons/win/icons/pause.ico " ) ;
auto tooltip_text = dopause ? QString ( tr ( " Resume execution " ) ) : QString ( tr ( " Pause execution " ) ) ;
2022-10-28 13:48:59 -04:00
ui - > actionPause - > setIcon ( pause_icon ) ;
ui - > actionPause - > setToolTip ( tooltip_text ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionPreferences_triggered ( )
2021-12-28 16:47:10 +06:00
{
ProgSettings progsettings ( this ) ;
progsettings . exec ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionEnable_Discord_integration_triggered ( bool checked )
2022-01-09 01:04:59 +06:00
{
enable_discord = checked ;
2023-02-01 17:17:56 +01:00
# ifdef DISCORD
2022-11-19 08:49:04 -05:00
if ( enable_discord ) {
2022-01-09 01:04:59 +06:00
discord_init ( ) ;
discord_update_activity ( dopause ) ;
} else
discord_close ( ) ;
2023-02-01 17:17:56 +01:00
# endif
2022-01-09 01:04:59 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : showSettings ( )
2022-01-22 01:10:11 +02:00
{
2022-11-19 08:49:04 -05:00
if ( findChild < Settings * > ( ) = = nullptr )
2022-01-22 01:10:11 +02:00
ui - > actionSettings - > trigger ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : hardReset ( )
2022-01-22 01:10:11 +02:00
{
ui - > actionHard_Reset - > trigger ( ) ;
2022-01-22 02:41:02 +02:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : togglePause ( )
2022-01-22 02:41:02 +02:00
{
ui - > actionPause - > trigger ( ) ;
2022-01-22 22:00:44 +02:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : changeEvent ( QEvent * event )
2022-01-22 22:00:44 +02:00
{
2022-01-27 21:26:30 +02:00
# ifdef Q_OS_WINDOWS
2022-11-19 08:49:04 -05:00
if ( event - > type ( ) = = QEvent : : LanguageChange ) {
2022-01-22 22:00:44 +02:00
auto font_name = tr ( " FONT_NAME " ) ;
auto font_size = tr ( " FONT_SIZE " ) ;
2022-02-04 23:01:53 +02:00
QApplication : : setFont ( QFont ( font_name , font_size . toInt ( ) ) ) ;
2022-01-22 22:00:44 +02:00
}
2022-01-27 21:26:30 +02:00
# endif
2022-01-22 22:00:44 +02:00
QWidget : : changeEvent ( event ) ;
2022-08-14 12:28:36 +06:00
if ( isVisible ( ) ) {
monitor_settings [ 0 ] . mon_window_maximized = isMaximized ( ) ;
config_save ( ) ;
}
2022-02-03 16:55:32 +06:00
}
2022-02-27 14:56:51 +02:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionRenderer_options_triggered ( )
2022-02-27 14:56:51 +02:00
{
auto dlg = ui - > stackedWidget - > getOptions ( this ) ;
2022-07-07 14:34:59 +06:00
if ( dlg ) {
if ( dlg - > exec ( ) = = QDialog : : Accepted ) {
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] & & renderers [ i ] - > hasOptions ( ) )
renderers [ i ] - > reloadOptions ( ) ;
2022-07-07 14:34:59 +06:00
}
}
}
2022-02-27 14:56:51 +02:00
}
2022-05-23 17:29:45 +06:00
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionMCA_devices_triggered ( )
2022-05-23 17:29:45 +06:00
{
auto dlg = new MCADeviceList ( this ) ;
if ( dlg )
dlg - > exec ( ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionShow_non_primary_monitors_triggered ( )
2022-07-10 11:41:02 +06:00
{
2022-11-19 08:49:04 -05:00
show_second_monitors = ( int ) ui - > actionShow_non_primary_monitors - > isChecked ( ) ;
2022-07-10 11:41:02 +06:00
2022-07-31 23:31:59 +02:00
blitDummied = true ;
2022-07-10 11:41:02 +06:00
if ( show_second_monitors ) {
for ( int monitor_index = 1 ; monitor_index < MONITORS_NUM ; monitor_index + + ) {
2022-11-19 08:49:04 -05:00
auto & secondaryRenderer = renderers [ monitor_index ] ;
if ( ! renderers [ monitor_index ] )
continue ;
2022-07-10 11:41:02 +06:00
secondaryRenderer - > show ( ) ;
if ( window_remember ) {
secondaryRenderer - > setGeometry ( monitor_settings [ monitor_index ] . mon_window_x < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_x ,
2022-11-19 08:49:04 -05:00
monitor_settings [ monitor_index ] . mon_window_y < 120 ? 120 : monitor_settings [ monitor_index ] . mon_window_y ,
monitor_settings [ monitor_index ] . mon_window_w > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_w ,
monitor_settings [ monitor_index ] . mon_window_h > 2048 ? 2048 : monitor_settings [ monitor_index ] . mon_window_h ) ;
2022-07-10 11:41:02 +06:00
}
2022-11-19 08:49:04 -05:00
secondaryRenderer - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2023-01-26 14:29:40 +06:00
ui - > stackedWidget - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2022-07-10 11:41:02 +06:00
}
} else {
for ( int monitor_index = 1 ; monitor_index < MONITORS_NUM ; monitor_index + + ) {
2022-11-19 08:49:04 -05:00
auto & secondaryRenderer = renderers [ monitor_index ] ;
if ( ! renderers [ monitor_index ] )
continue ;
2022-07-10 11:41:02 +06:00
secondaryRenderer - > hide ( ) ;
if ( window_remember & & renderers [ monitor_index ] ) {
monitor_settings [ monitor_index ] . mon_window_w = renderers [ monitor_index ] - > geometry ( ) . width ( ) ;
monitor_settings [ monitor_index ] . mon_window_h = renderers [ monitor_index ] - > geometry ( ) . height ( ) ;
monitor_settings [ monitor_index ] . mon_window_x = renderers [ monitor_index ] - > geometry ( ) . x ( ) ;
monitor_settings [ monitor_index ] . mon_window_y = renderers [ monitor_index ] - > geometry ( ) . y ( ) ;
}
}
}
2022-07-31 23:31:59 +02:00
blitDummied = false ;
2022-07-10 11:41:02 +06:00
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionOpen_screenshots_folder_triggered ( )
2022-08-09 15:35:32 +06:00
{
QDir ( QString ( usr_path ) + QString ( " /screenshots/ " ) ) . mkpath ( " . " ) ;
QDesktopServices : : openUrl ( QUrl ( QString ( " file:/// " ) + usr_path + QString ( " /screenshots/ " ) ) ) ;
}
2022-11-19 08:49:04 -05:00
void
MainWindow : : on_actionApply_fullscreen_stretch_mode_when_maximized_triggered ( bool checked )
2022-08-10 01:27:54 +06:00
{
video_fullscreen_scale_maximized = checked ;
auto widget = ui - > stackedWidget - > currentWidget ( ) ;
ui - > stackedWidget - > onResize ( widget - > width ( ) , widget - > height ( ) ) ;
for ( int i = 1 ; i < MONITORS_NUM ; i + + ) {
2022-11-19 08:49:04 -05:00
if ( renderers [ i ] )
renderers [ i ] - > onResize ( renderers [ i ] - > width ( ) , renderers [ i ] - > height ( ) ) ;
2022-08-10 01:27:54 +06:00
}
device_force_redraw ( ) ;
config_save ( ) ;
}
2023-01-03 15:42:57 +06:00
void MainWindow : : on_actionCursor_Puck_triggered ( )
{
tablet_tool_type = 0 ;
config_save ( ) ;
}
void MainWindow : : on_actionPen_triggered ( )
{
tablet_tool_type = 1 ;
config_save ( ) ;
2023-02-07 17:18:12 +06:00
}
2023-01-03 15:42:57 +06:00
2023-02-06 01:39:34 +06:00
void MainWindow : : on_actionACPI_Shutdown_triggered ( )
{
acpi_pwrbut_pressed = 1 ;
2023-02-07 17:04:25 +06:00
}