示例#1
0
/* Send power messages to rootDomain */
bool Insomnia::send_event(UInt32 msg) {
	IOPMrootDomain *root = NULL;
	IOReturn		ret=kIOReturnSuccess;
	char			err_str[100];
	
	IOLog("Insomina: Sending event\n");
	
	root = getPMRootDomain();
	if (!root) {
		IOLog("Insomnia: Fatal error could not get RootDomain.\n");
		return false;
	}
	
	
	ret = root->receivePowerNotification(msg);
	
	IOLog("Insomnia: root returns %d\n", ret);
	
	if(ret!=kIOReturnSuccess)
	{
		snprintf(err_str, 100, "Insomina: Error sending event: %d\n", ret);
		IOLog("%s", err_str);
	}
	else
		IOLog("Insomnia: Message sent to root\n");
	
	return true;
}
示例#2
0
/* Send power messages to rootDomain */
bool Insomnia::send_event(UInt32 msg) {
    IOPMrootDomain *root = NULL;
    IOReturn        ret=kIOReturnSuccess;
    
    DLog("");
    
    root = getPMRootDomain();
    if (!root) {
        DLog("Fatal error could not get RootDomain.");
        return false;
    }

    ret = root->receivePowerNotification(msg);
    
    Log("root returns %d", ret);
    
    if(ret!=kIOReturnSuccess)
    {
        DLog("Error sending event: %d", ret);
    }
    else
        Log("Message sent to root");
    
    return true;
}
IOReturn ACPIACAdapter::message(UInt32 type, IOService* provider, void* argument)
{
    DEBUG_LOG("ACPIACAdapter::message: type: %08X provider: %s\n", (unsigned int)type, provider->getName());
    
    if (type == kIOACPIMessageDeviceNotification && fProvider)
    {
        UInt32 acpi = 0;
        if (kIOReturnSuccess == fProvider->evaluateInteger("_PSR", &acpi))
        {
            DEBUG_LOG("ACPIACAdapter::message setting AC %s\n", (acpi ? "connected" : "disconnected"));
            
            // notify system of change in AC state
            if (IOPMrootDomain* root = getPMRootDomain())
                root->receivePowerNotification(kIOPMSetACAdaptorConnected | acpi ? kIOPMSetValue : 0);
            else
                DEBUG_LOG("ACPIACAdapter::message could not notify OS about AC status\n");
            
            // notify battery managers of change in AC state
            if (NULL != fTracker)
                fTracker->notifyBatteryManagers(acpi);
        }
        else
        {
            IOLog("ACPIACAdapter: ACPI method _PSR failed\n");
        }
    }
    return kIOReturnSuccess;
}
bool IOEthernetInterface::controllerDidOpen(IONetworkController * ctr)
{
    bool                 ret = false;
    OSData *             addrData;
    IOEthernetAddress *  addr;

    do {
        // Call the controllerDidOpen() in superclass first.

        if ( (ctr == 0) || (super::controllerDidOpen(ctr) == false) )
             break;

        // If the controller supports some form of multicast filtering,
        // then set the ifnet IFF_MULTICAST flag.

        if ( GET_SUPPORTED_FILTERS(gIONetworkFilterGroup) &
             (kIOPacketFilterMulticast | kIOPacketFilterMulticastAll) )
        {
            setFlags(IFF_MULTICAST);
        }

        // Advertise Wake on Magic Packet feature if supported.
        
        if ( _supportedWakeFilters & kIOEthernetWakeOnMagicPacket )
        {
            IOPMrootDomain * root = getPMRootDomain();
            if ( root ) root->publishFeature( kWOMPFeatureKey,
                             kIOPMSupportedOnAC | kIOPMSupportedOnUPS, 
                             (uint32_t *)&_publishedFeatureID);
        }

        // Get the controller's MAC/Ethernet address.

        addrData = OSDynamicCast(OSData, ctr->getProperty(kIOMACAddress));
        if ( (addrData == 0) || (addrData->getLength() != ETHER_ADDR_LEN) )
        {
            DLOG("%s: kIOMACAddress property access error (len %d)\n",
                 getName(), addrData ? addrData->getLength() : 0);
            break;
        }

        addr = (IOEthernetAddress *) addrData->getBytesNoCopy();

        DLOG("%s: Ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n",
              ctr->getName(),
              addr->bytes[0],
              addr->bytes[1],
              addr->bytes[2],
              addr->bytes[3],
              addr->bytes[4],
              addr->bytes[5]);

        ret = true;
    }
    while (0);

    return ret;
}
void IOEthernetInterface::controllerWillClose(IONetworkController * ctr)
{
    if ( _supportedWakeFilters & kIOEthernetWakeOnMagicPacket )
    {
        IOPMrootDomain * root = getPMRootDomain();
        if ( root ) root->removePublishedFeature( _publishedFeatureID );
        _publishedFeatureID = 0;
    }
    
    super::controllerWillClose(ctr);
}
bool NoSleepExtension::start( IOService * provider )
{
#ifdef DEBUG
    IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__,
		  provider);
