Re-worked mouse code to be devices (to allow for configuration.)

Re-worked the system pathnames (pc.c), renamed cfg_path to usr_path.
Other small things here and there.
Logitech bus mouse re-worked, should be OK now.
This commit is contained in:
waltje
2017-12-04 11:59:26 -05:00
parent 5bf569759e
commit fc34a6eaf3
35 changed files with 1630 additions and 1308 deletions

View File

@@ -8,7 +8,7 @@
*
* Application resource script for Windows.
*
* Version: @(#)86Box.rc 1.0.20 2017/11/18
* Version: @(#)86Box.rc 1.0.21 2017/11/25
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -849,19 +849,6 @@ BEGIN
IDS_2170 "Check BPB"
IDS_2171 "Unable to initialize FluidSynth, make sure you have the following libraries\nin your 86Box folder:\n\nlibfluidsynth.dll\nlibglib-2.0-0.dll\nlibiconv-2.dll\nlibintl-8.dll\nlibpcre-1.dll"
IDS_3072 "None"
IDS_3073 "Internal"
IDS_3074 "[Bus] Logitech Bus Mouse"
IDS_3075 "[Bus] Microsoft Bus Mouse (InPort)"
IDS_3076 "[Serial] Mouse Systems Mouse"
IDS_3077 "[Serial] Microsoft 2-button Mouse"
IDS_3078 "[Serial] Logitech 3-button Mouse"
IDS_3079 "[Serial] Microsoft Wheel Mouse"
IDS_3080 "[PS/2] 2-button Mouse"
IDS_3081 "[PS/2] Microsoft Intellimouse"
IDS_3082 "[Proprietary] Amstrad Mouse"
IDS_3083 "[Proprietary] Olivetti M24 Mouse"
IDS_4096 "Hard disk (%s)"
IDS_4097 "%01i:%01i"
IDS_4098 "%i"

View File

@@ -8,7 +8,7 @@
#
# Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.82 2017/11/27
# Version: @(#)Makefile.mingw 1.0.81 2017/11/25
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -446,7 +446,7 @@ VIDOBJ := video.o \
PLATOBJ := win.o \
win_crashdump.o win_dynld.o win_thread.o $(WSERIAL) \
win_cdrom.o win_cdrom_ioctl.o win_keyboard.o \
win_mouse.o win_joystick.o win_midi.o win_video.o
win_mouse.o win_joystick.o win_midi.o
OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \
$(FDDOBJ) $(CDROMOBJ) $(HDDOBJ) \

View File

@@ -8,7 +8,7 @@
*
* Platform main support module for Windows.
*
* Version: @(#)win.c 1.0.37 2017/11/20
* Version: @(#)win.c 1.0.40 2017/12/03
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -20,20 +20,34 @@
*/
#define UNICODE
#include <windows.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <wchar.h>
#include "../86box.h"
#include "../config.h"
#include "../device.h"
#include "../mouse.h"
#include "../video/video.h"
#define GLOBAL
#include "../plat.h"
#include "../plat_mouse.h"
#include "../plat_midi.h"
#include "../ui.h"
#ifdef USE_VNC
# include "../vnc.h"
#endif
#ifdef USE_RDP
# include "../rdp.h"
#endif
#ifdef USE_WX
# include "../wx/wx_ui.h"
#else
# include "win_ddraw.h"
# include "win_d3d.h"
#endif
#include "win.h"
@@ -52,7 +66,6 @@ DWORD dwSubLangID;
/* Local data. */
static HANDLE thMain;
static rc_str_t *lpRCstr2048,
*lpRCstr3072,
*lpRCstr4096,
*lpRCstr4352,
*lpRCstr4608,
@@ -62,13 +75,61 @@ static rc_str_t *lpRCstr2048,
*lpRCstr6144;
static struct {
char *name;
int local;
int (*init)(void *);
void (*close)(void);
void (*resize)(int x, int y);
int (*pause)(void);
} vid_apis[2][4] = {
{
#ifdef USE_WX
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
#else
{ "DDraw", 1, (int(*)(void*))ddraw_init, ddraw_close, NULL, ddraw_pause },
{ "D3D", 1, (int(*)(void*))d3d_init, d3d_close, d3d_resize, d3d_pause },
#endif
#ifdef USE_VNC
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
#else
{ NULL, 0, NULL, NULL, NULL, NULL },
#endif
#ifdef USE_RDP
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
#else
{ NULL, 0, NULL, NULL, NULL, NULL }
#endif
},
{
#ifdef USE_WX
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
#else
{ "DDraw", 1, (int(*)(void*))ddraw_init_fs, ddraw_close, NULL, ddraw_pause },
{ "D3D", 1, (int(*)(void*))d3d_init_fs, d3d_close, NULL, d3d_pause },
#endif
#ifdef USE_VNC
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
#else
{ NULL, 0, NULL, NULL, NULL, NULL },
#endif
#ifdef USE_RDP
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
#else
{ NULL, 0, NULL, NULL, NULL, NULL }
#endif
},
};
static void
LoadCommonStrings(void)
{
int i;
lpRCstr2048 = (rc_str_t *)malloc(STR_NUM_2048*sizeof(rc_str_t));
lpRCstr3072 = (rc_str_t *)malloc(STR_NUM_3072*sizeof(rc_str_t));
lpRCstr4096 = (rc_str_t *)malloc(STR_NUM_4096*sizeof(rc_str_t));
lpRCstr4352 = (rc_str_t *)malloc(STR_NUM_4352*sizeof(rc_str_t));
lpRCstr4608 = (rc_str_t *)malloc(STR_NUM_4608*sizeof(rc_str_t));
@@ -80,9 +141,6 @@ LoadCommonStrings(void)
for (i=0; i<STR_NUM_2048; i++)
LoadString(hinstance, 2048+i, lpRCstr2048[i].str, 512);
for (i=0; i<STR_NUM_3072; i++)
LoadString(hinstance, 3072+i, lpRCstr3072[i].str, 512);
for (i=0; i<STR_NUM_4096; i++)
LoadString(hinstance, 4096+i, lpRCstr4096[i].str, 512);
@@ -136,8 +194,6 @@ plat_get_string(int i)
if ((i >= 2048) && (i <= 3071)) {
str = lpRCstr2048[i-2048].str;
} else if ((i >= 3072) && (i <= 4095)) {
str = lpRCstr3072[i-3072].str;
} else if ((i >= 4096) && (i <= 4351)) {
str = lpRCstr4096[i-4096].str;
} else if ((i >= 4352) && (i <= 4607)) {
@@ -272,9 +328,7 @@ ProcessCommandLine(wchar_t ***argw)
}
/* @@@
* For the Windows platform, this is the start of the application.
*/
/* For the Windows platform, this is the start of the application. */
int WINAPI
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
{
@@ -308,14 +362,9 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
return(1);
}
/* Cleanup: we no longer need the commandline arguments. */
/* Cleanup: we may no longer need the console. */
if (! force_debug)
CreateConsole(0);
#if 0
//QUICKFIX, DO NOT CHANGE --FvK
free(argw[0]);
free(argw);
#endif
/* Handle our GUI. */
i = ui_init(nCmdShow);
@@ -344,11 +393,6 @@ do_start(void)
timer_freq = qpc.QuadPart;
pclog("Main timer precision: %llu\n", timer_freq);
#if 0
/* We should have an application-wide at_exit catcher. */
atexit(plat_mouse_capture);
#endif
/* Start the emulator, really. */
thMain = thread_create(pc_thread, &quited);
SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST);
@@ -406,6 +450,28 @@ plat_remove(wchar_t *path)
}
/* Make sure a path ends with a trailing (back)slash. */
void
plat_path_slash(wchar_t *path)
{
if ((path[wcslen(path)-1] != L'\\') &&
(path[wcslen(path)-1] != L'/')) {
wcscat(path, L"\\");
}
}
/* Check if the given path is absolute or not. */
int
plat_path_abs(wchar_t *path)
{
if ((path[1] == L':') || (path[0] == L'\\'))
return(1);
return(0);
}
wchar_t *
plat_get_filename(wchar_t *s)
{
@@ -440,7 +506,7 @@ plat_get_extension(wchar_t *s)
void
plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size)
plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2)
{
wcscat(dest, s1);
wcscat(dest, s2);
@@ -497,3 +563,251 @@ plat_delay_ms(uint32_t count)
{
Sleep(count);
}
/* Return the VIDAPI number for the given name. */
int
plat_vidapi(char *name)
{
int i;
if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) return(1);
for (i=0; i<4; i++) {
if (vid_apis[0][i].name &&
!strcasecmp(vid_apis[0][i].name, name)) return(i);
}
/* Default value. */
return(1);
}
/* Return the VIDAPI name for the given number. */
char *
plat_vidapi_name(int api)
{
char *name = "default";
switch(api) {
#if USE_WX
case 0:
break;
case 1:
name = "wxwidgets";
break;
#else
case 0:
name = "ddraw";
break;
case 1:
#if 0
/* Direct3D is default. */
name = "d3d";
#endif
break;
#endif
#ifdef USE_VNC
case 2:
name = "vnc";
break;
#endif
#ifdef USE_RDP
case 3:
name = "rdp";
break;
#endif
}
return(name);
}
int
plat_setvid(int api)
{
int i;
pclog("Initializing VIDAPI: api=%d\n", api);
startblit();
video_wait_for_blit();
/* Close the (old) API. */
vid_apis[0][vid_api].close();
//#ifdef USE_WX
// ui_check_menu_item(IDM_View_WX+vid_api, 0);
//#endif
vid_api = api;
#ifndef USE_WX
if (vid_apis[0][vid_api].local)
ShowWindow(hwndRender, SW_SHOW);
else
ShowWindow(hwndRender, SW_HIDE);
#endif
/* Initialize the (new) API. */
#ifdef USE_WX
// ui_check_menu_item(IDM_View_WX+vid_api, 1);
i = vid_apis[0][vid_api].init(NULL);
#else
i = vid_apis[0][vid_api].init((void *)hwndRender);
#endif
endblit();
if (! i) return(0);
device_force_redraw();
return(1);
}
/* Tell the renderers about a new screen resolution. */
void
plat_vidsize(int x, int y)
{
if (! vid_apis[video_fullscreen][vid_api].resize) return;
startblit();
video_wait_for_blit();
vid_apis[video_fullscreen][vid_api].resize(x, y);
endblit();
}
int
get_vidpause(void)
{
return(vid_apis[video_fullscreen][vid_api].pause());
}
void
plat_setfullscreen(int on)
{
static int flag = 0;
HWND *hw;
/* Want off and already off? */
if (!on && !video_fullscreen) return;
/* Want on and already on? */
if (on && video_fullscreen) return;
if (!on && !flag) {
/* We want to leave FS mode. */
flag = 1;
#ifdef USE_WX
goto doit;
#endif
return;
}
if (video_fullscreen_first) {
video_fullscreen_first = 0;
ui_msgbox(MBX_INFO, (wchar_t *)IDS_2074);
}
/* OK, claim the video. */
#ifdef USE_WX
doit:
#endif
startblit();
video_wait_for_blit();
win_mouse_close();
/* Close the current mode, and open the new one. */
vid_apis[video_fullscreen][vid_api].close();
video_fullscreen = on;
hw = (video_fullscreen) ? &hwndMain : &hwndRender;
vid_apis[video_fullscreen][vid_api].init((void *) *hw);
flag = 0;
#ifdef USE_WX
wx_set_fullscreen(on);
#endif
win_mouse_init();
leave_fullscreen_flag = 0;
/* Release video and make it redraw the screen. */
endblit();
device_force_redraw();
}
void
take_screenshot(void)
{
wchar_t path[1024], fn[128];
struct tm *info;
time_t now;
pclog("Screenshot: video API is: %i\n", vid_api);
if ((vid_api < 0) || (vid_api > 1)) return;
memset(fn, 0, sizeof(fn));
memset(path, 0, sizeof(path));
(void)time(&now);
info = localtime(&now);
plat_append_filename(path, usr_path, SCREENSHOT_PATH);
if (! plat_dir_check(path))
plat_dir_create(path);
wcscat(path, L"\\");
switch(vid_api) {
#ifdef USE_WX
case 0:
case 1:
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
wcscat(path, fn);
wx_screenshot(path);
break;
#else
case 0: /* ddraw */
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.bmp", info);
wcscat(path, fn);
ddraw_take_screenshot(path);
break;
case 1: /* d3d9 */
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
wcscat(path, fn);
d3d_take_screenshot(path);
break;
#endif
#ifdef USE_VNC
case 2: /* vnc */
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
wcscat(path, fn);
vnc_take_screenshot(path);
break;
#endif
}
}
void /* plat_ */
startblit(void)
{
WaitForSingleObject(ghMutex, INFINITE);
}
void /* plat_ */
endblit(void)
{
ReleaseMutex(ghMutex);
}

View File

@@ -8,7 +8,7 @@
*
* Platform support defintions for Win32.
*
* Version: @(#)win.h 1.0.10 2017/11/20
* Version: @(#)win.h 1.0.11 2017/11/24
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -82,6 +82,9 @@ extern int get_vidpause(void);
extern void keyboard_getkeymap(void);
extern void keyboard_handle(LPARAM lParam, int infocus);
extern void win_mouse_init(void);
extern void win_mouse_close(void);
extern int fdd_type_to_icon(int type);
#ifdef EMU_DEVICE_H

View File

@@ -68,7 +68,7 @@ cdrom_ioctl_log(const char *format, ...)
va_start(ap, format);
vfprintf(stdlog, format, ap);
va_end(ap);
fflush(stdstdlog);
fflush(stdlog);
}
#endif
}

View File

@@ -8,7 +8,7 @@
*
* Rendering module for Microsoft Direct3D 9.
*
* Version: @(#)win_d3d.cc 1.0.6 2017/11/12
* Version: @(#)win_d3d.cpp 1.0.6 2017/11/25
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>

View File

@@ -11,7 +11,7 @@
* NOTES: This code should be re-merged into a single init() with a
* 'fullscreen' argument, indicating FS mode is requested.
*
* Version: @(#)win_ddraw.cc 1.0.2 2017/11/12
* Version: @(#)win_ddraw.cpp 1.0.2 2017/11/25
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>

View File

@@ -8,7 +8,7 @@
*
* Windows device configuration dialog implementation.
*
* Version: @(#)win_devconf.c 1.0.9 2017/11/18
* Version: @(#)win_devconf.c 1.0.10 2017/11/25
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -117,7 +117,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FILE:
case CONFIG_FNAME:
{
wchar_t* str = config_get_wstring(config_device->name, config->name, 0);
if (str)
@@ -218,7 +218,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FILE:
case CONFIG_FNAME:
{
char* str = config_get_string(config_device->name, config->name, (char*)"");
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
@@ -318,7 +318,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FILE:
case CONFIG_FNAME:
SendMessage(h, WM_GETTEXT, 511, (LPARAM)ws);
config_set_wstring(config_device->name, config->name, ws);
@@ -387,7 +387,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
id += 2;
break;
case CONFIG_FILE:
case CONFIG_FNAME:
{
if (cid == id+1)
{
@@ -605,7 +605,7 @@ uint8_t deviceconfig_open(HWND hwnd, device_t *device)
y += 20;
break;
case CONFIG_FILE:
case CONFIG_FNAME:
/*File*/
item = (DLGITEMTEMPLATE *)data;
item->x = 70;

View File

@@ -8,7 +8,7 @@
*
* Joystick interface to host device.
*
* Version: @(#)win_joystick.cc 1.0.6 2017/11/18
* Version: @(#)win_joystick.cpp 1.0.6 2017/11/25
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>

View File

@@ -8,7 +8,7 @@
*
* Mouse interface to host device.
*
* Version: @(#)win_mouse.cc 1.0.5 2017/10/22
* Version: @(#)win_mouse.cpp 1.0.6 2017/11/25
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -23,7 +23,6 @@
#include "../86Box.h"
#include "../mouse.h"
#include "../plat.h"
#include "../plat_mouse.h"
#include "win.h"
@@ -36,32 +35,32 @@ static DIMOUSESTATE mousestate;
void
mouse_init(void)
win_mouse_init(void)
{
atexit(mouse_close);
atexit(win_mouse_close);
mouse_capture = 0;
if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION,
IID_IDirectInput8A, (void **) &lpdi, NULL)))
fatal("mouse_init : DirectInputCreate failed\n");
fatal("plat_mouse_init: DirectInputCreate failed\n");
if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdi_mouse, NULL)))
fatal("mouse_init : CreateDevice failed\n");
fatal("plat_mouse_init: CreateDevice failed\n");
if (FAILED(lpdi_mouse->SetCooperativeLevel(hwndMain,
DISCL_FOREGROUND | (video_fullscreen ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE))))
fatal("mouse_init : SetCooperativeLevel failed\n");
fatal("plat_mouse_init: SetCooperativeLevel failed\n");
if (FAILED(lpdi_mouse->SetDataFormat(&c_dfDIMouse)))
fatal("mouse_init : SetDataFormat failed\n");
fatal("plat_mouse_init: SetDataFormat failed\n");
}
void
mouse_close(void)
win_mouse_close(void)
{
if (lpdi_mouse) {
if (lpdi_mouse != NULL) {
lpdi_mouse->Release();
lpdi_mouse = NULL;
}
@@ -69,7 +68,7 @@ mouse_close(void)
void
mouse_poll_host(void)
mouse_poll(void)
{
static int buttons = 0;
static int x = 0, y = 0, z = 0;

View File

@@ -8,7 +8,7 @@
*
* Windows 86Box Settings dialog handler.
*
* Version: @(#)win_settings.c 1.0.24 2017/11/08
* Version: @(#)win_settings.c 1.0.25 2017/11/24
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -927,11 +927,11 @@ static int mouse_valid(int type, int machine)
static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
wchar_t str[128];
HWND h;
int c = 0;
int d = 0;
int type;
int str_id = 0;
switch (message)
{
@@ -946,9 +946,8 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa
if (mouse_valid(type, temp_machine))
{
str_id = IDS_3072 + c;
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)plat_get_string(str_id));
mbstowcs(str, mouse_get_name(c), sizeof_w(str));
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)str);
settings_list_to_mouse[d] = c;
d++;

View File

@@ -8,7 +8,7 @@
*
* user Interface module for WinAPI on Windows.
*
* Version: @(#)win_ui.c 1.0.5 2017/11/28
* Version: @(#)win_ui.c 1.0.6 2017/11/28
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -30,12 +30,11 @@
#include "../86box.h"
#include "../config.h"
#include "../device.h"
#include "../mouse.h"
#include "../keyboard.h"
#include "../mouse.h"
#include "../video/video.h"
#include "../video/vid_ega.h" // for update_overscan
#include "../plat.h"
#include "../plat_mouse.h"
#include "../plat_midi.h"
#include "../ui.h"
#include "win.h"
@@ -651,6 +650,11 @@ ui_init(int nCmdShow)
HACCEL haccel; /* handle to accelerator table */
int bRet;
#if 0
/* We should have an application-wide at_exit catcher. */
atexit(plat_mouse_capture);
#endif
/* Create our main window's class and register it. */
wincl.hInstance = hinstance;
wincl.lpszClassName = CLASS_NAME;
@@ -735,6 +739,9 @@ ui_init(int nCmdShow)
}
keyboard_getkeymap();
/* Initialize the mouse module. */
win_mouse_init();
/* Create the status bar window. */
StatusBarCreate(hwndMain, IDC_STATUS, hinstance);
@@ -824,11 +831,13 @@ ui_init(int nCmdShow)
if (mouse_capture)
plat_mouse_capture(0);
/* Close down the emulator. */
do_stop();
UnregisterClass(SUB_CLASS_NAME, hinstance);
UnregisterClass(CLASS_NAME, hinstance);
/* Close down the emulator. */
do_stop();
win_mouse_close();
return(messages.wParam);
}

View File

@@ -1,394 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Video API platform support for Windows.
*
* Version: @(#)win_video.c 1.0.8 2017/11/18
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2017 Fred N. van Kempen.
*/
#define UNICODE
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <wchar.h>
#include "../86box.h"
#include "../config.h"
#include "../device.h"
#include "../mouse.h"
#include "../video/video.h"
#include "../plat.h"
#include "../plat_mouse.h"
#include "../ui.h"
#ifdef USE_VNC
# include "../vnc.h"
#endif
#ifdef USE_RDP
# include "../rdp.h"
#endif
#ifdef USE_WX
# include "../wx/wx_ui.h"
#else
# include "win_ddraw.h"
# include "win_d3d.h"
#endif
#include "win.h"
static struct {
char *name;
int local;
int (*init)(void *);
void (*close)(void);
void (*resize)(int x, int y);
int (*pause)(void);
} vid_apis[2][4] = {
{
#ifdef USE_WX
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
#else
{ "DDraw", 1, (int(*)(void*))ddraw_init, ddraw_close, NULL, ddraw_pause },
{ "D3D", 1, (int(*)(void*))d3d_init, d3d_close, d3d_resize, d3d_pause },
#endif
#ifdef USE_VNC
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
#else
{ NULL, 0, NULL, NULL, NULL, NULL },
#endif
#ifdef USE_RDP
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
#else
{ NULL, 0, NULL, NULL, NULL, NULL }
#endif
},
{
#ifdef USE_WX
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
#else
{ "DDraw", 1, (int(*)(void*))ddraw_init_fs, ddraw_close, NULL, ddraw_pause },
{ "D3D", 1, (int(*)(void*))d3d_init_fs, d3d_close, NULL, d3d_pause },
#endif
#ifdef USE_VNC
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
#else
{ NULL, 0, NULL, NULL, NULL, NULL },
#endif
#ifdef USE_RDP
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
#else
{ NULL, 0, NULL, NULL, NULL, NULL }
#endif
},
};
/* Return the VIDAPI number for the given name. */
int
plat_vidapi(char *name)
{
int i;
if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) return(1);
for (i=0; i<4; i++) {
if (vid_apis[0][i].name &&
!strcasecmp(vid_apis[0][i].name, name)) return(i);
}
/* Default value. */
return(1);
}
/* Return the VIDAPI name for the given number. */
char *
plat_vidapi_name(int api)
{
char *name = "default";
switch(api) {
#if USE_WX
case 0:
break;
case 1:
name = "wxwidgets";
break;
#else
case 0:
name = "ddraw";
break;
case 1:
#if 0
/* Direct3D is default. */
name = "d3d";
#endif
break;
#endif
#ifdef USE_VNC
case 2:
name = "vnc";
break;
#endif
#ifdef USE_RDP
case 3:
name = "rdp";
break;
#endif
}
return(name);
}
int
plat_setvid(int api)
{
int i;
pclog("Initializing VIDAPI: api=%d\n", api);
startblit();
video_wait_for_blit();
/* Close the (old) API. */
vid_apis[0][vid_api].close();
//#ifdef USE_WX
// ui_check_menu_item(IDM_View_WX+vid_api, 0);
//#endif
vid_api = api;
#ifndef USE_WX
if (vid_apis[0][vid_api].local)
ShowWindow(hwndRender, SW_SHOW);
else
ShowWindow(hwndRender, SW_HIDE);
#endif
/* Initialize the (new) API. */
#ifdef USE_WX
// ui_check_menu_item(IDM_View_WX+vid_api, 1);
i = vid_apis[0][vid_api].init(NULL);
#else
i = vid_apis[0][vid_api].init((void *)hwndRender);
#endif
endblit();
if (! i) return(0);
device_force_redraw();
return(1);
}
/* Tell the renderers about a new screen resolution. */
void
plat_vidsize(int x, int y)
{
if (! vid_apis[video_fullscreen][vid_api].resize) return;
startblit();
video_wait_for_blit();
vid_apis[video_fullscreen][vid_api].resize(x, y);
endblit();
}
int
get_vidpause(void)
{
return(vid_apis[video_fullscreen][vid_api].pause());
}
void
plat_setfullscreen(int on)
{
static int flag = 0;
HWND *hw;
/* Want off and already off? */
if (!on && !video_fullscreen) return;
/* Want on and already on? */
if (on && video_fullscreen) return;
if (!on && !flag) {
/* We want to leave FS mode. */
flag = 1;
#ifdef USE_WX
goto doit;
#endif
return;
}
if (video_fullscreen_first) {
video_fullscreen_first = 0;
ui_msgbox(MBX_INFO, (wchar_t *)IDS_2074);
}
/* OK, claim the video. */
#ifdef USE_WX
doit:
#endif
startblit();
video_wait_for_blit();
mouse_close();
/* Close the current mode, and open the new one. */
vid_apis[video_fullscreen][vid_api].close();
video_fullscreen = on;
hw = (video_fullscreen) ? &hwndMain : &hwndRender;
vid_apis[video_fullscreen][vid_api].init((void *) *hw);
flag = 0;
#ifdef USE_WX
wx_set_fullscreen(on);
#endif
mouse_init();
leave_fullscreen_flag = 0;
/* Release video and make it redraw the screen. */
endblit();
device_force_redraw();
}
void
take_screenshot(void)
{
wchar_t path[1024], fn[128];
struct tm *info;
time_t now;
pclog("Screenshot: video API is: %i\n", vid_api);
if ((vid_api < 0) || (vid_api > 1)) return;
memset(fn, 0, sizeof(fn));
memset(path, 0, sizeof(path));
(void)time(&now);
info = localtime(&now);
plat_append_filename(path, cfg_path, SCREENSHOT_PATH, sizeof(path)-2);
if (! plat_dir_check(path))
plat_dir_create(path);
wcscat(path, L"\\");
switch(vid_api) {
#ifdef USE_WX
case 0:
case 1:
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
wcscat(path, fn);
wx_screenshot(path);
break;
#else
case 0: /* ddraw */
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.bmp", info);
wcscat(path, fn);
ddraw_take_screenshot(path);
break;
case 1: /* d3d9 */
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
wcscat(path, fn);
d3d_take_screenshot(path);
break;
#endif
#ifdef USE_VNC
case 2: /* vnc */
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
wcscat(path, fn);
vnc_take_screenshot(path);
break;
#endif
}
}
void /* plat_ */
startblit(void)
{
WaitForSingleObject(ghMutex, INFINITE);
}
void /* plat_ */
endblit(void)
{
ReleaseMutex(ghMutex);
}
#if 0
/* Tell the UI and/or renderers about a new screen resolution. */
void
plat_resize(int x, int y)
{
pclog("PLAT: VID[%d,%d] resizing to %dx%d\n", video_fullscreen, vid_api, x, y);
/* Do not accept these sizes. */
if (x==0 || x<320 || y==0 || y<200) return;
/* First, see if we should resize the UI window. */
if (! vid_resize)
#ifdef USE_WX
wx_resize(x, y);
#else
ui_resize(x, y);
#endif
#if 0
/* Now, tell the renderer about the new screen size we want. */
if (vid_apis[video_fullscreen][vid_api].resize) {
startblit();
vid_apis[video_fullscreen][vid_api].resize(x, y);
endblit();
}
#endif
}
void
plat_mouse_capture(int on)
{
if (on && !mouse_capture) {
/* Enable the in-app mouse. */
#ifdef USE_WX
wx_capture_mouse(1);
#endif
mouse_capture = 1;
} else if (!on && mouse_capture) {
/* Disable the in-app mouse. */
#ifdef USE_WX
wx_capture_mouse(0);
#endif
mouse_capture = 0;
}
}
#endif