Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Oct 2024 19:14:05 GMT
From:      Li-Wen Hsu <lwhsu@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org
Subject:   git: ea2855f6a7bb - main - cad/PrusaSlicer: Update to 2.8.1
Message-ID:  <202410281914.49SJE5Tl097587@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by lwhsu:

URL: https://cgit.FreeBSD.org/ports/commit/?id=ea2855f6a7bbd7555f46e8437b238aafe8ce8dca

commit ea2855f6a7bbd7555f46e8437b238aafe8ce8dca
Author:     Teodor Sigaev <teodorsigaev@gmail.com>
AuthorDate: 2024-10-28 19:13:29 +0000
Commit:     Li-Wen Hsu <lwhsu@FreeBSD.org>
CommitDate: 2024-10-28 19:13:29 +0000

    cad/PrusaSlicer: Update to 2.8.1
    
    PR:             282145
---
 cad/PrusaSlicer/Makefile                           |    3 +-
 cad/PrusaSlicer/distinfo                           |    6 +-
 cad/PrusaSlicer/files/patch-CMakeLists.txt         |   21 +-
 ... patch-bundled__deps_avrdude_avrdude_arduino.c} |    4 +-
 ...tch-bundled__deps_avrdude_avrdude_libavrdude.h} |    4 +-
 ... => patch-bundled__deps_avrdude_avrdude_main.c} |    4 +-
 ...t => patch-bundled__deps_hidapi_CMakeLists.txt} |   10 +-
 .../files/patch-bundled__deps_hidapi_libusb_hid.c  | 1517 ++++++++++++++++++++
 ...pp => patch-bundled__deps_hints_HintsToPot.cpp} |    4 +-
 cad/PrusaSlicer/files/patch-src_CMakeLists.txt     |    6 +-
 .../files/patch-src_hidapi_libusb_hid.c            |    2 +-
 .../files/patch-src_libnanosvg_nanosvgrast.h       |   20 +-
 ...libslic3r_Arrange_Core_NFP_NFPConcave__CGAL.cpp |   11 +-
 .../files/patch-src_libslic3r_CMakeLists.txt       |   12 +-
 .../files/patch-src_libslic3r_CutSurface.cpp       |    9 +-
 .../files/patch-src_libslic3r_EmbossShape.hpp      |    4 +-
 .../files/patch-src_libslic3r_Format_SL1__SVG.cpp  |   15 +-
 .../files/patch-src_libslic3r_Format_SVG.cpp       |   11 +
 ...tch-src_libslic3r_Geometry_VoronoiUtilsCgal.cpp |    4 +-
 .../files/patch-src_libslic3r_MeshBoolean.cpp      |   10 +-
 .../files/patch-src_libslic3r_NSVGUtils.cpp        |   11 +
 .../files/patch-src_libslic3r_NSVGUtils.hpp        |   10 +-
 .../files/patch-src_libslic3r_Platform.cpp         |   10 +-
 .../patch-src_libslic3r_SupportSpotsGenerator.cpp  |    4 +-
 .../files/patch-src_libslic3r_Triangulation.cpp    |    4 +-
 .../files/patch-src_occt__wrapper_CMakeLists.txt   |   10 +-
 .../files/patch-src_slic3r_CMakeLists.txt          |   45 +-
 .../files/patch-src_slic3r_GUI_BitmapCache.cpp     |    6 +-
 .../files/patch-src_slic3r_GUI_ConfigWizard.cpp    |   28 +-
 .../files/patch-src_slic3r_GUI_ConfigWizard.hpp    |    8 +-
 ...tch-src_slic3r_GUI_DesktopIntegrationDialog.hpp |    4 +-
 .../files/patch-src_slic3r_GUI_EditGCodeDialog.cpp |   29 +
 .../files/patch-src_slic3r_GUI_Field.cpp           |    4 +-
 .../files/patch-src_slic3r_GUI_GLCanvas3D.cpp      |    4 +-
 .../files/patch-src_slic3r_GUI_GLTexture.cpp       |    8 +-
 .../files/patch-src_slic3r_GUI_GUI__App.cpp        |   52 +-
 .../patch-src_slic3r_GUI_Gizmos_GLGizmoSVG.cpp     |    8 +-
 .../patch-src_slic3r_GUI_HintNotification.cpp      |   16 +
 .../files/patch-src_slic3r_GUI_IconManager.cpp     |    6 +-
 .../files/patch-src_slic3r_GUI_ImGuiWrapper.cpp    |    6 +-
 .../files/patch-src_slic3r_GUI_InstanceCheck.cpp   |    6 +-
 .../files/patch-src_slic3r_GUI_OptionsGroup.cpp    |    6 +-
 .../patch-src_slic3r_GUI_PhysicalPrinterDialog.cpp |    4 +-
 .../files/patch-src_slic3r_GUI_Plater.cpp          |   19 +-
 .../files/patch-src_slic3r_GUI_Preferences.cpp     |    8 +-
 .../files/patch-src_slic3r_GUI_Search.cpp          |   20 +
 cad/PrusaSlicer/files/patch-src_slic3r_GUI_Tab.cpp |    6 +-
 .../files/patch-src_slic3r_GUI_TopBar.cpp          |   11 +
 .../patch-src_slic3r_GUI_UnsavedChangesDialog.cpp  |   16 +-
 .../files/patch-src_slic3r_GUI_UpdateDialogs.cpp   |    6 +-
 ...tch-src_slic3r_GUI_UserAccountCommunication.cpp |    4 +-
 .../files/patch-src_slic3r_GUI_WipeTowerDialog.cpp |   11 +
 .../files/patch-src_slic3r_Utils_AppUpdater.cpp    |   11 +
 .../patch-src_slic3r_Utils_FontConfigHelp.hpp      |    6 +-
 .../files/patch-src_slic3r_Utils_WxFontUtils.cpp   |   17 +-
 .../files/patch-tests_libslic3r_test__emboss.cpp   |    4 +-
 56 files changed, 1900 insertions(+), 205 deletions(-)

