Example #1
0
void updateindicators(usbdevice* kb, int force){
    // Set NumLock on permanently
    char ileds = 1;
    // Set Caps Lock if enabled. Unlike Linux, OSX keyboards have independent caps lock states, so
    // we use the last-assigned value rather than fetching it from the system
    if(kb->eflags & kCGEventFlagMaskAlphaShift)
        ileds |= 2;
    if(force || ileds != kb->ileds){
        kb->ileds = ileds;
        // Set the LEDs
        CFArrayRef leds = IOHIDDeviceCopyMatchingElements(kb->handles[0], 0, kIOHIDOptionsTypeNone);
        CFIndex count = CFArrayGetCount(leds);
        for(CFIndex i = 0; i < count; i++){
            IOHIDElementRef led = (void*)CFArrayGetValueAtIndex(leds, i);
            uint32_t page = IOHIDElementGetUsagePage(led);
            if(page != kHIDPage_LEDs)
                continue;
            uint32_t usage = IOHIDElementGetUsage(led);
            IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, led, 0, !!(ileds & (1 << (usage - 1))));
            IOHIDDeviceSetValue(kb->handles[0], led, value);
            CFRelease(value);
        }
        CFRelease(leds);
        IOHIDDeviceSetReport(kb->handles[1], kIOHIDReportTypeOutput, 0, &kb->ileds, 1);
    }
}
Example #2
0
void os_updateindicators(usbdevice* kb, int force){
    if(!IS_CONNECTED(kb) || NEEDS_FW_UPDATE(kb))
        return;
    // Set NumLock on permanently
    char ileds = 1;
    // Set Caps Lock if enabled. Unlike Linux, OSX keyboards have independent caps lock states, so
    // we use the last-assigned value rather than fetching it from the system
    if(kb->eventflags & kCGEventFlagMaskAlphaShift)
        ileds |= 2;
    usbmode* mode = kb->profile.currentmode;
    if(mode && kb->active)
        ileds = (ileds & ~mode->ioff) | mode->ion;
    if(force || ileds != kb->ileds){
        kb->ileds = ileds;
        // Set the LEDs
        CFArrayRef leds = IOHIDDeviceCopyMatchingElements(kb->handles[0], 0, kIOHIDOptionsTypeNone);
        CFIndex count = CFArrayGetCount(leds);
        for(CFIndex i = 0; i < count; i++){
            IOHIDElementRef led = (void*)CFArrayGetValueAtIndex(leds, i);
            uint32_t page = IOHIDElementGetUsagePage(led);
            if(page != kHIDPage_LEDs)
                continue;
            uint32_t usage = IOHIDElementGetUsage(led);
            IOHIDValueRef value = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, led, 0, !!(ileds & (1 << (usage - 1))));
            IOHIDDeviceSetValue(kb->handles[0], led, value);
            CFRelease(value);
        }
        CFRelease(leds);
    }
}
static void __deviceReportCallback(void * context, IOReturn result, void * sender, IOHIDReportType type, uint32_t reportID, uint8_t * report, CFIndex reportLength)
{
    int index;
    
    printf("IOHIDDeviceRef[%p]: result=0x%08x reportType=%s reportID=%d reportLength=%ld: ", sender, result, getReportTypeString(type), reportID, reportLength);
    for (index=0; result==kIOReturnSuccess && index<reportLength; index++)
        printf("%02x ", report[index]);
    printf("\n");
    
    // toggle a report
    if ( gSend || gSendTransaction ) {
        CFArrayRef outputElements  = NULL;
        
        outputElements = CFDictionaryGetValue(gOutputElements, sender);
        
        if ( outputElements ) {
            static uint8_t      value       = 0;
            IOHIDTransactionRef transaction = NULL;
            
            transaction = IOHIDTransactionCreate(kCFAllocatorDefault, (IOHIDDeviceRef)sender, kIOHIDTransactionDirectionTypeOutput, 0);
            if ( transaction ) {
                IOReturn    ret;
                CFIndex     index, count;
                
                for ( index=0, count = CFArrayGetCount(outputElements); index<count; index++) {
                    
                    IOHIDElementRef element     = (IOHIDElementRef)CFArrayGetValueAtIndex(outputElements, index);
                    IOHIDValueRef   hidValue    = 0;
                    
                    if ( !element )
                        continue;
                    
                    IOHIDTransactionAddElement(transaction, element);
                    
                    hidValue = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, element, 0, value);
                    if ( !hidValue )
                        continue;
                    
                    if ( gSendTransaction ) {
                        IOHIDTransactionSetValue(transaction, element, hidValue, 0);
                    } else {
                        ret = IOHIDDeviceSetValue((IOHIDDeviceRef)sender, element, hidValue);
                        printf("Attempt to send value. Ret = 0x%08x\n", ret);
                    }
                    CFRelease(hidValue);
                    
                }
                
                if ( gSendTransaction ) {
                    ret = IOHIDTransactionCommit(transaction);
                    printf("Attempt to send transaction. Ret = 0x%08x\n", ret);
                }
                value = value+1 % 2;
                
                CFRelease(transaction);
            }
        }
    }
}
Example #4
0
void setKeyboard(struct __IOHIDDevice *device, CFDictionaryRef keyboardDictionary, LedState changes[])
{
    CFStringRef deviceNameRef = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
    if (!deviceNameRef) return;
    
    const char * deviceName = CFStringGetCStringPtr(deviceNameRef, kCFStringEncodingUTF8);
    
    if (nameMatch && fnmatch(nameMatch, deviceName, 0) != 0)
        return;
    
    if (verbose)
        printf("\n \"%s\" ", deviceName);
    
    CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, keyboardDictionary, kIOHIDOptionsTypeNone);
    if (elements) {
        for (CFIndex elementIndex = 0; elementIndex < CFArrayGetCount(elements); elementIndex++) {
            IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, elementIndex);
            if (element && kHIDPage_LEDs == IOHIDElementGetUsagePage(element)) {
                uint32_t led = IOHIDElementGetUsage(element);
                
                if (led >= maxLeds) break;
                
                // Get current keyboard led status
                IOHIDValueRef currentValue = 0;
                if (IOHIDDeviceGetValue(device, element, &currentValue) == kIOReturnSuccess &&
                    IOHIDValueGetLength(currentValue) < 3) {
                    long current = IOHIDValueGetIntegerValue(currentValue);
                    CFRelease(currentValue);
                    
                    // Should we try to set the led?
                    if (changes[led] != NoChange && changes[led] != current) {
                        IOHIDValueRef newValue = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, element, 0, changes[led]);
                        if (newValue) {
                            IOReturn changeResult = IOHIDDeviceSetValue(device, element, newValue);
                            
                            // Was the change successful?
                            if (kIOReturnSuccess == changeResult && verbose) {
                                printf("%s%s ", stateSymbol[changes[led]], ledNames[led - 1]);
                            }
                            CFRelease(newValue);
                        }
                    } else if (verbose) {
                        printf("%s%s ", stateSymbol[current], ledNames[led - 1]);
                    }
                }
            }
        }
        CFRelease(elements);
    }
    
    if (verbose)
        printf("\n");
}
Example #5
0
//int main( int argc, const char * argv[] )
int manipulate_led( int which_led, int led_value )
{
#pragma unused ( argc, argv )
	IOHIDDeviceRef * tIOHIDDeviceRefs = nil;

	// create a IO HID Manager reference
	IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
	require( tIOHIDManagerRef, Oops );

	// Create a device matching dictionary
	CFDictionaryRef matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( TRUE,
																				  kHIDPage_GenericDesktop,
																				  kHIDUsage_GD_Keyboard );
	require( matchingCFDictRef, Oops );

	// set the HID device matching dictionary
	IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );

	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}

	// Now open the IO HID Manager reference
	IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone );
	require_noerr( tIOReturn, Oops );

	// and copy out its devices
	CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef );
	require( deviceCFSetRef, Oops );

	// how many devices in the set?
	CFIndex deviceIndex, deviceCount = CFSetGetCount( deviceCFSetRef );

	// allocate a block of memory to extact the device ref's from the set into
	tIOHIDDeviceRefs = malloc( sizeof( IOHIDDeviceRef ) * deviceCount );
	if (!tIOHIDDeviceRefs) {
		CFRelease(deviceCFSetRef);
		deviceCFSetRef = NULL;
		goto Oops;
	}

	// now extract the device ref's from the set
	CFSetGetValues( deviceCFSetRef, (const void **) tIOHIDDeviceRefs );
	CFRelease(deviceCFSetRef);
	deviceCFSetRef = NULL;

	// before we get into the device loop we'll setup our element matching dictionary
	matchingCFDictRef = hu_CreateMatchingDictionaryUsagePageUsage( FALSE, kHIDPage_LEDs, 0 );
	require( matchingCFDictRef, Oops );

	int pass;	// do 256 passes
	//for ( pass = 0; pass < 256; pass++ ) {
		Boolean delayFlag = FALSE;	// if we find an LED element we'll set this to TRUE

		//printf( "pass = %d.\n", pass );
		for ( deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++ ) {

			// if this isn't a keyboard device...
			if ( !IOHIDDeviceConformsTo( tIOHIDDeviceRefs[deviceIndex], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard ) ) {
				continue;	// ...skip it
			}

			//printf( "	 device = %p.\n", tIOHIDDeviceRefs[deviceIndex] );

			// copy all the elements
			CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements( tIOHIDDeviceRefs[deviceIndex],
																		   matchingCFDictRef,
																		   kIOHIDOptionsTypeNone );
			require( elementCFArrayRef, next_device );

			// for each device on the system these values are divided by the value ranges of all LED elements found
			// for example, if the first four LED element have a range of 0-1 then the four least significant bits of
			// this value will be sent to these first four LED elements, etc.
			int device_value = pass;

			// iterate over all the elements
			CFIndex elementIndex, elementCount = CFArrayGetCount( elementCFArrayRef );
			for ( elementIndex = 0; elementIndex < elementCount; elementIndex++ ) {
				IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( elementCFArrayRef, elementIndex );
				require( tIOHIDElementRef, next_element );

				uint32_t usagePage = IOHIDElementGetUsagePage( tIOHIDElementRef );

				// if this isn't an LED element...
				if ( kHIDPage_LEDs != usagePage ) {
					continue;	// ...skip it
				}

				uint32_t usage = IOHIDElementGetUsage( tIOHIDElementRef );
				IOHIDElementType tIOHIDElementType = IOHIDElementGetType( tIOHIDElementRef );

				//printf( "		 element = %p (page: %d, usage: %d, type: %d ).\n",
				//	   tIOHIDElementRef, usagePage, usage, tIOHIDElementType );

				// get the logical mix/max for this LED element
				CFIndex minCFIndex = IOHIDElementGetLogicalMin( tIOHIDElementRef );
				CFIndex maxCFIndex = IOHIDElementGetLogicalMax( tIOHIDElementRef );

				// calculate the range
				CFIndex modCFIndex = maxCFIndex - minCFIndex + 1;

				// compute the value for this LED element
				//CFIndex tCFIndex = minCFIndex + ( device_value % modCFIndex );
				CFIndex tCFIndex = led_value;
				device_value /= modCFIndex;

				//printf( "			 value = 0x%08lX.\n", tCFIndex );

				uint64_t timestamp = 0; // create the IO HID Value to be sent to this LED element
				IOHIDValueRef tIOHIDValueRef = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, tIOHIDElementRef, timestamp, tCFIndex );
				if ( tIOHIDValueRef ) {
					// now set it on the device
					tIOReturn = IOHIDDeviceSetValue( tIOHIDDeviceRefs[deviceIndex], tIOHIDElementRef, tIOHIDValueRef );
					CFRelease( tIOHIDValueRef );
					require_noerr( tIOReturn, next_element );
					delayFlag = TRUE;	// set this TRUE so we'll delay before changing our LED values again
				}
			next_element:	;
				continue;
			}
			CFRelease( elementCFArrayRef );
		next_device: ;
			continue;
		}

		// if we found an LED we'll delay before continuing
		//if ( delayFlag ) {
		//	usleep( 500000 ); // sleep one half second
		//}

		// if the mouse is down…
		//if (GetCurrentButtonState()) {
		//	break;	// abort pass loop
		//}
	//}						  // next pass

	if ( matchingCFDictRef ) {
		CFRelease( matchingCFDictRef );
	}
