From 53c6b7fce6a70915464b692d0142989d456633cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincas=20Mili=C5=ABnas?= Date: Mon, 11 Jul 2011 21:23:32 +0300 Subject: [PATCH 17/20] server+user32: Added RegisterRawInputDevices implementation (try 16) --- dlls/user32/input.c | 200 ++++++++++++++++++++++++++++++++++++++++++++- dlls/user32/tests/input.c | 74 ++++++++-------- server/protocol.def | 23 +++++ server/raw_input.c | 53 ++++++++++++ 4 files changed, 310 insertions(+), 40 deletions(-) diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 5923fac..432410d 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -511,17 +511,211 @@ UINT WINAPI GetRawInputDeviceList(PRAWINPUTDEVICELIST pRawInputDeviceList, PUINT return ret ? result : (UINT)-1; } +#define HID_USAGE_PAGE_GENERIC ((unsigned short)0x01) +#define HID_USAGE_GENERIC_MOUSE ((unsigned short)0x02) +#define HID_USAGE_GENERIC_KEYBOARD ((unsigned short)0x06) /****************************************************************** * RegisterRawInputDevices (USER32.@) */ BOOL WINAPI DECLSPEC_HOTPATCH RegisterRawInputDevices(PRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize) { - FIXME("(pRawInputDevices=%p, uiNumDevices=%d, cbSize=%d) stub!\n", pRawInputDevices, uiNumDevices, cbSize); + BOOL result = TRUE; + UINT i, registrations_size = uiNumDevices * sizeof( struct raw_input_device_registration ); + struct raw_input_device_registration *registrations; - return TRUE; -} + TRACE("(pRawInputDevices=%p, uiNumDevices=%d, cbSize=%d)\n", pRawInputDevices, uiNumDevices, cbSize); + + if (pRawInputDevices == NULL || uiNumDevices == 0 || cbSize != sizeof( RAWINPUTDEVICE )) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + registrations = HeapAlloc( GetProcessHeap(), 0, registrations_size ); + if (!registrations) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + + /* Construct and validate registration data */ + for (i = 0; i < uiNumDevices; i++) + { + RAWINPUTDEVICE *device = &pRawInputDevices[i]; + BOOL is_mouse = device->usUsagePage == HID_USAGE_PAGE_GENERIC && + device->usUsage == HID_USAGE_GENERIC_MOUSE; + BOOL is_keyboard = device->usUsagePage == HID_USAGE_PAGE_GENERIC && + device->usUsage == HID_USAGE_GENERIC_KEYBOARD; + UINT device_flags = device->dwFlags, registration_flags = 0; + + if (device->usUsagePage == 0) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + + /* RIDEV_* values can overlap, therefore we need to remove confirmed cases */ + + if ((device_flags & RIDEV_REMOVE) == RIDEV_REMOVE) + { + if (device->hwndTarget != NULL) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + device_flags &= ~RIDEV_REMOVE; + registration_flags |= RAW_INPUT_DEVICE_FLAG_REMOVE; + } + + if ((device_flags & RIDEV_NOHOTKEYS) == RIDEV_NOHOTKEYS && is_keyboard) + { + FIXME("RIDEV_NOHOTKEYS support is not implemented\n"); + device_flags &= ~RIDEV_NOHOTKEYS; + registration_flags |= RAW_INPUT_DEVICE_FLAG_NOHOTKEYS; + } + + if ((device_flags & RIDEV_NOLEGACY) == RIDEV_NOLEGACY && !is_mouse && !is_keyboard) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + else if ((device_flags & RIDEV_NOLEGACY) == RIDEV_NOLEGACY) + { + FIXME("RIDEV_NOLEGACY support is not implemented\n"); + device_flags &= ~RIDEV_NOLEGACY; + registration_flags |= RAW_INPUT_DEVICE_FLAG_NOLEGACY; + + if ((device_flags & RIDEV_CAPTUREMOUSE) == RIDEV_CAPTUREMOUSE && is_mouse) + { + FIXME("RIDEV_CAPTUREMOUSE support is not implemented\n"); + if (device->hwndTarget == NULL) + { + SetLastError( ERROR_INVALID_FLAGS ); + result = FALSE; + break; + } + device_flags &= ~RIDEV_CAPTUREMOUSE; + registration_flags |= RAW_INPUT_DEVICE_FLAG_CAPTUREMOUSE; + } + /* RIDEV_CAPTUREMOUSE && is_keyboard is not possible, because + RIDEV_CAPTUREMOUSE == RIDEV_NOHOTKEYS */ + if ((device_flags & RIDEV_APPKEYS) == RIDEV_APPKEYS && is_keyboard) + { + FIXME("RIDEV_APPKEYS support is not implemented\n"); + device_flags &= ~RIDEV_APPKEYS; + registration_flags |= RAW_INPUT_DEVICE_FLAG_APPKEYS; + } + else if ((device_flags & RIDEV_APPKEYS) == RIDEV_APPKEYS && is_mouse) + { + SetLastError( ERROR_INVALID_FLAGS ); + result = FALSE; + break; + } + } + else if ((device_flags & RIDEV_CAPTUREMOUSE) == RIDEV_CAPTUREMOUSE || + (device_flags & RIDEV_APPKEYS) == RIDEV_APPKEYS) + { + SetLastError( ERROR_INVALID_FLAGS ); + result = FALSE; + break; + } + + if ((device_flags & RIDEV_PAGEONLY) == RIDEV_PAGEONLY && device->usUsage == 0) + { + device_flags &= ~RIDEV_PAGEONLY; + registration_flags |= RAW_INPUT_DEVICE_FLAG_PAGEONLY; + } + else if (((device_flags & RIDEV_PAGEONLY) == RIDEV_PAGEONLY && device->usUsage != 0) || + ((device_flags & RIDEV_PAGEONLY) != RIDEV_PAGEONLY && device->usUsage == 0)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + + if ((device_flags & RIDEV_EXCLUDE) == RIDEV_EXCLUDE) + { + if (device->hwndTarget != NULL) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + device_flags &= ~RIDEV_EXCLUDE; + registration_flags |= RAW_INPUT_DEVICE_FLAG_EXCLUDE; + } + + if ((device_flags & RIDEV_INPUTSINK) == RIDEV_INPUTSINK) + { + FIXME("RIDEV_INPUTSINK support is not implemented\n"); + if (device->hwndTarget == NULL) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + device_flags &= ~RIDEV_INPUTSINK; + registration_flags |= RAW_INPUT_DEVICE_FLAG_INPUTSINK; + } + + if ((device_flags & RIDEV_EXINPUTSINK) == RIDEV_EXINPUTSINK) + { + FIXME("RIDEV_EXINPUTSINK support is not implemented\n"); + if (device->hwndTarget == NULL) + { + SetLastError( ERROR_INVALID_PARAMETER ); + result = FALSE; + break; + } + device_flags &= ~RIDEV_EXINPUTSINK; + registration_flags |= RAW_INPUT_DEVICE_FLAG_EXINPUTSINK; + } + + if ((device_flags & RIDEV_DEVNOTIFY) == RIDEV_DEVNOTIFY) + { + FIXME("RIDEV_DEVNOTIFY support is not implemented\n"); + device_flags &= ~RIDEV_DEVNOTIFY; + registration_flags |= RAW_INPUT_DEVICE_FLAG_DEVNOTIFY; + } + + /* If anything is left, it's invalid */ + if (device_flags) + { + SetLastError( ERROR_INVALID_FLAGS ); + result = FALSE; + break; + } + + registrations[i].usage_page = device->usUsagePage; + registrations[i].usage = device->usUsage; + registrations[i].flags = registration_flags; + registrations[i].target_window = wine_server_user_handle( device->hwndTarget ); + } + + if (result) + { + BOOL ret; + + SERVER_START_REQ( register_raw_input_devices ) + { + req->count = uiNumDevices; + wine_server_add_data( req, registrations, registrations_size ); + ret = !wine_server_call_err( req ); + } + SERVER_END_REQ; + + result = ret; + } + + HeapFree( GetProcessHeap(), 0, registrations ); + + return result; +} /****************************************************************** * GetRawInputData (USER32.@) diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 543912a..d2ac666 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1945,14 +1945,14 @@ static void test_basic_get_registered_raw_input_devices(void) ret2 = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); ok(ret2 == 0, "GetRegisteredRawInputDevices returned wrong value: " "expected 0, got %u\n", ret2); - todo_wine ok(count == 1, "GetRegisteredRawInputDevices returned incorrect registration count: " + ok(count == 1, "GetRegisteredRawInputDevices returned incorrect registration count: " "expected 1, got %u\n", count); memset(&devices[0], 0xFF, sizeof(RAWINPUTDEVICE)); ret2 = pGetRegisteredRawInputDevices(&devices[0], &count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(ret2 == 1, "GetRegisteredRawInputDevices returned wrong value: " + ok(ret2 == 1, "GetRegisteredRawInputDevices returned wrong value: " "expected 1, got %u\n", ret2); - todo_wine ok(memcmp(&device, &devices[0], sizeof(RAWINPUTDEVICE)) == 0, + ok(memcmp(&device, &devices[0], sizeof(RAWINPUTDEVICE)) == 0, "GetRegisteredRawInputDevices returned incorrect raw input device registration\n"); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); @@ -1961,9 +1961,9 @@ static void test_basic_get_registered_raw_input_devices(void) /* Verify that there is still the only one registration */ memset(&devices[0], 0xFF, sizeof(RAWINPUTDEVICE)); ret2 = pGetRegisteredRawInputDevices(&devices[0], &count, sizeof(RAWINPUTDEVICE)); - todo_wine ok(ret2 == 1, "GetRegisteredRawInputDevices returned wrong value: " + ok(ret2 == 1, "GetRegisteredRawInputDevices returned wrong value: " "expected 1, got %u\n", ret2); - todo_wine ok(memcmp(&device, &devices[0], sizeof(RAWINPUTDEVICE)) == 0, + ok(memcmp(&device, &devices[0], sizeof(RAWINPUTDEVICE)) == 0, "GetRegisteredRawInputDevices returned incorrect raw input device registration\n"); device.dwFlags = RIDEV_REMOVE; @@ -1996,15 +1996,15 @@ static void test_basic_register_raw_input_devices(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(NULL, 0, 0); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(NULL, 0, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); device.usUsagePage = 0; @@ -2014,15 +2014,15 @@ static void test_basic_register_raw_input_devices(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 0, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); device.usUsagePage = HID_USAGE_PAGE_GENERIC; @@ -2077,8 +2077,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_PAGEONLY requires usUsage to be 0 */ @@ -2088,8 +2088,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_EXCLUDE requires usUsage to be non-0 */ @@ -2099,8 +2099,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_NOLEGACY cannot be used with other device then mouse and keyboard */ @@ -2110,8 +2110,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_INPUTSINK requires hwndTarget to be non-null */ @@ -2121,8 +2121,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_PARAMETER, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_CAPTUREMOUSE must be combined with RIDEV_NOLEGACY @@ -2133,8 +2133,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_APPKEYS must be combined with RIDEV_NOLEGACY */ @@ -2144,8 +2144,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_APPKEYS cannot be used with mouse */ @@ -2155,8 +2155,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test that RIDEV_NOHOTKEYS cannot be used with mouse */ @@ -2166,8 +2166,8 @@ static void test_raw_input_device_flag_preconditions(void) SetLastError(0xdeadbeef); ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Test reaction to an invalid flag */ @@ -2178,8 +2178,8 @@ static void test_raw_input_device_flag_preconditions(void) device.hwndTarget = NULL; ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); error = GetLastError(); - todo_wine ok(!ret, "RegisterRawInputDevices should have failed\n"); - todo_wine ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " + ok(!ret, "RegisterRawInputDevices should have failed\n"); + ok(error == ERROR_INVALID_FLAGS, "RegisterRawInputDevices returned " "wrong error code: %u\n", error); /* Assert that no registrations are present */ @@ -2238,7 +2238,7 @@ static void test_extended_register_raw_input_devices(void) ret2 = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); ok(ret2 == 0, "GetRegisteredRawInputDevices returned wrong value: " "expected 0, got %u\n", ret2); - todo_wine ok(count == 1, "GetRegisteredRawInputDevices returned incorrect registration count: " + ok(count == 1, "GetRegisteredRawInputDevices returned incorrect registration count: " "expected 1, got %u\n", count); device.dwFlags = RIDEV_REMOVE; @@ -2292,7 +2292,7 @@ static void test_extended_register_raw_input_devices(void) ret2 = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); ok(ret2 == 0, "GetRegisteredRawInputDevices returned wrong value: " "expected 0, got %u\n", ret2); - todo_wine ok(count == 1, "GetRegisteredRawInputDevices returned incorrect registration count: " + ok(count == 1, "GetRegisteredRawInputDevices returned incorrect registration count: " "expected 1, got %u\n", count); devices[1].dwFlags = RIDEV_REMOVE; @@ -2323,7 +2323,7 @@ static void test_extended_register_raw_input_devices(void) ret2 = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); ok(ret2 == 0, "GetRegisteredRawInputDevices returned wrong value: " "expected 0, got %u\n", ret2); - todo_wine ok(count == 2, "GetRegisteredRawInputDevices returned incorrect registration count: " + ok(count == 2, "GetRegisteredRawInputDevices returned incorrect registration count: " "expected 2, got %u\n", count); devices[0].dwFlags = RIDEV_REMOVE | RIDEV_PAGEONLY; @@ -2370,7 +2370,7 @@ static void test_extended_register_raw_input_devices(void) devices[1].dwFlags = 0; devices[1].hwndTarget = NULL; ret = pRegisterRawInputDevices(devices, 2, sizeof(RAWINPUTDEVICE)); - todo_wine ok(!ret, "RegisterRawInputDevices should fail to register the devices\n"); + ok(!ret, "RegisterRawInputDevices should fail to register the devices\n"); /* Assert that there are no devices registered */ count = 0xdeadbeef; diff --git a/server/protocol.def b/server/protocol.def index 0bdc018..70b3e49 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3392,3 +3392,26 @@ enum coords_relative unsigned int num_devices; /* number of raw input device registrations */ VARARG(devices,bytes); /* RAWINPUTDEVICE structures */ @END + +/* Register raw input devices */ +@REQ(register_raw_input_devices) + unsigned int count; /* number of registrations submitted */ + VARARG(registrations,bytes); /* raw_input_device_registration structures (see below) */ +@END +struct raw_input_device_registration +{ + unsigned short usage_page; /* usage page of the device group to register to */ + unsigned short usage; /* usage id of the device to register to */ + unsigned int flags; /* configuration of the registration (see below) */ + user_handle_t target_window; /* optional window handle to receive input messages */ +}; +#define RAW_INPUT_DEVICE_FLAG_REMOVE 0x0001 +#define RAW_INPUT_DEVICE_FLAG_PAGEONLY 0x0002 +#define RAW_INPUT_DEVICE_FLAG_EXCLUDE 0x0004 +#define RAW_INPUT_DEVICE_FLAG_NOLEGACY 0x0008 +#define RAW_INPUT_DEVICE_FLAG_NOHOTKEYS 0x0010 +#define RAW_INPUT_DEVICE_FLAG_CAPTUREMOUSE 0x0020 +#define RAW_INPUT_DEVICE_FLAG_APPKEYS 0x0040 +#define RAW_INPUT_DEVICE_FLAG_INPUTSINK 0x0080 +#define RAW_INPUT_DEVICE_FLAG_EXINPUTSINK 0x0100 +#define RAW_INPUT_DEVICE_FLAG_DEVNOTIFY 0x0200 diff --git a/server/raw_input.c b/server/raw_input.c index 2869315..e53c14a 100644 --- a/server/raw_input.c +++ b/server/raw_input.c @@ -90,6 +90,49 @@ void release_raw_input( struct list *registrations ) } } +/* Register or unregister a given raw input device registration */ +static void register_raw_input_device( struct raw_input_device_registration *new_registration ) +{ + struct raw_registration *registration; + LIST_FOR_EACH_ENTRY( registration, ¤t->process->raw_registered, + struct raw_registration, entry ) + { + /* * They must be on the same usage page + * both marked as PAGEONLY or + both not marked as PAGEONLY and have identical usage ids */ + if (registration->usage_page != new_registration->usage_page || + (!(registration->flags & RAW_INPUT_DEVICE_FLAG_PAGEONLY && + new_registration->flags & RAW_INPUT_DEVICE_FLAG_PAGEONLY) && + (registration->flags & RAW_INPUT_DEVICE_FLAG_PAGEONLY || + new_registration->flags & RAW_INPUT_DEVICE_FLAG_PAGEONLY || + registration->usage != new_registration->usage))) + continue; + + if (new_registration->flags & RAW_INPUT_DEVICE_FLAG_REMOVE) + { + list_remove( ®istration->entry ); + free( registration ); + return; + } + + /* Update existing registration */ + registration->flags = new_registration->flags; + registration->target_window = new_registration->target_window; + return; + } + + if (new_registration->flags & RAW_INPUT_DEVICE_FLAG_REMOVE || + !(registration = mem_alloc( sizeof( *registration ) ))) + return; + + registration->usage_page = new_registration->usage_page; + registration->usage = new_registration->usage; + registration->flags = new_registration->flags; + registration->target_window = new_registration->target_window; + + list_add_tail( ¤t->process->raw_registered, ®istration->entry ); +} + /* Get the raw input device list */ DECL_HANDLER(get_raw_input_device_list) { @@ -217,3 +260,13 @@ DECL_HANDLER(get_registered_raw_input_devices) index += 1; } } + +/* Register raw input devices */ +DECL_HANDLER(register_raw_input_devices) +{ + struct raw_input_device_registration *registrations = + (struct raw_input_device_registration *)get_req_data(); + unsigned int i; + for (i = 0; i < req->count; i++) + register_raw_input_device( ®istrations[i] ); +} -- 1.7.3.4