diff --git a/cad/PrusaSlicer/Makefile b/cad/PrusaSlicer/Makefile
index 1a91b82b1bc4..d770864caeb9 100644
--- a/cad/PrusaSlicer/Makefile
+++ b/cad/PrusaSlicer/Makefile
@@ -1,7 +1,6 @@
 PORTNAME=	PrusaSlicer
 DISTVERSIONPREFIX=version_
-DISTVERSION=	2.8.0
-PORTREVISION=	2
+DISTVERSION=	2.8.1
 CATEGORIES=	cad
 DIST_SUBDIR=	PrusaSlicer
 
diff --git a/cad/PrusaSlicer/distinfo b/cad/PrusaSlicer/distinfo
index 59cb1f3b0a83..dc388786dc81 100644
--- a/cad/PrusaSlicer/distinfo
+++ b/cad/PrusaSlicer/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1719924925
-SHA256 (PrusaSlicer/prusa3d-PrusaSlicer-version_2.8.0_GH0.tar.gz) = 58d484f85b34d83026f8220bab983f855fbcd72767d0887f21f5cc382e5b19ab
-SIZE (PrusaSlicer/prusa3d-PrusaSlicer-version_2.8.0_GH0.tar.gz) = 69806919
+TIMESTAMP = 1728981634
+SHA256 (PrusaSlicer/prusa3d-PrusaSlicer-version_2.8.1_GH0.tar.gz) = f71033dd4e9fdd8e5ac7b5be5803d0d6d09ec0fd87de92b152b3c6bbae04c103
+SIZE (PrusaSlicer/prusa3d-PrusaSlicer-version_2.8.1_GH0.tar.gz) = 69409077
diff --git a/cad/PrusaSlicer/files/patch-CMakeLists.txt b/cad/PrusaSlicer/files/patch-CMakeLists.txt
index 44016fce0aca..64eae04effc9 100644
--- a/cad/PrusaSlicer/files/patch-CMakeLists.txt
+++ b/cad/PrusaSlicer/files/patch-CMakeLists.txt
@@ -1,4 +1,4 @@
---- CMakeLists.txt.orig	2024-06-27 09:25:47 UTC
+--- CMakeLists.txt.orig	2024-09-18 13:39:04 UTC
 +++ CMakeLists.txt
 @@ -14,6 +14,7 @@ include(CMakeDependentOption)
  include("version.inc")
@@ -17,7 +17,7 @@
      find_package(PkgConfig REQUIRED)
  
      if (CMAKE_VERSION VERSION_LESS "3.1")
-@@ -264,6 +265,8 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL 
+@@ -263,6 +264,8 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL 
      # On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error.
      add_compile_options(-Werror=return-type)
  
@@ -26,7 +26,20 @@
      # removes LOTS of extraneous Eigen warnings (GCC only supports it since 6.1)
      # https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1221
      if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
-@@ -648,8 +651,8 @@ elseif (SLIC3R_FHS)
+@@ -371,10 +374,10 @@ set(MINIMUM_BOOST_VERSION "1.66.0")
+ # boost::process was introduced first in version 1.64.0,
+ # boost::beast::detail::base64 was introduced first in version 1.66.0
+ set(MINIMUM_BOOST_VERSION "1.66.0")
+-set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time;iostreams;nowide")
++set(_boost_components "system;filesystem;thread;log;log_setup;locale;regex;chrono;atomic;date_time;iostreams;nowide")
+ find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components})
+ 
+-find_package(Eigen3 3.3.7 REQUIRED)
++find_package(Eigen3 3.3.7 REQUIRED NO_MODULE)
+ 
+ add_library(boost_libs INTERFACE)
+ add_library(boost_headeronly INTERFACE)
+@@ -636,8 +639,8 @@ elseif (SLIC3R_FHS)
      install(DIRECTORY ${SLIC3R_RESOURCES_DIR}/ DESTINATION ${SLIC3R_FHS_RESOURCES}
          PATTERN "*/udev" EXCLUDE
      )
