split files

This commit is contained in:
Wengier 2022-01-24 14:00:48 -05:00
parent 285e15345b
commit 2a0e06f345
11 changed files with 4630 additions and 4486 deletions

View File

@ -387,93 +387,11 @@ uint16_t cpMap_PC98[256] = {
0x0020, 0x0020, 0x0020, 0x0020, 0x005C, 0x0020, 0x0020, 0x0020 // 0xF8-0xFF 0xFC = Backslash
};
bool getClipboard();
bool lastwrite = false;
uint8_t *clipAscii = NULL;
uint32_t clipSize = 0, cPointer = 0, fPointer;
#if defined(WIN32)
bool CodePageHostToGuestUTF16(char *d/*CROSS_LEN*/,const uint16_t *s/*CROSS_LEN*/);
bool Unicode2Ascii(const uint16_t* unicode) {
int memNeeded = 0;
char temp[4096];
bool ret=false;
morelen=true;
if (CodePageHostToGuestUTF16(temp,unicode) && (clipAscii = (uint8_t *)malloc(strlen(temp)+1))) {
morelen=false;
ret=true;
strcpy((char *)clipAscii, temp);
memNeeded = strlen(temp);
} else {
morelen=false;
int memNeeded = WideCharToMultiByte(dos.loaded_codepage==808?866:(dos.loaded_codepage==872?855:(dos.loaded_codepage==951?950:dos.loaded_codepage)), WC_NO_BEST_FIT_CHARS, (LPCWSTR)unicode, -1, NULL, 0, "\x07", NULL);
if (memNeeded <= 1) // Includes trailing null
return false;
if (!(clipAscii = (uint8_t *)malloc(memNeeded)))
return false;
// Untranslated characters will be set to 0x07 (BEL), and later stripped
if (WideCharToMultiByte(dos.loaded_codepage==808?866:(dos.loaded_codepage==872?855:(dos.loaded_codepage==951?950:dos.loaded_codepage)), WC_NO_BEST_FIT_CHARS, (LPCWSTR)unicode, -1, (LPSTR)clipAscii, memNeeded, "\x07", NULL) != memNeeded) { // Can't actually happen of course
free(clipAscii);
clipAscii = NULL;
return false;
}
memNeeded--; // Don't include trailing null
}
for (int i = 0; i < memNeeded; i++)
if (clipAscii[i] > 31 || clipAscii[i] == 9 || clipAscii[i] == 10 || clipAscii[i] == 13 // Space and up, or TAB, CR/LF allowed (others make no sense when pasting)
|| (dos.loaded_codepage == 932 && (TTF_using() || IS_JEGA_ARCH || showdbcs)
#if defined(USE_TTF)
&& halfwidthkana
#endif
&& ((IS_JEGA_ARCH && clipAscii[i] && clipAscii[i] < 32) || (!IS_PC98_ARCH && !IS_JEGA_ARCH && lowboxdrawmap.find(clipAscii[i])!=lowboxdrawmap.end()))))
clipAscii[clipSize++] = clipAscii[i];
return ret; // clipAscii dould be downsized, but of no real interest
}
#else
typedef char host_cnv_char_t;
host_cnv_char_t *CodePageGuestToHost(const char *s);
#endif
bool swapad=true;
extern std::string strPasteBuffer;
void PasteClipboard(bool bPressed);
bool getClipboard() {
if (clipAscii) {
free(clipAscii);
clipAscii = NULL;
}
#if defined(WIN32)
clipSize = 0;
if (OpenClipboard(NULL)) {
if (HANDLE cbText = GetClipboardData(CF_UNICODETEXT)) {
uint16_t *unicode = (uint16_t *)GlobalLock(cbText);
Unicode2Ascii(unicode);
GlobalUnlock(cbText);
}
CloseClipboard();
}
#else
swapad=false;
PasteClipboard(true);
swapad=true;
clipSize = 0;
unsigned int extra = 0;
unsigned char head, last=13;
for (size_t i=0; i<strPasteBuffer.length(); i++) if (strPasteBuffer[i]==10||strPasteBuffer[i]==13) extra++;
clipAscii = (uint8_t*)malloc(strPasteBuffer.length() + extra);
if (clipAscii)
while (strPasteBuffer.length()) {
head = strPasteBuffer[0];
if (head == 10 && last != 13) clipAscii[clipSize++] = 13;
if (head > 31 || head == 9 || head == 10 || head == 13)
clipAscii[clipSize++] = head;
if (head == 13 && (strPasteBuffer.length() < 2 || strPasteBuffer[1] != 10)) clipAscii[clipSize++] = 10;
strPasteBuffer = strPasteBuffer.substr(1, strPasteBuffer.length());
last = head;
}
#endif
return clipSize != 0;
}
uint32_t cPointer = 0, fPointer;
extern uint32_t clipSize;
extern uint8_t *clipAscii;
class device_CLIP : public DOS_Device {
private:
char tmpAscii[20];

View File

@ -8,8 +8,9 @@ libgui_a_SOURCES = \
render_templates.h render_loops.h render_simple.h \
render_templates_sai.h render_templates_hq.h \
render_templates_hq2x.h render_templates_hq3x.h \
midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h midi_alsa.h \
midi_coremidi.h sdl_gui.cpp dosbox_splash.h menu.cpp bitop.cpp ptrop.cpp zipcrc.c zipfile.cpp
midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h \
midi_alsa.h midi_coremidi.h sdl_gui.cpp dosbox_splash.h \
menu.cpp menu_callback.cpp bitop.cpp ptrop.cpp zipcrc.c zipfile.cpp
if C_MT32
AM_CPPFLAGS += -I$(top_srcdir)/src/libs/mt32

3388
src/gui/menu_callback.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1191,7 +1191,6 @@ bool GFX_IsFullscreen(void), Direct3D_using(void);
void ttf_reset(void), resetFontSize(), setVGADAC(), OUTPUT_TTF_Select(int fsize), RENDER_Reset(void), KEYBOARD_Clear(), GFX_SwitchFullscreenNoReset(void);
bool ttfswitch=false, switch_output_from_ttf=false;
extern bool resetreq, colorChanged;
extern int switchoutput;
void ttf_switch_on(bool ss=true) {
if ((ss&&ttfswitch)||(!ss&&switch_output_from_ttf)) {

View File

@ -3,4 +3,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src "-DRESDIR=\"$(resdir)\
resdir = $(datarootdir)/dosbox-x
noinst_LIBRARIES = libmisc.a
libmisc_a_SOURCES = cross.cpp ethernet.cpp ethernet_pcap.cpp ethernet_slirp.cpp messages.cpp programs.cpp setup.cpp support.cpp regionalloctracking.cpp savestates.cpp shiftjis.cpp iconvpp.cpp
libmisc_a_SOURCES = clipboard.cpp cross.cpp ethernet.cpp ethernet_pcap.cpp ethernet_slirp.cpp messages.cpp programs.cpp setup.cpp support.cpp regionalloctracking.cpp savestates.cpp shiftjis.cpp iconvpp.cpp

862
src/misc/clipboard.cpp Normal file
View File

@ -0,0 +1,862 @@
/*
* Copyright (C) 2002-2021 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "dosbox.h"
#include "dos_inc.h"
#include "sdlmain.h"
#include "keyboard.h"
#include "render.h"
#include "jfont.h"
#include "bios.h"
#include "../ints/int10.h"
uint8_t *clipAscii = NULL;
uint32_t clipSize = 0;
bool direct_mouse_clipboard = false;
extern const char *modifier;
extern std::map<int, int> lowboxdrawmap;
extern bool morelen, showdbcs, selmark, clipboard_biospaste;
extern int mouse_start_x, mouse_start_y, mouse_end_x, mouse_end_y, fx, fy, selsrow, selscol, selerow, selecol, mbutton;
bool CodePageHostToGuestUTF16(char *d/*CROSS_LEN*/,const uint16_t *s/*CROSS_LEN*/);
bool CodePageGuestToHostUTF16(uint16_t *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/);
#if defined(WIN32)
bool Unicode2Ascii(const uint16_t* unicode) {
int memNeeded = 0;
char temp[4096];
bool ret=false;
morelen=true;
if (CodePageHostToGuestUTF16(temp,unicode) && (clipAscii = (uint8_t *)malloc(strlen(temp)+1))) {
morelen=false;
ret=true;
strcpy((char *)clipAscii, temp);
memNeeded = strlen(temp);
} else {
morelen=false;
int memNeeded = WideCharToMultiByte(dos.loaded_codepage==808?866:(dos.loaded_codepage==872?855:(dos.loaded_codepage==951?950:dos.loaded_codepage)), WC_NO_BEST_FIT_CHARS, (LPCWSTR)unicode, -1, NULL, 0, "\x07", NULL);
if (memNeeded <= 1) // Includes trailing null
return false;
if (!(clipAscii = (uint8_t *)malloc(memNeeded)))
return false;
// Untranslated characters will be set to 0x07 (BEL), and later stripped
if (WideCharToMultiByte(dos.loaded_codepage==808?866:(dos.loaded_codepage==872?855:(dos.loaded_codepage==951?950:dos.loaded_codepage)), WC_NO_BEST_FIT_CHARS, (LPCWSTR)unicode, -1, (LPSTR)clipAscii, memNeeded, "\x07", NULL) != memNeeded) { // Can't actually happen of course
free(clipAscii);
clipAscii = NULL;
return false;
}
memNeeded--; // Don't include trailing null
}
for (int i = 0; i < memNeeded; i++)
if (clipAscii[i] > 31 || clipAscii[i] == 9 || clipAscii[i] == 10 || clipAscii[i] == 13 // Space and up, or TAB, CR/LF allowed (others make no sense when pasting)
|| (dos.loaded_codepage == 932 && (TTF_using() || IS_JEGA_ARCH || showdbcs)
#if defined(USE_TTF)
&& halfwidthkana
#endif
&& ((IS_JEGA_ARCH && clipAscii[i] && clipAscii[i] < 32) || (!IS_PC98_ARCH && !IS_JEGA_ARCH && lowboxdrawmap.find(clipAscii[i])!=lowboxdrawmap.end()))))
clipAscii[clipSize++] = clipAscii[i];
return ret; // clipAscii dould be downsized, but of no real interest
}
#else
typedef char host_cnv_char_t;
host_cnv_char_t *CodePageGuestToHost(const char *s);
#endif
bool swapad=true;
extern std::string strPasteBuffer;
void PasteClipboard(bool bPressed);
bool getClipboard() {
if (clipAscii) {
free(clipAscii);
clipAscii = NULL;
}
#if defined(WIN32)
clipSize = 0;
if (OpenClipboard(NULL)) {
if (HANDLE cbText = GetClipboardData(CF_UNICODETEXT)) {
uint16_t *unicode = (uint16_t *)GlobalLock(cbText);
Unicode2Ascii(unicode);
GlobalUnlock(cbText);
}
CloseClipboard();
}
#else
swapad=false;
PasteClipboard(true);
swapad=true;
clipSize = 0;
unsigned int extra = 0;
unsigned char head, last=13;
for (size_t i=0; i<strPasteBuffer.length(); i++) if (strPasteBuffer[i]==10||strPasteBuffer[i]==13) extra++;
clipAscii = (uint8_t*)malloc(strPasteBuffer.length() + extra);
if (clipAscii)
while (strPasteBuffer.length()) {
head = strPasteBuffer[0];
if (head == 10 && last != 13) clipAscii[clipSize++] = 13;
if (head > 31 || head == 9 || head == 10 || head == 13)
clipAscii[clipSize++] = head;
if (head == 13 && (strPasteBuffer.length() < 2 || strPasteBuffer[1] != 10)) clipAscii[clipSize++] = 10;
strPasteBuffer = strPasteBuffer.substr(1, strPasteBuffer.length());
last = head;
}
#endif
return clipSize != 0;
}
#if defined(WIN32) && (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#ifndef DIK_PAUSE
#define DIK_PAUSE 0xC5
#endif
#ifndef DIK_OEM_102
#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */
#endif
#else
#define UINT unsigned int
#endif
#if defined(C_SDL2)
#define SDLKey SDL_Keycode
#define SDLMod SDL_Keymod
#endif
static SDLKey aryScanCodeToSDLKey[0x100];
static bool bScanCodeMapInited = false;
static void PasteInitMapSCToSDLKey()
{
/* Map the DIK scancodes to SDL keysyms */
for (unsigned int i = 0; i<SDL_arraysize(aryScanCodeToSDLKey); ++i)
aryScanCodeToSDLKey[i] = SDLK_UNKNOWN;
/* Defined DIK_* constants */
#if defined(WIN32) && (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
aryScanCodeToSDLKey[DIK_ESCAPE] = SDLK_ESCAPE;
aryScanCodeToSDLKey[DIK_1] = SDLK_1;
aryScanCodeToSDLKey[DIK_2] = SDLK_2;
aryScanCodeToSDLKey[DIK_3] = SDLK_3;
aryScanCodeToSDLKey[DIK_4] = SDLK_4;
aryScanCodeToSDLKey[DIK_5] = SDLK_5;
aryScanCodeToSDLKey[DIK_6] = SDLK_6;
aryScanCodeToSDLKey[DIK_7] = SDLK_7;
aryScanCodeToSDLKey[DIK_8] = SDLK_8;
aryScanCodeToSDLKey[DIK_9] = SDLK_9;
aryScanCodeToSDLKey[DIK_0] = SDLK_0;
aryScanCodeToSDLKey[DIK_MINUS] = SDLK_MINUS;
aryScanCodeToSDLKey[DIK_EQUALS] = SDLK_EQUALS;
aryScanCodeToSDLKey[DIK_BACK] = SDLK_BACKSPACE;
aryScanCodeToSDLKey[DIK_TAB] = SDLK_TAB;
aryScanCodeToSDLKey[DIK_Q] = SDLK_q;
aryScanCodeToSDLKey[DIK_W] = SDLK_w;
aryScanCodeToSDLKey[DIK_E] = SDLK_e;
aryScanCodeToSDLKey[DIK_R] = SDLK_r;
aryScanCodeToSDLKey[DIK_T] = SDLK_t;
aryScanCodeToSDLKey[DIK_Y] = SDLK_y;
aryScanCodeToSDLKey[DIK_U] = SDLK_u;
aryScanCodeToSDLKey[DIK_I] = SDLK_i;
aryScanCodeToSDLKey[DIK_O] = SDLK_o;
aryScanCodeToSDLKey[DIK_P] = SDLK_p;
aryScanCodeToSDLKey[DIK_LBRACKET] = SDLK_LEFTBRACKET;
aryScanCodeToSDLKey[DIK_RBRACKET] = SDLK_RIGHTBRACKET;
aryScanCodeToSDLKey[DIK_RETURN] = SDLK_RETURN;
aryScanCodeToSDLKey[DIK_LCONTROL] = SDLK_LCTRL;
aryScanCodeToSDLKey[DIK_A] = SDLK_a;
aryScanCodeToSDLKey[DIK_S] = SDLK_s;
aryScanCodeToSDLKey[DIK_D] = SDLK_d;
aryScanCodeToSDLKey[DIK_F] = SDLK_f;
aryScanCodeToSDLKey[DIK_G] = SDLK_g;
aryScanCodeToSDLKey[DIK_H] = SDLK_h;
aryScanCodeToSDLKey[DIK_J] = SDLK_j;
aryScanCodeToSDLKey[DIK_K] = SDLK_k;
aryScanCodeToSDLKey[DIK_L] = SDLK_l;
aryScanCodeToSDLKey[DIK_SEMICOLON] = SDLK_SEMICOLON;
aryScanCodeToSDLKey[DIK_APOSTROPHE] = SDLK_QUOTE;
aryScanCodeToSDLKey[DIK_GRAVE] = SDLK_BACKQUOTE;
aryScanCodeToSDLKey[DIK_LSHIFT] = SDLK_LSHIFT;
aryScanCodeToSDLKey[DIK_BACKSLASH] = SDLK_BACKSLASH;
aryScanCodeToSDLKey[DIK_OEM_102] = SDLK_LESS;
aryScanCodeToSDLKey[DIK_Z] = SDLK_z;
aryScanCodeToSDLKey[DIK_X] = SDLK_x;
aryScanCodeToSDLKey[DIK_C] = SDLK_c;
aryScanCodeToSDLKey[DIK_V] = SDLK_v;
aryScanCodeToSDLKey[DIK_B] = SDLK_b;
aryScanCodeToSDLKey[DIK_N] = SDLK_n;
aryScanCodeToSDLKey[DIK_M] = SDLK_m;
aryScanCodeToSDLKey[DIK_COMMA] = SDLK_COMMA;
aryScanCodeToSDLKey[DIK_PERIOD] = SDLK_PERIOD;
aryScanCodeToSDLKey[DIK_SLASH] = SDLK_SLASH;
aryScanCodeToSDLKey[DIK_RSHIFT] = SDLK_RSHIFT;
aryScanCodeToSDLKey[DIK_MULTIPLY] = SDLK_KP_MULTIPLY;
aryScanCodeToSDLKey[DIK_LMENU] = SDLK_LALT;
aryScanCodeToSDLKey[DIK_SPACE] = SDLK_SPACE;
aryScanCodeToSDLKey[DIK_CAPITAL] = SDLK_CAPSLOCK;
aryScanCodeToSDLKey[DIK_F1] = SDLK_F1;
aryScanCodeToSDLKey[DIK_F2] = SDLK_F2;
aryScanCodeToSDLKey[DIK_F3] = SDLK_F3;
aryScanCodeToSDLKey[DIK_F4] = SDLK_F4;
aryScanCodeToSDLKey[DIK_F5] = SDLK_F5;
aryScanCodeToSDLKey[DIK_F6] = SDLK_F6;
aryScanCodeToSDLKey[DIK_F7] = SDLK_F7;
aryScanCodeToSDLKey[DIK_F8] = SDLK_F8;
aryScanCodeToSDLKey[DIK_F9] = SDLK_F9;
aryScanCodeToSDLKey[DIK_F10] = SDLK_F10;
#if defined(C_SDL2)
aryScanCodeToSDLKey[DIK_NUMLOCK] = SDLK_NUMLOCKCLEAR;
aryScanCodeToSDLKey[DIK_SCROLL] = SDLK_SCROLLLOCK;
#else
aryScanCodeToSDLKey[DIK_NUMLOCK] = SDLK_NUMLOCK;
aryScanCodeToSDLKey[DIK_SCROLL] = SDLK_SCROLLOCK;
#endif
aryScanCodeToSDLKey[DIK_SUBTRACT] = SDLK_KP_MINUS;
aryScanCodeToSDLKey[DIK_ADD] = SDLK_KP_PLUS;
#if defined(C_SDL2)
aryScanCodeToSDLKey[DIK_NUMPAD7] = SDLK_KP_7;
aryScanCodeToSDLKey[DIK_NUMPAD8] = SDLK_KP_8;
aryScanCodeToSDLKey[DIK_NUMPAD9] = SDLK_KP_9;
aryScanCodeToSDLKey[DIK_NUMPAD4] = SDLK_KP_4;
aryScanCodeToSDLKey[DIK_NUMPAD5] = SDLK_KP_5;
aryScanCodeToSDLKey[DIK_NUMPAD6] = SDLK_KP_6;
aryScanCodeToSDLKey[DIK_NUMPAD1] = SDLK_KP_1;
aryScanCodeToSDLKey[DIK_NUMPAD2] = SDLK_KP_2;
aryScanCodeToSDLKey[DIK_NUMPAD3] = SDLK_KP_3;
aryScanCodeToSDLKey[DIK_NUMPAD0] = SDLK_KP_0;
#else
aryScanCodeToSDLKey[DIK_NUMPAD7] = SDLK_KP7;
aryScanCodeToSDLKey[DIK_NUMPAD8] = SDLK_KP8;
aryScanCodeToSDLKey[DIK_NUMPAD9] = SDLK_KP9;
aryScanCodeToSDLKey[DIK_NUMPAD4] = SDLK_KP4;
aryScanCodeToSDLKey[DIK_NUMPAD5] = SDLK_KP5;
aryScanCodeToSDLKey[DIK_NUMPAD6] = SDLK_KP6;
aryScanCodeToSDLKey[DIK_NUMPAD1] = SDLK_KP1;
aryScanCodeToSDLKey[DIK_NUMPAD2] = SDLK_KP2;
aryScanCodeToSDLKey[DIK_NUMPAD3] = SDLK_KP3;
aryScanCodeToSDLKey[DIK_NUMPAD0] = SDLK_KP0;
#endif
aryScanCodeToSDLKey[DIK_DECIMAL] = SDLK_KP_PERIOD;
aryScanCodeToSDLKey[DIK_F11] = SDLK_F11;
aryScanCodeToSDLKey[DIK_F12] = SDLK_F12;
aryScanCodeToSDLKey[DIK_F13] = SDLK_F13;
aryScanCodeToSDLKey[DIK_F14] = SDLK_F14;
aryScanCodeToSDLKey[DIK_F15] = SDLK_F15;
aryScanCodeToSDLKey[DIK_NUMPADEQUALS] = SDLK_KP_EQUALS;
aryScanCodeToSDLKey[DIK_NUMPADENTER] = SDLK_KP_ENTER;
aryScanCodeToSDLKey[DIK_RCONTROL] = SDLK_RCTRL;
aryScanCodeToSDLKey[DIK_DIVIDE] = SDLK_KP_DIVIDE;
#if defined(C_SDL2)
aryScanCodeToSDLKey[DIK_SYSRQ] = SDLK_PRINTSCREEN;
#else
aryScanCodeToSDLKey[DIK_SYSRQ] = SDLK_PRINT;
#endif
aryScanCodeToSDLKey[DIK_RMENU] = SDLK_RALT;
aryScanCodeToSDLKey[DIK_PAUSE] = SDLK_PAUSE;
aryScanCodeToSDLKey[DIK_HOME] = SDLK_HOME;
aryScanCodeToSDLKey[DIK_UP] = SDLK_UP;
aryScanCodeToSDLKey[DIK_PRIOR] = SDLK_PAGEUP;
aryScanCodeToSDLKey[DIK_LEFT] = SDLK_LEFT;
aryScanCodeToSDLKey[DIK_RIGHT] = SDLK_RIGHT;
aryScanCodeToSDLKey[DIK_END] = SDLK_END;
aryScanCodeToSDLKey[DIK_DOWN] = SDLK_DOWN;
aryScanCodeToSDLKey[DIK_NEXT] = SDLK_PAGEDOWN;
aryScanCodeToSDLKey[DIK_INSERT] = SDLK_INSERT;
aryScanCodeToSDLKey[DIK_DELETE] = SDLK_DELETE;
#if defined(C_SDL2)
aryScanCodeToSDLKey[DIK_LWIN] = SDLK_LGUI;
aryScanCodeToSDLKey[DIK_RWIN] = SDLK_RGUI;
#else
aryScanCodeToSDLKey[DIK_LWIN] = SDLK_LMETA;
aryScanCodeToSDLKey[DIK_RWIN] = SDLK_RMETA;
#endif
aryScanCodeToSDLKey[DIK_APPS] = SDLK_MENU;
#elif defined(C_SDL2)
aryScanCodeToSDLKey['1'] = SDLK_KP_1;
aryScanCodeToSDLKey['2'] = SDLK_KP_2;
aryScanCodeToSDLKey['3'] = SDLK_KP_3;
aryScanCodeToSDLKey['4'] = SDLK_KP_4;
aryScanCodeToSDLKey['5'] = SDLK_KP_5;
aryScanCodeToSDLKey['6'] = SDLK_KP_6;
aryScanCodeToSDLKey['7'] = SDLK_KP_7;
aryScanCodeToSDLKey['8'] = SDLK_KP_8;
aryScanCodeToSDLKey['9'] = SDLK_KP_9;
aryScanCodeToSDLKey['0'] = SDLK_KP_0;
aryScanCodeToSDLKey[0xFF] = SDLK_LALT;
#else
aryScanCodeToSDLKey['1'] = SDLK_KP1;
aryScanCodeToSDLKey['2'] = SDLK_KP2;
aryScanCodeToSDLKey['3'] = SDLK_KP3;
aryScanCodeToSDLKey['4'] = SDLK_KP4;
aryScanCodeToSDLKey['5'] = SDLK_KP5;
aryScanCodeToSDLKey['6'] = SDLK_KP6;
aryScanCodeToSDLKey['7'] = SDLK_KP7;
aryScanCodeToSDLKey['8'] = SDLK_KP8;
aryScanCodeToSDLKey['9'] = SDLK_KP9;
aryScanCodeToSDLKey['0'] = SDLK_KP0;
aryScanCodeToSDLKey[0xFF] = SDLK_LALT;
#endif
bScanCodeMapInited = true;
}
// Just in case, to keep us from entering an unexpected KB state
const size_t kPasteMinBufExtra = 4;
/// Sightly inefficient, but who cares
static void GenKBStroke(const UINT uiScanCode, const bool bDepressed, const SDLMod keymods)
{
const SDLKey sdlkey = aryScanCodeToSDLKey[uiScanCode & 0xFF];
if (sdlkey == SDLK_UNKNOWN)
return;
SDL_Event evntKeyStroke = { 0 };
evntKeyStroke.type = bDepressed ? SDL_KEYDOWN : SDL_KEYUP;
#if defined(C_SDL2)
evntKeyStroke.key.keysym.scancode = SDL_GetScancodeFromKey(sdlkey);
#else
evntKeyStroke.key.keysym.scancode = uiScanCode & 0xFF;
#endif
evntKeyStroke.key.keysym.sym = sdlkey;
evntKeyStroke.key.keysym.mod = keymods;
#if !defined(C_SDL2)
evntKeyStroke.key.keysym.unicode = 0;
#endif
evntKeyStroke.key.state = bDepressed ? SDL_PRESSED : SDL_RELEASED;
SDL_PushEvent(&evntKeyStroke);
}
bool PasteClipboardNext() {
if (strPasteBuffer.length() == 0)
return false;
if(clipboard_biospaste) {
if (strPasteBuffer[0]==13) {
KEYBOARD_AddKey(KBD_enter, true);
KEYBOARD_AddKey(KBD_enter, false);
} else
BIOS_AddKeyToBuffer(strPasteBuffer[0]<0?strPasteBuffer[0]&0xff:strPasteBuffer[0]);
strPasteBuffer = strPasteBuffer.substr(1, strPasteBuffer.length());
return true;
}
if (!bScanCodeMapInited)
PasteInitMapSCToSDLKey();
const char cKey = strPasteBuffer[0];
#if defined(WIN32) && (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
SHORT shVirKey = VkKeyScan(cKey); // If it fails then MapVirtK will also fail, so no bail yet
UINT uiScanCode = MapVirtualKey(LOBYTE(shVirKey), MAPVK_VK_TO_VSC);
if (uiScanCode)
{
const bool bModShift = ((shVirKey & 0x0100) != 0);
const bool bModCntrl = ((shVirKey & 0x0200) != 0);
const bool bModAlt = ((shVirKey & 0x0400) != 0);
const SDLMod sdlmModsOn = SDL_GetModState();
const bool bModShiftOn = ((sdlmModsOn & (KMOD_LSHIFT | KMOD_RSHIFT)) > 0);
const bool bModCntrlOn = ((sdlmModsOn & (KMOD_LCTRL | KMOD_RCTRL)) > 0);
const bool bModAltOn = ((sdlmModsOn & (KMOD_LALT | KMOD_RALT)) > 0);
const UINT uiScanCodeShift = MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC);
const UINT uiScanCodeCntrl = MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC);
const UINT uiScanCodeAlt = MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC);
const SDLMod sdlmMods = (SDLMod)((sdlmModsOn & ~(KMOD_LSHIFT | KMOD_RSHIFT |
KMOD_LCTRL | KMOD_RCTRL |
KMOD_LALT | KMOD_RALT)) |
(bModShiftOn ? KMOD_LSHIFT : 0) |
(bModCntrlOn ? KMOD_LCTRL : 0) |
(bModAltOn ? KMOD_LALT : 0));
/// \note Currently pasteing a character is a two step affair, because if
/// you do it too quickly DI can miss a key press/release.
// Could be made more efficient, but would require tracking of more state,
// so let's forgot that for now...
size_t sStrokesRequired = 2; // At least the key & up/down
if (bModShift != bModShiftOn) sStrokesRequired += 2; // To press/release Shift
if (bModCntrl != bModCntrlOn) sStrokesRequired += 2; // To press/release Control
if (bModAlt != bModAltOn) sStrokesRequired += 2; // To press/release Alt
/// \fixme Should check if key is already pressed or not so it can toggle press
/// but since we don't actually have any mappings from VK/SC to DI codes
/// (which SDL (can) use(s) internally as actually scancodes), we can't
/// actually check that ourselves, sadly...
if (KEYBOARD_BufferSpaceAvail() < (sStrokesRequired + kPasteMinBufExtra))
return false;
if (bModShift != bModShiftOn) GenKBStroke(uiScanCodeShift, !bModShiftOn, sdlmMods);
if (bModCntrl != bModCntrlOn) GenKBStroke(uiScanCodeCntrl, !bModCntrlOn, sdlmMods);
if (bModAlt != bModAltOn) GenKBStroke(uiScanCodeAlt, !bModAltOn, sdlmMods);
GenKBStroke(uiScanCode, true, sdlmMods);
GenKBStroke(uiScanCode, false, sdlmMods);
if (bModShift != bModShiftOn) GenKBStroke(uiScanCodeShift, bModShiftOn, sdlmMods);
if (bModCntrl != bModCntrlOn) GenKBStroke(uiScanCodeCntrl, bModCntrlOn, sdlmMods);
if (bModAlt != bModAltOn) GenKBStroke(uiScanCodeAlt, bModAltOn, sdlmMods);
//putchar(cKey); // For debugging dropped strokes
} else {
const UINT uiScanCodeAlt = MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC);
#else
{
//UINT uiScanCode = cKey; UNUSED
const UINT uiScanCodeAlt = 0xFF;
#endif
if (KEYBOARD_BufferSpaceAvail() < (10+kPasteMinBufExtra)) // For simplicity, we just mimic Alt+<3 digits>
return false;
#if !defined(WIN32) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
if (strPasteBuffer[0]==13) {
KEYBOARD_AddKey(KBD_enter, true);
KEYBOARD_AddKey(KBD_enter, false);
strPasteBuffer = strPasteBuffer.substr(1, strPasteBuffer.length());
return true;
}
#endif
const SDLMod sdlmModsOn = SDL_GetModState();
const bool bModShiftOn = ((sdlmModsOn & (KMOD_LSHIFT|KMOD_RSHIFT)) > 0);
const bool bModCntrlOn = ((sdlmModsOn & (KMOD_LCTRL|KMOD_RCTRL )) > 0);
const bool bModAltOn = ((sdlmModsOn&(KMOD_LALT|KMOD_RALT)) > 0);
const SDLMod sdlmMods = (SDLMod)((sdlmModsOn&~(KMOD_LSHIFT|KMOD_RSHIFT|KMOD_LCTRL|KMOD_RCTRL|KMOD_LALT|KMOD_RALT)) |
(bModShiftOn ? KMOD_LSHIFT : 0) |
(bModCntrlOn ? KMOD_LCTRL : 0) |
(bModAltOn ? KMOD_LALT : 0));
if (!bModAltOn) // Alt down if not already down
GenKBStroke(uiScanCodeAlt, true, sdlmMods);
uint8_t ansiVal = cKey;
unsigned int ct = 0;
for (int i = 100; i; i /= 10) {
int numKey = ansiVal/i; // High digit of Alt+ASCII number combination
if (!numKey) ct++;
ansiVal %= i;
#if defined(WIN32) && (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
UINT uiScanCode = MapVirtualKey(numKey+VK_NUMPAD0, MAPVK_VK_TO_VSC);
#else
UINT uiScanCode = numKey+'0';
#endif
GenKBStroke(uiScanCode, true, sdlmMods);
GenKBStroke(uiScanCode, false, sdlmMods);
}
GenKBStroke(uiScanCodeAlt, false, sdlmMods); // Alt up
if (ct%2) {
GenKBStroke(uiScanCodeAlt, true, sdlmMods);
#if defined(WIN32) && (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
UINT uiScanCode = MapVirtualKey(0+VK_NUMPAD0, MAPVK_VK_TO_VSC);
#else
UINT uiScanCode = 0+'0';
#endif
GenKBStroke(uiScanCode, true, sdlmMods);
GenKBStroke(uiScanCode, false, sdlmMods);
GenKBStroke(uiScanCodeAlt, false, sdlmMods);
}
if (bModAltOn) // Alt down if is was already down
GenKBStroke(uiScanCodeAlt, true, sdlmMods);
}
// Pop head. Could be made more efficient, but this is neater.
strPasteBuffer = strPasteBuffer.substr(1, strPasteBuffer.length()); // technically -1, but it clamps by itself anyways...
return true;
}
// added emendelson from dbDos; improved by Wengier
#if defined(WIN32) && !defined(C_SDL2) && !defined(__MINGW32__)
void PasteClipboard(bool bPressed)
{
if (!bPressed) return;
SDL_SysWMinfo wmiInfo;
SDL_VERSION(&wmiInfo.version);
if (SDL_GetWMInfo(&wmiInfo) != 1||!OpenClipboard(wmiInfo.window)) return;
if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) {CloseClipboard();return;}
HANDLE hContents = GetClipboardData(CF_UNICODETEXT);
if (!hContents) {CloseClipboard();return;}
uint16_t *szClipboard = (uint16_t *)GlobalLock(hContents);
if (szClipboard)
{
clipSize=0;
bool ret=Unicode2Ascii(szClipboard);
unsigned long j=0;
for (size_t i = 0; i < clipSize; ++i) {
if (clipAscii[i] == 9) j++;
else if (ret&&clipAscii[i]==0x0A&&(i==0||clipAscii[i-1]!=0x0D)) clipAscii[i]=0x0D;
}
if (ret&&clipAscii[clipSize-1]==0xD) clipAscii[--clipSize]=0;
// Create a copy of the string, and filter out Linefeed characters (ASCII '10')
char* szFilteredText = reinterpret_cast<char*>(alloca(clipSize + j*3 + 1));
char* szFilterNextChar = szFilteredText;
for (size_t i = 0; i < clipSize; ++i)
if (clipAscii[i] == 9) // Tab to spaces
for (int k=0; k<4; k++) {
*szFilterNextChar = ' ';
++szFilterNextChar;
}
else if (clipAscii[i] != 0x0A) // Skip linefeeds
{
*szFilterNextChar = clipAscii[i];
++szFilterNextChar;
}
*szFilterNextChar = '\0'; // Cap it.
strPasteBuffer.append(szFilteredText);
GlobalUnlock(hContents);
clipSize=0;
}
CloseClipboard();
}
/// TODO: add menu items here
#else // end emendelson from dbDOS; improved by Wengier
#if defined(WIN32) // SDL2, MinGW / Added by Wengier
void PasteClipboard(bool bPressed) {
if (!bPressed||!OpenClipboard(NULL)) return;
if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) {CloseClipboard();return;}
HANDLE hContents = GetClipboardData(CF_UNICODETEXT);
if (!hContents) {CloseClipboard();return;}
uint16_t *szClipboard = (uint16_t *)GlobalLock(hContents);
if (szClipboard)
{
clipSize=0;
bool ret=Unicode2Ascii(szClipboard);
unsigned long j=0;
for (size_t i = 0; i < clipSize; ++i) {
if (clipAscii[i] == 9) j++;
else if (ret&&clipAscii[i]==0xA&&(i==0||clipAscii[i-1]!=0xD)) clipAscii[i]=0xD;
}
if (ret&&clipAscii[clipSize-1]==0xD) clipAscii[--clipSize]=0;
char* szFilteredText = reinterpret_cast<char*>(alloca(clipSize + j*3 + 1));
char* szFilterNextChar = szFilteredText;
for (size_t i = 0; i < clipSize; ++i)
if (clipAscii[i] == 9) // Tab to spaces
for (int k=0; k<4; k++) {
*szFilterNextChar = ' ';
++szFilterNextChar;
}
else if (clipAscii[i] != 0x0A) // Skip linefeeds
{
*szFilterNextChar = clipAscii[i];
++szFilterNextChar;
}
*szFilterNextChar = '\0'; // Cap it.
strPasteBuffer.append(szFilteredText);
GlobalUnlock(hContents);
clipSize=0;
}
CloseClipboard();
}
#elif defined(C_SDL2) || defined(MACOSX)
typedef char host_cnv_char_t;
char *CodePageHostToGuest(const host_cnv_char_t *s);
void PasteClipboard(bool bPressed) {
if (!bPressed) return;
char *text;
#if defined(C_SDL2)
text = SDL_GetClipboardText();
#else
std::string clip="";
GetClipboard(&clip);
text = new char[clip.size()+1];
strcpy(text, clip.c_str());
#endif
if (text==NULL) return;
std::string result="", pre="";
morelen=true;
for (unsigned int i=0; i<strlen(text); i++) {
if (swapad&&text[i]==0x0A&&(i==0||text[i-1]!=0x0D)) text[i]=0x0D;
if (text[i]==9) result+=" ";
else if (text[i]<0) {
char c=text[i];
int n=1;
if ((c & 0xe0) == 0xc0) n=2;
else if ((c & 0xf0) == 0xe0) n=3;
else if ((c & 0xf8) == 0xf0) n=4;
pre="";
bool exit=false;
for (int k=0; k<n; k++) {
if (n>2&&i>=strlen(text)) {exit=true;break;}
else if (i>=strlen(text)) {i++;break;}
if (text[i]>=0) {exit=true;break;}
pre+=std::string(1, text[i]);
i++;
}
if (exit) continue;
const char* asc = CodePageHostToGuest(pre.c_str());
result+=asc!=NULL?std::string(asc):(n>2?"":pre);
i--;
} else {
const char* asc = CodePageHostToGuest(std::string(1, text[i]).c_str());
result+=asc != NULL?std::string(asc):std::string(1, text[i]);
}
}
morelen=false;
delete text;
strPasteBuffer.append(result.c_str());
}
#elif defined(LINUX) && C_X11
#include <X11/Xlib.h>
#include <X11/Xatom.h>
typedef char host_cnv_char_t;
char *CodePageHostToGuest(const host_cnv_char_t *s);
void paste_utf8_prop(Display *dpy, Window w, Atom p)
{
Atom da, incr, type;
int di;
unsigned long size, dul;
unsigned char *prop_ret = NULL;
XGetWindowProperty(dpy, w, p, 0, 0, False, AnyPropertyType, &type, &di, &dul, &size, &prop_ret);
XFree(prop_ret);
incr = XInternAtom(dpy, "INCR", False);
if (type == incr) return;
XGetWindowProperty(dpy, w, p, 0, size, False, AnyPropertyType, &da, &di, &dul, &dul, &prop_ret);
char *text=(char *)prop_ret;
std::string result="", pre="";
for (unsigned int i=0; i<strlen(text); i++) {
if (swapad&&text[i]==0x0A&&(i==0||text[i-1]!=0x0D)) text[i]=0x0D;
if (text[i]==9) result+=" ";
else if (swapad&&text[i]==0x0A) continue;
else if (text[i]<0) {
char c=text[i];
int n=1;
if ((c & 0xe0) == 0xc0) n=2;
else if ((c & 0xf0) == 0xe0) n=3;
else if ((c & 0xf8) == 0xf0) n=4;
pre="";
bool exit=false;
for (int k=0; k<n; k++) {
if (n>2&&i>=strlen(text)) {exit=true;break;}
else if (i>=strlen(text)) {i++;break;}
if (text[i]>=0) {exit=true;break;}
pre+=std::string(1, text[i]);
i++;
}
if (exit) continue;
const char* asc = CodePageHostToGuest(pre.c_str());
result+=asc!=NULL?std::string(asc):(n>2?"":pre);
i--;
} else {
const char* asc = CodePageHostToGuest(std::string(1, text[i]).c_str());
result+=asc != NULL?std::string(asc):std::string(1, text[i]);
}
}
strPasteBuffer.append(result.c_str());
fflush(stdout);
XFree(prop_ret);
XDeleteProperty(dpy, w, p);
}
void PasteClipboard(bool bPressed) {
if (!bPressed) return;
Display *dpy;
Window owner, target_window, root;
int screen;
Atom sel, target_property, utf8;
XEvent ev;
XSelectionEvent *sev;
dpy = XOpenDisplay(NULL);
if (!dpy) return;
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
sel = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
owner = XGetSelectionOwner(dpy, sel);
if (owner == None) return;
target_window = XCreateSimpleWindow(dpy, root, -10, -10, 1, 1, 0, 0, 0);
target_property = XInternAtom(dpy, "PENGUIN", False);
XConvertSelection(dpy, sel, utf8, target_property, target_window,
CurrentTime);
for (;;) {
XNextEvent(dpy, &ev);
switch (ev.type) {
case SelectionNotify:
sev = (XSelectionEvent*)&ev.xselection;
if (sev->property == None) return;
else {
paste_utf8_prop(dpy, target_window, target_property);
return;
}
break;
}
}
}
#else
void PasteClipboard(bool bPressed) {
if (!bPressed) return;
// stub
}
#endif
#endif
extern uint16_t baselen;
extern std::list<uint16_t> bdlist;
#ifdef WIN32
void CopyClipboard(int all) {
uint16_t len=0;
const char* text = (char *)(all==2?Mouse_GetSelected(0,0,(int)(currentWindowWidth-1-sdl.clip.x),(int)(currentWindowHeight-1-sdl.clip.y),(int)(currentWindowWidth-sdl.clip.x),(int)(currentWindowHeight-sdl.clip.y), &len):(all==1?Mouse_GetSelected(selscol, selsrow, selecol, selerow, -1, -1, &len):Mouse_GetSelected(mouse_start_x-sdl.clip.x,mouse_start_y-sdl.clip.y,mouse_end_x-sdl.clip.x,mouse_end_y-sdl.clip.y,sdl.clip.w,sdl.clip.h, &len)));
if (OpenClipboard(NULL)&&EmptyClipboard()) {
std::wstring result=L"";
std::istringstream iss(text);
uint16_t* wch, temp[4096];
morelen=true;
baselen=0;
for (std::string token; std::getline(iss, token); ) {
if (CodePageGuestToHostUTF16(temp,token.c_str())) {
result+=(wchar_t *)temp;
} else {
int reqsize = MultiByteToWideChar(dos.loaded_codepage==808?866:(dos.loaded_codepage==872?855:(dos.loaded_codepage==951?950:dos.loaded_codepage)), 0, token.c_str(), token.size()+1, NULL, 0);
if (reqsize>0) {
wch = new uint16_t[reqsize+1];
if (MultiByteToWideChar(dos.loaded_codepage==808?866:(dos.loaded_codepage==872?855:(dos.loaded_codepage==951?950:dos.loaded_codepage)), 0, token.c_str(), token.size()+1, (LPWSTR)wch, reqsize)==reqsize) {
result+=(wchar_t *)wch;
delete[] wch;
continue;
} else
delete[] wch;
}
wch = new uint16_t[token.size()+1];
mbstowcs((wchar_t *)wch, token.c_str(), token.size()+1);
result+=(wchar_t *)wch;
delete[] wch;
}
result+=std::wstring(1, '\r')+std::wstring(1, '\n');
baselen+=token.size()+2;
}
if (baselen>1) {
result.pop_back();
result.pop_back();
baselen-=2;
}
morelen=false;
baselen=0;
bdlist={};
HGLOBAL clipbuffer = GlobalAlloc(GMEM_DDESHARE, (result.size()+1)*sizeof(wchar_t));
LPWSTR buffer = static_cast<LPWSTR>(GlobalLock(clipbuffer));
if (buffer!=NULL) {
for (unsigned int i=0; i<result.size(); i++) buffer[i]=(wchar_t)result[i];
GlobalUnlock(clipbuffer);
SetClipboardData(CF_UNICODETEXT,clipbuffer);
}
}
CloseClipboard();
}
#elif defined(C_SDL2) || defined(MACOSX)
bool CodePageGuestToHostUTF8(char *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/);
void CopyClipboard(int all) {
uint16_t len=0;
char* text = (char *)(all==2?Mouse_GetSelected(0,0,currentWindowWidth-1-sdl.clip.x,currentWindowHeight-1-sdl.clip.y,(int)(currentWindowWidth-sdl.clip.x),(int)(currentWindowHeight-sdl.clip.y), &len):(all==1?Mouse_GetSelected(selscol, selsrow, selecol, selerow, -1, -1, &len):Mouse_GetSelected(mouse_start_x-sdl.clip.x,mouse_start_y-sdl.clip.y,mouse_end_x-sdl.clip.x,mouse_end_y-sdl.clip.y,sdl.clip.w,sdl.clip.h, &len)));
std::string result="";
std::istringstream iss(text);
char temp[4096];
morelen=true;
baselen=0;
for (std::string token; std::getline(iss, token); ) {
if (CodePageGuestToHostUTF8(temp,token.c_str()))
result+=temp;
else
result+=token;
result+=std::string(1, 10);
baselen+=token.size()+1;
}
morelen=false;
baselen=0;
bdlist={};
if (result.size()&&result.back()==10) result.pop_back();
#if defined(C_SDL2)
SDL_SetClipboardText(result.c_str());
#else
SetClipboard(result);
#endif
}
#endif
void PasteClipStop(bool bPressed) {
if (!bPressed) return;
strPasteBuffer = "";
}
#if defined(WIN32) || defined(MACOSX) || defined(C_SDL2)
bool isModifierApplied() {
return direct_mouse_clipboard || !strcmp(modifier,"none") ||
((!strcmp(modifier,"ctrl") || !strcmp(modifier,"lctrl")) && sdl.lctrlstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"ctrl") || !strcmp(modifier,"rctrl")) && sdl.rctrlstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"alt") || !strcmp(modifier,"lalt")) && sdl.laltstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"alt") || !strcmp(modifier,"ralt")) && sdl.raltstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"shift") || !strcmp(modifier,"lshift")) && sdl.lshiftstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"shift") || !strcmp(modifier,"rshift")) && sdl.rshiftstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"ctrlalt") || !strcmp(modifier,"lctrlalt")) && sdl.lctrlstate==SDL_KEYDOWN && sdl.laltstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"ctrlalt") || !strcmp(modifier,"rctrlalt")) && sdl.rctrlstate==SDL_KEYDOWN && sdl.raltstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"ctrlshift") || !strcmp(modifier,"lctrlshift")) && sdl.lctrlstate==SDL_KEYDOWN && sdl.lshiftstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"ctrlshift") || !strcmp(modifier,"rctrlshift")) && sdl.rctrlstate==SDL_KEYDOWN && sdl.rshiftstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"altshift") || !strcmp(modifier,"laltshift")) && sdl.laltstate==SDL_KEYDOWN && sdl.lshiftstate==SDL_KEYDOWN) ||
((!strcmp(modifier,"altshift") || !strcmp(modifier,"raltshift")) && sdl.raltstate==SDL_KEYDOWN && sdl.rshiftstate==SDL_KEYDOWN);
}
void ClipKeySelect(int sym) {
if (sym==SDLK_ESCAPE) {
if (mbutton==4 && selsrow>-1 && selscol>-1) {
Mouse_Select(selscol, selsrow, selmark?selecol:selscol, selmark?selerow:selsrow, -1, -1, false);
selmark = false;
selsrow = selscol = selerow = selecol = -1;
} else if (mouse_start_x >= 0 && mouse_start_y >= 0 && fx >= 0 && fy >= 0) {
Mouse_Select(mouse_start_x-sdl.clip.x,mouse_start_y-sdl.clip.y,fx-sdl.clip.x,fy-sdl.clip.y,sdl.clip.w,sdl.clip.h, false);
mouse_start_x = mouse_start_y = -1;
mouse_end_x = mouse_end_y = -1;
fx = fy = -1;
}
return;
}
if (mbutton!=4 || (CurMode->type!=M_TEXT && !IS_DOSV && !IS_PC98_ARCH)) return;
if (sym==SDLK_HOME) {
if (selsrow==-1 || selscol==-1) {
int p=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
selscol = CURSOR_POS_COL(p);
selsrow = CURSOR_POS_ROW(p);
} else {
if (selsrow>-1 && selscol>-1) Mouse_Select(selscol, selsrow, selmark?selecol:selscol, selmark?selerow:selsrow, -1, -1, false);
if (selmark) {
selscol = selecol;
selsrow = selerow;
}
}
selmark = true;
selecol = selscol;
selerow = selsrow;
Mouse_Select(selscol, selsrow, selecol, selerow, -1, -1, true);
} else if (sym==SDLK_END) {
if (selmark) {
if (selsrow>-1 && selscol>-1 && selerow > -1 && selecol > -1) {
Mouse_Select(selscol, selsrow, selecol, selerow, -1, -1, false);
CopyClipboard(1);
}
selmark = false;
selsrow = selscol = selerow = selecol = -1;
}
} else if (sym==SDLK_LEFT || sym==SDLK_RIGHT || sym==SDLK_UP || sym==SDLK_DOWN) {
if (selsrow==-1 || selscol==-1) {
int p=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
selscol = CURSOR_POS_COL(p);
selsrow = CURSOR_POS_ROW(p);
selerow = selecol = -1;
selmark = false;
} else
Mouse_Select(selscol, selsrow, selmark?selecol:selscol, selmark?selerow:selsrow, -1, -1, false);
if (sym==SDLK_LEFT && (selmark?selecol:selscol)>0) (selmark?selecol:selscol)--;
else if (sym==SDLK_RIGHT && (selmark?selecol:selscol)<(IS_PC98_ARCH?80:real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS))-1) (selmark?selecol:selscol)++;
else if (sym==SDLK_UP && (selmark?selerow:selsrow)>0) (selmark?selerow:selsrow)--;
else if (sym==SDLK_DOWN && (selmark?selerow:selsrow)<(IS_PC98_ARCH?(real_readb(0x60,0x113)&0x01?25:20)-1:(IS_EGAVGA_ARCH?real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS):24))) (selmark?selerow:selsrow)++;
Mouse_Select(selscol, selsrow, selmark?selecol:selscol, selmark?selerow:selsrow, -1, -1, true);
}
}
#endif