Oops:	;
	if ( tIOHIDDeviceRefs ) {
		free(tIOHIDDeviceRefs);
	}

	if ( tIOHIDManagerRef ) {
		CFRelease( tIOHIDManagerRef );
	}
	return 0;
} /* main */
Example #6
0
void GPUSB_SetBit(int bit, int val)
{
    if (!pGPUSB) return;  // no device, bail
    IOHIDElementRef pCurrentHIDElement = NULL;
    //IOHIDEventStruct HID_IOEvent;
    
    int i;
    static int bitarray[8]={0,0,0,0,1,1,0,0};
    static unsigned char GPUSB_reg = 0x30;

    if (GPUSB_Model)
    { 
        // Newer models - use a single byte
        pCurrentHIDElement = GetFirstOutputElement(pGPUSB);
        if(pCurrentHIDElement == NULL)
        {
            wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Null element");
            return;
        }
//      HIDTransactionAddElement(pGPUSB,pCurrentHIDElement);
        
        unsigned char bmask = 1;
        bmask = bmask << bit;
        if (val)
        {
            GPUSB_reg = GPUSB_reg | bmask;
        }
        else
        {
            GPUSB_reg = GPUSB_reg & ~bmask;
        }
        
        //HID_IOEvent.longValueSize = 0;
        //HID_IOEvent.longValue = nil;

        /*IOHIDValueRef valueToSend = IOHIDValueCreateWithBytes(
                                        kCFAllocatorDefault, 
                                        pCurrentHIDElement, 
                                        uint64_t        inTimeStamp,
                                        &GPUSB_reg,
                                        1);
        */

        //IOHIDElementCookie cookie = IOHIDElementGetCookie(pCurrentHIDElement);
        IOHIDValueRef valueToSend;
        IOReturn tIOReturn = IOHIDDeviceGetValue(pGPUSB, pCurrentHIDElement, &valueToSend);
        if(tIOReturn != kIOReturnSuccess)
        {
            CFRelease(pCurrentHIDElement);
            wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot retrieve value (1)");
            return;
        }
        
        assert(IOHIDValueGetLength(valueToSend) == 1);
        
        IOHIDValueRef valueToSendCopied = IOHIDValueCreateWithBytes(
                                        kCFAllocatorDefault, 
                                        pCurrentHIDElement, 
                                        IOHIDValueGetTimeStamp(valueToSend),
                                        &GPUSB_reg,
                                        1);
        
        
        tIOReturn = IOHIDDeviceSetValue(pGPUSB, pCurrentHIDElement, valueToSendCopied);
        if(tIOReturn != kIOReturnSuccess)
        {
            CFRelease(pCurrentHIDElement);
            wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot send value (1)");
            return;
        }

        
        
        //pGPUSB_interface->getElementValue (pGPUSB_interface, cookie, &HID_IOEvent);

        //HID_IOEvent.value = (SInt32) GPUSB_reg;
//      wxMessageBox(wxString::Format("%x - %x %x    %d %d",foo,GPUSB_reg,bmask,bit,val));
//      HID_IOEvent.type = (IOHIDElementType) pCurrentHIDElement->type;
        //HIDSetElementValue(pGPUSB,pCurrentHIDElement,&HID_IOEvent);
//      HIDTransactionCommit(pGPUSB);
        CFRelease(pCurrentHIDElement);
    }
    else {
        // Generic bit-set routine.  For older adapters, we can't send a whole
        // byte and things are setup as SInt32's per bit with 8 bits total...
        //IOHIDEventStruct hidstruct = {kIOHIDElementTypeOutput};
        
        
        IOHIDTransactionRef transaction = IOHIDTransactionCreate(
                          kCFAllocatorDefault,
                          pGPUSB,
                          kIOHIDTransactionDirectionTypeOutput, 
                          kIOHIDOptionsTypeNone);    
                          
        if(transaction == NULL)
        {
            wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot create a transaction");
        }
        
        
        bitarray[bit]=val;
//      std::cout << "Setting to ";
        for (i=0; i<8; i++) {  // write
//          std::cout << " " << bitarray[i];
            if (i==0)
            {
                pCurrentHIDElement = GetFirstOutputElement(pGPUSB);
            }
            else
            {
                pCurrentHIDElement = GetNextOutputElement(pGPUSB, pCurrentHIDElement);
            }
            
            IOHIDValueRef valueToSend;
            IOReturn tIOReturn = IOHIDDeviceGetValue(pGPUSB, pCurrentHIDElement, &valueToSend);
            if(tIOReturn != kIOReturnSuccess)
            {
                CFRelease(pCurrentHIDElement);
                wxMessageBox(std::string(__PRETTY_FUNCTION__) + " Cannot retrieve value (1)");
                return;
            }
            
            //CFTypeID tID = IOHIDValueGetTypeID(valueToSend);
            
            /*IOHIDValueRef valueToSendCopied = IOHIDValueCreateWithBytes(
                                                  kCFAllocatorDefault, 
                                                  pCurrentHIDElement, 
                                                  IOHIDValueGetTimeStamp(valueToSend),
                                                  &bitarray[i],
                                                  sizeof(bitarray[i]));   */
                                                  
            IOHIDValueRef valueToSendCopied = IOHIDValueCreateWithIntegerValue(
                                                  kCFAllocatorDefault,
                                                  pCurrentHIDElement,
                                                  IOHIDValueGetTimeStamp(valueToSend),
                                                  bitarray[i]);
            
            IOHIDTransactionAddElement(transaction, pCurrentHIDElement);
            IOHIDTransactionSetValue(transaction, pCurrentHIDElement, valueToSendCopied, 0);
            
            
            //HIDTransactionAddElement(pGPUSB,pCurrentHIDElement);
            //hidstruct.type = (IOHIDElementType) pCurrentHIDElement->type;
            //hidstruct.value = (SInt32) bitarray[i];
            //HIDTransactionSetElementValue(pGPUSB,pCurrentHIDElement,&hidstruct);
        }
//      std::cout << "\n";
        IOHIDTransactionCommit(transaction);
    }

//  wxMilliSleep(30);
}