2022-02-07 15:00:02 +06: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 .
*
* This file is part of the 86 Box distribution .
*
* Main window module .
*
*
*
* Authors : Joakim L . Gilje < jgilje @ jgilje . net >
* Cacodemon345
* Teemu Korhonen
2022-02-07 15:35:15 +06:00
* dob205
2022-02-07 15:00:02 +06:00
*
* Copyright 2021 Joakim L . Gilje
* Copyright 2021 - 2022 Cacodemon345
* Copyright 2021 - 2022 Teemu Korhonen
2022-02-07 15:35:15 +06:00
* Copyright 2022 dob205
2022-02-07 15:00:02 +06:00
*/
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"
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-01-09 01:04:59 +06:00
# include <86box/discord.h>
2021-11-30 16:26:49 +06:00
# include <86box/video.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>
2022-02-04 15:19:18 +06:00
2022-02-12 17:31:28 +02:00
extern int qt_nvr_save ( void ) ;
2022-02-04 15:19:18 +06:00
# ifdef MTR_ENABLED
# include <minitrace/minitrace.h>
# 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>
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>
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
# ifdef __unix__
2021-12-27 16:32:03 +06:00
# ifdef WAYLAND
# include "wl_mouse.hpp"
# endif
2021-11-30 16:26:49 +06:00
# include <X11/Xlib.h>
# include <X11/keysym.h>
2021-12-05 15:57:46 +06:00
# undef KeyPress
# undef KeyRelease
2021-11-30 16:26:49 +06:00
# endif
extern void qt_mouse_capture ( int ) ;
extern " C " void qt_blit ( int x , int y , int w , int h ) ;
2021-11-25 10:20:56 +01:00
MainWindow : : MainWindow ( QWidget * parent ) :
QMainWindow ( parent ) ,
ui ( new Ui : : MainWindow )
{
2021-12-03 11:38:00 +01:00
mm = std : : make_shared < MediaMenu > ( this ) ;
MediaMenu : : ptr = mm ;
2021-12-14 00:31:55 +06:00
status = std : : make_unique < MachineStatus > ( this ) ;
2021-11-25 10:20:56 +01:00
2022-01-20 20:19:18 +02:00
setUnifiedTitleAndToolBarOnMac ( true ) ;
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-01-09 17:00:16 +02:00
ui - > toolBar - > setVisible ( ! hide_tool_bar ) ;
2021-11-30 16:26:49 +06:00
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-02-10 20:21:00 +06: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
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-01-13 08:33:29 +02:00
connect ( this , & MainWindow : : setTitle , this , [ this , toolbar_label ] ( const QString & title ) {
2022-02-13 00:36:47 +06:00
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-01-22 22:02:57 +02:00
ui - > actionPause - > setChecked ( dopause ) ;
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 ( ) ;
2021-12-02 16:26:33 +06:00
# ifdef WAYLAND
if ( QGuiApplication : : platformName ( ) . contains ( " wayland " ) ) {
wl_mouse_capture ( this - > windowHandle ( ) ) ;
}
# endif
} else {
2021-12-29 23:49:09 +06:00
this - > releaseKeyboard ( ) ;
2021-12-02 16:26:33 +06:00
# ifdef WAYLAND
if ( QGuiApplication : : platformName ( ) . contains ( " wayland " ) ) {
wl_mouse_uncapture ( ) ;
}
# endif
}
2021-11-25 10:20:56 +01:00
} ) ;
connect ( this , & MainWindow : : resizeContents , this , [ this ] ( int w , int h ) {
2021-12-12 01:16:27 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_resize = = 0 ) {
2022-02-10 22:32:17 +06:00
w = qRound ( w / ( ! dpi_scale ? util : : screenOfWidget ( this ) - > devicePixelRatio ( ) : 1. ) ) ;
2022-02-20 02:26:27 -05:00
2022-02-10 22:32:17 +06:00
int modifiedHeight = qRound ( 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
2021-12-05 20:51:59 +01:00
ui - > stackedWidget - > resize ( w , h ) ;
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
} ) ;
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 ( ) ;
2021-12-29 23:49:09 +06:00
if ( QApplication : : activeWindow ( ) = = this )
{
ui - > stackedWidget - > current - > setFocus ( ) ;
}
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 ) ;
2021-12-03 11:38:00 +01:00
connect ( this , & MainWindow : : updateStatusBarActivity , status . get ( ) , & MachineStatus : : setActivity ) ;
connect ( this , & MainWindow : : updateStatusBarEmpty , status . get ( ) , & MachineStatus : : setEmpty ) ;
connect ( this , & MainWindow : : statusBarMessage , status . get ( ) , & MachineStatus : : message ) ;
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 ) ;
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 ) ;
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 ) ;
if ( QOpenGLContext : : openGLModuleType ( ) ! = QOpenGLContext : : LibGLES & & vid_api = = 2 ) vid_api = 1 ;
# endif
if ( QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_api > = 1 ) {
fprintf ( stderr , " OpenGL renderers are unsupported on EGLFS. \n " ) ;
vid_api = 0 ;
}
2021-12-18 01:03:05 +06:00
QActionGroup * actGroup = nullptr ;
2021-12-06 21:39:39 +01:00
switch ( vid_api ) {
case 0 :
2021-12-15 19:58:09 +01:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Software ) ;
2021-12-06 21:39:39 +01:00
ui - > actionSoftware_Renderer - > setChecked ( true ) ;
break ;
case 1 :
2021-12-15 19:58:09 +01:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGL ) ;
2021-12-06 21:39:39 +01:00
ui - > actionHardware_Renderer_OpenGL - > setChecked ( true ) ;
break ;
case 2 :
2021-12-15 19:58:09 +01:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGLES ) ;
2021-12-06 21:39:39 +01:00
ui - > actionHardware_Renderer_OpenGL_ES - > setChecked ( true ) ;
break ;
2021-12-27 16:32:03 +06:00
case 3 :
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGL3 ) ;
ui - > actionOpenGL_3_0_Core - > setChecked ( true ) ;
break ;
2021-12-06 21:39:39 +01: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 ) ;
2021-12-06 21:58:41 +01:00
switch ( scale ) {
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 ;
}
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 ) ;
2021-12-06 22:02:18 +01:00
switch ( video_filter_method ) {
case 0 :
ui - > actionNearest - > setChecked ( true ) ;
break ;
case 1 :
ui - > actionLinear - > setChecked ( true ) ;
break ;
}
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 ) {
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-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 ) {
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-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 ) {
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-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 - > actionFullscreen - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionCtrl_Alt_Del - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionTake_screenshot - > setShortcutVisibleInContextMenu ( true ) ;
# endif
2021-12-04 21:33:04 +01:00
video_setblit ( qt_blit ) ;
2022-01-12 20:12:47 +02:00
if ( start_in_fullscreen ) {
connect ( ui - > stackedWidget , & RendererStack : : blitToRenderer , this , [ this ] ( ) {
if ( start_in_fullscreen ) {
QTimer : : singleShot ( 100 , ui - > actionFullscreen , & QAction : : trigger ) ;
start_in_fullscreen = 0 ;
}
} ) ;
}
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-02-04 15:19:18 +06:00
static auto init_trace = [ & ]
{
mtr_init ( " trace.json " ) ;
mtr_start ( ) ;
} ;
static auto shutdown_trace = [ & ]
{
mtr_stop ( ) ;
mtr_shutdown ( ) ;
} ;
# ifdef Q_OS_MACOS
2022-02-05 02:04:32 +06:00
ui - > actionBegin_trace - > setShortcutVisibleInContextMenu ( true ) ;
ui - > actionEnd_trace - > setShortcutVisibleInContextMenu ( true ) ;
2022-02-04 15:19:18 +06:00
# endif
static bool trace = false ;
2022-02-05 02:04:32 +06:00
connect ( ui - > actionBegin_trace , & QAction : : triggered , this , [ this ]
2022-02-04 15:19:18 +06:00
{
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-02-05 02:04:32 +06:00
connect ( ui - > actionEnd_trace , & QAction : : triggered , this , [ this ]
2022-02-04 15:19:18 +06:00
{
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 ) ;
2021-11-25 10:20:56 +01:00
}
2021-12-12 01:16:27 +06:00
void MainWindow : : closeEvent ( QCloseEvent * event ) {
2022-02-12 17:31:28 +02:00
if ( confirm_exit & & confirm_exit_cmdl & & cpu_thread_run )
2021-12-12 01:16:27 +06:00
{
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 ) ;
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 ) ;
bool confirm_exit_temp = false ;
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-02-12 17:31:28 +02:00
qt_nvr_save ( ) ;
2021-12-24 01:57:26 +06:00
config_save ( ) ;
2022-02-17 11:45:42 +06:00
# ifdef __unix__
extern void xinput2_exit ( ) ;
if ( QApplication : : platformName ( ) = = " xcb " ) xinput2_exit ( ) ;
# endif
2021-12-12 01:16:27 +06:00
event - > accept ( ) ;
}
2021-11-25 10:20:56 +01:00
MainWindow : : ~ MainWindow ( ) {
delete ui ;
}
2021-12-12 01:16:27 +06:00
void MainWindow : : showEvent ( QShowEvent * event ) {
2021-12-24 01:57:26 +06:00
if ( shownonce ) return ;
shownonce = true ;
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-01-09 17:00:16 +02:00
setFixedSize ( fixed_size_x , fixed_size_y
+ menuBar ( ) - > height ( )
+ ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) )
+ ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
2021-12-12 01:16:27 +06:00
scrnsz_x = fixed_size_x ;
scrnsz_y = fixed_size_y ;
}
2022-02-09 16:45:57 +06:00
else if ( window_remember & & vid_resize = = 1 ) {
2022-02-11 15:40:07 +06:00
ui - > stackedWidget - > setFixedSize ( window_w , window_h ) ;
adjustSize ( ) ;
ui - > stackedWidget - > setFixedSize ( QWIDGETSIZE_MAX , QWIDGETSIZE_MAX ) ;
2021-12-12 01:16:27 +06:00
scrnsz_x = window_w ;
scrnsz_y = window_h ;
}
}
2021-11-25 10:20:56 +01:00
void MainWindow : : on_actionKeyboard_requires_capture_triggered ( ) {
kbd_req_capture ^ = 1 ;
}
void MainWindow : : on_actionRight_CTRL_is_left_ALT_triggered ( ) {
rctrl_is_lalt ^ = 1 ;
}
void MainWindow : : on_actionHard_Reset_triggered ( ) {
2022-01-07 16:41:57 +06:00
if ( confirm_reset )
{
QMessageBox questionbox ( QMessageBox : : Icon : : Question , " 86Box " , tr ( " Are you sure you want to hard reset the emulated machine? " ) , QMessageBox : : NoButton , this ) ;
questionbox . addButton ( tr ( " Don't reset " ) , QMessageBox : : AcceptRole ) ;
questionbox . addButton ( tr ( " Reset " ) , QMessageBox : : RejectRole ) ;
QCheckBox * chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! confirm_reset ) ;
bool confirm_exit_temp = false ;
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
confirm_reset = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
if ( questionbox . result ( ) = = QDialog : : Rejected )
{
confirm_reset = true ;
return ;
}
}
config_changed = 2 ;
2021-11-25 10:20:56 +01:00
pc_reset_hard ( ) ;
}
void MainWindow : : on_actionCtrl_Alt_Del_triggered ( ) {
pc_send_cad ( ) ;
}
void MainWindow : : on_actionCtrl_Alt_Esc_triggered ( ) {
pc_send_cae ( ) ;
}
void MainWindow : : on_actionPause_triggered ( ) {
plat_pause ( dopause ^ 1 ) ;
}
void MainWindow : : on_actionExit_triggered ( ) {
close ( ) ;
}
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 ( ) ) {
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-12-01 14:50:49 +06:00
plat_pause ( currentPause ) ;
2021-11-25 10:20:56 +01:00
}
2021-11-30 16:26:49 +06:00
std : : array < uint32_t , 256 > x11_to_xt_base
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0x01 ,
0x02 ,
0x03 ,
0x04 ,
0x05 ,
0x06 ,
0x07 ,
0x08 ,
0x09 ,
0x0A ,
0x0B ,
0x0C ,
0x0D ,
0x0E ,
0x0F ,
0x10 ,
0x11 ,
0x12 ,
0x13 ,
0x14 ,
0x15 ,
0x16 ,
0x17 ,
0x18 ,
0x19 ,
0x1A ,
0x1B ,
0x1C ,
0x1D ,
0x1E ,
0x1F ,
0x20 ,
0x21 ,
0x22 ,
0x23 ,
0x24 ,
0x25 ,
0x26 ,
0x27 ,
0x28 ,
0x29 ,
0x2A ,
0x2B ,
0x2C ,
0x2D ,
0x2E ,
0x2F ,
0x30 ,
0x31 ,
0x32 ,
0x33 ,
0x34 ,
0x35 ,
0x36 ,
0x37 ,
0x38 ,
0x39 ,
0x3A ,
0x3B ,
0x3C ,
0x3D ,
0x3E ,
0x3F ,
0x40 ,
0x41 ,
0x42 ,
0x43 ,
0x44 ,
0x45 ,
0x46 ,
0x47 ,
0x48 ,
0x49 ,
0x4A ,
0x4B ,
0x4C ,
0x4D ,
0x4E ,
0x4F ,
0x50 ,
0x51 ,
0x52 ,
0x53 ,
0x54 ,
0x55 ,
0x56 ,
0x57 ,
0x58 ,
0x147 ,
0x148 ,
0x149 ,
0 ,
0x14B ,
0 ,
0x14D ,
0x14F ,
0x150 ,
0x151 ,
0x152 ,
0x153 ,
0x11C ,
0x11D ,
0 , // Pause/Break key.
0x137 ,
0x135 ,
0x138 ,
0 , // Ditto as above comment.
0x15B ,
0x15C ,
0x15D ,
} ;
std : : array < uint32_t , 256 > x11_to_xt_2
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0x01 ,
0x02 ,
0x03 ,
0x04 ,
0x05 ,
0x06 ,
0x07 ,
0x08 ,
0x09 ,
0x0A ,
0x0B ,
0x0C ,
0x0D ,
0x0E ,
0x0F ,
0x10 ,
0x11 ,
0x12 ,
0x13 ,
0x14 ,
0x15 ,
0x16 ,
0x17 ,
0x18 ,
0x19 ,
0x1A ,
0x1B ,
0x1C ,
0x1D ,
0x1E ,
0x1F ,
0x20 ,
0x21 ,
0x22 ,
0x23 ,
0x24 ,
0x25 ,
0x26 ,
0x27 ,
0x28 ,
0x29 ,
0x2A ,
0x2B ,
0x2C ,
0x2D ,
0x2E ,
0x2F ,
0x30 ,
0x31 ,
0x32 ,
0x33 ,
0x34 ,
0x35 ,
0x36 ,
0x37 ,
0x38 ,
0x39 ,
0x3A ,
0x3B ,
0x3C ,
0x3D ,
0x3E ,
0x3F ,
0x40 ,
0x41 ,
0x42 ,
0x43 ,
0x44 ,
0x45 ,
0x46 ,
0x47 ,
0x48 ,
0x49 ,
0x4A ,
0x4B ,
0x4C ,
0x4D ,
0x4E ,
0x4F ,
0x50 ,
0x51 ,
0x52 ,
0x53 ,
0x54 ,
0x55 ,
0x56 ,
0x57 ,
0x58 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0x11C ,
0x11D ,
0x135 ,
0x137 ,
0x138 ,
0 ,
0x147 ,
0x148 ,
0x149 ,
0x14B ,
0x14D ,
0x14F ,
0x150 ,
0x151 ,
0x152 ,
0x153
} ;
std : : array < uint32_t , 256 > x11_to_xt_vnc
{
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0x1D ,
0x11D ,
0x2A ,
0x36 ,
0 ,
0 ,
0x38 ,
0x138 ,
0x39 ,
0x0B ,
0x02 ,
0x03 ,
0x04 ,
0x05 ,
0x06 ,
0x07 ,
0x08 ,
0x09 ,
0x0A ,
0x0C ,
0x0D ,
0x1A ,
0x1B ,
0x27 ,
0x28 ,
0x29 ,
0x33 ,
0x34 ,
0x35 ,
0x2B ,
0x1E ,
0x30 ,
0x2E ,
0x20 ,
0x12 ,
0x21 ,
0x22 ,
0x23 ,
0x17 ,
0x24 ,
0x25 ,
0x26 ,
0x32 ,
0x31 ,
0x18 ,
0x19 ,
0x10 ,
0x13 ,
0x1F ,
0x14 ,
0x16 ,
0x2F ,
0x11 ,
0x2D ,
0x15 ,
0x2C ,
0x0E ,
0x1C ,
0x0F ,
0x01 ,
0x153 ,
0x147 ,
0x14F ,
0x149 ,
0x151 ,
0x148 ,
0x150 ,
0x14B ,
0x14D ,
} ;
std : : array < uint32_t , 256 > darwin_to_xt
{
0x1E ,
0x1F ,
0x20 ,
0x21 ,
0x23 ,
0x22 ,
0x2C ,
0x2D ,
0x2E ,
0x2F ,
0x2B ,
0x30 ,
0x10 ,
0x11 ,
0x12 ,
0x13 ,
0x15 ,
0x14 ,
0x02 ,
0x03 ,
0x04 ,
0x05 ,
0x07 ,
0x06 ,
0x0D ,
0x0A ,
0x08 ,
0x0C ,
0x09 ,
0x0B ,
0x1B ,
0x18 ,
0x16 ,
0x1A ,
0x17 ,
0x19 ,
0x1C ,
0x26 ,
0x24 ,
0x28 ,
0x25 ,
0x27 ,
0x2B ,
0x33 ,
0x35 ,
0x31 ,
0x32 ,
0x34 ,
0x0F ,
0x39 ,
0x29 ,
0x0E ,
0x11C ,
0x01 ,
0x15C ,
0x15B ,
0x2A ,
0x3A ,
0x38 ,
0x1D ,
0x36 ,
0x138 ,
0x11D ,
0x15C ,
0 ,
0x53 ,
0 ,
0x37 ,
0 ,
0x4E ,
0 ,
0x45 ,
0x130 ,
0x12E ,
0x120 ,
0x135 ,
0x11C ,
0 ,
0x4A ,
0 ,
0 ,
0 ,
0x52 ,
0x4F ,
0x50 ,
0x51 ,
0x4B ,
0x4C ,
0x4D ,
0x47 ,
0 ,
0x48 ,
0x49 ,
0 ,
0 ,
0 ,
0x3F ,
0x40 ,
0x41 ,
0x3D ,
0x42 ,
0x43 ,
0 ,
0x57 ,
0 ,
0x137 ,
0 ,
0x46 ,
0 ,
0x44 ,
0x15D ,
0x58 ,
0 ,
0 , // Pause/Break key.
0x152 ,
0x147 ,
0x149 ,
0x153 ,
0x3E ,
0x14F ,
0x3C ,
0x151 ,
0x3B ,
0x14B ,
0x14D ,
0x150 ,
0x148 ,
0 ,
2021-11-25 10:20:56 +01:00
} ;
2021-12-05 20:51:59 +01:00
static std : : unordered_map < uint32_t , uint16_t > evdev_to_xt =
{
{ 96 , 0x11C } ,
{ 97 , 0x11D } ,
{ 98 , 0x135 } ,
{ 99 , 0x71 } ,
{ 100 , 0x138 } ,
{ 101 , 0x1C } ,
{ 102 , 0x147 } ,
{ 103 , 0x148 } ,
{ 104 , 0x149 } ,
{ 105 , 0x14B } ,
{ 106 , 0x14D } ,
{ 107 , 0x14F } ,
{ 108 , 0x150 } ,
{ 109 , 0x151 } ,
{ 110 , 0x152 } ,
{ 111 , 0x153 }
} ;
2021-11-30 16:26:49 +06:00
static std : : array < uint32_t , 256 > & selected_keycode = x11_to_xt_base ;
uint16_t x11_keycode_to_keysym ( uint32_t keycode )
{
2021-12-24 16:31:36 +06:00
uint16_t finalkeycode = 0 ;
2021-12-02 19:35:08 +02:00
# if defined(Q_OS_WINDOWS)
2021-12-24 16:31:36 +06:00
finalkeycode = ( keycode & 0xFFFF ) ;
2021-12-02 19:35:08 +02:00
# elif defined(__APPLE__)
2021-12-24 16:31:36 +06:00
finalkeycode = darwin_to_xt [ keycode ] ;
2021-11-30 16:26:49 +06:00
# else
static Display * x11display = nullptr ;
if ( QApplication : : platformName ( ) . contains ( " wayland " ) )
{
selected_keycode = x11_to_xt_2 ;
}
2021-12-05 20:51:59 +01:00
else if ( QApplication : : platformName ( ) . contains ( " eglfs " ) )
{
keycode - = 8 ;
2021-12-24 16:31:36 +06:00
if ( keycode < = 88 ) finalkeycode = keycode ;
else finalkeycode = evdev_to_xt [ keycode ] ;
2021-12-05 20:51:59 +01:00
}
2021-11-30 16:26:49 +06:00
else if ( ! x11display )
{
x11display = XOpenDisplay ( nullptr ) ;
if ( XKeysymToKeycode ( x11display , XK_Home ) = = 110 )
{
selected_keycode = x11_to_xt_2 ;
}
else if ( XKeysymToKeycode ( x11display , XK_Home ) = = 69 )
{
selected_keycode = x11_to_xt_vnc ;
}
}
2021-12-24 16:31:36 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) ) finalkeycode = selected_keycode [ keycode ] ;
2021-11-30 16:26:49 +06:00
# endif
2021-12-24 16:31:36 +06:00
if ( rctrl_is_lalt & & finalkeycode = = 0x11D )
{
finalkeycode = 0x38 ;
}
return finalkeycode ;
2021-11-30 16:26:49 +06:00
}
2021-11-25 10:20:56 +01: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 ( ) ;
2021-12-09 19:48:56 +01:00
ui - > menubar - > show ( ) ;
2021-12-25 15:28:48 +06:00
if ( ! hide_status_bar ) ui - > statusbar - > show ( ) ;
2022-01-09 17:00:16 +02:00
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-01-09 17:00:16 +02:00
if ( vid_resize = = 2 ) setFixedSize ( fixed_size_x , fixed_size_y
+ menuBar ( ) - > height ( )
+ ( ! hide_status_bar ? statusBar ( ) - > height ( ) : 0 )
+ ( ! hide_tool_bar ? ui - > toolBar - > height ( ) : 0 ) ) ;
2021-12-25 15:28:48 +06:00
emit resizeContents ( scrnsz_x , scrnsz_y ) ;
}
2021-11-30 21:26:51 +01:00
} else {
2022-01-12 01:09:43 +06:00
if ( video_fullscreen_first )
{
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-01-12 01:09:43 +06:00
QCheckBox * chkbox = new QCheckBox ( tr ( " Don't show this message again " ) ) ;
questionbox . setCheckBox ( chkbox ) ;
chkbox - > setChecked ( ! video_fullscreen_first ) ;
bool confirm_exit_temp = false ;
QObject : : connect ( chkbox , & QCheckBox : : stateChanged , [ ] ( int state ) {
video_fullscreen_first = ( state = = Qt : : CheckState : : Unchecked ) ;
} ) ;
questionbox . exec ( ) ;
config_save ( ) ;
}
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 ( ) ;
2021-11-30 21:26:51 +01:00
showFullScreen ( ) ;
video_fullscreen = 1 ;
}
2022-01-12 20:12:47 +02:00
ui - > stackedWidget - > rendererWindow - > onResize ( width ( ) , height ( ) ) ;
2021-11-25 10:20:56 +01:00
}
2021-11-29 17:25:31 +01:00
2021-12-01 15:55:41 +06:00
void MainWindow : : getTitle_ ( wchar_t * title )
{
this - > windowTitle ( ) . toWCharArray ( title ) ;
}
void MainWindow : : getTitle ( wchar_t * title )
{
if ( QThread : : currentThread ( ) = = this - > thread ( ) ) {
getTitle_ ( title ) ;
} else {
emit getTitleForNonQtThread ( title ) ;
}
}
2021-12-05 15:57:46 +06:00
bool MainWindow : : eventFilter ( QObject * receiver , QEvent * event )
{
if ( this - > keyboardGrabber ( ) = = this ) {
if ( event - > type ( ) = = QEvent : : KeyPress ) {
event - > accept ( ) ;
this - > keyPressEvent ( ( QKeyEvent * ) event ) ;
return true ;
}
if ( event - > type ( ) = = QEvent : : KeyRelease ) {
event - > accept ( ) ;
this - > keyReleaseEvent ( ( QKeyEvent * ) event ) ;
return true ;
}
}
2021-12-06 21:26:17 +01:00
2022-02-04 15:19:18 +06:00
if ( receiver = = this )
{
static auto curdopause = dopause ;
if ( event - > type ( ) = = QEvent : : WindowBlocked ) { curdopause = dopause ; plat_pause ( 1 ) ; }
else if ( event - > type ( ) = = QEvent : : WindowUnblocked ) { plat_pause ( curdopause ) ; }
}
2021-12-05 15:57:46 +06:00
return QMainWindow : : eventFilter ( receiver , event ) ;
}
2021-12-03 11:38:00 +01:00
void MainWindow : : refreshMediaMenu ( ) {
mm - > refresh ( ui - > menuMedia ) ;
2021-12-14 00:31:55 +06:00
status - > refresh ( ui - > statusbar ) ;
2021-12-03 11:38:00 +01:00
}
2021-11-29 17:25:31 +01:00
void MainWindow : : showMessage ( const QString & header , const QString & message ) {
if ( QThread : : currentThread ( ) = = this - > thread ( ) ) {
showMessage_ ( header , message ) ;
} else {
emit showMessageForNonQtThread ( header , message ) ;
}
}
void MainWindow : : showMessage_ ( const QString & header , const QString & message ) {
QMessageBox box ( QMessageBox : : Warning , header , message , QMessageBox : : NoButton , this ) ;
2021-12-10 15:36:55 +06:00
box . setTextFormat ( Qt : : TextFormat : : RichText ) ;
2021-11-29 17:25:31 +01:00
box . exec ( ) ;
}
2021-11-30 16:26:49 +06:00
void MainWindow : : keyPressEvent ( QKeyEvent * event )
{
2021-12-24 16:31:36 +06:00
if ( send_keyboard_input & & ! ( kbd_req_capture & & ! mouse_capture & & ! video_fullscreen ) )
2021-12-09 20:59:50 +02:00
{
2021-11-30 16:26:49 +06:00
# ifdef __APPLE__
2021-12-09 20:59:50 +02:00
keyboard_input ( 1 , x11_keycode_to_keysym ( event - > nativeVirtualKey ( ) ) ) ;
2021-11-30 16:26:49 +06:00
# else
2021-12-09 20:59:50 +02:00
keyboard_input ( 1 , x11_keycode_to_keysym ( event - > nativeScanCode ( ) ) ) ;
2021-11-30 16:26:49 +06:00
# endif
2021-12-09 20:59:50 +02:00
}
2021-11-30 21:29:58 +01:00
2021-12-09 19:48:56 +01:00
if ( ( video_fullscreen > 0 ) & & keyboard_isfsexit ( ) ) {
2021-11-30 21:29:58 +01:00
ui - > actionFullscreen - > trigger ( ) ;
}
if ( keyboard_ismsexit ( ) ) {
plat_mouse_capture ( 0 ) ;
}
2021-12-05 15:57:46 +06:00
event - > accept ( ) ;
2021-11-30 16:26:49 +06:00
}
2021-12-02 00:47:02 +06:00
void MainWindow : : blitToWidget ( int x , int y , int w , int h )
{
2021-12-04 21:33:04 +01:00
ui - > stackedWidget - > blit ( x , y , w , h ) ;
2021-12-02 00:47:02 +06:00
}
2021-11-30 16:26:49 +06:00
void MainWindow : : keyReleaseEvent ( QKeyEvent * event )
{
2021-12-09 20:59:50 +02:00
if ( ! send_keyboard_input )
return ;
2021-11-30 16:26:49 +06:00
# ifdef __APPLE__
keyboard_input ( 0 , x11_keycode_to_keysym ( event - > nativeVirtualKey ( ) ) ) ;
# else
keyboard_input ( 0 , x11_keycode_to_keysym ( event - > nativeScanCode ( ) ) ) ;
# endif
}
2021-12-04 21:33:04 +01:00
2021-12-12 01:16:27 +06:00
QSize MainWindow : : getRenderWidgetSize ( )
{
return ui - > stackedWidget - > size ( ) ;
}
2021-12-04 21:33:04 +01:00
void MainWindow : : on_actionSoftware_Renderer_triggered ( ) {
2021-12-15 19:58:09 +01:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Software ) ;
2021-12-06 21:39:39 +01:00
ui - > actionHardware_Renderer_OpenGL - > setChecked ( false ) ;
ui - > actionHardware_Renderer_OpenGL_ES - > setChecked ( false ) ;
2021-12-27 16:32:03 +06:00
ui - > actionOpenGL_3_0_Core - > setChecked ( false ) ;
2021-12-06 21:39:39 +01:00
vid_api = 0 ;
2021-12-04 21:33:04 +01:00
}
void MainWindow : : on_actionHardware_Renderer_OpenGL_triggered ( ) {
2021-12-15 19:58:09 +01:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGL ) ;
2021-12-06 21:39:39 +01:00
ui - > actionSoftware_Renderer - > setChecked ( false ) ;
ui - > actionHardware_Renderer_OpenGL_ES - > setChecked ( false ) ;
2021-12-27 16:32:03 +06:00
ui - > actionOpenGL_3_0_Core - > setChecked ( false ) ;
2021-12-06 21:39:39 +01:00
vid_api = 1 ;
2021-12-04 21:33:04 +01:00
}
void MainWindow : : on_actionHardware_Renderer_OpenGL_ES_triggered ( ) {
2021-12-15 19:58:09 +01:00
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGLES ) ;
2021-12-06 21:39:39 +01:00
ui - > actionSoftware_Renderer - > setChecked ( false ) ;
ui - > actionHardware_Renderer_OpenGL - > setChecked ( false ) ;
2021-12-27 16:32:03 +06:00
ui - > actionOpenGL_3_0_Core - > setChecked ( false ) ;
2021-12-06 21:39:39 +01:00
vid_api = 2 ;
2021-12-04 21:33:04 +01:00
}
2021-12-05 15:57:46 +06:00
void MainWindow : : focusInEvent ( QFocusEvent * event )
{
2021-12-31 16:47:49 +06:00
this - > grabKeyboard ( ) ;
2021-12-05 15:57:46 +06:00
}
void MainWindow : : focusOutEvent ( QFocusEvent * event )
{
this - > releaseKeyboard ( ) ;
2021-12-05 20:51:59 +01:00
}
2021-12-06 21:26:17 +01:00
void MainWindow : : on_actionResizable_window_triggered ( bool checked ) {
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 ) ;
} else {
vid_resize = 0 ;
2021-12-24 01:57:26 +06:00
setWindowFlag ( Qt : : WindowMaximizeButtonHint , false ) ;
setWindowFlag ( Qt : : MSWindowsFixedSizeDialogHint ) ;
2021-12-06 21:26:17 +01:00
}
2021-12-24 01:57:26 +06:00
show ( ) ;
2021-12-25 15:28:48 +06:00
ui - > stackedWidget - > switchRenderer ( ( RendererStack : : Renderer ) vid_api ) ;
2021-12-24 01:57:26 +06:00
2021-12-06 21:58:41 +01:00
ui - > menuWindow_scale_factor - > setEnabled ( ! checked ) ;
2021-12-06 21:26:17 +01:00
emit resizeContents ( scrnsz_x , scrnsz_y ) ;
}
2021-12-06 21:45:40 +01:00
static void
video_toggle_option ( QAction * action , int * val )
{
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 ( ) ;
device_force_redraw ( ) ;
}
void MainWindow : : on_actionInverted_VGA_monitor_triggered ( ) {
video_toggle_option ( ui - > actionInverted_VGA_monitor , & invert_display ) ;
}
2021-12-06 21:58:41 +01:00
static void update_scaled_checkboxes ( Ui : : MainWindow * ui , QAction * selected ) {
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 ) ;
reset_screen_size ( ) ;
device_force_redraw ( ) ;
video_force_resize_set ( 1 ) ;
2021-12-17 22:23:08 +02:00
atomic_flag_clear ( & doresize ) ;
2021-12-06 21:58:41 +01:00
config_save ( ) ;
}
void MainWindow : : on_action0_5x_triggered ( ) {
scale = 0 ;
update_scaled_checkboxes ( ui , ui - > action0_5x ) ;
}
void MainWindow : : on_action1x_triggered ( ) {
scale = 1 ;
update_scaled_checkboxes ( ui , ui - > action1x ) ;
}
void MainWindow : : on_action1_5x_triggered ( ) {
scale = 2 ;
update_scaled_checkboxes ( ui , ui - > action1_5x ) ;
}
void MainWindow : : on_action2x_triggered ( ) {
scale = 3 ;
update_scaled_checkboxes ( ui , ui - > action2x ) ;
}
2021-12-06 22:02:18 +01:00
void MainWindow : : on_actionNearest_triggered ( ) {
video_filter_method = 0 ;
ui - > actionLinear - > setChecked ( false ) ;
}
void MainWindow : : on_actionLinear_triggered ( ) {
video_filter_method = 1 ;
ui - > actionNearest - > setChecked ( false ) ;
}
2021-12-07 13:47:42 +01:00
static void update_fullscreen_scale_checkboxes ( Ui : : MainWindow * ui , QAction * selected ) {
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 ) ;
if ( video_fullscreen > 0 ) {
auto widget = ui - > stackedWidget - > currentWidget ( ) ;
2021-12-31 13:02:27 +06:00
auto rc = ui - > stackedWidget - > rendererWindow ;
2021-12-07 13:47:42 +01:00
rc - > onResize ( widget - > width ( ) , widget - > height ( ) ) ;
}
device_force_redraw ( ) ;
config_save ( ) ;
}
void MainWindow : : on_actionFullScreen_stretch_triggered ( ) {
video_fullscreen_scale = FULLSCR_SCALE_FULL ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_stretch ) ;
}
void MainWindow : : on_actionFullScreen_43_triggered ( ) {
video_fullscreen_scale = FULLSCR_SCALE_43 ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_43 ) ;
}
void MainWindow : : on_actionFullScreen_keepRatio_triggered ( ) {
video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_keepRatio ) ;
}
void MainWindow : : on_actionFullScreen_int_triggered ( ) {
video_fullscreen_scale = FULLSCR_SCALE_INT ;
update_fullscreen_scale_checkboxes ( ui , ui - > actionFullScreen_int ) ;
}
2021-12-08 15:12:21 +01:00
static void update_greyscale_checkboxes ( Ui : : MainWindow * ui , QAction * selected , int value ) {
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 ;
video_copy = ( video_grayscale | | invert_display ) ? video_transform_copy : memcpy ;
endblit ( ) ;
device_force_redraw ( ) ;
config_save ( ) ;
}
void MainWindow : : on_actionRGB_Color_triggered ( ) {
update_greyscale_checkboxes ( ui , ui - > actionRGB_Color , 0 ) ;
}
void MainWindow : : on_actionRGB_Grayscale_triggered ( ) {
update_greyscale_checkboxes ( ui , ui - > actionRGB_Grayscale , 1 ) ;
}
void MainWindow : : on_actionAmber_monitor_triggered ( ) {
update_greyscale_checkboxes ( ui , ui - > actionAmber_monitor , 2 ) ;
}
void MainWindow : : on_actionGreen_monitor_triggered ( ) {
update_greyscale_checkboxes ( ui , ui - > actionGreen_monitor , 3 ) ;
}
void MainWindow : : on_actionWhite_monitor_triggered ( ) {
update_greyscale_checkboxes ( ui , ui - > actionWhite_monitor , 4 ) ;
}
2021-12-08 15:17:33 +01:00
static void update_greyscale_type_checkboxes ( Ui : : MainWindow * ui , QAction * selected , int value ) {
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 ( ) ;
}
void MainWindow : : on_actionBT601_NTSC_PAL_triggered ( ) {
update_greyscale_type_checkboxes ( ui , ui - > actionBT601_NTSC_PAL , 0 ) ;
}
void MainWindow : : on_actionBT709_HDTV_triggered ( ) {
update_greyscale_type_checkboxes ( ui , ui - > actionBT709_HDTV , 1 ) ;
}
void MainWindow : : on_actionAverage_triggered ( ) {
update_greyscale_type_checkboxes ( ui , ui - > actionAverage , 2 ) ;
}
2021-12-09 20:59:50 +02:00
2021-12-09 16:27:53 +06:00
void MainWindow : : on_actionAbout_Qt_triggered ( )
{
QApplication : : aboutQt ( ) ;
}
void MainWindow : : on_actionAbout_86Box_triggered ( )
{
QMessageBox msgBox ;
msgBox . setTextFormat ( Qt : : RichText ) ;
2021-12-09 20:10:23 +01:00
QString githash ;
# ifdef EMU_GIT_HASH
githash = QString ( " [%1] " ) . arg ( EMU_GIT_HASH ) ;
# endif
2022-01-08 00:53:45 +06:00
msgBox . setText ( QString ( " <b>%3%1%2</b> " ) . arg ( EMU_VERSION_FULL , githash , 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 ) ;
2021-12-09 16:27:53 +06: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 ( ) ;
}
void MainWindow : : on_actionDocumentation_triggered ( )
{
2022-02-15 20:44:13 -03:00
QDesktopServices : : openUrl ( QUrl ( EMU_DOCS_URL ) ) ;
2021-12-09 16:27:53 +06:00
}
2021-12-09 19:36:35 +01:00
2021-12-09 11:55:28 +01:00
void MainWindow : : on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered ( ) {
update_overscan = 1 ;
video_toggle_option ( ui - > actionCGA_PCjr_Tandy_EGA_S_VGA_overscan , & enable_overscan ) ;
}
void MainWindow : : on_actionChange_contrast_for_monochrome_display_triggered ( ) {
vid_cga_contrast ^ = 1 ;
cgapal_rebuild ( ) ;
config_save ( ) ;
}
void MainWindow : : on_actionForce_4_3_display_ratio_triggered ( ) {
video_toggle_option ( ui - > actionForce_4_3_display_ratio , & force_43 ) ;
video_force_resize_set ( 1 ) ;
}
2021-12-09 21:02:10 +02:00
2021-12-12 01:16:27 +06:00
void MainWindow : : on_actionRemember_size_and_position_triggered ( )
{
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 ( ) ;
}
ui - > actionRemember_size_and_position - > setChecked ( window_remember ) ;
}
void MainWindow : : on_actionSpecify_dimensions_triggered ( )
{
SpecifyDimensions dialog ( this ) ;
dialog . setWindowModality ( Qt : : WindowModal ) ;
dialog . exec ( ) ;
}
void MainWindow : : on_actionHiDPI_scaling_triggered ( )
{
dpi_scale ^ = 1 ;
ui - > actionHiDPI_scaling - > setChecked ( dpi_scale ) ;
emit resizeContents ( scrnsz_x , scrnsz_y ) ;
}
void MainWindow : : on_actionHide_status_bar_triggered ( )
{
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 ) {
setFixedSize ( fixed_size_x , fixed_size_y
+ menuBar ( ) - > height ( )
+ ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) )
+ ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
} else {
int vid_resize_orig = vid_resize ;
vid_resize = 0 ;
emit resizeContents ( scrnsz_x , scrnsz_y ) ;
vid_resize = vid_resize_orig ;
}
}
void MainWindow : : on_actionHide_tool_bar_triggered ( )
{
hide_tool_bar ^ = 1 ;
ui - > actionHide_tool_bar - > setChecked ( hide_tool_bar ) ;
ui - > toolBar - > setVisible ( ! hide_tool_bar ) ;
if ( vid_resize > = 2 ) {
setFixedSize ( fixed_size_x , fixed_size_y
+ menuBar ( ) - > height ( )
+ ( hide_status_bar ? 0 : statusBar ( ) - > height ( ) )
+ ( hide_tool_bar ? 0 : ui - > toolBar - > height ( ) ) ) ;
} else {
2021-12-12 01:16:27 +06:00
int vid_resize_orig = vid_resize ;
vid_resize = 0 ;
emit resizeContents ( scrnsz_x , scrnsz_y ) ;
vid_resize = vid_resize_orig ;
}
}
void MainWindow : : on_actionUpdate_status_bar_icons_triggered ( )
{
update_icons ^ = 1 ;
ui - > actionUpdate_status_bar_icons - > setChecked ( update_icons ) ;
}
void MainWindow : : on_actionTake_screenshot_triggered ( )
{
startblit ( ) ;
screenshots + + ;
endblit ( ) ;
device_force_redraw ( ) ;
}
2021-12-12 16:22:35 +06:00
void MainWindow : : on_actionSound_gain_triggered ( )
{
SoundGain gain ( this ) ;
gain . exec ( ) ;
}
2021-12-12 14:12:11 +02:00
2021-12-09 20:59:50 +02:00
void MainWindow : : setSendKeyboardInput ( bool enabled )
{
send_keyboard_input = enabled ;
2021-12-18 01:03:05 +06:00
}
2021-12-27 16:32:03 +06:00
void MainWindow : : on_actionOpenGL_3_0_Core_triggered ( )
{
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGL3 ) ;
ui - > actionSoftware_Renderer - > setChecked ( false ) ;
ui - > actionHardware_Renderer_OpenGL - > setChecked ( false ) ;
ui - > actionHardware_Renderer_OpenGL_ES - > setChecked ( false ) ;
ui - > actionOpenGL_3_0_Core - > setChecked ( true ) ;
vid_api = 3 ;
}
2021-12-28 16:47:10 +06:00
void MainWindow : : on_actionPreferences_triggered ( )
{
ProgSettings progsettings ( this ) ;
progsettings . exec ( ) ;
}
2022-01-09 01:04:59 +06:00
void MainWindow : : on_actionEnable_Discord_integration_triggered ( bool checked )
{
enable_discord = checked ;
if ( enable_discord ) {
discord_init ( ) ;
discord_update_activity ( dopause ) ;
} else
discord_close ( ) ;
}
2022-01-22 01:10:11 +02:00
void MainWindow : : showSettings ( )
{
if ( findChild < Settings * > ( ) = = nullptr )
ui - > actionSettings - > trigger ( ) ;
}
void MainWindow : : hardReset ( )
{
ui - > actionHard_Reset - > trigger ( ) ;
2022-01-22 02:41:02 +02:00
}
void MainWindow : : togglePause ( )
{
ui - > actionPause - > trigger ( ) ;
2022-01-22 22:00:44 +02:00
}
void MainWindow : : changeEvent ( QEvent * event )
{
2022-01-27 21:26:30 +02:00
# ifdef Q_OS_WINDOWS
2022-01-22 22:00:44 +02:00
if ( event - > type ( ) = = QEvent : : LanguageChange )
{
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-02-03 16:55:32 +06:00
}