]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/hidsystem/drvAppleADBDevices/AppleADBButtons.cpp
b0c7168f7b2dc6b3759a8f9c08a5caefe18c39c4
[apple/xnu.git] / iokit / Drivers / hidsystem / drvAppleADBDevices / AppleADBButtons.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 #include "AppleADBButtons.h"
23 #include "AppleADBKeyboard.h"
24 #include <IOKit/IOLib.h>
25 #include <IOKit/pwr_mgt/IOPM.h>
26 #include <IOKit/hidsystem/IOHIDTypes.h>
27 #include <IOKit/hidsystem/IOHIDParameter.h>
28
29 #define super IOHIKeyboard
30 OSDefineMetaClassAndStructors(AppleADBButtons,IOHIKeyboard)
31
32 bool displayWranglerFound( OSObject *, void *, IOService * );
33 void button_data ( IOService * us, UInt8 adbCommand, IOByteCount length, UInt8 * data );
34 void asyncFunc ( void * );
35
36 // **********************************************************************************
37 // start
38 //
39 // **********************************************************************************
40 bool AppleADBButtons::start ( IOService * theNub )
41 {
42 int i;
43
44 for ( i = 0; i < kMax_registrations; i++ ) {
45 keycodes[i] = kNullKey;
46 downHandlers[i] = NULL;
47 }
48
49 adbDevice = (IOADBDevice *)theNub;
50
51 if( !super::start(theNub))
52 return false;
53
54 if( !adbDevice->seizeForClient(this, button_data) ) {
55 IOLog("%s: Seize failed\n", getName());
56 return false;
57 }
58
59 addNotification( gIOPublishNotification,serviceMatching("IODisplayWrangler"), // look for the display wrangler
60 (IOServiceNotificationHandler)displayWranglerFound, this, 0 );
61 _initial_handler_id = adbDevice->handlerID();
62
63 return true;
64 }
65
66 UInt64 AppleADBButtons::getGUID()
67 {
68 return(kAppleOnboardGUID);
69 }
70
71 // **********************************************************************************
72 // displayWranglerFound
73 //
74 // The Display Wrangler has appeared. We will be calling its
75 // ActivityTickle method when there is user activity.
76 // **********************************************************************************
77 bool displayWranglerFound( OSObject * us, void * ref, IOService * yourDevice )
78 {
79 if ( yourDevice != NULL ) {
80 ((AppleADBButtons *)us)->displayManager = yourDevice;
81 }
82 return true;
83 }
84
85 UInt32 AppleADBButtons::interfaceID()
86 {
87 return NX_EVS_DEVICE_INTERFACE_ADB;
88 }
89
90 UInt32 AppleADBButtons::deviceType()
91 {
92 //if initial id is 31 then this is a post-WallStreet PowerBook, so
93 //look for a AppleADBKeyboard driver and return the handler ID from it.
94 //Note though that the ADB keyboard driver may not exist.
95 if (_initial_handler_id == 31)
96 {
97 mach_timespec_t t;
98 AppleADBKeyboard *adbkeyboard;
99
100 t.tv_sec = 2;
101 t.tv_nsec = 0;
102 adbkeyboard = (AppleADBKeyboard *)waitForService(serviceMatching("AppleADBKeyboard"), &t);
103 if (adbkeyboard)
104 {
105 return adbkeyboard->deviceType();
106 }
107
108 }
109
110 return adbDevice->handlerID();
111 }
112
113 // **********************************************************************************
114 // registerForButton
115 //
116 // Clients call here, specifying a button and a routine to call when that
117 // button is pressed or released.
118 // **********************************************************************************
119 IOReturn AppleADBButtons::registerForButton ( unsigned int keycode, IOService * registrant, button_handler handler, bool down )
120 {
121 int i;
122
123 for ( i = 0; i < kMax_registrations; i++ ) {
124 if ( keycodes[i] == kNullKey ) {
125 if ( down ) {
126 registrants[i] = registrant;
127 downHandlers[i] = handler;
128 keycodes[i] = keycode;
129 break;
130 }
131 }
132 }
133 return kIOReturnSuccess;
134 }
135
136 // **********************************************************************************
137 // button_data
138 //
139 // **********************************************************************************
140 void button_data ( IOService * us, UInt8 adbCommand, IOByteCount length, UInt8 * data )
141 {
142 ((AppleADBButtons *)us)->packet(data,length,adbCommand);
143 }
144
145
146 // **********************************************************************************
147 // packet
148 //
149 // **********************************************************************************
150 IOReturn AppleADBButtons::packet (UInt8 * data, IOByteCount, UInt8 adbCommand )
151 {
152 unsigned int keycode;
153 bool down;
154
155 keycode = *data;
156 down = ((keycode & 0x80) == 0);
157 keycode &= 0x7f;
158 dispatchButtonEvent(keycode,down);
159
160 keycode = *(data + 1);
161 if( keycode != 0xff ) {
162 down = ((keycode & 0x80) == 0);
163 keycode &= 0x7f;
164 dispatchButtonEvent(keycode,down);
165 }
166
167 if ( displayManager != NULL ) { // if there is a display manager, tell
168 displayManager->activityTickle(kIOPMSuperclassPolicy1); // it there is user activity
169 }
170
171 return kIOReturnSuccess;
172 }
173
174
175 // **********************************************************************************
176 // dispatchButtonEvent
177 //
178 // Look for any registered handlers for this button and notify them.
179 // **********************************************************************************
180 void AppleADBButtons::dispatchButtonEvent (unsigned int keycode, bool down )
181 {
182 int i;
183 AbsoluteTime now;
184
185 if (_initial_handler_id == 0xc0) //For Apple ADB AV and ColorSync monitors
186 {
187 switch (keycode)
188 {
189 case kVolume_up_AV:
190 keycode = kVolume_up;
191 break;
192 case kVolume_down_AV:
193 keycode = kVolume_down;
194 break;
195 case kMute_AV:
196 keycode = kMute;
197 break;
198 default:
199 //No other volume codes are available for OS X
200 break;
201 }
202 }
203
204 clock_get_uptime(&now);
205
206 for ( i = 0; i < kMax_registrations; i++ ) {
207 if ( keycodes[i] == keycode ) {
208 if ( down ) {
209 if (downHandlers[i] != NULL ) {
210 thread_call_func((thread_call_func_t)downHandlers[i],
211 (thread_call_param_t)registrants[i],
212 true);
213 }
214 }
215 }
216 }
217
218 //Only dispatch keycodes that this driver understands.
219 // See appleADBButtonsKeyMap[] for the list.
220 switch (keycode)
221 {
222 case kVolume_up:
223 case kVolume_down:
224 case kMute:
225 case kEject:
226 case kBrightness_up:
227 case kBrightness_down:
228 case kNum_lock_on_laptops:
229 dispatchKeyboardEvent(keycode, down, now);
230 break;
231 default: //Don't dispatch anything else
232 break;
233 }
234 }
235
236 const unsigned char *AppleADBButtons::defaultKeymapOfLength(UInt32 *length)
237 {
238 static const unsigned char appleADBButtonsKeyMap[] = {
239 0x00, 0x00, // chars
240 0x00, // no modifier keys
241 0x00, // no defs
242 0x00, // no seqs
243 0x07, // 6 special keys
244 NX_KEYTYPE_SOUND_UP, kVolume_up,
245 NX_KEYTYPE_SOUND_DOWN, kVolume_down,
246 NX_KEYTYPE_MUTE, kMute,
247 NX_KEYTYPE_BRIGHTNESS_UP, kBrightness_up,
248 NX_KEYTYPE_BRIGHTNESS_DOWN, kBrightness_down,
249 NX_KEYTYPE_NUM_LOCK, kNum_lock_on_laptops,
250 NX_KEYTYPE_EJECT, kEject
251 };
252
253 *length = sizeof(appleADBButtonsKeyMap);
254
255 return appleADBButtonsKeyMap;
256 }
257
258 IOReturn AppleADBButtons::setParamProperties(OSDictionary *dict)
259 {
260 dict->removeObject(kIOHIDKeyMappingKey);
261
262 return super::setParamProperties(dict);
263 }