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
2022-03-11 12:03:54 +06:00
# if defined __unix__ && !defined __HAIKU__
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
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
// The namespace is required to avoid clashing typedefs; we only use this
// header for its #defines anyway.
namespace IOKit {
# include <IOKit/hidsystem/IOLLEvent.h>
}
# endif
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
# include <os/AppKit.h>
# include <os/InterfaceKit.h>
extern MainWindow * main_window ;
filter_result keyb_filter ( BMessage * message , BHandler * * target , BMessageFilter * filter )
{
if ( message - > what = = B_KEY_DOWN | | message - > what = = B_KEY_UP
| | message - > what = = B_UNMAPPED_KEY_DOWN | | message - > what = = B_UNMAPPED_KEY_UP )
{
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 ) ) ;
if ( key_scancode = = 0x68 & & key_state )
{
QGuiApplication : : postEvent ( main_window , new QKeyEvent ( QEvent : : KeyRelease , 0 , QGuiApplication : : keyboardModifiers ( ) , key_scancode , 0 , 0 ) ) ;
}
}
return B_DISPATCH_MESSAGE ;
}
static BMessageFilter * filter ;
# endif
2021-11-30 16:26:49 +06:00
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-03-11 12:03:54 +06:00
# ifdef __HAIKU__
filter = new BMessageFilter ( B_PROGRAMMED_DELIVERY , B_ANY_SOURCE , keyb_filter ) ;
( ( BWindow * ) this - > winId ( ) ) - > AddFilter ( filter ) ;
# endif
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 ( ) ;
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 ) {
2021-12-12 01:16:27 +06:00
if ( ! QApplication : : platformName ( ) . contains ( " eglfs " ) & & vid_resize = = 0 ) {
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
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 )
{
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 ) ;
2021-12-03 11:38:00 +01:00
connect ( this , & MainWindow : : updateStatusBarActivity , status . get ( ) , & MachineStatus : : setActivity ) ;
connect ( this , & MainWindow : : updateStatusBarEmpty , status . get ( ) , & MachineStatus : : setEmpty ) ;
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 ) ;
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
2022-03-01 13:31:19 +06:00
ui - > actionHardware_Renderer_OpenGL - > setVisible ( QOpenGLContext : : openGLModuleType ( ) ! = QOpenGLContext : : LibGLES ) ;
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 " ) ) {
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-02-27 14:56:51 +02:00
2022-04-25 16:09:37 +06:00
# if !QT_CONFIG(vulkan)
if ( vid_api = = 4 ) vid_api = 0 ;
ui - > actionVulkan - > setVisible ( false ) ;
# endif
2021-12-18 01:03:05 +06: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-02-27 14:56:51 +02:00
actGroup - > setExclusive ( true ) ;
connect ( actGroup , & QActionGroup : : triggered , [ this ] ( QAction * action ) {
vid_api = action - > property ( " vid_api " ) . toInt ( ) ;
switch ( vid_api )
{
case 0 :
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Software ) ;
break ;
case 1 :
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGL ) ;
break ;
case 2 :
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGLES ) ;
break ;
case 3 :
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : OpenGL3 ) ;
break ;
2022-04-21 16:32:46 +06:00
case 4 :
ui - > stackedWidget - > switchRenderer ( RendererStack : : Renderer : : Vulkan ) ;
break ;
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 ) {
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-03-10 23:14:13 +02:00
if ( mouse_capture ) {
event - > ignore ( ) ;
return ;
}
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 ) ;
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-02-12 17:31:28 +02:00
qt_nvr_save ( ) ;
2021-12-24 01:57:26 +06:00
config_save ( ) ;
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 ) ;
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 ) ;
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 ( ) ;
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
}
2022-04-14 06:48:25 +05:00
# if defined(__unix__) && !defined(__HAIKU__)
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 ,
} ;
2022-04-14 06:48:25 +05:00
# endif
2021-11-30 16:26:49 +06:00
2022-04-14 06:48:25 +05:00
# ifdef Q_OS_MACOS
2021-11-30 16:26:49 +06:00
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
} ;
2022-04-14 06:48:25 +05:00
# endif
2021-11-25 10:20:56 +01:00
2022-04-14 06:48:25 +05:00
# if defined(__unix__) && !defined(__HAIKU__)
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 }
} ;
2022-04-14 06:48:25 +05:00
# endif
2021-12-05 20:51:59 +01:00
2022-03-11 12:03:54 +06:00
# ifdef __HAIKU__
static std : : unordered_map < uint8_t , uint16_t > be_to_xt =
{
{ 0x01 , 0x01 } ,
{ B_F1_KEY , 0x3B } ,
{ B_F2_KEY , 0x3C } ,
{ B_F3_KEY , 0x3D } ,
{ B_F4_KEY , 0x3E } ,
{ B_F5_KEY , 0x3F } ,
{ B_F6_KEY , 0x40 } ,
{ B_F7_KEY , 0x41 } ,
{ B_F8_KEY , 0x42 } ,
{ B_F9_KEY , 0x43 } ,
{ B_F10_KEY , 0x44 } ,
{ B_F11_KEY , 0x57 } ,
{ B_F12_KEY , 0x58 } ,
{ 0x11 , 0x29 } ,
{ 0x12 , 0x02 } ,
{ 0x13 , 0x03 } ,
{ 0x14 , 0x04 } ,
{ 0x15 , 0x05 } ,
{ 0x16 , 0x06 } ,
{ 0x17 , 0x07 } ,
{ 0x18 , 0x08 } ,
{ 0x19 , 0x09 } ,
{ 0x1A , 0x0A } ,
{ 0x1B , 0x0B } ,
{ 0x1C , 0x0C } ,
{ 0x1D , 0x0D } ,
{ 0x1E , 0x0E } ,
{ 0x1F , 0x152 } ,
{ 0x20 , 0x147 } ,
{ 0x21 , 0x149 } ,
{ 0x22 , 0x45 } ,
{ 0x23 , 0x135 } ,
{ 0x24 , 0x37 } ,
{ 0x25 , 0x4A } ,
{ 0x26 , 0x0F } ,
{ 0x27 , 0x10 } ,
{ 0x28 , 0x11 } ,
{ 0x29 , 0x12 } ,
{ 0x2A , 0x13 } ,
{ 0x2B , 0x14 } ,
{ 0x2C , 0x15 } ,
{ 0x2D , 0x16 } ,
{ 0x2E , 0x17 } ,
{ 0x2F , 0x18 } ,
{ 0x30 , 0x19 } ,
{ 0x31 , 0x1A } ,
{ 0x32 , 0x1B } ,
{ 0x33 , 0x2B } ,
{ 0x34 , 0x153 } ,
{ 0x35 , 0x14F } ,
{ 0x36 , 0x151 } ,
{ 0x37 , 0x47 } ,
{ 0x38 , 0x48 } ,
{ 0x39 , 0x49 } ,
{ 0x3A , 0x4E } ,
{ 0x3B , 0x3A } ,
{ 0x3C , 0x1E } ,
{ 0x3D , 0x1F } ,
{ 0x3E , 0x20 } ,
{ 0x3F , 0x21 } ,
{ 0x40 , 0x22 } ,
{ 0x41 , 0x23 } ,
{ 0x42 , 0x24 } ,
{ 0x43 , 0x25 } ,
{ 0x44 , 0x26 } ,
{ 0x45 , 0x27 } ,
{ 0x46 , 0x28 } ,
{ 0x47 , 0x1C } ,
{ 0x48 , 0x4B } ,
{ 0x49 , 0x4C } ,
{ 0x4A , 0x4D } ,
{ 0x4B , 0x2A } ,
{ 0x4C , 0x2C } ,
{ 0x4D , 0x2D } ,
{ 0x4E , 0x2E } ,
{ 0x4F , 0x2F } ,
{ 0x50 , 0x30 } ,
{ 0x51 , 0x31 } ,
{ 0x52 , 0x32 } ,
{ 0x53 , 0x33 } ,
{ 0x54 , 0x34 } ,
{ 0x55 , 0x35 } ,
{ 0x56 , 0x36 } ,
{ 0x57 , 0x148 } ,
{ 0x58 , 0x51 } ,
{ 0x59 , 0x50 } ,
{ 0x5A , 0x4F } ,
{ 0x5B , 0x11C } ,
{ 0x5C , 0x1D } ,
{ 0x5D , 0x38 } ,
{ 0x5E , 0x39 } ,
{ 0x5F , 0x138 } ,
{ 0x60 , 0x11D } ,
{ 0x61 , 0x14B } ,
{ 0x62 , 0x150 } ,
{ 0x63 , 0x14D } ,
{ 0x64 , 0x52 } ,
{ 0x65 , 0x53 } ,
{ 0x0e , 0x137 } ,
{ 0x0f , 0x46 } ,
{ 0x66 , 0x15B } ,
{ 0x67 , 0x15C } ,
{ 0x68 , 0x15D } ,
{ 0x69 , 0x56 }
} ;
# endif
2022-04-14 06:48:25 +05:00
# if defined(__unix__) && !defined(__HAIKU__)
2021-11-30 16:26:49 +06:00
static std : : array < uint32_t , 256 > & selected_keycode = x11_to_xt_base ;
2022-04-14 06:48:25 +05:00
# endif
2021-11-30 16:26:49 +06:00
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 ) ;
2022-03-19 23:06:17 +00:00
# elif defined(Q_OS_MACOS)
2021-12-24 16:31:36 +06:00
finalkeycode = darwin_to_xt [ keycode ] ;
2022-03-11 12:03:54 +06:00
# elif defined(__HAIKU__)
finalkeycode = be_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
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 = {
{ 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 } ,
} ;
void MainWindow : : processMacKeyboardInput ( bool down , const QKeyEvent * event ) {
// 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 ( ) ;
for ( auto const & pair : mac_modifiers_to_xt ) {
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 ) {
keyboard_input ( 1 , 0x3A ) ;
keyboard_input ( 0 , 0x3A ) ;
}
} else {
keyboard_input ( down , x11_keycode_to_keysym ( event - > nativeVirtualKey ( ) ) ) ;
}
}
# endif
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-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-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 ) ;
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
/* (re-capture mouse after dialog. */
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 ( ) ;
2021-11-30 21:26:51 +01:00
showFullScreen ( ) ;
}
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
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 )
{
2022-03-21 15:28:43 +06:00
if ( ! dopause & & ( mouse_capture | | ! kbd_req_capture ) ) {
if ( event - > type ( ) = = QEvent : : Shortcut ) {
auto shortcutEvent = ( QShortcutEvent * ) event ;
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 ) ;
}
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
{
2022-04-26 16:56:44 +06:00
// Windows keys in Qt have one-to-one mapping.
if ( event - > key ( ) = = Qt : : Key_Super_L | | event - > key ( ) = = Qt : : Key_Super_R ) {
keyboard_input ( 1 , event - > key ( ) = = Qt : : Key_Super_L ? 0x15B : 0x15C ) ;
} else
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
processMacKeyboardInput ( true , event ) ;
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 ;
2022-04-26 16:56:44 +06:00
if ( event - > key ( ) = = Qt : : Key_Super_L | | event - > key ( ) = = Qt : : Key_Super_R ) {
keyboard_input ( 0 , event - > key ( ) = = Qt : : Key_Super_L ? 0x15B : 0x15C ) ;
} else
2022-03-19 23:06:17 +00:00
# ifdef Q_OS_MACOS
processMacKeyboardInput ( false , event ) ;
2021-11-30 16:26:49 +06:00
# 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-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 ( ) ;
2022-02-27 14:56:51 +02:00
ui - > stackedWidget - > onResize ( widget - > width ( ) , widget - > height ( ) ) ;
2021-12-07 13:47:42 +01:00
}
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
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
}
2022-02-27 14:56:51 +02:00
void MainWindow : : on_actionRenderer_options_triggered ( )
{
auto dlg = ui - > stackedWidget - > getOptions ( this ) ;
if ( dlg )
dlg - > exec ( ) ;
}