Add HID Utilities and ForceFeedback

Patch functions with same signature
This commit is contained in:
maride 2016-04-02 15:32:35 +02:00
parent c05119a2da
commit 9f81d2eb96
34 changed files with 11347 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,816 @@
//-----------------------------------------------------------------------------
// File: ForceFeedback.h
// Contains: Public interfaces for ForceFeedback technology.
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _FORCEFEEDBACK_H_
#define _FORCEFEEDBACK_H_
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! @header ForceFeedback.h
@abstract Public Interfaces to the Force Feedback implementation in Mac OS X.
@discussion The Force Feedback API allows developers to control Force Feedback devices attached to the system. It is a distilled version of the Force Feedback functionality found in Microsoft's DirectInput API. Developers familiar with that API should find this API to be similar.
*/
#include <CoreFoundation/CoreFoundation.h>
#if COREFOUNDATION_CFPLUGINCOM_SEPARATE
#include <CoreFoundation/CFPlugInCOM.h>
#endif
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <IOKit/IOTypes.h>
#include <ForceFeedback/ForceFeedbackConstants.h>
//-----------------------------------------------------------------------------
// The Version of the FF API
//-----------------------------------------------------------------------------
enum {
kFFAPIMajorRev = 1,
kFFAPIMinorAndBugRev = 0,
kFFAPIStage = finalStage,
kFFAPINonRelRev = 0
};
//-----------------------------------------------------------------------------
// Effect definition structures
//-----------------------------------------------------------------------------
struct FFCONSTANTFORCE
{
LONG lMagnitude;
};
typedef struct FFCONSTANTFORCE FFCONSTANTFORCE;
typedef FFCONSTANTFORCE * PFFCONSTANTFORCE;
struct FFRAMPFORCE
{
LONG lStart;
LONG lEnd;
};
typedef struct FFRAMPFORCE FFRAMPFORCE;
typedef FFRAMPFORCE * PFFRAMPFORCE;
struct FFPERIODIC
{
DWORD dwMagnitude;
LONG lOffset;
DWORD dwPhase;
DWORD dwPeriod;
};
typedef struct FFPERIODIC FFPERIODIC;
typedef FFPERIODIC * PFFPERIODIC;
struct FFCONDITION
{
LONG lOffset;
LONG lPositiveCoefficient;
LONG lNegativeCoefficient;
DWORD dwPositiveSaturation;
DWORD dwNegativeSaturation;
LONG lDeadBand;
};
typedef struct FFCONDITION FFCONDITION;
typedef FFCONDITION * PFFCONDITION;
struct FFCUSTOMFORCE
{
DWORD cChannels;
DWORD dwSamplePeriod;
DWORD cSamples;
LPLONG rglForceData;
};
typedef struct FFCUSTOMFORCE FFCUSTOMFORCE;
typedef FFCUSTOMFORCE * PFFCUSTOMFORCE;
struct FFENVELOPE
{
DWORD dwSize; /* sizeof(FFENVELOPE) */
DWORD dwAttackLevel;
DWORD dwAttackTime; /* Microseconds */
DWORD dwFadeLevel;
DWORD dwFadeTime; /* Microseconds */
};
typedef struct FFENVELOPE FFENVELOPE;
typedef FFENVELOPE * PFFENVELOPE;
// IMPORTANT NOTE: OBJECT IDS cannot be used to identify trigger buttons
// in FFEFFECT.dwTriggerButton, and output axes in FFEFFECT.rgdwAxes[n].
// Please use object offsets (FFJOFS_* constants), the only supported method.
struct FFEFFECT
{
DWORD dwSize; /* sizeof(FFEFFECT) */
DWORD dwFlags; /* FFEFF_* */
DWORD dwDuration; /* Microseconds */
DWORD dwSamplePeriod; /* Microseconds */
DWORD dwGain;
DWORD dwTriggerButton; /* or FFEB_NOTRIGGER */
DWORD dwTriggerRepeatInterval; /* Microseconds */
DWORD cAxes; /* Number of axes */
LPDWORD rgdwAxes; /* Array of axes */
LPLONG rglDirection; /* Array of directions */
PFFENVELOPE lpEnvelope; /* Optional */
DWORD cbTypeSpecificParams; /* Size of params */
void* lpvTypeSpecificParams; /* Pointer to params */
DWORD dwStartDelay; /* Microseconds */
};
typedef struct FFEFFECT FFEFFECT;
typedef FFEFFECT * PFFEFFECT;
struct FFEFFESCAPE
{
DWORD dwSize;
DWORD dwCommand;
void* lpvInBuffer;
DWORD cbInBuffer;
void* lpvOutBuffer;
DWORD cbOutBuffer;
};
typedef struct FFEFFESCAPE FFEFFESCAPE;
typedef FFEFFESCAPE * PFFEFFESCAPE;
// NOTE: this structure has no DirectInput equivalent
struct FFCAPABILITIES
{
NumVersion ffSpecVer; // Version of specification supported by the driver
UInt32 supportedEffects; // FFCAP_ET_*; including emulated effects
UInt32 emulatedEffects; // FFCAP_ET_*; driver-emulated effects
UInt32 subType; // FFCAP_TYPE_*
UInt32 numFfAxes;
UInt8 ffAxes[32];
UInt32 storageCapacity; // number of effects that can be stored
// by the driver/device
UInt32 playbackCapacity; // number of effects that can be _simultaneously_
// played back by the driver/device
NumVersion firmwareVer; // device firmware version, vendor-defined
NumVersion hardwareVer; // hardware version, vendor-defined
NumVersion driverVer; // driver version, vendor-defined
};
typedef struct FFCAPABILITIES FFCAPABILITIES;
typedef FFCAPABILITIES * PFFCAPABILITIES;
//-----------------------------------------------------------------------------
// Object reference pointers
//-----------------------------------------------------------------------------
// FFDeviceObjectReference and FFEffectObjectReference are opaque handles
// to objects created and maintained by the FF API.
// A FFDeviceObjectReference is obtained through a call to FFCreateDevice and
// refers to a specific attached device supporting force feedback. This
// reference may be passed to any of the "FFDevice" functions (below). When
// you are through with it, call FFReleaseDevice to release the memory.
// Similarly, a FFEffectObjectReference is obtained through a call to
// FFDeviceCreateEffect and refers to a created force feedback effect on a
// particular device. This reference may be passed to any of the "FFEffect"
// functions. Call FFDeviceReleaseEffect to unload the effect and clean up
// its memory. - Jeff Mallett 9/25/02
//
typedef struct {} __FFDHIDDEN, * FFDeviceObjectReference;
typedef struct {} __FFEHIDDEN, * FFEffectObjectReference;
//-----------------------------------------------------------------------------
// FF (general) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFCreateDevice
@abstract Creates a new API device object from an OS object in preparation to use the device for force feedback.
@param hidDevice Pointer to a HID device object.
@param pdeviceReference Address of a variable to receive an opaque reference handle to a new device object. This reference can be used in subsequent calls to FFDevice* functions
@result If the method succeeds, and the device supports FF, the return value is FF_OK.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br> FFERR_INTERNAL
<br>
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object.
*/
extern HRESULT
FFCreateDevice(
io_service_t hidDevice,
FFDeviceObjectReference * pDeviceReference
);
/*! @function FFReleaseDevice
@abstract Disposes of an API device object created with FFCreateDevice.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@result If the method succeeds, and the device supports FF, the return value is FF_OK.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br>
@discussion
*/
extern HRESULT
FFReleaseDevice(
FFDeviceObjectReference deviceReference
);
/*! @function FFIsForceFeedback
@abstract Used to determine if a particular device provided by HID Manager is a force feedback device.
@param hidDevice Pointer to a HID device object to be tested for force feedback support.
@result If the method succeeds, and the device supports FF, the return value is FF_OK. If the method succeeds, and the device does not support FF, the return value is FFERR_NOINTERFACE. If the method fails, the return value is FFERR_INVALIDPARAM
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object.
*/
extern HRESULT
FFIsForceFeedback(
io_service_t hidDevice
);
//-----------------------------------------------------------------------------
// FFDevice (device related) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFDeviceCreateEffect
@abstract Creates and initializes an instance of an effect identified by the effect UUID on the device.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param uuidRef Reference to the UUID identifying the effect to be created. Only predefined effect UUIDs are accepted. The following standard effect UUIDs are defined:
<br>
<br> kFFEffectType_ConstantForce_ID
<br> kFFEffectType_RampForce_ID
<br> kFFEffectType_Square_ID
<br> kFFEffectType_Sine_ID
<br> kFFEffectType_Triangle_ID
<br> kFFEffectType_SawtoothUp_ID
<br> kFFEffectType_SawtoothDown_ID
<br> kFFEffectType_Spring_ID
<br> kFFEffectType_Damper_ID
<br> kFFEffectType_Inertia_ID
<br> kFFEffectType_Friction_ID
<br> kFFEffectType_CustomForce_ID
<br>
<br>
@param pEffectDefinition Pointer to FFEFFECT structure that provides parameters for the created effect. This parameter is optional. If it is NULL, the effect object is created without parameters. The application must then call the FFEffectSetParameters function to set the parameters of the effect before it can download the effect.
@param pEffectReference Address of a variable to receive an opaque reference handle to a new effect object. This reference can be used in subsequent calls to FFEffect* functions.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTEDAXIS
<br> FFERR_OUTOFMEMORY
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
@discussion When you are finished with the effect, FFReleaseEffect must be called on the reference received in this function to dispose of the API effect object.
*/
extern HRESULT
FFDeviceCreateEffect(
FFDeviceObjectReference deviceReference,
CFUUIDRef uuidRef,
FFEFFECT * pEffectDefinition,
FFEffectObjectReference * pEffectReference
);
/*! @function FFDeviceReleaseEffect
@abstract Disposes of an API effect object created with FFDeviceCreateEffect.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFDeviceReleaseEffect(
FFDeviceObjectReference deviceReference,
FFEffectObjectReference effectReference
);
/*! @function FFDeviceEscape
@abstract Sends a hardware-specific command to the device.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param pFFEffectEscape Pointer to FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTED
<br>
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver.
*/
extern HRESULT
FFDeviceEscape(
FFDeviceObjectReference deviceReference,
FFEFFESCAPE * pFFEffectEscape
);
/*! @function FFDeviceGetForceFeedbackState
@abstract Retrieves the state of the device's force feedback system.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param pFFState Location for flags that describe the current state of the device's force feedback system.
The value is a combination of the following constants:
<br>
<br> FFGFFS_ACTUATORSOFF
<br> The device's force feedback actuators are disabled.
<br>
<br> FFGFFS_ACTUATORSON
<br> The device's force feedback actuators are enabled.
<br>
<br> FFGFFS_DEVICELOST
<br> The device suffered an unexpected failure and is in an indeterminate state. It must be reset either by unacquiring and reacquiring the device, or by sending a FFSFFC_RESET command.
<br>
<br> FFGFFS_EMPTY
<br> The device has no downloaded effects.
<br>
<br> FFGFFS_PAUSED
<br> Playback of all active effects has been paused.
<br>
<br> FFGFFS_POWEROFF
<br> The force feedback system is not currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.
<br>
<br> FFGFFS_POWERON
<br> Power to the force feedback system is currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.
<br>
<br> FFGFFS_SAFETYSWITCHOFF
<br> The safety switch is currently off; that is, the device cannot operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.
<br>
<br> FFGFFS_SAFETYSWITCHON
<br> The safety switch is currently on; that is, the device can operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.
<br>
<br> FFGFFS_STOPPED
<br> No effects are playing, and the device is not paused.
<br>
<br> FFGFFS_USERFFSWITCHOFF
<br> The user force feedback switch is currently off; that is, the device cannot operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.
<br>
<br> FFGFFS_USERFFSWITCHON
<br> The user force feedback switch is currently on; that is, the device can operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.
<br>
<br> Future versions can define additional flags. Applications should ignore any flags that are not currently defined.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackState(
FFDeviceObjectReference deviceReference,
FFState * pFFState
);
/*! @function FFDeviceSendForceFeedbackCommand
@abstract Sends a command to the device's force feedback system.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param flags Single value indicating the desired change in state. The value can be one of the following:
<br>
<br> FFSFFC_CONTINUE
<br> Paused playback of all active effects is to be continued. It is an error to send this command when the device is not in a paused state.
<br>
<br> FFSFFC_PAUSE
<br> Playback of all active effects is to be paused. This command also stops the clock-on effects so that they continue playing to their full duration when restarted.
<br>
<br> While the device is paused, new effects cannot be started, and existing ones cannot be modified. Doing so can cause the subsequent FFSFFC_CONTINUE command to fail to perform properly.
<br>
<br> To abandon a pause and stop all effects, use the FFSFFC_STOPALL or FFSFCC_RESET commands.
<br>
<br> FFSFFC_RESET
<br> The device's force feedback system is to be put in its startup state. All effects are removed from the device, are no longer valid, and must be recreated if they are to be used again. The device's actuators are disabled.
<br>
<br> FFSFFC_SETACTUATORSOFF
<br> The device's force feedback actuators are to be disabled. While the actuators are off, effects continue to play but are ignored by the device. Using the analogy of a sound playback device, they are muted, rather than paused.
<br>
<br> FFSFFC_SETACTUATORSON
<br> The device's force feedback actuators are to be enabled.
<br>
<br> FFSFFC_STOPALL
<br> Playback of any active effects is to be stopped. All active effects are reset, but are still being maintained by the device and are still valid. If the device is in a paused state, that state is lost.
<br>
<br> This command is equivalent to calling the FFEffect_Stop method for each effect playing.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_INTERNAL
<br>
@discussion
*/
extern HRESULT
FFDeviceSendForceFeedbackCommand(
FFDeviceObjectReference deviceReference,
FFCommandFlag flags
);
/*! @function FFDeviceSetForceFeedbackProperty
@abstract Retrieves the device's force feedback capabilities.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param property The following property values are defined for a FF device:
<br>
<br> FFPROP_AUTOCENTER
<br> Specifies whether the actuated FF axes are self-centering. This property controls the device's "default centering spring".
<br> The pValue member points to a UInt32 can be one of the following values.
<br> 0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
<br> 1 - ON: The device should automatically center when the user releases the device.
<br> Not all devices support the autocenter property.
<br>
<br> FFPROP_FFGAIN
<br> Sets the gain for the device.
<br> The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
<br> Setting a gain value is useful when an application wants to scale down the strength of all force feedback effects uniformly, based on user preferences.
@param pValue Address of the location where the property value is to be read. SetForceFeedbackProperty will assume that the data is valid, and of the correct type.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceSetForceFeedbackProperty(
FFDeviceObjectReference deviceReference,
FFProperty property,
void * pValue
);
/*! @function FFDeviceGetForceFeedbackProperty
@abstract Gets properties that define the device behavior.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param property The following property values are defined for a FF device (see FFDeviceSetForceFeedbackProperty for details):
<br>
<br> FFPROP_AUTOCENTER
<br> FFPROP_FFGAIN
<br>
@param pValue Address of the location where the value associated with the property is to be stored. GetForceFeedbackProperty assumes that the pointer is valid, although it will perform a size check before writing the data to pValue
@param valueSize Size, in bytes, of data area pointed to by pValue. Size is compared to expected property size, and the function fails if a mismatch occurs.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackProperty(
FFDeviceObjectReference deviceReference,
FFProperty property,
void * pValue,
IOByteCount valueSize
);
/*! @function FFDeviceSetCooperativeLevel
@abstract Function is unimplemented in version 1.0 of this API
@discussion
*/
extern HRESULT
FFDeviceSetCooperativeLevel(
FFDeviceObjectReference deviceReference,
void * taskIdentifier,
FFCooperativeLevelFlag flags
);
/*! @function FFDeviceGetForceFeedbackCapabilities
@abstract Retrieves the device's force feedback capabilities.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param pFFCapabilities Pointer to a FFCAPABILITIES structure that is to be filled in by the this call.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackCapabilities(
FFDeviceObjectReference deviceReference,
FFCAPABILITIES * pFFCapabilities
);
//-----------------------------------------------------------------------------
// FFEffect (effect related) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFEffectDownload
@abstract Places the effect on the device. If the effect is already on the device, the existing effect is updated to match the values set by the FFEffectSetParameters method.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK or S_FALSE. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
<br> If the method returns S_FALSE, the effect has already been downloaded to the device.
<br>
@discussion It is valid to update an effect while it is playing. The semantics of such an operation are explained in the reference for FFEffectSetParameters.
*/
extern HRESULT
FFEffectDownload(
FFEffectObjectReference effectReference
);
/*! @function FFEffectEscape
@abstract Sends a hardware-specific command to the driver.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffectEscape FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_UNSUPPORTED
<br>
<br> Other device-specific error codes are also possible. Ask the hardware manufacturer for details
<br>
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver.
*/
extern HRESULT
FFEffectEscape(
FFEffectObjectReference effectReference,
FFEFFESCAPE * pFFEffectEscape
);
/*! @function FFEffectGetEffectStatus
@abstract Sends a hardware-specific command to the driver.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFlags Pointer to status flags for the effect. The value can be 0 or one or more of the following constants:
<br>
<br> FFEGES_PLAYING
<br> The effect is playing.
<br>
<br> FFEGES_EMULATED
<br> The effect is emulated.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br>
@discussion
*/
extern HRESULT
FFEffectGetEffectStatus(
FFEffectObjectReference effectReference,
FFEffectStatusFlag * pFlags
);
/*! @function FFEffectGetParameters
@abstract Retrieves information about an effect.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffect Address of a FFEFFECT structure that receives effect information. The dwSize member must be filled in by the application before calling this method.
@param flags Flags that specify which parts of the effect information are to be retrieved. The value can be 0 or one or more of the following constants:
<br>
<br> FFEP_ALLPARAMS
<br> The union of all other FFEP_* flags, indicating that all members of the FFEFFECT structure are being requested.
<br>
<br> FFEP_AXES
<br> The cAxes and rgdwAxes members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rgdwAxes member. If the buffer is too small, the method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
<br>
<br> FFEP_DIRECTION
<br> The cAxes and rglDirection members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rglDirection member. If the buffer is too small, the GetParameters method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
<br> The dwFlags member must include at least one of the coordinate system flags (FFEFF_CARTESIAN, FFEFF_POLAR, or FFEFF_SPHERICAL). The API returns the direction of the effect in one of the coordinate systems you specified, converting between coordinate systems as necessary. On exit, exactly one of the coordinate system flags is set in the dwFlags member, indicating which coordinate system the FF API used. In particular, passing all three coordinate system flags retrieves the coordinates in exactly the same format in which they were set.
<br>
<br> FFEP_DURATION
<br> The dwDuration member should receive data.
<br>
<br> FFEP_ENVELOPE
<br> The lpEnvelope member points to a FFENVELOPE structure that should receive data. If the effect does not have an envelope associated with it, the lpEnvelope member is set to NULL.
<br>
<br> FFEP_GAIN
<br> The dwGain member should receive data.
<br>
<br> FFEP_SAMPLEPERIOD
<br> The dwSamplePeriod member should receive data.
<br>
<br> FFEP_STARTDELAY
<br> The dwStartDelay member should receive data.
<br>
<br> FFEP_TRIGGERBUTTON
<br> The dwTriggerButton member should receive data.
<br>
<br> FFEP_TRIGGERREPEATINTERVAL
<br> The dwTriggerRepeatInterval member should receive data.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> The lpvTypeSpecificParams member points to a buffer whose size is specified by the cbTypeSpecificParams member. On return, the buffer is filled in with the type-specific data associated with the effect, and the cbTypeSpecificParams member contains the number of bytes copied. If the buffer supplied by the application is too small to contain all the type-specific data, the method returns FFERR_MOREDATA, and the cbTypeSpecificParams member contains the required size of the buffer in bytes.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_MOREDATA
<br>
@discussion Common errors resulting in a FFERR_INVALIDPARAM error include not setting the dwSize member of the FFEFFECT structure, passing invalid flags, or not setting up the members in the FFEFFECT structure properly in preparation for receiving the effect information.
*/
extern HRESULT
FFEffectGetParameters(
FFEffectObjectReference effectReference,
FFEFFECT * pFFEffect,
FFEffectParameterFlag flags
);
/*! @function FFEffectSetParameters
@abstract Sets the characteristics of an effect.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffect Address of a FFEFFECT structure that contains effect information. The dwSize member must be filled in by the application before calling this method, as well as any members specified by corresponding bits in the flags parameter.
@param flags Flags that specify which portions of the effect information are to be set and how the downloading of the parameters should be handled. The value can be 0 or one or more of the following constants:
<br>
<br> FFEP_AXES
<br> The cAxes and rgdwAxes members contain data.
<br>
<br> FFEP_DIRECTION
<br> The cAxes and rglDirection members contain data. The dwFlags member specifies (with FFEFF_CARTESIAN or FFEFF_POLAR) the coordinate system in which the values should be interpreted.
<br>
<br> FFEP_DURATION
<br> The dwDuration member contains data.
<br>
<br> FFEP_ENVELOPE
<br> The lpEnvelope member points to a FFENVELOPE structure that contains data. To detach any existing envelope from the effect, pass this flag and set the lpEnvelope member to NULL.
<br>
<br> FFEP_GAIN
<br> The dwGain member contains data.
<br>
<br> FFEP_NODOWNLOAD
<br> Suppress the automatic FFEffect_Download that is normally performed after the parameters are updated.
<br>
<br> FFEP_NORESTART
<br> Suppress the stopping and restarting of the effect to change parameters. See Remarks.
<br>
<br> FFEP_SAMPLEPERIOD
<br> The dwSamplePeriod member contains data.
<br>
<br> FFEP_START
<br> The effect is to be started (or restarted if it is currently playing) after the parameters are updated. By default, the play state of the effect is not altered.
<br>
<br> FFEP_STARTDELAY
<br> The dwStartDelay member contains data.
<br>
<br> FFEP_TRIGGERBUTTON
<br> The dwTriggerButton member contains data.
<br>
<br>
<br> The dwTriggerRepeatInterval member contains data.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> The lpvTypeSpecificParams and cbTypeSpecificParams members of the FFEFFECT structure contain the address and size of type-specific data for the effect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTEDAXIS
<br> FFERR_OUTOFMEMORY
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
@discussion The FFEffectSetParameters method automatically downloads the effect, but this behavior can be suppressed by setting the FFEP_NODOWNLOAD flag. If automatic download has been suppressed, you can manually download the effect by invoking the FFEffectDownload method.
<br>
<br> If the effect is playing while the parameters are changed, the new parameters take effect as if they were the parameters when the effect started.
<br>
<br> For example, suppose a periodic effect with a duration of three seconds is started. After two seconds, the direction of the effect is changed. The effect then continues for one additional second in the new direction. The envelope, phase, amplitude, and other parameters of the effect continue smoothly, as if the direction had not changed.
<br>
<br> In the same situation, if after two seconds the duration of the effect were changed to 1.5 seconds, the effect would stop.
<br>
<br> Normally, if the driver cannot update the parameters of a playing effect, the driver is permitted to stop the effect, update the parameters, and then restart the effect. Passing the FFEP_NORESTART flag suppresses this behavior. If the driver cannot update the parameters of an effect while it is playing, the error code FFERR_EFFECTPLAYING is returned, and the parameters are not updated.
<br>
<br> No more than one of the FFEP_NODOWNLOAD, FFEP_START, and FFEP_NORESTART flags should be set. (It is also valid to pass none of them.)
<br>
<br> These three flags control download and playback behavior as follows:
<br>
<br> If FFEP_NODOWNLOAD is set, the effect parameters are updated but not downloaded to the device.
<br>
<br> If the FFEP_START flag is set, the effect parameters are updated and downloaded to the device, and the effect is started just as if the FFEffect_Start method had been called with the dwIterations parameter set to 1 and with no flags. (Combining the update with FFEP_START is slightly faster than calling Start separately, because it requires less information to be transmitted to the device.)
<br>
<br> If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is not playing, the parameters are updated and downloaded to the device.
<br>
<br> If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is playing, the parameters are updated if the device supports on-the-fly updating. Otherwise the behavior depends on the state of the FFEP_NORESTART flag. If it is set, the error code FFERR_EFFECTPLAYING is returned. If it is clear, the effect is stopped, the parameters are updated, and the effect is restarted.
*/
extern HRESULT
FFEffectSetParameters(
FFEffectObjectReference effectReference,
FFEFFECT * pFFEffect,
FFEffectParameterFlag flags
);
/*! @function FFEffectStart
@abstract Begins playing an effect. If the effect is already playing, it is restarted from the beginning. If the effect has not been downloaded or has been modified since its last download, it is downloaded before being started. This default behavior can be suppressed by passing the FFES_NODOWNLOAD flag.
@param efffectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param iterations Number of times to play the effect in sequence. The envelope is re-articulated with each iteration.
<br>
<br> To play the effect exactly once, pass 1. To play the effect repeatedly until explicitly stopped, pass INFINITE. To play the effect until explicitly stopped without re-articulating the envelope, modify the effect parameters with the FFEffect_SetParameters method, and change the dwDuration member to INFINITE.
@param flags Flags that describe how the effect should be played by the device. The value can be 0 or one or more of the following values:
<br>
<br> FFES_SOLO
<br> All other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects already started on the device.
<br>
<br> FFES_NODOWNLOAD
<br> Do not automatically download the effect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br> FFERR_GENERIC
<br>
@discussion Not all devices support multiple iterations.
*/
extern HRESULT
FFEffectStart(
FFEffectObjectReference effectReference,
UInt32 iterations,
FFEffectStartFlag flags
);
/*! @function FFEffectStop
@abstract Stops playing an effect.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFEffectStop(
FFEffectObjectReference effectReference
);
/*! @function FFEffectUnload
@abstract Removes the effect from the device. If the effect is playing, it is automatically stopped before it is unloaded.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFEffectUnload(
FFEffectObjectReference effectReference
);
#ifdef __cplusplus
}
#endif
#endif // _FORCEFEEDBACK_H_

View File

@ -0,0 +1,572 @@
//-----------------------------------------------------------------------------
// File: ForceFeedbackConstants.h
// Contains: Public interfaces for ForceFeedback technology.
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _FORCEFEEDBACKCONSTANTS_H_
#define _FORCEFEEDBACKCONSTANTS_H_
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! @header ForceFeedbackConstants.h
@abstract Constants used in the public interfaces to the Force Feedback implementation in Mac OS X.
@discussion This header file contains the Effect type UUIDs, type definitions used in the API, force feedback
constants and error values used by the API.
*/
//-----------------------------------------------------------------------------
// General defines
//-----------------------------------------------------------------------------
#if !defined( DWORD )
typedef UInt32 DWORD;
typedef DWORD* LPDWORD;
#endif
#if !defined( LONG )
typedef SInt32 LONG;
typedef LONG* LPLONG;
#endif
#define FF_INFINITE 0xFFFFFFFF
#define FF_DEGREES 100
#define FF_FFNOMINALMAX 10000
#define FF_SECONDS 1000000
//-----------------------------------------------------------------------------
// Effect type UUIDs
//-----------------------------------------------------------------------------
// E559C460-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_ConstantForce_ID
@discussion UUID for a constant force effect type
*/
#define kFFEffectType_ConstantForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x60, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C461-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_RampForce_ID
@discussion UUID for a ramp force effect type
*/
#define kFFEffectType_RampForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x61, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C462-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Square_ID
@discussion UUID for a square wave effect type
*/
#define kFFEffectType_Square_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x62, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C463-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Sine_ID
@discussion UUID for a sine wave effect type
*/
#define kFFEffectType_Sine_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x63, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C464-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Sine_ID
@discussion UUID for a sine wave effect type
*/
#define kFFEffectType_Triangle_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x64, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C465-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_SawtoothUp_ID
@discussion UUID for a upwards sawtooth wave effect type
*/
#define kFFEffectType_SawtoothUp_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x65, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C466-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_SawtoothDown_ID
@discussion UUID for a downwards sawtooth wave effect type
*/
#define kFFEffectType_SawtoothDown_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x66, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C467-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Spring_ID
@discussion UUID for a spring effect type
*/
#define kFFEffectType_Spring_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x67, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C468-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Damper_ID
@discussion UUID for a damper effect type
*/
#define kFFEffectType_Damper_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x68, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C469-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Inertia_ID
@discussion UUID for an inertia effect type
*/
#define kFFEffectType_Inertia_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x69, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C46A-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Friction_ID
@discussion UUID for a friction effect type
*/
#define kFFEffectType_Friction_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x6A, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C46B-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_CustomForce_ID
@discussion UUID for a custom force effect type
*/
#define kFFEffectType_CustomForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x6B, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
//-----------------------------------------------------------------------------
// Effect definition constants
//-----------------------------------------------------------------------------
// FFEFFECT.dwFlags constants
// IMPORTANT NOTE: OBJECT IDS cannot be used to identify trigger buttons
// in FFEFFECT.dwTriggerButton, and output axes in FFEFFECT.rgdwAxes[n].
// Please use object offsets (FFJOFS_* constants), the only supported method.
// #define FFEFF_OBJECTIDS 0x00000001
#define FFEFF_OBJECTOFFSETS 0x00000002
typedef UInt32 FFCoordinateSystemFlag;
enum
{
FFEFF_CARTESIAN = 0x00000010,
FFEFF_POLAR = 0x00000020,
FFEFF_SPHERICAL = 0x00000040
};
// Effect Parameter flags for use in calls to FFEffectGetParameters() and FFEffectSetParameters()
//
typedef UInt32 FFEffectParameterFlag;
enum
{
FFEP_DURATION = 0x00000001,
FFEP_SAMPLEPERIOD = 0x00000002,
FFEP_GAIN = 0x00000004,
FFEP_TRIGGERBUTTON = 0x00000008,
FFEP_TRIGGERREPEATINTERVAL = 0x00000010,
FFEP_AXES = 0x00000020,
FFEP_DIRECTION = 0x00000040,
FFEP_ENVELOPE = 0x00000080,
FFEP_TYPESPECIFICPARAMS = 0x00000100,
FFEP_STARTDELAY = 0x00000200,
FFEP_ALLPARAMS = 0x000003FF,
FFEP_START = 0x20000000,
FFEP_NORESTART = 0x40000000,
FFEP_NODOWNLOAD = 0x80000000,
FFEB_NOTRIGGER = 0xFFFFFFFF
};
// Effect Parameter flags for use in calls to FFEffectStart()
//
typedef UInt32 FFEffectStartFlag;
enum
{
FFES_SOLO = 0x00000001,
FFES_NODOWNLOAD = 0x80000000
};
// Effect Parameter flags for use in calls to FFEffectGetEffectStatus()
//
typedef UInt32 FFEffectStatusFlag;
enum
{
FFEGES_NOTPLAYING = 0x00000000,
FFEGES_PLAYING = 0x00000001,
FFEGES_EMULATED = 0x00000002
};
// command flags for FFDeviceSendForceFeedbackCommand()
//
typedef UInt32 FFCommandFlag;
enum
{
FFSFFC_RESET = 0x00000001,
FFSFFC_STOPALL = 0x00000002,
FFSFFC_PAUSE = 0x00000004,
FFSFFC_CONTINUE = 0x00000008,
FFSFFC_SETACTUATORSON = 0x00000010,
FFSFFC_SETACTUATORSOFF = 0x00000020
};
// device state flags returned by FFDeviceGetForceFeedbackState()
//
typedef UInt32 FFState;
enum
{
FFGFFS_EMPTY = 0x00000001,
FFGFFS_STOPPED = 0x00000002,
FFGFFS_PAUSED = 0x00000004,
FFGFFS_ACTUATORSON = 0x00000010,
FFGFFS_ACTUATORSOFF = 0x00000020,
FFGFFS_POWERON = 0x00000040,
FFGFFS_POWEROFF = 0x00000080,
FFGFFS_SAFETYSWITCHON = 0x00000100,
FFGFFS_SAFETYSWITCHOFF = 0x00000200,
FFGFFS_USERFFSWITCHON = 0x00000400,
FFGFFS_USERFFSWITCHOFF = 0x00000800,
FFGFFS_DEVICELOST = 0x80000000
};
// axis and button "field offsets",
// used in
// FFEFFECT.dwTriggerButton
// FFEFFECT.rgdwAxes[n]
#define FFJOFS_X 0
#define FFJOFS_Y 4
#define FFJOFS_Z 8
#define FFJOFS_RX 12
#define FFJOFS_RY 16
#define FFJOFS_RZ 20
#define FFJOFS_SLIDER(n) (24 + (n) * sizeof(LONG))
#define FFJOFS_POV(n) (32 + (n) * sizeof(DWORD))
#define FFJOFS_BUTTON(n) (48 + (n))
#define FFJOFS_BUTTON0 FFJOFS_BUTTON(0)
#define FFJOFS_BUTTON1 FFJOFS_BUTTON(1)
#define FFJOFS_BUTTON2 FFJOFS_BUTTON(2)
#define FFJOFS_BUTTON3 FFJOFS_BUTTON(3)
#define FFJOFS_BUTTON4 FFJOFS_BUTTON(4)
#define FFJOFS_BUTTON5 FFJOFS_BUTTON(5)
#define FFJOFS_BUTTON6 FFJOFS_BUTTON(6)
#define FFJOFS_BUTTON7 FFJOFS_BUTTON(7)
#define FFJOFS_BUTTON8 FFJOFS_BUTTON(8)
#define FFJOFS_BUTTON9 FFJOFS_BUTTON(9)
#define FFJOFS_BUTTON10 FFJOFS_BUTTON(10)
#define FFJOFS_BUTTON11 FFJOFS_BUTTON(11)
#define FFJOFS_BUTTON12 FFJOFS_BUTTON(12)
#define FFJOFS_BUTTON13 FFJOFS_BUTTON(13)
#define FFJOFS_BUTTON14 FFJOFS_BUTTON(14)
#define FFJOFS_BUTTON15 FFJOFS_BUTTON(15)
#define FFJOFS_BUTTON16 FFJOFS_BUTTON(16)
#define FFJOFS_BUTTON17 FFJOFS_BUTTON(17)
#define FFJOFS_BUTTON18 FFJOFS_BUTTON(18)
#define FFJOFS_BUTTON19 FFJOFS_BUTTON(19)
#define FFJOFS_BUTTON20 FFJOFS_BUTTON(20)
#define FFJOFS_BUTTON21 FFJOFS_BUTTON(21)
#define FFJOFS_BUTTON22 FFJOFS_BUTTON(22)
#define FFJOFS_BUTTON23 FFJOFS_BUTTON(23)
#define FFJOFS_BUTTON24 FFJOFS_BUTTON(24)
#define FFJOFS_BUTTON25 FFJOFS_BUTTON(25)
#define FFJOFS_BUTTON26 FFJOFS_BUTTON(26)
#define FFJOFS_BUTTON27 FFJOFS_BUTTON(27)
#define FFJOFS_BUTTON28 FFJOFS_BUTTON(28)
#define FFJOFS_BUTTON29 FFJOFS_BUTTON(29)
#define FFJOFS_BUTTON30 FFJOFS_BUTTON(30)
#define FFJOFS_BUTTON31 FFJOFS_BUTTON(31)
// defines for FFDeviceGetForceFeedbackProperty() and FFDeviceSetForceFeedbackProperty()
//
typedef UInt32 FFProperty;
enum
{
FFPROP_FFGAIN = 1,
FFPROP_AUTOCENTER = 3
};
// flags for FFDeviceSetCooperativeLevel()
//
typedef UInt32 FFCooperativeLevelFlag;
enum
{
FFSCL_EXCLUSIVE = 0x00000001,
FFSCL_NONEXCLUSIVE = 0x00000002,
FFSCL_FOREGROUND = 0x00000004,
FFSCL_BACKGROUND = 0x00000008
};
// types used in FFCAPABILITIES structure
//
typedef UInt32 FFCapabilitiesEffectType;
enum
{
FFCAP_ET_CONSTANTFORCE = 0x00000001,
FFCAP_ET_RAMPFORCE = 0x00000002,
FFCAP_ET_SQUARE = 0x00000004,
FFCAP_ET_SINE = 0x00000008,
FFCAP_ET_TRIANGLE = 0x00000010,
FFCAP_ET_SAWTOOTHUP = 0x00000020,
FFCAP_ET_SAWTOOTHDOWN = 0x00000040,
FFCAP_ET_SPRING = 0x00000080,
FFCAP_ET_DAMPER = 0x00000100,
FFCAP_ET_INERTIA = 0x00000200,
FFCAP_ET_FRICTION = 0x00000400,
FFCAP_ET_CUSTOMFORCE = 0x00000800
};
typedef UInt32 FFCapabilitiesEffectSubType;
enum
{
FFCAP_ST_KINESTHETIC = 1,
FFCAP_ST_VIBRATION = 2
};
//-----------------------------------------------------------------------------
// Error return values
//-----------------------------------------------------------------------------
/*!
@defined FF_OK
@discussion The operation completed successfully.
*/
#define FF_OK S_OK
/*!
@defined FF_FALSE
@discussion The operation did not complete successfully.
*/
#define FF_FALSE S_FALSE
/*!
@defined FF_DOWNLOADSKIPPED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but the effect was not
* downloaded because the FFEP_NODOWNLOAD flag was passed.
*/
#define FF_DOWNLOADSKIPPED ((HRESULT)0x00000003L)
/*!
@defined FF_EFFECTRESTARTED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but in order to change
* the parameters, the effect needed to be restarted.
*/
#define FF_EFFECTRESTARTED ((HRESULT)0x00000004L)
/*!
@defined FF_TRUNCATED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but some of them were
* beyond the capabilities of the device and were truncated.
*/
#define FF_TRUNCATED ((HRESULT)0x00000008L)
/*!
@defined FF_TRUNCATEDANDRESTARTED
* @discussion
* Equal to FF_EFFECTRESTARTED | FF_TRUNCATED.
*/
#define FF_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL)
/*!
@defined FFERR_DEVICENOTREG
* @discussion
* The device or device instance or effect is not registered.
*/
#define FFERR_DEVICENOTREG REGDB_E_CLASSNOTREG
/*!
@defined FFERR_INVALIDPARAM
* @discussion
* An invalid parameter was passed to the returning function,
* or the object was not in a state that admitted the function
* to be called.
*/
#define FFERR_INVALIDPARAM E_INVALIDARG
/*!
@defined FFERR_NOINTERFACE
* @discussion
* The specified interface is not supported by the object
*/
#define FFERR_NOINTERFACE E_NOINTERFACE
/*!
@defined FFERR_GENERIC
* @discussion
* An undetermined error occurred.
*/
#define FFERR_GENERIC E_FAIL
/*!
@defined FFERR_OUTOFMEMORY
* @discussion
* Couldn't allocate sufficient memory to complete the caller's request.
*/
#define FFERR_OUTOFMEMORY E_OUTOFMEMORY
/*!
@defined FFERR_UNSUPPORTED
* @discussion
* The function called is not supported at this time
*/
#define FFERR_UNSUPPORTED E_NOTIMPL
#ifndef E_PENDING
/*!
@defined E_PENDING
* @discussion
* Data is not yet available.
*/
#define E_PENDING 0x8000000AL
#endif
/*!
@defined FFERR_DEVICEFULL
* @discussion
* The device is full.
*/
#define FFERR_DEVICEFULL 0x80040201L
/*!
@defined FFERR_MOREDATA
* @discussion
* Not all the requested information fit into the buffer.
*/
#define FFERR_MOREDATA 0x80040202L
/*!
@defined FFERR_NOTDOWNLOADED
* @discussion
* The effect is not downloaded.
*/
#define FFERR_NOTDOWNLOADED 0x80040203L
/*!
@defined FFERR_HASEFFECTS
* @discussion
* The device cannot be reinitialized because there are still effects
* attached to it.
*/
#define FFERR_HASEFFECTS 0x80040204L
/*!
@defined FFERR_INCOMPLETEEFFECT
* @discussion
* The effect could not be downloaded because essential information
* is missing. For example, no axes have been associated with the
* effect, or no type-specific information has been created.
*/
#define FFERR_INCOMPLETEEFFECT 0x80040206L
/*!
@defined FFERR_EFFECTPLAYING
* @discussion
* An attempt was made to modify parameters of an effect while it is
* playing. Not all hardware devices support altering the parameters
* of an effect while it is playing.
*/
#define FFERR_EFFECTPLAYING 0x80040208L
/*!
@defined FFERR_UNPLUGGED
* @discussion
* The operation could not be completed because the device is not
* plugged in.
*/
#define FFERR_UNPLUGGED 0x80040209L
//
// Mac OS X specific
//
/*!
@defined FFERR_INVALIDDOWNLOADID
* @discussion
* The effect index provided by the API in downloadID is not recognized by the
* IOForceFeedbackLib driver.
*/
#define FFERR_INVALIDDOWNLOADID 0x80040300
/*!
@defined FFERR_DEVICEPAUSED
* @discussion
* When the device is paused via a call to FFDeviceSendForceFeedbackCommand(),
* other operations such as modifying existing effect parameters and creating
* new effects are not allowed.
*/
#define FFERR_DEVICEPAUSED 0x80040301
/*!
@defined FFERR_INTERNAL
* @discussion
* The IOForceFededbackLib driver has detected an internal fault. Often this
* occurs because of an unexpected internal code path.
*/
#define FFERR_INTERNAL 0x80040302
/*!
@defined FFERR_EFFECTTYPEMISMATCH
* @discussion
* The IOForceFededbackLib driver has received an effect modification request
* whose basic type does not match the defined effect type for the given effect.
*/
#define FFERR_EFFECTTYPEMISMATCH 0x80040303
/*!
@defined FFERR_UNSUPPORTEDAXIS
* @discussion
* The effect includes one or more axes that the device does not support.
*/
#define FFERR_UNSUPPORTEDAXIS 0x80040304
/*!
@defined FFERR_NOTINITIALIZED
* @discussion
* This object has not been initialized
*/
#define FFERR_NOTINITIALIZED 0x80040305
/*!
@defined FFERR_EFFECTTYPENOTSUPPORTED
* @discussion
* The effect type requested is not explicitly supported by the particular device.
*/
#define FFERR_EFFECTTYPENOTSUPPORTED 0x80040306
/*!
@defined FFERR_DEVICERELEASED
* @discussion
* The device has been released.
*/
#define FFERR_DEVICERELEASED 0x80040307
#ifdef __cplusplus
}
#endif
#endif // _FORCEFEEDBACKCONSTANTS_H_

