2019-06-22 01:33:15 +10:00
|
|
|
use std::{
|
|
|
|
mem::{self, size_of},
|
|
|
|
ptr,
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
};
|
2019-06-22 01:33:15 +10:00
|
|
|
|
|
|
|
use winapi::{
|
|
|
|
ctypes::wchar_t,
|
|
|
|
shared::{
|
|
|
|
hidusage::{HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC},
|
|
|
|
minwindef::{TRUE, UINT, USHORT},
|
|
|
|
windef::HWND,
|
|
|
|
},
|
|
|
|
um::{
|
|
|
|
winnt::HANDLE,
|
|
|
|
winuser::{
|
|
|
|
self, HRAWINPUT, RAWINPUT, RAWINPUTDEVICE, RAWINPUTDEVICELIST, RAWINPUTHEADER,
|
|
|
|
RIDEV_DEVNOTIFY, RIDEV_INPUTSINK, RIDI_DEVICEINFO, RIDI_DEVICENAME, RID_DEVICE_INFO,
|
|
|
|
RID_DEVICE_INFO_HID, RID_DEVICE_INFO_KEYBOARD, RID_DEVICE_INFO_MOUSE, RID_INPUT,
|
|
|
|
RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE,
|
|
|
|
},
|
|
|
|
},
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
};
|
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
use crate::{event::ElementState, platform_impl::platform::util};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn get_raw_input_device_list() -> Option<Vec<RAWINPUTDEVICELIST>> {
|
|
|
|
let list_size = size_of::<RAWINPUTDEVICELIST>() as UINT;
|
|
|
|
|
|
|
|
let mut num_devices = 0;
|
2019-06-22 01:33:15 +10:00
|
|
|
let status =
|
|
|
|
unsafe { winuser::GetRawInputDeviceList(ptr::null_mut(), &mut num_devices, list_size) };
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
if status == UINT::max_value() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut buffer = Vec::with_capacity(num_devices as _);
|
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
let num_stored = unsafe {
|
|
|
|
winuser::GetRawInputDeviceList(buffer.as_ptr() as _, &mut num_devices, list_size)
|
|
|
|
};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
if num_stored == UINT::max_value() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_assert_eq!(num_devices, num_stored);
|
|
|
|
|
|
|
|
unsafe { buffer.set_len(num_devices as _) };
|
|
|
|
|
|
|
|
Some(buffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub enum RawDeviceInfo {
|
|
|
|
Mouse(RID_DEVICE_INFO_MOUSE),
|
|
|
|
Keyboard(RID_DEVICE_INFO_KEYBOARD),
|
|
|
|
Hid(RID_DEVICE_INFO_HID),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<RID_DEVICE_INFO> for RawDeviceInfo {
|
|
|
|
fn from(info: RID_DEVICE_INFO) -> Self {
|
|
|
|
unsafe {
|
|
|
|
match info.dwType {
|
|
|
|
RIM_TYPEMOUSE => RawDeviceInfo::Mouse(*info.u.mouse()),
|
|
|
|
RIM_TYPEKEYBOARD => RawDeviceInfo::Keyboard(*info.u.keyboard()),
|
|
|
|
RIM_TYPEHID => RawDeviceInfo::Hid(*info.u.hid()),
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn get_raw_input_device_info(handle: HANDLE) -> Option<RawDeviceInfo> {
|
2019-06-29 08:07:36 +10:00
|
|
|
let mut info: RID_DEVICE_INFO = unsafe { mem::zeroed() };
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
let info_size = size_of::<RID_DEVICE_INFO>() as UINT;
|
|
|
|
|
|
|
|
info.cbSize = info_size;
|
|
|
|
|
|
|
|
let mut minimum_size = 0;
|
2019-06-22 01:33:15 +10:00
|
|
|
let status = unsafe {
|
|
|
|
winuser::GetRawInputDeviceInfoW(
|
|
|
|
handle,
|
|
|
|
RIDI_DEVICEINFO,
|
|
|
|
&mut info as *mut _ as _,
|
|
|
|
&mut minimum_size,
|
|
|
|
)
|
|
|
|
};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
if status == UINT::max_value() || status == 0 {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_assert_eq!(info_size, status);
|
|
|
|
|
|
|
|
Some(info.into())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_raw_input_device_name(handle: HANDLE) -> Option<String> {
|
|
|
|
let mut minimum_size = 0;
|
2019-06-22 01:33:15 +10:00
|
|
|
let status = unsafe {
|
|
|
|
winuser::GetRawInputDeviceInfoW(handle, RIDI_DEVICENAME, ptr::null_mut(), &mut minimum_size)
|
|
|
|
};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
if status != 0 {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut name: Vec<wchar_t> = Vec::with_capacity(minimum_size as _);
|
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
let status = unsafe {
|
|
|
|
winuser::GetRawInputDeviceInfoW(
|
|
|
|
handle,
|
|
|
|
RIDI_DEVICENAME,
|
|
|
|
name.as_ptr() as _,
|
|
|
|
&mut minimum_size,
|
|
|
|
)
|
|
|
|
};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
if status == UINT::max_value() || status == 0 {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_assert_eq!(minimum_size, status);
|
|
|
|
|
|
|
|
unsafe { name.set_len(minimum_size as _) };
|
|
|
|
|
|
|
|
Some(util::wchar_to_string(&name))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn register_raw_input_devices(devices: &[RAWINPUTDEVICE]) -> bool {
|
|
|
|
let device_size = size_of::<RAWINPUTDEVICE>() as UINT;
|
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
let success = unsafe {
|
|
|
|
winuser::RegisterRawInputDevices(devices.as_ptr() as _, devices.len() as _, device_size)
|
|
|
|
};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
success == TRUE
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn register_all_mice_and_keyboards_for_raw_input(window_handle: HWND) -> bool {
|
|
|
|
// RIDEV_DEVNOTIFY: receive hotplug events
|
|
|
|
// RIDEV_INPUTSINK: receive events even if we're not in the foreground
|
|
|
|
let flags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
|
|
|
|
|
|
|
|
let devices: [RAWINPUTDEVICE; 2] = [
|
|
|
|
RAWINPUTDEVICE {
|
|
|
|
usUsagePage: HID_USAGE_PAGE_GENERIC,
|
|
|
|
usUsage: HID_USAGE_GENERIC_MOUSE,
|
|
|
|
dwFlags: flags,
|
|
|
|
hwndTarget: window_handle,
|
|
|
|
},
|
|
|
|
RAWINPUTDEVICE {
|
|
|
|
usUsagePage: HID_USAGE_PAGE_GENERIC,
|
|
|
|
usUsage: HID_USAGE_GENERIC_KEYBOARD,
|
|
|
|
dwFlags: flags,
|
|
|
|
hwndTarget: window_handle,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
register_raw_input_devices(&devices)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_raw_input_data(handle: HRAWINPUT) -> Option<RAWINPUT> {
|
2019-06-29 08:07:36 +10:00
|
|
|
let mut data: RAWINPUT = unsafe { mem::zeroed() };
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
let mut data_size = size_of::<RAWINPUT>() as UINT;
|
|
|
|
let header_size = size_of::<RAWINPUTHEADER>() as UINT;
|
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
let status = unsafe {
|
|
|
|
winuser::GetRawInputData(
|
|
|
|
handle,
|
|
|
|
RID_INPUT,
|
|
|
|
&mut data as *mut _ as _,
|
|
|
|
&mut data_size,
|
|
|
|
header_size,
|
|
|
|
)
|
|
|
|
};
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
|
|
|
|
if status == UINT::max_value() || status == 0 {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(data)
|
|
|
|
}
|
|
|
|
|
2019-06-22 01:33:15 +10:00
|
|
|
fn button_flags_to_element_state(
|
|
|
|
button_flags: USHORT,
|
|
|
|
down_flag: USHORT,
|
|
|
|
up_flag: USHORT,
|
|
|
|
) -> Option<ElementState> {
|
Windows: Implement DeviceEvents (#482)
Fixes #467
All variants other than Text have been implemented. While Text can
be implemented using ToUnicode, that doesn't play nice with dead
keys, IME, etc.
Most of the mouse DeviceEvents were already implemented, but due
to the flags that were used when registering for raw input events,
they only worked when the window was in the foreground.
This is also a step forward for #338, as DeviceIds are no longer
useless on Windows. On DeviceEvents, the DeviceId contains that
device's handle. While that handle could ostensibly be used by
developers to query device information, my actual reason for
choosing it is because it's simply a very easy way to handle this.
As a fun bonus, this enabled me to create this method:
DevideIdExt::get_persistent_identifier() -> Option<String>
Using this gives you a unique identifier for the device that
persists across replugs/reboots/etc., so it's ideal for something
like device-specific configuration.
There's a notable caveat to the new DeviceIds, which is that the
value will always be 0 for a WindowEvent. There doesn't seem to be
any straightforward way around this limitation.
I was concerned that multi-window applications would receive n
copies of every DeviceEvent, but Windows only sends them to one
window per application.
Lastly, there's a chance that these additions will cause
antivirus/etc. software to detect winit applications as keyloggers.
I don't know how likely that is to actually happen to people, but
if it does become an issue, the raw input code is neatly
sequestered and would be easy to make optional during compilation.
2018-04-29 02:42:33 +10:00
|
|
|
// We assume the same button won't be simultaneously pressed and released.
|
|
|
|
if util::has_flag(button_flags, down_flag) {
|
|
|
|
Some(ElementState::Pressed)
|
|
|
|
} else if util::has_flag(button_flags, up_flag) {
|
|
|
|
Some(ElementState::Released)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_raw_mouse_button_state(button_flags: USHORT) -> [Option<ElementState>; 3] {
|
|
|
|
[
|
|
|
|
button_flags_to_element_state(
|
|
|
|
button_flags,
|
|
|
|
winuser::RI_MOUSE_LEFT_BUTTON_DOWN,
|
|
|
|
winuser::RI_MOUSE_LEFT_BUTTON_UP,
|
|
|
|
),
|
|
|
|
button_flags_to_element_state(
|
|
|
|
button_flags,
|
|
|
|
winuser::RI_MOUSE_MIDDLE_BUTTON_DOWN,
|
|
|
|
winuser::RI_MOUSE_MIDDLE_BUTTON_UP,
|
|
|
|
),
|
|
|
|
button_flags_to_element_state(
|
|
|
|
button_flags,
|
|
|
|
winuser::RI_MOUSE_RIGHT_BUTTON_DOWN,
|
|
|
|
winuser::RI_MOUSE_RIGHT_BUTTON_UP,
|
|
|
|
),
|
|
|
|
]
|
|
|
|
}
|