@@ -37,7 +50,7 @@
      foreach(SIZE 32 128 192)
          install(FILES ${SLIC3R_RESOURCES_DIR}/icons/PrusaSlicer_${SIZE}px.png
              DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME PrusaSlicer.png
-@@ -658,7 +661,8 @@ elseif (SLIC3R_FHS)
+@@ -646,7 +649,8 @@ elseif (SLIC3R_FHS)
              DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME PrusaSlicer-gcodeviewer.png
          )
      endforeach()
diff --git a/cad/PrusaSlicer/files/patch-src_avrdude_arduino.c b/cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_arduino.c
similarity index 52%
rename from cad/PrusaSlicer/files/patch-src_avrdude_arduino.c
rename to cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_arduino.c
index c7c282d53832..9aad1b125e9a 100644
--- a/cad/PrusaSlicer/files/patch-src_avrdude_arduino.c
+++ b/cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_arduino.c
@@ -1,5 +1,5 @@
---- src/avrdude/arduino.c.orig	2023-07-25 13:23:52 UTC
-+++ src/avrdude/arduino.c
+--- bundled_deps/avrdude/avrdude/arduino.c.orig	2024-09-18 13:39:04 UTC
++++ bundled_deps/avrdude/avrdude/arduino.c
 @@ -28,6 +28,7 @@
  #include "ac_cfg.h"
  
diff --git a/cad/PrusaSlicer/files/patch-src_avrdude_libavrdude.h b/cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_libavrdude.h
similarity index 63%
rename from cad/PrusaSlicer/files/patch-src_avrdude_libavrdude.h
rename to cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_libavrdude.h
index ed7c44e0e5bc..6d03bb0bc90d 100644
--- a/cad/PrusaSlicer/files/patch-src_avrdude_libavrdude.h
+++ b/cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_libavrdude.h
@@ -1,5 +1,5 @@
---- src/avrdude/libavrdude.h.orig	2022-09-06 07:09:19 UTC
-+++ src/avrdude/libavrdude.h
+--- bundled_deps/avrdude/avrdude/libavrdude.h.orig	2024-09-18 13:39:04 UTC
++++ bundled_deps/avrdude/avrdude/libavrdude.h
 @@ -950,6 +950,8 @@ int read_config_builtin();
  // Header file for alloca()
  #if defined(WIN32NATIVE)