View File

@ -0,0 +1,447 @@
//-----------------------------------------------------------------------------
// File: IOForceFeedbackLib.h
// Contains: Public interfaces for the Force Feedback Plugin architecture .
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _IOFORCEFEEDBACKLIB_H
#define _IOFORCEFEEDBACKLIB_H
#if PRAGMA_ONCE
#pragma once
#endif
/*! @header IOForceFeedbackLib.h
@abstract Public Interfaces and constants used to develop Force Feedback plugIns.
@discussion A force feedback device manufacturer might need to implement a plug in
to allow the Force Feedback Library to control the device. This header
file describes the functions that need to be implemented. This interface definition
follows Microsoft Windoes IDirectInputEffectDriver definition wherever it makes sense to do so.
Certain functions may contain more or fewer parameters than the Windows version
*/
#include <sys/cdefs.h>
__BEGIN_DECLS
#include <CoreFoundation/CoreFoundation.h>
#if COREFOUNDATION_CFPLUGINCOM_SEPARATE
#include <CoreFoundation/CFPlugInCOM.h>
#endif
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <IOKit/IOTypes.h>
#include <ForceFeedback/ForceFeedback.h>
//====================================================================================================================
// The Version of the FF PlugIn API
//====================================================================================================================
//
enum {
kFFPlugInAPIMajorRev = 1,
kFFPlugInAPIMinorAndBugRev = 0,
kFFPlugInAPIStage = finalStage,
kFFPlugInAPINonRelRev = 0
};
//====================================================================================================================
// Defines
//====================================================================================================================
//
#define FFDEVICESTATE ForceFeedbackDeviceState
#define PFFDEVICESTATE ForceFeedbackDeviceStatePtr
// F4545CE5-BF5B-11D6-A4BB-0003933E3E3E
#define kIOForceFeedbackLibTypeID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xF4, 0x54, 0x5C, 0xE5, 0xBF, 0x5B, 0x11, 0xD6, \
0xA4, 0xBB, 0x00, 0x03, 0x93, 0x3E, 0x3E, 0x3E)
// 1C7C5850-BB6A-11D6-B75F-003065FBE6B0
#define kIOForceFeedbackDeviceInterfaceID CFUUIDGetConstantUUIDWithBytes(NULL, \
0x1C, 0x7C, 0x58, 0x50, 0xBB, 0x6A, 0x11, 0xD6, \
0xB7, 0x5F, 0x00, 0x30, 0x65, 0xFB, 0xE6, 0xB0)
//====================================================================================================================
// Structs
//====================================================================================================================
//
struct ForceFeedbackDeviceState
{
UInt32 dwSize;
UInt32 dwState;
UInt32 dwLoad;
};
typedef struct ForceFeedbackDeviceState ForceFeedbackDeviceState;
typedef ForceFeedbackDeviceState * ForceFeedbackDeviceStatePtr;
struct ForceFeedbackVersion
{
NumVersion apiVersion;
NumVersion plugInVersion;
};
typedef struct ForceFeedbackVersion ForceFeedbackVersion;
typedef ForceFeedbackVersion * ForceFeedbackVersionPtr;
//====================================================================================================================
// Types
//====================================================================================================================
//
typedef UInt32 FFEffectDownloadID;
//====================================================================================================================
//
// ForceFeedback Device Interface Functions available in version 1.0 of architecture
//
//====================================================================================================================
//
#define IOFORCEFEEDBACKDEVICE_FUNCS_100 \
\
HRESULT (*ForceFeedbackGetVersion)( void * self, \
ForceFeedbackVersion * version); \
\
HRESULT (*InitializeTerminate)( void * self, \
NumVersion forceFeedbackAPIVersion,\
io_object_t hidDevice, \
bool begin ); \
\
HRESULT (*DestroyEffect)( void * self, \
FFEffectDownloadID downloadID ); \
\
HRESULT (*DownloadEffect)( void * self, \
CFUUIDRef effectType, \
FFEffectDownloadID * pDownloadID, \
FFEFFECT * pEffect, \
FFEffectParameterFlag flags ); \
\
HRESULT (*Escape)( void * self, \
FFEffectDownloadID downloadID, \
FFEFFESCAPE * pEscape ); \
\
HRESULT (*GetEffectStatus)( void * self, \
FFEffectDownloadID downloadID, \
FFEffectStatusFlag * pStatusCode ); \
\
HRESULT (*GetForceFeedbackCapabilities)( void * self, \
FFCAPABILITIES * pCapabilities ); \
\
HRESULT (*GetForceFeedbackState)( void * self, \
ForceFeedbackDeviceState * pDeviceState ); \
\
HRESULT (*SendForceFeedbackCommand)( void * self, \
FFCommandFlag state ); \
\
HRESULT (*SetProperty)( void * self, \
FFProperty property, \
void * pValue ); \
\
HRESULT (*StartEffect)( void * self, \
FFEffectDownloadID downloadID, \
FFEffectStartFlag mode, \
UInt32 iterations ); \
\
HRESULT (*StopEffect)( void * self, \
FFEffectDownloadID downloadID );
//====================================================================================================================
//
// END OF DeviceInterface Functions available in version 1.0 of this API
//
//====================================================================================================================
//
struct IOForceFeedbackDeviceInterface {
IUNKNOWN_C_GUTS;
IOFORCEFEEDBACKDEVICE_FUNCS_100
};
typedef struct IOForceFeedbackDeviceInterface IOForceFeedbackDeviceInterface;
typedef IOForceFeedbackDeviceInterface * IOForceFeedbackDeviceInterfacePtr;
//====================================================================================================================
//
// ¥¥¥¥¥ The following is #ifdef out. It is here so that we can header doc this file without intruding in its
// ¥¥¥¥¥ readability.
//
//====================================================================================================================
//
#if 0
struct IOForceFeedbackDeviceInterface {
IUNKNOWN_C_GUTS;
/*! @function ForceFeedbackGetVersion
@abstract This function is used to determine driver and API version information.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param version Pointer to ForceFeedbackVersion structure that is to receive the required info. See the structure description for details.
@result Returns FF_OK if successful, or an error value otherwise.
*/
HRESULT (*ForceFeedbackGetVersion) (void * self, ForceFeedbackVersion * version);
/*! @function InitializeTerminate
@abstract This function is used to "create and destroy" particular device instances. It provides the FF plug-in driver with all the necessary start-up parameters.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param forceFeedbackAPIVersion The version number of FF API that loaded the effect driver. The plugIn should check that the major version of the forceFeedbackAPI version is the same as the major version of the API at the time the plugIn was compiled. If the major versions are different, then the plugIn API has changed and the plugIn will NOT be compatible with it.
<br>
If begin is false, this parameter is ignored.
@param hidDevice A device object that can be used by the FF plug-in to establish a connection to and communicate with the device. The caller will release the hidDevice device object with a call to IOObjectRelease() once the FF plug-in completes its InitializeTerminate processing, so a FF plug-in implementation should not make a copy of the io_object_t variable with the intention of using it outside the context of this call.
<br>
If begin is false, this parameter is ignored. (You can pass NULL.)
@param begin Nonzero if access to the device is beginning. Zero if the access to the device is ending. The FF API will call InitializeTerminate( begin=TRUE) when a FF device is first selected for use, and InitializeTerminate( begin=false) when the FF device is no longer needed.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br>
*/
HRESULT (*InitializeTerminate)(void * self, NumVersion forceFeedbackAPIVersion, io_object_t hidDevice, bool begin );
/*! @function DestroyEffect
@abstract This function commands the device to "destroy" a currently downloaded effect. The effect ID and any data that is associated with the effect are freed and available for reallocation.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect ID that was obtained from the device when the effect was downloaded.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br>
*/
HRESULT (*DestroyEffect)(void * self, FFEffectDownloadID downloadID );
/*! @function DownloadEffect
@abstract This function sends an effect to the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param effectType Indicates the type of effect being created. Valid UUIDs are listed as kFFEffectType_* constants in the ForceFeedbackConstants.h file. (Supported effect types include Sine, Square, Triangle, SawtoothUp, SawtoothDown, Constant, Spring, Damper, etc.).
@param pDownloadID On entry, this parameter points to the handle of the effect being downloaded. If the parameter points to a zero, then a new effect is downloaded. On exit, the FFEffectDownloadID pointed to by this parameter contains the new effect handle. On failure, the FFEffectDownloadID pointed to by this parameter is set to zero if the effect is lost, or left alone if the effect is still valid with its old parameters. Note that zero is never a valid effect handle.
@param pEffect The new parameters for the effect.
<br>
IMPORTANT NOTE: Unlike the IDirectInputEffectDriver specification, the axis and button values are NOT converted to object identifiers before they are handed over to the driver. In this case, the only supported method used to assign triggers and output axes is through object offsets, defined by the FFJOFS_* constants. Therefore, if a button is assigned to trigger an effect, FFEFFECT.dwTriggerButton will contain a constant of the form FFJOFS_BUTTONn. Similarly, output axes will be identified in FFEFFECT.rgdwAxes[n] as FFJOFS_X, FFJOFS_Y, etc.
@param flags Specifies which portions of the effect information have changed from the effect already on the device. This information is passed to drivers to allow for the optimization of effect modification. If an effect is being modified, a driver may be able to update the effect in its original position and transmit to the device only the information that has changed. Drivers are not, however, required to implement this optimization. All members of the FFEFFECT structure that are pointed to by the pEffect parameter are valid, and a driver may choose simply to update all parameters of the effect at each download. There may be zero, one, or more of the following:
<br>
<br> FFEP_DURATION
<br> Indicates the dwDuration member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_SAMPLEPERIOD
<br> Indicates the dwSamplePeriod member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_GAIN
<br> Indicates the dwGain member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_TRIGGERBUTTON
<br> Indicates the dwTriggerButton member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_TRIGGERREPEATINTERVAL
<br> Indicates the dwTriggerRepeatInterval member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_AXES
<br> Indicates the cAxes and rgdwAxes members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download.
<br>
<br> FFEP_DIRECTION
<br> Indicates the cAxes and rglDirection members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download. (The dwFlags member of the FFEFFECT structure specifies, through FFEFF_CARTESIAN or FFEFF_POLAR, the coordinate system in which the values should be interpreted.)
<br>
<br> FFEP_ENVELOPE
<br> Indicates the lpEnvelope member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download. If this flag is set and the lpEnvelope member is a NULL pointer, then the effect is being created with no envelope, or the existing envelope is being deleted.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> Indicates the cbTypeSpecificParams and lpTypeSpecificParams members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download.
<br>
<br> FFEP_STARTDELAY
<br> Indicates the dwStartDelay member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_START
<br> Indicates that the effect is to be restarted from the beginning after the parameters of the effect have been updated. Note that the FFEP_NODOWNLOAD flag overrides the FFEP_START flag.
<br>
<br> FFEP_NORESTART
<br> If this flag is not specified, the effect device driver is permitted to restart the effect if doing so is necessary to change the specified parameters. Note that the FFEP_NODOWNLOAD and FFEP_START flags override this flag.
<br>
<br> FFEP_NODOWNLOAD
<br> Suppresses the automatic download that is normally performed after the parameters are updated. If this flag is set, the driver should validate parameters without performing an actual download.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
*/
HRESULT (*DownloadEffect)( void * self, CFUUIDRef effectType, FFEffectDownloadID * pDownloadID,
FFEFFECT * pEffect, FFEffectParameterFlag flags );
/*! @function Escape
@abstract This function escapes to the driver. This method is called in response to an application invoking the FFEffectEscape or FFDeviceEscape methods.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Specifies the effect at which the command is directed, or zero if the command is directed at the device itself and not any particular effect.
@param pEscape Pointer to a FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of output buffer bytes actually used.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_UNSUPPORTED
<br>
*/
HRESULT (*Escape)( void * self, FFEffectDownloadID downloadID, FFEFFESCAPE * pEscape );
/*! @function GetEffectStatus
@abstract This function returns the device effect's status.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be queried.
@param pStatusCode Receives the effect status. The FFEffectStatusFlag pointed to by this parameter should be filled in with one of the following values:
<br>
<br> FFEGES_PLAYING
<br> The effect is still playing.
<br>
<br> FFEGES_NOTPLAYING
<br> The effect is not playing.
@result Returns FF_OK.
*/
HRESULT (*GetEffectStatus)( void * self, FFEffectDownloadID downloadID, FFEffectStatusFlag * pStatusCode );
/*! @function GetForceFeedbackCapabilities
@abstract This function escapes to the driver. This method is called in response to an application invoking the FFEffectEscape or FFDevicEscape methods.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param pCapabilities Pointer to a FFCAPABILITIES structure that should be filled in with version information describing the hardware, firmware, and driver.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_NOINTERFACE
<br>
*/
HRESULT (*GetForceFeedbackCapabilities)( void * self, FFCAPABILITIES * pCapabilities );
/*! @function GetForceFeedbackState
@abstract This function returns the state of the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param pDeviceState Pointer to a ForceFeedbackDeviceState structure that receives the device state. FF API sets the dwSize member of the ForceFeedbackDeviceState structure to sizeof(ForceFeedbackDeviceState) before calling this method.
@result Returns FF_OK.
*/
HRESULT (*GetForceFeedbackState)( void * self, ForceFeedbackDeviceState * pDeviceState );
/*! @function SendForceFeedbackCommand
@abstract This function sends a command to the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param state Indicates the command being sent. That command can be one of the following:
<br>
<br> FFSFFC_RESET
<br> Indicates that playback of any active effects should be been stopped and that all effects should be removed from the device. Once the device has been reset, all effects are no longer valid and must be re-created.
<br>
<br> FFSFFC_STOPALL
<br> Indicates that playback of all effects should be stopped. Sending the FFSFFC_STOPALL command is equivalent to invoking the FFEffect_Stop method on all effects that are playing. If the device is in a paused state, the device driver is permitted to lose the paused state.
<br>
<br> FFSFFC_PAUSE
<br> Indicates that playback of all effects should be paused. When effects are paused, time "stops" until the FFSFFC_CONTINUE command is sent. For example, suppose an effect of five seconds' duration is started. After one second, all effects are paused. After two more seconds, all effects are continued. The effect should then play for four additional seconds. While a force-feedback device is paused, starting a new effect or modifying existing ones can cause the paused state to be lost.
<br>
<br> FFSFFC_CONTINUE
<br> Indicates that playback should be resumed at the point at which it was interrupted for those effects that were paused by a previous FFSCFFC_PAUSE command.
<br>
<br> FFSFFC_SETACTUATORSON
<br> Indicates that the device's force-feedback actuators should be enabled.
<br>
<br> FFSFFC_SETACTUATORSOFF
<br> Indicates that the device's force-feedback actuators should be disabled. If successful, force-feedback effects are "muted". Note that time continues to elapse while actuators are off. For example, suppose an effect of five seconds' duration is started. After one second, actuators are turned off. After two more seconds, actuators are turned back on. The effect should then play for two additional seconds.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_INVALIDPARAM
<br>
*/
HRESULT (*SendForceFeedbackCommand)( void * self, FFCommandFlag state );
/*! @function SetProperty
@abstract This function sets properties that define the device behavior.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param property The following property values are defined for a FF device:
<br>
<br> FFPROP_AUTOCENTER
<br> Specifies whether the actuated FF axes are self-centering. This property controls the deviceÕs Òdefault centering springÓ.
<br> The pValue member points to a UInt32 and can be one of the following values.
<br>
<br> 0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
<br>
<br> 1 - ON: The device should automatically center when the user releases the device.
<br>
<br> Not all devices support the autocenter property.
<br>
<br> FFPROP_FFGAIN
<br> Sets the gain for the device.
<br>
<br> The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
<br>
<br> Setting a gain value is useful when an application wants to scale down the strength of all force-feedback effects uniformly, based on user preferences.
@param pValue Address of the location where the property value is to be read. This function will assume that the data is valid, and of the correct type.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
*/
HRESULT (*SetProperty)( void * self, FFProperty property, void * pValue );
/*! @function StartEffect
@abstract This function commands the device to play back an effect that was previously loaded.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be played.
@param mode Specifies how the effect is to affect other effects. Only the mode listed below can be used; all other modes are reserved. For example, the driver never receives the FFES_NODOWNLOAD flag because it is managed by the FF API and not the PlugIn driver. This parameter can be zero, one, or more of the following flags:
<br>
<br> FFES_SOLO
<br> Indicates that all other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects that have already started on the device.
@param iterations Specifies the number of times to perform the effect. If the value is FF_INFINITE, then the effect should be repeated until explicitly stopped or paused.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_GENERIC
<br> FFERR_INVALIDDOWNLOADID
<br>
*/
HRESULT (*StartEffect)( void * self, FFEffectDownloadID downloadID, FFEffectStartFlag mode, UInt32 iterations );
/*! @function StopEffect
@abstract This function commands the device to stop an effect that was previously started.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be stopped.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_GENERIC
<br> FFERR_INVALIDDOWNLOADID
<br>
*/
HRESULT (*StopEffect)( void * self, UInt32 downloadID );
};
#endif // #if 0 ¥¥¥ Used for header doc'ing only
__END_DECLS
#endif /* ! _IOFORCEFEEDBACKLIB_H */

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>ForceFeedback</string>
<key>CFBundleGetInfoString</key>
<string>1.0.0, Copyright Apple Computer, Inc. 2002</string>
<key>CFBundleIdentifier</key>
<string>com.apple.ForceFeedback</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ForceFeedback Framework</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>70</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>ProjectName</key>
<string>ForceFeedback</string>
<key>ReleaseStatus</key>
<string>Beta</string>
<key>SourceVersion</key>
<string>1000305</string>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,816 @@
//-----------------------------------------------------------------------------
// File: ForceFeedback.h
// Contains: Public interfaces for ForceFeedback technology.
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _FORCEFEEDBACK_H_
#define _FORCEFEEDBACK_H_
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! @header ForceFeedback.h
@abstract Public Interfaces to the Force Feedback implementation in Mac OS X.
@discussion The Force Feedback API allows developers to control Force Feedback devices attached to the system. It is a distilled version of the Force Feedback functionality found in Microsoft's DirectInput API. Developers familiar with that API should find this API to be similar.
*/
#include <CoreFoundation/CoreFoundation.h>
#if COREFOUNDATION_CFPLUGINCOM_SEPARATE
#include <CoreFoundation/CFPlugInCOM.h>
#endif
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <IOKit/IOTypes.h>
#include <ForceFeedback/ForceFeedbackConstants.h>
//-----------------------------------------------------------------------------
// The Version of the FF API
//-----------------------------------------------------------------------------
enum {
kFFAPIMajorRev = 1,
kFFAPIMinorAndBugRev = 0,
kFFAPIStage = finalStage,
kFFAPINonRelRev = 0
};
//-----------------------------------------------------------------------------
// Effect definition structures
//-----------------------------------------------------------------------------
struct FFCONSTANTFORCE
{
LONG lMagnitude;
};
typedef struct FFCONSTANTFORCE FFCONSTANTFORCE;
typedef FFCONSTANTFORCE * PFFCONSTANTFORCE;
struct FFRAMPFORCE
{
LONG lStart;
LONG lEnd;
};
typedef struct FFRAMPFORCE FFRAMPFORCE;
typedef FFRAMPFORCE * PFFRAMPFORCE;
struct FFPERIODIC
{
DWORD dwMagnitude;
LONG lOffset;
DWORD dwPhase;
DWORD dwPeriod;
};
typedef struct FFPERIODIC FFPERIODIC;
typedef FFPERIODIC * PFFPERIODIC;
struct FFCONDITION
{
LONG lOffset;
LONG lPositiveCoefficient;
LONG lNegativeCoefficient;
DWORD dwPositiveSaturation;
DWORD dwNegativeSaturation;
LONG lDeadBand;
};
typedef struct FFCONDITION FFCONDITION;
typedef FFCONDITION * PFFCONDITION;
struct FFCUSTOMFORCE
{
DWORD cChannels;
DWORD dwSamplePeriod;
DWORD cSamples;
LPLONG rglForceData;
};
typedef struct FFCUSTOMFORCE FFCUSTOMFORCE;
typedef FFCUSTOMFORCE * PFFCUSTOMFORCE;
struct FFENVELOPE
{
DWORD dwSize; /* sizeof(FFENVELOPE) */
DWORD dwAttackLevel;
DWORD dwAttackTime; /* Microseconds */
DWORD dwFadeLevel;
DWORD dwFadeTime; /* Microseconds */
};
typedef struct FFENVELOPE FFENVELOPE;
typedef FFENVELOPE * PFFENVELOPE;
// IMPORTANT NOTE: OBJECT IDS cannot be used to identify trigger buttons
// in FFEFFECT.dwTriggerButton, and output axes in FFEFFECT.rgdwAxes[n].
// Please use object offsets (FFJOFS_* constants), the only supported method.
struct FFEFFECT
{
DWORD dwSize; /* sizeof(FFEFFECT) */
DWORD dwFlags; /* FFEFF_* */
DWORD dwDuration; /* Microseconds */
DWORD dwSamplePeriod; /* Microseconds */
DWORD dwGain;
DWORD dwTriggerButton; /* or FFEB_NOTRIGGER */
DWORD dwTriggerRepeatInterval; /* Microseconds */
DWORD cAxes; /* Number of axes */
LPDWORD rgdwAxes; /* Array of axes */
LPLONG rglDirection; /* Array of directions */
PFFENVELOPE lpEnvelope; /* Optional */
DWORD cbTypeSpecificParams; /* Size of params */
void* lpvTypeSpecificParams; /* Pointer to params */
DWORD dwStartDelay; /* Microseconds */
};
typedef struct FFEFFECT FFEFFECT;
typedef FFEFFECT * PFFEFFECT;
struct FFEFFESCAPE
{
DWORD dwSize;
DWORD dwCommand;
void* lpvInBuffer;
DWORD cbInBuffer;
void* lpvOutBuffer;
DWORD cbOutBuffer;
};
typedef struct FFEFFESCAPE FFEFFESCAPE;
typedef FFEFFESCAPE * PFFEFFESCAPE;
// NOTE: this structure has no DirectInput equivalent
struct FFCAPABILITIES
{
NumVersion ffSpecVer; // Version of specification supported by the driver
UInt32 supportedEffects; // FFCAP_ET_*; including emulated effects
UInt32 emulatedEffects; // FFCAP_ET_*; driver-emulated effects
UInt32 subType; // FFCAP_TYPE_*
UInt32 numFfAxes;
UInt8 ffAxes[32];
UInt32 storageCapacity; // number of effects that can be stored
// by the driver/device
UInt32 playbackCapacity; // number of effects that can be _simultaneously_
// played back by the driver/device
NumVersion firmwareVer; // device firmware version, vendor-defined
NumVersion hardwareVer; // hardware version, vendor-defined
NumVersion driverVer; // driver version, vendor-defined
};
typedef struct FFCAPABILITIES FFCAPABILITIES;
typedef FFCAPABILITIES * PFFCAPABILITIES;
//-----------------------------------------------------------------------------
// Object reference pointers
//-----------------------------------------------------------------------------
// FFDeviceObjectReference and FFEffectObjectReference are opaque handles
// to objects created and maintained by the FF API.
// A FFDeviceObjectReference is obtained through a call to FFCreateDevice and
// refers to a specific attached device supporting force feedback. This
// reference may be passed to any of the "FFDevice" functions (below). When
// you are through with it, call FFReleaseDevice to release the memory.
// Similarly, a FFEffectObjectReference is obtained through a call to
// FFDeviceCreateEffect and refers to a created force feedback effect on a
// particular device. This reference may be passed to any of the "FFEffect"
// functions. Call FFDeviceReleaseEffect to unload the effect and clean up
// its memory. - Jeff Mallett 9/25/02
//
typedef struct {} __FFDHIDDEN, * FFDeviceObjectReference;
typedef struct {} __FFEHIDDEN, * FFEffectObjectReference;
//-----------------------------------------------------------------------------
// FF (general) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFCreateDevice
@abstract Creates a new API device object from an OS object in preparation to use the device for force feedback.
@param hidDevice Pointer to a HID device object.
@param pdeviceReference Address of a variable to receive an opaque reference handle to a new device object. This reference can be used in subsequent calls to FFDevice* functions
@result If the method succeeds, and the device supports FF, the return value is FF_OK.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br> FFERR_INTERNAL
<br>
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object.
*/
extern HRESULT
FFCreateDevice(
io_service_t hidDevice,
FFDeviceObjectReference * pDeviceReference
);
/*! @function FFReleaseDevice
@abstract Disposes of an API device object created with FFCreateDevice.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@result If the method succeeds, and the device supports FF, the return value is FF_OK.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br>
@discussion
*/
extern HRESULT
FFReleaseDevice(
FFDeviceObjectReference deviceReference
);
/*! @function FFIsForceFeedback
@abstract Used to determine if a particular device provided by HID Manager is a force feedback device.
@param hidDevice Pointer to a HID device object to be tested for force feedback support.
@result If the method succeeds, and the device supports FF, the return value is FF_OK. If the method succeeds, and the device does not support FF, the return value is FFERR_NOINTERFACE. If the method fails, the return value is FFERR_INVALIDPARAM
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object.
*/
extern HRESULT
FFIsForceFeedback(
io_service_t hidDevice
);
//-----------------------------------------------------------------------------
// FFDevice (device related) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFDeviceCreateEffect
@abstract Creates and initializes an instance of an effect identified by the effect UUID on the device.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param uuidRef Reference to the UUID identifying the effect to be created. Only predefined effect UUIDs are accepted. The following standard effect UUIDs are defined:
<br>
<br> kFFEffectType_ConstantForce_ID
<br> kFFEffectType_RampForce_ID
<br> kFFEffectType_Square_ID
<br> kFFEffectType_Sine_ID
<br> kFFEffectType_Triangle_ID
<br> kFFEffectType_SawtoothUp_ID
<br> kFFEffectType_SawtoothDown_ID
<br> kFFEffectType_Spring_ID
<br> kFFEffectType_Damper_ID
<br> kFFEffectType_Inertia_ID
<br> kFFEffectType_Friction_ID
<br> kFFEffectType_CustomForce_ID
<br>
<br>
@param pEffectDefinition Pointer to FFEFFECT structure that provides parameters for the created effect. This parameter is optional. If it is NULL, the effect object is created without parameters. The application must then call the FFEffectSetParameters function to set the parameters of the effect before it can download the effect.
@param pEffectReference Address of a variable to receive an opaque reference handle to a new effect object. This reference can be used in subsequent calls to FFEffect* functions.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTEDAXIS
<br> FFERR_OUTOFMEMORY
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
@discussion When you are finished with the effect, FFReleaseEffect must be called on the reference received in this function to dispose of the API effect object.
*/
extern HRESULT
FFDeviceCreateEffect(
FFDeviceObjectReference deviceReference,
CFUUIDRef uuidRef,
FFEFFECT * pEffectDefinition,
FFEffectObjectReference * pEffectReference
);
/*! @function FFDeviceReleaseEffect
@abstract Disposes of an API effect object created with FFDeviceCreateEffect.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFDeviceReleaseEffect(
FFDeviceObjectReference deviceReference,
FFEffectObjectReference effectReference
);
/*! @function FFDeviceEscape
@abstract Sends a hardware-specific command to the device.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param pFFEffectEscape Pointer to FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTED
<br>
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver.
*/
extern HRESULT
FFDeviceEscape(
FFDeviceObjectReference deviceReference,
FFEFFESCAPE * pFFEffectEscape
);
/*! @function FFDeviceGetForceFeedbackState
@abstract Retrieves the state of the device's force feedback system.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param pFFState Location for flags that describe the current state of the device's force feedback system.
The value is a combination of the following constants:
<br>
<br> FFGFFS_ACTUATORSOFF
<br> The device's force feedback actuators are disabled.
<br>
<br> FFGFFS_ACTUATORSON
<br> The device's force feedback actuators are enabled.
<br>
<br> FFGFFS_DEVICELOST
<br> The device suffered an unexpected failure and is in an indeterminate state. It must be reset either by unacquiring and reacquiring the device, or by sending a FFSFFC_RESET command.
<br>
<br> FFGFFS_EMPTY
<br> The device has no downloaded effects.
<br>
<br> FFGFFS_PAUSED
<br> Playback of all active effects has been paused.
<br>
<br> FFGFFS_POWEROFF
<br> The force feedback system is not currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.
<br>
<br> FFGFFS_POWERON
<br> Power to the force feedback system is currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.
<br>
<br> FFGFFS_SAFETYSWITCHOFF
<br> The safety switch is currently off; that is, the device cannot operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.
<br>
<br> FFGFFS_SAFETYSWITCHON
<br> The safety switch is currently on; that is, the device can operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.
<br>
<br> FFGFFS_STOPPED
<br> No effects are playing, and the device is not paused.
<br>
<br> FFGFFS_USERFFSWITCHOFF
<br> The user force feedback switch is currently off; that is, the device cannot operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.
<br>
<br> FFGFFS_USERFFSWITCHON
<br> The user force feedback switch is currently on; that is, the device can operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.
<br>
<br> Future versions can define additional flags. Applications should ignore any flags that are not currently defined.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackState(
FFDeviceObjectReference deviceReference,
FFState * pFFState
);
/*! @function FFDeviceSendForceFeedbackCommand
@abstract Sends a command to the device's force feedback system.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param flags Single value indicating the desired change in state. The value can be one of the following:
<br>
<br> FFSFFC_CONTINUE
<br> Paused playback of all active effects is to be continued. It is an error to send this command when the device is not in a paused state.
<br>
<br> FFSFFC_PAUSE
<br> Playback of all active effects is to be paused. This command also stops the clock-on effects so that they continue playing to their full duration when restarted.
<br>
<br> While the device is paused, new effects cannot be started, and existing ones cannot be modified. Doing so can cause the subsequent FFSFFC_CONTINUE command to fail to perform properly.
<br>
<br> To abandon a pause and stop all effects, use the FFSFFC_STOPALL or FFSFCC_RESET commands.
<br>
<br> FFSFFC_RESET
<br> The device's force feedback system is to be put in its startup state. All effects are removed from the device, are no longer valid, and must be recreated if they are to be used again. The device's actuators are disabled.
<br>
<br> FFSFFC_SETACTUATORSOFF
<br> The device's force feedback actuators are to be disabled. While the actuators are off, effects continue to play but are ignored by the device. Using the analogy of a sound playback device, they are muted, rather than paused.
<br>
<br> FFSFFC_SETACTUATORSON
<br> The device's force feedback actuators are to be enabled.
<br>
<br> FFSFFC_STOPALL
<br> Playback of any active effects is to be stopped. All active effects are reset, but are still being maintained by the device and are still valid. If the device is in a paused state, that state is lost.
<br>
<br> This command is equivalent to calling the FFEffect_Stop method for each effect playing.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_INTERNAL
<br>
@discussion
*/
extern HRESULT
FFDeviceSendForceFeedbackCommand(
FFDeviceObjectReference deviceReference,
FFCommandFlag flags
);
/*! @function FFDeviceSetForceFeedbackProperty
@abstract Retrieves the device's force feedback capabilities.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param property The following property values are defined for a FF device:
<br>
<br> FFPROP_AUTOCENTER
<br> Specifies whether the actuated FF axes are self-centering. This property controls the device's "default centering spring".
<br> The pValue member points to a UInt32 can be one of the following values.
<br> 0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
<br> 1 - ON: The device should automatically center when the user releases the device.
<br> Not all devices support the autocenter property.
<br>
<br> FFPROP_FFGAIN
<br> Sets the gain for the device.
<br> The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
<br> Setting a gain value is useful when an application wants to scale down the strength of all force feedback effects uniformly, based on user preferences.
@param pValue Address of the location where the property value is to be read. SetForceFeedbackProperty will assume that the data is valid, and of the correct type.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceSetForceFeedbackProperty(
FFDeviceObjectReference deviceReference,
FFProperty property,
void * pValue
);
/*! @function FFDeviceGetForceFeedbackProperty
@abstract Gets properties that define the device behavior.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param property The following property values are defined for a FF device (see FFDeviceSetForceFeedbackProperty for details):
<br>
<br> FFPROP_AUTOCENTER
<br> FFPROP_FFGAIN
<br>
@param pValue Address of the location where the value associated with the property is to be stored. GetForceFeedbackProperty assumes that the pointer is valid, although it will perform a size check before writing the data to pValue
@param valueSize Size, in bytes, of data area pointed to by pValue. Size is compared to expected property size, and the function fails if a mismatch occurs.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackProperty(
FFDeviceObjectReference deviceReference,
FFProperty property,
void * pValue,
IOByteCount valueSize
);
/*! @function FFDeviceSetCooperativeLevel
@abstract Function is unimplemented in version 1.0 of this API
@discussion
*/
extern HRESULT
FFDeviceSetCooperativeLevel(
FFDeviceObjectReference deviceReference,
void * taskIdentifier,
FFCooperativeLevelFlag flags
);
/*! @function FFDeviceGetForceFeedbackCapabilities
@abstract Retrieves the device's force feedback capabilities.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param pFFCapabilities Pointer to a FFCAPABILITIES structure that is to be filled in by the this call.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackCapabilities(
FFDeviceObjectReference deviceReference,
FFCAPABILITIES * pFFCapabilities
);
//-----------------------------------------------------------------------------
// FFEffect (effect related) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFEffectDownload
@abstract Places the effect on the device. If the effect is already on the device, the existing effect is updated to match the values set by the FFEffectSetParameters method.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK or S_FALSE. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
<br> If the method returns S_FALSE, the effect has already been downloaded to the device.
<br>
@discussion It is valid to update an effect while it is playing. The semantics of such an operation are explained in the reference for FFEffectSetParameters.
*/
extern HRESULT
FFEffectDownload(
FFEffectObjectReference effectReference
);
/*! @function FFEffectEscape
@abstract Sends a hardware-specific command to the driver.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffectEscape FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_UNSUPPORTED
<br>
<br> Other device-specific error codes are also possible. Ask the hardware manufacturer for details
<br>
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver.
*/
extern HRESULT
FFEffectEscape(
FFEffectObjectReference effectReference,
FFEFFESCAPE * pFFEffectEscape
);
/*! @function FFEffectGetEffectStatus
@abstract Sends a hardware-specific command to the driver.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFlags Pointer to status flags for the effect. The value can be 0 or one or more of the following constants:
<br>
<br> FFEGES_PLAYING
<br> The effect is playing.
<br>
<br> FFEGES_EMULATED
<br> The effect is emulated.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br>
@discussion
*/
extern HRESULT
FFEffectGetEffectStatus(
FFEffectObjectReference effectReference,
FFEffectStatusFlag * pFlags
);
/*! @function FFEffectGetParameters
@abstract Retrieves information about an effect.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffect Address of a FFEFFECT structure that receives effect information. The dwSize member must be filled in by the application before calling this method.
@param flags Flags that specify which parts of the effect information are to be retrieved. The value can be 0 or one or more of the following constants:
<br>
<br> FFEP_ALLPARAMS
<br> The union of all other FFEP_* flags, indicating that all members of the FFEFFECT structure are being requested.
<br>
<br> FFEP_AXES
<br> The cAxes and rgdwAxes members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rgdwAxes member. If the buffer is too small, the method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
<br>
<br> FFEP_DIRECTION
<br> The cAxes and rglDirection members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rglDirection member. If the buffer is too small, the GetParameters method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
<br> The dwFlags member must include at least one of the coordinate system flags (FFEFF_CARTESIAN, FFEFF_POLAR, or FFEFF_SPHERICAL). The API returns the direction of the effect in one of the coordinate systems you specified, converting between coordinate systems as necessary. On exit, exactly one of the coordinate system flags is set in the dwFlags member, indicating which coordinate system the FF API used. In particular, passing all three coordinate system flags retrieves the coordinates in exactly the same format in which they were set.
<br>
<br> FFEP_DURATION
<br> The dwDuration member should receive data.
<br>
<br> FFEP_ENVELOPE
<br> The lpEnvelope member points to a FFENVELOPE structure that should receive data. If the effect does not have an envelope associated with it, the lpEnvelope member is set to NULL.
<br>
<br> FFEP_GAIN
<br> The dwGain member should receive data.
<br>
<br> FFEP_SAMPLEPERIOD
<br> The dwSamplePeriod member should receive data.
<br>
<br> FFEP_STARTDELAY
<br> The dwStartDelay member should receive data.
<br>
<br> FFEP_TRIGGERBUTTON
<br> The dwTriggerButton member should receive data.
<br>
<br> FFEP_TRIGGERREPEATINTERVAL
<br> The dwTriggerRepeatInterval member should receive data.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> The lpvTypeSpecificParams member points to a buffer whose size is specified by the cbTypeSpecificParams member. On return, the buffer is filled in with the type-specific data associated with the effect, and the cbTypeSpecificParams member contains the number of bytes copied. If the buffer supplied by the application is too small to contain all the type-specific data, the method returns FFERR_MOREDATA, and the cbTypeSpecificParams member contains the required size of the buffer in bytes.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_MOREDATA
<br>
@discussion Common errors resulting in a FFERR_INVALIDPARAM error include not setting the dwSize member of the FFEFFECT structure, passing invalid flags, or not setting up the members in the FFEFFECT structure properly in preparation for receiving the effect information.
*/
extern HRESULT
FFEffectGetParameters(
FFEffectObjectReference effectReference,
FFEFFECT * pFFEffect,
FFEffectParameterFlag flags
);
/*! @function FFEffectSetParameters
@abstract Sets the characteristics of an effect.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffect Address of a FFEFFECT structure that contains effect information. The dwSize member must be filled in by the application before calling this method, as well as any members specified by corresponding bits in the flags parameter.
@param flags Flags that specify which portions of the effect information are to be set and how the downloading of the parameters should be handled. The value can be 0 or one or more of the following constants:
<br>
<br> FFEP_AXES
<br> The cAxes and rgdwAxes members contain data.
<br>
<br> FFEP_DIRECTION
<br> The cAxes and rglDirection members contain data. The dwFlags member specifies (with FFEFF_CARTESIAN or FFEFF_POLAR) the coordinate system in which the values should be interpreted.
<br>
<br> FFEP_DURATION
<br> The dwDuration member contains data.
<br>
<br> FFEP_ENVELOPE
<br> The lpEnvelope member points to a FFENVELOPE structure that contains data. To detach any existing envelope from the effect, pass this flag and set the lpEnvelope member to NULL.
<br>
<br> FFEP_GAIN
<br> The dwGain member contains data.
<br>
<br> FFEP_NODOWNLOAD
<br> Suppress the automatic FFEffect_Download that is normally performed after the parameters are updated.
<br>
<br> FFEP_NORESTART
<br> Suppress the stopping and restarting of the effect to change parameters. See Remarks.
<br>
<br> FFEP_SAMPLEPERIOD
<br> The dwSamplePeriod member contains data.
<br>
<br> FFEP_START
<br> The effect is to be started (or restarted if it is currently playing) after the parameters are updated. By default, the play state of the effect is not altered.
<br>
<br> FFEP_STARTDELAY
<br> The dwStartDelay member contains data.
<br>
<br> FFEP_TRIGGERBUTTON
<br> The dwTriggerButton member contains data.
<br>
<br>
<br> The dwTriggerRepeatInterval member contains data.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> The lpvTypeSpecificParams and cbTypeSpecificParams members of the FFEFFECT structure contain the address and size of type-specific data for the effect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTEDAXIS
<br> FFERR_OUTOFMEMORY
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
@discussion The FFEffectSetParameters method automatically downloads the effect, but this behavior can be suppressed by setting the FFEP_NODOWNLOAD flag. If automatic download has been suppressed, you can manually download the effect by invoking the FFEffectDownload method.
<br>
<br> If the effect is playing while the parameters are changed, the new parameters take effect as if they were the parameters when the effect started.
<br>
<br> For example, suppose a periodic effect with a duration of three seconds is started. After two seconds, the direction of the effect is changed. The effect then continues for one additional second in the new direction. The envelope, phase, amplitude, and other parameters of the effect continue smoothly, as if the direction had not changed.
<br>
<br> In the same situation, if after two seconds the duration of the effect were changed to 1.5 seconds, the effect would stop.
<br>
<br> Normally, if the driver cannot update the parameters of a playing effect, the driver is permitted to stop the effect, update the parameters, and then restart the effect. Passing the FFEP_NORESTART flag suppresses this behavior. If the driver cannot update the parameters of an effect while it is playing, the error code FFERR_EFFECTPLAYING is returned, and the parameters are not updated.
<br>
<br> No more than one of the FFEP_NODOWNLOAD, FFEP_START, and FFEP_NORESTART flags should be set. (It is also valid to pass none of them.)
<br>
<br> These three flags control download and playback behavior as follows:
<br>
<br> If FFEP_NODOWNLOAD is set, the effect parameters are updated but not downloaded to the device.
<br>
<br> If the FFEP_START flag is set, the effect parameters are updated and downloaded to the device, and the effect is started just as if the FFEffect_Start method had been called with the dwIterations parameter set to 1 and with no flags. (Combining the update with FFEP_START is slightly faster than calling Start separately, because it requires less information to be transmitted to the device.)
<br>
<br> If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is not playing, the parameters are updated and downloaded to the device.
<br>
<br> If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is playing, the parameters are updated if the device supports on-the-fly updating. Otherwise the behavior depends on the state of the FFEP_NORESTART flag. If it is set, the error code FFERR_EFFECTPLAYING is returned. If it is clear, the effect is stopped, the parameters are updated, and the effect is restarted.
*/
extern HRESULT
FFEffectSetParameters(
FFEffectObjectReference effectReference,
FFEFFECT * pFFEffect,
FFEffectParameterFlag flags
);
/*! @function FFEffectStart
@abstract Begins playing an effect. If the effect is already playing, it is restarted from the beginning. If the effect has not been downloaded or has been modified since its last download, it is downloaded before being started. This default behavior can be suppressed by passing the FFES_NODOWNLOAD flag.
@param efffectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param iterations Number of times to play the effect in sequence. The envelope is re-articulated with each iteration.
<br>
<br> To play the effect exactly once, pass 1. To play the effect repeatedly until explicitly stopped, pass INFINITE. To play the effect until explicitly stopped without re-articulating the envelope, modify the effect parameters with the FFEffect_SetParameters method, and change the dwDuration member to INFINITE.
@param flags Flags that describe how the effect should be played by the device. The value can be 0 or one or more of the following values:
<br>
<br> FFES_SOLO
<br> All other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects already started on the device.
<br>
<br> FFES_NODOWNLOAD
<br> Do not automatically download the effect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br> FFERR_GENERIC
<br>
@discussion Not all devices support multiple iterations.
*/
extern HRESULT
FFEffectStart(
FFEffectObjectReference effectReference,
UInt32 iterations,
FFEffectStartFlag flags
);
/*! @function FFEffectStop
@abstract Stops playing an effect.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFEffectStop(
FFEffectObjectReference effectReference
);
/*! @function FFEffectUnload
@abstract Removes the effect from the device. If the effect is playing, it is automatically stopped before it is unloaded.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFEffectUnload(
FFEffectObjectReference effectReference
);
#ifdef __cplusplus
}
#endif
#endif // _FORCEFEEDBACK_H_

View File

@ -0,0 +1,572 @@
//-----------------------------------------------------------------------------
// File: ForceFeedbackConstants.h
// Contains: Public interfaces for ForceFeedback technology.
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _FORCEFEEDBACKCONSTANTS_H_
#define _FORCEFEEDBACKCONSTANTS_H_
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! @header ForceFeedbackConstants.h
@abstract Constants used in the public interfaces to the Force Feedback implementation in Mac OS X.
@discussion This header file contains the Effect type UUIDs, type definitions used in the API, force feedback
constants and error values used by the API.
*/
//-----------------------------------------------------------------------------
// General defines
//-----------------------------------------------------------------------------
#if !defined( DWORD )
typedef UInt32 DWORD;
typedef DWORD* LPDWORD;
#endif
#if !defined( LONG )
typedef SInt32 LONG;
typedef LONG* LPLONG;
#endif
#define FF_INFINITE 0xFFFFFFFF
#define FF_DEGREES 100
#define FF_FFNOMINALMAX 10000
#define FF_SECONDS 1000000
//-----------------------------------------------------------------------------
// Effect type UUIDs
//-----------------------------------------------------------------------------
// E559C460-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_ConstantForce_ID
@discussion UUID for a constant force effect type
*/
#define kFFEffectType_ConstantForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x60, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C461-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_RampForce_ID
@discussion UUID for a ramp force effect type
*/
#define kFFEffectType_RampForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x61, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C462-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Square_ID
@discussion UUID for a square wave effect type
*/
#define kFFEffectType_Square_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x62, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C463-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Sine_ID
@discussion UUID for a sine wave effect type
*/
#define kFFEffectType_Sine_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x63, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C464-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Sine_ID
@discussion UUID for a sine wave effect type
*/
#define kFFEffectType_Triangle_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x64, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C465-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_SawtoothUp_ID
@discussion UUID for a upwards sawtooth wave effect type
*/
#define kFFEffectType_SawtoothUp_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x65, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C466-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_SawtoothDown_ID
@discussion UUID for a downwards sawtooth wave effect type
*/
#define kFFEffectType_SawtoothDown_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x66, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C467-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Spring_ID
@discussion UUID for a spring effect type
*/
#define kFFEffectType_Spring_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x67, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C468-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Damper_ID
@discussion UUID for a damper effect type
*/
#define kFFEffectType_Damper_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x68, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C469-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Inertia_ID
@discussion UUID for an inertia effect type
*/
#define kFFEffectType_Inertia_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x69, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C46A-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Friction_ID
@discussion UUID for a friction effect type
*/
#define kFFEffectType_Friction_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x6A, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C46B-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_CustomForce_ID
@discussion UUID for a custom force effect type
*/
#define kFFEffectType_CustomForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x6B, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
//-----------------------------------------------------------------------------
// Effect definition constants
//-----------------------------------------------------------------------------
// FFEFFECT.dwFlags constants
// IMPORTANT NOTE: OBJECT IDS cannot be used to identify trigger buttons
// in FFEFFECT.dwTriggerButton, and output axes in FFEFFECT.rgdwAxes[n].
// Please use object offsets (FFJOFS_* constants), the only supported method.
// #define FFEFF_OBJECTIDS 0x00000001
#define FFEFF_OBJECTOFFSETS 0x00000002
typedef UInt32 FFCoordinateSystemFlag;
enum
{
FFEFF_CARTESIAN = 0x00000010,
FFEFF_POLAR = 0x00000020,
FFEFF_SPHERICAL = 0x00000040
};
// Effect Parameter flags for use in calls to FFEffectGetParameters() and FFEffectSetParameters()
//
typedef UInt32 FFEffectParameterFlag;
enum
{
FFEP_DURATION = 0x00000001,
FFEP_SAMPLEPERIOD = 0x00000002,
FFEP_GAIN = 0x00000004,
FFEP_TRIGGERBUTTON = 0x00000008,
FFEP_TRIGGERREPEATINTERVAL = 0x00000010,
FFEP_AXES = 0x00000020,
FFEP_DIRECTION = 0x00000040,
FFEP_ENVELOPE = 0x00000080,
FFEP_TYPESPECIFICPARAMS = 0x00000100,
FFEP_STARTDELAY = 0x00000200,
FFEP_ALLPARAMS = 0x000003FF,
FFEP_START = 0x20000000,
FFEP_NORESTART = 0x40000000,
FFEP_NODOWNLOAD = 0x80000000,
FFEB_NOTRIGGER = 0xFFFFFFFF
};
// Effect Parameter flags for use in calls to FFEffectStart()
//
typedef UInt32 FFEffectStartFlag;
enum
{
FFES_SOLO = 0x00000001,
FFES_NODOWNLOAD = 0x80000000
};
// Effect Parameter flags for use in calls to FFEffectGetEffectStatus()
//
typedef UInt32 FFEffectStatusFlag;
enum
{
FFEGES_NOTPLAYING = 0x00000000,
FFEGES_PLAYING = 0x00000001,
FFEGES_EMULATED = 0x00000002
};
// command flags for FFDeviceSendForceFeedbackCommand()
//
typedef UInt32 FFCommandFlag;
enum
{
FFSFFC_RESET = 0x00000001,
FFSFFC_STOPALL = 0x00000002,
FFSFFC_PAUSE = 0x00000004,
FFSFFC_CONTINUE = 0x00000008,
FFSFFC_SETACTUATORSON = 0x00000010,
FFSFFC_SETACTUATORSOFF = 0x00000020
};
// device state flags returned by FFDeviceGetForceFeedbackState()
//
typedef UInt32 FFState;
enum
{
FFGFFS_EMPTY = 0x00000001,
FFGFFS_STOPPED = 0x00000002,
FFGFFS_PAUSED = 0x00000004,
FFGFFS_ACTUATORSON = 0x00000010,
FFGFFS_ACTUATORSOFF = 0x00000020,
FFGFFS_POWERON = 0x00000040,
FFGFFS_POWEROFF = 0x00000080,
FFGFFS_SAFETYSWITCHON = 0x00000100,
FFGFFS_SAFETYSWITCHOFF = 0x00000200,
FFGFFS_USERFFSWITCHON = 0x00000400,
FFGFFS_USERFFSWITCHOFF = 0x00000800,
FFGFFS_DEVICELOST = 0x80000000
};
// axis and button "field offsets",
// used in
// FFEFFECT.dwTriggerButton
// FFEFFECT.rgdwAxes[n]
#define FFJOFS_X 0
#define FFJOFS_Y 4
#define FFJOFS_Z 8
#define FFJOFS_RX 12
#define FFJOFS_RY 16
#define FFJOFS_RZ 20
#define FFJOFS_SLIDER(n) (24 + (n) * sizeof(LONG))
#define FFJOFS_POV(n) (32 + (n) * sizeof(DWORD))
#define FFJOFS_BUTTON(n) (48 + (n))
#define FFJOFS_BUTTON0 FFJOFS_BUTTON(0)
#define FFJOFS_BUTTON1 FFJOFS_BUTTON(1)
#define FFJOFS_BUTTON2 FFJOFS_BUTTON(2)
#define FFJOFS_BUTTON3 FFJOFS_BUTTON(3)
#define FFJOFS_BUTTON4 FFJOFS_BUTTON(4)
#define FFJOFS_BUTTON5 FFJOFS_BUTTON(5)
#define FFJOFS_BUTTON6 FFJOFS_BUTTON(6)
#define FFJOFS_BUTTON7 FFJOFS_BUTTON(7)
#define FFJOFS_BUTTON8 FFJOFS_BUTTON(8)
#define FFJOFS_BUTTON9 FFJOFS_BUTTON(9)
#define FFJOFS_BUTTON10 FFJOFS_BUTTON(10)
#define FFJOFS_BUTTON11 FFJOFS_BUTTON(11)
#define FFJOFS_BUTTON12 FFJOFS_BUTTON(12)
#define FFJOFS_BUTTON13 FFJOFS_BUTTON(13)
#define FFJOFS_BUTTON14 FFJOFS_BUTTON(14)
#define FFJOFS_BUTTON15 FFJOFS_BUTTON(15)
#define FFJOFS_BUTTON16 FFJOFS_BUTTON(16)
#define FFJOFS_BUTTON17 FFJOFS_BUTTON(17)
#define FFJOFS_BUTTON18 FFJOFS_BUTTON(18)
#define FFJOFS_BUTTON19 FFJOFS_BUTTON(19)
#define FFJOFS_BUTTON20 FFJOFS_BUTTON(20)
#define FFJOFS_BUTTON21 FFJOFS_BUTTON(21)
#define FFJOFS_BUTTON22 FFJOFS_BUTTON(22)
#define FFJOFS_BUTTON23 FFJOFS_BUTTON(23)
#define FFJOFS_BUTTON24 FFJOFS_BUTTON(24)
#define FFJOFS_BUTTON25 FFJOFS_BUTTON(25)
#define FFJOFS_BUTTON26 FFJOFS_BUTTON(26)
#define FFJOFS_BUTTON27 FFJOFS_BUTTON(27)
#define FFJOFS_BUTTON28 FFJOFS_BUTTON(28)
#define FFJOFS_BUTTON29 FFJOFS_BUTTON(29)
#define FFJOFS_BUTTON30 FFJOFS_BUTTON(30)
#define FFJOFS_BUTTON31 FFJOFS_BUTTON(31)
// defines for FFDeviceGetForceFeedbackProperty() and FFDeviceSetForceFeedbackProperty()
//
typedef UInt32 FFProperty;
enum
{
FFPROP_FFGAIN = 1,
FFPROP_AUTOCENTER = 3
};
// flags for FFDeviceSetCooperativeLevel()
//
typedef UInt32 FFCooperativeLevelFlag;
enum
{
FFSCL_EXCLUSIVE = 0x00000001,
FFSCL_NONEXCLUSIVE = 0x00000002,
FFSCL_FOREGROUND = 0x00000004,
FFSCL_BACKGROUND = 0x00000008
};
// types used in FFCAPABILITIES structure
//
typedef UInt32 FFCapabilitiesEffectType;
enum
{
FFCAP_ET_CONSTANTFORCE = 0x00000001,
FFCAP_ET_RAMPFORCE = 0x00000002,
FFCAP_ET_SQUARE = 0x00000004,
FFCAP_ET_SINE = 0x00000008,
FFCAP_ET_TRIANGLE = 0x00000010,
FFCAP_ET_SAWTOOTHUP = 0x00000020,
FFCAP_ET_SAWTOOTHDOWN = 0x00000040,
FFCAP_ET_SPRING = 0x00000080,
FFCAP_ET_DAMPER = 0x00000100,
FFCAP_ET_INERTIA = 0x00000200,
FFCAP_ET_FRICTION = 0x00000400,
FFCAP_ET_CUSTOMFORCE = 0x00000800
};
typedef UInt32 FFCapabilitiesEffectSubType;
enum
{
FFCAP_ST_KINESTHETIC = 1,
FFCAP_ST_VIBRATION = 2
};
//-----------------------------------------------------------------------------
// Error return values
//-----------------------------------------------------------------------------
/*!
@defined FF_OK
@discussion The operation completed successfully.
*/
#define FF_OK S_OK
/*!
@defined FF_FALSE
@discussion The operation did not complete successfully.
*/
#define FF_FALSE S_FALSE
/*!
@defined FF_DOWNLOADSKIPPED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but the effect was not
* downloaded because the FFEP_NODOWNLOAD flag was passed.
*/
#define FF_DOWNLOADSKIPPED ((HRESULT)0x00000003L)
/*!
@defined FF_EFFECTRESTARTED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but in order to change
* the parameters, the effect needed to be restarted.
*/
#define FF_EFFECTRESTARTED ((HRESULT)0x00000004L)
/*!
@defined FF_TRUNCATED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but some of them were
* beyond the capabilities of the device and were truncated.
*/
#define FF_TRUNCATED ((HRESULT)0x00000008L)
/*!
@defined FF_TRUNCATEDANDRESTARTED
* @discussion
* Equal to FF_EFFECTRESTARTED | FF_TRUNCATED.
*/
#define FF_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL)
/*!
@defined FFERR_DEVICENOTREG
* @discussion
* The device or device instance or effect is not registered.
*/
#define FFERR_DEVICENOTREG REGDB_E_CLASSNOTREG
/*!
@defined FFERR_INVALIDPARAM
* @discussion
* An invalid parameter was passed to the returning function,
* or the object was not in a state that admitted the function
* to be called.
*/
#define FFERR_INVALIDPARAM E_INVALIDARG
/*!
@defined FFERR_NOINTERFACE
* @discussion
* The specified interface is not supported by the object
*/
#define FFERR_NOINTERFACE E_NOINTERFACE
/*!
@defined FFERR_GENERIC
* @discussion
* An undetermined error occurred.
*/
#define FFERR_GENERIC E_FAIL
/*!
@defined FFERR_OUTOFMEMORY
* @discussion
* Couldn't allocate sufficient memory to complete the caller's request.
*/
#define FFERR_OUTOFMEMORY E_OUTOFMEMORY
/*!
@defined FFERR_UNSUPPORTED
* @discussion
* The function called is not supported at this time
*/
#define FFERR_UNSUPPORTED E_NOTIMPL
#ifndef E_PENDING
/*!
@defined E_PENDING
* @discussion
* Data is not yet available.
*/
#define E_PENDING 0x8000000AL
#endif
/*!
@defined FFERR_DEVICEFULL
* @discussion
* The device is full.
*/
#define FFERR_DEVICEFULL 0x80040201L
/*!
@defined FFERR_MOREDATA
* @discussion
* Not all the requested information fit into the buffer.
*/
#define FFERR_MOREDATA 0x80040202L
/*!
@defined FFERR_NOTDOWNLOADED
* @discussion
* The effect is not downloaded.
*/
#define FFERR_NOTDOWNLOADED 0x80040203L
/*!
@defined FFERR_HASEFFECTS
* @discussion
* The device cannot be reinitialized because there are still effects
* attached to it.
*/
#define FFERR_HASEFFECTS 0x80040204L
/*!
@defined FFERR_INCOMPLETEEFFECT
* @discussion
* The effect could not be downloaded because essential information
* is missing. For example, no axes have been associated with the
* effect, or no type-specific information has been created.
*/
#define FFERR_INCOMPLETEEFFECT 0x80040206L
/*!
@defined FFERR_EFFECTPLAYING
* @discussion
* An attempt was made to modify parameters of an effect while it is
* playing. Not all hardware devices support altering the parameters
* of an effect while it is playing.
*/
#define FFERR_EFFECTPLAYING 0x80040208L
/*!
@defined FFERR_UNPLUGGED
* @discussion
* The operation could not be completed because the device is not
* plugged in.
*/
#define FFERR_UNPLUGGED 0x80040209L
//
// Mac OS X specific
//
/*!
@defined FFERR_INVALIDDOWNLOADID
* @discussion
* The effect index provided by the API in downloadID is not recognized by the
* IOForceFeedbackLib driver.
*/
#define FFERR_INVALIDDOWNLOADID 0x80040300
/*!
@defined FFERR_DEVICEPAUSED
* @discussion
* When the device is paused via a call to FFDeviceSendForceFeedbackCommand(),
* other operations such as modifying existing effect parameters and creating
* new effects are not allowed.
*/
#define FFERR_DEVICEPAUSED 0x80040301
/*!
@defined FFERR_INTERNAL
* @discussion
* The IOForceFededbackLib driver has detected an internal fault. Often this
* occurs because of an unexpected internal code path.
*/
#define FFERR_INTERNAL 0x80040302
/*!
@defined FFERR_EFFECTTYPEMISMATCH
* @discussion
* The IOForceFededbackLib driver has received an effect modification request
* whose basic type does not match the defined effect type for the given effect.
*/
#define FFERR_EFFECTTYPEMISMATCH 0x80040303
/*!
@defined FFERR_UNSUPPORTEDAXIS
* @discussion
* The effect includes one or more axes that the device does not support.
*/
#define FFERR_UNSUPPORTEDAXIS 0x80040304
/*!
@defined FFERR_NOTINITIALIZED
* @discussion
* This object has not been initialized
*/
#define FFERR_NOTINITIALIZED 0x80040305
/*!
@defined FFERR_EFFECTTYPENOTSUPPORTED
* @discussion
* The effect type requested is not explicitly supported by the particular device.
*/
#define FFERR_EFFECTTYPENOTSUPPORTED 0x80040306
/*!
@defined FFERR_DEVICERELEASED
* @discussion
* The device has been released.
*/
#define FFERR_DEVICERELEASED 0x80040307
#ifdef __cplusplus
}
#endif
#endif // _FORCEFEEDBACKCONSTANTS_H_

