📄 osx.c
字号:
pElement = pElement->pSibling; // element of interest return hid_GetDeviceElement (pElement, typeMask); // otherwise return this element } } return NULL;}// return true if this is a valid device pointerBoolean HIDIsValidDevice(const pRecDevice pSearchDevice){ pRecDevice pDevice = gpDeviceList; while (pDevice) { if (pDevice == pSearchDevice) return true; pDevice = pDevice->pNext; } return false;}static IOReturn hid_CreateQueue (pRecDevice pDevice){ IOReturn result = kIOReturnError; // assume failure (pessimist!) if (HIDIsValidDevice(pDevice)) { if (NULL == pDevice->queue) // do we already have a queue { if (NULL != pDevice->interface) { pDevice->queue = (void *) (*(IOHIDDeviceInterface**) pDevice->interface)->allocQueue (pDevice->interface); // alloc queue if (pDevice->queue) { result = (*(IOHIDQueueInterface**) pDevice->queue)->create (pDevice->queue, 0, kDeviceQueueSize); // create actual queue if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("hid_CreateQueue - Failed to create queue via create", result); } else { HIDREPORTERROR ("hid_CreateQueue - Failed to alloc IOHIDQueueInterface ** via allocQueue"); result = kIOReturnError; // synthesis error } } else HIDREPORTERRORNUM ("hid_CreateQueue - Device inteface does not exist for queue creation", result); } } else HIDREPORTERRORNUM ("hid_CreateQueue - Invalid Device", result); return result;}static unsigned long HIDQueueDevice (pRecDevice pDevice){ IOReturn result = kIOReturnError; // assume failure (pessimist!) pRecElement pElement; if (HIDIsValidDevice(pDevice)) { // error checking if (NULL == pDevice) { HIDREPORTERROR ("HIDQueueDevice - Device does not exist."); return kIOReturnBadArgument; } if (NULL == pDevice->interface) // must have interface { HIDREPORTERROR ("HIDQueueDevice - Device does not have interface."); return kIOReturnError; } if (NULL == pDevice->queue) // if no queue create queue result = hid_CreateQueue (pDevice); if ((kIOReturnSuccess != result) || (NULL == pDevice->queue)) { HIDREPORTERRORNUM ("HIDQueueDevice - problem creating queue.", result); if (kIOReturnSuccess != result) return result; else return kIOReturnError; } // stop queue result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDQueueDevice - Failed to stop queue.", result); // queue element //¥ pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeInput | kHIDElementTypeFeature); while (pElement) { if (!(*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie)) { result = (*(IOHIDQueueInterface**) pDevice->queue)->addElement (pDevice->queue, pElement->cookie, 0); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDQueueDevice - Failed to add element to queue.", result); } //¥ pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeInput | kHIDElementTypeFeature); } // start queue result = (*(IOHIDQueueInterface**) pDevice->queue)->start (pDevice->queue); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDQueueDevice - Failed to start queue.", result); } else HIDREPORTERROR ("HIDQueueDevice - Invalid device."); return result;}/* -- END HID UTILITIES -- */static int available_mice = 0;static pRecDevice *devices = NULL;/* returns non-zero if (a <= b). */typedef unsigned long long ui64;static inline int oldEvent(const AbsoluteTime *a, const AbsoluteTime *b){#if 0 // !!! FIXME: doesn't work, timestamps aren't reliable. const ui64 a64 = (((unsigned long long) a->hi) << 32) | a->lo; const ui64 b64 = (((unsigned long long) b->hi) << 32) | b->lo;#endif return 0;} /* oldEvent */static int poll_mouse(pRecDevice mouse, ManyMouseEvent *outevent){ int unhandled = 1; while (unhandled) /* read until failure or valid event. */ { pRecElement recelem; IOHIDEventStruct event; if (!HIDGetEvent(mouse, &event)) return(0); /* no new event. */ unhandled = 0; /* will reset if necessary. */ recelem = HIDGetFirstDeviceElement(mouse, kHIDElementTypeInput); while (recelem != NULL) { if (recelem->cookie == event.elementCookie) break; recelem = HIDGetNextDeviceElement(recelem, kHIDElementTypeInput); } /* while */ if (recelem == NULL) continue; /* unknown device element. Can this actually happen? */ outevent->value = event.value; if (recelem->usagePage == kHIDPage_GenericDesktop) { /* * some devices (two-finger-scroll trackpads?) seem to give * a flood of events with values of zero for every legitimate * event. Throw these zero events out. */ if (outevent->value == 0) unhandled = 1; else { switch (recelem->usage) { case kHIDUsage_GD_X: case kHIDUsage_GD_Y: if (oldEvent(&event.timestamp, &mouse->lastScrollTime)) unhandled = 1; else { outevent->type = MANYMOUSE_EVENT_RELMOTION; if (recelem->usage == kHIDUsage_GD_X) outevent->item = 0; else outevent->item = 1; } /* else */ break; case kHIDUsage_GD_Wheel: memcpy(&mouse->lastScrollTime, &event.timestamp, sizeof (AbsoluteTime)); outevent->type = MANYMOUSE_EVENT_SCROLL; outevent->item = 0; /* !!! FIXME: horiz scroll? */ break; default: /* !!! FIXME: absolute motion? */ unhandled = 1; } /* switch */ } /* else */ } /* if */ else if (recelem->usagePage == kHIDPage_Button) { outevent->type = MANYMOUSE_EVENT_BUTTON; outevent->item = ((int) recelem->usage) - 1; } /* else if */ else { unhandled = 1; } /* else */ } /* while */ return(1); /* got a valid event */} /* poll_mouse */static void macosx_hidmanager_quit(void){ HIDReleaseAllDeviceQueues(); HIDReleaseDeviceList(); free(devices); devices = NULL; available_mice = 0;} /* macosx_hidmanager_quit */static int macosx_hidmanager_init(void){ macosx_hidmanager_quit(); /* just in case... */ if (!HIDBuildDeviceList(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) return(-1); available_mice = HIDCountDevices(); if (available_mice > 0) { int i; pRecDevice dev = NULL; dev = HIDGetFirstDevice(); devices = (pRecDevice *) malloc(sizeof (pRecDevice) * available_mice); if ((devices == NULL) || (dev == NULL)) { macosx_hidmanager_quit(); return(-1); } /* if */ for (i = 0; i < available_mice; i++) { if (dev == NULL) /* what? list ended? Truncate final list... */ available_mice = i; if (HIDQueueDevice(dev) == kIOReturnSuccess) devices[i] = dev; else /* failed? Chop this device from the list... */ { i--; available_mice--; } /* else */ dev = HIDGetNextDevice(dev); } /* for */ } /* if */ return(available_mice);} /* macosx_hidmanager_init */static const char *macosx_hidmanager_name(unsigned int index){ if (index >= available_mice) return(NULL); return((const char *) devices[index]->product);} /* macosx_hidmanager_name */static int macosx_hidmanager_poll(ManyMouseEvent *event){ /* * (i) is static so we iterate through all mice round-robin. This * prevents a chatty mouse from dominating the queue. */ static unsigned int i = 0; if (i >= available_mice) i = 0; /* handle reset condition. */ if (event != NULL) { while (i < available_mice) { pRecDevice dev = devices[i]; if ((dev) && (dev->disconnect != DISCONNECT_COMPLETE)) { event->device = i; /* see if mouse was unplugged since last polling... */ if (dev->disconnect == DISCONNECT_TELLUSER) { dev->disconnect = DISCONNECT_COMPLETE; event->type = MANYMOUSE_EVENT_DISCONNECT; return(1); } /* if */ if (poll_mouse(dev, event)) return(1); } /* if */ i++; } /* while */ } /* if */ return(0); /* no new events */} /* macosx_hidmanager_poll */#elsestatic int macosx_hidmanager_init(void) { return(-1); }static void macosx_hidmanager_quit(void) {}static const char *macosx_hidmanager_name(unsigned int index) { return(0); }static int macosx_hidmanager_poll(ManyMouseEvent *event) { return(0); }#endif /* MacOSX blocker */ManyMouseDriver ManyMouseDriver_hidmanager ={ macosx_hidmanager_init, macosx_hidmanager_quit, macosx_hidmanager_name, macosx_hidmanager_poll};/* end of macosx_hidmanager.c ... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -