1/*
2 * @APPLE_LICENSE_HEADER_START@
3 *
4 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#include <IOKit/assert.h>
24#include <IOKit/IOMessage.h>
25#include <IOKit/IOLib.h>
26#include "IOBSDConsole.h"
27#include <IOKit/hidsystem/IOHIKeyboard.h>
28#include <IOKit/hidsystem/IOLLEvent.h>
29
30#define super IOService
31OSDefineMetaClassAndStructors(IOBSDConsole, IOService);
32
33// remove
34bool (*playBeep)(IOService *outputStream) = 0;
35
36//************************************************************************
37
38bool IOBSDConsole::start(IOService * provider)
39{
40    OSObject *	notify;
41
42    if (!super::start(provider))  return false;
43
44    notify = addNotification( gIOPublishNotification,
45        serviceMatching("IOHIKeyboard"),
46        (IOServiceNotificationHandler) &IOBSDConsole::publishNotificationHandler,
47        this, 0 );
48    assert( notify );
49
50    notify = addNotification( gIOPublishNotification,
51        serviceMatching("IODisplayWrangler"),
52        (IOServiceNotificationHandler) &IOBSDConsole::publishNotificationHandler,
53         this, 0 );
54    assert( notify );
55
56    notify = addNotification( gIOPublishNotification,
57        serviceMatching("IOAudioStream"),
58        (IOServiceNotificationHandler) &IOBSDConsole::publishNotificationHandler,
59        this, this );
60    assert( notify );
61
62    return( true );
63}
64
65bool IOBSDConsole::publishNotificationHandler(
66			    IOBSDConsole * self,
67                            void * ref,
68                            IOService * newService )
69
70{
71    IOHIKeyboard *	keyboard = 0;
72    IOService *		audio = 0;
73
74    if( ref) {
75        audio = OSDynamicCast(IOService, newService->metaCast("IOAudioStream"));
76        if (audio != 0) {
77            OSNumber *out = newService->copyProperty("Out");
78            if (OSDynamicCast(OSNumber, out)) {
79                if (out->unsigned8BitValue() == 1) {
80                    self->fAudioOut = newService;
81                }
82            }
83            OSSafeReleaseNULL(out);
84        }
85    } else {
86	audio = 0;
87        keyboard = OSDynamicCast( IOHIKeyboard, newService );
88
89        if( keyboard && self->attach( keyboard )) {
90            self->arbitrateForKeyboard( keyboard );
91        }
92
93        if( newService->metaCast("IODisplayWrangler"))
94            self->displayManager = newService;
95    }
96
97    return true;
98}
99
100//************************************************************************
101// Keyboard client stuff
102//************************************************************************
103
104void IOBSDConsole::arbitrateForKeyboard( IOHIKeyboard * nub )
105{
106  nub->open(this, 0, 0,
107	(KeyboardEventCallback)keyboardEvent,
108        (KeyboardSpecialEventCallback) 0,
109        (UpdateEventFlagsCallback)updateEventFlags);
110  // failure can be expected if the HID system already has it
111}
112
113IOReturn IOBSDConsole::message(UInt32 type, IOService * provider,
114				void * argument)
115{
116  IOReturn     status = kIOReturnSuccess;
117
118  switch (type)
119  {
120    case kIOMessageServiceIsTerminated:
121    case kIOMessageServiceIsRequestingClose:
122      provider->close( this );
123      break;
124
125    case kIOMessageServiceWasClosed:
126      arbitrateForKeyboard( (IOHIKeyboard *) provider );
127      break;
128
129    default:
130      status = super::message(type, provider, argument);
131      break;
132  }
133
134  return status;
135}
136
137extern "C" {
138  void cons_cinput( char c);
139}
140//#warning REMOVE cons_cinput DECLARATION FROM HERE
141
142void IOBSDConsole::keyboardEvent(OSObject * target,
143          /* eventType */        unsigned   eventType,
144          /* flags */            unsigned   flags,
145          /* keyCode */          unsigned   /* key */,
146          /* charCode */         unsigned   charCode,
147          /* charSet */          unsigned   charSet,
148          /* originalCharCode */ unsigned   /* origCharCode */,
149          /* originalCharSet */  unsigned   /* origCharSet */,
150          /* keyboardType */ 	 unsigned   /* keyboardType */,
151          /* repeat */           bool       /* repeat */,
152          /* atTime */           AbsoluteTime /* ts */,
153                                 OSObject * sender,
154                                 void *     refcon)
155{
156    static const char cursorCodes[] = { 'D', 'A', 'C', 'B' };
157
158    if ( ((IOBSDConsole *)target)->displayManager != NULL ) {
159        // if there is a display manager, tell it there is user activity
160        ((IOBSDConsole *)target)->displayManager->activityTickle(kIOPMSuperclassPolicy1);
161    }
162
163    if( (eventType == NX_KEYDOWN) && ((flags & NX_ALTERNATEMASK) != NX_ALTERNATEMASK)) {
164        if( (charSet == NX_SYMBOLSET)
165            && (charCode >= 0xac) && (charCode <= 0xaf)) {
166            cons_cinput( '\033');
167            cons_cinput( 'O');
168            charCode = cursorCodes[ charCode - 0xac ];
169        }
170        cons_cinput( charCode);
171    }
172}
173
174void IOBSDConsole::updateEventFlags(OSObject * /*target*/,
175                                    unsigned /*flags*/,
176                                    OSObject * /*sender*/,
177                                    void *     /*refcon*/)
178{
179  return;
180}
181
182
183