View File

@ -0,0 +1,447 @@
//-----------------------------------------------------------------------------
// File: IOForceFeedbackLib.h
// Contains: Public interfaces for the Force Feedback Plugin architecture .
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _IOFORCEFEEDBACKLIB_H
#define _IOFORCEFEEDBACKLIB_H
#if PRAGMA_ONCE
#pragma once
#endif
/*! @header IOForceFeedbackLib.h
@abstract Public Interfaces and constants used to develop Force Feedback plugIns.
@discussion A force feedback device manufacturer might need to implement a plug in
to allow the Force Feedback Library to control the device. This header
file describes the functions that need to be implemented. This interface definition
follows Microsoft Windoes IDirectInputEffectDriver definition wherever it makes sense to do so.
Certain functions may contain more or fewer parameters than the Windows version
*/
#include <sys/cdefs.h>
__BEGIN_DECLS
#include <CoreFoundation/CoreFoundation.h>
#if COREFOUNDATION_CFPLUGINCOM_SEPARATE
#include <CoreFoundation/CFPlugInCOM.h>
#endif
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <IOKit/IOTypes.h>
#include <ForceFeedback/ForceFeedback.h>
//====================================================================================================================
// The Version of the FF PlugIn API
//====================================================================================================================
//
enum {
kFFPlugInAPIMajorRev = 1,
kFFPlugInAPIMinorAndBugRev = 0,
kFFPlugInAPIStage = finalStage,
kFFPlugInAPINonRelRev = 0
};
//====================================================================================================================
// Defines
//====================================================================================================================
//
#define FFDEVICESTATE ForceFeedbackDeviceState
#define PFFDEVICESTATE ForceFeedbackDeviceStatePtr
// F4545CE5-BF5B-11D6-A4BB-0003933E3E3E
#define kIOForceFeedbackLibTypeID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xF4, 0x54, 0x5C, 0xE5, 0xBF, 0x5B, 0x11, 0xD6, \
0xA4, 0xBB, 0x00, 0x03, 0x93, 0x3E, 0x3E, 0x3E)
// 1C7C5850-BB6A-11D6-B75F-003065FBE6B0
#define kIOForceFeedbackDeviceInterfaceID CFUUIDGetConstantUUIDWithBytes(NULL, \
0x1C, 0x7C, 0x58, 0x50, 0xBB, 0x6A, 0x11, 0xD6, \
0xB7, 0x5F, 0x00, 0x30, 0x65, 0xFB, 0xE6, 0xB0)
//====================================================================================================================
// Structs
//====================================================================================================================
//
struct ForceFeedbackDeviceState
{
UInt32 dwSize;
UInt32 dwState;
UInt32 dwLoad;
};
typedef struct ForceFeedbackDeviceState ForceFeedbackDeviceState;
typedef ForceFeedbackDeviceState * ForceFeedbackDeviceStatePtr;
struct ForceFeedbackVersion
{
NumVersion apiVersion;
NumVersion plugInVersion;
};
typedef struct ForceFeedbackVersion ForceFeedbackVersion;
typedef ForceFeedbackVersion * ForceFeedbackVersionPtr;
//====================================================================================================================
// Types
//====================================================================================================================
//
typedef UInt32 FFEffectDownloadID;
//====================================================================================================================
//
// ForceFeedback Device Interface Functions available in version 1.0 of architecture
//
//====================================================================================================================
//
#define IOFORCEFEEDBACKDEVICE_FUNCS_100 \
\
HRESULT (*ForceFeedbackGetVersion)( void * self, \
ForceFeedbackVersion * version); \
\
HRESULT (*InitializeTerminate)( void * self, \
NumVersion forceFeedbackAPIVersion,\
io_object_t hidDevice, \
bool begin ); \
\
HRESULT (*DestroyEffect)( void * self, \
FFEffectDownloadID downloadID ); \
\
HRESULT (*DownloadEffect)( void * self, \
CFUUIDRef effectType, \
FFEffectDownloadID * pDownloadID, \
FFEFFECT * pEffect, \
FFEffectParameterFlag flags ); \
\
HRESULT (*Escape)( void * self, \
FFEffectDownloadID downloadID, \
FFEFFESCAPE * pEscape ); \
\
HRESULT (*GetEffectStatus)( void * self, \
FFEffectDownloadID downloadID, \
FFEffectStatusFlag * pStatusCode ); \
\
HRESULT (*GetForceFeedbackCapabilities)( void * self, \
FFCAPABILITIES * pCapabilities ); \
\
HRESULT (*GetForceFeedbackState)( void * self, \
ForceFeedbackDeviceState * pDeviceState ); \
\
HRESULT (*SendForceFeedbackCommand)( void * self, \
FFCommandFlag state ); \
\
HRESULT (*SetProperty)( void * self, \
FFProperty property, \
void * pValue ); \
\
HRESULT (*StartEffect)( void * self, \
FFEffectDownloadID downloadID, \
FFEffectStartFlag mode, \
UInt32 iterations ); \
\
HRESULT (*StopEffect)( void * self, \
FFEffectDownloadID downloadID );
//====================================================================================================================
//
// END OF DeviceInterface Functions available in version 1.0 of this API
//
//====================================================================================================================
//
struct IOForceFeedbackDeviceInterface {
IUNKNOWN_C_GUTS;
IOFORCEFEEDBACKDEVICE_FUNCS_100
};
typedef struct IOForceFeedbackDeviceInterface IOForceFeedbackDeviceInterface;
typedef IOForceFeedbackDeviceInterface * IOForceFeedbackDeviceInterfacePtr;
//====================================================================================================================
//
// ¥¥¥¥¥ The following is #ifdef out. It is here so that we can header doc this file without intruding in its
// ¥¥¥¥¥ readability.
//
//====================================================================================================================
//
#if 0
struct IOForceFeedbackDeviceInterface {
IUNKNOWN_C_GUTS;
/*! @function ForceFeedbackGetVersion
@abstract This function is used to determine driver and API version information.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param version Pointer to ForceFeedbackVersion structure that is to receive the required info. See the structure description for details.
@result Returns FF_OK if successful, or an error value otherwise.
*/
HRESULT (*ForceFeedbackGetVersion) (void * self, ForceFeedbackVersion * version);
/*! @function InitializeTerminate
@abstract This function is used to "create and destroy" particular device instances. It provides the FF plug-in driver with all the necessary start-up parameters.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param forceFeedbackAPIVersion The version number of FF API that loaded the effect driver. The plugIn should check that the major version of the forceFeedbackAPI version is the same as the major version of the API at the time the plugIn was compiled. If the major versions are different, then the plugIn API has changed and the plugIn will NOT be compatible with it.
<br>
If begin is false, this parameter is ignored.
@param hidDevice A device object that can be used by the FF plug-in to establish a connection to and communicate with the device. The caller will release the hidDevice device object with a call to IOObjectRelease() once the FF plug-in completes its InitializeTerminate processing, so a FF plug-in implementation should not make a copy of the io_object_t variable with the intention of using it outside the context of this call.
<br>
If begin is false, this parameter is ignored. (You can pass NULL.)
@param begin Nonzero if access to the device is beginning. Zero if the access to the device is ending. The FF API will call InitializeTerminate( begin=TRUE) when a FF device is first selected for use, and InitializeTerminate( begin=false) when the FF device is no longer needed.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br>
*/
HRESULT (*InitializeTerminate)(void * self, NumVersion forceFeedbackAPIVersion, io_object_t hidDevice, bool begin );
/*! @function DestroyEffect
@abstract This function commands the device to "destroy" a currently downloaded effect. The effect ID and any data that is associated with the effect are freed and available for reallocation.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect ID that was obtained from the device when the effect was downloaded.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br>
*/
HRESULT (*DestroyEffect)(void * self, FFEffectDownloadID downloadID );
/*! @function DownloadEffect
@abstract This function sends an effect to the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param effectType Indicates the type of effect being created. Valid UUIDs are listed as kFFEffectType_* constants in the ForceFeedbackConstants.h file. (Supported effect types include Sine, Square, Triangle, SawtoothUp, SawtoothDown, Constant, Spring, Damper, etc.).
@param pDownloadID On entry, this parameter points to the handle of the effect being downloaded. If the parameter points to a zero, then a new effect is downloaded. On exit, the FFEffectDownloadID pointed to by this parameter contains the new effect handle. On failure, the FFEffectDownloadID pointed to by this parameter is set to zero if the effect is lost, or left alone if the effect is still valid with its old parameters. Note that zero is never a valid effect handle.
@param pEffect The new parameters for the effect.
<br>
IMPORTANT NOTE: Unlike the IDirectInputEffectDriver specification, the axis and button values are NOT converted to object identifiers before they are handed over to the driver. In this case, the only supported method used to assign triggers and output axes is through object offsets, defined by the FFJOFS_* constants. Therefore, if a button is assigned to trigger an effect, FFEFFECT.dwTriggerButton will contain a constant of the form FFJOFS_BUTTONn. Similarly, output axes will be identified in FFEFFECT.rgdwAxes[n] as FFJOFS_X, FFJOFS_Y, etc.
@param flags Specifies which portions of the effect information have changed from the effect already on the device. This information is passed to drivers to allow for the optimization of effect modification. If an effect is being modified, a driver may be able to update the effect in its original position and transmit to the device only the information that has changed. Drivers are not, however, required to implement this optimization. All members of the FFEFFECT structure that are pointed to by the pEffect parameter are valid, and a driver may choose simply to update all parameters of the effect at each download. There may be zero, one, or more of the following:
<br>
<br> FFEP_DURATION
<br> Indicates the dwDuration member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_SAMPLEPERIOD
<br> Indicates the dwSamplePeriod member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_GAIN
<br> Indicates the dwGain member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_TRIGGERBUTTON
<br> Indicates the dwTriggerButton member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_TRIGGERREPEATINTERVAL
<br> Indicates the dwTriggerRepeatInterval member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_AXES
<br> Indicates the cAxes and rgdwAxes members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download.
<br>
<br> FFEP_DIRECTION
<br> Indicates the cAxes and rglDirection members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download. (The dwFlags member of the FFEFFECT structure specifies, through FFEFF_CARTESIAN or FFEFF_POLAR, the coordinate system in which the values should be interpreted.)
<br>
<br> FFEP_ENVELOPE
<br> Indicates the lpEnvelope member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download. If this flag is set and the lpEnvelope member is a NULL pointer, then the effect is being created with no envelope, or the existing envelope is being deleted.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> Indicates the cbTypeSpecificParams and lpTypeSpecificParams members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download.
<br>
<br> FFEP_STARTDELAY
<br> Indicates the dwStartDelay member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_START
<br> Indicates that the effect is to be restarted from the beginning after the parameters of the effect have been updated. Note that the FFEP_NODOWNLOAD flag overrides the FFEP_START flag.
<br>
<br> FFEP_NORESTART
<br> If this flag is not specified, the effect device driver is permitted to restart the effect if doing so is necessary to change the specified parameters. Note that the FFEP_NODOWNLOAD and FFEP_START flags override this flag.
<br>
<br> FFEP_NODOWNLOAD
<br> Suppresses the automatic download that is normally performed after the parameters are updated. If this flag is set, the driver should validate parameters without performing an actual download.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
*/
HRESULT (*DownloadEffect)( void * self, CFUUIDRef effectType, FFEffectDownloadID * pDownloadID,
FFEFFECT * pEffect, FFEffectParameterFlag flags );
/*! @function Escape
@abstract This function escapes to the driver. This method is called in response to an application invoking the FFEffectEscape or FFDeviceEscape methods.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Specifies the effect at which the command is directed, or zero if the command is directed at the device itself and not any particular effect.
@param pEscape Pointer to a FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of output buffer bytes actually used.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_UNSUPPORTED
<br>
*/
HRESULT (*Escape)( void * self, FFEffectDownloadID downloadID, FFEFFESCAPE * pEscape );
/*! @function GetEffectStatus
@abstract This function returns the device effect's status.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be queried.
@param pStatusCode Receives the effect status. The FFEffectStatusFlag pointed to by this parameter should be filled in with one of the following values:
<br>
<br> FFEGES_PLAYING
<br> The effect is still playing.
<br>
<br> FFEGES_NOTPLAYING
<br> The effect is not playing.
@result Returns FF_OK.
*/
HRESULT (*GetEffectStatus)( void * self, FFEffectDownloadID downloadID, FFEffectStatusFlag * pStatusCode );
/*! @function GetForceFeedbackCapabilities
@abstract This function escapes to the driver. This method is called in response to an application invoking the FFEffectEscape or FFDevicEscape methods.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param pCapabilities Pointer to a FFCAPABILITIES structure that should be filled in with version information describing the hardware, firmware, and driver.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_NOINTERFACE
<br>
*/
HRESULT (*GetForceFeedbackCapabilities)( void * self, FFCAPABILITIES * pCapabilities );
/*! @function GetForceFeedbackState
@abstract This function returns the state of the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param pDeviceState Pointer to a ForceFeedbackDeviceState structure that receives the device state. FF API sets the dwSize member of the ForceFeedbackDeviceState structure to sizeof(ForceFeedbackDeviceState) before calling this method.
@result Returns FF_OK.
*/
HRESULT (*GetForceFeedbackState)( void * self, ForceFeedbackDeviceState * pDeviceState );
/*! @function SendForceFeedbackCommand
@abstract This function sends a command to the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param state Indicates the command being sent. That command can be one of the following:
<br>
<br> FFSFFC_RESET
<br> Indicates that playback of any active effects should be been stopped and that all effects should be removed from the device. Once the device has been reset, all effects are no longer valid and must be re-created.
<br>
<br> FFSFFC_STOPALL
<br> Indicates that playback of all effects should be stopped. Sending the FFSFFC_STOPALL command is equivalent to invoking the FFEffect_Stop method on all effects that are playing. If the device is in a paused state, the device driver is permitted to lose the paused state.
<br>
<br> FFSFFC_PAUSE
<br> Indicates that playback of all effects should be paused. When effects are paused, time "stops" until the FFSFFC_CONTINUE command is sent. For example, suppose an effect of five seconds' duration is started. After one second, all effects are paused. After two more seconds, all effects are continued. The effect should then play for four additional seconds. While a force-feedback device is paused, starting a new effect or modifying existing ones can cause the paused state to be lost.
<br>
<br> FFSFFC_CONTINUE
<br> Indicates that playback should be resumed at the point at which it was interrupted for those effects that were paused by a previous FFSCFFC_PAUSE command.
<br>
<br> FFSFFC_SETACTUATORSON
<br> Indicates that the device's force-feedback actuators should be enabled.
<br>
<br> FFSFFC_SETACTUATORSOFF
<br> Indicates that the device's force-feedback actuators should be disabled. If successful, force-feedback effects are "muted". Note that time continues to elapse while actuators are off. For example, suppose an effect of five seconds' duration is started. After one second, actuators are turned off. After two more seconds, actuators are turned back on. The effect should then play for two additional seconds.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_INVALIDPARAM
<br>
*/
HRESULT (*SendForceFeedbackCommand)( void * self, FFCommandFlag state );
/*! @function SetProperty
@abstract This function sets properties that define the device behavior.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param property The following property values are defined for a FF device:
<br>
<br> FFPROP_AUTOCENTER
<br> Specifies whether the actuated FF axes are self-centering. This property controls the deviceÕs Òdefault centering springÓ.
<br> The pValue member points to a UInt32 and can be one of the following values.
<br>
<br> 0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
<br>
<br> 1 - ON: The device should automatically center when the user releases the device.
<br>
<br> Not all devices support the autocenter property.
<br>
<br> FFPROP_FFGAIN
<br> Sets the gain for the device.
<br>
<br> The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
<br>
<br> Setting a gain value is useful when an application wants to scale down the strength of all force-feedback effects uniformly, based on user preferences.
@param pValue Address of the location where the property value is to be read. This function will assume that the data is valid, and of the correct type.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
*/
HRESULT (*SetProperty)( void * self, FFProperty property, void * pValue );
/*! @function StartEffect
@abstract This function commands the device to play back an effect that was previously loaded.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be played.
@param mode Specifies how the effect is to affect other effects. Only the mode listed below can be used; all other modes are reserved. For example, the driver never receives the FFES_NODOWNLOAD flag because it is managed by the FF API and not the PlugIn driver. This parameter can be zero, one, or more of the following flags:
<br>
<br> FFES_SOLO
<br> Indicates that all other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects that have already started on the device.
@param iterations Specifies the number of times to perform the effect. If the value is FF_INFINITE, then the effect should be repeated until explicitly stopped or paused.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_GENERIC
<br> FFERR_INVALIDDOWNLOADID
<br>
*/
HRESULT (*StartEffect)( void * self, FFEffectDownloadID downloadID, FFEffectStartFlag mode, UInt32 iterations );
/*! @function StopEffect
@abstract This function commands the device to stop an effect that was previously started.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be stopped.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_GENERIC
<br> FFERR_INVALIDDOWNLOADID
<br>
*/
HRESULT (*StopEffect)( void * self, UInt32 downloadID );
};
#endif // #if 0 ¥¥¥ Used for header doc'ing only
__END_DECLS
#endif /* ! _IOFORCEFEEDBACKLIB_H */

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>ForceFeedback</string>
<key>CFBundleGetInfoString</key>
<string>1.0.0, Copyright Apple Computer, Inc. 2002</string>
<key>CFBundleIdentifier</key>
<string>com.apple.ForceFeedback</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ForceFeedback Framework</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>70</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>ProjectName</key>
<string>ForceFeedback</string>
<key>ReleaseStatus</key>
<string>Beta</string>
<key>SourceVersion</key>
<string>1000305</string>
</dict>
</plist>

