mac: Option to open device in non-exclusive mode #27

Closed
opened 2019-06-18 13:15:50 -05:00 by z3ntu · 15 comments
z3ntu commented 2019-06-18 13:15:50 -05:00 (Migrated from github.com)

Example: If you open a mouse currently (on macOS), the mouse input doesn't reach the OS, so you can't move the cursor with the mouse anymore while the device is opened in hidapi. That can be solved by not opening the device in exclusive mode, so github.com/z3ntu/hidapi@fc9077c470 / https://github.com/signal11/hidapi/pull/297

For my specific use case I have to look if it's possible to open a different usb device interface from the same device that doesn't block mouse input, but it seems that this feature is wanted by at least one other person too.

Example: If you open a mouse currently (on macOS), the mouse input doesn't reach the OS, so you can't move the cursor with the mouse anymore while the device is opened in hidapi. That can be solved by not opening the device in exclusive mode, so https://github.com/z3ntu/hidapi/commit/fc9077c470803ee89d4748b2dcbd62328fc224f8 / https://github.com/signal11/hidapi/pull/297 For my specific use case I have to look if it's possible to open a different usb device interface from the same device that doesn't block mouse input, but it seems that this feature is wanted by at least one other person too.
Youw commented 2019-06-18 14:03:04 -05:00 (Migrated from github.com)

I think https://github.com/signal11/hidapi/pull/335 refers to the same general issue, but on Windows
we need to consider an API that would allow specifying access mode

or not?

I think https://github.com/signal11/hidapi/pull/335 refers to the same general issue, but on Windows we need to consider an API that would allow specifying access mode or not?
z3ntu commented 2019-06-19 01:55:18 -05:00 (Migrated from github.com)

a.k.a https://github.com/libusb/hidapi/pull/1

On Windows it seems it's not possible to open some devices in exclusive mode. On Mac both is possible, so no fallback is possible on the hidapi side. About Linux, I don't know :).

a.k.a https://github.com/libusb/hidapi/pull/1 On Windows it seems it's not possible to open some devices in exclusive mode. On Mac both is possible, so no fallback is possible on the hidapi side. About Linux, I don't know :).
Youw commented 2019-06-19 02:30:47 -05:00 (Migrated from github.com)

hmm, yes, it is different
would be nice to find out what possible regressions could github.com/z3ntu/hidapi@fc9077c470 possibly cause, if there is any
after going thru documentation - I'd say, that there shouldn't be any (direct) issues, but theoretically, some project, might rely on the fact, that if a device is opened - it is opened in exclusive mode

on the other hand, we could add something like:
hid_open_path_opt(char* path, int bit_options) and define different options for different platforms (like OPEN_EXCLUSIVE for mac), to allow those projects restore their behavior

hmm, yes, it is different would be nice to find out what possible regressions could https://github.com/z3ntu/hidapi/commit/fc9077c470803ee89d4748b2dcbd62328fc224f8 possibly cause, if there is any after going thru documentation - I'd say, that there shouldn't be any (direct) issues, but theoretically, some project, might rely on the fact, that if a device is opened - it is opened in exclusive mode on the other hand, we could add something like: `hid_open_path_opt(char* path, int bit_options)` and define different options for different platforms (like OPEN_EXCLUSIVE for mac), to allow those projects restore their behavior
z3ntu commented 2019-06-19 04:47:20 -05:00 (Migrated from github.com)
https://github.com/signal11/hidapi/issues/295#issuecomment-272234180
mattsains commented 2020-02-21 20:43:08 -06:00 (Migrated from github.com)

I opened PR #148 to solve this

I opened PR #148 to solve this
Youw commented 2020-02-24 09:40:31 -06:00 (Migrated from github.com)

So I give this problem some thinking, and here what I suggest:

  • accept #148 as is;
  • add new API: hid_open<_path>_exclusive to cover current behavior;

Motivation:

  1. On Windows hid_open/_path is non-exclusive in any case, so #148 will make the behavior consistent, which is great;

    • still need to check how hidraw/libusb behaves - don't really know yet;

    It will be very convenient for many users who find exclusive mode on macOS inconvenient/unusable;

  2. hid_open<_path>_exclusive will make possible to preserve the old behavior for users which may rely on it;

  3. Such approach won't break anything on both API/ABI levels for users who don't care how the device is open on macOS.

