#include <IOKit/assert.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOLib.h>
#include "IOBSDConsole.h"
#include <IOKit/hidsystem/IOHIKeyboard.h>
#include <IOKit/hidsystem/IOLLEvent.h>
static IOBSDConsole * gBSDConsoleInst = 0;
bool displayWranglerPublished( OSObject *, void *, IOService * );
#define super IOService
OSDefineMetaClassAndStructors(IOBSDConsole, IOService);
bool IOBSDConsole::start(IOService * provider)
{
OSObject * notify;
if (!super::start(provider)) return false;
assert( gBSDConsoleInst == 0 );
gBSDConsoleInst = this;
notify = addNotification( gIOPublishNotification,
serviceMatching("IOHIKeyboard"),
(IOServiceNotificationHandler) &IOBSDConsole::publishNotificationHandler,
this, 0 );
assert( notify );
notify = addNotification( gIOPublishNotification,
serviceMatching("IODisplayWrangler"),
(IOServiceNotificationHandler)displayWranglerPublished,
this, 0 );
assert( notify );
notify = addNotification( gIOPublishNotification,
serviceMatching("IOAudioStream"),
(IOServiceNotificationHandler) &IOBSDConsole::publishNotificationHandler,
this, this );
assert( notify );
return( true );
}
bool IOBSDConsole::publishNotificationHandler(
IOBSDConsole * self,
void * ref,
IOService * newService )
{
IOHIKeyboard * keyboard = 0;
IOService * audio = 0;
if( ref) {
audio = OSDynamicCast(IOService, newService->metaCast("IOAudioStream"));
if (audio != 0) {
OSNumber *out;
out = OSDynamicCast(OSNumber, newService->getProperty("Out"));
if (out) {
if (out->unsigned8BitValue() == 1) {
self->fAudioOut = newService;
}
}
}
} else {
audio = 0;
keyboard = OSDynamicCast( IOHIKeyboard, newService );
if( keyboard && self->attach( keyboard )) {
self->arbitrateForKeyboard( keyboard );
}
}
if( !keyboard && !audio)
IOLog("%s: strange service notify \"%s\"\n",
self->getName(), newService->getName());
return true;
}
bool displayWranglerPublished( OSObject * us, void * ref, IOService * yourDevice )
{
if ( yourDevice != NULL ) {
((IOBSDConsole *)us)->displayManager = yourDevice;
}
return true;
}
void IOBSDConsole::arbitrateForKeyboard( IOHIKeyboard * nub )
{
nub->open(this, 0,
keyboardEvent, 0, updateEventFlags);
}
IOReturn IOBSDConsole::message(UInt32 type, IOService * provider,
void * argument)
{
IOReturn status = kIOReturnSuccess;
switch (type)
{
case kIOMessageServiceIsTerminated:
case kIOMessageServiceIsRequestingClose:
provider->close( this );
break;
case kIOMessageServiceWasClosed:
arbitrateForKeyboard( (IOHIKeyboard *) provider );
break;
default:
status = super::message(type, provider, argument);
break;
}
return status;
}
extern "C" {
void cons_cinput( char c);
}
#warning REMOVE cons_cinput DECLARATION FROM HERE
void IOBSDConsole::keyboardEvent(OSObject * target,
unsigned eventType,
unsigned ,
unsigned ,
unsigned charCode,
unsigned charSet,
unsigned ,
unsigned ,
unsigned ,
bool ,
AbsoluteTime )
{
static const char cursorCodes[] = { 'D', 'A', 'C', 'B' };
if ( ((IOBSDConsole *)target)->displayManager != NULL ) { ((IOBSDConsole *)target)->displayManager->activityTickle(kIOPMSuperclassPolicy1); }
if( eventType == NX_KEYDOWN) {
if( (charSet == NX_SYMBOLSET)
&& (charCode >= 0xac) && (charCode <= 0xaf)) {
cons_cinput( '\033');
cons_cinput( 'O');
charCode = cursorCodes[ charCode - 0xac ];
}
cons_cinput( charCode);
}
}
void IOBSDConsole::updateEventFlags(OSObject * , unsigned )
{
return;
}
extern "C" {
int asc_ringbell();
}
bool (*playBeep)(IOService *outputStream) = 0;
int asc_ringbell()
{
IOService *output;
if (gBSDConsoleInst && playBeep && (output = gBSDConsoleInst->getAudioOut())) {
playBeep(output);
}
return true;
}