View File

@ -0,0 +1,816 @@
//-----------------------------------------------------------------------------
// File: ForceFeedback.h
// Contains: Public interfaces for ForceFeedback technology.
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _FORCEFEEDBACK_H_
#define _FORCEFEEDBACK_H_
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! @header ForceFeedback.h
@abstract Public Interfaces to the Force Feedback implementation in Mac OS X.
@discussion The Force Feedback API allows developers to control Force Feedback devices attached to the system. It is a distilled version of the Force Feedback functionality found in Microsoft's DirectInput API. Developers familiar with that API should find this API to be similar.
*/
#include <CoreFoundation/CoreFoundation.h>
#if COREFOUNDATION_CFPLUGINCOM_SEPARATE
#include <CoreFoundation/CFPlugInCOM.h>
#endif
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <IOKit/IOTypes.h>
#include <ForceFeedback/ForceFeedbackConstants.h>
//-----------------------------------------------------------------------------
// The Version of the FF API
//-----------------------------------------------------------------------------
enum {
kFFAPIMajorRev = 1,
kFFAPIMinorAndBugRev = 0,
kFFAPIStage = finalStage,
kFFAPINonRelRev = 0
};
//-----------------------------------------------------------------------------
// Effect definition structures
//-----------------------------------------------------------------------------
struct FFCONSTANTFORCE
{
LONG lMagnitude;
};
typedef struct FFCONSTANTFORCE FFCONSTANTFORCE;
typedef FFCONSTANTFORCE * PFFCONSTANTFORCE;
struct FFRAMPFORCE
{
LONG lStart;
LONG lEnd;
};
typedef struct FFRAMPFORCE FFRAMPFORCE;
typedef FFRAMPFORCE * PFFRAMPFORCE;
struct FFPERIODIC
{
DWORD dwMagnitude;
LONG lOffset;
DWORD dwPhase;
DWORD dwPeriod;
};
typedef struct FFPERIODIC FFPERIODIC;
typedef FFPERIODIC * PFFPERIODIC;
struct FFCONDITION
{
LONG lOffset;
LONG lPositiveCoefficient;
LONG lNegativeCoefficient;
DWORD dwPositiveSaturation;
DWORD dwNegativeSaturation;
LONG lDeadBand;
};
typedef struct FFCONDITION FFCONDITION;
typedef FFCONDITION * PFFCONDITION;
struct FFCUSTOMFORCE
{
DWORD cChannels;
DWORD dwSamplePeriod;
DWORD cSamples;
LPLONG rglForceData;
};
typedef struct FFCUSTOMFORCE FFCUSTOMFORCE;
typedef FFCUSTOMFORCE * PFFCUSTOMFORCE;
struct FFENVELOPE
{
DWORD dwSize; /* sizeof(FFENVELOPE) */
DWORD dwAttackLevel;
DWORD dwAttackTime; /* Microseconds */
DWORD dwFadeLevel;
DWORD dwFadeTime; /* Microseconds */
};
typedef struct FFENVELOPE FFENVELOPE;
typedef FFENVELOPE * PFFENVELOPE;
// IMPORTANT NOTE: OBJECT IDS cannot be used to identify trigger buttons
// in FFEFFECT.dwTriggerButton, and output axes in FFEFFECT.rgdwAxes[n].
// Please use object offsets (FFJOFS_* constants), the only supported method.
struct FFEFFECT
{
DWORD dwSize; /* sizeof(FFEFFECT) */
DWORD dwFlags; /* FFEFF_* */
DWORD dwDuration; /* Microseconds */
DWORD dwSamplePeriod; /* Microseconds */
DWORD dwGain;
DWORD dwTriggerButton; /* or FFEB_NOTRIGGER */
DWORD dwTriggerRepeatInterval; /* Microseconds */
DWORD cAxes; /* Number of axes */
LPDWORD rgdwAxes; /* Array of axes */
LPLONG rglDirection; /* Array of directions */
PFFENVELOPE lpEnvelope; /* Optional */
DWORD cbTypeSpecificParams; /* Size of params */
void* lpvTypeSpecificParams; /* Pointer to params */
DWORD dwStartDelay; /* Microseconds */
};
typedef struct FFEFFECT FFEFFECT;
typedef FFEFFECT * PFFEFFECT;
struct FFEFFESCAPE
{
DWORD dwSize;
DWORD dwCommand;
void* lpvInBuffer;
DWORD cbInBuffer;
void* lpvOutBuffer;
DWORD cbOutBuffer;
};
typedef struct FFEFFESCAPE FFEFFESCAPE;
typedef FFEFFESCAPE * PFFEFFESCAPE;
// NOTE: this structure has no DirectInput equivalent
struct FFCAPABILITIES
{
NumVersion ffSpecVer; // Version of specification supported by the driver
UInt32 supportedEffects; // FFCAP_ET_*; including emulated effects
UInt32 emulatedEffects; // FFCAP_ET_*; driver-emulated effects
UInt32 subType; // FFCAP_TYPE_*
UInt32 numFfAxes;
UInt8 ffAxes[32];
UInt32 storageCapacity; // number of effects that can be stored
// by the driver/device
UInt32 playbackCapacity; // number of effects that can be _simultaneously_
// played back by the driver/device
NumVersion firmwareVer; // device firmware version, vendor-defined
NumVersion hardwareVer; // hardware version, vendor-defined
NumVersion driverVer; // driver version, vendor-defined
};
typedef struct FFCAPABILITIES FFCAPABILITIES;
typedef FFCAPABILITIES * PFFCAPABILITIES;
//-----------------------------------------------------------------------------
// Object reference pointers
//-----------------------------------------------------------------------------
// FFDeviceObjectReference and FFEffectObjectReference are opaque handles
// to objects created and maintained by the FF API.
// A FFDeviceObjectReference is obtained through a call to FFCreateDevice and
// refers to a specific attached device supporting force feedback. This
// reference may be passed to any of the "FFDevice" functions (below). When
// you are through with it, call FFReleaseDevice to release the memory.
// Similarly, a FFEffectObjectReference is obtained through a call to
// FFDeviceCreateEffect and refers to a created force feedback effect on a
// particular device. This reference may be passed to any of the "FFEffect"
// functions. Call FFDeviceReleaseEffect to unload the effect and clean up
// its memory. - Jeff Mallett 9/25/02
//
typedef struct {} __FFDHIDDEN, * FFDeviceObjectReference;
typedef struct {} __FFEHIDDEN, * FFEffectObjectReference;
//-----------------------------------------------------------------------------
// FF (general) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFCreateDevice
@abstract Creates a new API device object from an OS object in preparation to use the device for force feedback.
@param hidDevice Pointer to a HID device object.
@param pdeviceReference Address of a variable to receive an opaque reference handle to a new device object. This reference can be used in subsequent calls to FFDevice* functions
@result If the method succeeds, and the device supports FF, the return value is FF_OK.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br> FFERR_INTERNAL
<br>
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object.
*/
extern HRESULT
FFCreateDevice(
io_service_t hidDevice,
FFDeviceObjectReference * pDeviceReference
);
/*! @function FFReleaseDevice
@abstract Disposes of an API device object created with FFCreateDevice.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@result If the method succeeds, and the device supports FF, the return value is FF_OK.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br>
@discussion
*/
extern HRESULT
FFReleaseDevice(
FFDeviceObjectReference deviceReference
);
/*! @function FFIsForceFeedback
@abstract Used to determine if a particular device provided by HID Manager is a force feedback device.
@param hidDevice Pointer to a HID device object to be tested for force feedback support.
@result If the method succeeds, and the device supports FF, the return value is FF_OK. If the method succeeds, and the device does not support FF, the return value is FFERR_NOINTERFACE. If the method fails, the return value is FFERR_INVALIDPARAM
@discussion When you are finished with the device, FFReleaseDevice must be called on the reference received in this function to dispose of the API device object.
*/
extern HRESULT
FFIsForceFeedback(
io_service_t hidDevice
);
//-----------------------------------------------------------------------------
// FFDevice (device related) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFDeviceCreateEffect
@abstract Creates and initializes an instance of an effect identified by the effect UUID on the device.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param uuidRef Reference to the UUID identifying the effect to be created. Only predefined effect UUIDs are accepted. The following standard effect UUIDs are defined:
<br>
<br> kFFEffectType_ConstantForce_ID
<br> kFFEffectType_RampForce_ID
<br> kFFEffectType_Square_ID
<br> kFFEffectType_Sine_ID
<br> kFFEffectType_Triangle_ID
<br> kFFEffectType_SawtoothUp_ID
<br> kFFEffectType_SawtoothDown_ID
<br> kFFEffectType_Spring_ID
<br> kFFEffectType_Damper_ID
<br> kFFEffectType_Inertia_ID
<br> kFFEffectType_Friction_ID
<br> kFFEffectType_CustomForce_ID
<br>
<br>
@param pEffectDefinition Pointer to FFEFFECT structure that provides parameters for the created effect. This parameter is optional. If it is NULL, the effect object is created without parameters. The application must then call the FFEffectSetParameters function to set the parameters of the effect before it can download the effect.
@param pEffectReference Address of a variable to receive an opaque reference handle to a new effect object. This reference can be used in subsequent calls to FFEffect* functions.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTEDAXIS
<br> FFERR_OUTOFMEMORY
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
@discussion When you are finished with the effect, FFReleaseEffect must be called on the reference received in this function to dispose of the API effect object.
*/
extern HRESULT
FFDeviceCreateEffect(
FFDeviceObjectReference deviceReference,
CFUUIDRef uuidRef,
FFEFFECT * pEffectDefinition,
FFEffectObjectReference * pEffectReference
);
/*! @function FFDeviceReleaseEffect
@abstract Disposes of an API effect object created with FFDeviceCreateEffect.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFDeviceReleaseEffect(
FFDeviceObjectReference deviceReference,
FFEffectObjectReference effectReference
);
/*! @function FFDeviceEscape
@abstract Sends a hardware-specific command to the device.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param pFFEffectEscape Pointer to FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTED
<br>
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver.
*/
extern HRESULT
FFDeviceEscape(
FFDeviceObjectReference deviceReference,
FFEFFESCAPE * pFFEffectEscape
);
/*! @function FFDeviceGetForceFeedbackState
@abstract Retrieves the state of the device's force feedback system.
@param deviceReference An opaque reference handle to a device object. This is obtained from a previous call to FFCreateDevice.
@param pFFState Location for flags that describe the current state of the device's force feedback system.
The value is a combination of the following constants:
<br>
<br> FFGFFS_ACTUATORSOFF
<br> The device's force feedback actuators are disabled.
<br>
<br> FFGFFS_ACTUATORSON
<br> The device's force feedback actuators are enabled.
<br>
<br> FFGFFS_DEVICELOST
<br> The device suffered an unexpected failure and is in an indeterminate state. It must be reset either by unacquiring and reacquiring the device, or by sending a FFSFFC_RESET command.
<br>
<br> FFGFFS_EMPTY
<br> The device has no downloaded effects.
<br>
<br> FFGFFS_PAUSED
<br> Playback of all active effects has been paused.
<br>
<br> FFGFFS_POWEROFF
<br> The force feedback system is not currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.
<br>
<br> FFGFFS_POWERON
<br> Power to the force feedback system is currently available. If the device cannot report the power state, neither FFGFFS_POWERON nor FFGFFS_POWEROFF is returned.
<br>
<br> FFGFFS_SAFETYSWITCHOFF
<br> The safety switch is currently off; that is, the device cannot operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.
<br>
<br> FFGFFS_SAFETYSWITCHON
<br> The safety switch is currently on; that is, the device can operate. If the device cannot report the state of the safety switch, neither FFGFFS_SAFETYSWITCHON nor FFGFFS_SAFETYSWITCHOFF is returned.
<br>
<br> FFGFFS_STOPPED
<br> No effects are playing, and the device is not paused.
<br>
<br> FFGFFS_USERFFSWITCHOFF
<br> The user force feedback switch is currently off; that is, the device cannot operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.
<br>
<br> FFGFFS_USERFFSWITCHON
<br> The user force feedback switch is currently on; that is, the device can operate. If the device cannot report the state of the user force feedback switch, neither FFGFFS_USERFFSWITCHON nor FFGFFS_USERFFSWITCHOFF is returned.
<br>
<br> Future versions can define additional flags. Applications should ignore any flags that are not currently defined.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackState(
FFDeviceObjectReference deviceReference,
FFState * pFFState
);
/*! @function FFDeviceSendForceFeedbackCommand
@abstract Sends a command to the device's force feedback system.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param flags Single value indicating the desired change in state. The value can be one of the following:
<br>
<br> FFSFFC_CONTINUE
<br> Paused playback of all active effects is to be continued. It is an error to send this command when the device is not in a paused state.
<br>
<br> FFSFFC_PAUSE
<br> Playback of all active effects is to be paused. This command also stops the clock-on effects so that they continue playing to their full duration when restarted.
<br>
<br> While the device is paused, new effects cannot be started, and existing ones cannot be modified. Doing so can cause the subsequent FFSFFC_CONTINUE command to fail to perform properly.
<br>
<br> To abandon a pause and stop all effects, use the FFSFFC_STOPALL or FFSFCC_RESET commands.
<br>
<br> FFSFFC_RESET
<br> The device's force feedback system is to be put in its startup state. All effects are removed from the device, are no longer valid, and must be recreated if they are to be used again. The device's actuators are disabled.
<br>
<br> FFSFFC_SETACTUATORSOFF
<br> The device's force feedback actuators are to be disabled. While the actuators are off, effects continue to play but are ignored by the device. Using the analogy of a sound playback device, they are muted, rather than paused.
<br>
<br> FFSFFC_SETACTUATORSON
<br> The device's force feedback actuators are to be enabled.
<br>
<br> FFSFFC_STOPALL
<br> Playback of any active effects is to be stopped. All active effects are reset, but are still being maintained by the device and are still valid. If the device is in a paused state, that state is lost.
<br>
<br> This command is equivalent to calling the FFEffect_Stop method for each effect playing.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_INTERNAL
<br>
@discussion
*/
extern HRESULT
FFDeviceSendForceFeedbackCommand(
FFDeviceObjectReference deviceReference,
FFCommandFlag flags
);
/*! @function FFDeviceSetForceFeedbackProperty
@abstract Retrieves the device's force feedback capabilities.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param property The following property values are defined for a FF device:
<br>
<br> FFPROP_AUTOCENTER
<br> Specifies whether the actuated FF axes are self-centering. This property controls the device's "default centering spring".
<br> The pValue member points to a UInt32 can be one of the following values.
<br> 0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
<br> 1 - ON: The device should automatically center when the user releases the device.
<br> Not all devices support the autocenter property.
<br>
<br> FFPROP_FFGAIN
<br> Sets the gain for the device.
<br> The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
<br> Setting a gain value is useful when an application wants to scale down the strength of all force feedback effects uniformly, based on user preferences.
@param pValue Address of the location where the property value is to be read. SetForceFeedbackProperty will assume that the data is valid, and of the correct type.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceSetForceFeedbackProperty(
FFDeviceObjectReference deviceReference,
FFProperty property,
void * pValue
);
/*! @function FFDeviceGetForceFeedbackProperty
@abstract Gets properties that define the device behavior.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param property The following property values are defined for a FF device (see FFDeviceSetForceFeedbackProperty for details):
<br>
<br> FFPROP_AUTOCENTER
<br> FFPROP_FFGAIN
<br>
@param pValue Address of the location where the value associated with the property is to be stored. GetForceFeedbackProperty assumes that the pointer is valid, although it will perform a size check before writing the data to pValue
@param valueSize Size, in bytes, of data area pointed to by pValue. Size is compared to expected property size, and the function fails if a mismatch occurs.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackProperty(
FFDeviceObjectReference deviceReference,
FFProperty property,
void * pValue,
IOByteCount valueSize
);
/*! @function FFDeviceSetCooperativeLevel
@abstract Function is unimplemented in version 1.0 of this API
@discussion
*/
extern HRESULT
FFDeviceSetCooperativeLevel(
FFDeviceObjectReference deviceReference,
void * taskIdentifier,
FFCooperativeLevelFlag flags
);
/*! @function FFDeviceGetForceFeedbackCapabilities
@abstract Retrieves the device's force feedback capabilities.
@param deviceReference An opaque reference handle to the device object that is be disposed of. This handle is obtained from a previous call to FFCreateDevice.
@param pFFCapabilities Pointer to a FFCAPABILITIES structure that is to be filled in by the this call.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
@discussion
*/
extern HRESULT
FFDeviceGetForceFeedbackCapabilities(
FFDeviceObjectReference deviceReference,
FFCAPABILITIES * pFFCapabilities
);
//-----------------------------------------------------------------------------
// FFEffect (effect related) function prototypes
//-----------------------------------------------------------------------------
/*! @function FFEffectDownload
@abstract Places the effect on the device. If the effect is already on the device, the existing effect is updated to match the values set by the FFEffectSetParameters method.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK or S_FALSE. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
<br> If the method returns S_FALSE, the effect has already been downloaded to the device.
<br>
@discussion It is valid to update an effect while it is playing. The semantics of such an operation are explained in the reference for FFEffectSetParameters.
*/
extern HRESULT
FFEffectDownload(
FFEffectObjectReference effectReference
);
/*! @function FFEffectEscape
@abstract Sends a hardware-specific command to the driver.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffectEscape FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of bytes of the output buffer used.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_UNSUPPORTED
<br>
<br> Other device-specific error codes are also possible. Ask the hardware manufacturer for details
<br>
@discussion Because each driver implements different escapes, it is the application's responsibility to ensure that it is sending the escape to the correct driver.
*/
extern HRESULT
FFEffectEscape(
FFEffectObjectReference effectReference,
FFEFFESCAPE * pFFEffectEscape
);
/*! @function FFEffectGetEffectStatus
@abstract Sends a hardware-specific command to the driver.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFlags Pointer to status flags for the effect. The value can be 0 or one or more of the following constants:
<br>
<br> FFEGES_PLAYING
<br> The effect is playing.
<br>
<br> FFEGES_EMULATED
<br> The effect is emulated.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br>
@discussion
*/
extern HRESULT
FFEffectGetEffectStatus(
FFEffectObjectReference effectReference,
FFEffectStatusFlag * pFlags
);
/*! @function FFEffectGetParameters
@abstract Retrieves information about an effect.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffect Address of a FFEFFECT structure that receives effect information. The dwSize member must be filled in by the application before calling this method.
@param flags Flags that specify which parts of the effect information are to be retrieved. The value can be 0 or one or more of the following constants:
<br>
<br> FFEP_ALLPARAMS
<br> The union of all other FFEP_* flags, indicating that all members of the FFEFFECT structure are being requested.
<br>
<br> FFEP_AXES
<br> The cAxes and rgdwAxes members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rgdwAxes member. If the buffer is too small, the method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
<br>
<br> FFEP_DIRECTION
<br> The cAxes and rglDirection members should receive data. The cAxes member on entry contains the size (in DWORDs) of the buffer pointed to by the rglDirection member. If the buffer is too small, the GetParameters method returns FFERR_MOREDATA and sets cAxes to the necessary size of the buffer.
<br> The dwFlags member must include at least one of the coordinate system flags (FFEFF_CARTESIAN, FFEFF_POLAR, or FFEFF_SPHERICAL). The API returns the direction of the effect in one of the coordinate systems you specified, converting between coordinate systems as necessary. On exit, exactly one of the coordinate system flags is set in the dwFlags member, indicating which coordinate system the FF API used. In particular, passing all three coordinate system flags retrieves the coordinates in exactly the same format in which they were set.
<br>
<br> FFEP_DURATION
<br> The dwDuration member should receive data.
<br>
<br> FFEP_ENVELOPE
<br> The lpEnvelope member points to a FFENVELOPE structure that should receive data. If the effect does not have an envelope associated with it, the lpEnvelope member is set to NULL.
<br>
<br> FFEP_GAIN
<br> The dwGain member should receive data.
<br>
<br> FFEP_SAMPLEPERIOD
<br> The dwSamplePeriod member should receive data.
<br>
<br> FFEP_STARTDELAY
<br> The dwStartDelay member should receive data.
<br>
<br> FFEP_TRIGGERBUTTON
<br> The dwTriggerButton member should receive data.
<br>
<br> FFEP_TRIGGERREPEATINTERVAL
<br> The dwTriggerRepeatInterval member should receive data.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> The lpvTypeSpecificParams member points to a buffer whose size is specified by the cbTypeSpecificParams member. On return, the buffer is filled in with the type-specific data associated with the effect, and the cbTypeSpecificParams member contains the number of bytes copied. If the buffer supplied by the application is too small to contain all the type-specific data, the method returns FFERR_MOREDATA, and the cbTypeSpecificParams member contains the required size of the buffer in bytes.
<br>
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_MOREDATA
<br>
@discussion Common errors resulting in a FFERR_INVALIDPARAM error include not setting the dwSize member of the FFEFFECT structure, passing invalid flags, or not setting up the members in the FFEFFECT structure properly in preparation for receiving the effect information.
*/
extern HRESULT
FFEffectGetParameters(
FFEffectObjectReference effectReference,
FFEFFECT * pFFEffect,
FFEffectParameterFlag flags
);
/*! @function FFEffectSetParameters
@abstract Sets the characteristics of an effect.
@param efffectRef An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param pFFEffect Address of a FFEFFECT structure that contains effect information. The dwSize member must be filled in by the application before calling this method, as well as any members specified by corresponding bits in the flags parameter.
@param flags Flags that specify which portions of the effect information are to be set and how the downloading of the parameters should be handled. The value can be 0 or one or more of the following constants:
<br>
<br> FFEP_AXES
<br> The cAxes and rgdwAxes members contain data.
<br>
<br> FFEP_DIRECTION
<br> The cAxes and rglDirection members contain data. The dwFlags member specifies (with FFEFF_CARTESIAN or FFEFF_POLAR) the coordinate system in which the values should be interpreted.
<br>
<br> FFEP_DURATION
<br> The dwDuration member contains data.
<br>
<br> FFEP_ENVELOPE
<br> The lpEnvelope member points to a FFENVELOPE structure that contains data. To detach any existing envelope from the effect, pass this flag and set the lpEnvelope member to NULL.
<br>
<br> FFEP_GAIN
<br> The dwGain member contains data.
<br>
<br> FFEP_NODOWNLOAD
<br> Suppress the automatic FFEffect_Download that is normally performed after the parameters are updated.
<br>
<br> FFEP_NORESTART
<br> Suppress the stopping and restarting of the effect to change parameters. See Remarks.
<br>
<br> FFEP_SAMPLEPERIOD
<br> The dwSamplePeriod member contains data.
<br>
<br> FFEP_START
<br> The effect is to be started (or restarted if it is currently playing) after the parameters are updated. By default, the play state of the effect is not altered.
<br>
<br> FFEP_STARTDELAY
<br> The dwStartDelay member contains data.
<br>
<br> FFEP_TRIGGERBUTTON
<br> The dwTriggerButton member contains data.
<br>
<br>
<br> The dwTriggerRepeatInterval member contains data.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> The lpvTypeSpecificParams and cbTypeSpecificParams members of the FFEFFECT structure contain the address and size of type-specific data for the effect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_UNSUPPORTEDAXIS
<br> FFERR_OUTOFMEMORY
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
@discussion The FFEffectSetParameters method automatically downloads the effect, but this behavior can be suppressed by setting the FFEP_NODOWNLOAD flag. If automatic download has been suppressed, you can manually download the effect by invoking the FFEffectDownload method.
<br>
<br> If the effect is playing while the parameters are changed, the new parameters take effect as if they were the parameters when the effect started.
<br>
<br> For example, suppose a periodic effect with a duration of three seconds is started. After two seconds, the direction of the effect is changed. The effect then continues for one additional second in the new direction. The envelope, phase, amplitude, and other parameters of the effect continue smoothly, as if the direction had not changed.
<br>
<br> In the same situation, if after two seconds the duration of the effect were changed to 1.5 seconds, the effect would stop.
<br>
<br> Normally, if the driver cannot update the parameters of a playing effect, the driver is permitted to stop the effect, update the parameters, and then restart the effect. Passing the FFEP_NORESTART flag suppresses this behavior. If the driver cannot update the parameters of an effect while it is playing, the error code FFERR_EFFECTPLAYING is returned, and the parameters are not updated.
<br>
<br> No more than one of the FFEP_NODOWNLOAD, FFEP_START, and FFEP_NORESTART flags should be set. (It is also valid to pass none of them.)
<br>
<br> These three flags control download and playback behavior as follows:
<br>
<br> If FFEP_NODOWNLOAD is set, the effect parameters are updated but not downloaded to the device.
<br>
<br> If the FFEP_START flag is set, the effect parameters are updated and downloaded to the device, and the effect is started just as if the FFEffect_Start method had been called with the dwIterations parameter set to 1 and with no flags. (Combining the update with FFEP_START is slightly faster than calling Start separately, because it requires less information to be transmitted to the device.)
<br>
<br> If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is not playing, the parameters are updated and downloaded to the device.
<br>
<br> If neither FFEP_NODOWNLOAD nor FFEP_START is set and the effect is playing, the parameters are updated if the device supports on-the-fly updating. Otherwise the behavior depends on the state of the FFEP_NORESTART flag. If it is set, the error code FFERR_EFFECTPLAYING is returned. If it is clear, the effect is stopped, the parameters are updated, and the effect is restarted.
*/
extern HRESULT
FFEffectSetParameters(
FFEffectObjectReference effectReference,
FFEFFECT * pFFEffect,
FFEffectParameterFlag flags
);
/*! @function FFEffectStart
@abstract Begins playing an effect. If the effect is already playing, it is restarted from the beginning. If the effect has not been downloaded or has been modified since its last download, it is downloaded before being started. This default behavior can be suppressed by passing the FFES_NODOWNLOAD flag.
@param efffectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@param iterations Number of times to play the effect in sequence. The envelope is re-articulated with each iteration.
<br>
<br> To play the effect exactly once, pass 1. To play the effect repeatedly until explicitly stopped, pass INFINITE. To play the effect until explicitly stopped without re-articulating the envelope, modify the effect parameters with the FFEffect_SetParameters method, and change the dwDuration member to INFINITE.
@param flags Flags that describe how the effect should be played by the device. The value can be 0 or one or more of the following values:
<br>
<br> FFES_SOLO
<br> All other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects already started on the device.
<br>
<br> FFES_NODOWNLOAD
<br> Do not automatically download the effect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br> FFERR_GENERIC
<br>
@discussion Not all devices support multiple iterations.
*/
extern HRESULT
FFEffectStart(
FFEffectObjectReference effectReference,
UInt32 iterations,
FFEffectStartFlag flags
);
/*! @function FFEffectStop
@abstract Stops playing an effect.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFEffectStop(
FFEffectObjectReference effectReference
);
/*! @function FFEffectUnload
@abstract Removes the effect from the device. If the effect is playing, it is automatically stopped before it is unloaded.
@param effectReference An opaque reference handle to an effect object. This is obtained from a previous call to FFDeviceCreateEffect.
@result If the method succeeds, the return value is FF_OK. If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOTDOWNLOADED
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br> FFERR_INVALIDDOWNLOADID
<br>
@discussion
*/
extern HRESULT
FFEffectUnload(
FFEffectObjectReference effectReference
);
#ifdef __cplusplus
}
#endif
#endif // _FORCEFEEDBACK_H_