We still have 2 options for hid_open<_path>_exclusive:

  1. Make it conditionally available (under ifdef for macOS-only (or other backend(s) that support it);
  2. Make it available for all backends with fallback to non-exclusive mode, in case if backend doesn't support it (e.g. on Windows);

@z3ntu @libusb/hidapi thoughts?

So I give this problem some thinking, and here what I suggest: - accept #148 as is; - add new API: `hid_open<_path>_exclusive` to cover current behavior; Motivation: 1) On Windows `hid_open/_path` is non-exclusive in any case, so #148 will make the behavior consistent, which is great; - still need to check how `hidraw`/`libusb` behaves - don't really know yet; It will be very convenient for many users who find exclusive mode on macOS inconvenient/unusable; 2) `hid_open<_path>_exclusive` will make possible to preserve the old behavior for users which may rely on it; 3) Such approach won't break anything on both API/ABI levels for users who don't care how the device is open on macOS. We still have 2 options for `hid_open<_path>_exclusive`: 1) Make it conditionally available (under `ifdef` for macOS-only (or other backend(s) that support it); 2) Make it available for all backends with fallback to non-exclusive mode, in case if backend doesn't support it (e.g. on Windows); @z3ntu @libusb/hidapi thoughts?
z3ntu commented 2020-02-24 15:30:11 -06:00 (Migrated from github.com)

add new API: hid_open<_path>_exclusive to cover current behavior;

I think adding an api like hid_open_opts (or if we follow Linux kernel naming hid_open2 😉) is a better choice. That way we can add options that control the behavior extensible & backwards-compatible (applications using these flags can use #ifdef if they want to support older hidapi versions).

We could add a flag OPEN_EXCLUSIVE where the documentation states the behavior on the different platforms which applications can request and we'll open the device non-exclusively or exclusively on macOS for example - and on other platforms where this isn't supported, ignore it.

Not sure if there are other "options" we could implement (or are already implemented somehow)

If possible I wouldn't change the behavior of existing APIs (so I don't think hid_open should be non-exclusive on macOS all of a sudden)

Make it conditionally available (under ifdef for macOS-only (or other backend(s) that support it);

Sounds horrible, as an application developer I don't want to add extra ifdefs for platform support (which probably differs between different hidapi versions). That's why we have hidapi and don't ifdef support for all platforms manually.

> add new API: hid_open<_path>_exclusive to cover current behavior; I think adding an api like `hid_open_opts` (or if we follow [Linux kernel naming `hid_open2`](https://lwn.net/Articles/796868/) :wink:) is a better choice. That way we can add options that control the behavior extensible & backwards-compatible (applications using these flags can use #ifdef if they want to support older hidapi versions). We could add a flag `OPEN_EXCLUSIVE` where the documentation states the behavior on the different platforms which applications can request and we'll open the device non-exclusively or exclusively on macOS for example - and on other platforms where this isn't supported, ignore it. Not sure if there are other "options" we could implement (or are already implemented somehow) If possible I wouldn't change the behavior of existing APIs (so I don't think `hid_open` should be non-exclusive on macOS all of a sudden) > Make it conditionally available (under ifdef for macOS-only (or other backend(s) that support it); Sounds horrible, as an application developer I don't want to add extra ifdefs for platform support (which probably differs between different hidapi versions). That's why we have hidapi and don't ifdef support for all platforms manually.
Youw commented 2020-02-24 17:51:25 -06:00 (Migrated from github.com)

hid_open_opts

Yep, I like this way better too. (Hello from WINAPI world: hid_open_ex 😄)

If possible I wouldn't change the behavior of existing APIs

I'll try & give it additional thinking. On the plate right now:

  • some projects are /already broken because of it/using custom forks/;
  • new API will allow the old behavior;
  • current default behavior is inconsistent with at least Windows (I will check libusb and hidraw too);
  • some users might rely on current behavior (this one may count for more then one item);
  • can't make up an example to strongly support current behavior, where exclusive access is mandatory (but not on all platforms);
  • when I checked macOS implementation for the very first time, I was confused: it wasn't obvious why the exclusive access is required (would hidapi break, if it is not?);
  • one more time - there might be projects in release (in some package manager) that rely on exclusive access;
> `hid_open_opts` Yep, I like this way better too. (Hello from WINAPI world: `hid_open_ex` :smile:) > If possible I wouldn't change the behavior of existing APIs I'll try & give it additional thinking. On the plate right now: - some projects are /already broken because of it/using custom forks/; - new API will allow the old behavior; - current default behavior is inconsistent with at least Windows (I will check libusb and hidraw too); - some users might rely on current behavior (this one may count for more then one item); - can't make up an example to strongly support current behavior, where exclusive access is mandatory (but not on all platforms); - when I checked macOS implementation for the very first time, I was confused: it wasn't obvious why the exclusive access is required (would `hidapi` break, if it is not?); - one more time - there might be projects in release (in some package manager) that rely on exclusive access;
nikitalita commented 2020-10-21 16:22:41 -05:00 (Migrated from github.com)

Any movement on this? There are a lot of projects who have macOS support blocked by this.

Any movement on this? There are a lot of projects who have macOS support blocked by this.
Youw commented 2020-11-24 07:07:42 -06:00 (Migrated from github.com)

A suggestion from my side:
Add macOS specific function to hidapi: int hid_macos_set_open_non_exclusive(bool non_exclusive);
Or something more general, like: int hid_set_options(int option, int value); with defined option HID_OPTION_MACOS_OPEN_NON_EXCLUSIVE.

Setting such option would change the behavior of hid_open/hid_open_path. That allows to save the backward compatibility by leaving the default behavior to the same as current.

A suggestion from my side: Add macOS specific function to hidapi: `int hid_macos_set_open_non_exclusive(bool non_exclusive);` Or something more general, like: `int hid_set_options(int option, int value);` with defined option `HID_OPTION_MACOS_OPEN_NON_EXCLUSIVE`. Setting such option would change the behavior of `hid_open`/`hid_open_path`. That allows to save the backward compatibility by leaving the default behavior to the same as current.
todbot commented 2020-12-11 14:35:45 -06:00 (Migrated from github.com)

From https://github.com/signal11/hidapi/pull/335 it looks like Windows has the option of exclusive/non-exclusive modes too (I'm assuming opening R/W is "exclusive" vs R being "non-exclusive". bad assumption?)

In libusb on Linux I recall you could "claim" the interface and that was the exclusive lock. And hidraw uses normal unix open() semantics for this I think?

So, could we make hid_set_open_non_exclusive(bool) be platform-agnostic, with any callouts for platform gotchas?

From https://github.com/signal11/hidapi/pull/335 it looks like Windows has the option of exclusive/non-exclusive modes too (I'm assuming opening R/W is "exclusive" vs R being "non-exclusive". bad assumption?) In libusb on Linux I recall you could "claim" the interface and that was the exclusive lock. And hidraw uses normal unix `open()` semantics for this I think? So, could we make `hid_set_open_non_exclusive(bool)` be platform-agnostic, with any callouts for platform gotchas?
Youw commented 2020-12-11 18:43:33 -06:00 (Migrated from github.com)

bad assumption?)

On Windows, in read-only mode you cannot hid_write. It is also possible to open in write-only (no hid_read), or without access specifier at all. In such mode you can the device and get its properties/some descriptor info, but cannot really interact with it. And I believe it this no-mode allows to open a device, which is opened by someone else in read-write mode.
This is something to be double checked - but to my knowledge, multiple clients may open same HID device in read-write mode with no issues.

libusb on Linux I recall you could "claim" the interface

Without claiming the interface you cannot interact with it at all, so that's not it either.

And hidraw uses normal unix open() semantics for this I think?

Yes, which allows to open in read-only, write-only, or read-write. But doesn't allow opening a device without specifier at all, so not exactly the same semantics as on Windows. And I've never thought is is possible to open same HID device with hidraw by multiple clients.

> bad assumption?) On Windows, in read-only mode you cannot hid_write. It is also possible to open in write-only (no hid_read), or without access specifier at all. In such mode you can the device and get its properties/some descriptor info, but cannot really interact with it. And I believe it this no-mode allows to open a device, which is opened by someone else in read-write mode. This is something to be double checked - but to my knowledge, multiple clients may open same HID device in read-write mode with no issues. > libusb on Linux I recall you could "claim" the interface Without claiming the interface you cannot interact with it at all, so that's not it either. > And hidraw uses normal unix open() semantics for this I think? Yes, which allows to open in read-only, write-only, or read-write. But doesn't allow opening a device without specifier at all, so not exactly the same semantics as on Windows. And I've never thought is is possible to open same HID device with hidraw by multiple clients.
mcuee commented 2021-06-13 07:06:59 -05:00 (Migrated from github.com)

Recent updates on libusb under macOS for reference.
Ref:https://github.com/libusb/libusb/pull/911

Recent updates on libusb under macOS for reference. Ref:https://github.com/libusb/libusb/pull/911
panathea commented 2021-11-15 14:18:50 -06:00 (Migrated from github.com)

It seems like #344 may duplicate this issue. I'm interested in a non-exclusive option on Mac as well, is there anything I can do to support @Youw ?

It seems like #344 may duplicate this issue. I'm interested in a non-exclusive option on Mac as well, is there anything I can do to support @Youw ?
Youw commented 2021-11-15 15:12:54 -06:00 (Migrated from github.com)

I have a plan how to make it happen, just can't get my hands to it.
For now if you really need it - make a fork, and patch it for yourself.

I have a plan how to make it happen, just can't get my hands to it. For now if you really need it - make a fork, and patch it for yourself.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-libusb/hidapi#27
No description provided.