00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "detectmac.h"
00021
00022 #include "gluon_input_export.h"
00023 #include "gluondevices.h"
00024 #include "inputthread.h"
00025 #include "detectmacprivate.h"
00026
00027 #include <QtCore/QDebug>
00028 #include <IOKit/IOKitLib.h>
00029 #include <IOKit/hid/IOHIDUsageTables.h>
00030
00031 using namespace GluonInput;
00032
00033 DetectMac::DetectMac( QObject* parent )
00034 : Detect( parent )
00035 , d( new DetectMacPrivate() )
00036 {
00037 }
00038
00039 DetectMac::~DetectMac()
00040 {
00041 CFRelease( d->deviceManager );
00042
00043 }
00044
00045 void DetectMac::detectDevices()
00046 {
00047 if( d->deviceManager == 0 )
00048 {
00049 d->deviceManager = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
00050 }
00051
00052 CFMutableDictionaryRef dict;
00053 CFMutableArrayRef matchingArray = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks );
00054
00055 dict = createMatchingDictionary( kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard );
00056 if( dict )
00057 {
00058 CFArrayAppendValue( matchingArray, dict );
00059 CFRelease( dict );
00060 }
00061
00062
00063 dict = createMatchingDictionary( kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse );
00064 if( dict )
00065 {
00066 CFArrayAppendValue( matchingArray, dict );
00067 CFRelease( dict );
00068 }
00069
00070
00071 dict = createMatchingDictionary( kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick );
00072 if( dict )
00073 {
00074 CFArrayAppendValue( matchingArray, dict );
00075 CFRelease( dict );
00076 }
00077
00078
00079 dict = createMatchingDictionary( kHIDPage_Digitizer, kHIDUsage_Dig_Digitizer );
00080 if( dict )
00081 {
00082 CFArrayAppendValue( matchingArray, dict );
00083 CFRelease( dict );
00084 }
00085
00086
00087 dict = createMatchingDictionary( kHIDPage_Digitizer, kHIDUsage_Dig_TouchPad );
00088 if( dict )
00089 {
00090 CFArrayAppendValue( matchingArray, dict );
00091 CFRelease( dict );
00092 }
00093
00094 if( CFGetTypeID( d->deviceManager ) == IOHIDManagerGetTypeID() )
00095 {
00096 IOHIDManagerSetDeviceMatchingMultiple( d->deviceManager, matchingArray );
00097
00098 if( IOHIDManagerOpen( d->deviceManager, kIOHIDOptionsTypeNone ) == kIOReturnSuccess )
00099 {
00100 d->devices = IOHIDManagerCopyDevices( d->deviceManager );
00101
00102 if( CFSetGetCount( d->devices ) > 0 )
00103 {
00104 CFSetApplyFunction( d->devices, createDevices, this );
00105 }
00106 }
00107 }
00108 }
00109
00110 QList<InputDevice*> DetectMac::inputList()
00111 {
00112 return d->m_inputList;
00113 }
00114
00115 QList<Keyboard*> DetectMac::keyboardList()
00116 {
00117 return d->m_keyboardList;
00118 }
00119
00120 QList<Mouse*> DetectMac::mouseList()
00121 {
00122 return d->m_mouseList;
00123 }
00124
00125 QList<Joystick*> DetectMac::joystickList()
00126 {
00127 return d->m_joystickList;
00128 }
00129
00130 QList<Touch*> DetectMac::touchList()
00131 {
00132 return d->m_touchList;
00133 }
00134
00135 QList<InputDevice*> DetectMac::unknownDeviceList()
00136 {
00137 return d->m_unknownList;
00138 }
00139
00140
00141 void DetectMac::addInput( InputDevice* i )
00142 {
00143 d->m_inputList.append( i );
00144 }
00145
00146 void DetectMac::addKeyboard( InputDevice* i )
00147 {
00148 Keyboard* keybd = qobject_cast<Keyboard*>( i );
00149
00150 d->m_keyboardList.append( keybd );
00151 d->m_inputList.append( i );
00152 }
00153
00154 void DetectMac::addMouse( InputDevice* i )
00155 {
00156 Mouse* mouse = qobject_cast<Mouse*>( i );
00157
00158 d->m_mouseList.append( mouse );
00159 d->m_inputList.append( i );
00160 }
00161
00162 void DetectMac::addJoystick( InputDevice* i )
00163 {
00164 Joystick* joy = qobject_cast<Joystick*>( i );
00165
00166 d->m_joystickList.append( joy );
00167 d->m_inputList.append( i );
00168 }
00169
00170 void DetectMac::addTouch( InputDevice* i )
00171 {
00172 Touch* touch = qobject_cast<Touch*>( i );
00173
00174 d->m_touchList.append( touch );
00175 d->m_inputList.append( i );
00176 }
00177
00178 void DetectMac::addUnknown( InputDevice* i )
00179 {
00180 d->m_unknownList.append( i );
00181 d->m_inputList.append( i );
00182 }
00183
00184 void DetectMac::clear()
00185 {
00186 d->m_inputList.clear();
00187 d->m_keyboardList.clear();
00188 d->m_mouseList.clear();
00189 d->m_joystickList.clear();
00190 d->m_touchList.clear();
00191 d->m_unknownList.clear();
00192 }
00193
00194 void DetectMac::setAllEnabled( bool enable )
00195 {
00196 foreach( InputDevice * input, inputList() )
00197 {
00198 input->setEnabled( enable );
00199 }
00200 }
00201
00202 void DetectMac::createDevices( const void* value, void* context )
00203 {
00204 IOHIDDeviceRef device = ( IOHIDDeviceRef )value;
00205 DetectMac* detect = ( DetectMac* ) context;
00206
00207 if( CFGetTypeID( device ) == IOHIDDeviceGetTypeID() )
00208 {
00209 IOHIDDeviceOpen( device, kIOHIDOptionsTypeNone );
00210
00211 int usagePage = NULL;
00212 int usage = NULL;
00213
00214 CFTypeRef type = IOHIDDeviceGetProperty( device, CFSTR( kIOHIDDeviceUsagePageKey ) );
00215
00216 if( type )
00217 {
00218
00219 if( CFNumberGetTypeID() == CFGetTypeID( type ) )
00220 {
00221
00222 CFNumberGetValue(( CFNumberRef )type, kCFNumberSInt32Type, &usagePage );
00223 }
00224 CFRelease( type );
00225 }
00226
00227 type = IOHIDDeviceGetProperty( device, CFSTR( kIOHIDDeviceUsageKey ) );
00228
00229 if( type )
00230 {
00231
00232 if( CFNumberGetTypeID() == CFGetTypeID( type ) )
00233 {
00234
00235 CFNumberGetValue(( CFNumberRef )type, kCFNumberSInt32Type, &usage );
00236 }
00237 CFRelease( type );
00238 }
00239
00240 if( !usage || !usagePage )
00241 {
00242 type = IOHIDDeviceGetProperty( device, CFSTR( kIOHIDPrimaryUsagePageKey ) );
00243
00244 if( type )
00245 {
00246
00247 if( CFNumberGetTypeID() == CFGetTypeID( type ) )
00248 {
00249
00250 CFNumberGetValue(( CFNumberRef )type, kCFNumberSInt32Type, &usagePage );
00251 }
00252 CFRelease( type );
00253 }
00254
00255 type = IOHIDDeviceGetProperty( device, CFSTR( kIOHIDPrimaryUsageKey ) );
00256
00257 if( type )
00258 {
00259
00260 if( CFNumberGetTypeID() == CFGetTypeID( type ) )
00261 {
00262
00263 CFNumberGetValue(( CFNumberRef )type, kCFNumberSInt32Type, &usage );
00264 }
00265 CFRelease( type );
00266 }
00267
00268 }
00269
00270 if( !usage || !usagePage )
00271 {
00272 usagePage = 0;
00273 }
00274
00275 InputDevice* inputDevice;
00276 if( usagePage == kHIDPage_GenericDesktop )
00277 {
00278 switch( usage )
00279 {
00280 case GluonInput::KeyboardDevice:
00281 inputDevice = new Keyboard( new InputThread( device ) );
00282 detect->addKeyboard( inputDevice );
00283 break;
00284 case GluonInput::MouseDevice:
00285 inputDevice = new Mouse( new InputThread( device ) );
00286 detect->addMouse( inputDevice );
00287 break;
00288 case GluonInput::JoystickDevice:
00289 inputDevice = new Joystick( new InputThread( device ) );
00290 detect->addJoystick( inputDevice );
00291 break;
00292 default:
00293 inputDevice = new InputDevice( new InputThread( device ) );
00294 detect->addUnknown( inputDevice );
00295 break;
00296 }
00297 }
00298 else if( usagePage == kHIDPage_Digitizer )
00299 {
00300 switch( usage )
00301 {
00302
00303
00304 case GluonInput::TouchDevice:
00305 inputDevice = new Touch( new InputThread( device ) );
00306 detect->addTouch( inputDevice );
00307 break;
00308 default:
00309 inputDevice = new InputDevice( new InputThread( device ) );
00310 detect->addUnknown( inputDevice );
00311 break;
00312 }
00313 }
00314
00315 }
00316 }
00317
00318 CFMutableDictionaryRef DetectMac::createMatchingDictionary( UInt32 pUsagePage, UInt32 pUsage )
00319 {
00320 CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
00321 CFNumberRef usagePage = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &pUsagePage );
00322 CFNumberRef usage = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &pUsage );
00323 if( matchDict && usagePage && usage )
00324 {
00325 CFDictionarySetValue( matchDict, CFSTR( kIOHIDDeviceUsagePageKey ), usagePage );
00326 CFDictionarySetValue( matchDict, CFSTR( kIOHIDDeviceUsageKey ), usage );
00327 CFRelease( usagePage );
00328 CFRelease( usage );
00329 return matchDict;
00330 }
00331 else
00332 {
00333 return 0;
00334 }
00335 }
00336
00337 #include "detectmac.moc"