View File

@ -1,2 +1,254 @@
// common routines reused in different outputs go there
/*
* Copyright (C) 2002-2021 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "dosbox.h"
#include "video.h"
#include "setup.h"
#include "jfont.h"
#include "cpu.h"
#include "sdlmain.h"
#include "control.h"
#include "render.h"
#include "logging.h"
#if defined(WIN32)
#include "resource.h"
#endif
#if C_DIRECT3D
void d3d_init(void);
#endif
#if defined(USE_TTF)
void resetFontSize();
#endif
void UpdateOverscanMenu(void);
extern int initgl;
extern bool rtl, gbk, chinasea, isVirtualBox;
std::string GetDefaultOutput() {
static std::string output = "surface";
#if defined(USE_TTF)
# if 0 /* TODO: If someone wants to compile DOSBox-X to default to TTF, change this to "# if 1" or "# if defined(...)" here */
std::string mtype(static_cast<Section_prop *>(control->GetSection("dosbox"))->Get_string("machine"));
if (mtype.substr(0, 3) == "vga" || mtype.substr(0, 4) == "svga" || mtype.substr(0, 4) == "vesa" || mtype.substr(0, 4) == "pc98")
return "ttf";
# endif
#endif
#if defined(WIN32)
# if defined(HX_DOS)
output = "surface"; /* HX-DOS should stick to surface */
# elif defined(__MINGW32__) && !(C_DIRECT3D) && !defined(C_SDL2)
/* NTS: OpenGL output never seems to work in VirtualBox under Windows XP */
output = isVirtualBox ? "surface" : "opengl"; /* MinGW builds do not yet have Direct3D */
# elif C_DIRECT3D
output = "direct3d";
# elif C_OPENGL && !defined(C_SDL2)
output = isVirtualBox ? "surface" : "opengl";
# elif C_OPENGL
output = "opengl";
# else
output = "surface";
# endif
#elif defined(C_OPENGL) && !(defined(LINUX) && !defined(C_SDL2)) && !(defined(MACOSX) && defined(C_SDL2))
/* NTS: Lately, especially on Macbooks with Retina displays, OpenGL gives better performance
than the CG bitmap-based "surface" output.
On my dev system, "top" shows a 20% CPU load doing 1:1 CG Bitmap output to the screen
on a High DPI setup, while ignoring High DPI and rendering through Cocoa at 2x size
pegs the CPU core DOSBox-X is running on at 100% and emulation stutters.
So for the best experience, default to OpenGL.
Note that "surface" yields good performance with SDL2 and macOS because SDL2 doesn't
use the CGBitmap system, it uses OpenGL or Metal underneath automatically. */
output = "opengl";
#else
output = "surface";
#endif
return output;
}
void change_output(int output) {
GFX_Stop();
Section * sec = control->GetSection("sdl");
Section_prop * section=static_cast<Section_prop *>(sec);
sdl.overscan_width=(unsigned int)section->Get_int("overscan");
UpdateOverscanMenu();
sdl.desktop.isperfect = false; /* Reset before selection */
switch (output) {
case 0:
OUTPUT_SURFACE_Select();
break;
case 1:
OUTPUT_SURFACE_Select();
break;
case 2: /* do nothing */
break;
case 3:
#if C_OPENGL
change_output(2);
OUTPUT_OPENGL_Select(GLBilinear);
#endif
break;
case 4:
#if C_OPENGL
change_output(2);
OUTPUT_OPENGL_Select(GLNearest);
#endif
break;
case 5:
#if C_OPENGL
change_output(2);
OUTPUT_OPENGL_Select(GLPerfect);
#endif
break;
#if C_DIRECT3D
case 6:
OUTPUT_DIRECT3D_Select();
d3d_init();
break;
#endif
case 7:
break;
case 8:
// do not set want_type
break;
case 9:
#if C_DIRECT3D
if (sdl.desktop.want_type == SCREEN_DIRECT3D) {
OUTPUT_DIRECT3D_Select();
d3d_init();
}
#endif
break;
#if defined(USE_TTF)
case 10:
OUTPUT_TTF_Select();
case 11:
sdl.desktop.want_type = SCREEN_TTF;
ttf.inUse = true;
break;
#endif
default:
LOG_MSG("SDL: Unsupported output device %d, switching back to surface",output);
OUTPUT_SURFACE_Select();
break;
}
#if C_OPENGL
if (sdl.desktop.want_type != SCREEN_OPENGL) mainMenu.get_item("load_glsl_shader").enable(false).refresh_item(mainMenu);
#endif
#if C_DIRECT3D
if (sdl.desktop.want_type != SCREEN_DIRECT3D) mainMenu.get_item("load_d3d_shader").enable(false).refresh_item(mainMenu);
#endif
#if defined(USE_TTF)
if (sdl.desktop.want_type != SCREEN_TTF) {
mainMenu.get_item("load_ttf_font").enable(false).refresh_item(mainMenu);
resetreq = false;
ttf.inUse = false;
}
#endif
const char* windowresolution=section->Get_string("windowresolution");
if (windowresolution && *windowresolution)
{
char res[100];
safe_strncpy( res,windowresolution, sizeof( res ));
windowresolution = lowcase (res);//so x and X are allowed
if (strcmp(windowresolution,"original"))
{
if (output == 0)
{
std::string tmp("windowresolution=original");
sec->HandleInputline(tmp);
}
}
}
res_init();
if (sdl.draw.callback)
(sdl.draw.callback)( GFX_CallBackReset );
#ifdef C_OPENGL
mainMenu.get_item("load_glsl_shader").enable(sdl.desktop.want_type==SCREEN_OPENGL&&initgl==2).refresh_item(mainMenu);
#endif
#ifdef C_DIRECT3D
mainMenu.get_item("load_d3d_shader").enable(sdl.desktop.want_type==SCREEN_DIRECT3D).refresh_item(mainMenu);
#endif
#ifdef USE_TTF
mainMenu.get_item("load_ttf_font").enable(sdl.desktop.want_type==SCREEN_TTF).refresh_item(mainMenu);
#endif
#if defined(USE_TTF)
if ((output==9||output==10)&&ttf.inUse) {
resetFontSize();
resetreq = true;
}
#if defined(WIN32) && !defined(HX_DOS)
HMENU sysmenu = GetSystemMenu(GetHWND(), TRUE);
if (sysmenu != NULL) {
EnableMenuItem(sysmenu, ID_WIN_SYSMENU_TTFINCSIZE, MF_BYCOMMAND|(TTF_using()?MF_ENABLED:MF_DISABLED));
EnableMenuItem(sysmenu, ID_WIN_SYSMENU_TTFDECSIZE, MF_BYCOMMAND|(TTF_using()?MF_ENABLED:MF_DISABLED));
}
#endif
mainMenu.get_item("mapper_incsize").enable(TTF_using()).refresh_item(mainMenu);
mainMenu.get_item("mapper_decsize").enable(TTF_using()).refresh_item(mainMenu);
mainMenu.get_item("ttf_resetcolor").enable(TTF_using()).refresh_item(mainMenu);
mainMenu.get_item("ttf_showbold").enable(TTF_using()).check(showbold).refresh_item(mainMenu);
mainMenu.get_item("ttf_showital").enable(TTF_using()).check(showital).refresh_item(mainMenu);
mainMenu.get_item("ttf_showline").enable(TTF_using()).check(showline).refresh_item(mainMenu);
mainMenu.get_item("ttf_showsout").enable(TTF_using()).check(showsout).refresh_item(mainMenu);
mainMenu.get_item("ttf_wpno").enable(TTF_using()).check(!wpType).refresh_item(mainMenu);
mainMenu.get_item("ttf_wpwp").enable(TTF_using()).check(wpType==1).refresh_item(mainMenu);
mainMenu.get_item("ttf_wpws").enable(TTF_using()).check(wpType==2).refresh_item(mainMenu);
mainMenu.get_item("ttf_wpxy").enable(TTF_using()).check(wpType==3).refresh_item(mainMenu);
mainMenu.get_item("ttf_wpfe").enable(TTF_using()).check(wpType==4).refresh_item(mainMenu);
mainMenu.get_item("ttf_blinkc").enable(TTF_using()).check(blinkCursor>-1).refresh_item(mainMenu);
mainMenu.get_item("ttf_right_left").enable(TTF_using()).check(rtl).refresh_item(mainMenu);
#if C_PRINTER
mainMenu.get_item("ttf_printfont").enable(TTF_using()).check(printfont).refresh_item(mainMenu);
#endif
mainMenu.get_item("ttf_dbcs_sbcs").enable(TTF_using()&&!IS_PC98_ARCH&&!IS_JEGA_ARCH&&enable_dbcs_tables).check(dbcs_sbcs||IS_PC98_ARCH||IS_JEGA_ARCH).refresh_item(mainMenu);
mainMenu.get_item("ttf_autoboxdraw").enable(TTF_using()&&!IS_PC98_ARCH&&!IS_JEGA_ARCH&&enable_dbcs_tables).check(autoboxdraw||IS_PC98_ARCH||IS_JEGA_ARCH).refresh_item(mainMenu);
mainMenu.get_item("ttf_halfwidthkana").enable(TTF_using()&&!IS_PC98_ARCH&&!IS_JEGA_ARCH&&enable_dbcs_tables).check(halfwidthkana||IS_PC98_ARCH||IS_JEGA_ARCH).refresh_item(mainMenu);
mainMenu.get_item("ttf_extcharset").enable(TTF_using()&&!IS_PC98_ARCH&&!IS_JEGA_ARCH&&enable_dbcs_tables).check(dos.loaded_codepage==936?gbk:(dos.loaded_codepage==950||dos.loaded_codepage==951?chinasea:gbk&&chinasea)).refresh_item(mainMenu);
#endif
if (output != 7) GFX_SetTitle((int32_t)(CPU_CycleAutoAdjust?CPU_CyclePercUsed:CPU_CycleMax),-1,-1,false);
GFX_LogSDLState();
UpdateWindowDimensions();
}
void OutputSettingMenuUpdate(void) {
mainMenu.get_item("output_surface").check(sdl.desktop.want_type == SCREEN_SURFACE).refresh_item(mainMenu);
#if C_DIRECT3D
mainMenu.get_item("output_direct3d").check(sdl.desktop.want_type == SCREEN_DIRECT3D).refresh_item(mainMenu);
#endif
#if C_OPENGL
mainMenu.get_item("output_opengl").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLBilinear).refresh_item(mainMenu);
mainMenu.get_item("output_openglnb").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLNearest).refresh_item(mainMenu);
mainMenu.get_item("output_openglpp").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLPerfect).refresh_item(mainMenu);
#endif
#if defined(USE_TTF)
mainMenu.get_item("output_ttf").check(sdl.desktop.want_type == SCREEN_TTF).refresh_item(mainMenu);
#endif
}