View File

@ -0,0 +1,572 @@
//-----------------------------------------------------------------------------
// File: ForceFeedbackConstants.h
// Contains: Public interfaces for ForceFeedback technology.
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _FORCEFEEDBACKCONSTANTS_H_
#define _FORCEFEEDBACKCONSTANTS_H_
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! @header ForceFeedbackConstants.h
@abstract Constants used in the public interfaces to the Force Feedback implementation in Mac OS X.
@discussion This header file contains the Effect type UUIDs, type definitions used in the API, force feedback
constants and error values used by the API.
*/
//-----------------------------------------------------------------------------
// General defines
//-----------------------------------------------------------------------------
#if !defined( DWORD )
typedef UInt32 DWORD;
typedef DWORD* LPDWORD;
#endif
#if !defined( LONG )
typedef SInt32 LONG;
typedef LONG* LPLONG;
#endif
#define FF_INFINITE 0xFFFFFFFF
#define FF_DEGREES 100
#define FF_FFNOMINALMAX 10000
#define FF_SECONDS 1000000
//-----------------------------------------------------------------------------
// Effect type UUIDs
//-----------------------------------------------------------------------------
// E559C460-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_ConstantForce_ID
@discussion UUID for a constant force effect type
*/
#define kFFEffectType_ConstantForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x60, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C461-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_RampForce_ID
@discussion UUID for a ramp force effect type
*/
#define kFFEffectType_RampForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x61, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C462-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Square_ID
@discussion UUID for a square wave effect type
*/
#define kFFEffectType_Square_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x62, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C463-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Sine_ID
@discussion UUID for a sine wave effect type
*/
#define kFFEffectType_Sine_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x63, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C464-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Sine_ID
@discussion UUID for a sine wave effect type
*/
#define kFFEffectType_Triangle_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x64, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C465-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_SawtoothUp_ID
@discussion UUID for a upwards sawtooth wave effect type
*/
#define kFFEffectType_SawtoothUp_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x65, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C466-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_SawtoothDown_ID
@discussion UUID for a downwards sawtooth wave effect type
*/
#define kFFEffectType_SawtoothDown_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x66, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C467-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Spring_ID
@discussion UUID for a spring effect type
*/
#define kFFEffectType_Spring_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x67, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C468-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Damper_ID
@discussion UUID for a damper effect type
*/
#define kFFEffectType_Damper_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x68, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C469-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Inertia_ID
@discussion UUID for an inertia effect type
*/
#define kFFEffectType_Inertia_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x69, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C46A-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_Friction_ID
@discussion UUID for a friction effect type
*/
#define kFFEffectType_Friction_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x6A, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
// E559C46B-C5CD-11D6-8A1C-00039353BD00
/*!
@defined kFFEffectType_CustomForce_ID
@discussion UUID for a custom force effect type
*/
#define kFFEffectType_CustomForce_ID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xE5, 0x59, 0xC4, 0x6B, 0xC5, 0xCD, 0x11, 0xD6, \
0x8A, 0x1C, 0x00, 0x03, 0x93, 0x53, 0xBD, 0x00)
//-----------------------------------------------------------------------------
// Effect definition constants
//-----------------------------------------------------------------------------
// FFEFFECT.dwFlags constants
// IMPORTANT NOTE: OBJECT IDS cannot be used to identify trigger buttons
// in FFEFFECT.dwTriggerButton, and output axes in FFEFFECT.rgdwAxes[n].
// Please use object offsets (FFJOFS_* constants), the only supported method.
// #define FFEFF_OBJECTIDS 0x00000001
#define FFEFF_OBJECTOFFSETS 0x00000002
typedef UInt32 FFCoordinateSystemFlag;
enum
{
FFEFF_CARTESIAN = 0x00000010,
FFEFF_POLAR = 0x00000020,
FFEFF_SPHERICAL = 0x00000040
};
// Effect Parameter flags for use in calls to FFEffectGetParameters() and FFEffectSetParameters()
//
typedef UInt32 FFEffectParameterFlag;
enum
{
FFEP_DURATION = 0x00000001,
FFEP_SAMPLEPERIOD = 0x00000002,
FFEP_GAIN = 0x00000004,
FFEP_TRIGGERBUTTON = 0x00000008,
FFEP_TRIGGERREPEATINTERVAL = 0x00000010,
FFEP_AXES = 0x00000020,
FFEP_DIRECTION = 0x00000040,
FFEP_ENVELOPE = 0x00000080,
FFEP_TYPESPECIFICPARAMS = 0x00000100,
FFEP_STARTDELAY = 0x00000200,
FFEP_ALLPARAMS = 0x000003FF,
FFEP_START = 0x20000000,
FFEP_NORESTART = 0x40000000,
FFEP_NODOWNLOAD = 0x80000000,
FFEB_NOTRIGGER = 0xFFFFFFFF
};
// Effect Parameter flags for use in calls to FFEffectStart()
//
typedef UInt32 FFEffectStartFlag;
enum
{
FFES_SOLO = 0x00000001,
FFES_NODOWNLOAD = 0x80000000
};
// Effect Parameter flags for use in calls to FFEffectGetEffectStatus()
//
typedef UInt32 FFEffectStatusFlag;
enum
{
FFEGES_NOTPLAYING = 0x00000000,
FFEGES_PLAYING = 0x00000001,
FFEGES_EMULATED = 0x00000002
};
// command flags for FFDeviceSendForceFeedbackCommand()
//
typedef UInt32 FFCommandFlag;
enum
{
FFSFFC_RESET = 0x00000001,
FFSFFC_STOPALL = 0x00000002,
FFSFFC_PAUSE = 0x00000004,
FFSFFC_CONTINUE = 0x00000008,
FFSFFC_SETACTUATORSON = 0x00000010,
FFSFFC_SETACTUATORSOFF = 0x00000020
};
// device state flags returned by FFDeviceGetForceFeedbackState()
//
typedef UInt32 FFState;
enum
{
FFGFFS_EMPTY = 0x00000001,
FFGFFS_STOPPED = 0x00000002,
FFGFFS_PAUSED = 0x00000004,
FFGFFS_ACTUATORSON = 0x00000010,
FFGFFS_ACTUATORSOFF = 0x00000020,
FFGFFS_POWERON = 0x00000040,
FFGFFS_POWEROFF = 0x00000080,
FFGFFS_SAFETYSWITCHON = 0x00000100,
FFGFFS_SAFETYSWITCHOFF = 0x00000200,
FFGFFS_USERFFSWITCHON = 0x00000400,
FFGFFS_USERFFSWITCHOFF = 0x00000800,
FFGFFS_DEVICELOST = 0x80000000
};
// axis and button "field offsets",
// used in
// FFEFFECT.dwTriggerButton
// FFEFFECT.rgdwAxes[n]
#define FFJOFS_X 0
#define FFJOFS_Y 4
#define FFJOFS_Z 8
#define FFJOFS_RX 12
#define FFJOFS_RY 16
#define FFJOFS_RZ 20
#define FFJOFS_SLIDER(n) (24 + (n) * sizeof(LONG))
#define FFJOFS_POV(n) (32 + (n) * sizeof(DWORD))
#define FFJOFS_BUTTON(n) (48 + (n))
#define FFJOFS_BUTTON0 FFJOFS_BUTTON(0)
#define FFJOFS_BUTTON1 FFJOFS_BUTTON(1)
#define FFJOFS_BUTTON2 FFJOFS_BUTTON(2)
#define FFJOFS_BUTTON3 FFJOFS_BUTTON(3)
#define FFJOFS_BUTTON4 FFJOFS_BUTTON(4)
#define FFJOFS_BUTTON5 FFJOFS_BUTTON(5)
#define FFJOFS_BUTTON6 FFJOFS_BUTTON(6)
#define FFJOFS_BUTTON7 FFJOFS_BUTTON(7)
#define FFJOFS_BUTTON8 FFJOFS_BUTTON(8)
#define FFJOFS_BUTTON9 FFJOFS_BUTTON(9)
#define FFJOFS_BUTTON10 FFJOFS_BUTTON(10)
#define FFJOFS_BUTTON11 FFJOFS_BUTTON(11)
#define FFJOFS_BUTTON12 FFJOFS_BUTTON(12)
#define FFJOFS_BUTTON13 FFJOFS_BUTTON(13)
#define FFJOFS_BUTTON14 FFJOFS_BUTTON(14)
#define FFJOFS_BUTTON15 FFJOFS_BUTTON(15)
#define FFJOFS_BUTTON16 FFJOFS_BUTTON(16)
#define FFJOFS_BUTTON17 FFJOFS_BUTTON(17)
#define FFJOFS_BUTTON18 FFJOFS_BUTTON(18)
#define FFJOFS_BUTTON19 FFJOFS_BUTTON(19)
#define FFJOFS_BUTTON20 FFJOFS_BUTTON(20)
#define FFJOFS_BUTTON21 FFJOFS_BUTTON(21)
#define FFJOFS_BUTTON22 FFJOFS_BUTTON(22)
#define FFJOFS_BUTTON23 FFJOFS_BUTTON(23)
#define FFJOFS_BUTTON24 FFJOFS_BUTTON(24)
#define FFJOFS_BUTTON25 FFJOFS_BUTTON(25)
#define FFJOFS_BUTTON26 FFJOFS_BUTTON(26)
#define FFJOFS_BUTTON27 FFJOFS_BUTTON(27)
#define FFJOFS_BUTTON28 FFJOFS_BUTTON(28)
#define FFJOFS_BUTTON29 FFJOFS_BUTTON(29)
#define FFJOFS_BUTTON30 FFJOFS_BUTTON(30)
#define FFJOFS_BUTTON31 FFJOFS_BUTTON(31)
// defines for FFDeviceGetForceFeedbackProperty() and FFDeviceSetForceFeedbackProperty()
//
typedef UInt32 FFProperty;
enum
{
FFPROP_FFGAIN = 1,
FFPROP_AUTOCENTER = 3
};
// flags for FFDeviceSetCooperativeLevel()
//
typedef UInt32 FFCooperativeLevelFlag;
enum
{
FFSCL_EXCLUSIVE = 0x00000001,
FFSCL_NONEXCLUSIVE = 0x00000002,
FFSCL_FOREGROUND = 0x00000004,
FFSCL_BACKGROUND = 0x00000008
};
// types used in FFCAPABILITIES structure
//
typedef UInt32 FFCapabilitiesEffectType;
enum
{
FFCAP_ET_CONSTANTFORCE = 0x00000001,
FFCAP_ET_RAMPFORCE = 0x00000002,
FFCAP_ET_SQUARE = 0x00000004,
FFCAP_ET_SINE = 0x00000008,
FFCAP_ET_TRIANGLE = 0x00000010,
FFCAP_ET_SAWTOOTHUP = 0x00000020,
FFCAP_ET_SAWTOOTHDOWN = 0x00000040,
FFCAP_ET_SPRING = 0x00000080,
FFCAP_ET_DAMPER = 0x00000100,
FFCAP_ET_INERTIA = 0x00000200,
FFCAP_ET_FRICTION = 0x00000400,
FFCAP_ET_CUSTOMFORCE = 0x00000800
};
typedef UInt32 FFCapabilitiesEffectSubType;
enum
{
FFCAP_ST_KINESTHETIC = 1,
FFCAP_ST_VIBRATION = 2
};
//-----------------------------------------------------------------------------
// Error return values
//-----------------------------------------------------------------------------
/*!
@defined FF_OK
@discussion The operation completed successfully.
*/
#define FF_OK S_OK
/*!
@defined FF_FALSE
@discussion The operation did not complete successfully.
*/
#define FF_FALSE S_FALSE
/*!
@defined FF_DOWNLOADSKIPPED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but the effect was not
* downloaded because the FFEP_NODOWNLOAD flag was passed.
*/
#define FF_DOWNLOADSKIPPED ((HRESULT)0x00000003L)
/*!
@defined FF_EFFECTRESTARTED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but in order to change
* the parameters, the effect needed to be restarted.
*/
#define FF_EFFECTRESTARTED ((HRESULT)0x00000004L)
/*!
@defined FF_TRUNCATED
* @discussion
* The parameters of the effect were successfully updated by
* FFEffectSetParameters, but some of them were
* beyond the capabilities of the device and were truncated.
*/
#define FF_TRUNCATED ((HRESULT)0x00000008L)
/*!
@defined FF_TRUNCATEDANDRESTARTED
* @discussion
* Equal to FF_EFFECTRESTARTED | FF_TRUNCATED.
*/
#define FF_TRUNCATEDANDRESTARTED ((HRESULT)0x0000000CL)
/*!
@defined FFERR_DEVICENOTREG
* @discussion
* The device or device instance or effect is not registered.
*/
#define FFERR_DEVICENOTREG REGDB_E_CLASSNOTREG
/*!
@defined FFERR_INVALIDPARAM
* @discussion
* An invalid parameter was passed to the returning function,
* or the object was not in a state that admitted the function
* to be called.
*/
#define FFERR_INVALIDPARAM E_INVALIDARG
/*!
@defined FFERR_NOINTERFACE
* @discussion
* The specified interface is not supported by the object
*/
#define FFERR_NOINTERFACE E_NOINTERFACE
/*!
@defined FFERR_GENERIC
* @discussion
* An undetermined error occurred.
*/
#define FFERR_GENERIC E_FAIL
/*!
@defined FFERR_OUTOFMEMORY
* @discussion
* Couldn't allocate sufficient memory to complete the caller's request.
*/
#define FFERR_OUTOFMEMORY E_OUTOFMEMORY
/*!
@defined FFERR_UNSUPPORTED
* @discussion
* The function called is not supported at this time
*/
#define FFERR_UNSUPPORTED E_NOTIMPL
#ifndef E_PENDING
/*!
@defined E_PENDING
* @discussion
* Data is not yet available.
*/
#define E_PENDING 0x8000000AL
#endif
/*!
@defined FFERR_DEVICEFULL
* @discussion
* The device is full.
*/
#define FFERR_DEVICEFULL 0x80040201L
/*!
@defined FFERR_MOREDATA
* @discussion
* Not all the requested information fit into the buffer.
*/
#define FFERR_MOREDATA 0x80040202L
/*!
@defined FFERR_NOTDOWNLOADED
* @discussion
* The effect is not downloaded.
*/
#define FFERR_NOTDOWNLOADED 0x80040203L
/*!
@defined FFERR_HASEFFECTS
* @discussion
* The device cannot be reinitialized because there are still effects
* attached to it.
*/
#define FFERR_HASEFFECTS 0x80040204L
/*!
@defined FFERR_INCOMPLETEEFFECT
* @discussion
* The effect could not be downloaded because essential information
* is missing. For example, no axes have been associated with the
* effect, or no type-specific information has been created.
*/
#define FFERR_INCOMPLETEEFFECT 0x80040206L
/*!
@defined FFERR_EFFECTPLAYING
* @discussion
* An attempt was made to modify parameters of an effect while it is
* playing. Not all hardware devices support altering the parameters
* of an effect while it is playing.
*/
#define FFERR_EFFECTPLAYING 0x80040208L
/*!
@defined FFERR_UNPLUGGED
* @discussion
* The operation could not be completed because the device is not
* plugged in.
*/
#define FFERR_UNPLUGGED 0x80040209L
//
// Mac OS X specific
//
/*!
@defined FFERR_INVALIDDOWNLOADID
* @discussion
* The effect index provided by the API in downloadID is not recognized by the
* IOForceFeedbackLib driver.
*/
#define FFERR_INVALIDDOWNLOADID 0x80040300
/*!
@defined FFERR_DEVICEPAUSED
* @discussion
* When the device is paused via a call to FFDeviceSendForceFeedbackCommand(),
* other operations such as modifying existing effect parameters and creating
* new effects are not allowed.
*/
#define FFERR_DEVICEPAUSED 0x80040301
/*!
@defined FFERR_INTERNAL
* @discussion
* The IOForceFededbackLib driver has detected an internal fault. Often this
* occurs because of an unexpected internal code path.
*/
#define FFERR_INTERNAL 0x80040302
/*!
@defined FFERR_EFFECTTYPEMISMATCH
* @discussion
* The IOForceFededbackLib driver has received an effect modification request
* whose basic type does not match the defined effect type for the given effect.
*/
#define FFERR_EFFECTTYPEMISMATCH 0x80040303
/*!
@defined FFERR_UNSUPPORTEDAXIS
* @discussion
* The effect includes one or more axes that the device does not support.
*/
#define FFERR_UNSUPPORTEDAXIS 0x80040304
/*!
@defined FFERR_NOTINITIALIZED
* @discussion
* This object has not been initialized
*/
#define FFERR_NOTINITIALIZED 0x80040305
/*!
@defined FFERR_EFFECTTYPENOTSUPPORTED
* @discussion
* The effect type requested is not explicitly supported by the particular device.
*/
#define FFERR_EFFECTTYPENOTSUPPORTED 0x80040306
/*!
@defined FFERR_DEVICERELEASED
* @discussion
* The device has been released.
*/
#define FFERR_DEVICERELEASED 0x80040307
#ifdef __cplusplus
}
#endif
#endif // _FORCEFEEDBACKCONSTANTS_H_

View File

@ -0,0 +1,447 @@
//-----------------------------------------------------------------------------
// File: IOForceFeedbackLib.h
// Contains: Public interfaces for the Force Feedback Plugin architecture .
// Copyright: © 2002 by Apple Computer, Inc. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef _IOFORCEFEEDBACKLIB_H
#define _IOFORCEFEEDBACKLIB_H
#if PRAGMA_ONCE
#pragma once
#endif
/*! @header IOForceFeedbackLib.h
@abstract Public Interfaces and constants used to develop Force Feedback plugIns.
@discussion A force feedback device manufacturer might need to implement a plug in
to allow the Force Feedback Library to control the device. This header
file describes the functions that need to be implemented. This interface definition
follows Microsoft Windoes IDirectInputEffectDriver definition wherever it makes sense to do so.
Certain functions may contain more or fewer parameters than the Windows version
*/
#include <sys/cdefs.h>
__BEGIN_DECLS
#include <CoreFoundation/CoreFoundation.h>
#if COREFOUNDATION_CFPLUGINCOM_SEPARATE
#include <CoreFoundation/CFPlugInCOM.h>
#endif
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
#include <IOKit/IOTypes.h>
#include <ForceFeedback/ForceFeedback.h>
//====================================================================================================================
// The Version of the FF PlugIn API
//====================================================================================================================
//
enum {
kFFPlugInAPIMajorRev = 1,
kFFPlugInAPIMinorAndBugRev = 0,
kFFPlugInAPIStage = finalStage,
kFFPlugInAPINonRelRev = 0
};
//====================================================================================================================
// Defines
//====================================================================================================================
//
#define FFDEVICESTATE ForceFeedbackDeviceState
#define PFFDEVICESTATE ForceFeedbackDeviceStatePtr
// F4545CE5-BF5B-11D6-A4BB-0003933E3E3E
#define kIOForceFeedbackLibTypeID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xF4, 0x54, 0x5C, 0xE5, 0xBF, 0x5B, 0x11, 0xD6, \
0xA4, 0xBB, 0x00, 0x03, 0x93, 0x3E, 0x3E, 0x3E)
// 1C7C5850-BB6A-11D6-B75F-003065FBE6B0
#define kIOForceFeedbackDeviceInterfaceID CFUUIDGetConstantUUIDWithBytes(NULL, \
0x1C, 0x7C, 0x58, 0x50, 0xBB, 0x6A, 0x11, 0xD6, \
0xB7, 0x5F, 0x00, 0x30, 0x65, 0xFB, 0xE6, 0xB0)
//====================================================================================================================
// Structs
//====================================================================================================================
//
struct ForceFeedbackDeviceState
{
UInt32 dwSize;
UInt32 dwState;
UInt32 dwLoad;
};
typedef struct ForceFeedbackDeviceState ForceFeedbackDeviceState;
typedef ForceFeedbackDeviceState * ForceFeedbackDeviceStatePtr;
struct ForceFeedbackVersion
{
NumVersion apiVersion;
NumVersion plugInVersion;
};
typedef struct ForceFeedbackVersion ForceFeedbackVersion;
typedef ForceFeedbackVersion * ForceFeedbackVersionPtr;
//====================================================================================================================
// Types
//====================================================================================================================
//
typedef UInt32 FFEffectDownloadID;
//====================================================================================================================
//
// ForceFeedback Device Interface Functions available in version 1.0 of architecture
//
//====================================================================================================================
//
#define IOFORCEFEEDBACKDEVICE_FUNCS_100 \
\
HRESULT (*ForceFeedbackGetVersion)( void * self, \
ForceFeedbackVersion * version); \
\
HRESULT (*InitializeTerminate)( void * self, \
NumVersion forceFeedbackAPIVersion,\
io_object_t hidDevice, \
bool begin ); \
\
HRESULT (*DestroyEffect)( void * self, \
FFEffectDownloadID downloadID ); \
\
HRESULT (*DownloadEffect)( void * self, \
CFUUIDRef effectType, \
FFEffectDownloadID * pDownloadID, \
FFEFFECT * pEffect, \
FFEffectParameterFlag flags ); \
\
HRESULT (*Escape)( void * self, \
FFEffectDownloadID downloadID, \
FFEFFESCAPE * pEscape ); \
\
HRESULT (*GetEffectStatus)( void * self, \
FFEffectDownloadID downloadID, \
FFEffectStatusFlag * pStatusCode ); \
\
HRESULT (*GetForceFeedbackCapabilities)( void * self, \
FFCAPABILITIES * pCapabilities ); \
\
HRESULT (*GetForceFeedbackState)( void * self, \
ForceFeedbackDeviceState * pDeviceState ); \
\
HRESULT (*SendForceFeedbackCommand)( void * self, \
FFCommandFlag state ); \
\
HRESULT (*SetProperty)( void * self, \
FFProperty property, \
void * pValue ); \
\
HRESULT (*StartEffect)( void * self, \
FFEffectDownloadID downloadID, \
FFEffectStartFlag mode, \
UInt32 iterations ); \
\
HRESULT (*StopEffect)( void * self, \
FFEffectDownloadID downloadID );
//====================================================================================================================
//
// END OF DeviceInterface Functions available in version 1.0 of this API
//
//====================================================================================================================
//
struct IOForceFeedbackDeviceInterface {
IUNKNOWN_C_GUTS;
IOFORCEFEEDBACKDEVICE_FUNCS_100
};
typedef struct IOForceFeedbackDeviceInterface IOForceFeedbackDeviceInterface;
typedef IOForceFeedbackDeviceInterface * IOForceFeedbackDeviceInterfacePtr;
//====================================================================================================================
//
// ¥¥¥¥¥ The following is #ifdef out. It is here so that we can header doc this file without intruding in its
// ¥¥¥¥¥ readability.
//
//====================================================================================================================
//
#if 0
struct IOForceFeedbackDeviceInterface {
IUNKNOWN_C_GUTS;
/*! @function ForceFeedbackGetVersion
@abstract This function is used to determine driver and API version information.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param version Pointer to ForceFeedbackVersion structure that is to receive the required info. See the structure description for details.
@result Returns FF_OK if successful, or an error value otherwise.
*/
HRESULT (*ForceFeedbackGetVersion) (void * self, ForceFeedbackVersion * version);
/*! @function InitializeTerminate
@abstract This function is used to "create and destroy" particular device instances. It provides the FF plug-in driver with all the necessary start-up parameters.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param forceFeedbackAPIVersion The version number of FF API that loaded the effect driver. The plugIn should check that the major version of the forceFeedbackAPI version is the same as the major version of the API at the time the plugIn was compiled. If the major versions are different, then the plugIn API has changed and the plugIn will NOT be compatible with it.
<br>
If begin is false, this parameter is ignored.
@param hidDevice A device object that can be used by the FF plug-in to establish a connection to and communicate with the device. The caller will release the hidDevice device object with a call to IOObjectRelease() once the FF plug-in completes its InitializeTerminate processing, so a FF plug-in implementation should not make a copy of the io_object_t variable with the intention of using it outside the context of this call.
<br>
If begin is false, this parameter is ignored. (You can pass NULL.)
@param begin Nonzero if access to the device is beginning. Zero if the access to the device is ending. The FF API will call InitializeTerminate( begin=TRUE) when a FF device is first selected for use, and InitializeTerminate( begin=false) when the FF device is no longer needed.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INVALIDPARAM
<br> FFERR_NOINTERFACE
<br> FFERR_OUTOFMEMORY
<br>
*/
HRESULT (*InitializeTerminate)(void * self, NumVersion forceFeedbackAPIVersion, io_object_t hidDevice, bool begin );
/*! @function DestroyEffect
@abstract This function commands the device to "destroy" a currently downloaded effect. The effect ID and any data that is associated with the effect are freed and available for reallocation.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect ID that was obtained from the device when the effect was downloaded.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_GENERIC
<br> FFERR_INTERNAL
<br>
*/
HRESULT (*DestroyEffect)(void * self, FFEffectDownloadID downloadID );
/*! @function DownloadEffect
@abstract This function sends an effect to the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param effectType Indicates the type of effect being created. Valid UUIDs are listed as kFFEffectType_* constants in the ForceFeedbackConstants.h file. (Supported effect types include Sine, Square, Triangle, SawtoothUp, SawtoothDown, Constant, Spring, Damper, etc.).
@param pDownloadID On entry, this parameter points to the handle of the effect being downloaded. If the parameter points to a zero, then a new effect is downloaded. On exit, the FFEffectDownloadID pointed to by this parameter contains the new effect handle. On failure, the FFEffectDownloadID pointed to by this parameter is set to zero if the effect is lost, or left alone if the effect is still valid with its old parameters. Note that zero is never a valid effect handle.
@param pEffect The new parameters for the effect.
<br>
IMPORTANT NOTE: Unlike the IDirectInputEffectDriver specification, the axis and button values are NOT converted to object identifiers before they are handed over to the driver. In this case, the only supported method used to assign triggers and output axes is through object offsets, defined by the FFJOFS_* constants. Therefore, if a button is assigned to trigger an effect, FFEFFECT.dwTriggerButton will contain a constant of the form FFJOFS_BUTTONn. Similarly, output axes will be identified in FFEFFECT.rgdwAxes[n] as FFJOFS_X, FFJOFS_Y, etc.
@param flags Specifies which portions of the effect information have changed from the effect already on the device. This information is passed to drivers to allow for the optimization of effect modification. If an effect is being modified, a driver may be able to update the effect in its original position and transmit to the device only the information that has changed. Drivers are not, however, required to implement this optimization. All members of the FFEFFECT structure that are pointed to by the pEffect parameter are valid, and a driver may choose simply to update all parameters of the effect at each download. There may be zero, one, or more of the following:
<br>
<br> FFEP_DURATION
<br> Indicates the dwDuration member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_SAMPLEPERIOD
<br> Indicates the dwSamplePeriod member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_GAIN
<br> Indicates the dwGain member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_TRIGGERBUTTON
<br> Indicates the dwTriggerButton member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_TRIGGERREPEATINTERVAL
<br> Indicates the dwTriggerRepeatInterval member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_AXES
<br> Indicates the cAxes and rgdwAxes members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download.
<br>
<br> FFEP_DIRECTION
<br> Indicates the cAxes and rglDirection members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download. (The dwFlags member of the FFEFFECT structure specifies, through FFEFF_CARTESIAN or FFEFF_POLAR, the coordinate system in which the values should be interpreted.)
<br>
<br> FFEP_ENVELOPE
<br> Indicates the lpEnvelope member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download. If this flag is set and the lpEnvelope member is a NULL pointer, then the effect is being created with no envelope, or the existing envelope is being deleted.
<br>
<br> FFEP_TYPESPECIFICPARAMS
<br> Indicates the cbTypeSpecificParams and lpTypeSpecificParams members of the FFEFFECT structure are being downloaded for the first time or have changed since their last download.
<br>
<br> FFEP_STARTDELAY
<br> Indicates the dwStartDelay member of the FFEFFECT structure is being downloaded for the first time or has changed since its last download.
<br>
<br> FFEP_START
<br> Indicates that the effect is to be restarted from the beginning after the parameters of the effect have been updated. Note that the FFEP_NODOWNLOAD flag overrides the FFEP_START flag.
<br>
<br> FFEP_NORESTART
<br> If this flag is not specified, the effect device driver is permitted to restart the effect if doing so is necessary to change the specified parameters. Note that the FFEP_NODOWNLOAD and FFEP_START flags override this flag.
<br>
<br> FFEP_NODOWNLOAD
<br> Suppresses the automatic download that is normally performed after the parameters are updated. If this flag is set, the driver should validate parameters without performing an actual download.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_INVALIDDOWNLOADID
<br> FFERR_INTERNAL
<br> FFERR_EFFECTTYPEMISMATCH
<br>
*/
HRESULT (*DownloadEffect)( void * self, CFUUIDRef effectType, FFEffectDownloadID * pDownloadID,
FFEFFECT * pEffect, FFEffectParameterFlag flags );
/*! @function Escape
@abstract This function escapes to the driver. This method is called in response to an application invoking the FFEffectEscape or FFDeviceEscape methods.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Specifies the effect at which the command is directed, or zero if the command is directed at the device itself and not any particular effect.
@param pEscape Pointer to a FFEFFESCAPE structure that describes the command to be sent. On success, the cbOutBuffer member contains the number of output buffer bytes actually used.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_UNSUPPORTED
<br>
*/
HRESULT (*Escape)( void * self, FFEffectDownloadID downloadID, FFEFFESCAPE * pEscape );
/*! @function GetEffectStatus
@abstract This function returns the device effect's status.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be queried.
@param pStatusCode Receives the effect status. The FFEffectStatusFlag pointed to by this parameter should be filled in with one of the following values:
<br>
<br> FFEGES_PLAYING
<br> The effect is still playing.
<br>
<br> FFEGES_NOTPLAYING
<br> The effect is not playing.
@result Returns FF_OK.
*/
HRESULT (*GetEffectStatus)( void * self, FFEffectDownloadID downloadID, FFEffectStatusFlag * pStatusCode );
/*! @function GetForceFeedbackCapabilities
@abstract This function escapes to the driver. This method is called in response to an application invoking the FFEffectEscape or FFDevicEscape methods.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param pCapabilities Pointer to a FFCAPABILITIES structure that should be filled in with version information describing the hardware, firmware, and driver.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_NOINTERFACE
<br>
*/
HRESULT (*GetForceFeedbackCapabilities)( void * self, FFCAPABILITIES * pCapabilities );
/*! @function GetForceFeedbackState
@abstract This function returns the state of the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param pDeviceState Pointer to a ForceFeedbackDeviceState structure that receives the device state. FF API sets the dwSize member of the ForceFeedbackDeviceState structure to sizeof(ForceFeedbackDeviceState) before calling this method.
@result Returns FF_OK.
*/
HRESULT (*GetForceFeedbackState)( void * self, ForceFeedbackDeviceState * pDeviceState );
/*! @function SendForceFeedbackCommand
@abstract This function sends a command to the device.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param state Indicates the command being sent. That command can be one of the following:
<br>
<br> FFSFFC_RESET
<br> Indicates that playback of any active effects should be been stopped and that all effects should be removed from the device. Once the device has been reset, all effects are no longer valid and must be re-created.
<br>
<br> FFSFFC_STOPALL
<br> Indicates that playback of all effects should be stopped. Sending the FFSFFC_STOPALL command is equivalent to invoking the FFEffect_Stop method on all effects that are playing. If the device is in a paused state, the device driver is permitted to lose the paused state.
<br>
<br> FFSFFC_PAUSE
<br> Indicates that playback of all effects should be paused. When effects are paused, time "stops" until the FFSFFC_CONTINUE command is sent. For example, suppose an effect of five seconds' duration is started. After one second, all effects are paused. After two more seconds, all effects are continued. The effect should then play for four additional seconds. While a force-feedback device is paused, starting a new effect or modifying existing ones can cause the paused state to be lost.
<br>
<br> FFSFFC_CONTINUE
<br> Indicates that playback should be resumed at the point at which it was interrupted for those effects that were paused by a previous FFSCFFC_PAUSE command.
<br>
<br> FFSFFC_SETACTUATORSON
<br> Indicates that the device's force-feedback actuators should be enabled.
<br>
<br> FFSFFC_SETACTUATORSOFF
<br> Indicates that the device's force-feedback actuators should be disabled. If successful, force-feedback effects are "muted". Note that time continues to elapse while actuators are off. For example, suppose an effect of five seconds' duration is started. After one second, actuators are turned off. After two more seconds, actuators are turned back on. The effect should then play for two additional seconds.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_INVALIDPARAM
<br>
*/
HRESULT (*SendForceFeedbackCommand)( void * self, FFCommandFlag state );
/*! @function SetProperty
@abstract This function sets properties that define the device behavior.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param property The following property values are defined for a FF device:
<br>
<br> FFPROP_AUTOCENTER
<br> Specifies whether the actuated FF axes are self-centering. This property controls the deviceÕs Òdefault centering springÓ.
<br> The pValue member points to a UInt32 and can be one of the following values.
<br>
<br> 0 - OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.
<br>
<br> 1 - ON: The device should automatically center when the user releases the device.
<br>
<br> Not all devices support the autocenter property.
<br>
<br> FFPROP_FFGAIN
<br> Sets the gain for the device.
<br>
<br> The pValue member points to a UInt32 that contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90% of their nominal magnitudes.
<br>
<br> Setting a gain value is useful when an application wants to scale down the strength of all force-feedback effects uniformly, based on user preferences.
@param pValue Address of the location where the property value is to be read. This function will assume that the data is valid, and of the correct type.
@result If the method succeeds, the return value is FF_OK or FFERR_UNSUPPORTED.
If the method fails, the return value can be one of the following error values:
<br>
<br> FFERR_INVALIDPARAM
<br>
*/
HRESULT (*SetProperty)( void * self, FFProperty property, void * pValue );
/*! @function StartEffect
@abstract This function commands the device to play back an effect that was previously loaded.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be played.
@param mode Specifies how the effect is to affect other effects. Only the mode listed below can be used; all other modes are reserved. For example, the driver never receives the FFES_NODOWNLOAD flag because it is managed by the FF API and not the PlugIn driver. This parameter can be zero, one, or more of the following flags:
<br>
<br> FFES_SOLO
<br> Indicates that all other effects on the device should be stopped before the specified effect is played. If this flag is omitted, the effect is mixed with existing effects that have already started on the device.
@param iterations Specifies the number of times to perform the effect. If the value is FF_INFINITE, then the effect should be repeated until explicitly stopped or paused.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_DEVICEPAUSED
<br> FFERR_DEVICEFULL
<br> FFERR_GENERIC
<br> FFERR_INVALIDDOWNLOADID
<br>
*/
HRESULT (*StartEffect)( void * self, FFEffectDownloadID downloadID, FFEffectStartFlag mode, UInt32 iterations );
/*! @function StopEffect
@abstract This function commands the device to stop an effect that was previously started.
@discussion
@param self Pointer to the FFPlugInDriver implementation instance.
@param downloadID Indicates the effect to be stopped.
@result Returns FF_OK if successful, or an error value otherwise:
<br>
<br> FFERR_INTERNAL
<br> FFERR_GENERIC
<br> FFERR_INVALIDDOWNLOADID
<br>
*/
HRESULT (*StopEffect)( void * self, UInt32 downloadID );
};
#endif // #if 0 ¥¥¥ Used for header doc'ing only
__END_DECLS
#endif /* ! _IOFORCEFEEDBACKLIB_H */

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>ForceFeedback</string>
<key>CFBundleGetInfoString</key>
<string>1.0.0, Copyright Apple Computer, Inc. 2002</string>
<key>CFBundleIdentifier</key>
<string>com.apple.ForceFeedback</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ForceFeedback Framework</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>70</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>ProjectName</key>
<string>ForceFeedback</string>
<key>ReleaseStatus</key>
<string>Beta</string>
<key>SourceVersion</key>
<string>1000305</string>
</dict>
</plist>

