Merge pull request #380 from OV2/win8pointers

Win8 touch support
This commit is contained in:
Squarepusher 2013-11-06 10:18:16 -08:00
commit 593bcf9b29
5 changed files with 167 additions and 12 deletions

View File

@ -175,6 +175,13 @@ static void create_gl_context(HWND hwnd)
}
}
#ifdef __cplusplus
extern "C"
#endif
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam);
static void *dinput;
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{
@ -226,7 +233,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
}
return 0;
}
if (dinput_handle_message(dinput, message, wparam, lparam))
return 0;
return DefWindowProc(hwnd, message, wparam, lparam);
}
@ -512,7 +520,7 @@ static void gfx_ctx_destroy(void)
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
{
void *dinput = input_dinput.init();
dinput = input_dinput.init();
*input = dinput ? &input_dinput : NULL;
*input_data = dinput;
}

View File

@ -60,11 +60,17 @@ namespace Monitor
static unsigned cur_mon_id;
}
#ifdef __cplusplus
extern "C"
#endif
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam);
namespace Callback
{
static bool quit = false;
static D3DVideo *curD3D = nullptr;
static HRESULT d3d_err;
static void *dinput;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
@ -98,10 +104,9 @@ namespace Callback
if (new_width && new_height)
curD3D->resize(new_width, new_height);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
if (dinput_handle_message(dinput, message, wParam, lParam))
return 0;
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
@ -1317,9 +1322,9 @@ static void *d3d9_init(const video_info_t *info, const input_driver_t **input,
if (input && input_data)
{
void *dinput = input_dinput.init();
*input = dinput ? &input_dinput : nullptr;
*input_data = dinput;
Callback::dinput = input_dinput.init();
*input = Callback::dinput ? &input_dinput : nullptr;
*input_data = Callback::dinput;
}
return vid;

View File

@ -27,10 +27,19 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <windowsx.h>
// Context has to be global as joypads also ride on this context.
static LPDIRECTINPUT8 g_ctx;
struct pointer_status
{
int pointer_id;
int pointer_x;
int pointer_y;
struct pointer_status *next;
};
struct dinput_input
{
LPDIRECTINPUTDEVICE8 keyboard;
@ -43,6 +52,7 @@ struct dinput_input
int mouse_x;
int mouse_y;
bool mouse_l, mouse_r, mouse_m;
struct pointer_status pointer_head; // dummy head for easier iteration
};
struct dinput_joypad
@ -234,11 +244,22 @@ static int16_t dinput_mouse_state(struct dinput_input *di, unsigned id)
static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, unsigned id, bool screen)
{
if (index != 0)
int16_t res_x = 0, res_y = 0, res_screen_x = 0, res_screen_y = 0;
unsigned num = 0;
struct pointer_status *check_pos = di->pointer_head.next;
while (check_pos && num < index)
{
num++;
check_pos = check_pos->next;
}
if (!check_pos && index > 0) // index = 0 has mouse fallback
return 0;
int16_t res_x = 0, res_y = 0, res_screen_x = 0, res_screen_y = 0;
bool valid = input_translate_coord_viewport(di->mouse_x, di->mouse_y,
int x = check_pos ? check_pos->pointer_x : di->mouse_x;
int y = check_pos ? check_pos->pointer_y : di->mouse_y;
bool pointer_down = check_pos ? true : di->mouse_l;
bool valid = input_translate_coord_viewport(x, y,
&res_x, &res_y, &res_screen_x, &res_screen_y);
if (!valid)
@ -262,7 +283,7 @@ static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, uns
case RETRO_DEVICE_ID_POINTER_Y:
return res_y;
case RETRO_DEVICE_ID_POINTER_PRESSED:
return di->mouse_l;
return pointer_down;
default:
return 0;
}
@ -299,6 +320,116 @@ static int16_t dinput_input_state(void *data,
}
}
// these are defined in later SDKs, thus ifdeffed
#ifndef WM_POINTERUPDATE
#define WM_POINTERUPDATE 0x0245
#endif
#ifndef WM_POINTERDOWN
#define WM_POINTERDOWN 0x0246
#endif
#ifndef WM_POINTERUP
#define WM_POINTERUP 0x0247
#endif
#ifndef GET_POINTERID_WPARAM
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
#endif
// stores x/y in client coordinates
void dinput_pointer_store_pos(struct pointer_status *pointer, WPARAM lParam)
{
POINT point;
point.x = GET_X_LPARAM(lParam);
point.y = GET_Y_LPARAM(lParam);
ScreenToClient((HWND)driver.video_window, &point);
pointer->pointer_x = point.x;
pointer->pointer_y = point.y;
}
void dinput_add_pointer(struct dinput_input *di, struct pointer_status *new_pointer)
{
new_pointer->next = NULL;
struct pointer_status *insert_pos = &di->pointer_head;
while (insert_pos->next)
insert_pos = insert_pos->next;
insert_pos->next = new_pointer;
}
void dinput_delete_pointer(struct dinput_input *di, int pointer_id)
{
struct pointer_status *check_pos = &di->pointer_head;
while (check_pos && check_pos->next)
{
if (check_pos->next->pointer_id == pointer_id)
{
struct pointer_status *to_delete = check_pos->next;
check_pos->next = check_pos->next->next;
free(to_delete);
}
check_pos = check_pos->next;
}
}
struct pointer_status *dinput_find_pointer(struct dinput_input *di, int pointer_id)
{
struct pointer_status *check_pos = di->pointer_head.next;
while (check_pos)
{
if (check_pos->pointer_id == pointer_id)
break;
check_pos = check_pos->next;
}
return check_pos;
}
void dinput_clear_pointers(struct dinput_input *di)
{
struct pointer_status *pointer = &di->pointer_head;
while (pointer->next)
{
struct pointer_status *del = pointer->next;
pointer->next = pointer->next->next;
free(del);
}
}
#ifdef __cplusplus
extern "C"
#endif
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam)
{
struct dinput_input *di = (struct dinput_input *)dinput;
/* WM_POINTERDOWN arrives for each new touch event with a new id - add to list
WM_POINTERUP arrives once the pointer is no longer down - remove from list
WM_POINTERUPDATE arrives for both pressed and hovering pointers - ignore hovering
*/
switch (message)
{
case WM_POINTERDOWN:
{
struct pointer_status *new_pointer = (struct pointer_status *)malloc(sizeof(struct pointer_status));
new_pointer->pointer_id = GET_POINTERID_WPARAM(wParam);
dinput_pointer_store_pos(new_pointer, lParam);
dinput_add_pointer(di, new_pointer);
return true;
}
case WM_POINTERUP:
{
int pointer_id = GET_POINTERID_WPARAM(wParam);
dinput_delete_pointer(di, pointer_id);
return true;
}
case WM_POINTERUPDATE:
{
int pointer_id = GET_POINTERID_WPARAM(wParam);
struct pointer_status *pointer = dinput_find_pointer(di, pointer_id);
if (pointer)
dinput_pointer_store_pos(pointer, lParam);
return true;
}
}
return false;
}
static void dinput_free(void *data)
{
struct dinput_input *di = (struct dinput_input*)data;
@ -310,6 +441,8 @@ static void dinput_free(void *data)
di->joypad->destroy();
g_ctx = hold_ctx;
dinput_clear_pointers(di); // clear any leftover pointers
if (di->keyboard)
IDirectInputDevice8_Release(di->keyboard);

8
media/rarch.manifest Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
</assembly>

View File

@ -1 +1,2 @@
1 ICON "retroarch-icon.ico"
1 24 "rarch.manifest"