#endif
    if( !super::start( provider ))
        return( false );
    
    //task_t x = current_task();
    //IOLog("task: %p, %p\n", x, bootstrap_port);
    
    delayTimer = thread_call_allocate(_switchOffUserSleepDisabled, (thread_call_param_t) this);
    
    isSleepStateInitialized = false;
    
    acSleepSuppressionState = kNoSleepStateDisabled;
    batterySleepSuppressionState = kNoSleepStateDisabled;
    
    forceClientMessage = false;
    isOnAC = true;
    pPowerSource = NULL;
    
    // This should be done ASAP, cause pRootDomain
    // is used later in other methods
    pRootDomain = getPMRootDomain();

    UInt8 loadedState;
    OSReturn ret = readNVRAM(&loadedState);
    if(ret == kOSReturnSuccess) {
        unpackSleepState(loadedState,
                         &batterySleepSuppressionState,
                         &acSleepSuppressionState);
    }
    
    /// NoSleep will be activeted after matching with the IOPMPowerSource
    //updateSleepPowerState();
    
    clamshellStateInterestNotifier = 
        pRootDomain->registerInterest(gIOGeneralInterest,
                                      NoSleepExtension::_clamshellEventInterestHandler, this);
    
    registerService();
    
    startPM(provider);
    
    IOLog("%s: successfully started\n", getName());
    
    return true;
}
void IOEthernetInterface::free()
{
    if ( _requiredFilters )
    {
        _requiredFilters->release();
        _requiredFilters = 0;
    }

    if ( _activeFilters )
    {
        _activeFilters->release();
        _activeFilters = 0;
    }
    
    if ( _supportedFilters )
    {
        _supportedFilters->release();
        _supportedFilters = 0; 
    }

    if ( _inputEventThreadCall )
    {
        thread_call_free( _inputEventThreadCall );
        _inputEventThreadCall = 0;
    }

	if ( _reserved )
	{
        if (kIOPMUndefinedDriverAssertionID != _wompEnabledAssertionID)
        {
            getPMRootDomain()->releasePMAssertion(_wompEnabledAssertionID);
            _wompEnabledAssertionID = kIOPMUndefinedDriverAssertionID;
        }

        if (_disabledWakeFilters)
        {
            _disabledWakeFilters->release();
            _disabledWakeFilters = 0;
        }
		IODelete( _reserved, ExpansionData, 1 );
        _reserved = 0;
    }
	
    super::free();
}
void IOPMPagingPlexus::processSiblings ( IOService * aNode )
{
    OSIterator *	parentIterator;
    IORegistryEntry *	nextNub;
    IORegistryEntry *	nextParent;
    OSIterator *	siblingIterator;
    IORegistryEntry *	nextSibling;

    parentIterator = aNode->getParentIterator(gIOPowerPlane);		// iterate parents of this node

    if ( parentIterator ) {
        while ( true ) {
            if ( ! (nextNub = (IORegistryEntry *)(parentIterator->getNextObject())) ) {
                parentIterator->release();
                break;
            }
            if ( OSDynamicCast(IOPowerConnection,nextNub) ) {
                nextParent = nextNub->getParentEntry(gIOPowerPlane);
                if ( nextParent == getPMRootDomain() ) {
                    continue;				// plexus already has root's children
                }
                if ( nextParent == this ) {
                    parentIterator->release();
                    removePowerChild((IOPowerConnection *)nextNub);
                    break;
                }
                siblingIterator = nextParent->getChildIterator(gIOPowerPlane);
                                                                                // iterate children of this parent
                if ( siblingIterator ) {
                    while ( (nextSibling = (IORegistryEntry *)(siblingIterator->getNextObject())) ) {
                        if ( OSDynamicCast(IOPowerConnection,nextSibling) ) {
                            nextSibling = nextSibling->getChildEntry(gIOPowerPlane);
                            if ( nextSibling != aNode ) {			// non-ancestor of driver gets
                                addPowerChild((IOService *)nextSibling);	// plexus as parent
                            }
                        }
                    }
                    siblingIterator->release();
                }
                processSiblings((IOService *)nextParent);			// do the same thing to this parent
            }
   	}
    }
}
示例#9
0
/* free function for Insomnia, fixed send_event to match other code */
void Insomnia::free() {
	IOPMrootDomain *root = NULL;
	
	root = getPMRootDomain();
	
	if (!root) {
		IOLog("Insomnia: Fatal error could not get RootDomain.\n");
		return;
	}
	
	/* Reset the system to orginal state */
	Insomnia::send_event(kIOPMAllowSleep | kIOPMEnableClamshell);
	
	
	IOLog("Insomnia: Lid close is now processed again.\n");
	
	super::free();
	return;
}
int IOPlatformExpert::haltRestart(unsigned int type)
{
  IOPMrootDomain *rd = getPMRootDomain();
  OSBoolean   *b = 0;
    
  if(rd) b = (OSBoolean *)OSDynamicCast(OSBoolean, rd->getProperty(OSString::withCString("StallSystemAtHalt")));

  if (type == kPEHangCPU) while (1);

  if (kOSBooleanTrue == b) {
    // Stall shutdown for 5 minutes, and if no outside force has removed our power, continue with
    // a reboot.
    IOSleep(1000*60*5);
    type = kPERestartCPU;
  }
  
  if (PE_halt_restart) return (*PE_halt_restart)(type);
  else return -1;
}
IOReturn IOPMPagingPlexus::setAggressiveness ( unsigned long type, unsigned long )
{
    OSDictionary *	dict;
    OSIterator *	iter;
    OSObject *		next;
    IOService *		candidate = 0;
    IOService *		pagingProvider;

    if( type != kPMMinutesToSleep)
        return IOPMNoErr;
    
    IOLockLock(ourLock);
    if ( systemBooting ) {
        systemBooting = false;
        IOLockUnlock(ourLock);
        dict = IOBSDNameMatching(rootdevice);
        if ( dict ) {
            iter = getMatchingServices(dict);
            if ( iter ) {
                while ( (next = iter->getNextObject()) ) {
                    if ( (candidate = OSDynamicCast(IOService,next)) ) {
                        break;
                    }
                }
                iter->release();
            }
        }
        if ( candidate ) {
            pagingProvider = findProvider(candidate);
            if ( pagingProvider ) {
                processSiblings(pagingProvider);
                pagingProvider->addPowerChild(this);
                getPMRootDomain()->removePowerChild(((IOPowerConnection *)getParentEntry(gIOPowerPlane)));
                processChildren();
            }
        }
    }
    else {
        IOLockUnlock(ourLock);
    }
    return IOPMNoErr;
}
bool ApplePS2Keyboard::dispatchKeyboardEventWithScancode(UInt8 scanCode)
{
  //
  // Parses the given scan code, updating all necessary internal state, and
  // should a new key be detected, the key event is dispatched.
  //
  // Returns true if a key event was indeed dispatched.
  //

  unsigned int keyCode;
  bool         goingDown;
  AbsoluteTime now;

  //
  // See if this scan code introduces an extended key sequence.  If so, note
  // it and then return.  Next time we get a key we'll finish the sequence.
  //

  if (scanCode == kSC_Extend)
  {
    _extendCount = 1;
    return false;
  }

  //
  // See if this scan code introduces an extended key sequence for the Pause
  // Key.  If so, note it and then return.  The next time we get a key, drop
  // it.  The next key we get after that finishes the Pause Key sequence.
  //
  // The sequence actually sent to us by the keyboard for the Pause Key is:
  //
  // 1. E1  Extended Sequence for Pause Key
  // 2. 1D  Useless Data, with Up Bit Cleared
  // 3. 45  Pause Key, with Up Bit Cleared
  // 4. E1  Extended Sequence for Pause Key
  // 5. 9D  Useless Data, with Up Bit Set
  // 6. C5  Pause Key, with Up Bit Set
  //
  // The reason items 4 through 6 are sent with the Pause Key is because the
  // keyboard hardware never generates a release code for the Pause Key and
  // the designers are being smart about it.  The sequence above translates
  // to this parser as two separate events, as it should be -- one down key
  // event and one up key event (for the Pause Key).
  //

  if (scanCode == kSC_Pause)
  {
    _extendCount = 2;
    return false;
  }

  //
  // Convert the scan code into a key code.
  //

	//IOLog("key 0x%x scan 0x%x ex %d\n",(scanCode & ~kSC_UpBit),scanCode,_extendCount);

  if (_extendCount == 0)
  {
    keyCode = scanCode & ~kSC_UpBit;

    // from "The Undocumented PC" chapter 8, The Keyboard System some
    // keyboard scan codes are single byte, some are multi-byte
    // 3023805:  I want to swap alt and windows, since the windows
    // key is located where the alt/option key is on an Apple PowerBook
    // or USB keyboard, and the alt key is where the Apple/Command
    // key is on the PB or USB keyboard. Left alt is a single scan
    // code byte, right alt is a double scan code byte. Left and
    // right windows keys are double bytes.  This is all set by an
    // entry in Info.plist for ApplePS2Keyboard.kext
    switch (keyCode)
    {
      case 0x3A: 
	if (emacsMode == true) {
	  keyCode = 0x60; 
	}
	break;			// caps lock becomes ctrl
      case 0x38: 
	if (macintoshMode == true) {
	  keyCode = 0x70; 
	}
	break;		// left alt becomes left windows
/* CFR: Nope...this is the code for =+
		case 0xd: // ²		
		if(scanCode==0xd) 
		{
			_extendCount=1; dispatchKeyboardEventWithScancode(0x5b);
			dispatchKeyboardEventWithScancode(0x56);
		}
		else
		{
			_extendCount=1; dispatchKeyboardEventWithScancode(0xdb);
			dispatchKeyboardEventWithScancode(0xd6);
		}
		return true;
*/
// CFR		case 0x56: keyCode = 0x29; break;            // <
// CFR		case 0x1a: keyCode = 0xd; break;            // +
// CFR		case 0x28: keyCode = 0x1a; break;            // ¼ »
// CFR		case 0x2b: keyCode = 0x28; break;            // ~
// CFR		case 0x29: keyCode = 0x2b; break;            
		case 0x8:
		if (keyi==true)	
		{
			if(scanCode==0x8) 
			{
				dispatchKeyboardEventWithScancode(0x2a);
			}
			else
			{
				dispatchKeyboardEventWithScancode(0xaa);
			}
			keyCode = 0x9;
		}
		break;
		case 0xb: 
		if (keyi==true)	
		{
			if(scanCode==0xb) 
			{
				dispatchKeyboardEventWithScancode(0x2a);
			}
			else
			{
				dispatchKeyboardEventWithScancode(0xaa);
			}
			keyCode = 0xa;
		}
		break;
		case 0x12: 
		if (keyi==true)	keyCode = 0x4;
		break;
		case 0x4: 
		if (keyi==true)	keyCode = 0x5;
		break; 
		case 0x5:
		if (keyi==true)	keyCode = 0xc;
		break;

    }
  }
  else
  {
    _extendCount--;
    if (_extendCount)  return false;

    //
    // Convert certain extended codes on the PC keyboard into single scancodes.
    // Refer to the conversion table in defaultKeymapOfLength.
    //

    switch (scanCode & ~kSC_UpBit)
    {	  	  

	  case 0x33: // Û
	  if(scanCode==0x33) 
		{
			dispatchKeyboardEventWithScancode(0x38);
			dispatchKeyboardEventWithScancode(0x10);
		}
		else
		{
			dispatchKeyboardEventWithScancode(0xb8);
			dispatchKeyboardEventWithScancode(0x90);
		}
		return true;
	  case 0x34: // $ = F12 - press and hold to eject cd rom
	  if (scanCode==0x34) 
	  {
		dispatchKeyboardEventWithScancode(0x58); 
		//dispatchKeyboardEventWithScancode(0x58); 
	  }
	  else 
	  {
		dispatchKeyboardEventWithScancode(0xd8); 
		//dispatchKeyboardEventWithScancode(0x58); 
	  }
	  return true;

	   
		 // scancodes from running showkey -s (under Linux) for extra keys on keyboard
      case 0x30: keyCode = 0x7d; break;		   // E030 = volume up
      case 0x2e: keyCode = 0x7e; break;		   // E02E = volume down
      case 0x20: keyCode = 0x7f; break;		   // E020 = volume mute

      case 0x5e: keyCode = 0x7c; break;            // E05E = power
      case 0x5f:                                   // E05F = sleep
        keyCode = 0;
        if (!(scanCode & kSC_UpBit))
        {
          IOPMrootDomain * rootDomain = getPMRootDomain();
          if (rootDomain)
            rootDomain->receivePowerNotification( kIOPMSleepNow );
        }
        break;

      case 0x1D: keyCode = 0x60; break;            // ctrl
      case 0x38:             			   // right alt may become right command
	if (macintoshMode == true) {
	  keyCode = 0x71; 
	} else {
	  keyCode = 0x61;			  
	}
	break;

      case 0x1C: keyCode = 0x62; break;            // enter
      case 0x35: keyCode = 0x63; break;            // /
      case 0x48: keyCode = 0x64; break;            // up arrow
      case 0x50: keyCode = 0x65; break;            // down arrow
      case 0x4B: keyCode = 0x66; break;            // left arrow
      case 0x4D: keyCode = 0x67; break;            // right arrow
      case 0x52: keyCode = 0x68; break;            // insert 0x68
      case 0x53: keyCode = 0x69; break;            // delete
      case 0x49: keyCode = 0x6A; break;            // page up
      case 0x51: keyCode = 0x6B; break;            // page down
      case 0x47: keyCode = 0x6C; break;            // home
      case 0x4F: keyCode = 0x6D; break;            // end
      case 0x37: //keyCode = 0x6E; break;            // PrintScreen
	  if(scanCode==0x37) 
		{
			dispatchKeyboardEventWithScancode(0x1d);
			dispatchKeyboardEventWithScancode(0x38);
			dispatchKeyboardEventWithScancode(0x2a);
			dispatchKeyboardEventWithScancode(0x5); 
		}
		else
		{
			dispatchKeyboardEventWithScancode(0x9d);
			dispatchKeyboardEventWithScancode(0xb8);
			dispatchKeyboardEventWithScancode(0xaa);
			dispatchKeyboardEventWithScancode(0x85); 
		}
		return true;
      case 0x45: //keyCode = 0x6F; break;            // Pause
       if(scanCode==0x45) 
		{
			dispatchKeyboardEventWithScancode(0x1d);
			dispatchKeyboardEventWithScancode(0x2e);
		}
		else
		{
			dispatchKeyboardEventWithScancode(0x9d);
			dispatchKeyboardEventWithScancode(0xae);
		}
		return true;
	  case 0x5B: 				   // left Windows key may become alt
	if (macintoshMode == true) {
	  keyCode = 0x38; 
	   if (scanCode==0x5B) keyi=true; else keyi=false;			   // alt 
	} else {
	  keyCode = 0x70;			   // Left command
	}
	break;
      case 0x5c:  				   // right Windows key may become alt
	if (macintoshMode == true) {
	  keyCode = 0x61; 			   // alt
	} else {
	  keyCode = 0x71; 			   // Right command
	}
	break;
      case 0x5D: keyCode = 0x38; if (scanCode==0x5D) keyi=true; else keyi=false; break;            // Application 0x72
      case 0x2A:             // header or trailer for PrintScreen
      default: return false;
    }
  }

	//IOLog("keycode 0x%x\n",keyCode);


  if (keyCode == 0)  return false;

  //
  // Update our key bit vector, which maintains the up/down status of all keys.
  //

  goingDown = !(scanCode & kSC_UpBit);

  if (goingDown)
  {
    //
    // Verify that this is not an autorepeated key -- discard it if it is.
    //

    if (KBV_IS_KEYDOWN(keyCode, _keyBitVector))  return false;

    KBV_KEYDOWN(keyCode, _keyBitVector);
  }
  else
  {
    KBV_KEYUP(keyCode, _keyBitVector);
  }

  //
  // We have a valid key event -- dispatch it to our superclass.
  //

  clock_get_uptime((uint64_t *)&now);

  dispatchKeyboardEvent( PS2ToADBMap[keyCode],
           /*direction*/ goingDown,
           /*timeStamp*/ now );

  return true;
}
bool ApplePS2Keyboard::dispatchKeyboardEventWithScancode(UInt8 scanCode)
{
  //
  // Parses the given scan code, updating all necessary internal state, and
  // should a new key be detected, the key event is dispatched.
  //
  // Returns true if a key event was indeed dispatched.
  //

  unsigned int keyCode;
  bool         goingDown;
  AbsoluteTime now;

    //
    //Accidental Input Keys
    //
    switch (scanCode & ~kSC_UpBit)
    {
        case 0X01://ESC
        case 0X0f://Tab
        case 0x3a://CapsLock
        case 0x2a://Shift
        case 0x36://
        case 0x1d://Cntrl
        case 0x5b://Window
        case 0x38://Alt
        case 0x5d://ContextMenu
        case 0x45://NumLock
        case 0x1c://Enter
        case 0x0e://Backspace
        case 0x64://Arrows
        case 0x65://
        case 0x66://
        case 0x67://
            _accidentalInputKeysException = true;
            break;
        case 0x52:/* 0........9 */
        case 0x4f:
        case 0x50:
        case 0x51:
        case 0x4b:
        case 0x4c:
        case 0x4d:
        case 0x47:
        case 0x48:
        case 0x49:
        case 0x53:/* ". / * - + ENTER" */
        case 0x63:
        case 0x37:
        case 0x4a:
        case 0x4e:
        case 0x62:
            _keyPadKeys = true;
            break;
        default:
            break;
    }

  //
  // See if this scan code introduces an extended key sequence.  If so, note
  // it and then return.  Next time we get a key we'll finish the sequence.
  //

  if (scanCode == kSC_Extend)
  {
    _extendCount = 1;
    return false;
  }

  //
  // See if this scan code introduces an extended key sequence for the Pause
  // Key.  If so, note it and then return.  The next time we get a key, drop
  // it.  The next key we get after that finishes the Pause Key sequence.
  //
  // The sequence actually sent to us by the keyboard for the Pause Key is:
  //
  // 1. E1  Extended Sequence for Pause Key
  // 2. 1D  Useless Data, with Up Bit Cleared
  // 3. 45  Pause Key, with Up Bit Cleared
  // 4. E1  Extended Sequence for Pause Key
  // 5. 9D  Useless Data, with Up Bit Set
  // 6. C5  Pause Key, with Up Bit Set
  //
  // The reason items 4 through 6 are sent with the Pause Key is because the
  // keyboard hardware never generates a release code for the Pause Key and
  // the designers are being smart about it.  The sequence above translates
  // to this parser as two separate events, as it should be -- one down key
  // event and one up key event (for the Pause Key).
  //

  if (scanCode == kSC_Pause)
  {
    _extendCount = 2;
    return false;
  }

  //
  // Convert the scan code into a key code.
  //

  if (_extendCount == 0)
  {
    keyCode = scanCode & ~kSC_UpBit;

    // from "The Undocumented PC" chapter 8, The Keyboard System some
    // keyboard scan codes are single byte, some are multi-byte
    // 3023805:  I want to swap alt and windows, since the windows
    // key is located where the alt/option key is on an Apple PowerBook
    // or USB keyboard, and the alt key is where the Apple/Command
    // key is on the PB or USB keyboard. Left alt is a single scan
    // code byte, right alt is a double scan code byte. Left and
    // right windows keys are double bytes.  This is all set by an
    // entry in Info.plist for ApplePS2Keyboard.kext
    switch (keyCode)
    {
      case 0x3A: 
	if (emacsMode == true) {
	  keyCode = 0x60; 
	}
	break;			// caps lock becomes ctrl
      case 0x38: 
	if (macintoshMode == true) {
	  keyCode = 0x70; 
	}
	break;		// left alt becomes left windows
    }
  }
  else
  {
    _extendCount--;
    if (_extendCount)  return false;
      
      
    //
    // Convert certain extended codes on the PC keyboard into single scancodes.
    // Refer to the conversion table in defaultKeymapOfLength.
    //

    switch (scanCode & ~kSC_UpBit)
    {
      // scancodes from running showkey -s (under Linux) for extra keys on keyboard
      case 0x30: keyCode = 0x7d; break;		   // E030 = volume up
      case 0x2e: keyCode = 0x7e; break;		   // E02E = volume down
      case 0x20: keyCode = 0x7f; break;		   // E020 = volume mute

      case 0x5e: keyCode = 0x7c; break;            // E05E = power
      case 0x5f:                                   // E05F = sleep
        keyCode = 0;
        if (!(scanCode & kSC_UpBit))
        {
          IOPMrootDomain * rootDomain = getPMRootDomain();
          if (rootDomain)
            rootDomain->receivePowerNotification( kIOPMSleepNow );
        }
        break;

      case 0x1D: keyCode = 0x60; break;            // ctrl
      case 0x38:             			   // right alt may become right command
	if (macintoshMode == true) {
	  keyCode = 0x71; 
	} else {
	  keyCode = 0x61;			  
	}
	break;
      case 0x1C: keyCode = 0x62; break;            // enter
      case 0x35: keyCode = 0x63; break;            // /
      case 0x48: keyCode = 0x64; break;            // up arrow
      case 0x50: keyCode = 0x65; break;            // down arrow
      case 0x4B: keyCode = 0x66; break;            // left arrow
      case 0x4D: keyCode = 0x67; break;            // right arrow
      case 0x52: keyCode = 0x68; break;            // insert
      case 0x53: keyCode = 0x69; break;            // delete
      case 0x49: keyCode = 0x6A; break;            // page up
      case 0x51: keyCode = 0x6B; break;            // page down
      case 0x47: keyCode = 0x6C; break;            // home
      case 0x4F: keyCode = 0x6D; break;            // end
      case 0x37: keyCode = 0x6E; break;            // PrintScreen
      case 0x45: keyCode = 0x6F; break;            // Pause
      case 0x5B: 				   // left Windows key may become alt
	if (macintoshMode == true) {
	  keyCode = 0x38; 			   // alt 
	} else {
	  keyCode = 0x70;			   // Left command
	}
	break;
      case 0x5d:  				   //right context click key becomes alt (right Windows key may become alt)
	if (macintoshMode == true) {
	  keyCode = 0x61; 			   // alt
	} else {
	  keyCode = 0x71; 			   // Right command
	}
	break;
      //case 0x5D: keyCode = 0x72; break;            // Application
      case 0x2A:             // header or trailer for PrintScreen
      default: return false;
    }
  }

  if (keyCode == 0)  return false;

  //
  // Update our key bit vector, which maintains the up/down status of all keys.
  //

  goingDown = !(scanCode & kSC_UpBit);

  if (goingDown)
  {
    //
    // Verify that this is not an autorepeated key -- discard it if it is.
    //

    if (KBV_IS_KEYDOWN(keyCode, _keyBitVector))  return false;

    KBV_KEYDOWN(keyCode, _keyBitVector);
  }
  else
  {
    KBV_KEYUP(keyCode, _keyBitVector);
  }

  //
  // We have a valid key event -- dispatch it to our superclass.
  //
    
  //IOLog("Keyboard key Code %x %d\n",keyCode,keyCode);
  //Sending PS2 Notification to Mouse/Touchpad
    if(goingDown)
    if(!_accidentalInputKeysException && !_keyPadKeys)
        _device->dispatchPS2Notification(kPS2C_DisableTouchpad);
    
  clock_get_uptime((uint64_t *)&now);

    //NUM LOCK and Print Screen Fix
    if(keyCode == 0x45 && goingDown)
    {
        setNumLockFeedback(_numKeypadLocked);
        _numKeypadLocked = !_numKeypadLocked;

    }
    else if(keyCode == 0x6e && goingDown)//Print Screen Simulation
    {
        dispatchKeyboardEvent( 55,
                              /*direction*/ true,
                              /*timeStamp*/ now );
        clock_get_uptime((uint64_t *)&now);
        dispatchKeyboardEvent( 56,
                              /*direction*/ true,
                              /*timeStamp*/ now );
        clock_get_uptime((uint64_t *)&now);
        dispatchKeyboardEvent( 21,
                              /*direction*/ true,
                              /*timeStamp*/ now );
        clock_get_uptime((uint64_t *)&now);
        dispatchKeyboardEvent( 21,
                              /*direction*/ false,
                              /*timeStamp*/ now );
        clock_get_uptime((uint64_t *)&now);
        dispatchKeyboardEvent( 56,
                              /*direction*/ false,
                              /*timeStamp*/ now );
        clock_get_uptime((uint64_t *)&now);
        dispatchKeyboardEvent( 55,
                              /*direction*/ false,
                              /*timeStamp*/ now );
    }
    else if(!((keyCode == 0x45 || keyCode == 0x6e) ||//NumLock & PrintScreen
            //Keypad Buttons
            ((keyCode == 0x52 || keyCode == 0x53 || keyCode == 0x62 || keyCode == 0x4f || keyCode == 0x50 ||
            keyCode == 0x51 || keyCode == 0x4b || keyCode == 0x4c || keyCode == 0x4d || keyCode == 0x47 ||
            keyCode == 0x48 || keyCode == 0x49 || keyCode == 0x63 || keyCode == 0x37 || keyCode == 0x4a ||
            keyCode == 0x4e)  && _numKeypadLocked)))
        dispatchKeyboardEvent( PS2ToADBMap[keyCode],  //Dispatch of Keyboard Events
           /*direction*/ goingDown,
           /*timeStamp*/ now );

   
    
    //PS2 Notification
    if(!goingDown && !_accidentalInputKeysException && !_keyPadKeys)
        _device->dispatchPS2Notification(kPS2C_EnableTouchpad);
    
    if(_accidentalInputKeysException)
        _accidentalInputKeysException = false;
    if(_keyPadKeys)
        _keyPadKeys = false;

        /*if(keyCode != 0x2a && keyCode != 0x36 && keyCode != 0x1d && keyCode != 0x60 &&
           keyCode != 0x70 && keyCode != 0x71 && keyCode != 0x38 && keyCode != 0x61 &&
           keyCode != 0x72 && keyCode != 0x0f && keyCode != 0x45 && keyCode != 0x6e && !(keyCode>0x3f && keyCode<0x44))*/
    
  return true;
}
示例#14
0
// This is called before to start the sleep process and after waking up before to
// start the wake process. We wish to disable the CPU nap mode going down and
// re-enable it before to go up.  For machines that support speed changing, we do
// some bookkeeping to make sure we end up in the right state coming out of sleep
IOReturn MacRISC2CPU::powerStateWillChangeTo ( IOPMPowerFlags theFlags, unsigned long, IOService*)
{

    if (!gPHibernateState) {
		OSData * data = OSDynamicCast(OSData, getPMRootDomain()->getProperty(kIOHibernateStateKey));
		if (data)
			gPHibernateState = (UInt32 *) data->getBytesNoCopy();
    }

    if ( ! (theFlags & IOPMPowerOn) ) {
        // Sleep sequence:
        kprintf("MacRISC2CPU %ld powerStateWillChangeTo to acknowledge power changes (DOWN) we set napping %d\n", getCPUNumber(), false);
        rememberNap = ml_enable_nap(getCPUNumber(), false);        // Disable napping (the function returns the previous state)

		// If processor based and currently slow, kick it back up so we safely come out of sleep
		if (macRISC2PE->processorSpeedChangeFlags & kProcessorBasedSpeedChange &&
			!(macRISC2PE->processorSpeedChangeFlags & kProcessorFast)) {
 				setAggressiveness (kPMSetProcessorSpeed, 0);				// Make it so
				macRISC2PE->processorSpeedChangeFlags &= ~kProcessorFast;	// Remember slow so we can set it after sleep
			}

		// on machines that use the processor based speed change, once we start the sleep process, we don't want to change the 
		// speed again until we wake. setting this true causes us to ignore all speed change requests.
		if(macRISC2PE->processorSpeedChangeFlags & kProcessorBasedSpeedChange)
		{	
			//IOLog("*** setting ignoreSpeedChange = true\n");
			ignoreSpeedChange = true;
		}
			
   } else {
        // Wake sequence:

		// on machines that use the processor based speed change, now that we're awake, we can again start accepting speed change requests.
		if(macRISC2PE->processorSpeedChangeFlags & kProcessorBasedSpeedChange)
		{	
			//IOLog("*** setting ignoreSpeedChange = false\n");
			ignoreSpeedChange = false;
		}

        kprintf("MacRISC2CPU %ld powerStateWillChangeTo to acknowledge power changes (UP) we set napping %d\n", getCPUNumber(), rememberNap);
        ml_enable_nap(getCPUNumber(), rememberNap); 		   // Re-set the nap as it was before.
		
		// If we have an ioPMon, it will handle this
		if (!ioPMon && (macRISC2PE->processorSpeedChangeFlags & kEnvironmentalSpeedChange)) {
			// Coming out of sleep we will be slow, so go to fast if necessary
			if (macRISC2PE->processorSpeedChangeFlags & kProcessorFast) {
				macRISC2PE->processorSpeedChangeFlags &= ~kProcessorFast;	// Clear fast flag so we know to speed up
				setAggressiveness (kPMSetProcessorSpeed, 0);				// Make it so
			} else
				doSleep = true;		// force delay on next call
		}
		
		// If processor based and flag indicates slow, we boosted it before going to sleep,
		// 		so set it back to slow
		if (macRISC2PE->processorSpeedChangeFlags & kProcessorBasedSpeedChange &&
			!(macRISC2PE->processorSpeedChangeFlags & kProcessorFast)) {
				macRISC2PE->processorSpeedChangeFlags |= kProcessorFast;	// Set fast so we know to go slow
 				setAggressiveness (kPMSetProcessorSpeed, 1);				// Make it so
			}

	}
	
    return IOPMAckImplied;
}
void IOEthernetInterface::reportInterfaceWakeFlags( IONetworkController * ctr )
{
    ifnet_t                 ifnet;
    OSNumber *              number;
    unsigned long           wakeSetting = 0;
    uint32_t                disabled    = 0;
    uint32_t                filters     = 0;
    uint32_t                linkStatus  = 0;

    ifnet = getIfnet();

    if (!ifnet || !ctr)
        return;

    // Across system sleep/wake, link down is expected, this should
    // not trigger a wake flags changed.

    if (_controllerLostPower)
    {
        DLOG("en%u: controllerLostPower\n", getUnitNumber());
        return;
    }

    do {
        // Report negative if controller is disabled or does not support WOL.

        if (!_ctrEnabled ||
            ((_supportedWakeFilters & kIOEthernetWakeOnMagicPacket) == 0))
        {
            DLOG("en%u: ctrEnabled = %x, WakeFilters = %x\n",
                getUnitNumber(), _ctrEnabled, _supportedWakeFilters);
            break;
        }

        // Poll for disabled WOL filters, which is allowed to change
        // after every link and WOL changed event.

        if (_disabledWakeFilters)
        {
            if ( ctr->getPacketFilters(
                    gIOEthernetDisabledWakeOnLANFilterGroup,
                    (UInt32 *) &disabled ) != kIOReturnSuccess )
            {
                disabled = 0;
            }
            _disabledWakeFilters->setValue( disabled );
        }

        // Check if network wake option is enabled,
        // that also implies system is on AC power.

        getAggressiveness(kPMEthernetWakeOnLANSettings, &wakeSetting);
        filters = wakeSetting & _supportedWakeFilters & ~disabled;
        DLOG("en%u: WakeSetting = %lx, WakeFilters = %x, disabled = %x\n",
            getUnitNumber(), wakeSetting, _supportedWakeFilters, disabled);
        
        if ((kIOEthernetWakeOnMagicPacket & filters) == 0)
            break;

        // Check driver is reporting valid link.

        number = OSDynamicCast(OSNumber, ctr->getProperty(kIOLinkStatus));
        if (!number)
        {
            filters = 0;
            break;
        }

        linkStatus = number->unsigned32BitValue();
        if ((linkStatus & (kIONetworkLinkValid | kIONetworkLinkActive)) ==
            kIONetworkLinkValid)
        {
            filters = 0;
        }
    }
    while (false);

    filters &= IFNET_WAKE_ON_MAGIC_PACKET;
    if (filters != (ifnet_get_wake_flags(ifnet) & IFNET_WAKE_ON_MAGIC_PACKET))
    {
        ifnet_set_wake_flags(ifnet, filters, IFNET_WAKE_ON_MAGIC_PACKET);
        DLOG("en%u: ifnet_set_wake_flags = %x\n", getUnitNumber(), filters);

        // Lazy create of kernel assertion
        if (kIOPMUndefinedDriverAssertionID == _wompEnabledAssertionID)
        {
            _wompEnabledAssertionID = getPMRootDomain()->createPMAssertion(
                kIOPMDriverAssertionMagicPacketWakeEnabledBit,
                (filters & IFNET_WAKE_ON_MAGIC_PACKET) ?
                    kIOPMDriverAssertionLevelOn : kIOPMDriverAssertionLevelOff,
                this, getName());
        }
        else
        {
            getPMRootDomain()->setPMAssertionLevel(_wompEnabledAssertionID,
                (filters & IFNET_WAKE_ON_MAGIC_PACKET) ?
                    kIOPMDriverAssertionLevelOn : kIOPMDriverAssertionLevelOff);
        }
    }
}
bool ApplePS2Keyboard::dispatchKeyboardEventWithScancode(UInt8 scanCode)
{
    // Parses the given scan code, updating all necessary internal state, and
    // should a new key be detected, the key event is dispatched.
    //
    // Returns true if a key event was indeed dispatched.

    DEBUG_LOG("%s: PS/2 scancode 0x%x\n", getName(), scanCode);

    //
    // See if this scan code introduces an extended key sequence.  If so, note
    // it and then return.  Next time we get a key we'll finish the sequence.
    //

    if (scanCode == kSC_Extend)
    {
        _extendCount = 1;
        return false;
    }

    //
    // See if this scan code introduces an extended key sequence for the Pause
    // Key.  If so, note it and then return.  The next time we get a key, drop
    // it.  The next key we get after that finishes the Pause Key sequence.
    //
    // The sequence actually sent to us by the keyboard for the Pause Key is:
    //
    // 1. E1  Extended Sequence for Pause Key
    // 2. 1D  Useless Data, with Up Bit Cleared
    // 3. 45  Pause Key, with Up Bit Cleared
    // 4. E1  Extended Sequence for Pause Key
    // 5. 9D  Useless Data, with Up Bit Set
    // 6. C5  Pause Key, with Up Bit Set
    //
    // The reason items 4 through 6 are sent with the Pause Key is because the
    // keyboard hardware never generates a release code for the Pause Key and
    // the designers are being smart about it.  The sequence above translates
    // to this parser as two separate events, as it should be -- one down key
    // event and one up key event (for the Pause Key).
    //
    if (scanCode == kSC_Pause)
    {
        _extendCount = 2;
        return false;
    }

    unsigned keyCodeRaw = scanCode & ~kSC_UpBit;
    unsigned keyCode;
    uint64_t now;
    clock_get_uptime(&now);

    //
    // Convert the scan code into a key code index.
    //
    // From "The Undocumented PC" chapter 8, The Keyboard System some
    // keyboard scan codes are single byte, some are multi-byte.
    // Scancodes from running showkey -s (under Linux) for extra keys on keyboard
    // Refer to the conversion table in defaultKeymapOfLength 
    // and the conversion table in ApplePS2ToADBMap.h.
    //
    if (_extendCount == 0)
    {
        // LANG1(Hangul) and LANG2(Hanja) make one event only when the key was pressed.
        // Make key-down and key-up event ADB event
        if (scanCode == 0xf2 || scanCode == 0xf1)
        {
            clock_get_uptime(&now);
            dispatchKeyboardEvent( PS2ToADBMap[scanCode], true, *((AbsoluteTime*)&now) );
            clock_get_uptime(&now);
            dispatchKeyboardEvent( PS2ToADBMap[scanCode], false, *((AbsoluteTime*)&now) );
            return true;
        }
        
        // Allow PS2 -> PS2 map to work, look in normal part of the table
        keyCode = _PS2ToPS2Map[keyCodeRaw];
        
#ifdef DEBUG_MSG
        if (keyCode != keyCodeRaw)
            DEBUG_LOG("%s: keycode translated from=0x%02x to=0x%04x\n", getName(), keyCodeRaw, keyCode);
#endif
    }
    else
    {
        // ignore incoming scan codes until extend count is zero
        if (--_extendCount)
            return false;
        
        // allow PS2 -> PS2 map to work, look in extended part of the table
        keyCodeRaw += KBV_NUM_SCANCODES;
        keyCode = _PS2ToPS2Map[keyCodeRaw];
#ifdef DEBUG_MSG
        if (keyCode != keyCodeRaw)
            DEBUG_LOG("%s: keycode translated from=0xe0%02x to=0x%04x\n", getName(), keyCodeRaw, keyCode);
#endif
        // handle special cases
        switch (keyCodeRaw)
        {
            case 0x012a: // header or trailer for PrintScreen
                return false;
        }
    }

    // handle special cases
    switch (keyCode)
    {
        case 0x0153:    // delete
            // check for Ctrl+Alt+Delete? (three finger salute)
            if (KBV_IS_KEYDOWN(0x1d, _keyBitVector) && KBV_IS_KEYDOWN(0x38, _keyBitVector))
            {
                keyCode = 0;
                if (scanCode & kSC_UpBit)
                {
                    // Note: If OS X thinks the Command and Control keys are down at the time of
                    //  receiving an ADB 0x7f (power button), it will unconditionaly and unsafely
                    //  reboot the computer, much like the old PC/AT Ctrl+Alt+Delete!
                    // That's why we make sure Control (0x3b) and Alt (0x37) are up!!
                    dispatchKeyboardEvent(0x37, false, now);
                    dispatchKeyboardEvent(0x3b, false, now);
                    dispatchKeyboardEvent(0x7f, true, now);
                    dispatchKeyboardEvent(0x7f, false, now);
                }
            }
            break;
                
        case 0x015f:    // sleep
            // This code relies on the keyboard sending repeats...  If not, it won't
            // invoke sleep until after time has expired and we get the keyup!
            keyCode = 0;
            if (!KBV_IS_KEYDOWN(keyCodeRaw, _keyBitVector))
                sleeppressedtime = now;
            if (now-sleeppressedtime >= maxsleeppresstime)
            {
                IOPMrootDomain* rootDomain = getPMRootDomain();
                if (NULL != rootDomain)
                    rootDomain->receivePowerNotification(kIOPMSleepNow);
            }
            break;
            
        case 0x0137:    // trackpad on/off
            keyCode = 0;
            if (!(scanCode & kSC_UpBit))
            {
                // get current enabled status, and toggle it
                bool enabled;
                _device->dispatchMouseMessage(kPS2M_getDisableTouchpad, &enabled);
                enabled = !enabled;
                _device->dispatchMouseMessage(kPS2M_setDisableTouchpad, &enabled);
            }
            break;
    }
        
    // Update our key bit vector, which maintains the up/down status of all keys.
    bool goingDown = !(scanCode & kSC_UpBit);
    if (goingDown)
    {
        // discard if auto-repeated key
        if (KBV_IS_KEYDOWN(keyCodeRaw, _keyBitVector))
            return false;

        KBV_KEYDOWN(keyCodeRaw, _keyBitVector);
    }
    else
    {
        KBV_KEYUP(keyCodeRaw, _keyBitVector);
    }

#ifdef DEBUG
    // allow hold Alt+numpad keys to type in arbitrary ADB key code
    static int genADB = -1;
    if (KBV_IS_KEYDOWN(0x38, _keyBitVector) && keyCodeRaw >= 0x47 && keyCodeRaw <= 0x52)
    {
        if (!KBV_IS_KEYDOWN(keyCodeRaw, _keyBitVector))
        {
            // map numpad scan codes to digits
            static int map[0x52-0x47+1] = { 7, 8, 9, -1, 4, 5, 6, -1, 1, 2, 3, 0 };
            if (-1 == genADB)
                genADB = 0;
            int digit = map[keyCodeRaw-0x47];
            if (-1 != digit)
                genADB = genADB * 10 + digit;
            DEBUG_LOG("%s: genADB = %d\n", getName(), genADB);
        }
        keyCode = 0;    // eat it
    }
#endif
    
    // We have a valid key event -- dispatch it to our superclass.
    
    // map scan code to Apple code
    UInt8 adbKeyCode = _PS2ToADBMap[keyCode];
    
#ifdef DEBUG_MSG
    if (adbKeyCode == DEADKEY && 0 != keyCode)
        IOLog("%s: Unknown ADB key for PS2 scancode: 0x%x\n", getName(), scanCode);
    else
        IOLog("%s: ADB key code 0x%x %s\n", getName(), adbKeyCode, goingDown?"down":"up");
#endif
    
    // allow mouse/trackpad driver to have time of last keyboard activity
    // used to implement "PalmNoAction When Typing" and "OutsizeZoneNoAction When Typing"
    PS2KeyInfo info;
    info.time = now;
    info.adbKeyCode = adbKeyCode;
    info.goingDown = goingDown;
    _device->dispatchMouseMessage(kPS2M_notifyKeyPressed, &info);

    // dispatch to HID system
    dispatchKeyboardEvent(adbKeyCode, goingDown, now);
    
#ifdef DEBUG
    if (0x38 == keyCode && !goingDown && -1 != genADB) // Alt going up
    {
        // dispatch typed adb code
        dispatchKeyboardEvent(genADB, true, now);
        dispatchKeyboardEvent(genADB, false, now);
        DEBUG_LOG("%s: sending typed ADB code 0x%x\n", getName(), genADB);
        genADB = -1;
    }
#endif

    return true;
}