Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106040641
D10155.id26727.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D10155.id26727.diff
View Options
Index: head/sysutils/Makefile
===================================================================
--- head/sysutils/Makefile
+++ head/sysutils/Makefile
@@ -1076,6 +1076,7 @@
SUBDIR += snowlog
SUBDIR += socket
SUBDIR += socklog
+ SUBDIR += solaar
SUBDIR += sortu
SUBDIR += spindown
SUBDIR += spinner
Index: head/sysutils/solaar/Makefile
===================================================================
--- head/sysutils/solaar/Makefile
+++ head/sysutils/solaar/Makefile
@@ -0,0 +1,43 @@
+# $FreeBSD$
+
+PORTNAME= solaar
+PORTVERSION= g20170327
+CATEGORIES= sysutils
+
+MAINTAINER= tobik@FreeBSD.org
+COMMENT= Device manager for the Logitech Unifying Receiver
+
+LICENSE= GPLv2+
+LICENSE_FILE= ${WRKSRC}/COPYING
+
+# libhidapi.so is only loaded at runtime via ctypes (dlopen)
+RUN_DEPENDS= ${LOCALBASE}/lib/libhidapi.so:comms/hidapi
+
+USES= python
+USE_PYTHON= distutils autoplist
+
+USE_GITHUB= yes
+GH_ACCOUNT= pwr
+GH_PROJECT= Solaar
+# The latest release is from 2013 and there is not going to be a new
+# release for now:
+# https://github.com/pwr/Solaar/issues/288
+# https://github.com/pwr/Solaar/issues/296
+GH_TAGNAME= 53ec751
+
+NO_ARCH= yes
+
+OPTIONS_DEFINE= GUI
+GUI_RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}gobject3>=0:devel/py${PYTHON_MAJOR_VER:S/2//}-gobject3
+
+post-patch:
+ @${CP} ${FILESDIR}/hidapi.py ${WRKSRC}/lib/hidapi/udev.py
+ @${REINPLACE_CMD} -e '/pyudev/d' \
+ -e 's|python-gi|${PYTHON_PKGNAMEPREFIX}gobject3|' \
+ ${WRKSRC}/lib/solaar/gtk.py
+ @${REINPLACE_CMD} 's|receiver\.path\.split.*|receiver.path)|' \
+ ${WRKSRC}/lib/logitech_receiver/listener.py
+ @${REINPLACE_CMD} 's|[[:<:]]cmd[[:>:]]|action|' \
+ ${WRKSRC}/lib/solaar/cli/__init__.py
+
+.include <bsd.port.mk>
Index: head/sysutils/solaar/distinfo
===================================================================
--- head/sysutils/solaar/distinfo
+++ head/sysutils/solaar/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1490648037
+SHA256 (pwr-Solaar-g20170327-53ec751_GH0.tar.gz) = 0dca927e30c5436215d732a328d72f6d73b2a1878df6efa4ba054b1dbec9310f
+SIZE (pwr-Solaar-g20170327-53ec751_GH0.tar.gz) = 1189828
Index: head/sysutils/solaar/files/hidapi.py
===================================================================
--- head/sysutils/solaar/files/hidapi.py
+++ head/sysutils/solaar/files/hidapi.py
@@ -0,0 +1,186 @@
+# $FreeBSD$
+# This is based on previous support for libhidapi which was dropped in
+# upstream commit f5d2eba.
+import ctypes as _C
+from struct import pack as _pack
+
+_native = _C.CDLL("libhidapi.so")
+
+class _NativeDeviceInfo(_C.Structure):
+ pass
+_NativeDeviceInfo._fields_ = [
+ ('path', _C.c_char_p),
+ ('vendor_id', _C.c_ushort),
+ ('product_id', _C.c_ushort),
+ ('serial', _C.c_wchar_p),
+ ('release', _C.c_ushort),
+ ('manufacturer', _C.c_wchar_p),
+ ('product', _C.c_wchar_p),
+ ('usage_page', _C.c_ushort),
+ ('usage', _C.c_ushort),
+ ('interface', _C.c_int),
+ ('next_device', _C.POINTER(_NativeDeviceInfo))
+]
+
+from collections import namedtuple
+DeviceInfo = namedtuple('DeviceInfo', [
+ 'path',
+ 'vendor_id',
+ 'product_id',
+ 'serial',
+ 'release',
+ 'manufacturer',
+ 'product',
+ 'interface',
+ 'driver',
+])
+del namedtuple
+
+def _makeDeviceInfo(native_device_info):
+ return DeviceInfo(
+ path=native_device_info.path.decode('ascii'),
+ vendor_id=hex(native_device_info.vendor_id)[2:].zfill(4),
+ product_id=hex(native_device_info.product_id)[2:].zfill(4),
+ serial=native_device_info.serial if native_device_info.serial else None,
+ release=hex(native_device_info.release)[2:],
+ manufacturer=native_device_info.manufacturer,
+ product=native_device_info.product,
+ interface=native_device_info.interface,
+ driver=None)
+
+_native.hid_init.argtypes = None
+_native.hid_init.restype = _C.c_int
+
+_native.hid_exit.argtypes = None
+_native.hid_exit.restype = _C.c_int
+
+_native.hid_enumerate.argtypes = [_C.c_ushort, _C.c_ushort]
+_native.hid_enumerate.restype = _C.POINTER(_NativeDeviceInfo)
+
+_native.hid_free_enumeration.argtypes = [_C.POINTER(_NativeDeviceInfo)]
+_native.hid_free_enumeration.restype = None
+
+_native.hid_open.argtypes = [_C.c_ushort, _C.c_ushort, _C.c_wchar_p]
+_native.hid_open.restype = _C.c_void_p
+
+_native.hid_open_path.argtypes = [_C.c_char_p]
+_native.hid_open_path.restype = _C.c_void_p
+
+_native.hid_close.argtypes = [_C.c_void_p]
+_native.hid_close.restype = None
+
+_native.hid_write.argtypes = [_C.c_void_p, _C.c_char_p, _C.c_size_t]
+_native.hid_write.restype = _C.c_int
+
+_native.hid_read.argtypes = [_C.c_void_p, _C.c_char_p, _C.c_size_t]
+_native.hid_read.restype = _C.c_int
+
+_native.hid_read_timeout.argtypes = [_C.c_void_p, _C.c_char_p, _C.c_size_t, _C.c_int]
+_native.hid_read_timeout.restype = _C.c_int
+
+_native.hid_set_nonblocking.argtypes = [_C.c_void_p, _C.c_int]
+_native.hid_set_nonblocking.restype = _C.c_int
+
+_native.hid_send_feature_report.argtypes = [_C.c_void_p, _C.c_char_p, _C.c_size_t]
+_native.hid_send_feature_report.restype = _C.c_int
+
+_native.hid_get_feature_report.argtypes = [_C.c_void_p, _C.c_char_p, _C.c_size_t]
+_native.hid_get_feature_report.restype = _C.c_int
+
+_native.hid_get_manufacturer_string.argtypes = [_C.c_void_p, _C.c_wchar_p, _C.c_size_t]
+_native.hid_get_manufacturer_string.restype = _C.c_int
+
+_native.hid_get_product_string.argtypes = [_C.c_void_p, _C.c_wchar_p, _C.c_size_t]
+_native.hid_get_product_string.restype = _C.c_int
+
+_native.hid_get_serial_number_string.argtypes = [_C.c_void_p, _C.c_wchar_p, _C.c_size_t]
+_native.hid_get_serial_number_string.restype = _C.c_int
+
+_native.hid_get_indexed_string.argtypes = [_C.c_void_p, _C.c_int, _C.c_wchar_p, _C.c_size_t]
+_native.hid_get_indexed_string.restype = _C.c_int
+
+_native.hid_error.argtypes = [_C.c_void_p]
+_native.hid_error.restype = _C.c_wchar_p
+
+def init():
+ return _native.hid_init() == 0
+
+def exit():
+ return _native.hid_exit() == 0
+
+def monitor_glib(callback, *device_filters):
+ pass
+
+def enumerate(vendor_id=None, product_id=None, interface_number=None, hid_driver=None):
+ devices = _native.hid_enumerate(vendor_id, product_id)
+ d = devices
+ while d:
+ if interface_number is None or interface_number == d.contents.interface:
+ yield _makeDeviceInfo(d.contents)
+ d = d.contents.next_device
+
+ if devices:
+ _native.hid_free_enumeration(devices)
+
+def open(vendor_id, product_id, serial=None):
+ return _native.hid_open(vendor_id, product_id, serial) or None
+
+def open_path(device_path):
+ if type(device_path) == str:
+ device_path = device_path.encode('ascii')
+ return _native.hid_open_path(device_path) or None
+
+def close(device_handle):
+ _native.hid_close(device_handle)
+
+def write(device_handle, data):
+ bytes_written = _native.hid_write(device_handle, _C.c_char_p(data), len(data))
+ if bytes_written != len(data):
+ raise IOError(_errno.EIO, 'written %d bytes out of expected %d' % (bytes_written, len(data)))
+
+def read(device_handle, bytes_count, timeout_ms=-1):
+ out_buffer = _C.create_string_buffer(b'\x00' * (bytes_count + 1))
+ bytes_read = _native.hid_read_timeout(device_handle, out_buffer, bytes_count, timeout_ms)
+ if bytes_read == -1:
+ return None
+ if bytes_read == 0:
+ return b''
+ return out_buffer[:bytes_read]
+
+def send_feature_report(device_handle, data, report_number=None):
+ if report_number is not None:
+ data = _pack(b'!B', report_number) + data
+ bytes_written = _native.hid_send_feature_report(device_handle, _C.c_char_p(data), len(data))
+ return bytes_written > -1
+
+def get_feature_report(device_handle, bytes_count, report_number=None):
+ out_buffer = _C.create_string_buffer('\x00' * (bytes_count + 2))
+ if report_number is not None:
+ out_buffer[0] = _pack(b'!B', report_number)
+ bytes_read = _native.hid_get_feature_report(device_handle, out_buffer, bytes_count)
+ if bytes_read > -1:
+ return out_buffer[:bytes_read]
+
+def _read_wchar(func, device_handle, index=None):
+ _BUFFER_SIZE = 64
+ buf = _C.create_unicode_buffer('\x00' * _BUFFER_SIZE)
+ if index is None:
+ ok = func(device_handle, buf, _BUFFER_SIZE)
+ else:
+ ok = func(device_handle, index, buf, _BUFFER_SIZE)
+ if ok == 0:
+ return buf.value
+
+def get_manufacturer(device_handle):
+ return _read_wchar(_native.hid_get_manufacturer_string, device_handle)
+
+def get_product(device_handle):
+ return _read_wchar(_native.hid_get_product_string, device_handle)
+
+def get_serial(device_handle):
+ serial = _read_wchar(_native.hid_get_serial_number_string, device_handle)
+ if serial is not None:
+ return ''.join(hex(ord(c)) for c in serial)
+
+def get_indexed_string(device_handle, index):
+ return _read_wchar(_native.hid_get_indexed_string, device_handle, index)
Index: head/sysutils/solaar/files/patch-setup.py
===================================================================
--- head/sysutils/solaar/files/patch-setup.py
+++ head/sysutils/solaar/files/patch-setup.py
@@ -0,0 +1,32 @@
+--- setup.py.orig 2017-03-20 23:07:26 UTC
++++ setup.py
+@@ -6,10 +6,8 @@ from distutils.core import setup
+ autostart_path = '/etc/xdg/autostart'
+
+ import sys
+-backup_path_0 = sys.path[0]
+-sys.path[0] = backup_path_0 + '/lib'
+-from solaar import NAME, __version__
+-sys.path[0] = backup_path_0
++NAME = 'Solaar'
++__version__ = '0.9.2'
+
+ if 'install' in sys.argv:
+ # naively guess where the autostart .desktop file should be installed
+@@ -22,7 +20,7 @@ if 'install' in sys.argv:
+ autostart_path = path.join(xdg_config_home, 'autostart')
+ del environ, path, xdg_config_home
+
+-del sys, backup_path_0
++del sys
+
+
+ def _data_files():
+@@ -36,7 +34,6 @@ def _data_files():
+ yield _dirname(mo), [mo]
+
+ yield 'share/applications', ['share/applications/solaar.desktop']
+- yield autostart_path, ['share/applications/solaar.desktop']
+
+ del _dirname
+
Index: head/sysutils/solaar/pkg-descr
===================================================================
--- head/sysutils/solaar/pkg-descr
+++ head/sysutils/solaar/pkg-descr
@@ -0,0 +1,9 @@
+Solaar is a device manager for Logitech's Unifying Receiver. It is
+able to pair/unpair devices to the receiver, and for most devices read
+battery status.
+
+It comes in two flavors, command-line and GUI. Both are able to list
+the devices paired to a Unifying Receiver, show detailed info for each
+device, and also pair/unpair supported devices with the receiver.
+
+WWW: https://pwr.github.io/Solaar/
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 25, 8:23 AM (9 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15594286
Default Alt Text
D10155.id26727.diff (10 KB)
Attached To
Mode
D10155: New port: sysutils/solaar
Attached
Detach File
Event Timeline
Log In to Comment