View File

@ -0,0 +1,476 @@
/*
File: HID_Utilities_External.h
Contains: Definition of the HID Utilities exported functions
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HID_Utilities_External_h_
#define _HID_Utilities_External_h_
// ==================================
//includes
#if TARGET_RT_MAC_CFM
typedef void (*IOHIDCallbackFunction)(void * target, unsigned long result, void* refcon, void * sender);
#else
#include <IOKit/hid/IOHIDLib.h>
#endif TARGET_RT_MAC_CFM
#include <stdio.h>
#if 0
#include <IOKit/hid/IOHIDUsageTables.h>
#include "PID.h" // NOTE: These are now in <IOHIDUsageTables.h>
#include "IOHIDPowerUsage.h" // NOTE: These are now in <IOHIDUsageTables.h>
#endif
#ifdef __MWERKS__
#define IOHIDEventStruct void
#endif
// ==================================
#ifdef __cplusplus
extern "C" {
#endif
// ==================================
// Device and Element Interfaces
typedef enum HIDElementTypeMask
{
kHIDElementTypeInput = 1 << 1,
kHIDElementTypeOutput = 1 << 2,
kHIDElementTypeFeature = 1 << 3,
kHIDElementTypeCollection = 1 << 4,
kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature,
kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection
}HIDElementTypeMask;
struct recElement
{
unsigned long type; // the type defined by IOHIDElementType in IOHIDKeys.h
long usagePage; // usage page from IOUSBHIDParser.h which defines general usage
long usage; // usage within above page from IOUSBHIDParser.h which defines specific usage
void * cookie; // unique value (within device of specific vendorID and productID) which identifies element, will NOT change
long min; // reported min value possible
long max; // reported max value possible
long scaledMin; // reported scaled min value possible
long scaledMax; // reported scaled max value possible
long size; // size in bits of data return from element
unsigned char relative; // are reports relative to last report (deltas)
unsigned char wrapping; // does element wrap around (one value higher than max is min)
unsigned char nonLinear; // are the values reported non-linear relative to element movement
unsigned char preferredState; // does element have a preferred state (such as a button)
unsigned char nullState; // does element have null state
long units; // units value is reported in (not used very often)
long unitExp; // exponent for units (also not used very often)
char name[256]; // name of element (c string)
// runtime variables
long calMin; // min returned value
long calMax; // max returned value (calibrate call)
long userMin; // user set value to scale to (scale call)
long userMax;
struct recElement * pPrevious; // previous element (NULL at list head)
struct recElement * pChild; // next child (only of collections)
struct recElement * pSibling; // next sibling (for elements and collections)
long depth;
};
typedef struct recElement recElement;
typedef recElement* pRecElement;
struct recDevice
{
void * interface; // interface to device, NULL = no interface
void * queue; // device queue, NULL = no queue
void * queueRunLoopSource; // device queue run loop source, NULL == no source
void * transaction; // output transaction interface, NULL == no interface
void * notification; // notifications
char transport[256]; // device transport (c string)
long vendorID; // id for device vendor, unique across all devices
long productID; // id for particular product, unique across all of a vendors devices
long version; // version of product
char manufacturer[256]; // name of manufacturer
char product[256]; // name of product
char serial[256]; // serial number of specific product, can be assumed unique across specific product or specific vendor (not used often)
long locID; // long representing location in USB (or other I/O) chain which device is pluged into, can identify specific device on machine
long usage; // usage page from IOUSBHID Parser.h which defines general usage
long usagePage; // usage within above page from IOUSBHID Parser.h which defines specific usage
long totalElements; // number of total elements (should be total of all elements on device including collections) (calculated, not reported by device)
long features; // number of elements of type kIOHIDElementTypeFeature
long inputs; // number of elements of type kIOHIDElementTypeInput_Misc or kIOHIDElementTypeInput_Button or kIOHIDElementTypeInput_Axis or kIOHIDElementTypeInput_ScanCodes
long outputs; // number of elements of type kIOHIDElementTypeOutput
long collections; // number of elements of type kIOHIDElementTypeCollection
long axis; // number of axis (calculated, not reported by device)
long buttons; // number of buttons (calculated, not reported by device)
long hats; // number of hat switches (calculated, not reported by device)
long sliders; // number of sliders (calculated, not reported by device)
long dials; // number of dials (calculated, not reported by device)
long wheels; // number of wheels (calculated, not reported by device)
recElement* pListElements; // head of linked list of elements
struct recDevice* pNext; // next device
};
typedef struct recDevice recDevice;
typedef recDevice* pRecDevice;
// ==================================
// HID Utilities interface
// ==================================
// Create and open an interface to device, required prior to extracting values or building queues
// Note: appliction now owns the device and must close and release it prior to exiting
extern unsigned long HIDCreateOpenDeviceInterface (UInt32 hidDevice, pRecDevice pDevice);
// builds list of device with elements (allocates memory and captures devices)
// list is allcoated internally within HID Utilites and can be accessed via accessor functions
// structures within list are considered flat and user accessable, butnot user modifiable
// can be called again to rebuild list to account for new devices (will do the right thing in case of disposing existing list)
extern Boolean HIDBuildDeviceList (UInt32 usagePage, UInt32 usage);
// release list built by above function
// MUST be called prior to application exit to properly release devices
// if not called (or app crashes) devices can be recovered by pluging into different location in USB chain
extern void HIDReleaseDeviceList (void);
// does a device list exist
extern Boolean HIDHaveDeviceList (void);
// how many HID devices have been found
// returns 0 if no device list exist
extern UInt32 HIDCountDevices (void);
// how many elements does a specific device have
// returns 0 if device is invalid or NULL
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get non-collection elements
extern UInt32 HIDCountDeviceElements (pRecDevice pDevice, HIDElementTypeMask typeMask);
// get the first device in the device list
// returns NULL if no list exists
extern pRecDevice HIDGetFirstDevice (void);
// get next device in list given current device as parameter
// returns NULL if end of list
extern pRecDevice HIDGetNextDevice (pRecDevice pDevice);
// get the first element of device passed in as parameter
// returns NULL if no list exists or device does not exists or is NULL
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality
extern pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask);
// get next element of given device in list given current element as parameter
// will walk down each collection then to next element or collection (depthwise traverse)
// returns NULL if end of list
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality
extern pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask);
// get previous element of given device in list given current element as parameter
// this wlaks directly up the tree to the top element and does not search at each level
// returns NULL if beginning of list
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get non-collection elements
extern pRecElement HIDGetPreviousDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask);
// returns C string type name given a type enumeration passed in as parameter (see IOHIDKeys.h)
// returns empty string for invlid types
extern void HIDGetTypeName (IOHIDElementType theType, char * cstrName);
// set name from vendor id/product id look up (using cookies)
extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName);
// set name from vendor id/product id look up (using usage page & usage)
extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName);
// returns C string usage given usage page and usage passed in as parameters (see IOUSBHIDParser.h)
// returns usage page and usage values in string form for unknown values
extern void HIDGetUsageName (long valueUsagePage, long valueUsage, char * cstrName);
// returns calibrated value given raw value passed in
// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values
extern SInt32 HIDCalibrateValue (SInt32 value, pRecElement pElement);
// returns scaled value given raw value passed in
// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values
extern SInt32 HIDScaleValue (SInt32 value, pRecElement pElement);
// ---------------------------------
// convert an element type to a mask
extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type);
// find this device
extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement,
pRecDevice *ppFoundDevice, pRecElement *ppFoundElement);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement);
// print out all of an elements information
extern int HIDPrintElement(const pRecElement pElement);
// return true if this is a valid device pointer
extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice);
// return true if this is a valid element pointer for this device
extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement);
// ==================================
// Element Event Queue and Value Interfaces
enum
{
kDefaultUserMin = 0, // default user min and max used for scaling
kDefaultUserMax = 255
};
enum
{
kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible
// but should account for the maximum possible events in the queue
// USB updates will likely occur at 100 Hz so one must account for this rate of
// if states change quickly (updates are only posted on state changes)
};
// ==================================
// queues specific element, performing any device queue set up required
extern unsigned long HIDQueueElement (pRecDevice pDevice, pRecElement pElement);
// adds all elements to queue, performing any device queue set up required
extern unsigned long HIDQueueDevice (pRecDevice pDevice);
// removes element for queue, if last element in queue will release queue and device
extern unsigned long HIDDequeueElement (pRecDevice pDevice, pRecElement pElement);
// completely removes all elements from queue and releases queue and device
extern unsigned long HIDDequeueDevice (pRecDevice pDevice);
// releases all device queues for quit or rebuild (must be called)
extern unsigned long HIDReleaseAllDeviceQueues (void);
// releases interface to device, should be done prior to exiting application (called from HIDReleaseDeviceList)
extern unsigned long HIDCloseReleaseInterface (pRecDevice pDevice);
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent);
// returns current value for element, creating device interface as required, polling element
extern long HIDGetElementValue (pRecDevice pDevice, pRecElement pElement);
// Set an elements value
// NOTE: This should only be used when a single element report needs to be sent.
// If multiple elements reports are to be send then transactions should be used.
// pIOHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern long HIDSetElementValue (pRecDevice pDevice, pRecElement pElement,void* pIOHIDEvent);
// Set a callback to be called when a queue goes from empty to non-empty
extern long HIDSetQueueCallback (pRecDevice pDevice, IOHIDCallbackFunction callback);
#if 0
// Get a report from a device
extern long HIDGetReport (pRecDevice pDevice,const IOHIDReportType reportType, const unsigned long reportID, void* reportBuffer, unsigned long* reportBufferSize);
// Send a report to a device
extern long HIDSetReport (pRecDevice pDevice,const IOHIDReportType reportType, const unsigned long reportID, void* reportBuffer, const unsigned long reportBufferSize);
#endif
// ==================================
// HUD utilities interfaces
// returns calibrated value given raw value passed in
// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values
extern long HIDCalibrateValue (long value, pRecElement pElement);
// returns scaled value given raw value passed in
// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values
extern long HIDScaleValue (long value, pRecElement pElement);
// convert an element type to a mask
extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type);
// find this device
extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement,
pRecDevice *ppFoundDevice, pRecElement *ppFoundElement);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement);
// print out all of an elements information
extern int HIDPrintElement(const pRecElement pElement);
// return true if this is a valid device pointer
extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice);
// return true if this is a valid element pointer for this device
extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement);
// ==================================
// Name Lookup Interfaces
// set name from vendor id/product id look up (using cookies)
extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName);
// set name from vendor id/product id look up (using usage page & usage)
extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName);
// ==================================
// Conguration and Save Interfaces
enum
{
kPercentMove = 10 // precent of overall range a element must move to register
};
typedef struct recSaveHID
{
long actionCookie;
// device
// need to add serial number when I have a test case
long vendorID;
long productID;
long locID;
long usage;
long usagePage;
// elements
long usagePageE;
long usageE;
void * cookie;
}recSaveHID,*pRecSaveHID;
// polls all devices and elements for a change greater than kPercentMove. Times out after given time
// returns true and pointer to device and element if found
// returns false and NULL for both parameters if not found
extern unsigned char HIDConfigureAction (pRecDevice * ppDevice, pRecElement * ppElement, float timeout);
// take input records, save required info
// assume file is open and at correct position.
extern void HIDSaveElementConfig (FILE * fileRef, pRecDevice pDevice, pRecElement pElement, long actionCookie);
// take file, read one record (assume file position is correct and file is open)
// search for matching device
// return pDevice, pElement and cookie for action
extern long HIDRestoreElementConfig (FILE * fileRef, pRecDevice * ppDevice, pRecElement * ppElement);
// Save the device & element values into the specified key in the specified applications preferences
extern Boolean HIDSaveElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice pDevice, pRecElement pElement);
// Find the specified preference in the specified application
// search for matching device and element
// return pDevice, pElement that matches
extern Boolean HIDRestoreElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice * ppDevice, pRecElement * ppElement);
// ==================================
// Output Transaction interface
// Create and open an transaction interface to device, required prior to extracting values or building Transactions
extern unsigned long HIDTransactionAddElement(pRecDevice pDevice, pRecElement pElement);
// removes an element from a Transaction
extern unsigned long HIDTransactionRemoveElement(pRecDevice pDevice, pRecElement pElement);
// return true if this transaction contains this element
extern Boolean HIDTransactionHasElement(pRecDevice pDevice, pRecElement pElement);
/* This changes the default value of an element, when the values of the */
/* elements are cleared, on clear or commit, they are reset to the */
/* default value */
/* This call can be made on elements that are not in the transaction, but */
/* has undefined behavior if made on elements not in the transaction */
/* which are later added to the transaction. */
/* In other words, an element should be added before its default is */
/* set, for well defined behavior. */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionSetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Get the current setting of an element's default value */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionGetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Add a change to the transaction, by setting an element value */
/* The change is not actually made until it is commited */
/* The element must be part of the transaction or this call will fail */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionSetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Get the current setting of an element value */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionGetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Commit the transaction, or clear all the changes and start over */
/* timoutMS is the timeout in milliseconds, a zero timeout will cause */
/* this call to be non-blocking (returning queue empty) if there */
/* is a NULL callback, and blocking forever until the queue is */
/* non-empty if their is a valid callback */
/* callback, if non-NULL is a callback to be called when data is */
/* inserted to the queue */
/* callbackTarget and callbackRefcon are passed to the callback */
extern unsigned long HIDTransactionCommit(pRecDevice pDevice);
/* Clear all the changes and start over */
extern unsigned long HIDTransactionClear(pRecDevice pDevice);
// ==================================
#ifdef __cplusplus
}
#endif
#endif // _HID_Utilities_External_h_

425
HID_Config_Utilities.c Executable file
View File

