/* 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; }
/* 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 } } } }
/* 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; }
// 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; }