2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2011-02-25 01:05:47 +03:00
|
|
|
// $Id$
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2021-01-30 21:32:52 +03:00
|
|
|
// Copyright (C) 2002-2021 The Bochs Project
|
2001-04-10 05:04:59 +04:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
2009-02-08 12:05:52 +03:00
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2008-02-16 01:05:43 +03:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// Much of this file was written by:
|
|
|
|
// David Ross
|
|
|
|
// dross@pobox.com
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
|
2008-02-06 01:57:43 +03:00
|
|
|
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
2002-10-25 01:07:56 +04:00
|
|
|
// is used to know when we are exporting symbols and when we are importing.
|
|
|
|
#define BX_PLUGGABLE
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
#include "bochs.h"
|
2010-02-26 17:18:19 +03:00
|
|
|
#include "param_names.h"
|
2009-02-23 14:06:53 +03:00
|
|
|
#include "keymap.h"
|
2004-12-05 23:23:39 +03:00
|
|
|
#include "iodev/iodev.h"
|
2002-11-19 08:47:45 +03:00
|
|
|
#if BX_WITH_WIN32
|
|
|
|
|
2004-12-05 23:23:39 +03:00
|
|
|
#include "zmouse.h"
|
2005-10-22 15:00:00 +04:00
|
|
|
#include "win32dialog.h"
|
2002-12-26 21:24:41 +03:00
|
|
|
#include "win32res.h"
|
2001-04-10 05:04:59 +04:00
|
|
|
#include "font/vga.bitmap.h"
|
2002-10-04 01:07:04 +04:00
|
|
|
// windows.h is included by bochs.h
|
2002-08-10 19:23:30 +04:00
|
|
|
#include <commctrl.h>
|
2001-04-10 05:04:59 +04:00
|
|
|
#include <process.h>
|
|
|
|
|
2020-07-17 19:12:21 +03:00
|
|
|
#define COMMAND_MODE_VKEY VK_F7
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
class bx_win32_gui_c : public bx_gui_c {
|
|
|
|
public:
|
2014-07-08 20:51:38 +04:00
|
|
|
bx_win32_gui_c(void);
|
2006-01-22 21:15:48 +03:00
|
|
|
DECLARE_GUI_VIRTUAL_METHODS();
|
2021-01-30 21:32:52 +03:00
|
|
|
virtual void set_font(bool lg);
|
2020-11-19 19:32:22 +03:00
|
|
|
virtual void draw_char(Bit8u ch, Bit8u fc, Bit8u bc, Bit16u xc, Bit16u yc,
|
|
|
|
Bit8u fw, Bit8u fh, Bit8u fx, Bit8u fy,
|
2021-01-30 21:32:52 +03:00
|
|
|
bool gfxcharw9, Bit8u cs, Bit8u ce, bool curs);
|
|
|
|
virtual void statusbar_setitem_specific(int element, bool active, bool w);
|
2006-12-05 22:45:56 +03:00
|
|
|
virtual void get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp);
|
2006-01-25 20:37:22 +03:00
|
|
|
virtual void set_tooltip(unsigned hbar_id, const char *tip);
|
2021-01-30 21:32:52 +03:00
|
|
|
virtual void set_mouse_mode_absxy(bool mode);
|
2006-01-22 21:15:48 +03:00
|
|
|
#if BX_SHOW_IPS
|
2006-01-22 15:31:16 +03:00
|
|
|
virtual void show_ips(Bit32u ips_count);
|
2006-01-22 21:15:48 +03:00
|
|
|
#endif
|
2002-10-25 01:07:56 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
// declare one instance of the gui object and call macro to insert the
|
|
|
|
// plugin code
|
|
|
|
static bx_win32_gui_c *theGui = NULL;
|
|
|
|
IMPLEMENT_GUI_PLUGIN_CODE(win32)
|
|
|
|
|
|
|
|
#define LOG_THIS theGui->
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
#define EXIT_GUI_SHUTDOWN 1
|
|
|
|
#define EXIT_GMH_FAILURE 2
|
|
|
|
#define EXIT_FONT_BITMAP_ERROR 3
|
|
|
|
#define EXIT_NORMAL 4
|
|
|
|
#define EXIT_HEADER_BITMAP_ERROR 5
|
|
|
|
|
2005-05-08 23:10:21 +04:00
|
|
|
#ifndef TBSTYLE_FLAT
|
|
|
|
#define TBSTYLE_FLAT 0x0800
|
|
|
|
#endif
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// Keyboard/mouse stuff
|
|
|
|
#define SCANCODE_BUFSIZE 20
|
|
|
|
#define MOUSE_PRESSED 0x20000000
|
2017-01-14 18:11:14 +03:00
|
|
|
#define TOOLBAR_CLICKED 0x08000000
|
2001-04-10 05:04:59 +04:00
|
|
|
#define MOUSE_MOTION 0x22000000
|
2014-12-27 18:57:30 +03:00
|
|
|
#define FOCUS_CHANGED 0x44000000
|
2006-12-05 22:45:56 +03:00
|
|
|
#define BX_SYSKEY (KF_UP|KF_REPEAT|KF_ALTDOWN)
|
2001-04-10 05:04:59 +04:00
|
|
|
void enq_key_event(Bit32u, Bit32u);
|
|
|
|
void enq_mouse_event(void);
|
|
|
|
|
|
|
|
struct QueueEvent {
|
|
|
|
Bit32u key_event;
|
|
|
|
int mouse_x;
|
|
|
|
int mouse_y;
|
2004-12-05 23:23:39 +03:00
|
|
|
int mouse_z;
|
2001-04-10 05:04:59 +04:00
|
|
|
int mouse_button_state;
|
|
|
|
};
|
|
|
|
QueueEvent* deq_key_event(void);
|
|
|
|
|
|
|
|
static QueueEvent keyevents[SCANCODE_BUFSIZE];
|
2014-12-30 19:31:17 +03:00
|
|
|
static unsigned head = 0, tail = 0;
|
2002-10-25 01:07:56 +04:00
|
|
|
static int mouse_button_state = 0;
|
2014-12-30 19:31:17 +03:00
|
|
|
static int ms_xdelta = 0, ms_ydelta = 0, ms_zdelta = 0;
|
|
|
|
static int ms_lastx = 0, ms_lasty = 0;
|
|
|
|
static int ms_savedx = 0, ms_savedy = 0;
|
2004-02-17 00:47:08 +03:00
|
|
|
static BOOL mouseCaptureMode, mouseCaptureNew, mouseToggleReq;
|
2012-06-26 00:08:52 +04:00
|
|
|
static BOOL win32MouseModeAbsXY = 0;
|
2013-11-01 22:19:52 +04:00
|
|
|
static HANDLE workerThread = 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
static DWORD workerThreadID = 0;
|
2004-08-18 13:03:48 +04:00
|
|
|
static int mouse_buttons = 3;
|
2021-01-30 21:32:52 +03:00
|
|
|
static bool win32_autoscale = 0;
|
|
|
|
static bool win32_nokeyrepeat = 0;
|
|
|
|
static bool win32_traphotkeys = 0;
|
2017-05-06 00:44:30 +03:00
|
|
|
HHOOK hKeyboardHook;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// Graphics screen stuff
|
2012-03-03 12:24:30 +04:00
|
|
|
static unsigned x_tilesize = 0;
|
2012-01-22 13:08:59 +04:00
|
|
|
static unsigned win32_max_xres = 0, win32_max_yres = 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
static BITMAPINFO* bitmap_info=(BITMAPINFO*)0;
|
|
|
|
static RGBQUAD* cmap_index; // indeces into system colormap
|
|
|
|
static HBITMAP MemoryBitmap = NULL;
|
|
|
|
static HDC MemoryDC = NULL;
|
|
|
|
static RECT updated_area;
|
|
|
|
static BOOL updated_area_valid = FALSE;
|
2006-12-05 22:45:56 +03:00
|
|
|
static HWND desktopWindow;
|
|
|
|
static RECT desktop;
|
|
|
|
static BOOL queryFullScreen = FALSE;
|
2020-10-23 16:14:34 +03:00
|
|
|
static unsigned desktop_x, desktop_y;
|
2020-10-25 19:23:42 +03:00
|
|
|
static unsigned max_client_x, max_client_y;
|
2006-12-05 22:45:56 +03:00
|
|
|
static BOOL toolbarVisible, statusVisible;
|
2020-10-25 19:23:42 +03:00
|
|
|
static BOOL fullscreenMode, inFullscreenToggle;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2006-10-15 20:23:42 +04:00
|
|
|
// Text mode screen stuff
|
|
|
|
static HBITMAP vgafont[256];
|
|
|
|
static int xChar = 8, yChar = 16;
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// Headerbar stuff
|
2003-10-19 12:24:12 +04:00
|
|
|
HWND hwndTB, hwndSB;
|
2010-01-24 15:46:42 +03:00
|
|
|
static unsigned bx_bitmap_entries;
|
|
|
|
static struct {
|
2001-04-10 05:04:59 +04:00
|
|
|
HBITMAP bmap;
|
|
|
|
unsigned xdim;
|
|
|
|
unsigned ydim;
|
|
|
|
} bx_bitmaps[BX_MAX_PIXMAPS];
|
|
|
|
|
|
|
|
static struct {
|
2002-08-10 19:23:30 +04:00
|
|
|
unsigned bmap_id;
|
2001-04-10 05:04:59 +04:00
|
|
|
void (*f)(void);
|
2006-01-25 20:37:22 +03:00
|
|
|
const char *tooltip;
|
2017-01-14 18:11:14 +03:00
|
|
|
} win32_toolbar_entry[BX_MAX_HEADERBAR_ENTRIES];
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2017-01-14 18:11:14 +03:00
|
|
|
static int win32_toolbar_entries;
|
2002-08-10 19:23:30 +04:00
|
|
|
static unsigned bx_hb_separator;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2004-02-07 17:34:35 +03:00
|
|
|
// Status Bar stuff
|
2006-01-24 00:53:57 +03:00
|
|
|
#if BX_SHOW_IPS
|
|
|
|
static BOOL ipsUpdate = FALSE;
|
2012-08-30 00:36:12 +04:00
|
|
|
static BOOL hideIPS = FALSE;
|
2006-01-24 00:53:57 +03:00
|
|
|
static char ipsText[20];
|
|
|
|
#endif
|
2012-08-30 00:36:12 +04:00
|
|
|
#define BX_SB_MAX_TEXT_ELEMENTS 2
|
2006-01-27 21:04:49 +03:00
|
|
|
#define SIZE_OF_SB_ELEMENT 40
|
|
|
|
#define SIZE_OF_SB_MOUSE_MESSAGE 170
|
2012-08-30 00:36:12 +04:00
|
|
|
#define SIZE_OF_SB_IPS_MESSAGE 90
|
2020-12-16 23:04:47 +03:00
|
|
|
Bit32u SB_Led_Colors[3] = {0x0000FF00, 0x000040FF, 0x0000FFFF};
|
2014-07-06 18:17:18 +04:00
|
|
|
Bit32s SB_Edges[BX_MAX_STATUSITEMS+BX_SB_MAX_TEXT_ELEMENTS+1];
|
2006-01-27 21:04:49 +03:00
|
|
|
char SB_Text[BX_MAX_STATUSITEMS][10];
|
2012-08-30 00:36:12 +04:00
|
|
|
unsigned SB_Text_Elements;
|
2021-01-30 21:32:52 +03:00
|
|
|
bool SB_Active[BX_MAX_STATUSITEMS];
|
2020-12-16 23:04:47 +03:00
|
|
|
Bit8u SB_ActiveColor[BX_MAX_STATUSITEMS];
|
2004-02-07 17:34:35 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// Misc stuff
|
2003-11-05 20:25:29 +03:00
|
|
|
static unsigned dimension_x, dimension_y, current_bpp;
|
2001-04-10 05:04:59 +04:00
|
|
|
static unsigned stretched_x, stretched_y;
|
2020-10-23 16:14:34 +03:00
|
|
|
static unsigned stretch_factor;
|
2005-05-08 23:10:21 +04:00
|
|
|
static BOOL fix_size = FALSE;
|
2009-01-12 22:15:35 +03:00
|
|
|
#if BX_DEBUGGER && BX_DEBUGGER_GUI
|
2008-12-27 15:06:39 +03:00
|
|
|
static BOOL gui_debug = FALSE;
|
2006-11-17 19:50:39 +03:00
|
|
|
#endif
|
2006-12-05 22:45:56 +03:00
|
|
|
static HWND hotKeyReceiver = NULL;
|
|
|
|
static HWND saveParent = NULL;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2010-05-17 00:44:08 +04:00
|
|
|
static char szMouseEnable[40];
|
|
|
|
static char szMouseDisable[40];
|
|
|
|
static char szMouseTooltip[64];
|
2004-08-18 13:03:48 +04:00
|
|
|
|
2009-11-03 23:38:03 +03:00
|
|
|
static const char szAppName[] = "Bochs for Windows";
|
|
|
|
static const char szWindowName[] = "Bochs for Windows - Display";
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
HINSTANCE hInstance;
|
|
|
|
|
|
|
|
CRITICAL_SECTION drawCS;
|
|
|
|
CRITICAL_SECTION keyCS;
|
|
|
|
CRITICAL_SECTION mouseCS;
|
|
|
|
|
|
|
|
int kill; // reason for terminateEmul(int)
|
|
|
|
BOOL UIinited;
|
2002-08-10 19:23:30 +04:00
|
|
|
HWND mainWnd;
|
|
|
|
HWND simWnd;
|
2001-04-10 05:04:59 +04:00
|
|
|
} sharedThreadInfo;
|
|
|
|
|
|
|
|
sharedThreadInfo stInfo;
|
|
|
|
|
2013-12-27 00:51:46 +04:00
|
|
|
LRESULT CALLBACK mainWndProc(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
LRESULT CALLBACK simWndProc(HWND, UINT, WPARAM, LPARAM);
|
2013-11-01 22:19:52 +04:00
|
|
|
DWORD WINAPI UIThread(PVOID);
|
2021-01-30 21:32:52 +03:00
|
|
|
void SetStatusText(unsigned Num, const char *Text, bool active, Bit8u color=0);
|
2001-04-10 05:04:59 +04:00
|
|
|
void terminateEmul(int);
|
|
|
|
void create_vga_font(void);
|
2020-11-19 19:32:22 +03:00
|
|
|
void DrawBitmap(HDC, HBITMAP, int, int, int, int, int, int, Bit8u, Bit8u);
|
2001-04-10 05:04:59 +04:00
|
|
|
void updateUpdated(int,int,int,int);
|
2017-01-14 18:11:14 +03:00
|
|
|
static void win32_toolbar_click(int x);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-10-25 21:37:58 +04:00
|
|
|
Bit32u win32_to_bx_key[2][0x100] =
|
|
|
|
{
|
|
|
|
{ /* normal-keys */
|
|
|
|
/* 0x00 - 0x0f */
|
|
|
|
0,
|
|
|
|
BX_KEY_ESC,
|
|
|
|
BX_KEY_1,
|
|
|
|
BX_KEY_2,
|
|
|
|
BX_KEY_3,
|
|
|
|
BX_KEY_4,
|
|
|
|
BX_KEY_5,
|
|
|
|
BX_KEY_6,
|
|
|
|
BX_KEY_7,
|
|
|
|
BX_KEY_8,
|
|
|
|
BX_KEY_9,
|
|
|
|
BX_KEY_0,
|
|
|
|
BX_KEY_MINUS,
|
|
|
|
BX_KEY_EQUALS,
|
|
|
|
BX_KEY_BACKSPACE,
|
|
|
|
BX_KEY_TAB,
|
|
|
|
/* 0x10 - 0x1f */
|
|
|
|
BX_KEY_Q,
|
|
|
|
BX_KEY_W,
|
|
|
|
BX_KEY_E,
|
|
|
|
BX_KEY_R,
|
|
|
|
BX_KEY_T,
|
|
|
|
BX_KEY_Y,
|
|
|
|
BX_KEY_U,
|
|
|
|
BX_KEY_I,
|
|
|
|
BX_KEY_O,
|
|
|
|
BX_KEY_P,
|
|
|
|
BX_KEY_LEFT_BRACKET,
|
|
|
|
BX_KEY_RIGHT_BRACKET,
|
|
|
|
BX_KEY_ENTER,
|
|
|
|
BX_KEY_CTRL_L,
|
|
|
|
BX_KEY_A,
|
|
|
|
BX_KEY_S,
|
|
|
|
/* 0x20 - 0x2f */
|
|
|
|
BX_KEY_D,
|
|
|
|
BX_KEY_F,
|
|
|
|
BX_KEY_G,
|
|
|
|
BX_KEY_H,
|
|
|
|
BX_KEY_J,
|
|
|
|
BX_KEY_K,
|
|
|
|
BX_KEY_L,
|
|
|
|
BX_KEY_SEMICOLON,
|
|
|
|
BX_KEY_SINGLE_QUOTE,
|
|
|
|
BX_KEY_GRAVE,
|
|
|
|
BX_KEY_SHIFT_L,
|
|
|
|
BX_KEY_BACKSLASH,
|
|
|
|
BX_KEY_Z,
|
|
|
|
BX_KEY_X,
|
|
|
|
BX_KEY_C,
|
|
|
|
BX_KEY_V,
|
|
|
|
/* 0x30 - 0x3f */
|
|
|
|
BX_KEY_B,
|
|
|
|
BX_KEY_N,
|
|
|
|
BX_KEY_M,
|
|
|
|
BX_KEY_COMMA,
|
|
|
|
BX_KEY_PERIOD,
|
|
|
|
BX_KEY_SLASH,
|
|
|
|
BX_KEY_SHIFT_R,
|
|
|
|
BX_KEY_KP_MULTIPLY,
|
|
|
|
BX_KEY_ALT_L,
|
|
|
|
BX_KEY_SPACE,
|
|
|
|
BX_KEY_CAPS_LOCK,
|
|
|
|
BX_KEY_F1,
|
|
|
|
BX_KEY_F2,
|
|
|
|
BX_KEY_F3,
|
|
|
|
BX_KEY_F4,
|
|
|
|
BX_KEY_F5,
|
|
|
|
/* 0x40 - 0x4f */
|
|
|
|
BX_KEY_F6,
|
|
|
|
BX_KEY_F7,
|
|
|
|
BX_KEY_F8,
|
|
|
|
BX_KEY_F9,
|
|
|
|
BX_KEY_F10,
|
|
|
|
BX_KEY_PAUSE,
|
|
|
|
BX_KEY_SCRL_LOCK,
|
|
|
|
BX_KEY_KP_HOME,
|
|
|
|
BX_KEY_KP_UP,
|
|
|
|
BX_KEY_KP_PAGE_UP,
|
|
|
|
BX_KEY_KP_SUBTRACT,
|
|
|
|
BX_KEY_KP_LEFT,
|
|
|
|
BX_KEY_KP_5,
|
|
|
|
BX_KEY_KP_RIGHT,
|
|
|
|
BX_KEY_KP_ADD,
|
|
|
|
BX_KEY_KP_END,
|
|
|
|
/* 0x50 - 0x5f */
|
|
|
|
BX_KEY_KP_DOWN,
|
|
|
|
BX_KEY_KP_PAGE_DOWN,
|
|
|
|
BX_KEY_KP_INSERT,
|
|
|
|
BX_KEY_KP_DELETE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_LEFT_BACKSLASH,
|
|
|
|
BX_KEY_F11,
|
|
|
|
BX_KEY_F12,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
/* 0x60 - 0x6f */
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
/* 0x70 - 0x7f */
|
2008-02-16 01:05:43 +03:00
|
|
|
0, /* Todo: "Katakana" key (ibm 133) for Japanese 106 keyboard */
|
2003-10-25 21:37:58 +04:00
|
|
|
0,
|
|
|
|
0,
|
2008-02-16 01:05:43 +03:00
|
|
|
0, /* Todo: "Ro" key (ibm 56) for Japanese 106 keyboard */
|
2003-10-25 21:37:58 +04:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
2008-02-16 01:05:43 +03:00
|
|
|
0, /* Todo: "convert" key (ibm 132) for Japanese 106 keyboard */
|
2003-10-25 21:37:58 +04:00
|
|
|
0,
|
2008-02-16 01:05:43 +03:00
|
|
|
0, /* Todo: "non-convert" key (ibm 131) for Japanese 106 keyboard */
|
2003-10-25 21:37:58 +04:00
|
|
|
0,
|
2008-02-16 01:05:43 +03:00
|
|
|
0, /* Todo: "Yen" key (ibm 14) for Japanese 106 keyboard */
|
2003-10-25 21:37:58 +04:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
},
|
|
|
|
{ /* extended-keys */
|
|
|
|
/* 0x00 - 0x0f */
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
/* 0x10 - 0x1f */
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_KP_ENTER,
|
|
|
|
BX_KEY_CTRL_R,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
/* 0x20 - 0x2f */
|
|
|
|
0,
|
|
|
|
BX_KEY_POWER_CALC,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
/* 0x30 - 0x3f */
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_INT_HOME,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_KP_DIVIDE,
|
|
|
|
0,
|
2007-08-18 12:05:33 +04:00
|
|
|
BX_KEY_PRINT,
|
2003-10-25 21:37:58 +04:00
|
|
|
BX_KEY_ALT_R,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
/* 0x40 - 0x4f */
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_NUM_LOCK,
|
2011-06-21 21:10:40 +04:00
|
|
|
BX_KEY_CTRL_BREAK,
|
2003-10-25 21:37:58 +04:00
|
|
|
BX_KEY_HOME,
|
|
|
|
BX_KEY_UP,
|
|
|
|
BX_KEY_PAGE_UP,
|
|
|
|
0,
|
|
|
|
BX_KEY_LEFT,
|
|
|
|
0,
|
|
|
|
BX_KEY_RIGHT,
|
|
|
|
0,
|
|
|
|
BX_KEY_END,
|
|
|
|
/* 0x50 - 0x5f */
|
|
|
|
BX_KEY_DOWN,
|
|
|
|
BX_KEY_PAGE_DOWN,
|
|
|
|
BX_KEY_INSERT,
|
|
|
|
BX_KEY_DELETE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_WIN_L,
|
|
|
|
BX_KEY_WIN_R,
|
|
|
|
BX_KEY_MENU,
|
|
|
|
BX_KEY_POWER_POWER,
|
|
|
|
BX_KEY_POWER_SLEEP,
|
|
|
|
/* 0x60 - 0x6f */
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
BX_KEY_POWER_WAKE,
|
|
|
|
0,
|
|
|
|
BX_KEY_INT_SEARCH,
|
|
|
|
BX_KEY_INT_FAV,
|
|
|
|
0,
|
|
|
|
BX_KEY_INT_STOP,
|
|
|
|
BX_KEY_INT_FORWARD,
|
|
|
|
BX_KEY_INT_BACK,
|
|
|
|
BX_KEY_POWER_MYCOMP,
|
|
|
|
BX_KEY_INT_MAIL,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
}
|
2003-02-17 22:08:12 +03:00
|
|
|
};
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
/* Macro to convert WM_ button state to BX button state */
|
|
|
|
|
2017-05-06 00:44:30 +03:00
|
|
|
void gen_key_event(Bit32u key, Bit32u press_release)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
|
|
|
enq_key_event(key, press_release);
|
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
|
|
|
|
{
|
|
|
|
if (nCode < 0 || nCode != HC_ACTION || (!mouseCaptureMode && !fullscreenMode))
|
|
|
|
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
|
|
|
|
|
|
|
|
KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
|
|
|
|
Bit32u press_release = (p->flags & LLKHF_UP) ? BX_KEY_RELEASED : BX_KEY_PRESSED;
|
|
|
|
BOOL bAltKeyDown = (p->flags & LLKHF_ALTDOWN);
|
|
|
|
BOOL bControlKeyDown = GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); //checks ctrl key pressed
|
|
|
|
|
|
|
|
if (p->vkCode == VK_TAB && bAltKeyDown) {
|
|
|
|
gen_key_event(p->scanCode, press_release);
|
|
|
|
return 1; //disable alt-tab
|
|
|
|
}
|
|
|
|
if (p->vkCode == VK_SPACE && bAltKeyDown) {
|
|
|
|
gen_key_event(p->scanCode, press_release);
|
|
|
|
return 1; //disable alt-space
|
|
|
|
}
|
|
|
|
if ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) {
|
|
|
|
gen_key_event(p->vkCode | 0x100, press_release);
|
|
|
|
return 1;//disable windows keys
|
|
|
|
}
|
|
|
|
if (p->vkCode == VK_ESCAPE && bAltKeyDown) {
|
|
|
|
gen_key_event(p->scanCode, press_release);
|
|
|
|
return 1;//disable alt-escape
|
|
|
|
}
|
|
|
|
if (p->vkCode == VK_ESCAPE && bControlKeyDown) {
|
|
|
|
gen_key_event(p->scanCode, press_release);
|
|
|
|
return 1; //disable ctrl-escape
|
|
|
|
}
|
|
|
|
|
|
|
|
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2009-05-13 21:26:45 +04:00
|
|
|
#if BX_SHOW_IPS
|
|
|
|
VOID CALLBACK MyTimer(HWND,UINT,UINT,DWORD);
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
|
|
|
|
2014-12-30 19:31:17 +03:00
|
|
|
static void cursorWarped()
|
|
|
|
{
|
|
|
|
POINT pt = { 0, 0 };
|
|
|
|
|
|
|
|
ClientToScreen(stInfo.simWnd, &pt);
|
|
|
|
SetCursorPos(pt.x + stretched_x / 2, pt.y + stretched_y / 2);
|
|
|
|
EnterCriticalSection(&stInfo.mouseCS);
|
|
|
|
ms_savedx = stretched_x / 2;
|
|
|
|
ms_savedy = stretched_y / 2;
|
|
|
|
LeaveCriticalSection(&stInfo.mouseCS);
|
|
|
|
}
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
static void processMouseXY(int x, int y, int z, int windows_state, int implied_state_change)
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
|
|
|
int bx_state;
|
|
|
|
int old_bx_state;
|
2008-02-16 01:05:43 +03:00
|
|
|
EnterCriticalSection(&stInfo.mouseCS);
|
2014-12-30 19:31:17 +03:00
|
|
|
bx_state = ((windows_state & MK_LBUTTON) ? 1 : 0) + ((windows_state & MK_RBUTTON) ? 2 : 0) +
|
|
|
|
((windows_state & MK_MBUTTON) ? 4 : 0);
|
|
|
|
old_bx_state = bx_state ^ implied_state_change;
|
|
|
|
if (old_bx_state != mouse_button_state) {
|
2001-04-10 05:04:59 +04:00
|
|
|
/* Make up for missing message */
|
2008-02-16 01:05:43 +03:00
|
|
|
BX_INFO(("&&&missing mouse state change"));
|
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
enq_mouse_event();
|
2014-12-30 19:31:17 +03:00
|
|
|
mouse_button_state = old_bx_state;
|
2008-02-16 01:05:43 +03:00
|
|
|
enq_key_event(mouse_button_state, MOUSE_PRESSED);
|
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
2014-12-30 19:31:17 +03:00
|
|
|
ms_ydelta = ms_savedy - y;
|
|
|
|
ms_xdelta = x - ms_savedx;
|
|
|
|
ms_zdelta = z;
|
|
|
|
ms_lastx = x;
|
|
|
|
ms_lasty = y;
|
|
|
|
if (bx_state!=mouse_button_state) {
|
2008-02-16 01:05:43 +03:00
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
enq_mouse_event();
|
2014-12-30 19:31:17 +03:00
|
|
|
mouse_button_state = bx_state;
|
2008-02-16 01:05:43 +03:00
|
|
|
enq_key_event(mouse_button_state, MOUSE_PRESSED);
|
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
2014-12-30 19:31:17 +03:00
|
|
|
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
|
|
|
cursorWarped();
|
|
|
|
}
|
2008-02-16 01:05:43 +03:00
|
|
|
LeaveCriticalSection(&stInfo.mouseCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// GUI thread must be dead/done in order to call terminateEmul
|
2008-02-16 01:05:43 +03:00
|
|
|
void terminateEmul(int reason)
|
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
// We know that Critical Sections were inited when x_tilesize has been set
|
2002-10-25 01:07:56 +04:00
|
|
|
// See bx_win32_gui_c::specific_init
|
2001-04-10 05:04:59 +04:00
|
|
|
if (x_tilesize != 0) {
|
|
|
|
DeleteCriticalSection (&stInfo.drawCS);
|
|
|
|
DeleteCriticalSection (&stInfo.keyCS);
|
|
|
|
DeleteCriticalSection (&stInfo.mouseCS);
|
|
|
|
}
|
2002-08-10 19:23:30 +04:00
|
|
|
x_tilesize = 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
if (MemoryDC) DeleteDC (MemoryDC);
|
|
|
|
if (MemoryBitmap) DeleteObject (MemoryBitmap);
|
|
|
|
|
2016-12-05 21:56:56 +03:00
|
|
|
delete[] (char*)bitmap_info;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-08-10 00:25:02 +04:00
|
|
|
for (unsigned b=0; b<bx_bitmap_entries; b++)
|
|
|
|
if (bx_bitmaps[b].bmap) DeleteObject(bx_bitmaps[b].bmap);
|
2001-04-10 05:04:59 +04:00
|
|
|
for (unsigned c=0; c<256; c++)
|
|
|
|
if (vgafont[c]) DeleteObject(vgafont[c]);
|
2002-08-10 00:25:02 +04:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
switch (reason) {
|
|
|
|
case EXIT_GUI_SHUTDOWN:
|
2017-01-25 00:52:19 +03:00
|
|
|
BX_FATAL(("Window closed, exiting!"));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case EXIT_GMH_FAILURE:
|
2017-01-25 00:52:19 +03:00
|
|
|
BX_FATAL(("GetModuleHandle failure!"));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case EXIT_FONT_BITMAP_ERROR:
|
2017-01-25 00:52:19 +03:00
|
|
|
BX_FATAL(("Font bitmap creation failure!"));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case EXIT_HEADER_BITMAP_ERROR:
|
2017-01-25 00:52:19 +03:00
|
|
|
BX_FATAL(("Header bitmap creation failure!"));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case EXIT_NORMAL:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-15 14:44:43 +03:00
|
|
|
// WIN32 implementation of the bx_gui_c methods (see nogui.cc for details)
|
|
|
|
|
2014-07-08 20:51:38 +04:00
|
|
|
bx_win32_gui_c::bx_win32_gui_c()
|
|
|
|
{
|
|
|
|
// prepare for possible fullscreen mode
|
|
|
|
desktopWindow = GetDesktopWindow();
|
|
|
|
GetWindowRect(desktopWindow, &desktop);
|
|
|
|
desktop_x = desktop.right - desktop.left;
|
|
|
|
desktop_y = desktop.bottom - desktop.top;
|
2020-10-25 19:23:42 +03:00
|
|
|
max_client_x = desktop_x - 20;
|
|
|
|
max_client_y = desktop_y - 80;
|
2014-07-08 20:51:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-03 16:41:24 +04:00
|
|
|
void bx_win32_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
|
2004-02-24 22:21:48 +03:00
|
|
|
{
|
2005-02-03 21:43:23 +03:00
|
|
|
int i;
|
2021-01-30 21:32:52 +03:00
|
|
|
bool gui_ci;
|
2004-02-23 19:33:52 +03:00
|
|
|
|
2009-03-24 19:28:03 +03:00
|
|
|
gui_ci = !strcmp(SIM->get_param_enum(BXPN_SEL_CONFIG_INTERFACE)->get_selected(), "win32config");
|
2013-12-29 16:56:52 +04:00
|
|
|
put("WINGUI");
|
2006-12-05 22:45:56 +03:00
|
|
|
|
|
|
|
hotKeyReceiver = stInfo.simWnd;
|
2014-05-20 22:42:36 +04:00
|
|
|
fullscreenMode = FALSE;
|
2020-10-25 19:23:42 +03:00
|
|
|
inFullscreenToggle = FALSE;
|
|
|
|
BX_INFO(("Desktop window dimensions: %d x %d", desktop_x, desktop_y));
|
2006-12-05 22:45:56 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
static RGBQUAD black_quad={ 0, 0, 0, 0};
|
|
|
|
stInfo.kill = 0;
|
|
|
|
stInfo.UIinited = FALSE;
|
|
|
|
InitializeCriticalSection(&stInfo.drawCS);
|
|
|
|
InitializeCriticalSection(&stInfo.keyCS);
|
|
|
|
InitializeCriticalSection(&stInfo.mouseCS);
|
|
|
|
|
2012-03-03 16:41:24 +04:00
|
|
|
x_tilesize = this->x_tilesize;
|
2012-01-22 13:08:59 +04:00
|
|
|
win32_max_xres = this->max_xres;
|
|
|
|
win32_max_yres = this->max_yres;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
bx_bitmap_entries = 0;
|
2017-01-14 18:11:14 +03:00
|
|
|
win32_toolbar_entries = 0;
|
2002-08-10 19:23:30 +04:00
|
|
|
bx_hb_separator = 0;
|
|
|
|
mouseCaptureMode = FALSE;
|
2004-02-17 00:47:08 +03:00
|
|
|
mouseCaptureNew = FALSE;
|
|
|
|
mouseToggleReq = FALSE;
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2004-08-18 13:03:48 +04:00
|
|
|
// parse win32 specific options
|
|
|
|
if (argc > 1) {
|
|
|
|
for (i = 1; i < argc; i++) {
|
2004-08-22 20:22:09 +04:00
|
|
|
BX_INFO(("option %d: %s", i, argv[i]));
|
2011-12-05 01:15:35 +04:00
|
|
|
if (!strcmp(argv[i], "nokeyrepeat")) {
|
|
|
|
BX_INFO(("disabled host keyboard repeat"));
|
|
|
|
win32_nokeyrepeat = 1;
|
2017-05-06 00:44:30 +03:00
|
|
|
} else if (!strcmp(argv[i], "traphotkeys")) {
|
|
|
|
BX_INFO(("trap system hotkeys for Bochs window"));
|
|
|
|
win32_traphotkeys = 1;
|
2009-01-12 22:15:35 +03:00
|
|
|
#if BX_DEBUGGER && BX_DEBUGGER_GUI
|
2008-12-27 15:06:39 +03:00
|
|
|
} else if (!strcmp(argv[i], "gui_debug")) {
|
2009-03-24 19:28:03 +03:00
|
|
|
if (gui_ci) {
|
|
|
|
gui_debug = TRUE;
|
|
|
|
SIM->set_debug_gui(1);
|
|
|
|
} else {
|
|
|
|
BX_PANIC(("Config interface 'win32config' is required for gui debugger"));
|
|
|
|
}
|
2012-08-30 00:36:12 +04:00
|
|
|
#endif
|
|
|
|
#if BX_SHOW_IPS
|
|
|
|
} else if (!strcmp(argv[i], "hideIPS")) {
|
|
|
|
BX_INFO(("hide IPS display in status bar"));
|
|
|
|
hideIPS = TRUE;
|
2006-11-12 13:07:18 +03:00
|
|
|
#endif
|
2020-07-17 19:12:21 +03:00
|
|
|
} else if (!strcmp(argv[i], "cmdmode")) {
|
|
|
|
command_mode.present = 1;
|
2020-10-23 16:14:34 +03:00
|
|
|
} else if (!strcmp(argv[i], "autoscale")) {
|
|
|
|
win32_autoscale = 1;
|
2004-08-18 13:03:48 +04:00
|
|
|
} else {
|
|
|
|
BX_PANIC(("Unknown win32 option '%s'", argv[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2010-05-18 19:33:41 +04:00
|
|
|
mouse_buttons = GetSystemMetrics(SM_CMOUSEBUTTONS);
|
|
|
|
BX_INFO(("Number of Mouse Buttons = %d", mouse_buttons));
|
|
|
|
if ((SIM->get_param_enum(BXPN_MOUSE_TOGGLE)->get() == BX_MOUSE_TOGGLE_CTRL_MB) &&
|
|
|
|
(mouse_buttons == 2)) {
|
|
|
|
lstrcpy(szMouseEnable, "CTRL + Lbutton + Rbutton enables mouse ");
|
|
|
|
lstrcpy(szMouseDisable, "CTRL + Lbutton + Rbutton disables mouse");
|
|
|
|
lstrcpy(szMouseTooltip, "Enable mouse capture\nUse CTRL + Lbutton + Rbutton to release");
|
2010-05-17 00:44:08 +04:00
|
|
|
} else {
|
2010-05-18 19:33:41 +04:00
|
|
|
wsprintf(szMouseEnable, "%s enables mouse ", get_toggle_info());
|
|
|
|
wsprintf(szMouseDisable, "%s disables mouse", get_toggle_info());
|
|
|
|
wsprintf(szMouseTooltip, "Enable mouse capture\nUse %s to release", get_toggle_info());
|
2004-08-18 13:03:48 +04:00
|
|
|
}
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
stInfo.hInstance = GetModuleHandle(NULL);
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
UNUSED(headerbar_y);
|
2001-04-10 05:04:59 +04:00
|
|
|
dimension_x = 640;
|
2002-08-10 19:23:30 +04:00
|
|
|
dimension_y = 480;
|
2003-11-05 20:25:29 +03:00
|
|
|
current_bpp = 8;
|
2001-04-10 05:04:59 +04:00
|
|
|
stretched_x = dimension_x;
|
|
|
|
stretched_y = dimension_y;
|
2020-10-23 16:14:34 +03:00
|
|
|
stretch_factor = 1;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
for(unsigned c=0; c<256; c++) vgafont[c] = NULL;
|
|
|
|
create_vga_font();
|
|
|
|
|
2016-12-05 21:56:56 +03:00
|
|
|
bitmap_info=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)+259*sizeof(RGBQUAD)]; // 256 + 3 entries for 16 bpp mode
|
2001-04-10 05:04:59 +04:00
|
|
|
bitmap_info->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
|
|
|
bitmap_info->bmiHeader.biWidth=x_tilesize;
|
|
|
|
// Height is negative for top-down bitmap
|
2006-10-15 20:23:42 +04:00
|
|
|
bitmap_info->bmiHeader.biHeight= -(LONG)y_tilesize;
|
2001-04-10 05:04:59 +04:00
|
|
|
bitmap_info->bmiHeader.biPlanes=1;
|
|
|
|
bitmap_info->bmiHeader.biBitCount=8;
|
|
|
|
bitmap_info->bmiHeader.biCompression=BI_RGB;
|
2003-06-28 12:04:31 +04:00
|
|
|
bitmap_info->bmiHeader.biSizeImage=x_tilesize*y_tilesize*4;
|
2001-04-10 05:04:59 +04:00
|
|
|
// I think these next two figures don't matter; saying 45 pixels/centimeter
|
|
|
|
bitmap_info->bmiHeader.biXPelsPerMeter=4500;
|
|
|
|
bitmap_info->bmiHeader.biYPelsPerMeter=4500;
|
|
|
|
bitmap_info->bmiHeader.biClrUsed=256;
|
|
|
|
bitmap_info->bmiHeader.biClrImportant=0;
|
|
|
|
cmap_index=bitmap_info->bmiColors;
|
|
|
|
// start out with all color map indeces pointing to Black
|
|
|
|
cmap_index[0] = black_quad;
|
2005-03-23 23:46:52 +03:00
|
|
|
for (i=1; i<259; i++) {
|
2001-04-10 05:04:59 +04:00
|
|
|
cmap_index[i] = cmap_index[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stInfo.hInstance)
|
2013-11-01 22:19:52 +04:00
|
|
|
workerThread = CreateThread(NULL, 0, UIThread, NULL, 0, &workerThreadID);
|
2001-04-10 05:04:59 +04:00
|
|
|
else
|
|
|
|
terminateEmul(EXIT_GMH_FAILURE);
|
|
|
|
|
2012-03-03 11:44:53 +04:00
|
|
|
// Wait until UI init is ready before continuing
|
|
|
|
if ((stInfo.kill == 0) && (stInfo.UIinited == FALSE))
|
2001-04-10 05:04:59 +04:00
|
|
|
Sleep(500);
|
|
|
|
|
|
|
|
// Now set this thread's priority to below normal because this is where
|
|
|
|
// the emulated CPU runs, and it hogs the real CPU
|
|
|
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
|
|
|
|
|
2006-02-22 00:35:09 +03:00
|
|
|
if (SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get())
|
|
|
|
BX_INFO(("private_colormap option ignored."));
|
2002-03-16 14:30:06 +03:00
|
|
|
|
|
|
|
// load keymap tables
|
2006-02-22 22:18:29 +03:00
|
|
|
if (SIM->get_param_bool(BXPN_KBD_USEMAPPING)->get()) {
|
2002-03-16 14:30:06 +03:00
|
|
|
bx_keymap.loadKeymap(NULL); // I have no function to convert X windows symbols
|
2005-10-21 22:00:17 +04:00
|
|
|
}
|
2004-02-23 19:33:52 +03:00
|
|
|
|
2009-03-24 19:28:03 +03:00
|
|
|
if (gui_ci) {
|
|
|
|
dialog_caps = BX_GUI_DLG_ALL;
|
|
|
|
}
|
2020-11-19 19:32:22 +03:00
|
|
|
new_text_api = 1;
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2014-05-22 23:06:01 +04:00
|
|
|
void set_fullscreen_mode(BOOL enable)
|
2005-05-08 23:10:21 +04:00
|
|
|
{
|
2014-05-18 23:13:35 +04:00
|
|
|
unsigned long mainStyle, simExStyle;
|
2005-05-08 23:10:21 +04:00
|
|
|
|
2014-05-22 23:06:01 +04:00
|
|
|
if (enable) {
|
|
|
|
if (desktop_y > 0) {
|
2020-10-25 19:23:42 +03:00
|
|
|
if (!queryFullScreen) {
|
|
|
|
MessageBox(NULL,
|
|
|
|
"Going into fullscreen mode -- Alt-Enter to revert",
|
|
|
|
"Going fullscreen",
|
|
|
|
MB_APPLMODAL);
|
|
|
|
queryFullScreen = TRUE;
|
|
|
|
enq_key_event(0x38, BX_KEY_RELEASED); // send lost ALT keyup event
|
|
|
|
}
|
|
|
|
inFullscreenToggle = TRUE;
|
|
|
|
BX_INFO(("entering fullscreen mode"));
|
2014-05-22 23:06:01 +04:00
|
|
|
stretched_x = desktop_x;
|
|
|
|
stretched_y = desktop_y;
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
2020-10-25 19:23:42 +03:00
|
|
|
if (win32_autoscale) {
|
|
|
|
stretch_factor = 1;
|
|
|
|
while (((dimension_x * stretch_factor * 2) <= desktop_x) &&
|
|
|
|
((dimension_y * stretch_factor * 2) <= desktop_y)) {
|
|
|
|
stretch_factor *= 2;
|
|
|
|
}
|
|
|
|
if (stretch_factor > 1) BX_INFO(("autoscale: factor = %d", stretch_factor));
|
2006-12-05 22:45:56 +03:00
|
|
|
}
|
|
|
|
// hide toolbar and status bars to get some additional space
|
|
|
|
ShowWindow(hwndTB, SW_HIDE);
|
|
|
|
ShowWindow(hwndSB, SW_HIDE);
|
2014-05-18 23:13:35 +04:00
|
|
|
// hide title bar and border
|
2006-12-05 22:45:56 +03:00
|
|
|
mainStyle = GetWindowLong(stInfo.mainWnd, GWL_STYLE);
|
2014-05-18 23:13:35 +04:00
|
|
|
mainStyle &= ~WS_CAPTION;
|
2006-12-05 22:45:56 +03:00
|
|
|
SetWindowLong(stInfo.mainWnd, GWL_STYLE, mainStyle);
|
2014-05-18 23:13:35 +04:00
|
|
|
simExStyle = GetWindowLong(stInfo.simWnd, GWL_EXSTYLE);
|
|
|
|
simExStyle &= ~WS_EX_CLIENTEDGE;
|
|
|
|
SetWindowLong(stInfo.simWnd, GWL_EXSTYLE, simExStyle);
|
2006-12-05 22:45:56 +03:00
|
|
|
// maybe need to adjust stInfo.simWnd here also?
|
2010-11-01 18:02:14 +03:00
|
|
|
saveParent = SetParent(stInfo.mainWnd, desktopWindow);
|
|
|
|
if (saveParent) {
|
2006-12-05 22:45:56 +03:00
|
|
|
BX_DEBUG(("Saved parent window"));
|
|
|
|
SetWindowPos(stInfo.mainWnd, HWND_TOPMOST, desktop.left, desktop.top,
|
|
|
|
desktop.right, desktop.bottom, SWP_SHOWWINDOW);
|
|
|
|
}
|
2014-05-20 22:42:36 +04:00
|
|
|
fullscreenMode = TRUE;
|
2020-10-25 19:23:42 +03:00
|
|
|
inFullscreenToggle = FALSE;
|
2006-12-05 22:45:56 +03:00
|
|
|
} else {
|
2020-10-25 19:23:42 +03:00
|
|
|
BX_INFO(("leaving fullscreen mode"));
|
2014-05-23 23:28:23 +04:00
|
|
|
stretched_x = dimension_x;
|
|
|
|
stretched_y = dimension_y;
|
2006-12-05 22:45:56 +03:00
|
|
|
if (saveParent) {
|
|
|
|
BX_DEBUG(("Restoring parent window"));
|
|
|
|
SetParent(stInfo.mainWnd, saveParent);
|
|
|
|
saveParent = NULL;
|
|
|
|
}
|
|
|
|
// put back the title bar, border, etc...
|
|
|
|
mainStyle = GetWindowLong(stInfo.mainWnd, GWL_STYLE);
|
2014-05-18 23:13:35 +04:00
|
|
|
mainStyle |= WS_CAPTION;
|
2006-12-05 22:45:56 +03:00
|
|
|
SetWindowLong(stInfo.mainWnd, GWL_STYLE, mainStyle);
|
2014-05-18 23:13:35 +04:00
|
|
|
simExStyle = GetWindowLong(stInfo.simWnd, GWL_EXSTYLE);
|
|
|
|
simExStyle |= WS_EX_CLIENTEDGE;
|
|
|
|
SetWindowLong(stInfo.simWnd, GWL_EXSTYLE, simExStyle);
|
2014-05-22 23:06:01 +04:00
|
|
|
fullscreenMode = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-23 23:28:23 +04:00
|
|
|
void resize_main_window(BOOL disable_fullscreen)
|
2014-05-22 23:06:01 +04:00
|
|
|
{
|
|
|
|
RECT R;
|
|
|
|
int toolbar_y = 0;
|
|
|
|
int statusbar_y = 0;
|
|
|
|
|
|
|
|
if (IsWindowVisible(hwndTB)) {
|
|
|
|
toolbarVisible = TRUE;
|
|
|
|
}
|
|
|
|
if (IsWindowVisible(hwndSB)) {
|
|
|
|
statusVisible = TRUE;
|
|
|
|
}
|
|
|
|
|
2020-10-25 19:23:42 +03:00
|
|
|
if ((desktop_y > 0) && (dimension_y >= desktop_y)) {
|
2014-05-22 23:06:01 +04:00
|
|
|
set_fullscreen_mode(true);
|
|
|
|
} else {
|
2014-05-23 23:28:23 +04:00
|
|
|
if (fullscreenMode && disable_fullscreen) {
|
2014-05-22 23:06:01 +04:00
|
|
|
set_fullscreen_mode(false);
|
|
|
|
}
|
2020-10-25 19:23:42 +03:00
|
|
|
if (win32_autoscale) {
|
|
|
|
stretch_factor = 1;
|
|
|
|
if (!fullscreenMode) {
|
|
|
|
while (((dimension_x * stretch_factor * 2) <= max_client_x) &&
|
|
|
|
((dimension_y * stretch_factor * 2) <= max_client_y)) {
|
|
|
|
stretch_factor *= 2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while (((dimension_x * stretch_factor * 2) <= desktop_x) &&
|
|
|
|
((dimension_y * stretch_factor * 2) <= desktop_y)) {
|
|
|
|
stretch_factor *= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (stretch_factor > 1) BX_INFO(("autoscale: factor = %d", stretch_factor));
|
2014-05-20 22:42:36 +04:00
|
|
|
}
|
2014-05-23 23:28:23 +04:00
|
|
|
if (!fullscreenMode) {
|
2020-10-25 19:23:42 +03:00
|
|
|
if (stretch_factor > 1) {
|
|
|
|
stretched_x = dimension_x * stretch_factor;
|
|
|
|
stretched_y = dimension_y * stretch_factor;
|
|
|
|
} else {
|
|
|
|
stretched_x = dimension_x;
|
|
|
|
stretched_y = dimension_y;
|
|
|
|
}
|
2014-05-23 23:28:23 +04:00
|
|
|
if (toolbarVisible) {
|
|
|
|
ShowWindow(hwndTB, SW_SHOW);
|
|
|
|
GetWindowRect(hwndTB, &R);
|
|
|
|
toolbar_y = R.bottom - R.top;
|
|
|
|
}
|
|
|
|
if (statusVisible) {
|
|
|
|
ShowWindow(hwndSB, SW_SHOW);
|
|
|
|
GetWindowRect(hwndSB, &R);
|
|
|
|
statusbar_y = R.bottom - R.top;
|
|
|
|
}
|
2014-05-20 22:42:36 +04:00
|
|
|
}
|
2006-12-05 22:45:56 +03:00
|
|
|
SetRect(&R, 0, 0, stretched_x, stretched_y);
|
|
|
|
DWORD style = GetWindowLong(stInfo.simWnd, GWL_STYLE);
|
|
|
|
DWORD exstyle = GetWindowLong(stInfo.simWnd, GWL_EXSTYLE);
|
|
|
|
AdjustWindowRectEx(&R, style, FALSE, exstyle);
|
|
|
|
style = GetWindowLong(stInfo.mainWnd, GWL_STYLE);
|
|
|
|
AdjustWindowRect(&R, style, FALSE);
|
|
|
|
SetWindowPos(stInfo.mainWnd, HWND_TOP, 0, 0, R.right - R.left,
|
2014-05-23 23:28:23 +04:00
|
|
|
R.bottom - R.top + toolbar_y + statusbar_y,
|
|
|
|
SWP_NOMOVE | SWP_NOZORDER);
|
2006-12-05 22:45:56 +03:00
|
|
|
}
|
2005-05-08 23:10:21 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// This thread controls the GUI window.
|
2013-11-01 22:19:52 +04:00
|
|
|
DWORD WINAPI UIThread(LPVOID)
|
2008-02-16 01:05:43 +03:00
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
MSG msg;
|
|
|
|
HDC hdc;
|
2002-12-29 21:39:21 +03:00
|
|
|
WNDCLASS wndclass;
|
2005-05-08 23:10:21 +04:00
|
|
|
RECT wndRect;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
workerThreadID = GetCurrentThreadId();
|
|
|
|
|
2005-05-08 23:10:21 +04:00
|
|
|
GetClassInfo(NULL, WC_DIALOG, &wndclass);
|
2012-04-01 20:50:42 +04:00
|
|
|
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;
|
2002-08-10 19:23:30 +04:00
|
|
|
wndclass.lpfnWndProc = mainWndProc;
|
2001-04-10 05:04:59 +04:00
|
|
|
wndclass.cbClsExtra = 0;
|
|
|
|
wndclass.cbWndExtra = 0;
|
|
|
|
wndclass.hInstance = stInfo.hInstance;
|
2002-12-26 21:24:41 +03:00
|
|
|
wndclass.hIcon = LoadIcon (stInfo.hInstance, MAKEINTRESOURCE(ICON_BOCHS));
|
2001-04-10 05:04:59 +04:00
|
|
|
wndclass.lpszMenuName = NULL;
|
|
|
|
wndclass.lpszClassName = szAppName;
|
|
|
|
|
2012-04-01 20:50:42 +04:00
|
|
|
RegisterClass(&wndclass);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
wndclass.lpfnWndProc = simWndProc;
|
|
|
|
wndclass.cbClsExtra = 0;
|
|
|
|
wndclass.cbWndExtra = 0;
|
|
|
|
wndclass.hInstance = stInfo.hInstance;
|
2002-12-26 21:24:41 +03:00
|
|
|
wndclass.hIcon = NULL;
|
2002-08-10 19:23:30 +04:00
|
|
|
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
|
|
|
|
wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
|
|
|
|
wndclass.lpszMenuName = NULL;
|
|
|
|
wndclass.lpszClassName = "SIMWINDOW";
|
|
|
|
|
2012-04-01 20:50:42 +04:00
|
|
|
RegisterClass(&wndclass);
|
2002-08-10 19:23:30 +04:00
|
|
|
|
2005-05-08 23:10:21 +04:00
|
|
|
SetRect(&wndRect, 0, 0, stretched_x, stretched_y);
|
|
|
|
DWORD sim_style = WS_CHILD;
|
|
|
|
DWORD sim_exstyle = WS_EX_CLIENTEDGE;
|
|
|
|
AdjustWindowRectEx(&wndRect, sim_style, FALSE, sim_exstyle);
|
|
|
|
DWORD main_style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
|
|
|
AdjustWindowRect(&wndRect, main_style, FALSE);
|
2002-08-10 19:23:30 +04:00
|
|
|
stInfo.mainWnd = CreateWindow (szAppName,
|
|
|
|
szWindowName,
|
2005-05-08 23:10:21 +04:00
|
|
|
main_style,
|
2002-08-10 19:23:30 +04:00
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
2005-05-08 23:10:21 +04:00
|
|
|
wndRect.right - wndRect.left,
|
|
|
|
wndRect.bottom - wndRect.top,
|
2002-08-10 19:23:30 +04:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
stInfo.hInstance,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (stInfo.mainWnd) {
|
|
|
|
|
2002-08-11 17:01:49 +04:00
|
|
|
InitCommonControls();
|
2002-08-10 19:23:30 +04:00
|
|
|
hwndTB = CreateWindowEx(0, TOOLBARCLASSNAME, (LPSTR) NULL,
|
2006-01-25 20:37:22 +03:00
|
|
|
WS_CHILD | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 0, 0, 0, 0, stInfo.mainWnd,
|
2002-08-10 19:23:30 +04:00
|
|
|
(HMENU) 100, stInfo.hInstance, NULL);
|
|
|
|
SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
|
|
|
|
SendMessage(hwndTB, TB_SETBITMAPSIZE, 0, (LPARAM)MAKELONG(32, 32));
|
2005-05-08 23:10:21 +04:00
|
|
|
|
2004-08-18 13:03:48 +04:00
|
|
|
hwndSB = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "",
|
2003-10-19 12:24:12 +04:00
|
|
|
stInfo.mainWnd, 0x7712);
|
|
|
|
if (hwndSB) {
|
2012-08-30 00:36:12 +04:00
|
|
|
unsigned elements;
|
2006-01-27 21:04:49 +03:00
|
|
|
SB_Edges[0] = SIZE_OF_SB_MOUSE_MESSAGE + SIZE_OF_SB_ELEMENT;
|
2012-08-30 00:36:12 +04:00
|
|
|
SB_Text_Elements = 1;
|
2006-01-27 21:04:49 +03:00
|
|
|
#if BX_SHOW_IPS
|
2012-08-30 00:36:12 +04:00
|
|
|
if (!hideIPS) {
|
|
|
|
SB_Edges[1] = SB_Edges[0] + SIZE_OF_SB_IPS_MESSAGE;
|
|
|
|
SB_Text_Elements = 2;
|
|
|
|
}
|
2006-01-27 21:04:49 +03:00
|
|
|
#endif
|
2012-08-30 00:36:12 +04:00
|
|
|
for (elements = SB_Text_Elements; elements < (BX_MAX_STATUSITEMS+SB_Text_Elements); elements++)
|
2004-02-07 17:34:35 +03:00
|
|
|
SB_Edges[elements] = SB_Edges[elements-1] + SIZE_OF_SB_ELEMENT;
|
|
|
|
SB_Edges[elements] = -1;
|
2012-08-30 00:36:12 +04:00
|
|
|
SendMessage(hwndSB, SB_SETPARTS, BX_MAX_STATUSITEMS+SB_Text_Elements+1, (LPARAM)&SB_Edges);
|
2003-10-19 12:24:12 +04:00
|
|
|
}
|
2004-08-18 13:03:48 +04:00
|
|
|
SetStatusText(0, szMouseEnable, TRUE);
|
2005-05-08 23:10:21 +04:00
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
stInfo.simWnd = CreateWindowEx(sim_exstyle,
|
2005-05-08 23:10:21 +04:00
|
|
|
"SIMWINDOW",
|
2002-08-10 19:23:30 +04:00
|
|
|
"",
|
2005-05-08 23:10:21 +04:00
|
|
|
sim_style,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
2002-08-10 19:23:30 +04:00
|
|
|
0,
|
|
|
|
stInfo.mainWnd,
|
|
|
|
NULL,
|
|
|
|
stInfo.hInstance,
|
|
|
|
NULL);
|
|
|
|
|
2003-05-04 20:03:23 +04:00
|
|
|
/* needed for the Japanese versions of Windows */
|
|
|
|
if (stInfo.simWnd) {
|
|
|
|
HMODULE hm;
|
|
|
|
hm = GetModuleHandle("USER32");
|
|
|
|
if (hm) {
|
|
|
|
BOOL (WINAPI *enableime)(HWND, BOOL);
|
|
|
|
enableime = (BOOL (WINAPI *)(HWND, BOOL))GetProcAddress(hm, "WINNLSEnableIME");
|
|
|
|
if (enableime) {
|
|
|
|
enableime(stInfo.simWnd, FALSE);
|
|
|
|
BX_INFO(("IME disabled"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
ShowWindow(stInfo.simWnd, SW_SHOW);
|
|
|
|
SetFocus(stInfo.simWnd);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2001-06-04 06:45:28 +04:00
|
|
|
ShowCursor(!mouseCaptureMode);
|
2014-12-30 19:31:17 +03:00
|
|
|
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
|
|
|
cursorWarped();
|
|
|
|
}
|
2002-03-28 04:12:26 +03:00
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
hdc = GetDC(stInfo.simWnd);
|
2012-01-22 13:08:59 +04:00
|
|
|
MemoryBitmap = CreateCompatibleBitmap(hdc, win32_max_xres, win32_max_yres);
|
2002-03-28 04:12:26 +03:00
|
|
|
MemoryDC = CreateCompatibleDC(hdc);
|
2002-08-10 19:23:30 +04:00
|
|
|
ReleaseDC(stInfo.simWnd, hdc);
|
2002-03-28 04:12:26 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
if (MemoryBitmap && MemoryDC) {
|
2014-05-23 23:28:23 +04:00
|
|
|
resize_main_window(FALSE);
|
2006-11-17 19:50:39 +03:00
|
|
|
ShowWindow(stInfo.mainWnd, SW_SHOW);
|
2009-01-12 22:15:35 +03:00
|
|
|
#if BX_DEBUGGER && BX_DEBUGGER_GUI
|
2008-12-27 15:06:39 +03:00
|
|
|
if (gui_debug) {
|
2012-06-24 13:14:43 +04:00
|
|
|
bx_gui->init_debug_dialog();
|
2006-11-17 19:50:39 +03:00
|
|
|
}
|
2009-05-13 21:26:45 +04:00
|
|
|
#endif
|
|
|
|
#if BX_SHOW_IPS
|
2012-08-30 00:36:12 +04:00
|
|
|
if (!hideIPS) {
|
|
|
|
UINT idTimer = 2;
|
|
|
|
SetTimer(stInfo.simWnd, idTimer, 1000, (TIMERPROC)MyTimer);
|
|
|
|
}
|
2006-11-17 19:50:39 +03:00
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
stInfo.UIinited = TRUE;
|
|
|
|
|
2003-09-17 23:47:41 +04:00
|
|
|
bx_gui->clear_screen();
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
while (GetMessage (&msg, NULL, 0, 0)) {
|
|
|
|
TranslateMessage (&msg);
|
|
|
|
DispatchMessage (&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stInfo.kill = EXIT_GUI_SHUTDOWN;
|
|
|
|
|
2013-11-01 22:19:52 +04:00
|
|
|
return 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2021-01-30 21:32:52 +03:00
|
|
|
void SetStatusText(unsigned Num, const char *Text, bool active, Bit8u color)
|
2003-10-19 12:24:12 +04:00
|
|
|
{
|
|
|
|
char StatText[MAX_PATH];
|
|
|
|
|
2012-08-30 00:36:12 +04:00
|
|
|
if ((Num < SB_Text_Elements) || (Num > (BX_MAX_STATUSITEMS+SB_Text_Elements))) {
|
2006-01-27 21:04:49 +03:00
|
|
|
StatText[0] = ' '; // Add space to text in 1st and last items
|
|
|
|
lstrcpy(StatText+1, Text);
|
2010-11-01 18:02:14 +03:00
|
|
|
SendMessage(hwndSB, SB_SETTEXT, Num, (LPARAM)StatText);
|
2004-02-08 21:38:26 +03:00
|
|
|
} else {
|
2006-01-27 21:04:49 +03:00
|
|
|
StatText[0] = 9; // Center the rest
|
|
|
|
lstrcpy(StatText+1, Text);
|
2012-08-30 00:36:12 +04:00
|
|
|
lstrcpy(SB_Text[Num-SB_Text_Elements], StatText);
|
|
|
|
SB_Active[Num-SB_Text_Elements] = active;
|
2020-12-16 23:04:47 +03:00
|
|
|
SB_ActiveColor[Num-SB_Text_Elements] = color;
|
2012-08-30 00:36:12 +04:00
|
|
|
SendMessage(hwndSB, SB_SETTEXT, Num | SBT_OWNERDRAW, (LPARAM)SB_Text[Num-SB_Text_Elements]);
|
2004-02-08 13:25:50 +03:00
|
|
|
}
|
2004-02-07 17:34:35 +03:00
|
|
|
UpdateWindow(hwndSB);
|
|
|
|
}
|
|
|
|
|
2021-01-30 21:32:52 +03:00
|
|
|
void bx_win32_gui_c::statusbar_setitem_specific(int element, bool active, bool w)
|
2004-02-07 17:34:35 +03:00
|
|
|
{
|
2020-12-16 23:04:47 +03:00
|
|
|
Bit8u color = 0;
|
|
|
|
if (w) {
|
|
|
|
color = statusitem[element].auto_off ? 1 : 2;
|
|
|
|
}
|
|
|
|
SetStatusText(element+SB_Text_Elements, statusitem[element].text, active, color);
|
2003-10-19 12:24:12 +04:00
|
|
|
}
|
|
|
|
|
2004-02-08 13:25:50 +03:00
|
|
|
LRESULT CALLBACK mainWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
DRAWITEMSTRUCT *lpdis;
|
|
|
|
char *sbtext;
|
2006-01-25 20:37:22 +03:00
|
|
|
NMHDR *lpnmh;
|
|
|
|
TOOLTIPTEXT *lpttt;
|
|
|
|
int idTT, hbar_id;
|
2003-10-25 15:57:42 +04:00
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
switch (iMsg) {
|
|
|
|
case WM_CREATE:
|
2004-12-28 17:38:30 +03:00
|
|
|
SetStatusText(0, szMouseEnable, TRUE);
|
2017-05-06 00:44:30 +03:00
|
|
|
if (win32_traphotkeys) {
|
|
|
|
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
|
|
|
|
}
|
2002-08-10 19:23:30 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
if (LOWORD(wParam) >= 101) {
|
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
2017-01-14 18:11:14 +03:00
|
|
|
enq_key_event(LOWORD(wParam)-101, TOOLBAR_CLICKED);
|
2002-08-10 19:23:30 +04:00
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_SETFOCUS:
|
|
|
|
SetFocus(stInfo.simWnd);
|
|
|
|
return 0;
|
|
|
|
|
2014-12-27 18:57:30 +03:00
|
|
|
case WM_KILLFOCUS:
|
|
|
|
enq_key_event(0, FOCUS_CHANGED);
|
|
|
|
return 0;
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
case WM_CLOSE:
|
|
|
|
SendMessage(stInfo.simWnd, WM_CLOSE, 0, 0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_DESTROY:
|
|
|
|
PostQuitMessage (0);
|
|
|
|
return 0;
|
|
|
|
|
2003-11-14 18:43:12 +03:00
|
|
|
case WM_SIZE:
|
2014-06-06 00:12:44 +04:00
|
|
|
if (!IsIconic(hwnd)) {
|
2006-12-05 22:45:56 +03:00
|
|
|
int x, y;
|
2005-05-08 23:10:21 +04:00
|
|
|
SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);
|
|
|
|
SendMessage(hwndSB, WM_SIZE, 0, 0);
|
2006-12-05 22:45:56 +03:00
|
|
|
// now fit simWindow to mainWindow
|
|
|
|
int rect_data[] = { 1, 0, IsWindowVisible(hwndTB),
|
2008-10-07 02:00:11 +04:00
|
|
|
100, IsWindowVisible(hwndSB), 0x7712, 0, 0 };
|
2005-05-08 23:10:21 +04:00
|
|
|
RECT R;
|
2008-02-16 01:05:43 +03:00
|
|
|
GetEffectiveClientRect(hwnd, &R, rect_data);
|
2006-12-05 22:45:56 +03:00
|
|
|
x = R.right - R.left;
|
|
|
|
y = R.bottom - R.top;
|
|
|
|
MoveWindow(stInfo.simWnd, R.left, R.top, x, y, TRUE);
|
2005-05-08 23:10:21 +04:00
|
|
|
GetClientRect(stInfo.simWnd, &R);
|
2006-12-05 22:45:56 +03:00
|
|
|
x = R.right - R.left;
|
|
|
|
y = R.bottom - R.top;
|
2020-10-25 19:23:42 +03:00
|
|
|
if (!inFullscreenToggle && ((x != (int)stretched_x) || (y != (int)stretched_y))) {
|
2006-12-05 22:45:56 +03:00
|
|
|
BX_ERROR(("Sim client size(%d, %d) != stretched size(%d, %d)!",
|
|
|
|
x, y, stretched_x, stretched_y));
|
|
|
|
if (!saveParent) fix_size = TRUE; // no fixing if fullscreen
|
2005-05-08 23:10:21 +04:00
|
|
|
}
|
|
|
|
}
|
2003-11-14 18:43:12 +03:00
|
|
|
break;
|
|
|
|
|
2004-02-08 13:25:50 +03:00
|
|
|
case WM_DRAWITEM:
|
|
|
|
lpdis = (DRAWITEMSTRUCT *)lParam;
|
|
|
|
if (lpdis->hwndItem == hwndSB) {
|
|
|
|
sbtext = (char *)lpdis->itemData;
|
2012-08-30 00:36:12 +04:00
|
|
|
if (SB_Active[lpdis->itemID-SB_Text_Elements]) {
|
2020-12-16 23:04:47 +03:00
|
|
|
SetBkColor(lpdis->hDC, SB_Led_Colors[SB_ActiveColor[lpdis->itemID-SB_Text_Elements]]);
|
2004-02-08 21:38:26 +03:00
|
|
|
} else {
|
|
|
|
SetBkMode(lpdis->hDC, TRANSPARENT);
|
|
|
|
SetTextColor(lpdis->hDC, 0x00808080);
|
|
|
|
}
|
2004-02-08 13:25:50 +03:00
|
|
|
DrawText(lpdis->hDC, sbtext+1, lstrlen(sbtext)-1, &lpdis->rcItem, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2006-01-25 20:37:22 +03:00
|
|
|
case WM_NOTIFY:
|
|
|
|
lpnmh = (LPNMHDR)lParam;
|
2007-12-03 23:38:55 +03:00
|
|
|
if (lpnmh->code == TTN_NEEDTEXT) {
|
2006-01-25 20:37:22 +03:00
|
|
|
lpttt = (LPTOOLTIPTEXT)lParam;
|
|
|
|
idTT = (int)wParam;
|
|
|
|
hbar_id = idTT - 101;
|
2017-01-14 18:11:14 +03:00
|
|
|
if (SendMessage(hwndTB, TB_GETSTATE, idTT, 0) && win32_toolbar_entry[hbar_id].tooltip != NULL) {
|
|
|
|
lstrcpy(lpttt->szText, win32_toolbar_entry[hbar_id].tooltip);
|
2006-01-25 20:37:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
break;
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
}
|
2008-10-07 02:00:11 +04:00
|
|
|
return DefWindowProc(hwnd, iMsg, wParam, lParam);
|
2002-08-10 19:23:30 +04:00
|
|
|
}
|
|
|
|
|
2020-07-17 19:12:21 +03:00
|
|
|
void SetMouseToggleInfo()
|
|
|
|
{
|
|
|
|
if (mouseCaptureMode) {
|
|
|
|
SetStatusText(0, szMouseDisable, TRUE);
|
|
|
|
} else {
|
|
|
|
SetStatusText(0, szMouseEnable, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-17 00:47:08 +03:00
|
|
|
void SetMouseCapture()
|
|
|
|
{
|
2014-12-30 19:31:17 +03:00
|
|
|
POINT pt = { 0, 0 };
|
|
|
|
RECT re;
|
|
|
|
|
2004-12-28 17:38:30 +03:00
|
|
|
if (mouseToggleReq) {
|
|
|
|
mouseCaptureMode = mouseCaptureNew;
|
|
|
|
mouseToggleReq = FALSE;
|
|
|
|
} else {
|
2006-02-22 22:18:29 +03:00
|
|
|
SIM->get_param_bool(BXPN_MOUSE_ENABLED)->set(mouseCaptureMode);
|
2004-12-28 17:38:30 +03:00
|
|
|
}
|
2004-02-17 00:47:08 +03:00
|
|
|
ShowCursor(!mouseCaptureMode);
|
|
|
|
ShowCursor(!mouseCaptureMode); // somehow one didn't do the trick (win98)
|
2014-12-30 19:31:17 +03:00
|
|
|
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
|
|
|
cursorWarped();
|
|
|
|
}
|
|
|
|
if (mouseCaptureMode) {
|
|
|
|
ClientToScreen(stInfo.simWnd, &pt);
|
|
|
|
re.left = pt.x;
|
|
|
|
re.top = pt.y;
|
|
|
|
re.right = pt.x + stretched_x;
|
|
|
|
re.bottom = pt.y + stretched_y;
|
|
|
|
ClipCursor(&re);
|
|
|
|
} else {
|
|
|
|
ClipCursor(NULL);
|
|
|
|
}
|
2020-07-17 19:12:21 +03:00
|
|
|
SetMouseToggleInfo();
|
2004-02-17 00:47:08 +03:00
|
|
|
}
|
2002-08-10 19:23:30 +04:00
|
|
|
|
2004-02-15 14:30:28 +03:00
|
|
|
LRESULT CALLBACK simWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
HDC hdc, hdcMem;
|
|
|
|
PAINTSTRUCT ps;
|
2021-01-30 21:32:52 +03:00
|
|
|
bool mouse_toggle = 0;
|
2020-07-18 16:36:21 +03:00
|
|
|
int toolbar_cmd = -1;
|
2020-07-30 23:04:31 +03:00
|
|
|
Bit8u kmodchange = 0;
|
2021-01-30 21:32:52 +03:00
|
|
|
bool keymod = 0;
|
2004-02-15 14:30:28 +03:00
|
|
|
static BOOL mouseModeChange = FALSE;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
switch (iMsg) {
|
2006-12-05 22:45:56 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
case WM_CREATE:
|
2014-12-29 21:50:03 +03:00
|
|
|
SetTimer(hwnd, 1, 250, NULL);
|
2001-04-10 05:04:59 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_TIMER:
|
2004-02-17 00:47:08 +03:00
|
|
|
if (mouseToggleReq && (GetActiveWindow() == stInfo.mainWnd)) {
|
|
|
|
SetMouseCapture();
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_PAINT:
|
|
|
|
EnterCriticalSection(&stInfo.drawCS);
|
|
|
|
hdc = BeginPaint (hwnd, &ps);
|
|
|
|
|
|
|
|
hdcMem = CreateCompatibleDC (hdc);
|
|
|
|
SelectObject (hdcMem, MemoryBitmap);
|
|
|
|
|
2020-10-23 16:14:34 +03:00
|
|
|
if (stretch_factor == 1) {
|
2003-09-17 23:47:41 +04:00
|
|
|
BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top,
|
|
|
|
ps.rcPaint.right - ps.rcPaint.left + 1,
|
|
|
|
ps.rcPaint.bottom - ps.rcPaint.top + 1, hdcMem,
|
|
|
|
ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
|
|
|
|
} else {
|
|
|
|
StretchBlt(hdc, ps.rcPaint.left, ps.rcPaint.top,
|
|
|
|
ps.rcPaint.right - ps.rcPaint.left + 1,
|
|
|
|
ps.rcPaint.bottom - ps.rcPaint.top + 1, hdcMem,
|
2020-10-23 16:14:34 +03:00
|
|
|
ps.rcPaint.left/stretch_factor, ps.rcPaint.top/stretch_factor,
|
|
|
|
(ps.rcPaint.right - ps.rcPaint.left+1)/stretch_factor,
|
|
|
|
(ps.rcPaint.bottom - ps.rcPaint.top+1)/stretch_factor, SRCCOPY);
|
2003-09-17 23:47:41 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
DeleteDC (hdcMem);
|
|
|
|
EndPaint (hwnd, &ps);
|
|
|
|
LeaveCriticalSection(&stInfo.drawCS);
|
|
|
|
return 0;
|
|
|
|
|
2014-12-30 19:31:17 +03:00
|
|
|
case WM_SIZE:
|
|
|
|
if (mouseCaptureMode) {
|
|
|
|
POINT pt = { 0, 0 };
|
|
|
|
RECT re;
|
|
|
|
ClientToScreen(stInfo.simWnd, &pt);
|
|
|
|
re.left = pt.x;
|
|
|
|
re.top = pt.y;
|
|
|
|
re.right = pt.x + stretched_x;
|
|
|
|
re.bottom = pt.y + stretched_y;
|
|
|
|
ClipCursor(&re);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
case WM_MOUSEMOVE:
|
2014-12-30 19:31:17 +03:00
|
|
|
if ((LOWORD(lParam) == ms_savedx) && (HIWORD(lParam) == ms_savedy)) {
|
|
|
|
// Ignore mouse event generated by SetCursorPos().
|
|
|
|
return 0;
|
|
|
|
}
|
2004-02-15 14:30:28 +03:00
|
|
|
if (!mouseModeChange) {
|
2012-11-27 19:40:45 +04:00
|
|
|
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 0);
|
2004-12-05 23:23:39 +03:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_MOUSEWHEEL:
|
|
|
|
if (!mouseModeChange) {
|
2004-12-07 00:12:11 +03:00
|
|
|
// WM_MOUSEWHEEL returns x and y relative to the main screen.
|
|
|
|
// WM_MOUSEMOVE below returns x and y relative to the current view.
|
2005-05-11 22:00:02 +04:00
|
|
|
POINT pt;
|
|
|
|
pt.x = LOWORD(lParam);
|
|
|
|
pt.y = HIWORD(lParam);
|
|
|
|
ScreenToClient(stInfo.simWnd, &pt);
|
2008-02-16 01:05:43 +03:00
|
|
|
processMouseXY(pt.x, pt.y, (Bit16s) HIWORD(wParam) / 120, LOWORD(wParam), 0);
|
2004-02-15 14:30:28 +03:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
|
|
case WM_LBUTTONUP:
|
2004-08-18 13:03:48 +04:00
|
|
|
if (mouse_buttons == 2) {
|
2010-05-18 19:33:41 +04:00
|
|
|
if ((wParam & MK_LBUTTON) == MK_LBUTTON) {
|
|
|
|
if (bx_gui->mouse_toggle_check(BX_MT_LBUTTON, 1)) {
|
2010-05-17 00:44:08 +04:00
|
|
|
mouseCaptureMode = !mouseCaptureMode;
|
|
|
|
SetMouseCapture();
|
|
|
|
mouseModeChange = TRUE;
|
|
|
|
}
|
2004-08-18 13:03:48 +04:00
|
|
|
} else if (mouseModeChange && (iMsg == WM_LBUTTONUP)) {
|
2010-05-18 19:33:41 +04:00
|
|
|
bx_gui->mouse_toggle_check(BX_MT_LBUTTON, 0);
|
2004-08-18 13:03:48 +04:00
|
|
|
mouseModeChange = FALSE;
|
|
|
|
} else {
|
2012-11-27 19:40:45 +04:00
|
|
|
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 1);
|
2004-08-18 13:03:48 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2012-11-27 19:40:45 +04:00
|
|
|
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 1);
|
2001-04-10 05:04:59 +04:00
|
|
|
return 0;
|
|
|
|
|
2004-02-15 03:03:16 +03:00
|
|
|
case WM_MBUTTONDOWN:
|
|
|
|
case WM_MBUTTONDBLCLK:
|
|
|
|
case WM_MBUTTONUP:
|
2010-05-17 00:44:08 +04:00
|
|
|
if ((wParam & MK_MBUTTON) == MK_MBUTTON) {
|
|
|
|
if (bx_gui->mouse_toggle_check(BX_MT_MBUTTON, 1)) {
|
|
|
|
mouseCaptureMode = !mouseCaptureMode;
|
|
|
|
SetMouseCapture();
|
|
|
|
mouseModeChange = TRUE;
|
|
|
|
}
|
2004-02-15 14:30:28 +03:00
|
|
|
} else if (mouseModeChange && (iMsg == WM_MBUTTONUP)) {
|
2010-05-17 00:44:08 +04:00
|
|
|
bx_gui->mouse_toggle_check(BX_MT_MBUTTON, 0);
|
2004-02-15 14:30:28 +03:00
|
|
|
mouseModeChange = FALSE;
|
|
|
|
} else {
|
2012-11-27 19:40:45 +04:00
|
|
|
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 4);
|
2004-02-15 14:30:28 +03:00
|
|
|
}
|
2004-02-15 03:03:16 +03:00
|
|
|
return 0;
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
case WM_RBUTTONDOWN:
|
|
|
|
case WM_RBUTTONDBLCLK:
|
|
|
|
case WM_RBUTTONUP:
|
2004-08-18 13:03:48 +04:00
|
|
|
if (mouse_buttons == 2) {
|
2010-05-18 19:33:41 +04:00
|
|
|
if ((wParam & MK_RBUTTON) == MK_RBUTTON) {
|
|
|
|
if (bx_gui->mouse_toggle_check(BX_MT_RBUTTON, 1)) {
|
2010-05-17 00:44:08 +04:00
|
|
|
mouseCaptureMode = !mouseCaptureMode;
|
|
|
|
SetMouseCapture();
|
|
|
|
mouseModeChange = TRUE;
|
|
|
|
}
|
2004-08-18 13:03:48 +04:00
|
|
|
} else if (mouseModeChange && (iMsg == WM_RBUTTONUP)) {
|
2010-05-18 19:33:41 +04:00
|
|
|
bx_gui->mouse_toggle_check(BX_MT_RBUTTON, 0);
|
2004-08-18 13:03:48 +04:00
|
|
|
mouseModeChange = FALSE;
|
|
|
|
} else {
|
2012-11-27 19:40:45 +04:00
|
|
|
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 2);
|
2004-08-18 13:03:48 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2012-11-27 19:40:45 +04:00
|
|
|
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 2);
|
2004-02-15 03:03:16 +03:00
|
|
|
return 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
case WM_CLOSE:
|
|
|
|
return DefWindowProc (hwnd, iMsg, wParam, lParam);
|
|
|
|
|
|
|
|
case WM_DESTROY:
|
2012-08-30 00:36:12 +04:00
|
|
|
KillTimer(hwnd, 1);
|
2001-04-10 05:04:59 +04:00
|
|
|
stInfo.UIinited = FALSE;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
case WM_SYSKEYDOWN:
|
2020-07-30 23:04:31 +03:00
|
|
|
// check modifier keys
|
|
|
|
if (wParam == VK_SHIFT) {
|
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_SHIFT, 1);
|
|
|
|
keymod = 1;
|
|
|
|
} else if (wParam == VK_CONTROL) {
|
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_CTRL, 1);
|
|
|
|
keymod = 1;
|
2010-05-17 00:44:08 +04:00
|
|
|
} else if (wParam == VK_MENU) {
|
2020-07-30 23:04:31 +03:00
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_ALT, 1);
|
|
|
|
keymod = 1;
|
|
|
|
} else if (wParam == VK_CAPITAL) {
|
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_CAPS, 1);
|
|
|
|
keymod = 1;
|
|
|
|
}
|
|
|
|
// mouse capture toggle-check
|
|
|
|
if (kmodchange == BX_MOD_KEY_CTRL) {
|
|
|
|
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_CTRL, 1);
|
|
|
|
} else if (kmodchange == BX_MOD_KEY_ALT) {
|
2010-05-17 00:44:08 +04:00
|
|
|
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_ALT, 1);
|
|
|
|
} else if (wParam == VK_F10) {
|
|
|
|
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_F10, 1);
|
2010-05-18 19:33:41 +04:00
|
|
|
} else if (wParam == VK_F12) {
|
|
|
|
mouse_toggle = bx_gui->mouse_toggle_check(BX_MT_KEY_F12, 1);
|
2010-05-17 00:44:08 +04:00
|
|
|
}
|
|
|
|
if (mouse_toggle) {
|
2004-02-23 19:33:52 +03:00
|
|
|
mouseCaptureMode = !mouseCaptureMode;
|
|
|
|
SetMouseCapture();
|
|
|
|
return 0;
|
|
|
|
}
|
2020-07-17 19:12:21 +03:00
|
|
|
if (bx_gui->command_mode_active()) {
|
2020-07-30 23:04:31 +03:00
|
|
|
if (bx_gui->get_modifier_keys() == 0) {
|
|
|
|
if (wParam == 'A') {
|
|
|
|
toolbar_cmd = 0; // Floppy A
|
|
|
|
} else if (wParam == 'B') {
|
|
|
|
toolbar_cmd = 1; // Floppy B
|
|
|
|
} else if (wParam == 'C') {
|
|
|
|
toolbar_cmd = 10; // Copy
|
|
|
|
} else if (wParam == 'F') {
|
|
|
|
if (!saveParent) {
|
|
|
|
set_fullscreen_mode(TRUE);
|
|
|
|
bx_gui->set_fullscreen_mode(1);
|
|
|
|
} else {
|
|
|
|
resize_main_window(TRUE);
|
|
|
|
bx_gui->set_fullscreen_mode(0);
|
|
|
|
}
|
2020-08-21 22:12:37 +03:00
|
|
|
} else if (wParam == 'M') {
|
|
|
|
bx_gui->marklog_handler();
|
2020-07-30 23:04:31 +03:00
|
|
|
} else if (wParam == 'P') {
|
|
|
|
toolbar_cmd = 9; // Paste
|
|
|
|
} else if (wParam == 'R') {
|
|
|
|
toolbar_cmd = 6; // Reset
|
|
|
|
} else if (wParam == 'S') {
|
|
|
|
toolbar_cmd = 8; // Snapshot
|
|
|
|
} else if (wParam == 'U') {
|
|
|
|
toolbar_cmd = 11; // User
|
|
|
|
}
|
|
|
|
} else if (bx_gui->get_modifier_keys() == BX_MOD_KEY_SHIFT) {
|
|
|
|
if (wParam == 'C') {
|
|
|
|
toolbar_cmd = 7; // Config
|
|
|
|
} else if (wParam == 'P') {
|
|
|
|
toolbar_cmd = 4; // Power
|
|
|
|
} else if (wParam == 'S') {
|
|
|
|
toolbar_cmd = 5; // Suspend
|
2020-07-17 19:12:21 +03:00
|
|
|
}
|
|
|
|
}
|
2020-07-30 23:04:31 +03:00
|
|
|
if (!keymod) {
|
|
|
|
bx_gui->set_command_mode(0);
|
|
|
|
SetMouseToggleInfo();
|
|
|
|
}
|
2020-07-18 16:36:21 +03:00
|
|
|
if (toolbar_cmd >= 0) {
|
2020-07-17 19:12:21 +03:00
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
2020-07-18 16:36:21 +03:00
|
|
|
enq_key_event((Bit32u)toolbar_cmd, TOOLBAR_CLICKED);
|
2020-07-17 19:12:21 +03:00
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (wParam != COMMAND_MODE_VKEY) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
2020-07-30 23:04:31 +03:00
|
|
|
if (bx_gui->has_command_mode() && (bx_gui->get_modifier_keys() == 0) &&
|
|
|
|
(wParam == COMMAND_MODE_VKEY)) {
|
2020-07-17 19:12:21 +03:00
|
|
|
bx_gui->set_command_mode(1);
|
|
|
|
SetStatusText(0, "Command mode", TRUE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2004-02-15 14:30:28 +03:00
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
2011-12-05 01:15:35 +04:00
|
|
|
if (((lParam & 0x40000000) == 0) || !win32_nokeyrepeat) {
|
|
|
|
enq_key_event(HIWORD (lParam) & 0x01FF, BX_KEY_PRESSED);
|
|
|
|
}
|
2004-02-15 14:30:28 +03:00
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case WM_KEYUP:
|
|
|
|
case WM_SYSKEYUP:
|
2006-12-05 22:45:56 +03:00
|
|
|
// check if it's keyup, alt key, non-repeat
|
|
|
|
// see http://msdn2.microsoft.com/en-us/library/ms646267.aspx
|
2008-06-01 14:56:29 +04:00
|
|
|
if ((wParam == VK_RETURN) &&
|
|
|
|
((HIWORD(lParam) & BX_SYSKEY) == (KF_ALTDOWN | KF_UP))) {
|
|
|
|
if (!saveParent) {
|
2014-05-22 23:06:01 +04:00
|
|
|
set_fullscreen_mode(TRUE);
|
2008-06-01 14:56:29 +04:00
|
|
|
} else {
|
2014-05-23 23:28:23 +04:00
|
|
|
resize_main_window(TRUE);
|
2006-12-05 22:45:56 +03:00
|
|
|
}
|
|
|
|
} else {
|
2020-07-30 23:04:31 +03:00
|
|
|
// check modifier keys
|
|
|
|
if (wParam == VK_SHIFT) {
|
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_SHIFT, 0);
|
|
|
|
} else if (wParam == VK_CONTROL) {
|
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_CTRL, 0);
|
2010-05-17 00:44:08 +04:00
|
|
|
} else if (wParam == VK_MENU) {
|
2020-07-30 23:04:31 +03:00
|
|
|
kmodchange = bx_gui->set_modifier_keys(BX_MOD_KEY_ALT, 0);
|
|
|
|
}
|
|
|
|
// mouse capture toggle-check
|
|
|
|
if (kmodchange == BX_MOD_KEY_CTRL) {
|
|
|
|
bx_gui->mouse_toggle_check(BX_MT_KEY_CTRL, 0);
|
|
|
|
} else if (kmodchange == BX_MOD_KEY_ALT) {
|
2010-05-17 00:44:08 +04:00
|
|
|
bx_gui->mouse_toggle_check(BX_MT_KEY_ALT, 0);
|
|
|
|
} else if (wParam == VK_F10) {
|
|
|
|
bx_gui->mouse_toggle_check(BX_MT_KEY_F10, 0);
|
2010-05-25 02:06:17 +04:00
|
|
|
} else if (wParam == VK_F12) {
|
|
|
|
bx_gui->mouse_toggle_check(BX_MT_KEY_F12, 0);
|
2010-05-17 00:44:08 +04:00
|
|
|
}
|
2006-12-05 22:45:56 +03:00
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
|
|
|
enq_key_event(HIWORD (lParam) & 0x01FF, BX_KEY_RELEASED);
|
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
return 0;
|
|
|
|
|
2006-12-05 22:45:56 +03:00
|
|
|
case WM_SYSCHAR:
|
|
|
|
// check if it's keydown, alt key, non-repeat
|
|
|
|
// see http://msdn2.microsoft.com/en-us/library/ms646267.aspx
|
|
|
|
if (wParam == VK_RETURN) {
|
|
|
|
if ((HIWORD(lParam) & BX_SYSKEY) == KF_ALTDOWN) {
|
|
|
|
if (!saveParent) {
|
2014-05-22 23:06:01 +04:00
|
|
|
set_fullscreen_mode(TRUE);
|
2006-12-05 22:45:56 +03:00
|
|
|
} else {
|
2014-05-23 23:28:23 +04:00
|
|
|
resize_main_window(TRUE);
|
2006-12-05 22:45:56 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
case WM_CHAR:
|
|
|
|
case WM_DEADCHAR:
|
|
|
|
case WM_SYSDEADCHAR:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return DefWindowProc (hwnd, iMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-15 14:30:28 +03:00
|
|
|
void enq_key_event(Bit32u key, Bit32u press_release)
|
|
|
|
{
|
2005-10-02 21:37:56 +04:00
|
|
|
static BOOL alt_pressed_l = FALSE;
|
|
|
|
static BOOL alt_pressed_r = FALSE;
|
|
|
|
static BOOL ctrl_pressed_l = FALSE;
|
|
|
|
static BOOL ctrl_pressed_r = FALSE;
|
|
|
|
static BOOL shift_pressed_l = FALSE;
|
|
|
|
static BOOL shift_pressed_r = FALSE;
|
|
|
|
|
2014-12-27 18:57:30 +03:00
|
|
|
if (press_release == FOCUS_CHANGED) {
|
|
|
|
alt_pressed_l = FALSE;
|
|
|
|
alt_pressed_r = FALSE;
|
|
|
|
ctrl_pressed_l = FALSE;
|
|
|
|
ctrl_pressed_r = FALSE;
|
|
|
|
shift_pressed_l = FALSE;
|
|
|
|
shift_pressed_r = FALSE;
|
|
|
|
} else if (press_release == BX_KEY_PRESSED) {
|
|
|
|
// Windows generates multiple keypresses when holding down these keys
|
2004-02-15 14:30:28 +03:00
|
|
|
switch (key) {
|
|
|
|
case 0x1d:
|
2005-10-02 21:37:56 +04:00
|
|
|
if (ctrl_pressed_l)
|
2004-02-15 14:30:28 +03:00
|
|
|
return;
|
2005-10-02 21:37:56 +04:00
|
|
|
ctrl_pressed_l = TRUE;
|
2004-02-15 14:30:28 +03:00
|
|
|
break;
|
|
|
|
case 0x2a:
|
2005-10-02 21:37:56 +04:00
|
|
|
if (shift_pressed_l)
|
|
|
|
return;
|
|
|
|
shift_pressed_l = TRUE;
|
|
|
|
break;
|
|
|
|
case 0x36:
|
|
|
|
if (shift_pressed_r)
|
2004-02-15 14:30:28 +03:00
|
|
|
return;
|
2005-10-02 21:37:56 +04:00
|
|
|
shift_pressed_r = TRUE;
|
2004-02-15 14:30:28 +03:00
|
|
|
break;
|
|
|
|
case 0x38:
|
2005-10-02 21:37:56 +04:00
|
|
|
if (alt_pressed_l)
|
|
|
|
return;
|
|
|
|
alt_pressed_l = TRUE;
|
|
|
|
break;
|
|
|
|
case 0x011d:
|
|
|
|
if (ctrl_pressed_r)
|
|
|
|
return;
|
|
|
|
ctrl_pressed_r = TRUE;
|
|
|
|
break;
|
|
|
|
case 0x0138:
|
|
|
|
if (alt_pressed_r)
|
2004-02-15 14:30:28 +03:00
|
|
|
return;
|
2006-07-23 15:09:15 +04:00
|
|
|
// This makes the "AltGr" key on European keyboards work
|
|
|
|
if (ctrl_pressed_l) {
|
|
|
|
enq_key_event(0x1d, BX_KEY_RELEASED);
|
|
|
|
}
|
2005-10-02 21:37:56 +04:00
|
|
|
alt_pressed_r = TRUE;
|
2004-02-15 14:30:28 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-10-02 21:37:56 +04:00
|
|
|
} else {
|
2004-02-15 14:30:28 +03:00
|
|
|
switch (key) {
|
|
|
|
case 0x1d:
|
2006-07-23 15:09:15 +04:00
|
|
|
if (!ctrl_pressed_l)
|
|
|
|
return;
|
2005-10-02 21:37:56 +04:00
|
|
|
ctrl_pressed_l = FALSE;
|
2004-02-15 14:30:28 +03:00
|
|
|
break;
|
|
|
|
case 0x2a:
|
2005-10-02 21:37:56 +04:00
|
|
|
shift_pressed_l = FALSE;
|
|
|
|
break;
|
|
|
|
case 0x36:
|
|
|
|
shift_pressed_r = FALSE;
|
2004-02-15 14:30:28 +03:00
|
|
|
break;
|
|
|
|
case 0x38:
|
2005-10-02 21:37:56 +04:00
|
|
|
alt_pressed_l = FALSE;
|
|
|
|
break;
|
|
|
|
case 0x011d:
|
|
|
|
ctrl_pressed_r = FALSE;
|
|
|
|
break;
|
|
|
|
case 0x0138:
|
|
|
|
alt_pressed_r = FALSE;
|
2004-02-15 14:30:28 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
if (((tail+1) % SCANCODE_BUFSIZE) == head) {
|
2008-02-16 01:05:43 +03:00
|
|
|
BX_ERROR(("enq_scancode: buffer full"));
|
2001-04-10 05:04:59 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
keyevents[tail].key_event = key | press_release;
|
|
|
|
tail = (tail + 1) % SCANCODE_BUFSIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void enq_mouse_event(void)
|
|
|
|
{
|
2008-02-16 01:05:43 +03:00
|
|
|
EnterCriticalSection(&stInfo.mouseCS);
|
2014-12-30 19:31:17 +03:00
|
|
|
if (ms_xdelta || ms_ydelta || ms_zdelta) {
|
2001-04-10 05:04:59 +04:00
|
|
|
if (((tail+1) % SCANCODE_BUFSIZE) == head) {
|
2009-06-06 11:44:16 +04:00
|
|
|
LeaveCriticalSection(&stInfo.mouseCS);
|
2008-02-16 01:05:43 +03:00
|
|
|
BX_ERROR(("enq_scancode: buffer full"));
|
2001-04-10 05:04:59 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
QueueEvent& current=keyevents[tail];
|
|
|
|
current.key_event=MOUSE_MOTION;
|
2012-06-26 00:08:52 +04:00
|
|
|
if (win32MouseModeAbsXY) {
|
|
|
|
current.mouse_x = ms_lastx * 0x7fff / dimension_x;
|
|
|
|
current.mouse_y = ms_lasty * 0x7fff / dimension_y;
|
|
|
|
} else {
|
|
|
|
current.mouse_x = ms_xdelta;
|
|
|
|
current.mouse_y = ms_ydelta;
|
|
|
|
}
|
2014-12-30 19:31:17 +03:00
|
|
|
current.mouse_z = ms_zdelta;
|
|
|
|
current.mouse_button_state = mouse_button_state;
|
|
|
|
ms_ydelta = ms_xdelta = ms_zdelta = 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
tail = (tail + 1) % SCANCODE_BUFSIZE;
|
|
|
|
}
|
2008-02-16 01:05:43 +03:00
|
|
|
LeaveCriticalSection(&stInfo.mouseCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
QueueEvent* deq_key_event(void)
|
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
QueueEvent* key;
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
if (head == tail) {
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_ERROR(("deq_scancode: buffer empty"));
|
2001-04-10 05:04:59 +04:00
|
|
|
return((QueueEvent*)0);
|
|
|
|
}
|
|
|
|
key = &keyevents[head];
|
|
|
|
head = (head + 1) % SCANCODE_BUFSIZE;
|
|
|
|
|
|
|
|
return(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void bx_win32_gui_c::handle_events(void)
|
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
Bit32u key;
|
2003-02-17 22:08:12 +03:00
|
|
|
Bit32u key_event;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
if (stInfo.kill) terminateEmul(stInfo.kill);
|
|
|
|
|
2014-06-06 00:12:44 +04:00
|
|
|
if (fix_size) {
|
|
|
|
resize_main_window(FALSE);
|
|
|
|
fix_size = FALSE;
|
|
|
|
}
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// Handle mouse moves
|
|
|
|
enq_mouse_event();
|
|
|
|
|
|
|
|
// Handle keyboard and mouse clicks
|
|
|
|
EnterCriticalSection(&stInfo.keyCS);
|
|
|
|
while (head != tail) {
|
2014-12-27 18:57:30 +03:00
|
|
|
QueueEvent* queue_event = deq_key_event();
|
|
|
|
if (!queue_event)
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
key = queue_event->key_event;
|
2014-12-27 18:57:30 +03:00
|
|
|
if (key == MOUSE_MOTION)
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
2012-06-21 21:33:37 +04:00
|
|
|
DEV_mouse_motion(queue_event->mouse_x, queue_event->mouse_y,
|
2012-06-26 00:08:52 +04:00
|
|
|
queue_event->mouse_z, queue_event->mouse_button_state, win32MouseModeAbsXY);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
2014-12-27 18:57:30 +03:00
|
|
|
else if (key == FOCUS_CHANGED) {
|
|
|
|
DEV_kbd_release_keys();
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
// Check for mouse buttons first
|
2008-02-16 01:05:43 +03:00
|
|
|
else if (key & MOUSE_PRESSED) {
|
2012-06-21 21:33:37 +04:00
|
|
|
DEV_mouse_motion(0, 0, 0, LOWORD(key), 0);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
2017-01-14 18:11:14 +03:00
|
|
|
else if (key & TOOLBAR_CLICKED) {
|
|
|
|
win32_toolbar_click(LOWORD(key));
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
else {
|
2003-10-25 21:37:58 +04:00
|
|
|
key_event = win32_to_bx_key[(key & 0x100) ? 1 : 0][key & 0xff];
|
2003-02-17 22:08:12 +03:00
|
|
|
if (key & BX_KEY_RELEASED) key_event |= BX_KEY_RELEASED;
|
|
|
|
DEV_kbd_gen_scancode(key_event);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
}
|
2009-06-06 11:44:16 +04:00
|
|
|
LeaveCriticalSection(&stInfo.keyCS);
|
2006-01-24 00:53:57 +03:00
|
|
|
#if BX_SHOW_IPS
|
|
|
|
if (ipsUpdate) {
|
2006-01-27 21:04:49 +03:00
|
|
|
SetStatusText(1, ipsText, 1);
|
2006-01-24 00:53:57 +03:00
|
|
|
ipsUpdate = FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void bx_win32_gui_c::flush(void)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(&stInfo.drawCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
if (updated_area_valid) {
|
|
|
|
// slight bugfix
|
|
|
|
updated_area.right++;
|
|
|
|
updated_area.bottom++;
|
2008-02-16 01:05:43 +03:00
|
|
|
InvalidateRect(stInfo.simWnd, &updated_area, FALSE);
|
2001-04-10 05:04:59 +04:00
|
|
|
updated_area_valid = FALSE;
|
|
|
|
}
|
2008-02-16 01:05:43 +03:00
|
|
|
LeaveCriticalSection(&stInfo.drawCS);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void bx_win32_gui_c::clear_screen(void)
|
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
HGDIOBJ oldObj;
|
|
|
|
|
|
|
|
if (!stInfo.UIinited) return;
|
|
|
|
|
|
|
|
EnterCriticalSection(&stInfo.drawCS);
|
|
|
|
|
|
|
|
oldObj = SelectObject(MemoryDC, MemoryBitmap);
|
2002-08-10 19:23:30 +04:00
|
|
|
PatBlt(MemoryDC, 0, 0, stretched_x, stretched_y, BLACKNESS);
|
2001-04-10 05:04:59 +04:00
|
|
|
SelectObject(MemoryDC, oldObj);
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
updateUpdated(0, 0, dimension_x-1, dimension_y-1);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
LeaveCriticalSection(&stInfo.drawCS);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-01-30 21:32:52 +03:00
|
|
|
void bx_win32_gui_c::set_font(bool lg)
|
2003-05-12 23:53:22 +04:00
|
|
|
{
|
2020-11-19 19:32:22 +03:00
|
|
|
Bit8u data[64], i;
|
2003-05-12 23:53:22 +04:00
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
for (unsigned c = 0; c<256; c++) {
|
|
|
|
if (char_changed[c]) {
|
|
|
|
memset(data, 0, sizeof(data));
|
|
|
|
BOOL gfxchar = lg && ((c & 0xE0) == 0xC0);
|
|
|
|
for (i=0; i<(unsigned)yChar; i++) {
|
|
|
|
data[i*2] = vga_charmap[c*32+i];
|
|
|
|
if (gfxchar) {
|
|
|
|
data[i*2+1] = (data[i*2] << 7);
|
2003-05-13 22:44:23 +04:00
|
|
|
}
|
2002-09-21 23:38:47 +04:00
|
|
|
}
|
2020-11-19 19:32:22 +03:00
|
|
|
SetBitmapBits(vgafont[c], 64, data);
|
|
|
|
char_changed[c] = 0;
|
2002-09-08 20:41:19 +04:00
|
|
|
}
|
|
|
|
}
|
2020-11-19 19:32:22 +03:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
void bx_win32_gui_c::draw_char(Bit8u ch, Bit8u fc, Bit8u bc, Bit16u xc, Bit16u yc,
|
|
|
|
Bit8u fw, Bit8u fh, Bit8u fx, Bit8u fy,
|
2021-01-30 21:32:52 +03:00
|
|
|
bool gfxcharw9, Bit8u cs, Bit8u ce, bool curs)
|
2020-11-19 19:32:22 +03:00
|
|
|
{
|
|
|
|
HDC hdc;
|
2003-06-22 16:37:03 +04:00
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
if (!stInfo.UIinited) return;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
EnterCriticalSection(&stInfo.drawCS);
|
|
|
|
hdc = GetDC(stInfo.simWnd);
|
|
|
|
DrawBitmap(hdc, vgafont[ch], xc, yc, fw, fh, fx, fy, fc, bc);
|
|
|
|
if (curs && (ce >= fy) && (cs < (fh + fy))) {
|
|
|
|
if (cs > fy) {
|
|
|
|
yc += (cs - fy);
|
|
|
|
fh -= (cs - fy);
|
2004-04-11 12:01:22 +04:00
|
|
|
}
|
2020-11-19 19:32:22 +03:00
|
|
|
if ((ce - cs + 1) < fh) {
|
|
|
|
fh = ce - cs + 1;
|
2004-04-11 12:01:22 +04:00
|
|
|
}
|
2020-11-19 19:32:22 +03:00
|
|
|
DrawBitmap(hdc, vgafont[ch], xc, yc, fw, fh, fx, fy, bc, fc);
|
|
|
|
}
|
2002-08-10 19:23:30 +04:00
|
|
|
ReleaseDC(stInfo.simWnd, hdc);
|
2001-04-10 05:04:59 +04:00
|
|
|
LeaveCriticalSection(&stInfo.drawCS);
|
|
|
|
}
|
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
void bx_win32_gui_c::text_update(Bit8u *old_text, Bit8u *new_text,
|
|
|
|
unsigned long cursor_x, unsigned long cursor_y,
|
|
|
|
bx_vga_tminfo_t *tm_info)
|
|
|
|
{
|
|
|
|
// present for compatibility
|
|
|
|
}
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
int bx_win32_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
|
2002-03-16 14:30:06 +03:00
|
|
|
{
|
2002-08-10 19:23:30 +04:00
|
|
|
if (OpenClipboard(stInfo.simWnd)) {
|
2002-03-16 14:30:06 +03:00
|
|
|
HGLOBAL hg = GetClipboardData(CF_TEXT);
|
|
|
|
char *data = (char *)GlobalLock(hg);
|
|
|
|
*nbytes = strlen(data);
|
2002-09-05 19:57:37 +04:00
|
|
|
*bytes = new Bit8u[1 + *nbytes];
|
2002-03-16 14:30:06 +03:00
|
|
|
BX_INFO (("found %d bytes on the clipboard", *nbytes));
|
|
|
|
memcpy (*bytes, data, *nbytes+1);
|
|
|
|
BX_INFO (("first byte is 0x%02x", *bytes[0]));
|
|
|
|
GlobalUnlock(hg);
|
|
|
|
CloseClipboard();
|
|
|
|
return 1;
|
2002-09-05 19:57:37 +04:00
|
|
|
// *bytes will be freed in bx_keyb_c::paste_bytes or
|
|
|
|
// bx_keyb_c::service_paste_buf, using delete [].
|
2002-03-16 14:30:06 +03:00
|
|
|
} else {
|
|
|
|
BX_ERROR (("paste: could not open clipboard"));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
int bx_win32_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
|
2002-03-15 19:45:10 +03:00
|
|
|
{
|
2002-08-10 19:23:30 +04:00
|
|
|
if (OpenClipboard(stInfo.simWnd)) {
|
2002-03-16 14:30:06 +03:00
|
|
|
HANDLE hMem = GlobalAlloc(GMEM_ZEROINIT, len);
|
|
|
|
EmptyClipboard();
|
|
|
|
lstrcpy((char *)hMem, text_snapshot);
|
|
|
|
SetClipboardData(CF_TEXT, hMem);
|
|
|
|
CloseClipboard();
|
|
|
|
GlobalFree(hMem);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
BX_ERROR (("copy: could not open clipboard"));
|
|
|
|
return 0;
|
|
|
|
}
|
2002-03-15 19:45:10 +03:00
|
|
|
}
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2021-01-30 21:32:52 +03:00
|
|
|
bool bx_win32_gui_c::palette_change(Bit8u index, Bit8u red, Bit8u green,
|
2012-10-14 22:29:44 +04:00
|
|
|
Bit8u blue) {
|
2005-03-23 23:46:52 +03:00
|
|
|
if ((current_bpp == 16) && (index < 3)) {
|
|
|
|
cmap_index[256+index].rgbRed = red;
|
|
|
|
cmap_index[256+index].rgbBlue = blue;
|
|
|
|
cmap_index[256+index].rgbGreen = green;
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
cmap_index[index].rgbRed = red;
|
|
|
|
cmap_index[index].rgbBlue = blue;
|
|
|
|
cmap_index[index].rgbGreen = green;
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void bx_win32_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
|
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
HDC hdc;
|
|
|
|
HGDIOBJ oldObj;
|
|
|
|
|
|
|
|
EnterCriticalSection(&stInfo.drawCS);
|
2002-08-10 19:23:30 +04:00
|
|
|
hdc = GetDC(stInfo.simWnd);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
oldObj = SelectObject(MemoryDC, MemoryBitmap);
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
StretchDIBits(MemoryDC, x0, y0, x_tilesize, y_tilesize, 0, 0,
|
2001-04-10 05:04:59 +04:00
|
|
|
x_tilesize, y_tilesize, tile, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
|
|
|
|
|
|
|
|
SelectObject(MemoryDC, oldObj);
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
updateUpdated(x0, y0, x0 + x_tilesize - 1, y0 + y_tilesize - 1);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
ReleaseDC(stInfo.simWnd, hdc);
|
2001-04-10 05:04:59 +04:00
|
|
|
LeaveCriticalSection(&stInfo.drawCS);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-06-28 12:04:31 +04:00
|
|
|
void bx_win32_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
|
2002-04-20 11:19:35 +04:00
|
|
|
{
|
2014-05-22 23:06:01 +04:00
|
|
|
guest_textmode = (fheight > 0);
|
2020-11-22 12:02:38 +03:00
|
|
|
guest_fwidth = fwidth;
|
|
|
|
guest_fheight = fheight;
|
2014-05-22 23:06:01 +04:00
|
|
|
guest_xres = x;
|
|
|
|
guest_yres = y;
|
|
|
|
if (guest_textmode) {
|
2020-10-23 16:14:34 +03:00
|
|
|
yChar = fheight;
|
|
|
|
xChar = fwidth;
|
2014-05-22 23:06:01 +04:00
|
|
|
}
|
2014-05-20 22:42:36 +04:00
|
|
|
|
2014-05-23 23:28:23 +04:00
|
|
|
if ((x == dimension_x) && (y == dimension_y) && (bpp == current_bpp))
|
|
|
|
return;
|
|
|
|
dimension_x = x;
|
|
|
|
dimension_y = y;
|
2002-04-20 11:19:35 +04:00
|
|
|
|
2020-10-25 19:23:42 +03:00
|
|
|
if ((desktop_y > 0) && ((x > desktop_x) | (y > desktop_y))) {
|
2014-05-30 14:12:13 +04:00
|
|
|
BX_ERROR(("dimension_update(): resolution of out of desktop bounds - screen only partly visible"));
|
|
|
|
}
|
2020-10-25 19:23:42 +03:00
|
|
|
// stretch small simulation window (compatibility code)
|
|
|
|
if (!win32_autoscale) {
|
|
|
|
stretch_factor = 1;
|
|
|
|
if (x < 400) {
|
|
|
|
stretch_factor = 2;
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2003-06-28 12:04:31 +04:00
|
|
|
bitmap_info->bmiHeader.biBitCount = bpp;
|
2012-10-14 22:29:44 +04:00
|
|
|
if (bpp == 16) {
|
2003-07-01 01:24:09 +04:00
|
|
|
bitmap_info->bmiHeader.biCompression = BI_BITFIELDS;
|
|
|
|
static RGBQUAD red_mask = {0x00, 0xF8, 0x00, 0x00};
|
|
|
|
static RGBQUAD green_mask = {0xE0, 0x07, 0x00, 0x00};
|
|
|
|
static RGBQUAD blue_mask = {0x1F, 0x00, 0x00, 0x00};
|
2005-03-23 23:46:52 +03:00
|
|
|
bitmap_info->bmiColors[256] = bitmap_info->bmiColors[0];
|
|
|
|
bitmap_info->bmiColors[257] = bitmap_info->bmiColors[1];
|
|
|
|
bitmap_info->bmiColors[258] = bitmap_info->bmiColors[2];
|
2003-07-01 01:24:09 +04:00
|
|
|
bitmap_info->bmiColors[0] = red_mask;
|
|
|
|
bitmap_info->bmiColors[1] = green_mask;
|
|
|
|
bitmap_info->bmiColors[2] = blue_mask;
|
2012-10-14 22:29:44 +04:00
|
|
|
} else {
|
|
|
|
if (current_bpp == 16) {
|
2005-03-23 23:46:52 +03:00
|
|
|
bitmap_info->bmiColors[0] = bitmap_info->bmiColors[256];
|
|
|
|
bitmap_info->bmiColors[1] = bitmap_info->bmiColors[257];
|
|
|
|
bitmap_info->bmiColors[2] = bitmap_info->bmiColors[258];
|
|
|
|
}
|
2003-07-01 01:24:09 +04:00
|
|
|
bitmap_info->bmiHeader.biCompression = BI_RGB;
|
2012-10-14 22:29:44 +04:00
|
|
|
if (bpp == 15) {
|
2003-07-11 19:11:24 +04:00
|
|
|
bitmap_info->bmiHeader.biBitCount = 16;
|
|
|
|
}
|
2003-07-01 01:24:09 +04:00
|
|
|
}
|
2012-10-14 22:29:44 +04:00
|
|
|
current_bpp = guest_bpp = bpp;
|
2002-03-21 21:40:20 +03:00
|
|
|
|
2014-05-23 23:28:23 +04:00
|
|
|
resize_main_window(FALSE);
|
2003-10-25 15:57:42 +04:00
|
|
|
|
2006-12-05 22:45:56 +03:00
|
|
|
BX_INFO(("dimension update x=%d y=%d fontheight=%d fontwidth=%d bpp=%d", x, y, fheight, fwidth, bpp));
|
2004-08-15 23:27:15 +04:00
|
|
|
|
2014-05-23 23:28:23 +04:00
|
|
|
host_xres = x;
|
|
|
|
host_yres = y;
|
|
|
|
host_bpp = bpp;
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-05 21:56:56 +03:00
|
|
|
unsigned bx_win32_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
|
2008-02-16 01:05:43 +03:00
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
unsigned char *data;
|
2002-08-10 19:23:30 +04:00
|
|
|
TBADDBITMAP tbab;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
if (bx_bitmap_entries >= BX_MAX_PIXMAPS)
|
|
|
|
terminateEmul(EXIT_HEADER_BITMAP_ERROR);
|
|
|
|
|
|
|
|
bx_bitmaps[bx_bitmap_entries].bmap = CreateBitmap(xdim,ydim,1,1,NULL);
|
|
|
|
if (!bx_bitmaps[bx_bitmap_entries].bmap)
|
|
|
|
terminateEmul(EXIT_HEADER_BITMAP_ERROR);
|
|
|
|
|
|
|
|
data = new unsigned char[ydim * xdim/8];
|
|
|
|
for (unsigned i=0; i<ydim * xdim/8; i++)
|
2002-08-10 19:23:30 +04:00
|
|
|
data[i] = 255 - reverse_bitorder(bmap[i]);
|
2001-04-10 05:04:59 +04:00
|
|
|
SetBitmapBits(bx_bitmaps[bx_bitmap_entries].bmap, ydim * xdim/8, data);
|
2001-12-21 22:33:18 +03:00
|
|
|
delete [] data;
|
|
|
|
data = NULL;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
bx_bitmaps[bx_bitmap_entries].xdim = xdim;
|
|
|
|
bx_bitmaps[bx_bitmap_entries].ydim = ydim;
|
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
tbab.hInst = NULL;
|
2010-11-01 18:02:14 +03:00
|
|
|
tbab.nID = (UINT_PTR)bx_bitmaps[bx_bitmap_entries].bmap;
|
2002-08-10 19:23:30 +04:00
|
|
|
SendMessage(hwndTB, TB_ADDBITMAP, 1, (LPARAM)&tbab);
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
bx_bitmap_entries++;
|
|
|
|
return(bx_bitmap_entries-1); // return index as handle
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-05 21:56:56 +03:00
|
|
|
unsigned bx_win32_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
|
2008-02-16 01:05:43 +03:00
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
unsigned hb_index;
|
2002-08-10 19:23:30 +04:00
|
|
|
TBBUTTON tbb[1];
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2017-01-14 18:11:14 +03:00
|
|
|
if ((win32_toolbar_entries+1) > BX_MAX_HEADERBAR_ENTRIES)
|
2001-04-10 05:04:59 +04:00
|
|
|
terminateEmul(EXIT_HEADER_BITMAP_ERROR);
|
|
|
|
|
2017-01-14 18:11:14 +03:00
|
|
|
hb_index = win32_toolbar_entries++;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-08-10 19:23:30 +04:00
|
|
|
memset(tbb,0,sizeof(tbb));
|
|
|
|
if (bx_hb_separator==0) {
|
|
|
|
tbb[0].iBitmap = 0;
|
|
|
|
tbb[0].idCommand = 0;
|
|
|
|
tbb[0].fsState = 0;
|
|
|
|
tbb[0].fsStyle = TBSTYLE_SEP;
|
|
|
|
SendMessage(hwndTB, TB_ADDBUTTONS, 1,(LPARAM)(LPTBBUTTON)&tbb);
|
|
|
|
}
|
|
|
|
tbb[0].iBitmap = bmap_id;
|
|
|
|
tbb[0].idCommand = hb_index + 101;
|
|
|
|
tbb[0].fsState = TBSTATE_ENABLED;
|
|
|
|
tbb[0].fsStyle = TBSTYLE_BUTTON;
|
2001-04-10 05:04:59 +04:00
|
|
|
if (alignment == BX_GRAVITY_LEFT) {
|
2002-08-10 19:23:30 +04:00
|
|
|
SendMessage(hwndTB, TB_INSERTBUTTON, bx_hb_separator,(LPARAM)(LPTBBUTTON)&tbb);
|
|
|
|
bx_hb_separator++;
|
2001-04-10 05:04:59 +04:00
|
|
|
} else { // BX_GRAVITY_RIGHT
|
2002-08-10 19:23:30 +04:00
|
|
|
SendMessage(hwndTB, TB_INSERTBUTTON, bx_hb_separator+1, (LPARAM)(LPTBBUTTON)&tbb);
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2017-01-14 18:11:14 +03:00
|
|
|
win32_toolbar_entry[hb_index].bmap_id = bmap_id;
|
|
|
|
win32_toolbar_entry[hb_index].f = f;
|
|
|
|
win32_toolbar_entry[hb_index].tooltip = NULL;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
return(hb_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
void bx_win32_gui_c::show_headerbar(void)
|
2002-08-10 19:23:30 +04:00
|
|
|
{
|
2005-05-08 23:10:21 +04:00
|
|
|
if (!IsWindowVisible(hwndTB)) {
|
|
|
|
SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);
|
|
|
|
ShowWindow(hwndTB, SW_SHOW);
|
2014-05-23 23:28:23 +04:00
|
|
|
resize_main_window(FALSE);
|
2006-01-25 20:37:22 +03:00
|
|
|
bx_gui->set_tooltip(bx_gui->get_mouse_headerbar_id(), szMouseTooltip);
|
2003-09-17 23:47:41 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
void bx_win32_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
|
2002-08-10 19:23:30 +04:00
|
|
|
{
|
2017-01-14 18:11:14 +03:00
|
|
|
if (bmap_id != win32_toolbar_entry[hbar_id].bmap_id) {
|
|
|
|
win32_toolbar_entry[hbar_id].bmap_id = bmap_id;
|
2021-01-30 21:32:52 +03:00
|
|
|
bool is_visible = IsWindowVisible(hwndTB);
|
2005-05-08 23:10:21 +04:00
|
|
|
if (is_visible) {
|
|
|
|
ShowWindow(hwndTB, SW_HIDE);
|
|
|
|
}
|
2002-08-10 19:23:30 +04:00
|
|
|
SendMessage(hwndTB, TB_CHANGEBITMAP, (WPARAM)hbar_id+101, (LPARAM)
|
|
|
|
MAKELPARAM(bmap_id, 0));
|
2005-05-08 23:10:21 +04:00
|
|
|
SendMessage(hwndTB, TB_AUTOSIZE, 0, 0);
|
|
|
|
if (is_visible) {
|
|
|
|
ShowWindow(hwndTB, SW_SHOW);
|
|
|
|
}
|
2002-08-10 19:23:30 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void bx_win32_gui_c::exit(void)
|
|
|
|
{
|
2014-08-17 16:48:05 +04:00
|
|
|
#if BX_DEBUGGER && BX_DEBUGGER_GUI
|
|
|
|
if (SIM->has_debug_gui()) {
|
|
|
|
close_debug_dialog();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
// kill thread first...
|
2002-08-10 19:23:30 +04:00
|
|
|
PostMessage(stInfo.mainWnd, WM_CLOSE, 0, 0);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// Wait until it dies
|
|
|
|
while ((stInfo.kill == 0) && (workerThreadID != 0)) Sleep(500);
|
|
|
|
|
|
|
|
if (!stInfo.kill) terminateEmul(EXIT_NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void create_vga_font(void)
|
|
|
|
{
|
2002-09-08 20:41:19 +04:00
|
|
|
unsigned char data[64];
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-05-13 22:44:23 +04:00
|
|
|
// VGA font is 8 or 9 wide and up to 32 high
|
2001-04-10 05:04:59 +04:00
|
|
|
for (unsigned c = 0; c<256; c++) {
|
2003-05-13 22:44:23 +04:00
|
|
|
vgafont[c] = CreateBitmap(9,32,1,1,NULL);
|
2001-04-10 05:04:59 +04:00
|
|
|
if (!vgafont[c]) terminateEmul(EXIT_FONT_BITMAP_ERROR);
|
2002-09-08 20:41:19 +04:00
|
|
|
memset(data, 0, sizeof(data));
|
2001-04-10 05:04:59 +04:00
|
|
|
for (unsigned i=0; i<16; i++)
|
|
|
|
data[i*2] = reverse_bitorder(bx_vgafont[c].data[i]);
|
2002-09-08 20:41:19 +04:00
|
|
|
SetBitmapBits(vgafont[c], 64, data);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
COLORREF GetColorRef(Bit8u pal_idx)
|
2002-08-12 18:41:42 +04:00
|
|
|
{
|
2006-10-15 20:23:42 +04:00
|
|
|
return RGB(cmap_index[pal_idx].rgbRed, cmap_index[pal_idx].rgbGreen,
|
|
|
|
cmap_index[pal_idx].rgbBlue);
|
2002-08-12 18:41:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-15 20:23:42 +04:00
|
|
|
void DrawBitmap(HDC hdc, HBITMAP hBitmap, int xStart, int yStart, int width,
|
2020-11-19 19:32:22 +03:00
|
|
|
int height, int fcol, int frow, Bit8u fgcolor, Bit8u bgcolor)
|
2008-02-16 01:05:43 +03:00
|
|
|
{
|
2001-04-10 05:04:59 +04:00
|
|
|
BITMAP bm;
|
|
|
|
HDC hdcMem;
|
|
|
|
POINT ptSize, ptOrg;
|
|
|
|
HGDIOBJ oldObj;
|
|
|
|
|
2020-10-23 16:14:34 +03:00
|
|
|
hdcMem = CreateCompatibleDC(hdc);
|
|
|
|
SelectObject(hdcMem, hBitmap);
|
|
|
|
SetMapMode(hdcMem, GetMapMode (hdc));
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2020-10-23 16:14:34 +03:00
|
|
|
GetObject(hBitmap, sizeof (BITMAP), (LPVOID) &bm);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-06-22 16:37:03 +04:00
|
|
|
ptSize.x = width;
|
|
|
|
ptSize.y = height;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2020-10-23 16:14:34 +03:00
|
|
|
DPtoLP(hdc, &ptSize, 1);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-06-22 16:37:03 +04:00
|
|
|
ptOrg.x = fcol;
|
|
|
|
ptOrg.y = frow;
|
2020-10-23 16:14:34 +03:00
|
|
|
DPtoLP(hdcMem, &ptOrg, 1);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
oldObj = SelectObject(MemoryDC, MemoryBitmap);
|
2003-05-13 22:44:23 +04:00
|
|
|
|
2020-11-19 19:32:22 +03:00
|
|
|
COLORREF crFore = SetTextColor(MemoryDC, GetColorRef(bgcolor));
|
|
|
|
COLORREF crBack = SetBkColor(MemoryDC, GetColorRef(fgcolor));
|
2020-10-23 16:14:34 +03:00
|
|
|
if (xChar > 9) {
|
|
|
|
StretchBlt(MemoryDC, xStart, yStart, ptSize.x, ptSize.y, hdcMem, ptOrg.x,
|
2020-11-19 19:32:22 +03:00
|
|
|
ptOrg.y, ptSize.x / 2, ptSize.y, SRCCOPY);
|
2020-10-23 16:14:34 +03:00
|
|
|
} else {
|
|
|
|
BitBlt(MemoryDC, xStart, yStart, ptSize.x, ptSize.y, hdcMem, ptOrg.x,
|
2020-11-19 19:32:22 +03:00
|
|
|
ptOrg.y, SRCCOPY);
|
2020-10-23 16:14:34 +03:00
|
|
|
}
|
2006-10-15 20:23:42 +04:00
|
|
|
SetBkColor(MemoryDC, crBack);
|
|
|
|
SetTextColor(MemoryDC, crFore);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
SelectObject(MemoryDC, oldObj);
|
|
|
|
|
|
|
|
updateUpdated(xStart, yStart, ptSize.x + xStart - 1, ptSize.y + yStart - 1);
|
|
|
|
|
2020-10-23 16:14:34 +03:00
|
|
|
DeleteDC(hdcMem);
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-16 01:05:43 +03:00
|
|
|
void updateUpdated(int x1, int y1, int x2, int y2)
|
|
|
|
{
|
2020-10-23 16:14:34 +03:00
|
|
|
x1 *= stretch_factor;
|
|
|
|
y1 *= stretch_factor;
|
|
|
|
x2 *= stretch_factor;
|
|
|
|
y2 *= stretch_factor;
|
2001-04-10 05:04:59 +04:00
|
|
|
if (!updated_area_valid) {
|
|
|
|
updated_area.left = x1 ;
|
|
|
|
updated_area.top = y1 ;
|
|
|
|
updated_area.right = x2 ;
|
|
|
|
updated_area.bottom = y2 ;
|
|
|
|
} else {
|
|
|
|
if (x1 < updated_area.left) updated_area.left = x1 ;
|
|
|
|
if (y1 < updated_area.top) updated_area.top = y1 ;
|
|
|
|
if (x2 > updated_area.right) updated_area.right = x2 ;
|
|
|
|
if (y2 > updated_area.bottom) updated_area.bottom = y2;
|
|
|
|
}
|
|
|
|
|
|
|
|
updated_area_valid = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-14 18:11:14 +03:00
|
|
|
void win32_toolbar_click(int x)
|
2002-08-10 19:23:30 +04:00
|
|
|
{
|
2017-01-14 18:11:14 +03:00
|
|
|
if (x < win32_toolbar_entries) {
|
|
|
|
win32_toolbar_entry[x].f();
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-30 21:32:52 +03:00
|
|
|
void bx_win32_gui_c::mouse_enabled_changed_specific(bool val)
|
2001-06-23 07:18:14 +04:00
|
|
|
{
|
2021-01-30 21:32:52 +03:00
|
|
|
if ((val != (bool)mouseCaptureMode) && !mouseToggleReq) {
|
2004-02-17 00:47:08 +03:00
|
|
|
mouseToggleReq = TRUE;
|
|
|
|
mouseCaptureNew = val;
|
|
|
|
}
|
2001-06-23 07:18:14 +04:00
|
|
|
}
|
2002-03-21 21:40:20 +03:00
|
|
|
|
2006-12-05 22:45:56 +03:00
|
|
|
void bx_win32_gui_c::get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp)
|
|
|
|
{
|
|
|
|
if (desktop_y > 0) {
|
|
|
|
*xres = desktop_x;
|
|
|
|
*yres = desktop_y;
|
|
|
|
*bpp = 32;
|
|
|
|
} else {
|
|
|
|
*xres = 1024;
|
|
|
|
*yres = 768;
|
|
|
|
*bpp = 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-25 20:37:22 +03:00
|
|
|
void bx_win32_gui_c::set_tooltip(unsigned hbar_id, const char *tip)
|
|
|
|
{
|
2017-01-14 18:11:14 +03:00
|
|
|
win32_toolbar_entry[hbar_id].tooltip = tip;
|
2006-01-25 20:37:22 +03:00
|
|
|
}
|
|
|
|
|
2021-01-30 21:32:52 +03:00
|
|
|
void bx_win32_gui_c::set_mouse_mode_absxy(bool mode)
|
2012-06-26 00:08:52 +04:00
|
|
|
{
|
|
|
|
win32MouseModeAbsXY = mode;
|
|
|
|
}
|
|
|
|
|
2006-01-22 21:15:48 +03:00
|
|
|
#if BX_SHOW_IPS
|
2009-05-13 21:26:45 +04:00
|
|
|
VOID CALLBACK MyTimer(HWND hwnd,UINT uMsg, UINT idEvent, DWORD dwTime)
|
|
|
|
{
|
2012-08-26 16:32:10 +04:00
|
|
|
bx_show_ips_handler();
|
2009-05-13 21:26:45 +04:00
|
|
|
}
|
|
|
|
|
2006-01-22 15:31:16 +03:00
|
|
|
void bx_win32_gui_c::show_ips(Bit32u ips_count)
|
|
|
|
{
|
2006-01-27 21:04:49 +03:00
|
|
|
if (!ipsUpdate) {
|
2011-08-15 00:21:07 +04:00
|
|
|
sprintf(ipsText, "IPS: %3.3fM", ips_count / 1000000.0);
|
2006-01-27 21:04:49 +03:00
|
|
|
ipsUpdate = TRUE;
|
2006-01-24 00:53:57 +03:00
|
|
|
}
|
2006-01-22 15:31:16 +03:00
|
|
|
}
|
2006-01-22 21:15:48 +03:00
|
|
|
#endif
|
2006-01-22 15:31:16 +03:00
|
|
|
|
2002-11-19 08:47:45 +03:00
|
|
|
#endif /* if BX_WITH_WIN32 */
|