diff --git a/cad/PrusaSlicer/files/patch-src_avrdude_main.c b/cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_main.c
similarity index 84%
rename from cad/PrusaSlicer/files/patch-src_avrdude_main.c
rename to cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_main.c
index 57f18516cc78..a6912d0091ef 100644
--- a/cad/PrusaSlicer/files/patch-src_avrdude_main.c
+++ b/cad/PrusaSlicer/files/patch-bundled__deps_avrdude_avrdude_main.c
@@ -1,5 +1,5 @@
---- src/avrdude/main.c.orig	2022-09-06 07:09:19 UTC
-+++ src/avrdude/main.c
+--- bundled_deps/avrdude/avrdude/main.c.orig	2024-09-18 13:39:04 UTC
++++ bundled_deps/avrdude/avrdude/main.c
 @@ -806,7 +806,7 @@ int avrdude_main(int argc, char * argv [])
    avrdude_message(MSG_NOTICE, "\n%s: Version %s, compiled on %s at %s\n"
                      "%sCopyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/\n"
diff --git a/cad/PrusaSlicer/files/patch-src_hidapi_CMakeLists.txt b/cad/PrusaSlicer/files/patch-bundled__deps_hidapi_CMakeLists.txt
similarity index 66%
rename from cad/PrusaSlicer/files/patch-src_hidapi_CMakeLists.txt
rename to cad/PrusaSlicer/files/patch-bundled__deps_hidapi_CMakeLists.txt
index 282d616f9efa..a8f856cd3cf2 100644
--- a/cad/PrusaSlicer/files/patch-src_hidapi_CMakeLists.txt
+++ b/cad/PrusaSlicer/files/patch-bundled__deps_hidapi_CMakeLists.txt
@@ -1,5 +1,5 @@
---- src/hidapi/CMakeLists.txt.orig	2022-09-06 07:09:19 UTC
-+++ src/hidapi/CMakeLists.txt
+--- bundled_deps/hidapi/CMakeLists.txt.orig	2024-09-18 13:39:04 UTC
++++ bundled_deps/hidapi/CMakeLists.txt
 @@ -1,8 +1,9 @@
 -
  if (WIN32)
@@ -11,10 +11,10 @@
  else ()
      # Assume Linux or Unix other than Mac OS
      set(HIDAPI_IMPL linux/hid.c)
-@@ -16,4 +17,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+@@ -16,4 +17,6 @@ target_link_libraries(hidapi PRIVATE dl)
  	# Don't link the udev library, as there are two versions out there (libudev.so.0, libudev.so.1), so they are linked explicitely.
  #	target_link_libraries(hidapi udev)
- 	target_link_libraries(hidapi dl)
+ target_link_libraries(hidapi PRIVATE dl)
 +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
-+	target_link_libraries(hidapi usb iconv)
++       target_link_libraries(hidapi usb iconv)
  endif()
diff --git a/cad/PrusaSlicer/files/patch-bundled__deps_hidapi_libusb_hid.c b/cad/PrusaSlicer/files/patch-bundled__deps_hidapi_libusb_hid.c
new file mode 100644
index 000000000000..df486242573f
--- /dev/null
+++ b/cad/PrusaSlicer/files/patch-bundled__deps_hidapi_libusb_hid.c
@@ -0,0 +1,1517 @@
+--- bundled_deps/hidapi/libusb/hid.c.orig	2024-10-15 09:17:30 UTC
++++ bundled_deps/hidapi/libusb/hid.c
+@@ -0,0 +1,1514 @@
++/*******************************************************
++ HIDAPI - Multi-Platform library for
++ communication with HID devices.
++
++ Alan Ott
++ Signal 11 Software
++
++ 8/22/2009
++ Linux Version - 6/2/2010
++ Libusb Version - 8/13/2010
++ FreeBSD Version - 11/1/2011
++
++ Copyright 2009, All Rights Reserved.
++
++ At the discretion of the user of this library,
++ this software may be licensed under the terms of the
++ GNU General Public License v3, a BSD-Style license, or the
++ original HIDAPI license as outlined in the LICENSE.txt,
++ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
++ files located at the root of the source distribution.
++ These files may also be found in the public source
++ code repository located at:
++        http://github.com/signal11/hidapi .
++********************************************************/
++
++#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
++
++/* C */
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <ctype.h>
++#include <locale.h>
++#include <errno.h>
++
++/* Unix */
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/ioctl.h>
++#include <sys/utsname.h>
++#include <fcntl.h>
++#include <pthread.h>
++#include <wchar.h>
++
++/* GNU / LibUSB */
++#include <libusb.h>
++#ifndef __ANDROID__
++#include <iconv.h>
++#endif
++
++#include "hidapi.h"
++
++#ifdef __ANDROID__
++
++/* Barrier implementation because Android/Bionic don't have pthread_barrier.
++   This implementation came from Brent Priddy and was posted on
++   StackOverflow. It is used with his permission. */
++typedef int pthread_barrierattr_t;
++typedef struct pthread_barrier {
++    pthread_mutex_t mutex;
++    pthread_cond_t cond;
++    int count;
++    int trip_count;
++} pthread_barrier_t;
++
++static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
++{
++	if(count == 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
++		return -1;
++	}
++	if(pthread_cond_init(&barrier->cond, 0) < 0) {
++		pthread_mutex_destroy(&barrier->mutex);
++		return -1;
++	}
++	barrier->trip_count = count;
++	barrier->count = 0;
++
++	return 0;
++}
++
++static int pthread_barrier_destroy(pthread_barrier_t *barrier)
++{
++	pthread_cond_destroy(&barrier->cond);
++	pthread_mutex_destroy(&barrier->mutex);
++	return 0;
++}
++
++static int pthread_barrier_wait(pthread_barrier_t *barrier)
++{
++	pthread_mutex_lock(&barrier->mutex);
++	++(barrier->count);
++	if(barrier->count >= barrier->trip_count)
++	{
++		barrier->count = 0;
++		pthread_cond_broadcast(&barrier->cond);
++		pthread_mutex_unlock(&barrier->mutex);
++		return 1;
++	}
++	else
++	{
++		pthread_cond_wait(&barrier->cond, &(barrier->mutex));
++		pthread_mutex_unlock(&barrier->mutex);
++		return 0;
++	}
++}
++
++#endif
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#ifdef DEBUG_PRINTF
++#define LOG(...) fprintf(stderr, __VA_ARGS__)
++#else
++#define LOG(...) do {} while (0)
++#endif
++
++#ifndef __FreeBSD__
++#define DETACH_KERNEL_DRIVER
++#endif
++
++/* Uncomment to enable the retrieval of Usage and Usage Page in
++hid_enumerate(). Warning, on platforms different from FreeBSD
++this is very invasive as it requires the detach
++and re-attach of the kernel driver. See comments inside hid_enumerate().
++libusb HIDAPI programs are encouraged to use the interface number
++instead to differentiate between interfaces on a composite HID device. */
++/*#define INVASIVE_GET_USAGE*/
++
++/* Linked List of input reports received from the device. */
++struct input_report {
++	uint8_t *data;
++	size_t len;
++	struct input_report *next;
++};
++
++
++struct hid_device_ {
++	/* Handle to the actual device. */
++	libusb_device_handle *device_handle;
++
++	/* Endpoint information */
++	int input_endpoint;
++	int output_endpoint;
++	int input_ep_max_packet_size;
++
++	/* The interface number of the HID */
++	int interface;
++
++	/* Indexes of Strings */
++	int manufacturer_index;
++	int product_index;
++	int serial_index;
++
++	/* Whether blocking reads are used */
++	int blocking; /* boolean */
++
++	/* Read thread objects */
++	pthread_t thread;
++	pthread_mutex_t mutex; /* Protects input_reports */
++	pthread_cond_t condition;
++	pthread_barrier_t barrier; /* Ensures correct startup sequence */
++	int shutdown_thread;
++	int cancelled;
++	struct libusb_transfer *transfer;
++
++	/* List of received input reports. */
++	struct input_report *input_reports;
++};
++
++static libusb_context *usb_context = NULL;
++
++uint16_t get_usb_code_for_current_locale(void);
++static int return_data(hid_device *dev, unsigned char *data, size_t length);
++
++static hid_device *new_hid_device(void)
++{
++	hid_device *dev = calloc(1, sizeof(hid_device));
++	dev->blocking = 1;
++
++	pthread_mutex_init(&dev->mutex, NULL);
++	pthread_cond_init(&dev->condition, NULL);
++	pthread_barrier_init(&dev->barrier, NULL, 2);
++
++	return dev;
++}
++
++static void free_hid_device(hid_device *dev)
++{
++	/* Clean up the thread objects */
++	pthread_barrier_destroy(&dev->barrier);
++	pthread_cond_destroy(&dev->condition);
++	pthread_mutex_destroy(&dev->mutex);
++
++	/* Free the device itself */
++	free(dev);
++}
++
++#if 0
++/*TODO: Implement this funciton on hidapi/libusb.. */
++static void register_error(hid_device *dev, const char *op)
++{
++
++}
++#endif
++
++#ifdef INVASIVE_GET_USAGE
++/* Get bytes from a HID Report Descriptor.
++   Only call with a num_bytes of 0, 1, 2, or 4. */
++static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur)
++{
++	/* Return if there aren't enough bytes. */
++	if (cur + num_bytes >= len)
++		return 0;
++
++	if (num_bytes == 0)
++		return 0;
++	else if (num_bytes == 1) {
++		return rpt[cur+1];
++	}
++	else if (num_bytes == 2) {
++		return (rpt[cur+2] * 256 + rpt[cur+1]);
++	}
++	else if (num_bytes == 4) {
++		return (rpt[cur+4] * 0x01000000 +
++		        rpt[cur+3] * 0x00010000 +
++		        rpt[cur+2] * 0x00000100 +
++		        rpt[cur+1] * 0x00000001);
++	}
++	else
++		return 0;
++}
++
++/* Retrieves the device's Usage Page and Usage from the report
++   descriptor. The algorithm is simple, as it just returns the first
++   Usage and Usage Page that it finds in the descriptor.
++   The return value is 0 on success and -1 on failure. */
++static int get_usage(uint8_t *report_descriptor, size_t size,
++                     unsigned short *usage_page, unsigned short *usage)
++{
++	unsigned int i = 0;
++	int size_code;
++	int data_len, key_size;
++	int usage_found = 0, usage_page_found = 0;
++
++	while (i < size) {
++		int key = report_descriptor[i];
++		int key_cmd = key & 0xfc;
++
++		//printf("key: %02hhx\n", key);
++
++		if ((key & 0xf0) == 0xf0) {
++			/* This is a Long Item. The next byte contains the
++			   length of the data section (value) for this key.
++			   See the HID specification, version 1.11, section
++			   6.2.2.3, titled "Long Items." */
++			if (i+1 < size)
++				data_len = report_descriptor[i+1];
++			else
++				data_len = 0; /* malformed report */
++			key_size = 3;
++		}
++		else {
++			/* This is a Short Item. The bottom two bits of the
++			   key contain the size code for the data section
++			   (value) for this key.  Refer to the HID
++			   specification, version 1.11, section 6.2.2.2,
++			   titled "Short Items." */
++			size_code = key & 0x3;
++			switch (size_code) {
++			case 0:
++			case 1:
++			case 2:
++				data_len = size_code;
++				break;
++			case 3:
++				data_len = 4;
++				break;
++			default:
++				/* Can't ever happen since size_code is & 0x3 */
++				data_len = 0;
++				break;
++			};
++			key_size = 1;
++		}
++
++		if (key_cmd == 0x4) {
++			*usage_page  = get_bytes(report_descriptor, size, data_len, i);
++			usage_page_found = 1;
++			//printf("Usage Page: %x\n", (uint32_t)*usage_page);
++		}
++		if (key_cmd == 0x8) {
++			*usage = get_bytes(report_descriptor, size, data_len, i);
++			usage_found = 1;
++			//printf("Usage: %x\n", (uint32_t)*usage);
++		}
++
++		if (usage_page_found && usage_found)
++			return 0; /* success */
++
++		/* Skip over this key and it's associated data */
++		i += data_len + key_size;
++	}
++
++	return -1; /* failure */
++}
++#endif /* INVASIVE_GET_USAGE */
++
++#if defined(__FreeBSD__) && __FreeBSD__ < 10
++/* The libusb version included in FreeBSD < 10 doesn't have this function. In
++   mainline libusb, it's inlined in libusb.h. This function will bear a striking
++   resemblance to that one, because there's about one way to code it.
++
++   Note that the data parameter is Unicode in UTF-16LE encoding.
++   Return value is the number of bytes in data, or LIBUSB_ERROR_*.
++ */
++static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
++	uint8_t descriptor_index, uint16_t lang_id,
++	unsigned char *data, int length)
++{
++	return libusb_control_transfer(dev,
++		LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */
++		LIBUSB_REQUEST_GET_DESCRIPTOR,
++		(LIBUSB_DT_STRING << 8) | descriptor_index,
++		lang_id, data, (uint16_t) length, 1000);
++}
++
++#endif
++
++
++/* Get the first language the device says it reports. This comes from
++   USB string #0. */
++static uint16_t get_first_language(libusb_device_handle *dev)
++{
++	uint16_t buf[32];
++	int len;
++
++	/* Get the string from libusb. */
++	len = libusb_get_string_descriptor(dev,
++			0x0, /* String ID */
++			0x0, /* Language */
++			(unsigned char*)buf,
++			sizeof(buf));
++	if (len < 4)
++		return 0x0;
++
++	return buf[1]; /* First two bytes are len and descriptor type. */
++}
++
++static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
++{
++	uint16_t buf[32];
++	int len;
++	int i;
++
++	/* Get the string from libusb. */
++	len = libusb_get_string_descriptor(dev,
++			0x0, /* String ID */
++			0x0, /* Language */
++			(unsigned char*)buf,
++			sizeof(buf));
++	if (len < 4)
++		return 0x0;
++
++
++	len /= 2; /* language IDs are two-bytes each. */
++	/* Start at index 1 because there are two bytes of protocol data. */
++	for (i = 1; i < len; i++) {
++		if (buf[i] == lang)
++			return 1;
++	}
++
++	return 0;
++}
++
++
++/* This function returns a newly allocated wide string containing the USB
++   device string numbered by the index. The returned string must be freed
++   by using free(). */
++static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
++{
++	char buf[512];
++	int len;
++	wchar_t *str = NULL;
++
++#ifndef __ANDROID__ /* we don't use iconv on Android */
++	wchar_t wbuf[256];
++	/* iconv variables */
++	iconv_t ic;
++	size_t inbytes;
++	size_t outbytes;
++	size_t res;
++#ifdef __FreeBSD__
++	const char *inptr;
++#else
++	char *inptr;
++#endif
++	char *outptr;
++#endif
++
++	/* Determine which language to use. */
++	uint16_t lang;
++	lang = get_usb_code_for_current_locale();
++	if (!is_language_supported(dev, lang))
++		lang = get_first_language(dev);
++
++	/* Get the string from libusb. */
++	len = libusb_get_string_descriptor(dev,
++			idx,
++			lang,
++			(unsigned char*)buf,
++			sizeof(buf));
++	if (len < 0)
++		return NULL;
++
++#ifdef __ANDROID__
++
++	/* Bionic does not have iconv support nor wcsdup() function, so it
++	   has to be done manually.  The following code will only work for
++	   code points that can be represented as a single UTF-16 character,
++	   and will incorrectly convert any code points which require more
++	   than one UTF-16 character.
++
++	   Skip over the first character (2-bytes).  */
++	len -= 2;
++	str = malloc((len / 2 + 1) * sizeof(wchar_t));
++	int i;
++	for (i = 0; i < len / 2; i++) {
++		str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
++	}
++	str[len / 2] = 0x00000000;
++
++#else
++
++	/* buf does not need to be explicitly NULL-terminated because
++	   it is only passed into iconv() which does not need it. */
++
++	/* Initialize iconv. */
++	ic = iconv_open("WCHAR_T", "UTF-16LE");
++	if (ic == (iconv_t)-1) {
++		LOG("iconv_open() failed\n");
++		return NULL;
++	}
++
++	/* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
++	   Skip the first character (2-bytes). */
++	inptr = buf+2;
++	inbytes = len-2;
++	outptr = (char*) wbuf;
++	outbytes = sizeof(wbuf);
++	res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
++	if (res == (size_t)-1) {
++		LOG("iconv() failed\n");
++		goto err;
++	}
++
++	/* Write the terminating NULL. */
++	wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
++	if (outbytes >= sizeof(wbuf[0]))
++		*((wchar_t*)outptr) = 0x00000000;
++
++	/* Allocate and copy the string. */
++	str = wcsdup(wbuf);
++
++err:
++	iconv_close(ic);
++
++#endif
++
++	return str;
++}
++
++static char *make_path(libusb_device *dev, int interface_number)
++{
++	char str[64];
++	snprintf(str, sizeof(str), "%04x:%04x:%02x",
++		libusb_get_bus_number(dev),
++		libusb_get_device_address(dev),
++		interface_number);
++	str[sizeof(str)-1] = '\0';
++
++	return strdup(str);
++}
++
++
++int HID_API_EXPORT hid_init(void)
++{
++	if (!usb_context) {
++		const char *locale;
++
++		/* Init Libusb */
++		if (libusb_init(&usb_context))
++			return -1;
++
++		/* Set the locale if it's not set. */
++		locale = setlocale(LC_CTYPE, NULL);
++		if (!locale)
++			setlocale(LC_CTYPE, "");
++	}
++
++	return 0;
++}
++
++int HID_API_EXPORT hid_exit(void)
++{
++	if (usb_context) {
++		libusb_exit(usb_context);
++		usb_context = NULL;
++	}
++
++	return 0;
++}
++
++struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
++{
++	libusb_device **devs;
++	libusb_device *dev;
++	libusb_device_handle *handle;
++	ssize_t num_devs;
++	int i = 0;
++
++	struct hid_device_info *root = NULL; /* return object */
++	struct hid_device_info *cur_dev = NULL;
++
++	if(hid_init() < 0)
++		return NULL;
++
++	num_devs = libusb_get_device_list(usb_context, &devs);
++	if (num_devs < 0)
++		return NULL;
++	while ((dev = devs[i++]) != NULL) {
++		struct libusb_device_descriptor desc;
++		struct libusb_config_descriptor *conf_desc = NULL;
++		int j, k;
++		int interface_num = 0;
++
++		int res = libusb_get_device_descriptor(dev, &desc);
++		unsigned short dev_vid = desc.idVendor;
++		unsigned short dev_pid = desc.idProduct;
++
++		res = libusb_get_active_config_descriptor(dev, &conf_desc);
++		if (res < 0)
++			libusb_get_config_descriptor(dev, 0, &conf_desc);
++		if (conf_desc) {
++			for (j = 0; j < conf_desc->bNumInterfaces; j++) {
++				const struct libusb_interface *intf = &conf_desc->interface[j];
++				for (k = 0; k < intf->num_altsetting; k++) {
++					const struct libusb_interface_descriptor *intf_desc;
++					intf_desc = &intf->altsetting[k];
++					if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
++						interface_num = intf_desc->bInterfaceNumber;
++
++						/* Check the VID/PID against the arguments */
++						if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
++						    (product_id == 0x0 || product_id == dev_pid)) {
++							struct hid_device_info *tmp;
++
++							/* VID/PID match. Create the record. */
++							tmp = calloc(1, sizeof(struct hid_device_info));
++							if (cur_dev) {
++								cur_dev->next = tmp;
++							}
++							else {
++								root = tmp;
++							}
++							cur_dev = tmp;
++
++							/* Fill out the record */
++							cur_dev->next = NULL;
++							cur_dev->path = make_path(dev, interface_num);
++
++							res = libusb_open(dev, &handle);
++
++							if (res >= 0) {
++								/* Serial Number */
++								if (desc.iSerialNumber > 0)
++									cur_dev->serial_number =
++										get_usb_string(handle, desc.iSerialNumber);
++
++								/* Manufacturer and Product strings */
++								if (desc.iManufacturer > 0)
++									cur_dev->manufacturer_string =
++										get_usb_string(handle, desc.iManufacturer);
++								if (desc.iProduct > 0)
++									cur_dev->product_string =
++										get_usb_string(handle, desc.iProduct);
++
++#ifdef INVASIVE_GET_USAGE
++{
++							/*
++							This section is removed because it is too
++							invasive on the system. Getting a Usage Page
++							and Usage requires parsing the HID Report
++							descriptor. Getting a HID Report descriptor
++							involves claiming the interface. Claiming the
++							interface involves detaching the kernel driver.
++							Detaching the kernel driver is hard on the system
++							because it will unclaim interfaces (if another
++							app has them claimed) and the re-attachment of
++							the driver will sometimes change /dev entry names.
++							It is for these reasons that this section is
++							#if 0. For composite devices, use the interface
++							field in the hid_device_info struct to distinguish
++							between interfaces. */
++								unsigned char data[256];
++#ifdef DETACH_KERNEL_DRIVER
++								int detached = 0;
++								/* Usage Page and Usage */
++								res = libusb_kernel_driver_active(handle, interface_num);
++								if (res == 1) {
++									res = libusb_detach_kernel_driver(handle, interface_num);
++									if (res < 0)
++										LOG("Couldn't detach kernel driver, even though a kernel driver was attached.");
++									else
++										detached = 1;
++								}
++#endif
++								res = libusb_claim_interface(handle, interface_num);
++								if (res >= 0) {
++									/* Get the HID Report Descriptor. */
++									res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000);
++									if (res >= 0) {
++										unsigned short page=0, usage=0;
++										/* Parse the usage and usage page
++										   out of the report descriptor. */
++										get_usage(data, res,  &page, &usage);
++										cur_dev->usage_page = page;
++										cur_dev->usage = usage;
++									}
++									else
++										LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res);
++
++									/* Release the interface */
++									res = libusb_release_interface(handle, interface_num);
++									if (res < 0)
++										LOG("Can't release the interface.\n");
++								}
++								else
++									LOG("Can't claim interface %d\n", res);
++#ifdef DETACH_KERNEL_DRIVER
++								/* Re-attach kernel driver if necessary. */
++								if (detached) {
++									res = libusb_attach_kernel_driver(handle, interface_num);
++									if (res < 0)
++										LOG("Couldn't re-attach kernel driver.\n");
++								}
++#endif
++}
++#endif /* INVASIVE_GET_USAGE */
++
++								libusb_close(handle);
++							}
++							/* VID/PID */
++							cur_dev->vendor_id = dev_vid;
++							cur_dev->product_id = dev_pid;
++
++							/* Release Number */
++							cur_dev->release_number = desc.bcdDevice;
++
++							/* Interface Number */
++							cur_dev->interface_number = interface_num;
++						}
++					}
++				} /* altsettings */
++			} /* interfaces */
++			libusb_free_config_descriptor(conf_desc);
++		}
++	}
++
++	libusb_free_device_list(devs, 1);
++
++	return root;
++}
++
++void  HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
++{
++	struct hid_device_info *d = devs;
++	while (d) {
++		struct hid_device_info *next = d->next;
++		free(d->path);
++		free(d->serial_number);
++		free(d->manufacturer_string);
++		free(d->product_string);
++		free(d);
++		d = next;
++	}
++}
++
++hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
++{
++	struct hid_device_info *devs, *cur_dev;
++	const char *path_to_open = NULL;
++	hid_device *handle = NULL;
++
++	devs = hid_enumerate(vendor_id, product_id);
++	cur_dev = devs;
++	while (cur_dev) {
++		if (cur_dev->vendor_id == vendor_id &&
++		    cur_dev->product_id == product_id) {
++			if (serial_number) {
++				if (cur_dev->serial_number &&
++				    wcscmp(serial_number, cur_dev->serial_number) == 0) {
++					path_to_open = cur_dev->path;
++					break;
++				}
++			}
++			else {
++				path_to_open = cur_dev->path;
++				break;
++			}
++		}
++		cur_dev = cur_dev->next;
++	}
++
++	if (path_to_open) {
++		/* Open the device */
++		handle = hid_open_path(path_to_open);
++	}
++
++	hid_free_enumeration(devs);
++
++	return handle;
++}
++
++static void read_callback(struct libusb_transfer *transfer)
++{
++	hid_device *dev = transfer->user_data;
++	int res;
++
++	if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
++
++		struct input_report *rpt = malloc(sizeof(*rpt));
++		rpt->data = malloc(transfer->actual_length);
++		memcpy(rpt->data, transfer->buffer, transfer->actual_length);
++		rpt->len = transfer->actual_length;
++		rpt->next = NULL;
++
++		pthread_mutex_lock(&dev->mutex);
++
++		/* Attach the new report object to the end of the list. */
++		if (dev->input_reports == NULL) {
++			/* The list is empty. Put it at the root. */
++			dev->input_reports = rpt;
++			pthread_cond_signal(&dev->condition);
++		}
++		else {
++			/* Find the end of the list and attach. */
++			struct input_report *cur = dev->input_reports;
++			int num_queued = 0;
++			while (cur->next != NULL) {
++				cur = cur->next;
*** 2114 LINES SKIPPED ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202410281914.49SJE5Tl097587>