void ApplePS2Keyboard::setDevicePowerState( UInt32 whatToDo )
{
  switch ( whatToDo )
  {
    case kPS2C_DisableDevice:

      //
      // Disable keyboard.
      //

      setKeyboardEnable( false );

      break;

    case kPS2C_EnableDevice:

          //
          // Reset the keyboard to its default state.
          //
          
          PS2Request * request = _device->allocateRequest();
          if (request)
          {
              request->commands[0].command = kPS2C_WriteDataPort;
              request->commands[0].inOrOut = kDP_SetDefaults;
              request->commands[1].command = kPS2C_ReadDataPortAndCompare;
              request->commands[1].inOrOut = kSC_Acknowledge;
              request->commandsCount = 2;
              _device->submitRequestAndBlock(request);
              _device->freeRequest(request);
          }

      
      //
      // Initialize the keyboard LED state.
      //

      setLEDs(_ledState);

      //
      // Enable the keyboard clock (should already be so), the keyboard
      // IRQ line, and the keyboard Kscan -> scan code translation mode.
      //

      setCommandByte( kCB_EnableKeyboardIRQ | kCB_TranslateMode,
                      kCB_DisableKeyboardClock );

      //
      // Finally, we enable the keyboard itself, so that it may start
      // reporting key events.
      //

      setKeyboardEnable( true );

      break;
  }
}
void ApplePS2Keyboard::setDevicePowerState( UInt32 whatToDo )
{
  switch ( whatToDo )
  {
    case kPS2C_DisableDevice:

      //
      // Disable keyboard.
      //

      setKeyboardEnable( false );

      break;

    case kPS2C_EnableDevice:

      //
      // Initialize the keyboard LED state.
      //

      setLEDs(_ledState);

      //
      // Enable the keyboard clock (should already be so), the keyboard
      // IRQ line, and the keyboard Kscan -> scan code translation mode.
      //

      setCommandByte( kCB_EnableKeyboardIRQ | kCB_TranslateMode,
                      kCB_DisableKeyboardClock );

      //
      // Finally, we enable the keyboard itself, so that it may start
      // reporting key events.
      //

      setKeyboardEnable( true );

      break;
  }
}
void ApplePS2Keyboard::stop(IOService * provider)
{
  //
  // The driver has been instructed to stop.  Note that we must break all
  // connections to other service objects now (ie. no registered actions,
  // no pointers and retains to objects, etc), if any.
  //

  assert(_device == provider);

  //
  // Disable the keyboard itself, so that it may stop reporting key events.
  //

  setKeyboardEnable(false);

  //
  // Disable the keyboard clock and the keyboard IRQ line.
  //

  setCommandByte(kCB_DisableKeyboardClock, kCB_EnableKeyboardIRQ);

  //
  // Uninstall the interrupt handler.
  //

  if ( _interruptHandlerInstalled )  _device->uninstallInterruptAction();
  _interruptHandlerInstalled = false;

  //
  // Uninstall the power control handler.
  //

  if ( _powerControlHandlerInstalled ) _device->uninstallPowerControlAction();
  _powerControlHandlerInstalled = false;

  //
  // Release the pointer to the provider object.
  //

  //
  // Unistalling our Mouse/Touchpad Notification Handler
  //
    _device->unistallPS2NotificationAction();
    _mouseTouchpadNotificationHandlerInstalled = false;
    
  _device->release();
  _device = 0;

  super::stop(provider);
}
void ApplePS2Keyboard::initKeyboard()
{
    //
    // Reset the keyboard to its default state.
    //

    PS2Request * request = _device->allocateRequest();
    if (request)
    {
        request->commands[0].command = kPS2C_WriteDataPort;
        request->commands[0].inOrOut = kDP_SetDefaults;
        request->commands[1].command = kPS2C_ReadDataPortAndCompare;
        request->commands[1].inOrOut = kSC_Acknowledge;
        request->commandsCount = 2;
        _device->submitRequestAndBlock(request);
        _device->freeRequest(request);
    }
    
    // start out with all keys up
    bzero(_keyBitVector, sizeof(_keyBitVector));
    
    //
    // Initialize the keyboard LED state.
    //

    setLEDs(_ledState);

    //
    // Enable the keyboard clock (should already be so), the keyboard IRQ line,
    // and the keyboard Kscan -> scan code translation mode.
    //

    setCommandByte(kCB_EnableKeyboardIRQ | kCB_TranslateMode,
            kCB_DisableKeyboardClock);

    //
    // Finally, we enable the keyboard itself, so that it may start reporting
    // key events.
    //
    
    setKeyboardEnable(true);
}
void ApplePS2Keyboard::setDevicePowerState( UInt32 whatToDo )
{
    switch ( whatToDo )
    {
        case kPS2C_DisableDevice:

            //
            // Disable keyboard.
            //
            setKeyboardEnable( false );

            // Work around for auto repeat keyboard sometimes after
            //  wakeup from sleep
            // see: http://www.mydellmini.com/forum/general-mac-os-x-discussion/3553-fixed-zero-key-stack-after-wake-up.html
            // remove interrupt handler
            setCommandByte(kCB_DisableKeyboardClock, kCB_EnableKeyboardIRQ);
            if (_interruptHandlerInstalled)
            {
                _device->uninstallInterruptAction();
                _interruptHandlerInstalled = false;
            }
            break;

        case kPS2C_EnableDevice:
            // re-install interrupt handler
            _device->installInterruptAction(this,
                /*(PS2InterruptAction)&ApplePS2Keyboard::interruptOccurred*/
                OSMemberFunctionCast(PS2InterruptAction, this, &ApplePS2Keyboard::interruptOccurred));
            _interruptHandlerInstalled = true;

            //
            // Enable keyboard and restore state.
            //
            initKeyboard();
            break;
    }
}
bool ApplePS2Keyboard::start(IOService * provider)
{
keyi=false;

  //
  // The driver has been instructed to start.   This is called after a
  // successful attach.
  //
  if (!super::start(provider))  return false;

  //
  // Maintain a pointer to and retain the provider object.
  //
  _device = (ApplePS2KeyboardDevice *)provider;
  _device->retain();


  if (kOSBooleanTrue == getProperty("Make capslock into control")) {
    emacsMode = true;
  } else {
    emacsMode = false;
  }
  if (kOSBooleanTrue == getProperty("Swap alt and windows key")) {
    macintoshMode = true;
  } else {
    macintoshMode = false;
  }
  //
  // Install our driver's interrupt handler, for asynchronous data delivery.
  //

  _device->installInterruptAction(this,
            /*(PS2InterruptAction)&ApplePS2Keyboard::interruptOccurred*/
			OSMemberFunctionCast(PS2InterruptAction, this, &ApplePS2Keyboard::interruptOccurred));
  _interruptHandlerInstalled = true;

  //
  // Initialize the keyboard LED state.
  //

  setLEDs(_ledState);

  //
  // Enable the keyboard clock (should already be so), the keyboard IRQ line,
  // and the keyboard Kscan -> scan code translation mode.
  //

  setCommandByte(kCB_EnableKeyboardIRQ | kCB_TranslateMode,
                 kCB_DisableKeyboardClock);

  //
  // Finally, we enable the keyboard itself, so that it may start reporting
  // key events.
  //

  setKeyboardEnable(true);

  //
  // Install our power control handler.
  //

  _device->installPowerControlAction( this,
           /*(PS2PowerControlAction) &ApplePS2Keyboard::setDevicePowerState*/
		   OSMemberFunctionCast(PS2PowerControlAction, this, &ApplePS2Keyboard::setDevicePowerState) );
  _powerControlHandlerInstalled = true;

  return true;
}