//====================================================================================================
// IOHIDEventOverrideDriver::dispatchKeyboardEvent
//====================================================================================================
void IOHIDEventOverrideDriver::dispatchEvent(IOHIDEvent * event, IOOptionBits options)
{
    IOHIDEvent * targetEvent = NULL;
    if ( (targetEvent = event->getEvent(kIOHIDEventTypePointer)) ) {
        AbsoluteTime    timestamp               = targetEvent->getTimeStamp();
        uint32_t        pointerButtonMaskNew    = targetEvent->getIntegerValue(kIOHIDEventFieldPointerButtonMask);
        uint32_t        pointerButtonMaskDelta  = _pointerButtonMask ^ pointerButtonMaskNew;
        int             index;
        
        for ( index=0; index<32; index++ ) {
            bool value;
            if ( (pointerButtonMaskDelta & (1<<index)) == 0 )
                continue;
            
            switch (_buttonMap[index].eventType ) {
                case kIOHIDEventTypeKeyboard:
                    value = pointerButtonMaskNew & (1<<index);
                    dispatchKeyboardEvent(timestamp, _buttonMap[index].usagePage, _buttonMap[index].usage, value);
                    break;
                default:
                    break;
            }
        }
        
        _pointerButtonMask = pointerButtonMaskNew;
    } else {
        super::dispatchEvent(event, options);
    }
}
Beispiel #2
0
bool NewEventHandler::handleKeyboardEvent(const WebKeyboardEvent& event)
{
    bool shouldSuppressCharEvent = m_suppressNextCharEvent;
    m_suppressNextCharEvent = false;

    if (event.type == WebInputEvent::Char) {
        if (shouldSuppressCharEvent)
            return true;
        // Do we really need to suppress keypress events for these keys anymore?
        if (event.key == VKEY_BACK
            || event.key == VKEY_ESCAPE)
            return true;
    }

    RefPtr<Node> target = targetForKeyboardEvent();
    bool handled = target && !dispatchKeyboardEvent(*target, event);

    // If the keydown event was handled, we don't want to "generate" a keypress
    // event for that keystroke. However, we'll receive a Char event from the
    // embedder regardless, so we set m_suppressNextCharEvent, will will prevent
    // us from dispatching the keypress event when we receive that Char event.
    if (handled && event.type == WebInputEvent::KeyDown)
        m_suppressNextCharEvent = true;

    return handled;
}
Beispiel #3
0
static void * getKeyboardCharThread(void *arg)
{
    printf("This virtual keyboard supports dispatching typed characters within the range of 'a' - 'z'\n");
    
    while (1) {
        dispatchKeyboardEvent(getchar());
    }
    return arg;
}
void IOHIKeyboard::close(IOService * client, IOOptionBits)
{
    // kill autorepeat task
    // do this before we issue keyup for any other keys 
    // that are down.
    AbsoluteTime ts;
    clock_get_uptime(&ts);
    if (_codeToRepeat != ((unsigned)-1))
        dispatchKeyboardEvent(_codeToRepeat, false, ts);
    
    // now get rid of any other keys that might be down
    UInt32 i, maxKeys = maxKeyCodes();
    for (i=0; i<maxKeys; i++)
        if ( EVK_IS_KEYDOWN(i,_keyState) )
            dispatchKeyboardEvent(i, false, ts);

    // continue to issue zero'ed out flags changed events
    // just in case any of the flag bits were manually set
    _updateEventFlags(this, 0);

    _keyboardSpecialEvent(  this, 
                            NX_SYSDEFINED, 
                            0, 
                            NX_NOSPECIALKEY, 
                            NX_SUBTYPE_STICKYKEYS_RELEASE, 
                            _guid, 
                            0, 
                            _lastEventTime);

    bzero(_keyState, _keyStateSize);

    _keyboardEventAction        = NULL;
    _keyboardEventTarget        = 0;
    _keyboardSpecialEventAction = NULL;
    _keyboardSpecialEventTarget = 0;
    _updateEventFlagsAction     = NULL;
    _updateEventFlagsTarget     = 0;
    
    super::close(client);
}
Beispiel #5
0
/*
 * Receive hotkey event (only down) and send keyboard down and up event
 * Limits the rate of event send to HID stack, otherwise the system slow down and the sound/sun bezel lags.
 */