@ -0,0 +1,425 @@
/*
File: HID_Config_Utilities.c
Contains: Implementation of the HID configuration utilities for the HID utilities.
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h> // malloc
#include <time.h> // clock
#include <IOKit/hid/IOHIDUsageTables.h>
#include "HID_Utilities_Internal.h"
#include "HID_Utilities_External.h"
// ---------------------------------
// polls all devices and elements for a change greater than kPercentMove. Times out after given time
// returns 1 and pointer to device and element if found
// returns 0 and NULL for both parameters if not found
unsigned char HIDConfigureAction (pRecDevice * ppDevice, pRecElement * ppElement, float timeout)
{
long numDevices, maxElements = 0;
long * saveValueArray;
pRecDevice pDevice = NULL;
pRecElement pElement = NULL;
short deviceNum = 0;
unsigned char found = 0, done = 0;
clock_t start = clock (), end;
if (!HIDHaveDeviceList ()) // if we do not have a device list
if (0 == HIDBuildDeviceList (kHIDPage_GenericDesktop, 0)) // if we could not build another list (use generic page)
return 0; // return 0
// build list of device and elements to save current values
numDevices = HIDCountDevices ();
pDevice = HIDGetFirstDevice ();
while (pDevice)
{
long numElements = HIDCountDeviceElements (pDevice, kHIDElementTypeInput);
if (numElements > maxElements)
maxElements = numElements;
pDevice = HIDGetNextDevice (pDevice);
}
saveValueArray = (long *) malloc (sizeof (long) * numDevices * maxElements); // 2D array to save values
bzero(saveValueArray,sizeof (long) * numDevices * maxElements); // clear array
// store current values
deviceNum = 0;
pDevice = HIDGetFirstDevice ();
while (pDevice)
{
short elementNum = 0;
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeInput);
while (pElement)
{
*(saveValueArray + (deviceNum * maxElements) + elementNum) = HIDGetElementValue (pDevice, pElement);
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeInput);
elementNum++;
}
pDevice = HIDGetNextDevice (pDevice);
deviceNum++;
}
// poll all devices and elements, compare current value to save +/- kPercentMove
while ((!found) && (!done))
{
double secs;
// are we done?
end = clock();
secs = (double)(end - start) / CLOCKS_PER_SEC;
if (secs > timeout)
done = 1;
deviceNum = 0;
pDevice = HIDGetFirstDevice ();
while (pDevice)
{
short elementNum = 0;
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeInput);
while (pElement)
{
// ignore force feedback devices AND arrays
if ((kHIDPage_PID != pElement->usagePage) && (-1 != pElement->usage))
{
long initialValue = *(saveValueArray + (deviceNum * maxElements) + elementNum);
long value = HIDGetElementValue (pDevice, pElement);
long delta = (float)(pElement->max - pElement->min) * kPercentMove * 0.01;
if (((initialValue + delta) < value) || ((initialValue - delta) > value))
{
found = 1;
break;
}
}
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeInput);
elementNum++;
}
if (found)
break;
pDevice = HIDGetNextDevice (pDevice);
deviceNum++;
}
}
// return device and element moved
if (found)
{
*ppDevice = pDevice;
*ppElement = pElement;
return 1;
}
else
{
*ppDevice = NULL;
*ppElement = NULL;
return 0;
}
}
// ---------------------------------
// takes input records, save required info
// assume file is open and at correct position.
// will always write to file (if file exists) size of recSaveHID, even if device and or element is bad
void HIDSaveElementConfig (FILE * fileRef, pRecDevice pDevice, pRecElement pElement, long actionCookie)
{
recSaveHID saveRec;
if (HIDIsValidElement(pDevice,pElement))
{
// clear rec
bzero(&saveRec,sizeof(recSaveHID));
saveRec.actionCookie = actionCookie;
// must save
// actionCookie
// Device: serial,vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
// need to add serial number when I have a test case
saveRec.vendorID = pDevice->vendorID;
saveRec.productID = pDevice->productID;
saveRec.locID = pDevice->locID;
saveRec.usage = pDevice->usage;
saveRec.usagePage = pDevice->usagePage;
saveRec.usagePageE = pElement->usagePage;
saveRec.usageE = pElement->usage;
saveRec.cookie = pElement->cookie;
// write to file
if (fileRef)
fwrite ((void *)&saveRec, sizeof (recSaveHID), 1, fileRef);
}
}
// ---------------------------------
// take file, read one record (assume file position is correct and file is open)
// search for matching device
// return pDevice, pElement and cookie for action
long HIDRestoreElementConfig (FILE * fileRef, pRecDevice * ppDevice, pRecElement * ppElement)
{
// Device: serial,vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
pRecDevice pDevice, pFoundDevice = NULL;
pRecElement pElement, pFoundElement = NULL;
recSaveHID restoreRec;
fread ((void *) &restoreRec, 1, sizeof (recSaveHID), fileRef);
// compare to current device list for matches
// look for device
if (restoreRec.locID && restoreRec.vendorID && restoreRec.productID)
{ // look for specific device type plug in to same port
pDevice = HIDGetFirstDevice ();
while (pDevice)
{
if ((restoreRec.locID == pDevice->locID) &&
(restoreRec.vendorID == pDevice->vendorID) &&
(restoreRec.productID == pDevice->productID))
pFoundDevice = pDevice;
if (pFoundDevice)
break;
pDevice = HIDGetNextDevice (pDevice);
}
if (pFoundDevice)
{
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
while (pElement)
{
if (restoreRec.cookie == pElement->cookie)
pFoundElement = pElement;
if (pFoundElement)
break;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
// if no cookie match (should NOT occur) match on usage
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
while (pElement)
{
if ((restoreRec.usageE == pElement->usage) &&
(restoreRec.usagePageE == pElement->usagePage))
pFoundElement = pElement;
if (pFoundElement)
break;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
}
}
// if we have not found a match, look at just vendor and product
if ((NULL == pFoundDevice) &&
(restoreRec.vendorID && restoreRec.productID))
{
pDevice = HIDGetFirstDevice ();
while (pDevice)
{
if ((restoreRec.vendorID == pDevice->vendorID) &&
(restoreRec.productID == pDevice->productID))
pFoundDevice = pDevice;
if (pFoundDevice)
break;
pDevice = HIDGetNextDevice (pDevice);
}
// match elements by cookie since same device type
if (pFoundDevice)
{
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
while (pElement)
{
if (restoreRec.cookie == pElement->cookie)
pFoundElement = pElement;
if (pFoundElement)
break;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
// if no cookie match (should NOT occur) match on usage
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
while (pElement)
{
if ((restoreRec.usageE == pElement->usage) &&
(restoreRec.usagePageE == pElement->usagePage))
pFoundElement = pElement;
if (pFoundElement)
break;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
}
}
// if we have not found a match look for just same type of device
if ((NULL == pFoundDevice) && (restoreRec.usage && restoreRec.usagePage))
{
pDevice = HIDGetFirstDevice ();
while (pDevice)
{
if ((restoreRec.usage == pDevice->usage) && (restoreRec.usagePage == pDevice->usagePage))
pFoundDevice = pDevice;
if (pFoundDevice)
break;
pDevice = HIDGetNextDevice (pDevice);
}
// match elements by type
if (pFoundDevice)
{
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
while (pElement)
{
if ((restoreRec.usageE == pElement->usage) &&
(restoreRec.usagePageE == pElement->usagePage))
pFoundElement = pElement;
if (pFoundElement)
break;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
}
}
// if still not found just get first device
if (NULL == pFoundDevice)
{
pFoundDevice = HIDGetFirstDevice ();
// match elements by type
if (pFoundDevice)
{
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
while (pElement)
{
if ((restoreRec.usageE == pElement->usage) &&
(restoreRec.usagePageE == pElement->usagePage))
pFoundElement = pElement;
if (pFoundElement)
break;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
}
}
if ((NULL == pFoundDevice) || (NULL == pFoundElement))
{
// no HID device
*ppDevice = NULL;
*ppElement = NULL;
return restoreRec.actionCookie;
}
else
{
// no HID device
*ppDevice = pFoundDevice;
*ppElement = pFoundElement;
return restoreRec.actionCookie;
}
}
// ---------------------------------
// Find the specified preference in the specified application
// search for matching device and element
// return pDevice, pElement that matches
Boolean HIDRestoreElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice * ppDevice, pRecElement * ppElement)
{
Boolean found = false;
if ((NULL != keyCFStringRef) && (NULL != appCFStringRef) && (NULL != ppDevice) && (NULL != ppElement))
{
CFPropertyListRef prefCFPropertyListRef = CFPreferencesCopyAppValue(keyCFStringRef, appCFStringRef);
if (NULL != prefCFPropertyListRef)
{
if (CFStringGetTypeID() == CFGetTypeID(prefCFPropertyListRef))
{
char buffer[256];
if (CFStringGetCString((CFStringRef) prefCFPropertyListRef, buffer, sizeof(buffer), kCFStringEncodingASCII))
{
recDevice searchDevice;
recElement searchElement;
int count = sscanf(buffer, "d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld}",
&searchDevice.vendorID, &searchDevice.productID, &searchDevice.locID, &searchDevice.usagePage, &searchDevice.usage,
&searchElement.type, &searchElement.usagePage, &searchElement.usage, (long*) &searchElement.cookie);
if (9 == count) // if we found all nine parametersÉ
{ // and can find a device & element that matches theseÉ
if (HIDFindActionDeviceAndElement(&searchDevice, &searchElement,ppDevice, ppElement))
{
found = true;
}
}
}
}
else
{
// We found the entry with this key but it's the wrong type; delete it.
CFPreferencesSetAppValue(keyCFStringRef, NULL, appCFStringRef);
(void) CFPreferencesAppSynchronize(appCFStringRef);
}
CFRelease(prefCFPropertyListRef);
}
}
return found;
}
// ---------------------------------
// Save the device & element values into the specified key in the specified applications preferences
Boolean HIDSaveElementPref (const CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice pDevice, pRecElement pElement)
{
Boolean success = false;
if ((NULL != keyCFStringRef) && (NULL != appCFStringRef) && HIDIsValidElement(pDevice,pElement))
{
CFStringRef prefCFStringRef =
CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{t:%ld, p:%ld, u:%ld, c:%ld}"),
pDevice->vendorID, pDevice->productID, pDevice->locID, pDevice->usagePage, pDevice->usage,
pElement->type, pElement->usagePage, pElement->usage, pElement->cookie);
if (NULL != prefCFStringRef)
{
CFPreferencesSetAppValue(keyCFStringRef, prefCFStringRef, kCFPreferencesCurrentApplication);
CFRelease(prefCFStringRef);
success = true;
}
}
return success;
}

104
HID_Error_Handler.c Executable file
View File

@ -0,0 +1,104 @@
/*
File: Error Handler.c
Contains: Implementation of the HID utility error handlers for the HID Utilities
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined (kBuildingLibrary)
#define kVerboseErrors
// system includes ----------------------------------------------------------
#ifdef kVerboseErrors
#include <Carbon/Carbon.h>
#endif
#endif // not kBuildingLibrary
#include <stdio.h>
// project includes ---------------------------------------------------------
#include "HID_Utilities_Internal.h"
// globals (internal/private) -----------------------------------------------
// prototypes (internal/private) --------------------------------------------
// functions (internal/private) ---------------------------------------------
#pragma mark -
// -------------------------------------
// central error reporting
void HIDReportErrorNum (char * strError, long numError)
{
char errMsgCStr [256];
sprintf (errMsgCStr, "%s #%ld (0x%lx)", strError, numError, numError);
// out as debug string
#ifdef kVerboseErrors
{
Str255 strErr = "\p";
CopyCStringToPascal (errMsgCStr, strErr);
DebugStr (strErr);
}
#endif // kVerboseErrors
}
// -------------------------------------
void HIDReportError (char * strError)
{
char errMsgCStr [256];
sprintf (errMsgCStr, "%s", strError);
// out as debug string
#ifdef kVerboseErrors
{
Str255 strErr = "\p";
CopyCStringToPascal (errMsgCStr, strErr);
DebugStr (strErr);
}
#endif // kVerboseErrors
}

74
HID_Error_Handler.h Executable file
View File

@ -0,0 +1,74 @@
/*
File: HID_Error_Handler.h
Contains: Definition of the interfaces to <HID_Error_Handler.c>
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Usage notes:
// include control --------------------------------------------------
#ifndef Error_Handler_h
#define Error_Handler_h
// includes ---------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
// structures (public) -----------------------------------------------
// public function declarations -------------------------------------
// Error reporter, can be set to report however the application desires
extern void HIDReportError (char * strError);
// Error with numeric code reporter, can be set to report however the application desires
extern void HIDReportErrorNum (char * strError, long numError);
#ifdef __cplusplus
}
#endif
#endif // Error_Handler_h

347
HID_Name_Lookup.c Executable file
View File

@ -0,0 +1,347 @@
/*
File: HID_Name_Lookup.c
Contains: Implementation of the HID device name lookup functions for the HID utilites.
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "HID_Utilities_Internal.h"
#include "HID_Name_Lookup.h"
#define FAKE_IT 0 // set true for debugging; returns the vendor, product & cookie (or usage info) as numbers.
// ---------------------------------
// Load the element strings from the given resource (XML) file into a CFPropertyListRef
static CFPropertyListRef xml_load(const CFStringRef pResourceName,const CFStringRef pResourceExtension)
{
CFPropertyListRef tCFPropertyListRef = NULL;
CFURLRef resFileCFURLRef = CFBundleCopyResourceURL(CFBundleGetMainBundle(), pResourceName, pResourceExtension, NULL);
if (NULL != resFileCFURLRef)
{
CFDataRef resCFDataRef;
if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, resFileCFURLRef, &resCFDataRef, nil, nil, nil))
{
if (NULL != resCFDataRef)
{
CFStringRef errorString;
tCFPropertyListRef = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resCFDataRef, kCFPropertyListImmutable, &errorString);
if (NULL == tCFPropertyListRef)
CFShow(errorString);
CFRelease(resCFDataRef);
}
}
CFRelease(resFileCFURLRef);
}
return tCFPropertyListRef;
}
// ---------------------------------
// Find an element string in the <HID_cookie_strings.plist> resource (XML) file
static Boolean xml_search_cookie(const long pVendorID, const long pProductID, const long pCookie, char* pCstr)
{
static CFPropertyListRef tCFPropertyListRef = NULL;
Boolean results = false;
if (NULL == tCFPropertyListRef)
tCFPropertyListRef = xml_load(CFSTR("HID_cookie_strings"), CFSTR("plist"));
if (NULL != tCFPropertyListRef)
{
if (CFDictionaryGetTypeID() == CFGetTypeID(tCFPropertyListRef))
{
CFDictionaryRef vendorCFDictionaryRef;
CFStringRef vendorKeyCFStringRef;
vendorKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), pVendorID);
if (CFDictionaryGetValueIfPresent(tCFPropertyListRef, vendorKeyCFStringRef, (const void**) &vendorCFDictionaryRef))
{
CFDictionaryRef productCFDictionaryRef;
CFStringRef productKeyCFStringRef;
CFStringRef vendorCFStringRef;
if (CFDictionaryGetValueIfPresent(vendorCFDictionaryRef, CFSTR("Name"), (const void**) &vendorCFStringRef))
{
//CFShow(vendorCFStringRef);
}
productKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), pProductID);
if (CFDictionaryGetValueIfPresent(vendorCFDictionaryRef, productKeyCFStringRef, (const void**) &productCFDictionaryRef))
{
CFStringRef fullCFStringRef = NULL;
CFStringRef cookieKeyCFStringRef;
CFStringRef productCFStringRef;
CFStringRef cookieCFStringRef;
if (CFDictionaryGetValueIfPresent(productCFDictionaryRef, CFSTR("Name"), (const void**) &productCFStringRef))
{
//CFShow(productCFStringRef);
}
cookieKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), pCookie);
if (CFDictionaryGetValueIfPresent(productCFDictionaryRef, cookieKeyCFStringRef, (const void**) &cookieCFStringRef))
{
fullCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ %@ %@"),
vendorCFStringRef, productCFStringRef, cookieCFStringRef);
// CFShow(cookieCFStringRef);
}
#if FAKE_IT
else
{
fullCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ %@ #%@"),
vendorCFStringRef, productCFStringRef, cookieKeyCFStringRef);
}
#endif
if (fullCFStringRef)
{
// CFShow(fullCFStringRef);
results = CFStringGetCString(
fullCFStringRef, pCstr, CFStringGetLength(fullCFStringRef) * sizeof(UniChar) + 1, kCFStringEncodingMacRoman);
CFRelease(fullCFStringRef);
}
CFRelease(cookieKeyCFStringRef);
}
CFRelease(productKeyCFStringRef);
}
CFRelease(vendorKeyCFStringRef);
}
//++CFRelease(tCFPropertyListRef); // Leak this!
}
return results;
}
// ---------------------------------
// Find an element string in the <HID_device_usage_strings.plist> resource (XML) file
static Boolean xml_search_usage(const long pVendorID, const long pProductID, const long pUsagePage, const long pUsage, char* pCstr)
{
static CFPropertyListRef tCFPropertyListRef = NULL;
Boolean results = false;
if (NULL == tCFPropertyListRef)
tCFPropertyListRef = xml_load(CFSTR("HID_device_usage_strings"), CFSTR("plist"));
if (NULL != tCFPropertyListRef)
{
if (CFDictionaryGetTypeID() == CFGetTypeID(tCFPropertyListRef))
{
CFDictionaryRef vendorCFDictionaryRef;
CFStringRef vendorKeyCFStringRef;
vendorKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), pVendorID);
if (CFDictionaryGetValueIfPresent(tCFPropertyListRef, vendorKeyCFStringRef, (const void**) &vendorCFDictionaryRef))
{
CFDictionaryRef productCFDictionaryRef;
CFStringRef productKeyCFStringRef;
CFStringRef vendorCFStringRef;
if (!CFDictionaryGetValueIfPresent(vendorCFDictionaryRef, CFSTR("Name"), (const void**) &vendorCFStringRef))
{
vendorCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("v: %ld"), pVendorID);
//CFShow(vendorCFStringRef);
}
productKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), pProductID);
if (CFDictionaryGetValueIfPresent(vendorCFDictionaryRef, productKeyCFStringRef, (const void**) &productCFDictionaryRef))
{
CFStringRef fullCFStringRef = NULL;
CFStringRef usageKeyCFStringRef;
CFStringRef productCFStringRef;
CFStringRef usageCFStringRef;
if (CFDictionaryGetValueIfPresent(productCFDictionaryRef, CFSTR("Name"), (const void**) &productCFStringRef))
{
//CFShow(productCFStringRef);
}
usageKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld:%ld"), pUsagePage, pUsage);
if (CFDictionaryGetValueIfPresent(productCFDictionaryRef, usageKeyCFStringRef, (const void**) &usageCFStringRef))
{
fullCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ %@ %@"),
vendorCFStringRef, productCFStringRef, usageCFStringRef);
// CFShow(usageCFStringRef);
}
#if FAKE_IT
else
{
fullCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ %@ #%@"),
vendorCFStringRef, productCFStringRef, usageKeyCFStringRef);
}
#endif
if (fullCFStringRef)
{
// CFShow(fullCFStringRef);
results = CFStringGetCString(
fullCFStringRef, pCstr, CFStringGetLength(fullCFStringRef) * sizeof(UniChar) + 1, kCFStringEncodingMacRoman);
CFRelease(fullCFStringRef);
}
CFRelease(usageKeyCFStringRef);
}
CFRelease(productKeyCFStringRef);
}
CFRelease(vendorKeyCFStringRef);
}
//++CFRelease(tCFPropertyListRef); // Leak this!
}
return results;
}
// ---------------------------------
// set name from vendor id/product id look up
Boolean HIDGetElementNameFromVendorProductCookie (const long pVendorID, const long pProductID, const long pCookie, char * pName)
{
Boolean result = false;
*pName = 0; // clear name
if (xml_search_cookie(pVendorID, pProductID, pCookie, pName))
return true;
switch (pVendorID) {
case kMacally:
switch (pProductID) {
case kiShock:
result = true;
switch (pCookie) {
case 3: sprintf(pName, "D-Pad Up"); break;
case 4: sprintf(pName, "D-Pad Down"); break;
case 5: sprintf(pName, "D-Pad Left"); break;
case 6: sprintf(pName, "D-Pad Right"); break;
case 7: sprintf(pName, "Up Button"); break;
case 8: sprintf(pName, "Right Button"); break;
case 9: sprintf(pName, "Down Button"); break;
case 10: sprintf(pName, "Left Button"); break;
case 11: sprintf(pName, "C Button"); break;
case 12: sprintf(pName, "B Button [Select]"); break;
case 13: sprintf(pName, "A Button [Start]"); break;
case 14: sprintf(pName, "F Button"); break;
case 15: sprintf(pName, "R1 Trigger"); break;
case 16: sprintf(pName, "R2 Trigger"); break;
case 17: sprintf(pName, "L1 Trigger"); break;
case 18: sprintf(pName, "L2 Trigger"); break;
case 19: sprintf(pName, "Left Stick Button"); break;
case 20: sprintf(pName, "Right Stick Button"); break;
case 21: sprintf(pName, "D Button"); break;
case 22: sprintf(pName, "E Button"); break;
case 23: sprintf(pName, "Left Stick X-Axis"); break;
case 24: sprintf(pName, "Left Stick Y-Axis"); break;
case 25: sprintf(pName, "Right Stick X-Axis"); break;
case 26: sprintf(pName, "Right Stick Y-Axis"); break;
default:
#if FAKE_IT
sprintf(pName, "#{V:Macally, P:iShock, C:%ld}#", pCookie);
#else
result = false;
#endif FAKE_IT
break;
}
break;
default:
#if FAKE_IT
sprintf(pName, "#{V:Macally, P:%ld, C:%ld}#", pProductID, pCookie); break;
#else
result = false;
#endif FAKE_IT
break;
}
break;
case kMacsense:
switch (pProductID) {
case kFunPadF107:
result = true;
switch (pCookie) {
case 3: sprintf(pName, "Button 1"); break;
case 4: sprintf(pName, "Button 2"); break;
case 5: sprintf(pName, "Button 3"); break;
case 6: sprintf(pName, "Button 4"); break;
case 7: sprintf(pName, "L1 Trigger"); break;
case 8: sprintf(pName, "R1 Trigger"); break;
case 9: sprintf(pName, "L2 Trigger"); break;
case 10: sprintf(pName, "R2 Trigger"); break;
case 11: sprintf(pName, "Right Stick X-Axis"); break;
case 12: sprintf(pName, "Right Stick Y-Axis"); break;
case 13: sprintf(pName, "Left Stick X-Axis"); break;
case 14: sprintf(pName, "Left Stick Y-Axis"); break;
case 15: sprintf(pName, "Hat Switch"); break;
default:
#if FAKE_IT
sprintf(pName, "#{V:Macsense, P:FunPad F-107, C:%ld}#", pCookie);
#else
result = false;
#endif FAKE_IT
break;
}
default:
#if FAKE_IT
sprintf(pName, "#{V:Macsense, P:%ld, C:%ld}#", pProductID, pCookie);
#else
result = false;
#endif FAKE_IT
break;
}
break;
default:
#if FAKE_IT
sprintf(pName, "#{V:%ld, P:%ld, C:%ld}#", pVendorID, pProductID, pCookie);
#else
result = false;
#endif FAKE_IT
break;
}
return result;
}
// ---------------------------------
// set name from vendor id/product id & usage look up
Boolean HIDGetElementNameFromVendorProductUsage (const long pVendorID, const long pProductID, const long pUsagePage, const long pUsage, char * pName)
{
Boolean result = false;
*pName = 0; // clear name
if (xml_search_usage(pVendorID, pProductID, pUsagePage, pUsage, pName))
return true;
#if FAKE_IT
sprintf(pName, "#{V:%ld, P:%ld, U:%ld:%ld}#", pVendorID, pProductID, pUsagePage, pUsage);
result = true;
#endif
return result;
}

87
HID_Name_Lookup.h Executable file
View File

@ -0,0 +1,87 @@
/*
File: HID_Name_Lookup.h
Contains: Definition of the HID device name lookup functions for the HID utilites.
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HID_Name_Lookup_h_
#define _HID_Name_Lookup_h_
#include "HID_Utilities.h"
// ==================================
#ifdef __cplusplus
extern "C" {
#endif
// ==================================
// Note: Now that as the device data has now been moved into external .XML files these
// constansts should no longer be used. They will eventually be eliminated from this header.
#define kMicrosoft 1118
#define kSideWinderFFB2 27
#define kLogitech 1133
#define kWingManStrikeForce3D 49797
#define kMacally 8738
#define kiShock 16400
#define kiShockIIFFB 16416
#define kMacsense 1635
#define kFunPadF107 38916
// ==================================
// set name from vendor id/product id look up (using cookies)
extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName);
// set name from vendor id/product id look up (using usage page & usage)
extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName);
// ==================================
#ifdef __cplusplus
}
#endif
#endif // _HID_Name_Lookup_h_

632
HID_Queue_Utilities.c Executable file
View File

@ -0,0 +1,632 @@
/*
File: HID_Queue_Utilities.c
Contains: Implementation of the HID queue functions for the HID utilites.
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#include <IOKit/hid/IOHIDDevice.h>
#include "HID_Utilities_Internal.h"
#include "HID_Utilities_External.h"
// ==================================
// compiler directives
// ==================================
#define USE_ASYNC_EVENTS TRUE
#define REPORT_ERRORS FALSE
// ==================================
#if REPORT_ERRORS
#define HIDREPORTERRORNUM(s,n) HIDReportErrorNum(s,n)
#define HIDREPORTERROR(s) HIDReportError(s)
#else
#define HIDREPORTERRORNUM(s,n) do {} while (false)
#define HIDREPORTERROR(s) do {} while (false)
#endif
// ==================================
// private functions
// ==================================
// creates a queue for a device
static IOReturn hid_CreateQueue (pRecDevice pDevice)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidDevice(pDevice))
{
if (NULL == pDevice->queue) // do we already have a queue
{
if (NULL != pDevice->interface)
{
pDevice->queue = (void *) (*(IOHIDDeviceInterface**) pDevice->interface)->allocQueue (pDevice->interface); // alloc queue
if (pDevice->queue)
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->create (pDevice->queue, 0, kDeviceQueueSize); // create actual queue
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("hid_CreateQueue - Failed to create queue via create", result);
}
else
{
HIDREPORTERROR ("hid_CreateQueue - Failed to alloc IOHIDQueueInterface ** via allocQueue");
result = kIOReturnError; // synthesis error
}
}
else
HIDREPORTERRORNUM ("hid_CreateQueue - Device inteface does not exist for queue creation", result);
}
}
else
HIDREPORTERRORNUM ("hid_CreateQueue - Invalid Device", result);
return result;
}
// ---------------------------------
// returns true if queue is empty false otherwise
// error if no device, empty if no queue
static unsigned char hid_IsDeviceQueueEmpty (pRecDevice pDevice)
{
if (HIDIsValidDevice(pDevice)) // need valid device
{
if (pDevice->queue) // and queue
{
pRecElement pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO);
while (pElement)
{
if ((*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie))
return false;
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
}
else
HIDREPORTERROR ("hid_IsDeviceQueueEmpty - no queue.");
}
else
HIDREPORTERROR ("hid_IsDeviceQueueEmpty - Invalid device.");
return true;
}
// ---------------------------------
// disposes and releases queue, sets queue to NULL,.
// Note: will have no effect if device or queue do not exist
static IOReturn hid_DisposeReleaseQueue (pRecDevice pDevice)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidDevice(pDevice)) // need valid device
{
if (pDevice->queue) // and queue
{
// stop queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to stop queue.", result);
// dispose of queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->dispose (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to dipose queue.", result);
// release the queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->Release (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to release queue.", result);
pDevice->queue = NULL;
}
else
HIDREPORTERROR ("hid_DisposeReleaseQueue - no queue.");
}
else
HIDREPORTERROR ("hid_DisposeReleaseQueue - Invalid device.");
return result;
}
// ==================================
// public functions
// ---------------------------------
// queues specific element, performing any device queue set up required
// queue is started and ready to return events on exit from this function
unsigned long HIDQueueElement (pRecDevice pDevice, pRecElement pElement)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidElement(pDevice,pElement))
{
if (NULL == pDevice->interface) // must have interface
{
HIDREPORTERROR ("HIDQueueElement - Device does not have interface.");
return kIOReturnError;
}
if (NULL == pDevice->queue) // if no queue create queue
result = hid_CreateQueue (pDevice);
if ((kIOReturnSuccess != result) || (NULL == pDevice->queue))
{
HIDREPORTERRORNUM ("HIDQueueElement - problem creating queue.", result);
if (kIOReturnSuccess != result)
return result;
else
return kIOReturnError;
}
// stop queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERROR ("HIDQueueElement - Failed to stop queue.");
// queue element
if (!(*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie))
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->addElement (pDevice->queue, pElement->cookie, 0);
if (kIOReturnSuccess != result)
HIDREPORTERROR ("HIDQueueElement - Failed to add Element to queue.");
}
// restart queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->start (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERROR ("HIDQueueElement - Failed to start queue.");
}
else
{
HIDREPORTERROR ("HIDQueueElement - Invalid Device and/or element.");
return kIOReturnBadArgument;
}
return result;
}
// ---------------------------------
// adds all elements to queue, performing any device queue set up required
// queue is started and ready to return events on exit from this function
unsigned long HIDQueueDevice (pRecDevice pDevice)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
pRecElement pElement;
if (HIDIsValidDevice(pDevice))
{
// error checking
if (NULL == pDevice)
{
HIDREPORTERROR ("HIDQueueDevice - Device does not exist.");
return kIOReturnBadArgument;
}
if (NULL == pDevice->interface) // must have interface
{
HIDREPORTERROR ("HIDQueueDevice - Device does not have interface.");
return kIOReturnError;
}
if (NULL == pDevice->queue) // if no queue create queue
result = hid_CreateQueue (pDevice);
if ((kIOReturnSuccess != result) || (NULL == pDevice->queue))
{
HIDREPORTERRORNUM ("HIDQueueDevice - problem creating queue.", result);
if (kIOReturnSuccess != result)
return result;
else
return kIOReturnError;
}
// stop queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDQueueDevice - Failed to stop queue.", result);
// queue element
//¥ pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO);
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeInput | kHIDElementTypeFeature);
while (pElement)
{
if (!(*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie))
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->addElement (pDevice->queue, pElement->cookie, 0);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDQueueDevice - Failed to add element to queue.", result);
}
//¥ pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeInput | kHIDElementTypeFeature);
}
// start queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->start (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDQueueDevice - Failed to start queue.", result);
}
else
HIDREPORTERROR ("HIDQueueDevice - Invalid device.");
return result;
}
// ---------------------------------
// removes element for queue, if last element in queue will release queue and closes device interface
unsigned long HIDDequeueElement (pRecDevice pDevice, pRecElement pElement)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidElement(pDevice,pElement))
{
if (!pDevice || !pElement)
result = kIOReturnBadArgument;
else
{
if ((pDevice->interface) && (pDevice->queue))
{
// stop queue
result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDDequeueElement - Failed to stop queue.", result);
if ((*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie)) // if has element then remove
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->removeElement (pDevice->queue, pElement->cookie);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDDequeueElement - Failed to add element to queue", result);
}
if (hid_IsDeviceQueueEmpty (pDevice)) // release device queue and close interface if queue empty
{
result = hid_DisposeReleaseQueue (pDevice);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDDequeueElement - Failed to dispose and release queue.", result);
}
else // not empty so restart queue
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->start (pDevice->queue);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDDequeueElement - Failed to start queue.", result);
}
}
else
{
HIDREPORTERROR ("HIDDequeueElement - No device inteface or queue.");
return kIOReturnError;
}
}
}
else
HIDREPORTERROR ("HIDDequeueElement - Invalid device.");
return result;
}
// ---------------------------------
// completely removes all elements from queue and releases queue and closes device interface
// does not release device interfaces, application must call HIDReleaseDeviceList on exit
unsigned long HIDDequeueDevice (pRecDevice pDevice)
{
IOReturn result = kIOReturnSuccess;
if (HIDIsValidDevice(pDevice))
{
if ((pDevice->interface) && (pDevice->queue))
{
// iterate through elements and if queued, remove
pRecElement pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO);
while (pElement)
{
if ((*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie))
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->removeElement (pDevice->queue, pElement->cookie);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDDequeueDevice - Failed to remove element from queue.", result);
}
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO);
}
}
// ensure queue is disposed and released
// interface will be closed and released on call to HIDReleaseDeviceList
result = hid_DisposeReleaseQueue (pDevice);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("removeElement - Failed to dispose and release queue.", result);
#if USE_ASYNC_EVENTS
else if (NULL != pDevice->queueRunLoopSource)
{
if (CFRunLoopContainsSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode))
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode);
CFRelease(pDevice->queueRunLoopSource);
pDevice->queueRunLoopSource = NULL;
}
#endif USE_ASYNC_EVENTS
}
else
{
HIDREPORTERROR ("HIDDequeueDevice - Invalid device.");
result = kIOReturnBadArgument;
}
return result;
}
// ---------------------------------
// releases all device queues for quit or rebuild (must be called)
// does not release device interfaces, application must call HIDReleaseDeviceList on exit
unsigned long HIDReleaseAllDeviceQueues (void)
{
IOReturn result = kIOReturnBadArgument;
pRecDevice pDevice = HIDGetFirstDevice ();
while (pDevice)
{
result = HIDDequeueDevice (pDevice);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDReleaseAllDeviceQueues - Could not dequeue device.", result);
pDevice = HIDGetNextDevice (pDevice);
}
return result;
}
// ---------------------------------
// Closes and releases interface to device, should be done prior to exting application
// Note: will have no affect if device or interface do not exist
// application will "own" the device if interface is not closed
// (device may have to be plug and re-plugged in different location to get it working again without a restart)
unsigned long HIDCloseReleaseInterface (pRecDevice pDevice)
{
IOReturn result = kIOReturnSuccess;
if (HIDIsValidDevice(pDevice) && (NULL != pDevice->interface))
{
// close the interface
result = (*(IOHIDDeviceInterface**) pDevice->interface)->close (pDevice->interface);
if (kIOReturnNotOpen == result)
{
// do nothing as device was not opened, thus can't be closed
}
else if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to close IOHIDDeviceInterface.", result);
//release the interface
result = (*(IOHIDDeviceInterface**) pDevice->interface)->Release (pDevice->interface);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to release interface.", result);
pDevice->interface = NULL;
}
return result;
}
// ---------------------------------
// Get the next event in the queue for a device
// elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
// Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition
// Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility)
unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent)
{
IOReturn result = kIOReturnBadArgument;
AbsoluteTime zeroTime = {0,0};
if (HIDIsValidDevice(pDevice))
{
if (pDevice->queue)
{
result = (*(IOHIDQueueInterface**) pDevice->queue)->getNextEvent (pDevice->queue, (IOHIDEventStruct *)pHIDEvent, zeroTime, 0);
if (kIOReturnUnderrun == result)
return false; // no events in queue not an error per say
else if (kIOReturnSuccess != result) // actual error versus just an empty queue
HIDREPORTERRORNUM ("HIDGetEvent - Could not get HID event via getNextEvent.", result);
else
return true;
}
else
HIDREPORTERROR ("HIDGetEvent - queue does not exist.");
}
else
HIDREPORTERROR ("HIDGetEvent - invalid device.");
return false; // did not get event
}
// ---------------------------------
// returns current value for element, polling element
// will return 0 on error conditions which should be accounted for by application
long HIDGetElementValue (pRecDevice pDevice, pRecElement pElement)
{
IOReturn result = kIOReturnBadArgument;
IOHIDEventStruct hidEvent;
hidEvent.value = 0;
hidEvent.longValueSize = 0;
hidEvent.longValue = nil;
if (HIDIsValidElement(pDevice, pElement))
{
if (NULL != pDevice->interface)
{
// ++ NOTE: If the element type is feature then use queryElementValue instead of getElementValue
if (kIOHIDElementTypeFeature == pElement->type)
{
result = (*(IOHIDDeviceInterface**) pDevice->interface)->queryElementValue (pDevice->interface, pElement->cookie, &hidEvent,0,NULL,NULL,NULL);
if (kIOReturnUnsupported == result) // unless it's unsuported.
goto try_getElementValue;
else if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDGetElementValue - Could not get HID element value via queryElementValue.", result);
}
else if (pElement->type <= kIOHIDElementTypeInput_ScanCodes)
{
try_getElementValue:
result = (*(IOHIDDeviceInterface**) pDevice->interface)->getElementValue (pDevice->interface, pElement->cookie, &hidEvent);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDGetElementValue - Could not get HID element value via getElementValue.", result);
}
// on 10.0.x this returns the incorrect result for negative ranges, so fix it!!!
// this is not required on Mac OS X 10.1+
if ((pElement->min < 0) && (hidEvent.value > pElement->max)) // assume range problem
hidEvent.value = hidEvent.value + pElement->min - pElement->max - 1;
}
else
HIDREPORTERROR ("HIDGetElementValue - no interface for device.");
}
else
HIDREPORTERROR ("HIDGetElementValue - invalid device and/or element.");
// record min and max for auto scale and auto ...
if (hidEvent.value < pElement->calMin)
pElement->calMin = hidEvent.value;
if (hidEvent.value > pElement->calMax)
pElement->calMax = hidEvent.value;
// auto user scale
return hidEvent.value;
}
// ---------------------------------
// Set an elements value
// NOTE: This should only be used when a single element of a report needs to be sent.
// If multiple elements are to be send then transactions should be used.
long HIDSetElementValue (pRecDevice pDevice, pRecElement pElement,void* pIOHIDEvent)
{
IOHIDEventStruct* pMyIOHIDEvent = (IOHIDEventStruct*) pIOHIDEvent;
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidElement(pDevice, pElement))
{
if (NULL != pDevice->interface)
{
result = (*(IOHIDDeviceInterface**) pDevice->interface)->setElementValue (pDevice->interface, pElement->cookie, pMyIOHIDEvent, -1, nil, nil, nil);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDSetElementValue - Could not set HID element value via setElementValue.", result);
}
else
HIDREPORTERROR ("HIDSetElementValue - no interface for device.");
}
else
HIDREPORTERROR ("HIDSetElementValue - invalid device and/or element.");
return result;
}
// ---------------------------------
// Set a callback to be called when a queue goes from empty to non-empty
long HIDSetQueueCallback (pRecDevice pDevice, IOHIDCallbackFunction callback)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidDevice(pDevice))
{
#if USE_ASYNC_EVENTS
// if we don't have a queue runloop sourceÉ
if (NULL == pDevice->queueRunLoopSource)
{
// then create one
result = (*(IOHIDQueueInterface**) pDevice->queue)->createAsyncEventSource((void *) pDevice->queue,
(CFRunLoopSourceRef*) &pDevice->queueRunLoopSource);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDSetQueueCallback - Failed to createAsyncEventSource error: ", result);
}
// if we have one nowÉ
if (NULL != pDevice->queueRunLoopSource)
{
// and it's not already attached to our runloopÉ
if (!CFRunLoopContainsSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode))
// then attach it now.
CFRunLoopAddSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode);
}
// now install our callback
result = (*(IOHIDQueueInterface**) pDevice->queue)->setEventCallout(pDevice->queue, callback, pDevice, pDevice);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDSetQueueCallback - Could not set HID queue callback via setEventCallout.", result);
#endif USE_ASYNC_EVENTS
}
else
HIDREPORTERROR ("HIDSetQueueCallback - invalid device and/or element.");
return result;
}
#if 1
// ---------------------------------
// Get a report from a device
long HIDGetReport (pRecDevice pDevice,const IOHIDReportType reportType, const UInt32 reportID, void* reportBuffer, UInt32* reportBufferSize)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidDevice(pDevice))
{
if (NULL != pDevice->interface)
{
result = (*(IOHIDDeviceInterface**) pDevice->interface)->getReport (pDevice->interface, reportType, reportID, reportBuffer, reportBufferSize, -1, nil, nil, nil);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDGetReport - Could not getReport, error: ", result);
}
else
HIDREPORTERROR ("HIDGetReport - no interface for device.");
}
else
HIDREPORTERROR ("HIDGetReport - invalid device.");
return result;
}
// ---------------------------------
// Send a report to a device
long HIDSetReport (pRecDevice pDevice,const IOHIDReportType reportType, const UInt32 reportID, void* reportBuffer, const UInt32 reportBufferSize)
{
IOReturn result = kIOReturnError; // assume failure (pessimist!)
if (HIDIsValidDevice(pDevice))
{
if (NULL != pDevice->interface)
{
result = (*(IOHIDDeviceInterface**) pDevice->interface)->setReport (pDevice->interface, reportType, reportID, reportBuffer, reportBufferSize, -1, nil, nil, nil);
if (kIOReturnSuccess != result)
HIDREPORTERRORNUM ("HIDGetReport - Could not setReport; error: ", result);
}
else
HIDREPORTERROR ("HIDGetReport - no interface for device.");
}
else
HIDREPORTERROR ("HIDGetReport - invalid device.");
return result;
}
#endif

114
HID_Queue_Utilities.h Executable file
View File

@ -0,0 +1,114 @@
/*
File: HID_Queue_Utilities.h
Contains: Definition of the HID queue functions for the HID utilites.
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HID_Queue_Utilities_h_
#define _HID_Queue_Utilities_h_
#include "HID_Utilities.h"
// ==================================
#ifdef __cplusplus
extern "C" {
#endif
// ==================================
enum
{
kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible
// but should account for the maximum possible events in the queue
// USB updates will likely occur at 100 Hz so one must account for this rate of
// if states change quickly (updates are only posted on state changes)
};
// ==================================
// queues specific element, performing any device queue set up required
extern unsigned long HIDQueueElement (pRecDevice pDevice, pRecElement pElement);
// adds all elements to queue, performing any device queue set up required
extern unsigned long HIDQueueDevice (pRecDevice pDevice);
// removes element for queue, if last element in queue will release queue and device
extern unsigned long HIDDequeueElement (pRecDevice pDevice, pRecElement pElement);
// completely removes all elements from queue and releases queue and device
extern unsigned long HIDDequeueDevice (pRecDevice pDevice);
// releases all device queues for quit or rebuild (must be called)
extern unsigned long HIDReleaseAllDeviceQueues (void);
// releases interface to device, should be done prior to exiting application (called from HIDReleaseDeviceList)
extern unsigned long HIDCloseReleaseInterface (pRecDevice pDevice);
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent);
// returns current value for element, creating device interface as required, polling element
extern long HIDGetElementValue (pRecDevice pDevice, pRecElement pElement);
// Set an elements value
// NOTE: This should only be used when a single element report needs to be sent.
// If multiple elements reports are to be send then transactions should be used.
extern long HIDSetElementValue (pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pIOHIDEvent);
// Set a callback to be called when a queue goes from empty to non-empty
extern long HIDSetQueueCallback (pRecDevice pDevice, IOHIDCallbackFunction callback);
#if 0
// Get a report from a device
extern long HIDGetReport (pRecDevice pDevice,const IOHIDReportType reportType, const UInt32 reportID, void* reportBuffer, UInt32* reportBufferSize);
// Send a report to a device
extern long HIDSetReport (pRecDevice pDevice,const IOHIDReportType reportType, const UInt32 reportID, void* reportBuffer, const UInt32 reportBufferSize);
#endif
#ifdef __cplusplus
}
#endif
#endif // _HID_Queue_Utilities_h_

316
HID_Transaction_Utilities.c Executable file
View File

@ -0,0 +1,316 @@
/*
File: HID_Transaction_Utilities.h
Contains: Definitions of the HID queue functions for the HID utilites.
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <CoreServices/CoreServices.h>
#include "HID_Utilities_Internal.h"
#include "HID_Utilities_External.h"
// ==================================
// private functions
// creates a transaction for a device, allocates and creates the transaction interface if required
static IOReturn hid_CreateTransaction(pRecDevice pDevice)
{
IOReturn result = kIOReturnSuccess;
if (HIDIsValidDevice(pDevice))
{
if (NULL == pDevice->transaction) // if we don't already have a transactionÉ
{
if (NULL != pDevice->interface) // and we do have an interfaceÉ
{
pDevice->transaction = (void *) (*(IOHIDDeviceInterface**) pDevice->interface)->allocOutputTransaction (pDevice->interface); // alloc Transaction
if (pDevice->transaction) // if it was successfulÉ
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->create (pDevice->transaction); // create actual transaction
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nFailed to create transaction via create: error = %ld.", result);
}
else
{
HIDReportError ("\nhid_CreateTransaction failed to allocOutputTransaction");
if (!result)
result = kIOReturnError; // synthesis error
}
}
else
HIDReportErrorNum ("\nhid_CreateTransaction failed: Device inteface does not exist.", result);
}
}
return result;
}
// ==================================
// public functions
// ---------------------------------
// add an element to a Transaction
unsigned long HIDTransactionAddElement(pRecDevice pDevice, pRecElement pElement)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidElement(pDevice,pElement))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->addElement (pDevice->transaction,pElement->cookie); // add element
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionAddElement failed to add Element: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionAddElement failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
// removes an element from a Transaction
unsigned long HIDTransactionRemoveElement(pRecDevice pDevice, pRecElement pElement)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidElement(pDevice,pElement))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->removeElement (pDevice->transaction,pElement->cookie); // remove element
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionRemoveElement failed to remove Element: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionRemoveElement failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
// return true if this transaction contains this element
Boolean HIDTransactionHasElement(pRecDevice pDevice, pRecElement pElement)
{
Boolean result = false;
if (HIDIsValidElement(pDevice,pElement))
{
(void) hid_CreateTransaction(pDevice);
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->hasElement (pDevice->transaction,pElement->cookie); // remove element
}
else
{
HIDReportError ("\nHIDTransactionHasElement failed: no transaction interface");
}
}
return result;
}
/* This changes the default value of an element, when the values of the */
/* elements are cleared, on clear or commit, they are reset to the */
/* default value */
/* This call can be made on elements that are not in the transaction, but */
/* has undefined behavior if made on elements not in the transaction */
/* which are later added to the transaction. */
/* In other words, an element should be added before its default is */
/* set, for well defined behavior. */
unsigned long HIDTransactionSetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidElement(pDevice,pElement))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->setElementDefault (pDevice->transaction,pElement->cookie, pValueEvent);
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionSetElementDefault failed to set Element Default: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionSetElementDefault failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
/* Get the current setting of an element's default value */
unsigned long HIDTransactionGetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidElement(pDevice,pElement))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->getElementDefault (pDevice->transaction,pElement->cookie, pValueEvent);
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionGetElementDefault failed to get Element Default: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionGetElementDefault failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
/* Add a change to the transaction, by setting an element value */
/* The change is not actually made until it is commited */
/* The element must be part of the transaction or this call will fail */
unsigned long HIDTransactionSetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidElement(pDevice,pElement))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->setElementValue (pDevice->transaction,pElement->cookie, pValueEvent);
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionSetElementValue failed to set Element Default: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionSetElementValue failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
/* Get the current setting of an element value */
unsigned long HIDTransactionGetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidElement(pDevice,pElement))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->getElementValue (pDevice->transaction,pElement->cookie, pValueEvent);
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionGetElementValue failed to get Element Default: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionGetElementValue failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
/* Commit the transaction, or clear all the changes and start over */
unsigned long HIDTransactionCommit(pRecDevice pDevice)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidDevice(pDevice))
{
if (pDevice->transaction)
{
#if 0000
// NOTE: this code is to workaround a bug where if you commit transactions
// too fast then some of the reports get dropped.
// (fixed in 10.2.1)
static AbsoluteTime nextTime = {0,0}; // first time this should be no delay
if (nextTime.hi || nextTime.lo)
MPDelayUntil(&nextTime);
#endif
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->commit (pDevice->transaction,-1,NULL,NULL,NULL);
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionCommit failed to commit: error = %ld.", result);
#if 0000
nextTime = AddDurationToAbsolute(20 * kDurationMillisecond,UpTime());
#endif
}
else
{
HIDReportError ("\nHIDTransactionCommit failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}
/* Clear all the changes and start over */
unsigned long HIDTransactionClear(pRecDevice pDevice)
{
IOReturn result = hid_CreateTransaction(pDevice);
if (HIDIsValidDevice(pDevice))
{
if (pDevice->transaction)
{
result = (*(IOHIDOutputTransactionInterface**) pDevice->transaction)->clear (pDevice->transaction);
if (kIOReturnSuccess != result)
HIDReportErrorNum ("\nHIDTransactionClear failed to get Element Default: error = %ld.", result);
}
else
{
HIDReportError ("\nHIDTransactionClear failed: no transaction interface");
if (!result)
result = kIOReturnError; // synthesis error
}
}
return result;
}

2197
HID_Utilities.c Executable file

File diff suppressed because it is too large Load Diff

256
HID_Utilities.h Executable file
View File

@ -0,0 +1,256 @@
/*
File: HID_Utilities.h
Contains: External interface for HID Utilities
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HID_Utilities_h_
#define _HID_Utilities_h_
#include <Carbon/Carbon.h>
#include <IOKit/IOTypes.h>
// 10.0.x
//#include <IOKit/IOUSBHIDParser.h>
// 10.1.x
#include <IOKit/hid/IOHIDUsageTables.h>
#include <IOKit/HID/IOHIDLib.h>
// ==================================
#ifdef __cplusplus
extern "C" {
#endif
// ==================================
enum
{
kDefaultUserMin = 0, // default user min and max used for scaling
kDefaultUserMax = 255,
};
typedef enum HIDElementTypeMask
{
kHIDElementTypeInput = 1 << 1,
kHIDElementTypeOutput = 1 << 2,
kHIDElementTypeFeature = 1 << 3,
kHIDElementTypeCollection = 1 << 4,
kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature,
kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection
}HIDElementTypeMask;
struct recElement
{
IOHIDElementType type; // the type defined by IOHIDElementType in IOHIDKeys.h
long usagePage; // usage page from IOUSBHIDParser.h which defines general usage
long usage; // usage within above page from IOUSBHIDParser.h which defines specific usage
IOHIDElementCookie cookie; // unique value (within device of specific vendorID and productID) which identifies element, will NOT change
long min; // reported min value possible
long max; // reported max value possible
long scaledMin; // reported scaled min value possible
long scaledMax; // reported scaled max value possible
long size; // size in bits of data return from element
Boolean relative; // are reports relative to last report (deltas)
Boolean wrapping; // does element wrap around (one value higher than max is min)
Boolean nonLinear; // are the values reported non-linear relative to element movement
Boolean preferredState; // does element have a preferred state (such as a button)
Boolean nullState; // does element have null state
long units; // units value is reported in (not used very often)
long unitExp; // exponent for units (also not used very often)
Str255 name; // name of element (not used often)
// runtime variables
long minReport; // min returned value
long maxReport; // max returned value (calibrate call)
long userMin; // user set value to scale to (scale call)
long userMax;
struct recElement * pPrevious; // previous element (NULL at list head)
struct recElement * pChild; // next child (only of collections)
struct recElement * pSibling; // next sibling (for elements and collections)
};
typedef struct recElement recElement;
typedef recElement* pRecElement;
struct recDevice
{
IOHIDDeviceInterface ** interface; // interface to device, NULL = no interface
IOHIDQueueInterface ** queue; // device queue, NULL = no queue
CFRunLoopSourceRef queueRunLoopSource; // device queue run loop source, NULL == no source
IOHIDOutputTransactionInterface ** transaction; // output transaction interface, NULL == no transaction
io_object_t notification; // notifications
Str255 transport; // device transport
long vendorID; // id for device vendor, unique across all devices
long productID; // id for particular product, unique across all of a vendors devices
long version; // version of product
Str255 manufacturer; // name of manufacturer
Str255 product; // name of product
Str255 serial; // serial number of specific product, can be assumed unique across specific product or specific vendor (not used often)
long locID; // long representing location in USB (or other I/O) chain which device is pluged into, can identify specific device on machine
long usage; // usage page from IOUSBHID Parser.h which defines general usage
long usagePage; // usage within above page from IOUSBHID Parser.h which defines specific usage
long totalElements; // number of total elements (should be total of all elements on device including collections) (calculated, not reported by device)
long features; // number of elements of type kIOHIDElementTypeFeature
long inputs; // number of elements of type kIOHIDElementTypeInput_Misc or kIOHIDElementTypeInput_Button or kIOHIDElementTypeInput_Axis or kIOHIDElementTypeInput_ScanCodes
long outputs; // number of elements of type kIOHIDElementTypeOutput
long collections; // number of elements of type kIOHIDElementTypeCollection
long axis; // number of axis (calculated, not reported by device)
long buttons; // number of buttons (calculated, not reported by device)
long hats; // number of hat switches (calculated, not reported by device)
long sliders; // number of sliders (calculated, not reported by device)
long dials; // number of dials (calculated, not reported by device)
long wheels; // number of wheels (calculated, not reported by device)
recElement* pListElements; // head of linked list of elements
struct recDevice* pNext; // next device
};
typedef struct recDevice recDevice;
typedef recDevice* pRecDevice;
// ==================================
// Create and open an interface to device, required prior to extracting values or building queues
// Note: appliction now owns the device and must close and release it prior to exiting
extern IOReturn HIDCreateOpenDeviceInterface (io_object_t hidDevice, pRecDevice pDevice);
// builds list of device with elements (allocates memory and captures devices)
// list is allcoated internally within HID Utilites and can be accessed via accessor functions
// structures within list are considered flat and user accessable, butnot user modifiable
// can be called again to rebuild list to account for new devices (will do the right thing in case of disposing existing list)
extern Boolean HIDBuildDeviceList (UInt32 usagePage, UInt32 usage);
// release list built by above function
// MUST be called prior to application exit to properly release devices
// if not called (or app crashes) devices can be recovered by pluging into different location in USB chain
extern void HIDReleaseDeviceList (void);
// does a device list exist
extern Boolean HIDHaveDeviceList (void);
// how many HID devices have been found
// returns 0 if no device list exist
extern UInt32 HIDCountDevices (void);
// how many elements does a specific device have
// returns 0 if device is invalid or NULL
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get non-collection elements
extern UInt32 HIDCountDeviceElements (pRecDevice pDevice, HIDElementTypeMask typeMask);
// get the first device in the device list
// returns NULL if no list exists
extern pRecDevice HIDGetFirstDevice (void);
// get next device in list given current device as parameter
// returns NULL if end of list
extern pRecDevice HIDGetNextDevice (pRecDevice pDevice);
// get the first element of device passed in as parameter
// returns NULL if no list exists or device does not exists or is NULL
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality
extern pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask);
// get next element of given device in list given current element as parameter
// will walk down each collection then to next element or collection (depthwise traverse)
// returns NULL if end of list
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality
extern pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask);
// get previous element of given device in list given current element as parameter
// this wlaks directly up the tree to the top element and does not search at each level
// returns NULL if beginning of list
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get non-collection elements
extern pRecElement HIDGetPreviousDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask);
// returns C string type name given a type enumeration passed in as parameter (see IOHIDKeys.h)
// returns empty string for invlid types
extern void HIDGetTypeName (IOHIDElementType type, char * cstrName);
// returns C string usage given usage page and usage passed in as parameters (see IOUSBHIDParser.h)
// returns usage page and usage values in string form for unknown values
extern void HIDGetUsageName (long valueUsagePage, long valueUsage, char * cstrName);
// returns calibrated value given raw value passed in
// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values
extern SInt32 HIDCalibrateValue (SInt32 value, pRecElement pElement);
// returns scaled value given raw value passed in
// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values
extern SInt32 HIDScaleValue (SInt32 value, pRecElement pElement);
// ---------------------------------
// convert an element type to a mask
extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type);
// find this device
extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement,
pRecDevice *ppFoundDevice, pRecElement *ppFoundElement);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement);
// print out all of an elements information
extern int HIDPrintElement(const pRecElement pElement);
// return true if this is a valid device pointer
extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice);
// return true if this is a valid element pointer for this device
extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement);
#ifdef __cplusplus
}
#endif
#endif // _HID_Utilities_h_

476
HID_Utilities_External.h Executable file
View File

@ -0,0 +1,476 @@
/*
File: HID_Utilities_External.h
Contains: Definition of the HID Utilities exported functions
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HID_Utilities_External_h_
#define _HID_Utilities_External_h_
// ==================================
//includes
#if TARGET_RT_MAC_CFM
typedef void (*IOHIDCallbackFunction)(void * target, unsigned long result, void* refcon, void * sender);
#else
#include <IOKit/hid/IOHIDLib.h>
#endif TARGET_RT_MAC_CFM
#include <stdio.h>
#if 0
#include <IOKit/hid/IOHIDUsageTables.h>
#include "PID.h" // NOTE: These are now in <IOHIDUsageTables.h>
#include "IOHIDPowerUsage.h" // NOTE: These are now in <IOHIDUsageTables.h>
#endif
#ifdef __MWERKS__
#define IOHIDEventStruct void
#endif
// ==================================
#ifdef __cplusplus
extern "C" {
#endif
// ==================================
// Device and Element Interfaces
typedef enum HIDElementTypeMask
{
kHIDElementTypeInput = 1 << 1,
kHIDElementTypeOutput = 1 << 2,
kHIDElementTypeFeature = 1 << 3,
kHIDElementTypeCollection = 1 << 4,
kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature,
kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection
}HIDElementTypeMask;
struct recElement
{
unsigned long type; // the type defined by IOHIDElementType in IOHIDKeys.h
long usagePage; // usage page from IOUSBHIDParser.h which defines general usage
long usage; // usage within above page from IOUSBHIDParser.h which defines specific usage
void * cookie; // unique value (within device of specific vendorID and productID) which identifies element, will NOT change
long min; // reported min value possible
long max; // reported max value possible
long scaledMin; // reported scaled min value possible
long scaledMax; // reported scaled max value possible
long size; // size in bits of data return from element
unsigned char relative; // are reports relative to last report (deltas)
unsigned char wrapping; // does element wrap around (one value higher than max is min)
unsigned char nonLinear; // are the values reported non-linear relative to element movement
unsigned char preferredState; // does element have a preferred state (such as a button)
unsigned char nullState; // does element have null state
long units; // units value is reported in (not used very often)
long unitExp; // exponent for units (also not used very often)
char name[256]; // name of element (c string)
// runtime variables
long calMin; // min returned value
long calMax; // max returned value (calibrate call)
long userMin; // user set value to scale to (scale call)
long userMax;
struct recElement * pPrevious; // previous element (NULL at list head)
struct recElement * pChild; // next child (only of collections)
struct recElement * pSibling; // next sibling (for elements and collections)
long depth;
};
typedef struct recElement recElement;
typedef recElement* pRecElement;
struct recDevice
{
void * interface; // interface to device, NULL = no interface
void * queue; // device queue, NULL = no queue
void * queueRunLoopSource; // device queue run loop source, NULL == no source
void * transaction; // output transaction interface, NULL == no interface
void * notification; // notifications
char transport[256]; // device transport (c string)
long vendorID; // id for device vendor, unique across all devices
long productID; // id for particular product, unique across all of a vendors devices
long version; // version of product
char manufacturer[256]; // name of manufacturer
char product[256]; // name of product
char serial[256]; // serial number of specific product, can be assumed unique across specific product or specific vendor (not used often)
long locID; // long representing location in USB (or other I/O) chain which device is pluged into, can identify specific device on machine
long usage; // usage page from IOUSBHID Parser.h which defines general usage
long usagePage; // usage within above page from IOUSBHID Parser.h which defines specific usage
long totalElements; // number of total elements (should be total of all elements on device including collections) (calculated, not reported by device)
long features; // number of elements of type kIOHIDElementTypeFeature
long inputs; // number of elements of type kIOHIDElementTypeInput_Misc or kIOHIDElementTypeInput_Button or kIOHIDElementTypeInput_Axis or kIOHIDElementTypeInput_ScanCodes
long outputs; // number of elements of type kIOHIDElementTypeOutput
long collections; // number of elements of type kIOHIDElementTypeCollection
long axis; // number of axis (calculated, not reported by device)
long buttons; // number of buttons (calculated, not reported by device)
long hats; // number of hat switches (calculated, not reported by device)
long sliders; // number of sliders (calculated, not reported by device)
long dials; // number of dials (calculated, not reported by device)
long wheels; // number of wheels (calculated, not reported by device)
recElement* pListElements; // head of linked list of elements
struct recDevice* pNext; // next device
};
typedef struct recDevice recDevice;
typedef recDevice* pRecDevice;
// ==================================
// HID Utilities interface
// ==================================
// Create and open an interface to device, required prior to extracting values or building queues
// Note: appliction now owns the device and must close and release it prior to exiting
extern unsigned long HIDCreateOpenDeviceInterface (UInt32 hidDevice, pRecDevice pDevice);
// builds list of device with elements (allocates memory and captures devices)
// list is allcoated internally within HID Utilites and can be accessed via accessor functions
// structures within list are considered flat and user accessable, butnot user modifiable
// can be called again to rebuild list to account for new devices (will do the right thing in case of disposing existing list)
extern Boolean HIDBuildDeviceList (UInt32 usagePage, UInt32 usage);
// release list built by above function
// MUST be called prior to application exit to properly release devices
// if not called (or app crashes) devices can be recovered by pluging into different location in USB chain
extern void HIDReleaseDeviceList (void);
// does a device list exist
extern Boolean HIDHaveDeviceList (void);
// how many HID devices have been found
// returns 0 if no device list exist
extern UInt32 HIDCountDevices (void);
// how many elements does a specific device have
// returns 0 if device is invalid or NULL
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get non-collection elements
extern UInt32 HIDCountDeviceElements (pRecDevice pDevice, HIDElementTypeMask typeMask);
// get the first device in the device list
// returns NULL if no list exists
extern pRecDevice HIDGetFirstDevice (void);
// get next device in list given current device as parameter
// returns NULL if end of list
extern pRecDevice HIDGetNextDevice (pRecDevice pDevice);
// get the first element of device passed in as parameter
// returns NULL if no list exists or device does not exists or is NULL
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality
extern pRecElement HIDGetFirstDeviceElement (pRecDevice pDevice, HIDElementTypeMask typeMask);
// get next element of given device in list given current element as parameter
// will walk down each collection then to next element or collection (depthwise traverse)
// returns NULL if end of list
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality
extern pRecElement HIDGetNextDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask);
// get previous element of given device in list given current element as parameter
// this wlaks directly up the tree to the top element and does not search at each level
// returns NULL if beginning of list
// uses mask of HIDElementTypeMask to restrict element found
// use kHIDElementTypeIO to get non-collection elements
extern pRecElement HIDGetPreviousDeviceElement (pRecElement pElement, HIDElementTypeMask typeMask);
// returns C string type name given a type enumeration passed in as parameter (see IOHIDKeys.h)
// returns empty string for invlid types
extern void HIDGetTypeName (IOHIDElementType theType, char * cstrName);
// set name from vendor id/product id look up (using cookies)
extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName);
// set name from vendor id/product id look up (using usage page & usage)
extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName);
// returns C string usage given usage page and usage passed in as parameters (see IOUSBHIDParser.h)
// returns usage page and usage values in string form for unknown values
extern void HIDGetUsageName (long valueUsagePage, long valueUsage, char * cstrName);
// returns calibrated value given raw value passed in
// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values
// extern SInt32 HIDCalibrateValue (SInt32 value, pRecElement pElement);
// returns scaled value given raw value passed in
// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values
// extern SInt32 HIDScaleValue (SInt32 value, pRecElement pElement);
// ---------------------------------
// convert an element type to a mask
extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type);
// find this device
extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement,
pRecDevice *ppFoundDevice, pRecElement *ppFoundElement);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement);
// print out all of an elements information
extern int HIDPrintElement(const pRecElement pElement);
// return true if this is a valid device pointer
extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice);
// return true if this is a valid element pointer for this device
extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement);
// ==================================
// Element Event Queue and Value Interfaces
enum
{
kDefaultUserMin = 0, // default user min and max used for scaling
kDefaultUserMax = 255
};
enum
{
kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible
// but should account for the maximum possible events in the queue
// USB updates will likely occur at 100 Hz so one must account for this rate of
// if states change quickly (updates are only posted on state changes)
};
// ==================================
// queues specific element, performing any device queue set up required
extern unsigned long HIDQueueElement (pRecDevice pDevice, pRecElement pElement);
// adds all elements to queue, performing any device queue set up required
extern unsigned long HIDQueueDevice (pRecDevice pDevice);
// removes element for queue, if last element in queue will release queue and device
extern unsigned long HIDDequeueElement (pRecDevice pDevice, pRecElement pElement);
// completely removes all elements from queue and releases queue and device
extern unsigned long HIDDequeueDevice (pRecDevice pDevice);
// releases all device queues for quit or rebuild (must be called)
extern unsigned long HIDReleaseAllDeviceQueues (void);
// releases interface to device, should be done prior to exiting application (called from HIDReleaseDeviceList)
extern unsigned long HIDCloseReleaseInterface (pRecDevice pDevice);
// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent);
// returns current value for element, creating device interface as required, polling element
extern long HIDGetElementValue (pRecDevice pDevice, pRecElement pElement);
// Set an elements value
// NOTE: This should only be used when a single element report needs to be sent.
// If multiple elements reports are to be send then transactions should be used.
// pIOHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern long HIDSetElementValue (pRecDevice pDevice, pRecElement pElement,void* pIOHIDEvent);
// Set a callback to be called when a queue goes from empty to non-empty
extern long HIDSetQueueCallback (pRecDevice pDevice, IOHIDCallbackFunction callback);
#if 0
// Get a report from a device
extern long HIDGetReport (pRecDevice pDevice,const IOHIDReportType reportType, const unsigned long reportID, void* reportBuffer, unsigned long* reportBufferSize);
// Send a report to a device
extern long HIDSetReport (pRecDevice pDevice,const IOHIDReportType reportType, const unsigned long reportID, void* reportBuffer, const unsigned long reportBufferSize);
#endif
// ==================================
// HUD utilities interfaces
// returns calibrated value given raw value passed in
// calibrated value is equal to min and max values returned by HIDGetElementValue since device list built scaled to element reported min and max values
extern long HIDCalibrateValue (long value, pRecElement pElement);
// returns scaled value given raw value passed in
// scaled value is equal to current value assumed to be in the range of element reported min and max values scaled to user min and max scaled values
extern long HIDScaleValue (long value, pRecElement pElement);
// convert an element type to a mask
extern HIDElementTypeMask HIDConvertElementTypeToMask (const long type);
// find this device
extern Boolean HIDFindDevice(const pRecDevice pSearchDevice, pRecDevice *ppFoundDevice);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindActionDeviceAndElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement,
pRecDevice *ppFoundDevice, pRecElement *ppFoundElement);
// find the device and element for this action
// Device: serial, vendorID, productID, location, usagePage, usage
// Element: cookie, usagePage, usage,
extern Boolean HIDFindSubElement(const pRecElement pStartElement, const pRecElement pSearchElement, pRecElement *ppFoundElement);
// print out all of an elements information
extern int HIDPrintElement(const pRecElement pElement);
// return true if this is a valid device pointer
extern Boolean HIDIsValidDevice(const pRecDevice pSearchDevice);
// return true if this is a valid element pointer for this device
extern Boolean HIDIsValidElement(const pRecDevice pSearchDevice, const pRecElement pSearchElement);
// ==================================
// Name Lookup Interfaces
// set name from vendor id/product id look up (using cookies)
extern Boolean HIDGetElementNameFromVendorProductCookie (const long vendorID, const long productID, const long cookie, char * pName);
// set name from vendor id/product id look up (using usage page & usage)
extern Boolean HIDGetElementNameFromVendorProductUsage (const long vendorID, const long productID, const long pUsagePage, const long pUsage, char * pName);
// ==================================
// Conguration and Save Interfaces
enum
{
kPercentMove = 10 // precent of overall range a element must move to register
};
typedef struct recSaveHID
{
long actionCookie;
// device
// need to add serial number when I have a test case
long vendorID;
long productID;
long locID;
long usage;
long usagePage;
// elements
long usagePageE;
long usageE;
void * cookie;
}recSaveHID,*pRecSaveHID;
// polls all devices and elements for a change greater than kPercentMove. Times out after given time
// returns true and pointer to device and element if found
// returns false and NULL for both parameters if not found
extern unsigned char HIDConfigureAction (pRecDevice * ppDevice, pRecElement * ppElement, float timeout);
// take input records, save required info
// assume file is open and at correct position.
extern void HIDSaveElementConfig (FILE * fileRef, pRecDevice pDevice, pRecElement pElement, long actionCookie);
// take file, read one record (assume file position is correct and file is open)
// search for matching device
// return pDevice, pElement and cookie for action
extern long HIDRestoreElementConfig (FILE * fileRef, pRecDevice * ppDevice, pRecElement * ppElement);
// Save the device & element values into the specified key in the specified applications preferences
extern Boolean HIDSaveElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice pDevice, pRecElement pElement);
// Find the specified preference in the specified application
// search for matching device and element
// return pDevice, pElement that matches
extern Boolean HIDRestoreElementPref (CFStringRef keyCFStringRef, CFStringRef appCFStringRef, pRecDevice * ppDevice, pRecElement * ppElement);
// ==================================
// Output Transaction interface
// Create and open an transaction interface to device, required prior to extracting values or building Transactions
extern unsigned long HIDTransactionAddElement(pRecDevice pDevice, pRecElement pElement);
// removes an element from a Transaction
extern unsigned long HIDTransactionRemoveElement(pRecDevice pDevice, pRecElement pElement);
// return true if this transaction contains this element
extern Boolean HIDTransactionHasElement(pRecDevice pDevice, pRecElement pElement);
/* This changes the default value of an element, when the values of the */
/* elements are cleared, on clear or commit, they are reset to the */
/* default value */
/* This call can be made on elements that are not in the transaction, but */
/* has undefined behavior if made on elements not in the transaction */
/* which are later added to the transaction. */
/* In other words, an element should be added before its default is */
/* set, for well defined behavior. */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionSetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Get the current setting of an element's default value */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionGetElementDefault(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Add a change to the transaction, by setting an element value */
/* The change is not actually made until it is commited */
/* The element must be part of the transaction or this call will fail */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionSetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Get the current setting of an element value */
// pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required
extern unsigned long HIDTransactionGetElementValue(pRecDevice pDevice, pRecElement pElement,IOHIDEventStruct* pValueEvent);
/* Commit the transaction, or clear all the changes and start over */
/* timoutMS is the timeout in milliseconds, a zero timeout will cause */
/* this call to be non-blocking (returning queue empty) if there */
/* is a NULL callback, and blocking forever until the queue is */
/* non-empty if their is a valid callback */
/* callback, if non-NULL is a callback to be called when data is */
/* inserted to the queue */
/* callbackTarget and callbackRefcon are passed to the callback */
extern unsigned long HIDTransactionCommit(pRecDevice pDevice);
/* Clear all the changes and start over */
extern unsigned long HIDTransactionClear(pRecDevice pDevice);
// ==================================
#ifdef __cplusplus
}
#endif
#endif // _HID_Utilities_External_h_

54
HID_Utilities_Internal.h Executable file
View File

@ -0,0 +1,54 @@
/*
File: HID_Utilities_Internal.h
Contains: Definition of HID Utilities internal functions
DRI: George Warner
Copyright: Copyright © 2002 Apple Computer, Inc., All Rights Reserved
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HID_Utilities_Internal_h_
#define _HID_Utilities_Internal_h_
// Moved into specific "HID_xxx.h" files.
#include "HID_Error_Handler.h"
#endif // _HID_Utilities_Internal_h_

95
ImmrHIDUtilAddOn.c Executable file
View File

@ -0,0 +1,95 @@
/*
* ImmrHIDUtilAddOn.c
* UseFFAPIFromHIDUtilities
*
* Created by rlacroix on Wed Oct 16 2002.
* Copyright (c) 2002 Immersion Corporation. All rights reserved.
*
*/
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDUsageTables.h>
#include "HID_Utilities_External.h"
#include "ImmrHIDUtilAddOn.h"
//---------------------------------------------------------------------------------
//
// AllocateHIDObjectFromRecDevice()
//
// returns:
// NULL, or acceptable io_object_t
//
//---------------------------------------------------------------------------------
io_service_t AllocateHIDObjectFromRecDevice( pRecDevice pDevice )
{
CFMutableDictionaryRef matchingDict;
UInt32 locationID = pDevice->locID;
CFNumberRef refUsage = NULL;
mach_port_t masterPort = NULL;
IOReturn result = kIOReturnSuccess;
io_service_t hidDevice = NULL;
do // while( 0 )
{
result = IOMasterPort (bootstrap_port, &masterPort);
if( result != kIOReturnSuccess )
{
break;
}
// Set up the matching criteria for the devices we're interested in.
// We are interested in instances of class IOHIDDevice.
// matchingDict is consumed below (in IOServiceGetMatchingService)
// so we have no leak here.
//
matchingDict = IOServiceMatching(kIOHIDDeviceKey);
if (!matchingDict)
{
break;
}
// Add a key for locationID to our matching dictionary. This works for matching to
// IOHIDDevices, so we will only look for a device attached to that particular port
// on the machine.
//
refUsage = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &locationID);
CFDictionaryAddValue( matchingDict,
CFSTR(kIOHIDLocationIDKey),
refUsage);
CFRelease(refUsage);
// IOServiceGetMatchingService assumes that we already know that there is only one device
// that matches. This way we don't have to do the whole iteration dance to look at each
// device that matches. This is a new API in 10.2
//
hidDevice = IOServiceGetMatchingService( masterPort, matchingDict);
}
while( 0 );
// Free master port if we created one.
//
if (masterPort)
mach_port_deallocate(mach_task_self(), masterPort);
return hidDevice;
}
//---------------------------------------------------------------------------------
//
// FreeHIDObject()
//
//---------------------------------------------------------------------------------
bool FreeHIDObject( io_service_t hidDevice )
{
kern_return_t kr;
kr = IOObjectRelease(hidDevice);
return( kIOReturnSuccess == kr );
}

11
ImmrHIDUtilAddOn.h Executable file
View File

@ -0,0 +1,11 @@
/*
* ImmrHIDUtilAddOn.h
* UseFFAPIFromHIDUtilities
*
* Created by rlacroix on Wed Oct 16 2002.
* Copyright (c) 2002 Immersion Corporation. All rights reserved.
*
*/
extern io_object_t AllocateHIDObjectFromRecDevice( pRecDevice pDevice );
extern bool FreeHIDObject( io_object_t hidDevice );

View File

@ -11,6 +11,14 @@
7489D5F11CAFF9D10063AC48 /* ASWAppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7489D5ED1CAFF9D00063AC48 /* ASWAppKit.framework */; };
7489D5F21CAFF9D10063AC48 /* ASWDebug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7489D5EE1CAFF9D10063AC48 /* ASWDebug.framework */; };
7489D5F31CAFF9D10063AC48 /* ASWFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7489D5EF1CAFF9D10063AC48 /* ASWFoundation.framework */; };
7489D6071CB0002C0063AC48 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7489D6061CB0002C0063AC48 /* ForceFeedback.framework */; settings = {ASSET_TAGS = (); }; };
7489D60E1CB000520063AC48 /* HID_Config_Utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D6081CB000520063AC48 /* HID_Config_Utilities.c */; settings = {ASSET_TAGS = (); }; };
7489D60F1CB000520063AC48 /* HID_Error_Handler.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D6091CB000520063AC48 /* HID_Error_Handler.c */; settings = {ASSET_TAGS = (); }; };
7489D6101CB000520063AC48 /* HID_Name_Lookup.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D60A1CB000520063AC48 /* HID_Name_Lookup.c */; settings = {ASSET_TAGS = (); }; };
7489D6111CB000520063AC48 /* HID_Queue_Utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D60B1CB000520063AC48 /* HID_Queue_Utilities.c */; settings = {ASSET_TAGS = (); }; };
7489D6121CB000520063AC48 /* HID_Transaction_Utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D60C1CB000520063AC48 /* HID_Transaction_Utilities.c */; settings = {ASSET_TAGS = (); }; };
7489D6131CB000520063AC48 /* HID_Utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D60D1CB000520063AC48 /* HID_Utilities.c */; settings = {ASSET_TAGS = (); }; };
7489D61C1CB000F00063AC48 /* ImmrHIDUtilAddOn.c in Sources */ = {isa = PBXBuildFile; fileRef = 7489D61A1CB000F00063AC48 /* ImmrHIDUtilAddOn.c */; settings = {ASSET_TAGS = (); }; };
7F06105A0876ED46001EA95C /* ai.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F060FE50876ED46001EA95C /* ai.cpp */; };
7F06105D0876ED46001EA95C /* carphysics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F060FEA0876ED46001EA95C /* carphysics.cpp */; };
7F06105E0876ED46001EA95C /* carselection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7F060FEC0876ED46001EA95C /* carselection.cpp */; };
@ -106,6 +114,21 @@
7489D5ED1CAFF9D00063AC48 /* ASWAppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ASWAppKit.framework; path = Frameworks/ASWAppKit.framework; sourceTree = "<group>"; };
7489D5EE1CAFF9D10063AC48 /* ASWDebug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ASWDebug.framework; path = Frameworks/ASWDebug.framework; sourceTree = "<group>"; };
7489D5EF1CAFF9D10063AC48 /* ASWFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ASWFoundation.framework; path = Frameworks/ASWFoundation.framework; sourceTree = "<group>"; };
7489D6061CB0002C0063AC48 /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = Frameworks/ForceFeedback.framework; sourceTree = "<group>"; };
7489D6081CB000520063AC48 /* HID_Config_Utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HID_Config_Utilities.c; sourceTree = "<group>"; };
7489D6091CB000520063AC48 /* HID_Error_Handler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HID_Error_Handler.c; sourceTree = "<group>"; };
7489D60A1CB000520063AC48 /* HID_Name_Lookup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HID_Name_Lookup.c; sourceTree = "<group>"; };
7489D60B1CB000520063AC48 /* HID_Queue_Utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HID_Queue_Utilities.c; sourceTree = "<group>"; };
7489D60C1CB000520063AC48 /* HID_Transaction_Utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HID_Transaction_Utilities.c; sourceTree = "<group>"; };
7489D60D1CB000520063AC48 /* HID_Utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HID_Utilities.c; sourceTree = "<group>"; };
7489D6141CB000620063AC48 /* HID_Utilities_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HID_Utilities_Internal.h; sourceTree = "<group>"; };
7489D6151CB0006F0063AC48 /* HID_Error_Handler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HID_Error_Handler.h; sourceTree = "<group>"; };
7489D6161CB0006F0063AC48 /* HID_Name_Lookup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HID_Name_Lookup.h; sourceTree = "<group>"; };
7489D6171CB0006F0063AC48 /* HID_Queue_Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HID_Queue_Utilities.h; sourceTree = "<group>"; };
7489D6181CB0007A0063AC48 /* HID_Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HID_Utilities.h; sourceTree = "<group>"; };
7489D6191CB000850063AC48 /* HID_Utilities_External.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HID_Utilities_External.h; sourceTree = "<group>"; };
7489D61A1CB000F00063AC48 /* ImmrHIDUtilAddOn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ImmrHIDUtilAddOn.c; sourceTree = "<group>"; };
7489D61B1CB000F00063AC48 /* ImmrHIDUtilAddOn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmrHIDUtilAddOn.h; sourceTree = "<group>"; };
7F060FE50876ED46001EA95C /* ai.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ai.cpp; sourceTree = "<group>"; };
7F060FEA0876ED46001EA95C /* carphysics.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = carphysics.cpp; sourceTree = "<group>"; };
7F060FEB0876ED46001EA95C /* carphysics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = carphysics.h; sourceTree = "<group>"; };
@ -274,6 +297,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7489D6071CB0002C0063AC48 /* ForceFeedback.framework in Frameworks */,
8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */,
7FC1DAFD087820860029047D /* AGL.framework in Frameworks */,
7FC1DB0E087820970029047D /* QuickTime.framework in Frameworks */,
@ -338,6 +362,7 @@
20286C32FDCF999611CA2CEA /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
7489D6061CB0002C0063AC48 /* ForceFeedback.framework */,
7489D5EC1CAFF9D00063AC48 /* AmbrosiaTools.framework */,
7489D5ED1CAFF9D00063AC48 /* ASWAppKit.framework */,
7489D5EE1CAFF9D10063AC48 /* ASWDebug.framework */,
@ -471,6 +496,20 @@
7F06136E087703B4001EA95C /* HID */ = {
isa = PBXGroup;
children = (
7489D6081CB000520063AC48 /* HID_Config_Utilities.c */,
7489D6091CB000520063AC48 /* HID_Error_Handler.c */,
7489D60A1CB000520063AC48 /* HID_Name_Lookup.c */,
7489D60B1CB000520063AC48 /* HID_Queue_Utilities.c */,
7489D60C1CB000520063AC48 /* HID_Transaction_Utilities.c */,
7489D60D1CB000520063AC48 /* HID_Utilities.c */,
7489D6141CB000620063AC48 /* HID_Utilities_Internal.h */,
7489D6151CB0006F0063AC48 /* HID_Error_Handler.h */,
7489D6161CB0006F0063AC48 /* HID_Name_Lookup.h */,
7489D6171CB0006F0063AC48 /* HID_Queue_Utilities.h */,
7489D6181CB0007A0063AC48 /* HID_Utilities.h */,
7489D6191CB000850063AC48 /* HID_Utilities_External.h */,
7489D61A1CB000F00063AC48 /* ImmrHIDUtilAddOn.c */,
7489D61B1CB000F00063AC48 /* ImmrHIDUtilAddOn.h */,
7FD85DEA08BC79EF00C3EB17 /* HID_Config_Utilities.c */,
7FD85DEB08BC79EF00C3EB17 /* HID_Error_Handler.c */,
7FD85DEC08BC79EF00C3EB17 /* HID_Name_Lookup.c */,
@ -606,18 +645,24 @@
7F0610670876ED46001EA95C /* entities.cpp in Sources */,
7F0610680876ED46001EA95C /* environment.cpp in Sources */,
7F0610690876ED46001EA95C /* fileio.cpp in Sources */,
7489D61C1CB000F00063AC48 /* ImmrHIDUtilAddOn.c in Sources */,
7F06106A0876ED46001EA95C /* gameframe.cpp in Sources */,
7F06106B0876ED46001EA95C /* gameinitexit.cpp in Sources */,
7F06106D0876ED46001EA95C /* infodisplay.cpp in Sources */,
7489D60E1CB000520063AC48 /* HID_Config_Utilities.c in Sources */,
7F06106E0876ED46001EA95C /* initexit.cpp in Sources */,
7F0610700876ED46001EA95C /* interfacemultiplayer.cpp in Sources */,
7F0610710876ED46001EA95C /* interfaceoptions.cpp in Sources */,
7F0610720876ED46001EA95C /* interfaceutil.cpp in Sources */,
7F0610730876ED46001EA95C /* lights.cpp in Sources */,
7489D6101CB000520063AC48 /* HID_Name_Lookup.c in Sources */,
7F0610740876ED46001EA95C /* log.cpp in Sources */,
7F0610750876ED46001EA95C /* maccontrols.cpp in Sources */,
7489D6121CB000520063AC48 /* HID_Transaction_Utilities.c in Sources */,
7489D60F1CB000520063AC48 /* HID_Error_Handler.c in Sources */,
7F0610760876ED46001EA95C /* macerror.cpp in Sources */,
7F0610770876ED46001EA95C /* macfileio.cpp in Sources */,
7489D6131CB000520063AC48 /* HID_Utilities.c in Sources */,
7F0610780876ED46001EA95C /* maclocaltracker.cpp in Sources */,
7F0610790876ED46001EA95C /* macscreen.cpp in Sources */,
7F06107A0876ED46001EA95C /* macsystem.cpp in Sources */,
@ -642,6 +687,7 @@
7F0610910876ED46001EA95C /* textures.cpp in Sources */,
7F0610920876ED46001EA95C /* tire.cpp in Sources */,
7F0610930876ED46001EA95C /* tracker.cpp in Sources */,
7489D6111CB000520063AC48 /* HID_Queue_Utilities.c in Sources */,
7F0610940876ED46001EA95C /* tracks.cpp in Sources */,
7F0610950876ED46001EA95C /* transparency.cpp in Sources */,
7F0610960876ED46001EA95C /* vectors.cpp in Sources */,