View File

@ -87,12 +87,12 @@ int wpBG = -1;
int wpFG = 7;
int lastset = 0;
int lastfontsize = 0;
int outputswitch = -1;
int switchoutput = -1;
int oldblinkc = -1;
static unsigned long ttfSize = sizeof(DOSBoxTTFbi), ttfSizeb = 0, ttfSizei = 0, ttfSizebi = 0;
static void * ttfFont = DOSBoxTTFbi, * ttfFontb = NULL, * ttfFonti = NULL, * ttfFontbi = NULL;
extern int posx, posy, switchoutput, eurAscii, NonUserResizeCounter;
extern int posx, posy, eurAscii, NonUserResizeCounter;
extern bool rtl, gbk, chinasea, force_conversion, blinking;
extern uint8_t ccount;
extern uint16_t cpMap[512], cpMap_PC98[256];

View File

@ -1351,6 +1351,7 @@ for /d %i in ($(SolutionDir)\..\contrib\translations\*) do copy %i "$(OutputPath
<ClCompile Include="..\src\aviwriter\ksdataformat.cpp" />
<ClCompile Include="..\src\libs\mt32\LA32Ramp.cpp" />
<ClCompile Include="..\src\libs\mt32\LA32WaveGenerator.cpp" />
<ClCompile Include="..\src\gui\menu_callback.cpp" />
<ClCompile Include="..\src\gui\menu.cpp" />
<ClCompile Include="..\src\gui\midi.cpp" />
<ClCompile Include="..\src\libs\mt32\Part.cpp" />
@ -1477,6 +1478,7 @@ for /d %i in ($(SolutionDir)\..\contrib\translations\*) do copy %i "$(OutputPath
<ClCompile Include="..\src\ints\xms.cpp" />
<ClCompile Include="..\src\libs\gui_tk\gui_tk.cpp" />
<ClCompile Include="..\src\libs\porttalk\porttalk.cpp" />
<ClCompile Include="..\src\misc\clipboard.cpp" />
<ClCompile Include="..\src\misc\cross.cpp" />
<ClCompile Include="..\src\misc\ethernet.cpp" />
<ClCompile Include="..\src\misc\messages.cpp" />