IOReturn WMIHIKeyboard::message( UInt32 type, IOService * provider, void * argument)
{
	if (type == kIOACPIMessageDeviceNotification)
	{
		clock_sec_t  secs, deltaSecs;
		clock_usec_t microsecs, deltaMicrosecs;
		clock_get_system_microtime(&secs,&microsecs);
		deltaSecs = secs - lastEventSecs;
		
		if (deltaSecs < 2)
		{
			deltaMicrosecs = microsecs + (1000000 * deltaSecs) - lastEventMicrosecs;
			if (deltaMicrosecs < 125000) // rate limiter to 125 ms
				return kIOReturnSuccess;
		}
		lastEventSecs =		 secs;
		lastEventMicrosecs = microsecs;
		
		{
			UInt32 code = *((UInt32 *) argument);
			
			AbsoluteTime now;
            uint64_t* pnow = reinterpret_cast<uint64_t*>(&now);
			clock_get_uptime(pnow);
			dispatchKeyboardEvent( code,
								  /*direction*/ true,
								  /*timeStamp*/ now );
			
			clock_get_uptime(pnow);
			dispatchKeyboardEvent( code,
								  /*direction*/ false,
								  /*timeStamp*/ now );
		}
	}
	return kIOReturnSuccess;
}
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;
}
void ApplePS2Keyboard::receiveMouseTouchpadNotifications(UInt32 data)
{
    AbsoluteTime now;
    
    clock_get_uptime((uint64_t *)&now);
    
    switch (data) {
        
        
        case kPS2C_SwipeLeft:// cmd + [
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 33,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 33,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case kPS2C_SwipeRight://cmd + ]
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 30,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 30,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case kPS2C_ZoomPlus://cmd + +
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 69,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 69,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case kPS2C_ZoomMinus://cmd + -
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 78,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 78,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case kPS2C_SwipeDown://cmd + tab
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 48,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 48,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case  kPS2C_SwipeUp://Launchpad
            dispatchKeyboardEvent( 131,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 131,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case kPS2C_RotateLeft://cmd + L
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 37,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            //clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 37,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            //clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );

            break;
        case kPS2C_RotateRight://cmd + R
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 15,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            // clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 15,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            //clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );

            break;
            case kPS2C_TwoFingersPress://cmd + 0
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 29,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 29,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
            case kPS2C_ReleaseKey://Just to release cmd after sleep and after swipe down
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            
            break;
          
        //If Command Key was modified at Modifier keys of Keyboard pane then we set command key
        case kCommandKeyPos_0:
            _commandKey = 55;
            break;
        case kCommandKeyPos_1:
            _commandKey = 58;
            break;
        case kCommandKeyPos_2:
            _commandKey = 59;
            break;
        case kCommandKeyPos_3:
            _commandKey = 57;
            break;
            
        //Three Finger Swipe Action Options
        case kPS2C_SwipeAction_1://Switch Applications Switch Tab + cmd
            dispatchKeyboardEvent( _commandKey,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 48,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 48,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
        case kPS2C_SwipeAction_2://Launchpad
            dispatchKeyboardEvent( 131,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 131,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );

            break;
        case kPS2C_SwipeAction_3://Dashboard & Switching Desktop Left Cntrl + Arrow
            dispatchKeyboardEvent( 59,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 123,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 123,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 59,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            break;
            
        case kPS2C_SwipeAction_4://Switching Desktop Left Cntrl + Right Arrow
            dispatchKeyboardEvent( 59,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 124,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 124,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 59,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );

            break;
            

        case kPS2C_SwipeAction_5://Show Application Windows Control + Down Arrow
            dispatchKeyboardEvent( 59,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 125,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 125,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 59,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            

            break;
        case kPS2C_SwipeAction_6://Mission Control
            dispatchKeyboardEvent( 160,
                                  /*direction*/ true,
                                  /*timeStamp*/ now );
            
            clock_get_uptime((uint64_t *)&now);
            dispatchKeyboardEvent( 160,
                                  /*direction*/ false,
                                  /*timeStamp*/ now );
            

            break;
            
            //For Future
        case kPS2C_SwipeAction_7:
            break;
        case kPS2C_SwipeAction_8:
            break;
        case kPS2C_SwipeAction_9:
            break;
        case kPS2C_SwipeAction_10:
            break;
            
        case kPS2C_NumLock:
            //Invoking Num Lock LED
            setNumLockFeedback(_numKeypadLocked);
            _numKeypadLocked = !_numKeypadLocked;
            break;
            
        default:
            break;
    }

    
    return;
}
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;
}
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;
}