From 76424950e373d3b04ac3dd13019151bfba3e8423 Mon Sep 17 00:00:00 2001 From: sumuel Date: Mon, 17 Aug 2026 20:44:55 +0000 Subject: Add the files --- src/detection/mouse/mouse.h | 8 ++++ src/detection/mouse/mouse_apple.c | 36 +++++++++++++++ src/detection/mouse/mouse_bsd.c | 56 +++++++++++++++++++++++ src/detection/mouse/mouse_haiku.cpp | 27 +++++++++++ src/detection/mouse/mouse_linux.c | 45 +++++++++++++++++++ src/detection/mouse/mouse_nosupport.c | 5 +++ src/detection/mouse/mouse_windows.c | 84 +++++++++++++++++++++++++++++++++++ 7 files changed, 261 insertions(+) create mode 100644 src/detection/mouse/mouse.h create mode 100644 src/detection/mouse/mouse_apple.c create mode 100644 src/detection/mouse/mouse_bsd.c create mode 100644 src/detection/mouse/mouse_haiku.cpp create mode 100644 src/detection/mouse/mouse_linux.c create mode 100644 src/detection/mouse/mouse_nosupport.c create mode 100644 src/detection/mouse/mouse_windows.c (limited to 'src/detection/mouse') diff --git a/src/detection/mouse/mouse.h b/src/detection/mouse/mouse.h new file mode 100644 index 0000000..3247eeb --- /dev/null +++ b/src/detection/mouse/mouse.h @@ -0,0 +1,8 @@ +#include "fastfetch.h" + +typedef struct FFMouseDevice { + FFstrbuf serial; + FFstrbuf name; +} FFMouseDevice; + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */); diff --git a/src/detection/mouse/mouse_apple.c b/src/detection/mouse/mouse_apple.c new file mode 100644 index 0000000..2c5b2d7 --- /dev/null +++ b/src/detection/mouse/mouse_apple.c @@ -0,0 +1,36 @@ +#include "mouse.h" +#include "common/apple/cf_helpers.h" +#include "common/mallocHelper.h" + +#include +#include + +static void enumSet(IOHIDDeviceRef value, FFlist* results) { + FFMouseDevice* device = FF_LIST_ADD(FFMouseDevice, *results); + ffStrbufInit(&device->serial); + ffStrbufInit(&device->name); + + CFStringRef product = IOHIDDeviceGetProperty(value, CFSTR(kIOHIDProductKey)); + ffCfStrGetString(product, &device->name); + + CFStringRef serialNumber = IOHIDDeviceGetProperty(value, CFSTR(kIOHIDSerialNumberKey)); + ffCfStrGetString(serialNumber, &device->serial); +} + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */) { + IOHIDManagerRef FF_CFTYPE_AUTO_RELEASE manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + if (IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone) != kIOReturnSuccess) { + return "IOHIDManagerOpen() failed"; + } + + CFDictionaryRef FF_CFTYPE_AUTO_RELEASE matching1 = CFDictionaryCreate(kCFAllocatorDefault, (const void**) (CFStringRef[]) { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) }, (const void**) (CFNumberRef[]) { ffCfCreateInt(kHIDPage_GenericDesktop), ffCfCreateInt(kHIDUsage_GD_Mouse) }, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + IOHIDManagerSetDeviceMatching(manager, matching1); + + CFSetRef FF_CFTYPE_AUTO_RELEASE set = IOHIDManagerCopyDevices(manager); + if (set) { + CFSetApplyFunction(set, (CFSetApplierFunction) &enumSet, devices); + } + IOHIDManagerClose(manager, kIOHIDOptionsTypeNone); + + return NULL; +} diff --git a/src/detection/mouse/mouse_bsd.c b/src/detection/mouse/mouse_bsd.c new file mode 100644 index 0000000..da7783b --- /dev/null +++ b/src/detection/mouse/mouse_bsd.c @@ -0,0 +1,56 @@ +#include "mouse.h" +#include "common/io.h" + +#include +#include +#include + +#if __has_include() + #include // FreeBSD +#else + #include // DragonFly +#endif + +#define MAX_UHID_MICE 64 + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */) { + char path[16]; + for (int i = 0; i < MAX_UHID_MICE; i++) { + snprintf(path, ARRAY_SIZE(path), "/dev/uhid%d", i); + FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + if (errno == ENOENT) { + break; // No more devices + } + continue; // Device not found + } + report_desc_t repDesc = hid_get_report_desc(fd); + if (!repDesc) { + continue; + } + + int reportId = hid_get_report_id(fd); + + struct hid_data* hData = hid_start_parse(repDesc, 0, reportId); + if (hData) { + struct hid_item hItem; + while (hid_get_item(hData, &hItem) > 0) { + if (HID_PAGE(hItem.usage) != 1 || HID_USAGE(hItem.usage) != 2) { + continue; + } + + struct usb_device_info di; + if (ioctl(fd, USB_GET_DEVICEINFO, &di) != -1) { + FFMouseDevice* device = FF_LIST_ADD(FFMouseDevice, *devices); + ffStrbufInitS(&device->serial, di.udi_serial); + ffStrbufInitS(&device->name, di.udi_product); + } + } + hid_end_parse(hData); + } + + hid_dispose_report_desc(repDesc); + } + + return NULL; +} diff --git a/src/detection/mouse/mouse_haiku.cpp b/src/detection/mouse/mouse_haiku.cpp new file mode 100644 index 0000000..5835c8e --- /dev/null +++ b/src/detection/mouse/mouse_haiku.cpp @@ -0,0 +1,27 @@ +extern "C" { +#include "mouse.h" +} + +#include +#include + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */) { + BList list; + + if (get_input_devices(&list) != B_OK) { + return "get_input_devices() failed"; + } + + for (int32 i = 0, n = list.CountItems(); i < n; i++) { + BInputDevice* device = (BInputDevice*) list.ItemAt(i); + if (device->Type() != B_POINTING_DEVICE || !device->IsRunning()) { + continue; + } + + FFMouseDevice* item = FF_LIST_ADD(FFMouseDevice, *devices); + ffStrbufInit(&item->serial); + ffStrbufInitS(&item->name, device->Name()); + } + + return NULL; +} diff --git a/src/detection/mouse/mouse_linux.c b/src/detection/mouse/mouse_linux.c new file mode 100644 index 0000000..939c332 --- /dev/null +++ b/src/detection/mouse/mouse_linux.c @@ -0,0 +1,45 @@ +#include "mouse.h" +#include "common/io.h" +#include "common/strutil.h" + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */) { + FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/input/"); + if (dirp == NULL) { + return "opendir(\"/sys/class/input/\") == NULL"; + } + + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/class/input/"); + uint32_t baseLen = path.length; + + struct dirent* entry; + while ((entry = readdir(dirp)) != NULL) { + if (!ffStrStartsWith(entry->d_name, "mouse")) { + continue; + } + if (!ffCharIsDigit(entry->d_name[strlen("mouse")])) { + continue; + } + + ffStrbufAppendS(&path, entry->d_name); + ffStrbufAppendS(&path, "/device/name"); + + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + if (ffAppendFileBuffer(path.chars, &name)) { + ffStrbufTrimRightSpace(&name); + ffStrbufSubstrBefore(&path, path.length - 4); + + FFMouseDevice* device = FF_LIST_ADD(FFMouseDevice, *devices); + ffStrbufInitMove(&device->name, &name); + ffStrbufInit(&device->serial); + + ffStrbufAppendS(&path, "uniq"); + if (ffAppendFileBuffer(path.chars, &device->serial)) { + ffStrbufTrimRightSpace(&device->serial); + } + } + + ffStrbufSubstrBefore(&path, baseLen); + } + + return NULL; +} diff --git a/src/detection/mouse/mouse_nosupport.c b/src/detection/mouse/mouse_nosupport.c new file mode 100644 index 0000000..aa1332d --- /dev/null +++ b/src/detection/mouse/mouse_nosupport.c @@ -0,0 +1,5 @@ +#include "mouse.h" + +const char* ffDetectMouse(FF_A_UNUSED FFlist* devices /* List of FFMouseDevice */) { + return "No mouse support on this platform"; +} diff --git a/src/detection/mouse/mouse_windows.c b/src/detection/mouse/mouse_windows.c new file mode 100644 index 0000000..3f2370a --- /dev/null +++ b/src/detection/mouse/mouse_windows.c @@ -0,0 +1,84 @@ +#define INITGUID + +#include "mouse.h" +#include "common/io.h" +#include "common/mallocHelper.h" +#include "common/windows/unicode.h" + +#include +#include +#include +#include + +const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */) { + UINT nDevices = 0; + if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST))) { + return "GetRawInputDeviceList(NULL) failed"; + } + if (nDevices == 0) { + return "No HID devices found"; + } + RAWINPUTDEVICELIST* FF_AUTO_FREE pRawInputDeviceList = (RAWINPUTDEVICELIST*) malloc(sizeof(RAWINPUTDEVICELIST) * nDevices); + if ((nDevices = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST))) == (UINT) -1) { + return "GetRawInputDeviceList(pRawInputDeviceList) failed"; + } + + for (UINT i = 0; i < nDevices; ++i) { + if (pRawInputDeviceList[i].dwType != RIM_TYPEMOUSE) { + continue; + } + + HANDLE hDevice = pRawInputDeviceList[i].hDevice; + + RID_DEVICE_INFO rdi; + UINT rdiSize = sizeof(rdi); + if (GetRawInputDeviceInfoW(hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == (UINT) -1) { + continue; + } + + WCHAR devName[MAX_PATH]; + UINT nameSize = MAX_PATH; + if (GetRawInputDeviceInfoW(hDevice, RIDI_DEVICENAME, devName, &nameSize) == (UINT) -1) { + continue; + } + + FFMouseDevice* device = FF_LIST_ADD(FFMouseDevice, *devices); + ffStrbufInit(&device->serial); + ffStrbufInit(&device->name); + + wchar_t buffer[MAX_PATH]; + + HANDLE FF_AUTO_CLOSE_FD hHidFile = CreateFileW(devName, 0 /* must be 0 instead of GENERIC_READ */, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hHidFile != INVALID_HANDLE_VALUE) { + if (HidD_GetProductString(hHidFile, buffer, (ULONG) sizeof(buffer))) { + ffStrbufSetWS(&device->name, buffer); + } + + if (HidD_GetSerialNumberString(hHidFile, buffer, sizeof(buffer))) { + ffStrbufSetWS(&device->serial, buffer); + } + } + + if (!device->name.length) { + // https://stackoverflow.com/a/64321096/9976392 + DEVPROPTYPE propertyType; + ULONG propertySize = sizeof(buffer); + + if (CM_Get_Device_Interface_PropertyW(devName, &DEVPKEY_Device_InstanceId, &propertyType, (PBYTE) buffer, &propertySize, 0) == CR_SUCCESS) { + DEVINST devInst; + if (CM_Locate_DevNodeW(&devInst, buffer, CM_LOCATE_DEVNODE_NORMAL) == CR_SUCCESS) { + propertySize = sizeof(buffer); + if (CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propertyType, (PBYTE) buffer, &propertySize, 0) == CR_SUCCESS) { + ffStrbufSetWS(&device->name, buffer); + } + } + } + } + + if (!device->name.length) { + ffStrbufSetF(&device->name, "Unknown device %04X-%04X", (unsigned) rdi.hid.dwVendorId, (unsigned) rdi.hid.dwProductId); + } + } + + return NULL; +} -- cgit v1.2.3