diff --git a/.gitignore b/.gitignore index 838b050..eac0ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,9 +15,15 @@ hid.*.pyd # IDE files .idea/ +.vscode/ # Virtual environments venv/ +Pipfile # Doc output docs/_build + +# macOS junk files +.DS_Store +._* diff --git a/chid.pxd b/chid.pxd index 8d3c3ab..0ae7339 100644 --- a/chid.pxd +++ b/chid.pxd @@ -50,3 +50,10 @@ cdef extern from "": int hid_get_indexed_string(hid_device*, int, wchar_t *, size_t) wchar_t *hid_error(hid_device *) char* hid_version_str() + +IF PLATFORM == "Darwin": + cdef extern from "": + int hid_darwin_get_location_id (hid_device *dev, unsigned *location_id) + void hid_darwin_set_open_exclusive(int open_exclusive) + int hid_darwin_get_open_exclusive() + int hid_darwin_is_device_open_exclusive(hid_device *dev) diff --git a/hid.pyx b/hid.pyx index ea93696..de174d8 100644 --- a/hid.pyx +++ b/hid.pyx @@ -82,6 +82,26 @@ def version_str(): """ return (hid_version_str()).decode('ascii') +IF PLATFORM == "Darwin": + def darwin_set_open_exclusive(int open_exclusive=1): + """Set open exclusive on macOS. + + :param open_exclusive: When set to 0 - all further devices will be opened + in non-exclusive mode. Otherwise - all further devices will be opened + in exclusive mode. Default = 1 + """ + + cdef int exclusive = open_exclusive + hid_darwin_set_open_exclusive(exclusive) + + def darwin_get_open_exclusive(): + """Get open exclusive on macOS. + + :return: 1 if all further devices will be opened in exclusive mode. + :rtype: int + """ + return hid_darwin_get_open_exclusive() + cdef class _closer: """Wrap a hid_device *ptr and a provide a way to call hid_close() on it. @@ -427,6 +447,35 @@ cdef class device: """ return U(hid_error(self._c_hid)) + IF PLATFORM == "Darwin": + def darwin_get_location_id(self): + """Return location id on macOS. + + :return: + :rtype: int + :raises ValueError: If connection is not opened. + :raises IOError: + """ + if self._c_hid == NULL: + raise ValueError('not open') + cdef unsigned int location_id + cdef int r = hid_darwin_get_location_id(self._c_hid, &location_id) + if r < 0: + raise IOError('get darwin location id error') + return location_id + + def darwin_is_device_open_exclusive(self): + """Check if the given device is opened in exclusive mode on macOS. + + :param dev: Device class + :return: 1 if the device is opened in exclusive mode, 0 - opened in non-exclusive, + -1 - if dev is invalid. + :rtype: int + :raises ValueError: If connection is not opened. + """ + if self._c_hid == NULL: + raise ValueError('not open') + return hid_darwin_is_device_open_exclusive(self._c_hid) # Finalize the HIDAPI library *only* once there are no more references to this # module, and it is being garbage collected. diff --git a/setup.py b/setup.py index 32a48bb..21b30db 100755 --- a/setup.py +++ b/setup.py @@ -3,6 +3,7 @@ from setuptools import setup, Extension, Distribution from subprocess import call, PIPE, Popen import os +import platform import re import shlex import subprocess @@ -18,6 +19,9 @@ tld = os.path.abspath(os.path.dirname(__file__)) embedded_hidapi_topdir = os.path.join(tld, "hidapi") embedded_hidapi_include = os.path.join(embedded_hidapi_topdir, "hidapi") +embedded_hidapi_macos_include = os.path.join(embedded_hidapi_topdir, "mac") + +ENV = {"PLATFORM": platform.system()} def to_bool(bool_str): @@ -100,7 +104,7 @@ def hid_from_embedded_hidapi(): Extension( "hid", sources=["hid.pyx", hidapi_src("mac")], - include_dirs=[embedded_hidapi_include], + include_dirs=[embedded_hidapi_include, embedded_hidapi_macos_include], # TODO: remove -Wno-unreachable-code when the time comes: https://github.com/cython/cython/issues/3172 extra_compile_args=[ "-isysroot", @@ -268,6 +272,6 @@ def find_version(): "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", ], - ext_modules=cythonize(modules, language_level=3), + ext_modules=cythonize(modules, language_level=3, compile_time_env=ENV), setup_requires=["setuptools>=19.0"], )