diff --git a/src/win/mingw/Makefile.MinGW b/src/win/mingw/Makefile.MinGW index 9f95da9..3cf02f8 100644 --- a/src/win/mingw/Makefile.MinGW +++ b/src/win/mingw/Makefile.MinGW @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the MinGW32 environment. # -# Version: @(#)Makefile.mingw 1.0.42 2018/05/09 +# Version: @(#)Makefile.mingw 1.0.43 2018/05/10 # # Author: Fred N. van Kempen, # @@ -490,13 +490,14 @@ CXXFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ ######################################################################### # Create the (final) list of objects to build. # ######################################################################### -MAINOBJ := pc.o config.o misc.o \ - random.o timer.o io.o dma.o nmi.o pic.o pit.o ppi.o \ - pci.o mca.o mcr.o mem.o memregs.o rom.o rom_load.o \ - device.o nvr.o nvr_at.o nvr_ps2.o $(VNCOBJ) $(RDPOBJ) +MAINOBJ := pc.o config.o misc.o random.o timer.o io.o mem.o \ + rom.o rom_load.o device.o nvr.o $(VNCOBJ) $(RDPOBJ) UIOBJ += ui_main.o ui_new_floppy.o ui_stbar.o ui_vidapi.o +SYSOBJ := dma.o nmi.o pic.o pit.o ppi.o pci.o mca.o mcr.o \ + memregs.o nvr_at.o nvr_ps2.o + INTELOBJ := intel.o \ intel_flash.o \ intel_sio.o \ @@ -637,8 +638,8 @@ PLATOBJ += win_crashdump.o endif -OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ - $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ +OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(SYSOBJ) $(DEVOBJ) \ + $(INTELOBJ) $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ $(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ $(UIOBJ) $(PLATOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) ifdef EXOBJ @@ -664,10 +665,6 @@ else @echo $< @$(CPP) $(CXXFLAGS) -c $< -%.int: %.c - @echo $< - @$(PREPROC) $(OPTS) $< >$@ - %.d: %.c $(wildcard $*.d) @echo $< @$(CC) $(CFLAGS) $(DEPS) -E $< >NUL diff --git a/src/win/msvc/Makefile.VC b/src/win/msvc/Makefile.VC index dd07cfb..5f88a23 100644 --- a/src/win/msvc/Makefile.VC +++ b/src/win/msvc/Makefile.VC @@ -8,7 +8,7 @@ # # Makefile for Windows using Visual Studio 2015. # -# Version: @(#)Makefile.VC 1.0.29 2018/05/09 +# Version: @(#)Makefile.VC 1.0.30 2018/05/10 # # Author: Fred N. van Kempen, # @@ -89,6 +89,9 @@ endif ifndef USB USB := n endif +ifndef SDL + SDL := n +endif ifndef VNC VNC := n endif @@ -362,31 +365,64 @@ MUNTOBJ := midi_mt32.obj \ Tables.obj TVA.obj TVF.obj TVP.obj sha1.obj c_interface.obj endif +ifeq ($(SDL), y) + OPTS += -DUSE_SDL + RFLAGS += -DUSE_SDL + ifneq ($(SDL_PATH), ) + OPTS += -I$(SDL_PATH)\INCLUDE\MSVC + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(SDL_PATH)\LIB\MSVC\x64 + else + LOPTS += -LIBPATH:$(SDL_PATH)\LIB\MSVC\x86 + endif + LIBS += sdl2.lib + endif + SDLOBJ := win_sdl.obj +endif + ifeq ($(VNC), y) -OPTS += -DUSE_VNC -RFLAGS += -DUSE_VNC + OPTS += -DUSE_VNC + RFLAGS += -DUSE_VNC ifneq ($(VNC_PATH), ) OPTS += -I$(VNC_PATH)\INCLUDE - LOPTS += $(VNC_PATH)\LIB - LIBS += -lvncserver + LOPTS += LIBPATH:$(VNC_PATH)\LIB + ifeq ($(X64), y) + LOPTS += \x64 + else + LOPTS += \x86 + endif + LIBS += libvncserver.lib endif -VNCOBJ := vnc.obj vnc_keymap.obj + VNCOBJ := vnc.obj vnc_keymap.obj endif ifeq ($(RDP), y) -OPTS += -DUSE_RDP -RFLAGS += -DUSE_RDP + OPTS += -DUSE_RDP + RFLAGS += -DUSE_RDP ifneq ($(RDP_PATH), ) - LOPTS += $(RDP_PATH)\LIB - LIBS += -lrdpsrvr + LOPTS += LIBPATH:$(RDP_PATH)\LIB + ifeq ($(X64), y) + LOPTS += \x64 + else + LOPTS += \x86 + endif + LIBS += rdpsrvr.lib endif -RDPOBJ := rdp.obj + RDPOBJ := rdp.obj endif ifeq ($(PNG), y) -OPTS += -DUSE_LIBPNG -RFLAGS += -DUSE_LIBPNG -LIBS += libpng16.lib zlib.lib + OPTS += -DUSE_LIBPNG + RFLAGS += -DUSE_LIBPNG + ifneq ($(PNG_PATH), ) + LOPTS += LIBPATH:$(PNG_PATH)\LIB + ifeq ($(X64), y) + LOPTS += \x64 + else + LOPTS += \x86 + endif + endif + LIBS += libpng16.lib zlib.lib endif # Options for the DEV branch. @@ -453,19 +489,21 @@ CXXFLAGS := $(WX_FLAGS) $(OPTS) $(CXXOPTS) $(COPTS) $(DOPTS) $(AOPTIM) $(AFLAGS) ######################################################################### # Create the (final) list of objects to build. # ######################################################################### -MAINOBJ := pc.obj config.obj misc.obj \ - random.obj timer.obj io.obj dma.obj nmi.obj pic.obj \ - pit.obj ppi.obj pci.obj mca.obj mcr.obj mem.obj \ - memregs.obj rom.obj rom_load.obj device.obj nvr.obj \ - nvr_at.obj nvr_ps2.obj $(VNCOBJ) $(RDPOBJ) -UIOBJ += ui_main.obj ui_new_floppy.obj ui_stbar.obj ui_vidapi.obj +MAINOBJ := pc.obj config.obj misc.obj random.obj timer.obj io.obj \ + mem.obj rom.obj rom_load.obj device.obj nvr.obj \ + $(SDLOBJ) $(VNCOBJ) $(RDPOBJ) INTELOBJ := intel.obj \ intel_flash.obj \ intel_sio.obj \ intel_piix.obj intel_piix4.obj +UIOBJ += ui_main.obj ui_new_floppy.obj ui_stbar.obj ui_vidapi.obj + +SYSOBJ := dma.obj nmi.obj pic.obj pit.obj ppi.obj pci.obj mca.obj \ + mcr.obj memregs.obj nvr_at.obj nvr_ps2.obj + CPUOBJ := cpu.obj cpu_table.obj \ 808x.obj 386.obj x86seg.obj x87.obj \ 386_dynarec.obj $(DYNARECOBJ) @@ -602,8 +640,8 @@ PLATOBJ += win_crashdump.obj endif -OBJ := $(MAINOBJ) $(INTELOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ - $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ +OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(SYSOBJ) $(DEVOBJ) \ + $(INTELOBJ) $(FDDOBJ) $(CDROMOBJ) $(ZIPOBJ) $(HDDOBJ) \ $(USBOBJ) $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) \ $(UIOBJ) $(PLATOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) ifdef EXOBJ @@ -627,9 +665,6 @@ else %.obj: %.cpp @$(CPP) $(CXXFLAGS) -Fo$@ -c $< -%.int: %.c - @$(PREPROC) $(OPTS) -Fo$@ $< - %.d: %.c $(wildcard $*.d) $(MCPP) $(OPTS) $(DEPS) $< >NUL diff --git a/src/win/win.c b/src/win/win.c index e545118..3df953c 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.11 2018/05/09 + * Version: @(#)win.c 1.0.12 2018/05/10 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -56,7 +56,7 @@ #define GLOBAL #include "../plat.h" #ifdef USE_SDL -# include "../sdl.h" +# include "win_sdl.h" #endif #ifdef USE_VNC # include "../vnc.h" diff --git a/src/win/win.h b/src/win/win.h index 46b0f9e..ce87a7b 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.13 2018/05/09 + * Version: @(#)win.h 1.0.14 2018/05/10 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -108,6 +108,7 @@ extern int fdd_type_icon(int type); /* Platform UI support functions. */ extern int ui_init(int nCmdShow); extern void ui_menu_update(void); +extern void plat_set_input(HWND h); #ifdef __cplusplus } diff --git a/src/win/win_keyboard.c b/src/win/win_keyboard.c index 29cef70..c5a1716 100644 --- a/src/win/win_keyboard.c +++ b/src/win/win_keyboard.c @@ -8,7 +8,7 @@ * * Windows raw keyboard input handler. * - * Version: @(#)win_keyboard.c 1.0.6 2018/05/06 + * Version: @(#)win_keyboard.c 1.0.7 2018/05/10 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -52,8 +52,10 @@ static uint16_t scancode_map[768]; -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ +/* + * This is so we can disambiguate scan codes that would otherwise + * conflict and get passed on incorrectly. + */ static UINT16 convert_scan_code(UINT16 code) { @@ -131,113 +133,124 @@ void keyboard_handle(LPARAM lParam, int focus) { static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; - uint32_t ri_size = 0; - UINT size; + uint32_t ri_size; + RAWKEYBOARD rawKB; + UINT size = 0; RAWINPUT *raw; USHORT code; if (! focus) return; + /* See how much data the RI has for us, and allocate a buffer. */ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + raw = (RAWINPUT *)malloc(size); + if (raw == NULL) { + pclog("KBD: out of memory for Raw Input buffer!\n"); + return; + } - raw = malloc(size); - if (raw == NULL) return; - - /* Here we read the raw input data for the keyboard */ + /* Read the event buffer from RI. */ ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); - if (ri_size != size) return; + if (ri_size != size) { + pclog("KBD: bad event buffer %d/%d\n", size, ri_size); + return; + } - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) { - RAWKEYBOARD rawKB = raw->data.keyboard; - code = rawKB.MakeCode; + /* We only process keyboard events. */ + if (raw->header.dwType != RIM_TYPEKEYBOARD) { + free(raw); + return; + } - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) { - if (rawKB.Flags & RI_KEY_E0) - code |= (0xE0 << 8); + rawKB = raw->data.keyboard; + code = rawKB.MakeCode; - /* Translate the scan code to 9-bit */ - code = convert_scan_code(code); + /* If it's not a scan code that starts with 0xE1 */ + if (!(rawKB.Flags & RI_KEY_E1)) { + if (rawKB.Flags & RI_KEY_E0) + code |= (0xE0 << 8); - /* Remap it according to the list from the Registry */ - /* pclog("Scan code: %04X (map: %04X)\n", code, scancode_map[code]); */ - code = scancode_map[code]; + /* Translate the scan code to 9-bit */ + code = convert_scan_code(code); - /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - if ((code == 0x00F) && - !(rawKB.Flags & RI_KEY_BREAK) && - (recv_lalt || recv_ralt) && - !mouse_capture) { - /* We received a TAB while ALT was pressed, while the mouse - is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) { - keyboard_input(0, 0x038); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x038); - keyboard_input(0, 0x038); - recv_lalt = 0; - } - if (recv_ralt) { - keyboard_input(0, 0x138); - /* Extra key press and release so the guest is not stuck in the - menu bar. */ - keyboard_input(1, 0x138); - keyboard_input(0, 0x138); - recv_ralt = 0; - } - } else if (((code == 0x038) || (code == 0x138)) && - !(rawKB.Flags & RI_KEY_BREAK) && - recv_tab && - !mouse_capture) { - /* We received an ALT while TAB was pressed, while the mouse - is not captured, suppress the ALT and send a TAB key up. */ - keyboard_input(0, 0x00F); - recv_tab = 0; - } else { - switch(code) { - case 0x00F: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; - } + /* Remap it according to the list from the Registry */ +#if 0 + pclog("Scan code: %04X (map: %04X)\n", code, scancode_map[code]); +#endif + code = scancode_map[code]; - /* Translate right CTRL to left ALT if the user has so - chosen. */ - if ((code == 0x11D) && rctrl_is_lalt) - code = 0x038; - - /* Normal scan code pass through, pass it through as is if - it's not an invalid scan code. */ - if (code != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), code); + /* + * If it's not 0xFFFF, send it to the emulated keyboard. + * We use scan code 0xFFFF to mean a mapping that + * has a prefix other than E0 and that is not E1 1D, + * which is, for our purposes, invalid. + */ + if ((code == 0x00F) && !(rawKB.Flags & RI_KEY_BREAK) && + (recv_lalt || recv_ralt) && !mouse_capture) { + /* We received a TAB while ALT was pressed, while the mouse + is not captured, suppress the TAB and send an ALT key up. */ + if (recv_lalt) { + keyboard_input(0, 0x038); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x038); + keyboard_input(0, 0x038); + recv_lalt = 0; } + if (recv_ralt) { + keyboard_input(0, 0x138); + /* Extra key press and release so the guest is not stuck in the + menu bar. */ + keyboard_input(1, 0x138); + keyboard_input(0, 0x138); + recv_ralt = 0; + } + } else if (((code == 0x038) || (code == 0x138)) && + !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && !mouse_capture) { + /* We received an ALT while TAB was pressed, while the mouse + is not captured, suppress the ALT and send a TAB key up. */ + keyboard_input(0, 0x00F); + recv_tab = 0; } else { - if (rawKB.MakeCode == 0x1D) { - /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - code = scancode_map[0x100]; - } else - code = 0xFFFF; + switch(code) { + case 0x00F: + recv_tab = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x038: + recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); + break; + + case 0x138: + recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); + break; + } + + /* Translate right CTRL to left ALT if the user has so + chosen. */ + if ((code == 0x11D) && rctrl_is_lalt) + code = 0x038; + + /* Normal scan code pass through, pass it through as is if + it's not an invalid scan code. */ if (code != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), code); } + } else { + if (rawKB.MakeCode == 0x1D) { + /* Translate E1 1D to 0x100 (which would + otherwise be E0 00 but that is invalid + anyway). + Also, take a potential mapping into + account. */ + code = scancode_map[0x100]; + } else + code = 0xFFFF; + + if (code != 0xFFFF) + keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), code); } free(raw); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index b6e55f7..edb4470 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * Implement the user Interface module. * - * Version: @(#)win_ui.c 1.0.22 2018/05/09 + * Version: @(#)win_ui.c 1.0.23 2018/05/10 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -76,7 +76,6 @@ int infocus = 1; /* Local data. */ static wchar_t wTitle[512]; -static RAWINPUTDEVICE device; static HHOOK hKeyboardHook; static LONG_PTR OriginalProcedure; static HWND hwndSBAR = NULL; /* application status bar */ @@ -337,30 +336,6 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } return(0); - case WM_INPUT: - keyboard_handle(lParam, infocus); - break; - - case WM_SETFOCUS: - infocus = 1; - if (! hook_enabled) { - hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, - LowLevelKeyboardProc, - GetModuleHandle(NULL), - 0); - hook_enabled = 1; - } - break; - - case WM_KILLFOCUS: - infocus = 0; - plat_mouse_capture(0); - if (hook_enabled) { - UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } - break; - case WM_LBUTTONUP: if (! vid_fullscreen) plat_mouse_capture(1); @@ -517,6 +492,7 @@ ui_init(int nCmdShow) { WCHAR title[200]; WNDCLASSEX wincl; /* buffer for main window's class */ + RAWINPUTDEVICE ridev; /* RawInput device */ MSG messages; /* received-messages buffer */ HACCEL haccel; /* handle to accelerator table */ DWORD flags; @@ -616,6 +592,21 @@ ui_init(int nCmdShow) /* Make the window visible on the screen. */ ShowWindow(hwndMain, nCmdShow); + /* Initialize the RawInput (keyboard) module. */ + memset(&ridev, 0x00, sizeof(ridev)); + ridev.usUsagePage = 0x01; + ridev.usUsage = 0x06; + ridev.dwFlags = RIDEV_NOHOTKEYS; + ridev.hwndTarget = NULL; /* current focus window */ + if (! RegisterRawInputDevices(&ridev, 1, sizeof(ridev))) { + ui_msgbox(MBX_CONFIG, (wchar_t *)IDS_2154); + return(4); + } + keyboard_getkeymap(); + + /* Set up the main window for RawInput. */ + plat_set_input(hwndMain); + /* Create the Machine Rendering window. */ hwndRender = CreateWindow(L"STATIC", NULL, @@ -684,17 +675,6 @@ again: /* Create the status bar window. */ StatusBarCreate(IDC_STATBAR); - /* Initialize the input (keyboard, mouse, game) module. */ - device.usUsagePage = 0x01; - device.usUsage = 0x06; - device.dwFlags = RIDEV_NOHOTKEYS; - device.hwndTarget = hwndMain; - if (! RegisterRawInputDevices(&device, 1, sizeof(device))) { - ui_msgbox(MBX_CONFIG, (wchar_t *)IDS_2154); - return(4); - } - keyboard_getkeymap(); - /* Initialize the mouse module. */ win_mouse_init(); @@ -760,6 +740,69 @@ again: } +/* Catch WM_INPUT messages for 'current focus' window. */ +static LONG_PTR input_orig_proc; +static HWND input_orig_hwnd = NULL; +#ifdef __amd64__ +static LRESULT CALLBACK +#else +static BOOL CALLBACK +#endif +input_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_INPUT: +pclog("UI: hwnd=%08lx WM_INPUT (infocus=%d) !\n", hwnd, infocus); + keyboard_handle(lParam, infocus); + break; + + case WM_SETFOCUS: +pclog("UI: hwnd=%08lx WM_SETFOCUS (infocus=%d) !\n", hwnd, infocus); + infocus = 1; + if (! hook_enabled) { + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, + LowLevelKeyboardProc, + GetModuleHandle(NULL), + 0); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: +pclog("UI: hwnd=%08lx WM_KILLFOCUS (infocus=%d) !\n", hwnd, infocus); + infocus = 0; + plat_mouse_capture(0); + if (hook_enabled) { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; + + default: + return(CallWindowProc((WNDPROC)input_orig_proc, + hwnd, message, wParam, lParam)); + } + + return(0); +} + + +void +plat_set_input(HWND h) +{ + /* If needed, rest the old one first. */ + if (input_orig_hwnd != NULL) { + SetWindowLongPtr(input_orig_hwnd, GWL_WNDPROC, + (LONG_PTR)input_orig_proc); + } + + /* Redirect the window procedure so we can catch WM_INPUT. */ + input_orig_proc = GetWindowLongPtr(h, GWLP_WNDPROC); + input_orig_hwnd = h; + SetWindowLongPtr(h, GWL_WNDPROC, (LONG_PTR)input_proc); +} + + /* Tell the UI about a new screen resolution. */ void ui_resize(int x, int y)