/od-win32/win32.cpp
C++ | 8048 lines | 7560 code | 354 blank | 134 comment | 1278 complexity | 49bd2430fa5b0cf46a57d05b9b623f71 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Win32 interface
- *
- * Copyright 1997-1998 Mathias Ortmann
- * Copyright 1997-1999 Brian King
- */
- //#define MEMDEBUG
- #define MOUSECLIP_LOG 0
- #define MOUSECLIP_HIDE 1
- #define TOUCH_SUPPORT 1
- #define TOUCH_DEBUG 1
- #define KBHOOK 0
- #include <stdlib.h>
- #include <stdarg.h>
- #include <signal.h>
- #include "sysconfig.h"
- #define USETHREADCHARACTERICS 1
- #define _WIN32_WINNT 0x0A00
- #include <windows.h>
- #include <commctrl.h>
- #include <commdlg.h>
- #include <shellapi.h>
- #include <zmouse.h>
- #include <ddraw.h>
- #include <dbt.h>
- #include <math.h>
- #include <mmsystem.h>
- #include <shobjidl.h>
- #include <shlobj.h>
- #include <shlwapi.h>
- #include <dbghelp.h>
- #include <float.h>
- #include <WtsApi32.h>
- #include <Avrt.h>
- #include <Cfgmgr32.h>
- #include <shellscalingapi.h>
- #include "resource.h"
- #include <wintab.h>
- #include "wintablet.h"
- #include <pktdef.h>
- #include "sysdeps.h"
- #include "options.h"
- #include "audio.h"
- #include "sound.h"
- #include "uae.h"
- #include "memory.h"
- #include "rommgr.h"
- #include "custom.h"
- #include "events.h"
- #include "newcpu.h"
- #include "traps.h"
- #include "xwin.h"
- #include "keyboard.h"
- #include "inputdevice.h"
- #include "keybuf.h"
- #include "drawing.h"
- #include "dxwrap.h"
- #include "picasso96_win.h"
- #include "bsdsocket.h"
- #include "win32.h"
- #include "win32gfx.h"
- #include "registry.h"
- #include "win32gui.h"
- #include "autoconf.h"
- #include "gui.h"
- #include "uae/mman.h"
- #include "avioutput.h"
- #include "ahidsound.h"
- #include "ahidsound_new.h"
- #include "zfile.h"
- #include "savestate.h"
- #include "ioport.h"
- #include "parser.h"
- #include "scsidev.h"
- #include "disk.h"
- #include "catweasel.h"
- #include "lcd.h"
- #include "uaeipc.h"
- #include "ar.h"
- #include "akiko.h"
- #include "cdtv.h"
- #include "direct3d.h"
- #include "clipboard_win32.h"
- #include "blkdev.h"
- #include "inputrecord.h"
- #include "gfxboard.h"
- #include "statusline.h"
- #include "devices.h"
- #ifdef RETROPLATFORM
- #include "rp.h"
- #include "cloanto/RetroPlatformIPC.h"
- #endif
- #include "uae/ppc.h"
- #include "fsdb.h"
- #include "uae/time.h"
- #include "specialmonitors.h"
- #include "debug.h"
- #include "disasm.h"
- const static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF,
- { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
- const static GUID GUID_DEVINTERFACE_KEYBOARD = { 0x884b96c3, 0x56ef, 0x11d1,
- { 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd } };
- const static GUID GUID_DEVINTERFACE_MOUSE = { 0x378de44c, 0x56ef, 0x11d1,
- { 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd } };
- extern int harddrive_dangerous, do_rdbdump;
- extern int no_rawinput, no_directinput, no_windowsmouse;
- extern int force_directsound;
- extern int log_a2065, a2065_promiscuous, log_ethernet;
- extern int rawinput_enabled_hid, rawinput_log;
- extern int log_filesys;
- extern int forcedframelatency;
- int log_scsi;
- int log_net;
- int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay;
- static int log_winmouse;
- int uaelib_debug;
- int pissoff_value = 15000 * CYCLE_UNIT;
- unsigned int fpucontrol;
- int extraframewait, extraframewait2;
- int busywait;
- static int noNtDelayExecution;
- extern FILE *debugfile;
- extern int console_logging;
- OSVERSIONINFO osVersion;
- static SYSTEM_INFO SystemInfo;
- static int logging_started;
- static MINIDUMP_TYPE minidumpmode = MiniDumpNormal;
- static int nocrashdump;
- static int doquit;
- static int console_started;
- void *globalipc;
- int cpu_mmx = 1;
- int D3DEX = 1;
- int shaderon = -1;
- int d3ddebug = 0;
- int max_uae_width;
- int max_uae_height;
- HINSTANCE hInst = NULL;
- HMODULE hUIDLL = NULL;
- HWND (WINAPI *pHtmlHelp)(HWND, LPCWSTR, UINT, LPDWORD);
- HWND hHiddenWnd, hGUIWnd;
- #if KBHOOK
- static HHOOK hhook;
- #endif
- static UINT TaskbarRestart;
- static HWND TaskbarRestartHWND;
- static int forceroms;
- static int start_data = 0;
- static void *tablet;
- HCURSOR normalcursor;
- static HWND hwndNextViewer;
- static bool clipboard_initialized;
- HANDLE AVTask;
- static int all_events_disabled;
- static int mainthreadid;
- TCHAR VersionStr[256];
- TCHAR BetaStr[64];
- extern pathtype path_type;
- int toggle_sound;
- int paraport_mask;
- HKEY hWinUAEKey = NULL;
- COLORREF g_dwBackgroundColor;
- HMODULE userdll;
- HMODULE kerneldll;
- int pause_emulation;
- static int sound_closed;
- static int recapture;
- static int focus;
- static int mouseinside;
- int mouseactive;
- int minimized;
- int monitor_off;
- static int mm_timerres;
- static int timermode, timeon;
- #define MAX_TIMEHANDLES 8
- static int timehandlecounter;
- static HANDLE timehandle[MAX_TIMEHANDLES];
- static bool timehandleinuse[MAX_TIMEHANDLES];
- static HANDLE cpu_wakeup_event;
- static volatile bool cpu_wakeup_event_triggered;
- int sleep_resolution;
- static CRITICAL_SECTION cs_time;
- TCHAR executable_path[MAX_DPATH];
- TCHAR start_path_data[MAX_DPATH];
- TCHAR start_path_exe[MAX_DPATH];
- TCHAR start_path_plugins[MAX_DPATH];
- TCHAR start_path_new1[MAX_DPATH]; /* AF2005 */
- TCHAR start_path_new2[MAX_DPATH]; /* AMIGAFOREVERDATA */
- TCHAR help_file[MAX_DPATH];
- TCHAR bootlogpath[MAX_DPATH];
- TCHAR logpath[MAX_DPATH];
- bool winuaelog_temporary_enable;
- int af_path_2005;
- int quickstart = 1, configurationcache = 1, relativepaths = 0, artcache = 0;
- int saveimageoriginalpath = 0;
- int recursiveromscan = 0;
- static TCHAR *inipath = NULL;
- static int guijoybutton[MAX_JPORTS];
- static int guijoyaxis[MAX_JPORTS][4];
- static bool guijoychange;
- typedef NTSTATUS(CALLBACK* NTDELAYEXECUTION)(BOOL, PLARGE_INTEGER);
- typedef NTSTATUS(CALLBACK* ZWSETTIMERRESOLUTION)(ULONG, BOOLEAN, PULONG);
- static NTDELAYEXECUTION pNtDelayExecution;
- static ZWSETTIMERRESOLUTION pZwSetTimerResolution;
- #if TOUCH_SUPPORT
- typedef BOOL (CALLBACK* REGISTERTOUCHWINDOW)(HWND, ULONG);
- typedef BOOL (CALLBACK* GETTOUCHINPUTINFO)(HTOUCHINPUT, UINT, PTOUCHINPUT, int);
- typedef BOOL (CALLBACK* CLOSETOUCHINPUTHANDLE)(HTOUCHINPUT);
- static GETTOUCHINPUTINFO pGetTouchInputInfo;
- static CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle;
- #endif
- ADJUSTWINDOWRECTEXFORDPI pAdjustWindowRectExForDpi;
- typedef HRESULT(CALLBACK* GETDPIFORMONITOR)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
- static GETDPIFORMONITOR pGetDpiForMonitor;
- typedef UINT(CALLBACK* GETDPIFORWINDOW)(HWND);
- static GETDPIFORWINDOW pGetDpiForWindow;
- int getdpiformonitor(HMONITOR mon)
- {
- if (mon) {
- static HMODULE shcore;
- if (!shcore)
- shcore = LoadLibrary(_T("Shcore.dll"));
- if (shcore) {
- if (!pGetDpiForMonitor) {
- pGetDpiForMonitor = (GETDPIFORMONITOR)GetProcAddress(shcore, "GetDpiForMonitor");
- }
- if (pGetDpiForMonitor) {
- UINT x, y;
- if (SUCCEEDED(pGetDpiForMonitor(mon, MDT_EFFECTIVE_DPI, &x, &y)))
- return y;
- }
- }
- }
- HDC hdc = GetDC(NULL);
- int dpi = GetDeviceCaps(hdc, LOGPIXELSX);
- ReleaseDC(NULL, hdc);
- return dpi;
- }
- int getdpiforwindow(HWND hwnd)
- {
- if (!pGetDpiForWindow) {
- pGetDpiForWindow = (GETDPIFORWINDOW)GetProcAddress(userdll, "GetDpiForWindow");
- }
- if (pGetDpiForWindow)
- return pGetDpiForWindow(hwnd);
- HDC hdc = GetDC(NULL);
- int dpi = GetDeviceCaps(hdc, LOGPIXELSY);
- ReleaseDC(NULL, hdc);
- return dpi;
- }
- static ULONG ActualTimerResolution;
- int target_sleep_nanos(int nanos)
- {
- static bool init;
- if (!init && !noNtDelayExecution) {
- pNtDelayExecution = (NTDELAYEXECUTION)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtDelayExecution");
- pZwSetTimerResolution = (ZWSETTIMERRESOLUTION)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "ZwSetTimerResolution");
- if (pZwSetTimerResolution) {
- // 0.5ms
- NTSTATUS status = pZwSetTimerResolution((500 * 1000) / 100, TRUE, &ActualTimerResolution);
- if (!status) {
- LARGE_INTEGER interval;
- interval.QuadPart = -(int)ActualTimerResolution;
- status = pNtDelayExecution(false, &interval);
- if (!status) {
- write_log(_T("Using NtDelayExecution. ActualTimerResolution=%u\n"), ActualTimerResolution);
- } else {
- write_log(_T("NtDelayExecution returned %08x\n"), status);
- pNtDelayExecution = NULL;
- pZwSetTimerResolution = NULL;
- }
- } else {
- write_log(_T("NtDelayExecution not available\n"));
- pNtDelayExecution = NULL;
- pZwSetTimerResolution = NULL;
- }
- }
- init = true;
- }
- if (pNtDelayExecution) {
- if (nanos < 0)
- return 800;
- LARGE_INTEGER interval;
- int start = read_processor_time();
- nanos *= 10;
- if (nanos < ActualTimerResolution)
- nanos = ActualTimerResolution;
- interval.QuadPart = -nanos;
- pNtDelayExecution(false, &interval);
- idletime += read_processor_time() - start;
- } else {
- if (nanos < 0)
- return 1300;
- sleep_millis_main(1);
- }
- return 0;
- }
- uae_u64 spincount;
- extern bool calculated_scanline;
- void target_spin(int total)
- {
- if (!spincount || calculated_scanline)
- return;
- if (total > 10)
- total = 10;
- while (total-- >= 0) {
- uae_u64 v1 = __rdtsc();
- v1 += spincount;
- while (v1 > __rdtsc());
- }
- }
- extern int vsync_activeheight;
- void target_calibrate_spin(void)
- {
- struct amigadisplay *ad = &adisplays[0];
- struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
- int vp;
- const int cntlines = 1;
- uae_u64 sc;
- spincount = 0;
- if (!ap->gfx_vsyncmode)
- return;
- if (busywait || calculated_scanline) {
- write_log(_T("target_calibrate_spin() skipped\n"));
- return;
- }
- write_log(_T("target_calibrate_spin() start\n"));
- sc = 0x800000000000;
- for (int i = 0; i < 50; i++) {
- for (;;) {
- vp = target_get_display_scanline(-1);
- if (vp <= -10)
- goto fail;
- if (vp >= 1 && vp < vsync_activeheight - 10)
- break;
- }
- uae_u64 v1;
- int vp2;
- for (;;) {
- v1 = __rdtsc();
- vp2 = target_get_display_scanline(-1);
- if (vp2 <= -10)
- goto fail;
- if (vp2 == vp + cntlines)
- break;
- if (vp2 < vp || vp2 > vp + cntlines)
- goto trynext;
- }
- for (;;) {
- int vp2 = target_get_display_scanline(-1);
- if (vp2 <= -10)
- goto fail;
- if (vp2 == vp + cntlines * 2) {
- uae_u64 scd = (__rdtsc() - v1) / cntlines;
- if (sc > scd)
- sc = scd;
- }
- if (vp2 < vp)
- break;
- if (vp2 > vp + cntlines * 2)
- break;
- }
- trynext:;
- }
- if (sc == 0x800000000000) {
- write_log(_T("Spincount calculation error, spinloop not used.\n"), sc);
- spincount = 0;
- } else {
- spincount = sc;
- write_log(_T("Spincount = %llu\n"), sc);
- }
- return;
- fail:
- write_log(_T("Scanline read failed: %d!\n"), vp);
- spincount = 0;
- }
- int timeend (void)
- {
- if (!timeon)
- return 1;
- timeon = 0;
- if (timeEndPeriod (mm_timerres) == TIMERR_NOERROR)
- return 1;
- write_log (_T("TimeEndPeriod() failed\n"));
- return 0;
- }
- int timebegin (void)
- {
- if (timeon) {
- timeend ();
- return timebegin ();
- }
- timeon = 0;
- if (timeBeginPeriod (mm_timerres) == TIMERR_NOERROR) {
- timeon = 1;
- return 1;
- }
- write_log (_T("TimeBeginPeriod() failed\n"));
- return 0;
- }
- static int init_mmtimer (void)
- {
- TIMECAPS tc;
- int i;
- mm_timerres = 0;
- if (timeGetDevCaps (&tc, sizeof (TIMECAPS)) != TIMERR_NOERROR)
- return 0;
- mm_timerres = min (max (tc.wPeriodMin, 1), tc.wPeriodMax);
- sleep_resolution = 1000 / mm_timerres;
- for (i = 0; i < MAX_TIMEHANDLES; i++)
- timehandle[i] = CreateEvent (NULL, TRUE, FALSE, NULL);
- cpu_wakeup_event = CreateEvent(NULL, FALSE, FALSE, NULL);
- InitializeCriticalSection (&cs_time);
- timehandlecounter = 0;
- return 1;
- }
- void sleep_cpu_wakeup(void)
- {
- if (!cpu_wakeup_event_triggered) {
- cpu_wakeup_event_triggered = true;
- SetEvent(cpu_wakeup_event);
- }
- }
- HANDLE get_sound_event(void);
- extern HANDLE waitvblankevent;
- static int sleep_millis2 (int ms, bool main)
- {
- UINT TimerEvent;
- int start = 0;
- int cnt;
- HANDLE sound_event = get_sound_event();
- bool wasneg = ms < 0;
- bool pullcheck = false;
- int ret = 0;
- if (ms < 0)
- ms = -ms;
- if (main) {
- if (sound_event) {
- bool pullcheck = audio_is_event_frame_possible(ms);
- if (pullcheck) {
- if (WaitForSingleObject(sound_event, 0) == WAIT_OBJECT_0) {
- if (wasneg) {
- write_log(_T("efw %d imm abort\n"), ms);
- }
- return -1;
- }
- }
- }
- if (WaitForSingleObject(cpu_wakeup_event, 0) == WAIT_OBJECT_0) {
- return 0;
- }
- if (waitvblankevent && WaitForSingleObject(waitvblankevent, 0) == WAIT_OBJECT_0) {
- return 0;
- }
- start = read_processor_time ();
- }
- EnterCriticalSection (&cs_time);
- for (;;) {
- timehandlecounter++;
- if (timehandlecounter >= MAX_TIMEHANDLES)
- timehandlecounter = 0;
- if (timehandleinuse[timehandlecounter] == false) {
- cnt = timehandlecounter;
- timehandleinuse[cnt] = true;
- break;
- }
- }
- LeaveCriticalSection (&cs_time);
- TimerEvent = timeSetEvent (ms, 0, (LPTIMECALLBACK)timehandle[cnt], 0, TIME_ONESHOT | TIME_CALLBACK_EVENT_SET);
- if (main) {
- int c = 0;
- HANDLE evt[4];
- int sound_event_cnt = -1;
- int vblank_event_cnt = -1;
- evt[c++] = timehandle[cnt];
- evt[c++] = cpu_wakeup_event;
- if (waitvblankevent) {
- vblank_event_cnt = c;
- evt[c++] = waitvblankevent;
- }
- if (sound_event && pullcheck) {
- sound_event_cnt = c;
- evt[c++] = sound_event;
- }
- DWORD status = WaitForMultipleObjects(c, evt, FALSE, ms);
- if (sound_event_cnt >= 0 && status == WAIT_OBJECT_0 + sound_event_cnt)
- ret = -1;
- if (vblank_event_cnt >= 0 && status == WAIT_OBJECT_0 + vblank_event_cnt)
- ret = -1;
- if (wasneg) {
- if (sound_event_cnt >= 0 && status == WAIT_OBJECT_0 + sound_event_cnt) {
- write_log(_T("efw %d delayed abort\n"), ms);
- } else if (status == WAIT_TIMEOUT) {
- write_log(_T("efw %d full wait\n"), ms);
- }
- }
- cpu_wakeup_event_triggered = false;
- } else {
- WaitForSingleObject(timehandle[cnt], ms);
- }
- ResetEvent (timehandle[cnt]);
- timeKillEvent (TimerEvent);
- timehandleinuse[cnt] = false;
- if (main)
- idletime += read_processor_time () - start;
- return ret;
- }
- int sleep_millis_main (int ms)
- {
- return sleep_millis2 (ms, true);
- }
- int sleep_millis (int ms)
- {
- return sleep_millis2 (ms, false);
- }
- int sleep_millis_amiga(int ms)
- {
- int ret = sleep_millis_main(ms);
- return ret;
- }
- bool quit_ok(void)
- {
- if (isfullscreen() > 0)
- return true;
- if (!currprefs.win32_warn_exit)
- return true;
- if (quit_program == -UAE_QUIT)
- return true;
- TCHAR temp[MAX_DPATH];
- WIN32GUI_LoadUIString(IDS_QUIT_WARNING, temp, MAX_DPATH);
- int ret = gui_message_multibutton(1, temp);
- return ret == 1;
- }
- static void setcursor(struct AmigaMonitor *mon, int oldx, int oldy)
- {
- int dx = (mon->amigawinclip_rect.left - mon->amigawin_rect.left) + (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2;
- int dy = (mon->amigawinclip_rect.top - mon->amigawin_rect.top) + (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2;
- mon->mouseposx = oldx - dx;
- mon->mouseposy = oldy - dy;
- mon->windowmouse_max_w = (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2 - 50;
- mon->windowmouse_max_h = (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2 - 50;
- if (mon->windowmouse_max_w < 10)
- mon->windowmouse_max_w = 10;
- if (mon->windowmouse_max_h < 10)
- mon->windowmouse_max_h = 10;
- if ((currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_tablet > 0 && mousehack_alive () && isfullscreen () <= 0) {
- mon->mouseposx = mon->mouseposy = 0;
- return;
- }
- #if MOUSECLIP_LOG
- write_log (_T("mon=%d %dx%d %dx%d %dx%d %dx%d (%dx%d %dx%d)\n"),
- mon->monitor_id,
- dx, dy,
- mon->mouseposx, mon->mouseposy,
- oldx, oldy,
- oldx + mon->amigawinclip_rect.left, oldy + mon->amigawinclip_rect.top,
- mon->amigawinclip_rect.left, mon->amigawinclip_rect.top,
- mon->amigawinclip_rect.right, mon->amigawinclip_rect.bottom);
- #endif
- if (oldx >= 30000 || oldy >= 30000 || oldx <= -30000 || oldy <= -30000) {
- oldx = oldy = 0;
- } else {
- if (abs(mon->mouseposx) < mon->windowmouse_max_w && abs(mon->mouseposy) < mon->windowmouse_max_h)
- return;
- }
- mon->mouseposx = mon->mouseposy = 0;
- if (oldx < 0 || oldy < 0 || oldx > mon->amigawin_rect.right - mon->amigawin_rect.left || oldy > mon->amigawin_rect.bottom - mon->amigawin_rect.top) {
- write_log (_T("Mouse out of range: mon=%d %dx%d (%dx%d %dx%d)\n"), mon->monitor_id, oldx, oldy,
- mon->amigawin_rect.left, mon->amigawin_rect.top, mon->amigawin_rect.right, mon->amigawin_rect.bottom);
- return;
- }
- int cx = (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2 + mon->amigawin_rect.left + (mon->amigawinclip_rect.left - mon->amigawin_rect.left);
- int cy = (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2 + mon->amigawin_rect.top + (mon->amigawinclip_rect.top - mon->amigawin_rect.top);
- #if MOUSECLIP_LOG
- write_log (_T("SetCursorPos(%d,%d) mon=%d\n"), cx, cy, mon->monitor_id);
- #endif
- SetCursorPos (cx, cy);
- }
- static int mon_cursorclipped;
- extern TCHAR config_filename[256];
- static void setmaintitle(int monid)
- {
- TCHAR txt[1000], txt2[500];
- HWND hwnd = AMonitors[monid].hMainWnd;
- #ifdef RETROPLATFORM
- if (rp_isactive ())
- return;
- #endif
- txt[0] = 0;
- if (!monid) {
- inprec_getstatus(txt);
- if (currprefs.config_window_title[0]) {
- _tcscat(txt, currprefs.config_window_title);
- _tcscat(txt, _T(" - "));
- } else if (config_filename[0]) {
- _tcscat(txt, _T("["));
- _tcscat(txt, config_filename);
- _tcscat(txt, _T("] - "));
- }
- } else {
- if (monid == currprefs.monitoremu_mon && currprefs.monitoremu >= 2) {
- _tcscat(txt, _T("["));
- _tcscat(txt, specialmonitorfriendlynames[currprefs.monitoremu - 2]);
- _tcscat(txt, _T("] - "));
- } else {
- for (int i = 0; i < MAX_RTG_BOARDS; i++) {
- if (monid == currprefs.rtgboards[i].monitor_id) {
- _tcscat(txt, _T("["));
- _tcscat(txt, gfxboard_get_name(currprefs.rtgboards[i].rtgmem_type));
- _tcscat(txt, _T("] - "));
- }
- }
- }
- }
- _tcscat (txt, _T("WinUAE"));
- txt2[0] = 0;
- if (!monid) {
- if (pause_emulation) {
- WIN32GUI_LoadUIString(IDS_WINUAETITLE_PAUSED, txt2, sizeof(txt2) / sizeof(TCHAR));
- } else if (mouseactive > 0) {
- WIN32GUI_LoadUIString((currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) ? IDS_WINUAETITLE_MMB : IDS_WINUAETITLE_NORMAL,
- txt2, sizeof(txt2) / sizeof(TCHAR));
- }
- if (_tcslen(WINUAEBETA) > 0) {
- _tcscat(txt, BetaStr);
- if (_tcslen(WINUAEEXTRA) > 0) {
- _tcscat(txt, _T(" "));
- _tcscat(txt, WINUAEEXTRA);
- }
- }
- }
- if (txt2[0]) {
- _tcscat (txt, _T(" - "));
- _tcscat (txt, txt2);
- }
- SetWindowText (hwnd, txt);
- }
- static int pausemouseactive;
- void resumesoundpaused (void)
- {
- resume_sound ();
- #ifdef AHI
- ahi_open_sound ();
- ahi2_pause_sound (0);
- #endif
- }
- void setsoundpaused (void)
- {
- pause_sound ();
- #ifdef AHI
- ahi_close_sound ();
- ahi2_pause_sound (1);
- #endif
- }
- bool resumepaused(int priority)
- {
- struct AmigaMonitor *mon = &AMonitors[0];
- //write_log (_T("resume %d (%d)\n"), priority, pause_emulation);
- if (pause_emulation > priority)
- return false;
- if (!pause_emulation)
- return false;
- devices_unpause();
- resumesoundpaused ();
- if (pausemouseactive) {
- pausemouseactive = 0;
- setmouseactive(mon->monitor_id, isfullscreen() > 0 ? 1 : -1);
- }
- pause_emulation = 0;
- setsystime ();
- setmaintitle(mon->monitor_id);
- wait_keyrelease();
- return true;
- }
- bool setpaused(int priority)
- {
- struct AmigaMonitor *mon = &AMonitors[0];
- //write_log (_T("pause %d (%d)\n"), priority, pause_emulation);
- if (pause_emulation > priority)
- return false;
- pause_emulation = priority;
- devices_pause();
- setsoundpaused ();
- pausemouseactive = 1;
- if (isfullscreen () <= 0) {
- pausemouseactive = mouseactive;
- setmouseactive(mon->monitor_id, 0);
- }
- setmaintitle(mon->monitor_id);
- return true;
- }
- void setminimized(int monid)
- {
- if (!minimized)
- minimized = 1;
- set_inhibit_frame(monid, IHF_WINDOWHIDDEN);
- if (isfullscreen() > 0 && D3D_resize) {
- write_log(_T("setminimized\n"));
- D3D_resize(monid, -1);
- }
- }
- void unsetminimized(int monid)
- {
- if (minimized < 0)
- WIN32GFX_DisplayChangeRequested(2);
- else if (minimized > 0)
- full_redraw_all();
- minimized = 0;
- clear_inhibit_frame(monid, IHF_WINDOWHIDDEN);
- }
- void refreshtitle(void)
- {
- for (int i = 0; i < MAX_AMIGAMONITORS; i++) {
- struct AmigaMonitor *mon = &AMonitors[i];
- if (mon->hMainWnd && isfullscreen() == 0) {
- setmaintitle(mon->monitor_id);
- }
- }
- }
- #ifndef AVIOUTPUT
- static int avioutput_video = 0;
- #endif
- void setpriority (struct threadpriorities *pri)
- {
- int err;
- if (!AVTask) {
- DWORD opri = GetPriorityClass (GetCurrentProcess ());
- if (opri != IDLE_PRIORITY_CLASS && opri != NORMAL_PRIORITY_CLASS && opri != BELOW_NORMAL_PRIORITY_CLASS && opri != ABOVE_NORMAL_PRIORITY_CLASS)
- return;
- err = SetPriorityClass (GetCurrentProcess (), pri->classvalue);
- if (!err)
- write_log (_T("priority set failed, %08X\n"), GetLastError ());
- }
- }
- static void setcursorshape(int monid)
- {
- if (currprefs.input_tablet && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_magic_mouse_cursor == MAGICMOUSE_NATIVE_ONLY) {
- if (GetCursor() != NULL)
- SetCursor(NULL);
- } else if (!picasso_setwincursor(monid)) {
- if (GetCursor() != normalcursor)
- SetCursor(normalcursor);
- }
- }
- void releasecapture(struct AmigaMonitor *mon)
- {
- //write_log(_T("releasecapture %d\n"), mon_cursorclipped);
- #if 0
- CURSORINFO pci;
- pci.cbSize = sizeof pci;
- GetCursorInfo(&pci);
- write_log(_T("PCI %08x %p %d %d\n"), pci.flags, pci.hCursor, pci.ptScreenPos.x, pci.ptScreenPos.y);
- #endif
- if (!mon_cursorclipped)
- return;
- if (!ClipCursor(NULL))
- write_log(_T("ClipCursor %08x\n"), GetLastError());
- if (!ReleaseCapture())
- write_log(_T("ReleaseCapture %08x\n"), GetLastError());
- int c = ShowCursor(TRUE);
- write_log(_T("ShowCursor %d\n"), c);
- mon_cursorclipped = 0;
- }
- void updatemouseclip(struct AmigaMonitor *mon)
- {
- if (mon_cursorclipped) {
- mon->amigawinclip_rect = mon->amigawin_rect;
- if (!isfullscreen()) {
- int idx = 0;
- reenumeratemonitors();
- while (Displays[idx].monitorname) {
- RECT out;
- struct MultiDisplay *md = &Displays[idx];
- idx++;
- if (md->rect.left == md->workrect.left && md->rect.right == md->workrect.right
- && md->rect.top == md->workrect.top && md->rect.bottom == md->workrect.bottom)
- continue;
- // not in this monitor?
- if (!IntersectRect(&out, &md->rect, &mon->amigawin_rect))
- continue;
- for (int e = 0; e < 4; e++) {
- int v1, v2, x, y;
- LONG *lp;
- switch (e)
- {
- case 0:
- default:
- v1 = md->rect.left;
- v2 = md->workrect.left;
- lp = &mon->amigawinclip_rect.left;
- x = v1 - 1;
- y = (md->rect.bottom - md->rect.top) / 2;
- break;
- case 1:
- v1 = md->rect.top;
- v2 = md->workrect.top;
- lp = &mon->amigawinclip_rect.top;
- x = (md->rect.right - md->rect.left) / 2;
- y = v1 - 1;
- break;
- case 2:
- v1 = md->rect.right;
- v2 = md->workrect.right;
- lp = &mon->amigawinclip_rect.right;
- x = v1 + 1;
- y = (md->rect.bottom - md->rect.top) / 2;
- break;
- case 3:
- v1 = md->rect.bottom;
- v2 = md->workrect.bottom;
- lp = &mon->amigawinclip_rect.bottom;
- x = (md->rect.right - md->rect.left) / 2;
- y = v1 + 1;
- break;
- }
- // is there another monitor sharing this edge?
- POINT pt;
- pt.x = x;
- pt.y = y;
- if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL))
- continue;
- // restrict mouse clip bounding box to this edge
- if (e >= 2) {
- if (*lp > v2) {
- *lp = v2;
- }
- } else {
- if (*lp < v2) {
- *lp = v2;
- }
- }
- }
- }
- // Too small or invalid?
- if (mon->amigawinclip_rect.right <= mon->amigawinclip_rect.left + 7 || mon->amigawinclip_rect.bottom <= mon->amigawinclip_rect.top + 7)
- mon->amigawinclip_rect = mon->amigawin_rect;
- }
- if (mon_cursorclipped == mon->monitor_id + 1) {
- #if MOUSECLIP_LOG
- write_log(_T("CLIP mon=%d %dx%d %dx%d %d\n"), mon->monitor_id, mon->amigawin_rect.left, mon->amigawin_rect.top, mon->amigawin_rect.right, mon->amigawin_rect.bottom, isfullscreen());
- #endif
- if (!ClipCursor(&mon->amigawinclip_rect))
- write_log(_T("ClipCursor error %d\n"), GetLastError());
- }
- }
- }
- void updatewinrect(struct AmigaMonitor *mon, bool allowfullscreen)
- {
- int f = isfullscreen ();
- if (!allowfullscreen && f > 0)
- return;
- GetWindowRect(mon->hAmigaWnd, &mon->amigawin_rect);
- GetWindowRect(mon->hAmigaWnd, &mon->amigawinclip_rect);
- #if MOUSECLIP_LOG
- write_log (_T("GetWindowRect mon=%d %dx%d %dx%d %d\n"), mon->monitor_id, mon->amigawin_rect.left, mon->amigawin_rect.top, mon->amigawin_rect.right, mon->amigawin_rect.bottom, f);
- #endif
- if (f == 0 && mon->monitor_id == 0) {
- changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.x = mon->amigawin_rect.left;
- changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.y = mon->amigawin_rect.top;
- currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.x = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.x;
- currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.y = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.y;
- }
- }
- #if KBHOOK
- static bool HasAltModifier(int flags)
- {
- return (flags & 0x20) == 0x20;
- }
- static LRESULT CALLBACK captureKey(int nCode, WPARAM wp, LPARAM lp)
- {
- if (nCode >= 0)
- {
- KBDLLHOOKSTRUCT *kbd = (KBDLLHOOKSTRUCT*)lp;
- DWORD vk = kbd->vkCode;
- DWORD flags = kbd->flags;
- // Disabling Windows keys
- if (vk == VK_RWIN || vk == VK_LWIN || (vk == VK_TAB && HasAltModifier(flags))) {
- return 1;
- }
- }
- return CallNextHookEx(hhook, nCode, wp, lp);
- }
- #endif
- static bool iswindowfocus(struct AmigaMonitor *mon)
- {
- bool donotfocus = false;
- HWND f = GetFocus ();
- HWND fw = GetForegroundWindow ();
- HWND w1 = mon->hAmigaWnd;
- HWND w2 = mon->hMainWnd;
- if (f != w1 && f != w2)
- donotfocus = true;
-
- //write_log(_T("f=%p fw=%p w1=%p w2=%p\n"), f, fw, w1, w2);
- #ifdef RETROPLATFORM
- if (rp_isactive()) {
- HWND hGuestParent = rp_getparent();
- DWORD dwHostProcessId;
- GetWindowThreadProcessId(hGuestParent, &dwHostProcessId);
- if (fw) {
- DWORD dwForegroundProcessId = 0;
- GetWindowThreadProcessId(fw, &dwForegroundProcessId);
- //write_log(_T("dwForegroundProcessId=%p dwHostProcessId=%p\n"), dwForegroundProcessId, dwHostProcessId);
- if (dwForegroundProcessId == dwHostProcessId) {
- donotfocus = false;
- }
- }
- }
- #endif
- if (isfullscreen () > 0)
- donotfocus = false;
- return donotfocus == false;
- }
- bool ismouseactive (void)
- {
- return mouseactive > 0;
- }
- void target_inputdevice_unacquire(void)
- {
- close_tablet(tablet);
- tablet = NULL;
- }
- void target_inputdevice_acquire(void)
- {
- struct AmigaMonitor *mon = &AMonitors[0];
- target_inputdevice_unacquire();
- tablet = open_tablet(mon->hAmigaWnd);
- }
- int getfocusedmonitor(void)
- {
- if (focus > 0) {
- return focus - 1;
- }
- return 0;
- }
- static void setmouseactive2(struct AmigaMonitor *mon, int active, bool allowpause)
- {
- #ifdef RETROPLATFORM
- bool isrp = rp_isactive () != 0;
- #else
- bool isrp = false;
- #endif
- //write_log (_T("setmouseactive %d->%d cursor=%d focus=%d recap=%d\n"), mouseactive, active, mon_cursorclipped, focus, recapture);
- if (active == 0)
- releasecapture (mon);
- if (mouseactive == active && active >= 0)
- return;
- if (!isrp && active == 1 && !(currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) {
- HANDLE c = GetCursor ();
- if (c != normalcursor)
- return;
- }
- if (active) {
- if (!isrp && !IsWindowVisible (mon->hAmigaWnd))
- return;
- }
- if (active < 0)
- active = 1;
- mouseactive = active ? mon->monitor_id + 1 : 0;
- mon->mouseposx = mon->mouseposy = 0;
- //write_log (_T("setmouseactive(%d)\n"), active);
- releasecapture (mon);
- recapture = 0;
- if (isfullscreen () <= 0 && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_tablet > 0) {
- if (mousehack_alive ())
- return;
- SetCursor (normalcursor);
- }
- bool gotfocus = false;
- for (int i = 0; i < MAX_AMIGAMONITORS; i++) {
- HWND h = GetFocus();
- if (h && (h == AMonitors[i].hAmigaWnd || h == AMonitors[i].hMainWnd)) {
- mon = &AMonitors[i];
- break;
- }
- }
- for (int i = 0; i < MAX_AMIGAMONITORS; i++) {
- if (iswindowfocus(&AMonitors[i])) {
- gotfocus = true;
- break;
- }
- }
- if (!gotfocus) {
- write_log (_T("Tried to capture mouse but window didn't have focus! F=%d A=%d\n"), focus, mouseactive);
- focus = 0;
- mouseactive = 0;
- active = 0;
- }
- if (mouseactive > 0)
- focus = mon->monitor_id + 1;
- //write_log(_T("setcapture %d %d %d\n"), mouseactive, focus, mon_cursorclipped);
- if (mouseactive) {
- if (focus) {
- if (GetActiveWindow() != mon->hMainWnd && GetActiveWindow() != mon->hAmigaWnd)
- SetActiveWindow(mon->hMainWnd);
- if (!mon_cursorclipped) {
- //write_log(_T("setcapture\n"));
- #if MOUSECLIP_HIDE
- ShowCursor (FALSE);
- #endif
- SetCapture (mon->hAmigaWnd);
- updatewinrect(mon, false);
- mon_cursorclipped = mon->monitor_id + 1;
- updatemouseclip(mon);
- }
- setcursor(mon, -30000, -30000);
- }
- wait_keyrelease();
- inputdevice_acquire(TRUE);
- setpriority (&priorities[currprefs.win32_active_capture_priority]);
- if (currprefs.win32_active_nocapture_pause) {
- resumepaused(2);
- } else if (currprefs.win32_active_nocapture_nosound && sound_closed < 0) {
- resumesoundpaused();
- }
- setmaintitle(mon->monitor_id);
- #if KBHOOK
- if (!hhook) {
- hhook = SetWindowsHookEx(WH_KEYBOARD_LL, captureKey, GetModuleHandle(NULL), 0);
- }
- #endif
- } else {
- #if KBHOOK
- if (hhook) {
- UnhookWindowsHookEx(hhook);
- hhook = NULL;
- }
- #endif
- inputdevice_acquire (FALSE);
- inputdevice_releasebuttons();
- }
- if (!active && allowpause) {
- if (currprefs.win32_active_nocapture_pause) {
- setpaused (2);
- } else if (currprefs.win32_active_nocapture_nosound) {
- setsoundpaused ();
- sound_closed = -1;
- }
- setmaintitle(mon->monitor_id);
- }
- #ifdef RETROPLATFORM
- rp_mouse_capture(active);
- rp_mouse_magic(magicmouse_alive());
- #endif
- }
- void setmouseactive(int monid, int active)
- {
- struct AmigaMonitor *mon = &AMonitors[monid];
- monitor_off = 0;
- if (active > 1)
- SetForegroundWindow(mon->hAmigaWnd);
- setmouseactive2(mon, active, true);
- }
- static int hotkeys[] = { VK_VOLUME_UP, VK_VOLUME_DOWN, VK_VOLUME_MUTE, -1 };
- static void winuae_active(struct AmigaMonitor *mon, HWND hwnd, int minimized)
- {
- struct threadpriorities *pri;
- //write_log (_T("winuae_active(%p,%d)\n"), hwnd, minimized);
- monitor_off = 0;
- /* without this returning from hibernate-mode causes wrong timing
- */
- timeend ();
- sleep_millis (2);
- timebegin ();
- focus = mon->monitor_id + 1;
- pri = &priorities[currprefs.win32_inactive_priority];
- if (!minimized)
- pri = &priorities[currprefs.win32_active_capture_priority];
- setpriority(pri);
- if (sound_closed) {
- if (sound_closed < 0) {
- resumesoundpaused ();
- } else {
- if (currprefs.win32_active_nocapture_pause) {
- if (mouseactive)
- resumepaused (2);
- } else if (currprefs.win32_iconified_pause && !currprefs.win32_inactive_pause)
- resumepaused (1);
- else if (currprefs.win32_inactive_pause)
- resumepaused (2);
- }
- sound_closed = 0;
- }
- #if 0
- RegisterHotKey (mon->hAmigaWnd, IDHOT_SNAPDESKTOP, 0, VK_SNAPSHOT);
- for (int i = 0; hotkeys[i] >= 0; i++)
- RegisterHotKey (mon->hAmigaWnd, hotkeys[i], 0, hotkeys[i]);
- #endif
- getcapslock ();
- wait_keyrelease ();
- inputdevice_acquire (TRUE);
- if ((isfullscreen () > 0 || currprefs.win32_capture_always) && !gui_active)
- setmouseactive(mon->monitor_id, 1);
- #ifdef LOGITECHLCD
- if (!minimized)
- lcd_priority (1);
- #endif
- clipboard_active(mon->hAmigaWnd, 1);
- #if USETHREADCHARACTERICS
- if (os_vista && AVTask == NULL) {
- typedef HANDLE(WINAPI* AVSETMMTHREADCHARACTERISTICS)(LPCTSTR, LPDWORD);
- DWORD taskIndex = 0;
- AVSETMMTHREADCHARACTERISTICS pAvSetMmThreadCharacteristics =
- (AVSETMMTHREADCHARACTERISTICS)GetProcAddress(GetModuleHandle(_T("Avrt.dll")), "AvSetMmThreadCharacteristicsW");
- if (pAvSetMmThreadCharacteristics) {
- if (!(AVTask = pAvSetMmThreadCharacteristics(TEXT("Pro Audio"), &taskIndex))) {
- write_log (_T("AvSetMmThreadCharacteristics failed: %d\n"), GetLastError ());
- }
- }
- }
- #endif
- }
- static void winuae_inactive(struct AmigaMonitor *mon, HWND hWnd, int minimized)
- {
- struct threadpriorities *pri;
- int wasfocus = focus;
- //write_log (_T("winuae_inactive(%d)\n"), minimized);
- #if USETHREADCHARACTERICS
- if (AVTask) {
- typedef BOOL(WINAPI* AVREVERTMMTHREADCHARACTERISTICS)(HANDLE);
- AVREVERTMMTHREADCHARACTERISTICS pAvRevertMmThreadCharacteristics =
- (AVREVERTMMTHREADCHARACTERISTICS)GetProcAddress(GetModuleHandle(_T("Avrt.dll")), "AvRevertMmThreadCharacteristics");
- if (pAvRevertMmThreadCharacteristics)
- pAvRevertMmThreadCharacteristics(AVTask);
- AVTask = NULL;
- }
- #endif
- if (!currprefs.win32_powersavedisabled)
- SetThreadExecutionState (ES_CONTINUOUS);
- if (minimized)
- exit_gui(0);
- #if 0
- for (int i = 0; hotkeys[i] >= 0; i++)
- UnregisterHotKey (mon->hAmigaWnd, hotkeys[i]);
- UnregisterHotKey (mon->hAmigaWnd, IDHOT_SNAPDESKTOP);
- #endif
- focus = 0;
- recapture = 0;
- wait_keyrelease ();
- setmouseactive(mon->monitor_id, 0);
- clipboard_active(mon->hAmigaWnd, 0);
- pri = &priorities[currprefs.win32_inactive_priority];
- if (!quit_program) {
- if (minimized) {
- pri = &priorities[currprefs.win32_iconified_priority];
- if (currprefs.win32_iconified_pause) {
- inputdevice_unacquire();
- setpaused(1);
- sound_closed = 1;
- } else if (currprefs.win32_iconified_nosound) {
- inputdevice_unacquire(true, currprefs.win32_iconified_input);
- setsoundpaused();
- sound_closed = -1;
- } else {
- inputdevice_unacquire(true, currprefs.win32_iconified_input);
- }
- } else if (mouseactive) {
- inputdevice_unacquire();
- if (currprefs.win32_active_nocapture_pause) {
- setpaused (2);
- sound_closed = 1;
- } else if (currprefs.win32_active_nocapture_nosound) {
- setsoundpaused ();
- sound_closed = -1;
- }
- } else {
- if (currprefs.win32_inactive_pause) {
- inputdevice_unacquire();
- setpaused(2);
- sound_closed = 1;
- } else if (currprefs.win32_inactive_nosound) {
- inputdevice_unacquire(true, currprefs.win32_inactive_input);
- setsoundpaused();
- sound_closed = -1;
- } else {
- inputdevice_unacquire(true, currprefs.win32_inactive_input);
- }
- }
- } else {
- inputdevice_unacquire();
- }
- setpriority (pri);
- #ifdef FILESYS
- filesys_flush_cache ();
- #endif
- #ifdef LOGITECHLCD
- lcd_priority (0);
- #endif
- }
- void minimizewindow(int monid)
- {
- struct AmigaMonitor *mon = &AMonitors[monid];
- if (mon->screen_is_initialized)
- ShowWindow (mon->hMainWnd, SW_MINIMIZE);
- }
- void enablecapture(int monid)
- {
- if (pause_emulation > 2)
- return;
- //write_log(_T("enablecapture\n"));
- setmouseactive(monid, 1);
- if (sound_closed < 0) {
- resumesoundpaused();
- sound_closed = 0;
- }
- if (currprefs.win32_inactive_pause || currprefs.win32_active_nocapture_pause) {
- resumepaused(2);
- }
- }
- void disablecapture(void)
- {
- //write_log(_T("disablecapture\n"));
- setmouseactive(0, 0);
- focus = 0;
- if (currprefs.win32_active_nocapture_pause && sound_closed == 0) {
- setpaused (2);
- sound_closed = 1;
- } else if (currprefs.win32_active_nocapture_nosound && sound_closed == 0) {
- setsoundpaused ();
- sound_closed = -1;
- }
- }
- void gui_gameport_button_change (int port, int button, int onoff)
- {
- //write_log (_T("%d %d %d\n"), port, button, onoff);
- #ifdef RETROPLATFORM
- int mask = 0;
- if (button == JOYBUTTON_CD32_PLAY)
- mask = RP_JOYSTICK_BUTTON5;
- if (button == JOYBUTTON_CD32_RWD)
- mask = RP_JOYSTICK_BUTTON6;
- if (button == JOYBUTTON_CD32_FFW)
- mask = RP_JOYSTICK_BUTTON7;
- if (button == JOYBUTTON_CD32_GREEN)
- mask = RP_JOYSTICK_BUTTON4;
- if (button == JOYBUTTON_3 || button == JOYBUTTON_CD32_YELLOW)
- mask = RP_JOYSTICK_BUTTON3;
- if (button == JOYBUTTON_1 || button == JOYBUTTON_CD32_RED)
- mask = RP_JOYSTICK_BUTTON1;
- if (button == JOYBUTTON_2 || button == JOYBUTTON_CD32_BLUE)
- mask = RP_JOYSTICK_BUTTON2;
- rp_update_gameport (port, mask, onoff);
- #endif
- if (onoff)
- guijoybutton[port] |= 1 << button;
- else
- guijoybutton[port] &= ~(1 << button);
- guijoychange = true;
- }
- void gui_gameport_axis_change (int port, int axis, int state, int max)
- {
- int onoff = state ? 100 : 0;
- if (axis < 0 || axis > 3)
- return;
- if (max < 0) {
- if (guijoyaxis[port][axis] == 0)
- return;
- if (guijoyaxis[port][axis] > 0)
- guijoyaxis[port][axis]--;
- } else {
- if (state > max)
- state = max;
- if (state < 0)
- state = 0;
- guijoyaxis[port][axis] = max ? state * 127 / max : onoff;
- #ifdef RETROPLATFORM
- if (axis == DIR_LEFT_BIT)
- rp_update_gameport (port, RP_JOYSTICK_LEFT, onoff);
- if (axis == DIR_RIGHT_BIT)
- rp_update_gameport (port, RP_JOYSTICK_RIGHT, onoff);
- if (axis == DIR_UP_BIT)
- rp_update_gameport (port, RP_JOYSTICK_UP, onoff);
- if (axis == DIR_DOWN_BIT)
- rp_update_gameport (port, RP_JOYSTICK_DOWN, onoff);
- #endif
- }
- guijoychange = true;
- }
- void setmouseactivexy(int monid, int x, int y, int dir)
- {
- struct AmigaMonitor *mon = &AMonitors[monid];
- int diff = 8;
- if (isfullscreen () > 0)
- return;
- x += mon->amigawin_rect.left;
- y += mon->amigawin_rect.top;
- if (dir & 1)
- x = mon->amigawin_rect.left - diff;
- if (dir & 2)
- x = mon->amigawin_rect.right + diff;
- if (dir & 4)
- y = mon->amigawin_rect.top - diff;
- if (dir & 8)
- y = mon->amigawin_rect.bottom + diff;
- if (!dir) {
- x += (mon->amigawin_rect.right - mon->amigawin_rect.left) / 2;
- y += (mon->amigawin_rect.bottom - mon->amigawin_rect.top) / 2;
- }
- if (isfullscreen () < 0) {
- POINT pt;
- pt.x = x;
- pt.y = y;
- if (MonitorFromPoint (pt, MONITOR_DEFAULTTONULL) == NULL)
- return;
- }
- if (mouseactive) {
- disablecapture ();
- SetCursorPos (x, y);
- if (dir) {
- recapture = 1;
- }
- }
- }
- int isfocus(void)
- {
- if (isfullscreen () > 0) {
- if (!minimized)
- return 2;
- return 0;
- }
- if (currprefs.input_tablet >= TABLET_MOUSEHACK && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC)) {
- if (mouseinside)
- return 2;
- if (focus)
- return 1;
- return 0;
- }
- if (focus && mouseactive > 0)
- return 2;
- if (focus)
- return -1;
- return 0;
- }
- static void activationtoggle(int monid, bool inactiveonly)
- {
- if (mouseactive) {
- if ((isfullscreen () > 0) || (isfullscreen () < 0 && currprefs.win32_minimize_inactive)) {
- disablecapture();
- minimizewindow(monid);
- } else {
- setmouseactive(monid, 0);
- }
- } else {
- if (!inactiveonly)
- setmouseactive(monid, 1);
- }
- }
- static void handleXbutton (WPARAM wParam, int updown)
- {
- int b = GET_XBUTTON_WPARAM (wParam);
- int num = (b & XBUTTON1) ? 3 : (b & XBUTTON2) ? 4 : -1;
- if (num >= 0)
- setmousebuttonstate (dinput_winmouse (), num, updown);
- }
- #define MEDIA_INSERT_QUEUE_SIZE 10
- static TCHAR *media_insert_queue[MEDIA_INSERT_QUEUE_SIZE];
- static int media_insert_queue_type[MEDIA_INSERT_QUEUE_SIZE];
- static int media_change_timer;
- static int device_change_timer;
- static int is_in_media_queue(const TCHAR *drvname)
- {
- for (int i = 0; i < MEDIA_INSERT_QUEUE_SIZE; i++) {
- if (media_insert_queue[i] != NULL) {
- if (!_tcsicmp(drvname, media_insert_queue[i]))
- return i;
- }
- }
- return -1;
- }
- static void start_media_insert_timer(HWND hwnd)
- {
- if (!media_change_timer) {
- media_change_timer = 1;
- SetTimer(hwnd, 2, 1000, NULL);
- }
- }
- static void add_media_insert_queue(HWND hwnd, const TCHAR *drvname, int retrycnt)
- {
- int idx = is_in_media_queue(drvname);
- if (idx >= 0) {
- if (retrycnt > media_insert_queue_type[idx])
- media_insert_queue_type[idx] = retrycnt;
- write_log(_T("%s already queued for insertion, cnt=%d.\n"), drvname, retrycnt);
- start_media_insert_timer(hwnd);
- return;
- }
- for (int i = 0; i < MEDIA_INSERT_QUEUE_SIZE; i++) {
- if (media_insert_queue[i] == NULL) {
- media_insert_queue[i] = my_strdup(drvname);
- media_insert_queue_type[i] = retrycnt;
- start_media_insert_timer(hwnd);
- return;
- }
- }
- }
- #if TOUCH_SUPPORT
- static int touch_touched;
- static DWORD touch_time;
- #define MAX_TOUCHES 10
- struct touch_store
- {
- bool inuse;
- DWORD id;
- int port;
- int button;
- int axis;
- };
- static struct touch_store touches[MAX_TOUCHES];
- static void touch_release(struct touch_store *ts, const RECT *rcontrol)
- {
- if (ts->port == 0) {
- if (ts->button == 0)
- inputdevice_uaelib(_T("JOY1_FIRE_BUTTON"), 0, 1, false);
- if (ts->button == 1)
- inputdevice_uaelib(_T("JOY1_2ND_BUTTON"), 0, 1, false);
- } else if (ts->port == 1) {
- if (ts->button == 0)
- inputdevice_uaelib(_T("JOY2_FIRE_BUTTON"), 0, 1, false);
- if (ts->button == 1)
- inputdevice_uaelib(_T("JOY2_2ND_BUTTON"), 0, 1, false);
- }
- if (ts->axis >= 0) {
- if (ts->port == 0) {
- inputdevice_uaelib(_T("MOUSE1_HORIZ"), 0, -1, false);
- inputdevice_uaelib(_T("MOUSE1_VERT"), 0, -1, false);
- } else {
- inputdevice_uaelib(_T("JOY2_HORIZ"), 0, 1, false);
- inputdevice_uaelib(_T("JOY2_VERT"), 0, 1, false);
- }
- }
- ts->button = -1;
- ts->axis = -1;
- }
- static void tablet_touch(DWORD id, int pressrel, int x, int y, const RECT *rcontrol)
- {
- struct touch_store *ts = NULL;
- int buttony = rcontrol->bottom - (rcontrol->bottom - rcontrol->top) / 4;
-
- int new_slot = -1;
- for (int i = 0; i < MAX_TOUCHES; i++) {
- struct touch_store *tts = &touches[i];
- if (!tts->inuse && new_slot < 0)
- new_slot = i;
- if (tts->inuse && tts->id == id) {
- ts = tts;
- #if TOUCH_DEBUG > 1
- write_log(_T("touch_event: old touch event %d\n"), id);
- #endif
- break;
- }
- }
- if (!ts) {
- // do not allocate new if release
- if (pressrel == 0)
- return;
- if (new_slot < 0)
- return;
- #if TOUCH_DEBUG > 1
- write_log(_T("touch_event: new touch event %d\n"), id);
- #endif
- ts = &touches[new_slot];
- ts->inuse = true;
- ts->axis = -1;
- ts->button = -1;
- ts->id = id;
- }
- // Touch release? Release buttons, center stick/mouse.
- if (ts->inuse && ts->id == id && pressrel < 0) {
- touch_release(ts, rcontrol);
- ts->inuse = false;
- return;
- }
- // Check hit boxes if new touch.
- for (int i = 0; i < 2; i++) {
- const RECT *r = &rcontrol[i];
- if (x >= r->left && x < r->right && y >= r->top && y < r->bottom) {
- #if TOUCH_DEBUG > 1
- write_log(_T("touch_event: press=%d rect=%d wm=%d\n"), pressrel, i, dinput_winmouse());
- #endif
- if (pressrel == 0) {
- // move? port can't change, axis<>button not allowed
- if (ts->port == i) {
- if (y >= buttony && ts->button >= 0) {
- int button = x > r->left + (r->right - r->left) / 2 ? 1 : 0;
- if (button != ts->button) {
- // button change, release old button
- touch_release(ts, rcontrol);
- ts->button = button;
- pressrel = 1;
- }
- }
- }
- } else if (pressrel > 0) {
- // new touch
- ts->port = i;
- if (ts->button < 0 && y >= buttony) {
- ts->button = x > r->left + (r->right - r->left) / 2 ? 1 : 0;
- } else if (ts->axis < 0 && y < buttony) {
- ts->axis = 1;
- }
- }
- }
- }
- // Directions hit?
- if (ts->inuse && ts->id == id && ts->axis >= 0) {
- const RECT *r = &rcontrol[ts->port];
- int xdiff = (r->left + (r->right - r->left) / 2) - x;
- int ydiff = (r->top + (buttony - r->top) / 2) - y;
- #if TOUCH_DEBUG > 1
- write_log(_T("touch_event: rect=%d xdiff %03d ydiff %03d\n"), ts->port, xdiff, ydiff);
- #endif
- xdiff = -xdiff;
- ydiff = -ydiff;
- if (ts->port == 0) {
- int div = (r->bottom - r->top) / (2 * 5);
- if (div <= 0)
- div = 1;
- int vx = xdiff / div;
- int vy = ydiff / div;
- #if TOUCH_DEBUG > 1
- write_log(_T("touch_event: xdiff %03d ydiff %03d div %03d vx %03d vy %03d\n"), xdiff, ydiff, div, vx, vy);
- #endif
- inputdevice_uaelib(_T("MOUSE1_HORIZ"), vx, -1, false);
- inputdevice_uaelib(_T("MOUSE1_VERT"), vy, -1, false);
- } else {
- int div = (r->bottom - r->top) / (2 * 3);
- if (div <= 0)
- div = 1;
- if (xdiff <= -div)
- inputdevice_uaelib(_T("JOY2_HORIZ"), -1, 1, false);
- else if (xdiff >= div)
- inputdevice_uaelib(_T("JOY2_HORIZ"), 1, 1, false);
- else
- inputdevice_uaelib(_T("JOY2_HORIZ"), 0, 1, false);
- if (ydiff <= -div)
- inputdevice_uaelib(_T("JOY2_VERT"), -1, 1, false);
- else if (ydiff >= div)
- inputdevice_uaelib(_T("JOY2_VERT"), 1, 1, false);
- else
- inputdevice_uaelib(_T("JOY2_VERT"), 0, 1, false);
- }
- }
- // Buttons hit?
- if (ts->inuse && ts->id == id && pressrel > 0) {
- if (ts->port == 0) {
- if (ts->button == 0)
- inputdevice_uaelib(_T("JOY1_FIRE_BUTTON"), 1, 1, false);
- if (ts->button == 1)
- inputdevice_uaelib(_T("JOY1_2ND_BUTTON"), 1, 1, false);
- } else if (ts->port == 1) {
- if (ts->button == 0)
- inputdevice_uaelib(_T("JOY2_FIRE_BUTTON"), 1, 1, false);
- if (ts->button == 1)
- inputdevice_uaelib(_T("JOY2_2ND_BUTTON"), 1, 1, false);
- }
- }
- }
- static void touch_event(DWORD id, int pressrel, int x, int y, const RECT *rcontrol)
- {
- if (is_touch_lightpen()) {
- tablet_lightpen(x, y, -1, -1, pressrel, pressrel > 0, true, dinput_lightpen(), -1);
- } else {
- tablet_touch(id, pressrel, x, y, rcontrol);
- }
- }
- static int touch_prev_x, touch_prev_y;
- static DWORD touch_prev_flags;
- static void processtouch(struct AmigaMonitor *mon, HWND hwnd, WPARAM wParam, LPARAM lParam)
- {
- RECT rgui, rcontrol[2];
- int bottom;
- if (currprefs.input_tablet && !is_touch_lightpen())
- return;
- if (isfullscreen()) {
- rgui.left = mon->amigawin_rect.left;
- rgui.top = mon->amigawin_rect.top;
- rgui.right = mon->amigawin_rect.right;
- rgui.bottom = mon->amigawin_rect.top + 30;
- bottom = mon->amigawin_rect.bottom;
- } else {
- rgui.left = mon->mainwin_rect.left;
- rgui.top = mon->mainwin_rect.top;
- rgui.right = mon->mainwin_rect.right;
- rgui.bottom = mon->amigawin_rect.top + GetSystemMetrics(SM_CYMENU) + 2;
- bottom = mon->mainwin_rect.bottom;
- }
- int maxx = rgui.right - rgui.left;
- int maxy = rgui.bottom - rgui.top;
- int max = maxx > maxy ? maxx : maxy;
- // left control region
- rcontrol[0].left = rgui.left;
- rcontrol[0].right = rcontrol[0].left + max / 2;
- rcontrol[0].bottom = bottom;
- rcontrol[0].top = bottom - max / 2;
- // right control region
- rcontrol[1].right = rgui.right;
- rcontrol[1].left = rcontrol[1].right - max / 2;
- rcontrol[1].bottom = bottom;
- rcontrol[1].top = bottom - max / 2;
- if (!pGetTouchInputInfo || !pCloseTouchInputHandle)
- return;
- UINT cInputs = LOWORD(wParam);
- PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
- if (NULL != pInputs) {
- if (pGetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) {
- for (int i = 0; i < cInputs; i++) {
- PTOUCHINPUT ti = &pInputs[i];
- int x = ti->x / 100;
- int y = ti->y / 100;
- if (x != touch_prev_x || y != touch_prev_y || ti->dwFlags != touch_prev_flags) {
- touch_prev_x = x;
- touch_prev_y = y;
- touch_prev_flags = ti->dwFlags;
- #if TOUCH_DEBUG
- // write_log(_T("ID=%08x FLAGS=%08x MASK=%08x X=%d Y=%d \n"), ti->dwID, ti->dwFlags, ti->dwMask, x, y);
- #endif
- if (is_touch_lightpen() || (currprefs.input_tablet == TABLET_OFF && dinput_winmouse() < 0)) {
- if (ti->dwFlags & TOUCHEVENTF_DOWN)
- touch_event(ti->dwID, 1, x, y, rcontrol);
- if (ti->dwFlags & TOUCHEVENTF_UP)
- touch_event(ti->dwID, -1, x, y, rcontrol);
- if (ti->dwFlags & TOUCHEVENTF_MOVE)
- touch_event(ti->dwID, 0, x, y, rcontrol);
- }
- if (ti->dwFlags & TOUCHEVENTF_PRIMARY) {
- if (x < rgui.left || x >= rgui.right || y < rgui.top || y >= rgui.bottom) {
- touch_touched = 0;
- } else {
- if (ti->dwFlags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_MOVE)) {
- if (!touch_touched && (ti->dwFlags & TOUCHEVENTF_DOWN)) {
- touch_touched = 1;
- touch_time = ti->dwTime;
- #if TOUCH_DEBUG
- write_log(_T("TOUCHED %d\n"), touch_time);
- #endif
- }
- } else if (ti->dwFlags & TOUCHEVENTF_UP) {
- if (touch_touched && ti->dwTime >= touch_time + 2 * 1000) {
- #if TOUCH_DEBUG
- write_log(_T("TOUCHED GUI\n"), touch_time);
- #endif
- inputdevice_add_inputcode(AKS_ENTERGUI, 1, NULL);
- }
- #if TOUCH_DEBUG
- write_log(_T("RELEASED\n"));
- #endif
- touch_touched = 0;
- }
- }
- }
- }
- }
- pCloseTouchInputHandle((HTOUCHINPUT)lParam);
- }
- delete [] pInputs;
- }
- }
- #endif
- static void resizing(struct AmigaMonitor *mon, int mode, RECT *r)
- {
- int nw = (r->right - r->left) + mon->ratio_adjust_x;
- int nh = (r->bottom - r->top) + mon->ratio_adjust_y;
- if (!mon->ratio_sizing || !mon->ratio_width || !mon->ratio_height)
- return;
- if (mode == WMSZ_BOTTOM || mode == WMSZ_TOP) {
- int w = nh * mon->ratio_width / mon->ratio_height;
- r->right = r->left + w - mon->ratio_adjust_x;
- } else if (mode == WMSZ_LEFT || mode == WMSZ_RIGHT) {
- int h = nw * mon->ratio_height / mon->ratio_width;
- r->bottom = r->top + h - mon->ratio_adjust_y;
- } else if (mode == WMSZ_BOTTOMRIGHT || mode == WMSZ_BOTTOMLEFT || mode == WMSZ_TOPLEFT || mode == WMSZ_TOPRIGHT) {
- int w = r->right - r->left;
- int h = r->bottom - r->top;
- if (nw * mon->ratio_height > nh * mon->ratio_width) {
- h = nw * mon->ratio_height / mon->ratio_width;
- } else {
- w = nh * mon->ratio_width / mon->ratio_height;
- }
- if (mode == WMSZ_BOTTOMRIGHT) {
- r->bottom = r->top + h;
- r->right = r->left + w;
- } else if (mode == WMSZ_BOTTOMLEFT) {
- r->bottom = r->top + h;
- r->left = r->right - w;
- } else if (mode == WMSZ_TOPLEFT) {
- r->top = r->bottom - h;
- r->left = r->right - w;
- } else if (mode == WMSZ_TOPRIGHT) {
- r->top = r->bottom - h;
- r->right = r->left + w;
- }
- }
- }
- #define MSGDEBUG 1
- static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- struct AmigaMonitor *mon = NULL;
- HDC hDC;
- int mx, my;
- int istablet = (GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700;
- static int mm, recursive, ignoremousemove;
- static bool ignorelbutton;
- for (int i = 0; i < MAX_AMIGAMONITORS; i++) {
- if (hWnd == AMonitors[i].hAmigaWnd) {
- mon = &AMonitors[i];
- break;
- }
- if (hWnd == AMonitors[i].hMainWnd) {
- mon = &AMonitors[i];
- break;
- }
- }
- if (!mon) {
- mon = &AMonitors[0];
- }
- #if MSGDEBUG > 1
- write_log (_T("AWP: %p %08x %08x %08x\n"), hWnd, message, wParam, lParam);
- #endif
- if (all_events_disabled)
- return 0;
- switch (message)
- {
- case WM_QUERYENDSESSION:
- {
- if (hWnd == mon->hMainWnd && currprefs.win32_shutdown_notification && !rp_isactive()) {
- return FALSE;
- }
- return TRUE;
- }
- case WM_ENDSESSION:
- return FALSE;
- case WM_INPUT:
- monitor_off = 0;
- handle_rawinput (lParam);
- DefWindowProc (hWnd, message, wParam, lParam);
- return 0;
- case WM_INPUT_DEVICE_CHANGE:
- if (is_hid_rawinput()) {
- if (handle_rawinput_change(lParam, wParam)) {
- // wait 2 seconds before re-enumerating
- if (device_change_timer)
- KillTimer(hWnd, 4);
- device_change_timer = 1;
- SetTimer(hWnd, 4, 2000, NULL);
- }
- return 0;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- switch (message)
- {
- case WM_SETFOCUS:
- //write_log(_T("WM_SETFOCUS\n"));
- winuae_active(mon, hWnd, minimized);
- unsetm…
Large files files are truncated, but you can click here to view the full file