View File

@ -348,6 +348,9 @@
<ClCompile Include="..\src\fpu\fpu.cpp">
<Filter>Sources\fpu</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\menu_callback.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
<ClCompile Include="..\src\gui\menu.cpp">
<Filter>Sources\gui</Filter>
</ClCompile>
@ -594,6 +597,9 @@
<ClCompile Include="..\src\ints\ems.cpp">
<Filter>Sources\ints</Filter>
</ClCompile>
<ClCompile Include="..\src\ints\int_dosv.cpp">
<Filter>Sources\ints</Filter>
</ClCompile>
<ClCompile Include="..\src\ints\int10.cpp">
<Filter>Sources\ints</Filter>
</ClCompile>
@ -639,6 +645,9 @@
<ClCompile Include="..\src\libs\porttalk\porttalk.cpp">
<Filter>Sources\libs\porttalk</Filter>
</ClCompile>
<ClCompile Include="..\src\misc\clipboard.cpp">
<Filter>Sources\misc</Filter>
</ClCompile>
<ClCompile Include="..\src\misc\cross.cpp">
<Filter>Sources\misc</Filter>
</ClCompile>
@ -660,6 +669,9 @@
<ClCompile Include="..\src\misc\programs.cpp">
<Filter>Sources\misc</Filter>
</ClCompile>
<ClCompile Include="..\src\misc\savestates.cpp">
<Filter>Sources\misc</Filter>
</ClCompile>
<ClCompile Include="..\src\misc\setup.cpp">
<Filter>Sources\misc</Filter>
</ClCompile>
@ -1575,12 +1587,6 @@
<ClCompile Include="..\src\libs\decoders\internal\opus\silk\debug_silk.c">
<Filter>Sources\libs\decoder</Filter>
</ClCompile>
<ClCompile Include="..\src\misc\savestates.cpp">
<Filter>Sources\misc</Filter>
</ClCompile>
<ClCompile Include="..\src\ints\int_dosv.cpp">
<Filter>Sources\ints</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\aviwriter\avi.h">