diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index 2fc2e01701..a3cd769801 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -923,7 +923,9 @@ static LRESULT CALLBACK wnd_proc_common( return 0; } -static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd, +/* XP and higher */ +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) +static LRESULT CALLBACK wnd_proc_common_raw_internal(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { LRESULT ret; @@ -958,24 +960,9 @@ static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd, if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80) mod |= RETROKMOD_META; - { - input_driver_t *driver = input_get_ptr(); - -#if _WIN32_WINNT >= 0x0501 /* XP */ -#ifdef HAVE_WINRAWINPUT - if (driver == &input_winraw) - keysym = (unsigned)wparam; - else -#endif -#endif -#ifdef HAVE_DINPUT - /* extended keys will map to dinput if the high bit is set */ - if (driver == &input_dinput && (lparam >> 24 & 0x1)) - keysym |= 0x80; -#else - /* fix key binding issues on winraw when DirectInput is not available */ -#endif - } + keysym = (unsigned)wparam; + /* fix key binding issues on winraw when + * DirectInput is not available */ keycode = input_keymaps_translate_keysym_to_rk(keysym); @@ -1004,15 +991,6 @@ static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd, #if _WIN32_WINNT >= 0x0500 /* 2K */ if (g_win32->taskbar_message && message == g_win32->taskbar_message) taskbar_is_created = true; -#endif -#ifdef HAVE_DINPUT - if (input_get_ptr() == &input_dinput) - { - void* input_data = input_get_data(); - if (input_data && dinput_handle_message(input_data, - message, wparam, lparam)) - return 0; - } #endif break; case WM_DROPFILES: @@ -1036,9 +1014,110 @@ static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd, return DefWindowProc(hwnd, message, wparam, lparam); } +#endif + +#ifdef HAVE_DINPUT +static LRESULT CALLBACK wnd_proc_common_dinput_internal(HWND hwnd, + UINT message, WPARAM wparam, LPARAM lparam) +{ + LRESULT ret; + bool keydown = true; + bool quit = false; + win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; + + switch (message) + { + case WM_KEYUP: /* Key released */ + case WM_SYSKEYUP: /* Key released */ + keydown = false; + /* fall-through */ + case WM_KEYDOWN: /* Key pressed */ + case WM_SYSKEYDOWN: /* Key pressed */ + quit = true; + { + uint16_t mod = 0; + unsigned keycode = 0; + unsigned keysym = (lparam >> 16) & 0xff; + + if (GetKeyState(VK_SHIFT) & 0x80) + mod |= RETROKMOD_SHIFT; + if (GetKeyState(VK_CONTROL) & 0x80) + mod |= RETROKMOD_CTRL; + if (GetKeyState(VK_MENU) & 0x80) + mod |= RETROKMOD_ALT; + if (GetKeyState(VK_CAPITAL) & 0x81) + mod |= RETROKMOD_CAPSLOCK; + if (GetKeyState(VK_SCROLL) & 0x81) + mod |= RETROKMOD_SCROLLOCK; + if ((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x80) + mod |= RETROKMOD_META; + + /* extended keys will map to dinput if the high bit is set */ + if ((lparam >> 24 & 0x1)) + keysym |= 0x80; + + keycode = input_keymaps_translate_keysym_to_rk(keysym); + + input_keyboard_event(keydown, keycode, + 0, mod, RETRO_DEVICE_KEYBOARD); + + if (message != WM_SYSKEYDOWN) + return 0; + + if ( + wparam == VK_F10 || + wparam == VK_MENU || + wparam == VK_RSHIFT + ) + return 0; + } + break; + case WM_MOUSEMOVE: + case WM_POINTERDOWN: + case WM_POINTERUP: + case WM_POINTERUPDATE: + case WM_DEVICECHANGE: + case WM_MOUSEWHEEL: + case WM_MOUSEHWHEEL: + case WM_NCLBUTTONDBLCLK: +#if _WIN32_WINNT >= 0x0500 /* 2K */ + if (g_win32->taskbar_message && message == g_win32->taskbar_message) + taskbar_is_created = true; +#endif + { + void* input_data = input_get_data(); + if (input_data && dinput_handle_message(input_data, + message, wparam, lparam)) + return 0; + } + break; + case WM_DROPFILES: + case WM_SYSCOMMAND: + case WM_CHAR: + case WM_CLOSE: + case WM_DESTROY: + case WM_QUIT: + case WM_MOVE: + case WM_SIZE: + case WM_COMMAND: + ret = wnd_proc_common(&quit, hwnd, message, wparam, lparam); + if (quit) + return ret; +#if _WIN32_WINNT >= 0x0500 /* 2K */ + if (g_win32->taskbar_message && message == g_win32->taskbar_message) + taskbar_is_created = true; +#endif + break; + } + + return DefWindowProc(hwnd, message, wparam, lparam); +} +#endif #if defined(HAVE_D3D) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12) -LRESULT CALLBACK WndProcD3D(HWND hwnd, UINT message, + +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) +LRESULT CALLBACK wnd_proc_d3d_raw(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; @@ -1052,12 +1131,34 @@ LRESULT CALLBACK WndProcD3D(HWND hwnd, UINT message, return 0; } - return wnd_proc_common_internal(hwnd, message, wparam, lparam); + return wnd_proc_common_raw_internal(hwnd, message, wparam, lparam); } #endif +#ifdef HAVE_DINPUT +LRESULT CALLBACK wnd_proc_d3d_dinput(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) +{ + win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; + + if (message == WM_CREATE) + { + if (DragAcceptFiles_func) + DragAcceptFiles_func(hwnd, true); + + g_win32_inited = true; + return 0; + } + + return wnd_proc_common_dinput_internal(hwnd, message, wparam, lparam); +} +#endif + +#endif + #if defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE) -LRESULT CALLBACK WndProcWGL(HWND hwnd, UINT message, +#ifdef HAVE_DINPUT +LRESULT CALLBACK wnd_proc_wgl_dinput(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { LRESULT ret; @@ -1071,12 +1172,33 @@ LRESULT CALLBACK WndProcWGL(HWND hwnd, UINT message, return 0; } - return wnd_proc_common_internal(hwnd, message, wparam, lparam); + return wnd_proc_common_dinput_internal(hwnd, message, wparam, lparam); } #endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) +LRESULT CALLBACK wnd_proc_wgl_raw(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) +{ + LRESULT ret; + win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; + + if (message == WM_CREATE) + { + create_wgl_context(hwnd, &g_win32->quit); + if (DragAcceptFiles_func) + DragAcceptFiles_func(hwnd, true); + return 0; + } + + return wnd_proc_common_raw_internal(hwnd, message, wparam, lparam); +} +#endif +#endif + #ifdef HAVE_VULKAN -LRESULT CALLBACK WndProcVK(HWND hwnd, UINT message, +#ifdef HAVE_DINPUT +LRESULT CALLBACK wnd_proc_vk_dinput(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; @@ -1089,12 +1211,32 @@ LRESULT CALLBACK WndProcVK(HWND hwnd, UINT message, return 0; } - return wnd_proc_common_internal(hwnd, message, wparam, lparam); + return wnd_proc_common_dinput_internal(hwnd, message, wparam, lparam); } #endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) +LRESULT CALLBACK wnd_proc_vk_raw(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) +{ + win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; + + if (message == WM_CREATE) + { + create_vk_context(hwnd, &g_win32->quit); + if (DragAcceptFiles_func) + DragAcceptFiles_func(hwnd, true); + return 0; + } + + return wnd_proc_common_raw_internal(hwnd, message, wparam, lparam); +} +#endif +#endif + #ifdef HAVE_GDI -LRESULT CALLBACK WndProcGDI(HWND hwnd, UINT message, +#ifdef HAVE_DINPUT +LRESULT CALLBACK wnd_proc_gdi_dinput(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { LRESULT ret; @@ -1139,10 +1281,61 @@ LRESULT CALLBACK WndProcGDI(HWND hwnd, UINT message, #endif } - return wnd_proc_common_internal(hwnd, message, wparam, lparam); + return wnd_proc_common_dinput_internal(hwnd, message, wparam, lparam); } #endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) +LRESULT CALLBACK wnd_proc_gdi_raw(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam) +{ + LRESULT ret; + win32_common_state_t *g_win32 = (win32_common_state_t*)&win32_st; + + if (message == WM_CREATE) + { + create_gdi_context(hwnd, &g_win32->quit); + if (DragAcceptFiles_func) + DragAcceptFiles_func(hwnd, true); + return 0; + } + else if (message == WM_PAINT) + { + gdi_t *gdi = (gdi_t*)video_driver_get_ptr(false); + + if (gdi && gdi->memDC) + { + gdi->bmp_old = (HBITMAP)SelectObject(gdi->memDC, gdi->bmp); + + /* Draw video content */ + StretchBlt( + gdi->winDC, + 0, + 0, + gdi->screen_width, + gdi->screen_height, + gdi->memDC, + 0, + 0, + gdi->video_width, + gdi->video_height, + SRCCOPY); + + SelectObject(gdi->memDC, gdi->bmp_old); + } + +#if _WIN32_WINNT >= 0x0500 /* 2K */ + if ( g_win32->taskbar_message + && message == g_win32->taskbar_message) + taskbar_is_created = true; +#endif + } + + return wnd_proc_common_raw_internal(hwnd, message, wparam, lparam); +} +#endif +#endif + bool win32_window_create(void *data, unsigned style, RECT *mon_rect, unsigned width, unsigned height, bool fullscreen) diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index f005b56781..1558b7ab79 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -123,21 +123,29 @@ bool win32_taskbar_is_created(void); float win32_get_refresh_rate(void *data); #if defined(HAVE_D3D8) || defined(HAVE_D3D9) || defined (HAVE_D3D10) || defined (HAVE_D3D11) || defined (HAVE_D3D12) -LRESULT CALLBACK WndProcD3D(HWND hwnd, UINT message, +LRESULT CALLBACK wnd_proc_d3d_dinput(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam); +LRESULT CALLBACK wnd_proc_d3d_raw(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); #endif #if defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE) -LRESULT CALLBACK WndProcWGL(HWND hwnd, UINT message, +LRESULT CALLBACK wnd_proc_wgl_dinput(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam); +LRESULT CALLBACK wnd_proc_wgl_raw(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); #endif #if defined(HAVE_VULKAN) -LRESULT CALLBACK WndProcVK(HWND hwnd, UINT message, +LRESULT CALLBACK wnd_proc_vk_dinput(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam); +LRESULT CALLBACK wnd_proc_vk_raw(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); #endif -LRESULT CALLBACK WndProcGDI(HWND hwnd, UINT message, +LRESULT CALLBACK wnd_proc_gdi_dinput(HWND hwnd, UINT message, + WPARAM wparam, LPARAM lparam); +LRESULT CALLBACK wnd_proc_gdi_raw(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); #ifdef _XBOX diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index 38132c3a03..ce19613978 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -621,7 +621,14 @@ static void *d3d10_gfx_init(const video_info_t* video, #endif #ifdef HAVE_MONITOR win32_monitor_init(); - wndclass.lpfnWndProc = WndProcD3D; +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + wndclass.lpfnWndProc = wnd_proc_d3d_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + wndclass.lpfnWndProc = wnd_proc_d3d_raw; +#endif #ifdef HAVE_WINDOW win32_window_init(&wndclass, true, NULL); #endif diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 8ce5031c92..473e7ced02 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -656,7 +656,14 @@ static void *d3d11_gfx_init(const video_info_t* video, #endif #ifdef HAVE_MONITOR win32_monitor_init(); - wndclass.lpfnWndProc = WndProcD3D; +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + wndclass.lpfnWndProc = wnd_proc_d3d_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + wndclass.lpfnWndProc = wnd_proc_d3d_raw; +#endif #ifdef HAVE_WINDOW win32_window_init(&wndclass, true, NULL); #endif diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 80c8f19e93..a6d47e8526 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -913,7 +913,14 @@ static void *d3d12_gfx_init(const video_info_t* video, #endif #ifdef HAVE_MONITOR win32_monitor_init(); - wndclass.lpfnWndProc = WndProcD3D; +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + wndclass.lpfnWndProc = wnd_proc_d3d_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + wndclass.lpfnWndProc = wnd_proc_d3d_raw; +#endif #ifdef HAVE_WINDOW win32_window_init(&wndclass, true, NULL); #endif diff --git a/gfx/drivers/d3d8.c b/gfx/drivers/d3d8.c index a9a30d0ece..592912417a 100644 --- a/gfx/drivers/d3d8.c +++ b/gfx/drivers/d3d8.c @@ -1148,7 +1148,14 @@ static bool d3d8_init_internal(d3d8_video_t *d3d, #ifdef HAVE_WINDOW memset(&d3d->windowClass, 0, sizeof(d3d->windowClass)); - d3d->windowClass.lpfnWndProc = WndProcD3D; +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + d3d->windowClass.lpfnWndProc = wnd_proc_d3d_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + d3d->windowClass.lpfnWndProc = wnd_proc_d3d_raw; +#endif win32_window_init(&d3d->windowClass, true, NULL); #endif diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index 298f78d06e..42c8277e4a 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -1158,7 +1158,14 @@ static bool d3d9_init_internal(d3d9_video_t *d3d, #ifdef HAVE_WINDOW memset(&d3d->windowClass, 0, sizeof(d3d->windowClass)); - d3d->windowClass.lpfnWndProc = WndProcD3D; +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + d3d->windowClass.lpfnWndProc = wnd_proc_d3d_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + d3d->windowClass.lpfnWndProc = wnd_proc_d3d_raw; +#endif win32_window_init(&d3d->windowClass, true, NULL); #endif diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index 01cc787e0c..8eedbc9763 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -82,7 +82,8 @@ static void gfx_ctx_gdi_get_video_size( static bool gfx_ctx_gdi_init(void) { - WNDCLASSEX wndclass = {0}; + WNDCLASSEX wndclass = {0}; + settings_t *settings = config_get_ptr(); if (g_win32_inited) return true; @@ -90,7 +91,15 @@ static bool gfx_ctx_gdi_init(void) win32_window_reset(); win32_monitor_init(); - wndclass.lpfnWndProc = WndProcGDI; +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + wndclass.lpfnWndProc = wnd_proc_gdi_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + wndclass.lpfnWndProc = wnd_proc_gdi_raw; +#endif + if (!win32_window_init(&wndclass, true, NULL)) return false; return true; diff --git a/gfx/drivers_context/w_vk_ctx.c b/gfx/drivers_context/w_vk_ctx.c index 12114926e2..273521cca3 100644 --- a/gfx/drivers_context/w_vk_ctx.c +++ b/gfx/drivers_context/w_vk_ctx.c @@ -216,7 +216,17 @@ static void *gfx_ctx_w_vk_init(void *video_driver) win32_window_reset(); win32_monitor_init(); - wndclass.lpfnWndProc = WndProcVK; + { + settings_t *settings = config_get_ptr(); +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + wndclass.lpfnWndProc = wnd_proc_vk_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + wndclass.lpfnWndProc = wnd_proc_vk_raw; +#endif + } if (!win32_window_init(&wndclass, true, NULL)) goto error; diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 0ed6959bee..96f5badf00 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -631,7 +631,17 @@ static void *gfx_ctx_wgl_init(void *video_driver) win32_window_reset(); win32_monitor_init(); - wndclass.lpfnWndProc = WndProcWGL; + { + settings_t *settings = config_get_ptr(); +#ifdef HAVE_DINPUT + if (string_is_equal(settings->arrays.input_driver, "dinput")) + wndclass.lpfnWndProc = wnd_proc_wgl_dinput; +#endif +#if _WIN32_WINNT >= 0x0501 && defined(HAVE_WINRAWINPUT) + if (string_is_equal(settings->arrays.input_driver, "raw")) + wndclass.lpfnWndProc = wnd_proc_wgl_raw; +#endif + } if (!win32_window_init(&wndclass, true, NULL)) goto error;