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#ifndef _IOHIKEYBOARDMAPPER_H 24#define _IOHIKEYBOARDMAPPER_H 25 26#include <IOKit/hidsystem/ev_keymap.h> 27#include <IOKit/hidsystem/IOLLEvent.h> 28#include <IOKit/IOTimerEventSource.h> 29#include <IOKit/IOInterruptEventSource.h> 30 31class IOHIKeyboard; 32class IOHIDSystem; 33 34/* 35 * Key ip/down state is tracked in a bit list. Bits are set 36 * for key-down, and cleared for key-up. The bit vector and macros 37 * for it's manipulation are defined here. 38 */ 39 40typedef UInt32 * kbdBitVector; 41 42#define EVK_BITS_PER_UNIT 32 43#define EVK_BITS_MASK 31 44#define EVK_BITS_SHIFT 5 // 1<<5 == 32, for cheap divide 45 46#define EVK_KEYDOWN(n, bits) \ 47 (bits)[((n)>>EVK_BITS_SHIFT)] |= (1 << ((n) & EVK_BITS_MASK)) 48 49#define EVK_KEYUP(n, bits) \ 50 (bits)[((n)>>EVK_BITS_SHIFT)] &= ~(1 << ((n) & EVK_BITS_MASK)) 51 52#define EVK_IS_KEYDOWN(n, bits) \ 53 (((bits)[((n)>>EVK_BITS_SHIFT)] & (1 << ((n) & EVK_BITS_MASK))) != 0) 54 55/* the maximum number of modifier keys sticky keys can hold at once */ 56#define kMAX_MODIFIERS 5 57 58/* the number of shift keys in a row that must be depressed to toggle state */ 59#define kNUM_SHIFTS_TO_ACTIVATE 5 60 61/* the number of milliseconds all the shifts must be pressed in - 30 seconds (30000 mS)*/ 62#define kDEFAULT_SHIFTEXPIREINTERVAL 30000 63 64 65// sticky keys state flags 66enum 67{ 68 kState_Disabled_Flag = 0x0001, // disabled and will do nothing until this is changed 69 kState_ShiftActivates_Flag = 0x0002, // the 'on' gesture (5 shifts) will activate 70 kState_On = 0x0004, // currently on, will hold down modifiers when pressed 71 kState_On_ModifiersDown = 0x0008, // one or more modifiers being held down 72 73 kState_Mask = 0x00FF, // mask for all states 74}; 75 76typedef struct _stickyKeys_ToggleInfo 77{ 78 // size of this allocation 79 IOByteCount size; 80 81 // which modifier key we are tracking (using NX_WHICHMODMASK) 82 unsigned toggleModifier; 83 84 // the number of times the modifier must be pressed to toggle 85 unsigned repetitionsToToggle; 86 87 // how long the user has to press the modifier repetitionsToToggle times 88 // the default is 30 seconds 89 AbsoluteTime expireInterval; 90 91 // the number of times the modifier used within the alloted time 92 unsigned currentCount; 93 94 // the times that the last shift must occer for this one to be used 95 // this array will actually be of size repetitionsToToggle 96 AbsoluteTime deadlines[1]; 97} StickyKeys_ToggleInfo; 98 99// Flags for each sticky key modifier 100// This will allow for chording of keys 101// and for key locking 102enum 103{ 104 kModifier_DidPerformModifiy = 0x01, 105 kModifier_DidKeyUp = 0x02, 106 kModifier_Locked = 0x04, 107}; 108typedef struct _stickyKeys_ModifierInfo 109{ 110 UInt8 key; // Key code of the sticky modifier 111 UInt8 state; // The state of the sticky modifier 112 UInt8 leftModBit; // System Mod bit of the sticky modifier 113} StickyKeys_ModifierInfo; 114 115class IOHIDKeyboardDevice; 116 117class IOHIKeyboardMapper : public OSObject 118{ 119 OSDeclareDefaultStructors(IOHIKeyboardMapper); 120 121private: 122 IOHIKeyboard * _delegate; // KeyMap delegate 123 bool _mappingShouldBeFreed; // true if map can be IOFree'd 124 NXParsedKeyMapping _parsedMapping; // current system-wide keymap 125 IOHIDSystem * _hidSystem; // target of IOHIKeyboard (should be IOHIDSystem) 126 127 // binary compatibility padding 128 struct ExpansionData { 129 130 // This is for F12 eject 131 UInt16 f12Eject_State; 132 UInt32 eject_Delay_MS; 133 IOTimerEventSource *ejectTimerEventSource; 134 135 // This is for sticky keys 136 kbdBitVector cached_KeyBits; 137 StickyKeys_ModifierInfo stickyKeys_StuckModifiers[kMAX_MODIFIERS]; 138 IOInterruptEventSource *stickyKeysMouseClickEventSource; 139 IOInterruptEventSource *stickyKeysSetFnStateEventSource; 140 // The following should really be statics, but placing here 141 // to match design by predecesor. 142 OSDictionary *offFnParamDict; 143 OSDictionary *onFnParamDict; 144 145 // This is for SlowKeys 146 UInt16 slowKeys_State; 147 UInt32 slowKeys_Delay_MS; 148 IOTimerEventSource *slowKeysTimerEventSource; 149 150 // stored for slowKeysPostProcess 151 UInt8 slowKeys_Aborted_Key; 152 UInt8 slowKeys_Current_Key; 153 154 UInt32 specialKeyModifierFlags; 155 156 bool supportsF12Eject; 157 158 SInt32 modifierSwap_Modifiers[NX_NUMMODIFIERS]; 159 160 unsigned char * cachedAlphaLockModDefs; 161 }; 162 ExpansionData * _reserved; // Reserved for future use. (Internal use only) 163 164public: 165 static IOHIKeyboardMapper * keyboardMapper( 166 IOHIKeyboard * delegate, 167 const UInt8 * mapping, 168 UInt32 mappingLength, 169 bool mappingShouldBeFreed ); 170 171 virtual bool init(IOHIKeyboard * delegate, 172 const UInt8 * mapping, 173 UInt32 mappingLength, 174 bool mappingShouldBeFreed); 175 virtual void free(); 176 177 virtual const UInt8 * mapping(); 178 virtual UInt32 mappingLength(); 179 virtual bool serialize(OSSerialize *s) const; 180 181 virtual void translateKeyCode(UInt8 key, bool keyDown, kbdBitVector keyBits); 182 virtual UInt8 getParsedSpecialKey(UInt8 logical); //retrieve a key from _parsedMapping 183 184 virtual void setKeyboardTarget (IOService * keyboardTarget); 185 186 virtual bool updateProperties (void); 187 virtual IOReturn setParamProperties (OSDictionary * dict); 188 189 // keyEventPostProcess is called while a lock is not held, so a recursive 190 // call back into HIKeyboard is possible 191 virtual void keyEventPostProcess (void); 192 193private: 194 static void makeNumberParamProperty( OSDictionary * dict, const char * key, 195 unsigned long long number, unsigned int bits ); 196 197 198 virtual bool parseKeyMapping(const UInt8 * mapping, 199 UInt32 mappingLength, 200 NXParsedKeyMapping * parsedMapping) const; 201 202 virtual void calcModBit(int bit, kbdBitVector keyBits); 203 virtual void doModCalc(int key, kbdBitVector keyBits); 204 virtual void doCharGen(int keyCode, bool down); 205 206 /* sticky keys functionality */ 207private: 208 // original translateKeyCode 209 void rawTranslateKeyCode (UInt8 key, bool keyDown, kbdBitVector keyBits); 210 bool modifierSwapFilterKey(UInt8 * key); 211 212 // the current state of stickyKeys 213 UInt32 _stickyKeys_State; 214 215 // the number of modifiers being held down by stickyKeys 216 int _stickyKeys_NumModifiersDown; 217 218 // contains the info needed to keep track of shift repetitions 219 StickyKeys_ToggleInfo * _stickyKeys_ShiftToggle; 220 221 // contains the info needed to keep track of option repetitions 222 StickyKeys_ToggleInfo * _stickyKeys_OptionToggle; 223 224 // dictionaries with cached on and off states, used to set params when state changes 225 bool _stateDirty; 226 OSDictionary * _onParamDict; 227 OSDictionary * _offParamDict; 228 229 // init/free vars 230 bool stickyKeysinit (void); 231 void stickyKeysfree (void); 232 233 // allocate/free a StickyKeys_ToggleInfo struct 234 static StickyKeys_ToggleInfo * stickyKeysAllocToggleInfo (unsigned maxCount); 235 static void stickyKeysFreeToggleInfo (StickyKeys_ToggleInfo * toggleInfo); 236 237 // create on/off dicts as part of init 238 bool createParamDicts (void); 239 240 // post special keyboard events thru the event system 241 void postKeyboardSpecialEvent (unsigned subtype, unsigned eventType=NX_SYSDEFINED); 242 243 // check any modifier to see if it is pressed 5 times 244 // based on StickyKeys_ToggleInfo 245 bool stickyKeysModifierToggleCheck( 246 StickyKeys_ToggleInfo * toggleInfo, 247 UInt8 key, 248 bool keyDown, 249 kbdBitVector keyBits, 250 bool mouseClick = false); 251 252 // non-modifier key pressed 253 void stickyKeysNonModifierKey (UInt8 key, bool keyDown, kbdBitVector keyBits, bool mouseClick = false); 254 255 // modifier key pressed (shift, command, option, control) 256 bool stickyKeysModifierKey (UInt8 key, bool keyDown, kbdBitVector keyBits); 257 258 // main entry point, called for all keys (returns true if key handled) 259 bool stickyKeysFilterKey (UInt8 key, bool keyDown, kbdBitVector keyBits, bool mouseClick = false); 260 261 // called by interrupt event source to inform sticky keys of mouse down event 262 static void stickyKeysMouseUp(IOHIKeyboardMapper *owner, IOEventSource *sender); 263 264 void stickyKeysCleanup(); 265 266 // called by interrupt event source to restore prior fn state 267 static void stickyKeysSetFnState(IOHIKeyboardMapper *owner, IOEventSource *sender); 268 269 /* F12 Eject Functionality */ 270private: 271 272 // Determining f12 eject key press 273 // Returns true if f12 held down for a predetermined period of time. 274 bool f12EjectFilterKey (UInt8 key, bool keyDown, kbdBitVector keyBits); 275 276 // Timer function for eject 277 static void performF12Eject(IOHIKeyboardMapper *owner, IOTimerEventSource *sender); 278 279 /* SlowKeys Functionality */ 280private: 281 // Slow keys methods 282 bool slowKeysFilterKey (UInt8 key, bool keyDown, kbdBitVector keyBits); 283 284 static void slowKeysPostProcess (IOHIKeyboardMapper *owner, IOTimerEventSource *sender); 285 286 287public: 288 OSMetaClassDeclareReservedUsed(IOHIKeyboardMapper, 0); 289 virtual IOReturn message( UInt32 type, IOService * provider, void * argument = 0 ); 290 291 // binary compatibility padding 292 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 1); 293 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 2); 294 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 3); 295 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 4); 296 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 5); 297 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 6); 298 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 7); 299 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 8); 300 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 9); 301 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 10); 302 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 11); 303 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 12); 304 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 13); 305 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 14); 306 OSMetaClassDeclareReservedUnused(IOHIKeyboardMapper, 15); 307}; 308 309#endif // _IOHIKEYBOARDMAPPER_H 310 311/* 312 * HISTORICAL NOTE: 313 * The "delegate" object had to respond to the following protocol; 314 * this protocol has since been merged into the IOHIKeyboard class. 315 * 316 * @protocol KeyMapDelegate 317 * 318 * - keyboardEvent :(unsigned)eventType 319 * flags :(unsigned)flags 320 * keyCode :(unsigned)keyCode 321 * charCode:(unsigned)charCode 322 * charSet :(unsigned)charSet 323 * originalCharCode:(unsigned)origCharCode 324 * originalCharSet:(unsigned)origCharSet; 325 * 326 * - keyboardSpecialEvent:(unsigned)eventType 327 * flags :(unsigned)flags 328 * keyCode :(unsigned)keyCode 329 * specialty:(unsigned)flavor; 330 * 331 * - updateEventFlags:(unsigned)flags; // Does not generate events 332 * 333 * - (unsigned)eventFlags; // Global event flags 334 * - (unsigned)deviceFlags; // per-device event flags 335 * - setDeviceFlags:(unsigned)flags; // Set device event flags 336 * - (bool)alphaLock; // current alpha-lock state 337 * - setAlphaLock:(bool)val; // Set current alpha-lock state 338 * - (bool)charKeyActive; // Is a character gen. key down? 339 * - setCharKeyActive:(bool)val; // Note that a char gen key is down. 340 * 341 * @end 342 */ 343