mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
5ae5d2e7eb
38 changed files with 10401 additions and 342 deletions
|
@ -27,6 +27,8 @@ endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
|||
|
||||
option( DYN_FLUIDSYNTH "Dynamically load fluidsynth" ON )
|
||||
|
||||
option( OSX_COCOA_BACKEND "Use native Cocoa backend instead of SDL" ON )
|
||||
|
||||
if( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||
set( X64 64 )
|
||||
endif( CMAKE_SIZEOF_VOID_P MATCHES "8" )
|
||||
|
@ -212,7 +214,9 @@ else( WIN32 )
|
|||
if( NOT SDL_FOUND )
|
||||
message( SEND_ERROR "SDL is required for building." )
|
||||
endif( NOT SDL_FOUND )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" )
|
||||
if( NOT APPLE OR NOT OSX_COCOA_BACKEND )
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" )
|
||||
endif( NOT APPLE OR NOT OSX_COCOA_BACKEND )
|
||||
include_directories( "${SDL_INCLUDE_DIR}" )
|
||||
|
||||
find_path( FPU_CONTROL_DIR fpu_control.h )
|
||||
|
@ -428,9 +432,10 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
|||
endif( PROFILE )
|
||||
|
||||
set( REL_CXX_FLAGS "-fno-rtti" )
|
||||
if( NOT PROFILE )
|
||||
if( NOT PROFILE AND NOT APPLE )
|
||||
# On OS X frame pointers are required for exception handling, at least with Clang
|
||||
set( REL_CXX_FLAGS "${REL_CXX_FLAGS} -fomit-frame-pointer" )
|
||||
endif( NOT PROFILE )
|
||||
endif( NOT PROFILE AND NOT APPLE )
|
||||
set( CMAKE_CXX_FLAGS_RELEASE "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}" )
|
||||
set( CMAKE_CXX_FLAGS_MINSIZEREL "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_MINSIZEREL}" )
|
||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${REL_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" )
|
||||
|
@ -556,21 +561,52 @@ set( PLAT_WIN32_SOURCES
|
|||
win32/i_system.cpp
|
||||
win32/st_start.cpp
|
||||
win32/win32video.cpp )
|
||||
set( PLAT_SDL_SOURCES
|
||||
set( PLAT_SDL_SYSTEM_SOURCES
|
||||
sdl/crashcatcher.c
|
||||
sdl/hardware.cpp
|
||||
sdl/i_cd.cpp
|
||||
sdl/i_input.cpp
|
||||
sdl/i_joystick.cpp
|
||||
sdl/i_main.cpp
|
||||
sdl/i_movie.cpp
|
||||
sdl/i_system.cpp
|
||||
sdl/sdlvideo.cpp
|
||||
sdl/st_start.cpp )
|
||||
set( PLAT_SDL_SPECIAL_SOURCES
|
||||
sdl/i_gui.cpp
|
||||
sdl/i_input.cpp
|
||||
sdl/i_joystick.cpp
|
||||
sdl/i_timer.cpp )
|
||||
set( PLAT_MAC_SOURCES
|
||||
sdl/SDLMain.m
|
||||
sdl/iwadpicker_cocoa.mm
|
||||
sdl/i_system_cocoa.mm )
|
||||
set( PLAT_COCOA_SOURCES
|
||||
cocoa/HID_Config_Utilities.c
|
||||
cocoa/HID_Error_Handler.c
|
||||
cocoa/HID_Name_Lookup.c
|
||||
cocoa/HID_Queue_Utilities.c
|
||||
cocoa/HID_Utilities.c
|
||||
cocoa/IOHIDDevice_.c
|
||||
cocoa/IOHIDElement_.c
|
||||
cocoa/ImmrHIDUtilAddOn.c
|
||||
cocoa/i_backend_cocoa.mm
|
||||
cocoa/i_joystick.cpp
|
||||
cocoa/i_timer.cpp
|
||||
cocoa/zdoom.icns )
|
||||
|
||||
if( APPLE )
|
||||
set( PLAT_SDL_SOURCES ${PLAT_SDL_SYSTEM_SOURCES} "${FMOD_LIBRARY}" )
|
||||
|
||||
if( OSX_COCOA_BACKEND )
|
||||
set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} )
|
||||
else( OSX_COCOA_BACKEND )
|
||||
set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} sdl/SDLMain.m )
|
||||
endif( OSX_COCOA_BACKEND )
|
||||
|
||||
set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
|
||||
set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks )
|
||||
else( APPLE )
|
||||
set( PLAT_SDL_SOURCES ${PLAT_SDL_SYSTEM_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} )
|
||||
endif( APPLE )
|
||||
|
||||
if( WIN32 )
|
||||
set( SYSTEM_SOURCES_DIR win32 )
|
||||
set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} )
|
||||
|
@ -772,7 +808,7 @@ set( NOT_COMPILED_SOURCE_FILES
|
|||
asm_x86_64/tmap3.s
|
||||
)
|
||||
|
||||
add_executable( zdoom WIN32
|
||||
add_executable( zdoom WIN32 MACOSX_BUNDLE
|
||||
${HEADER_FILES}
|
||||
${NOT_COMPILED_SOURCE_FILES}
|
||||
__autostart.cpp
|
||||
|
@ -1164,6 +1200,25 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
|||
endif( SSE_MATTERS )
|
||||
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||
|
||||
if( APPLE )
|
||||
set_target_properties(zdoom PROPERTIES
|
||||
LINK_FLAGS "-framework Carbon -framework Cocoa -framework IOKit -framework OpenGL"
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cocoa/zdoom-info.plist" )
|
||||
|
||||
# Fix fmod link so that it can be found in the app bundle.
|
||||
find_program( OTOOL otool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" )
|
||||
find_program( INSTALL_NAME_TOOL install_name_tool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" )
|
||||
execute_process( COMMAND "${OTOOL}" -L "${FMOD_LIBRARY}"
|
||||
COMMAND grep "libfmodex.dylib (compat"
|
||||
COMMAND head -n1
|
||||
COMMAND awk "{print $1}"
|
||||
OUTPUT_VARIABLE FMOD_LINK
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||
add_custom_command( TARGET zdoom POST_BUILD
|
||||
COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/libfmodex.dylib "$<TARGET_FILE:zdoom>"
|
||||
COMMENT "Relinking FMOD Ex" )
|
||||
endif( APPLE )
|
||||
|
||||
source_group("Assembly Files\\ia32" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_ia32/.+")
|
||||
source_group("Assembly Files\\x86_64" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/asm_x86_64/.+")
|
||||
source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+")
|
||||
|
@ -1171,6 +1226,7 @@ source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURC
|
|||
source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.cpp oplsynth/dosbox/opl.h)
|
||||
source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$")
|
||||
source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$")
|
||||
source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/cocoa/.+")
|
||||
source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+")
|
||||
source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
|
||||
source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+")
|
||||
|
|
|
@ -230,7 +230,11 @@ const char *KeyNames[NUM_KEYS] =
|
|||
NULL, NULL, NULL, NULL, NULL, "pause", NULL, "home", //C0
|
||||
"uparrow", "pgup", NULL, "leftarrow",NULL, "rightarrow",NULL, "end", //C8
|
||||
"downarrow","pgdn", "ins", "del", NULL, NULL, NULL, NULL, //D0
|
||||
#ifdef __APPLE__
|
||||
NULL, NULL, NULL, "command", NULL, "apps", "power", "sleep", //D8
|
||||
#else // !__APPLE__
|
||||
NULL, NULL, NULL, "lwin", "rwin", "apps", "power", "sleep", //D8
|
||||
#endif // __APPLE__
|
||||
NULL, NULL, NULL, "wake", NULL, "search", "favorites","refresh", //E0
|
||||
"webstop", "webforward","webback", "mycomputer","mail", "mediaselect",NULL, NULL, //E8
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, //F0
|
||||
|
|
|
@ -1426,7 +1426,11 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len)
|
|||
case 'V':
|
||||
TabbedLast = false;
|
||||
TabbedList = false;
|
||||
#ifdef __APPLE__
|
||||
if (ev->data3 & GKM_META)
|
||||
#else // !__APPLE__
|
||||
if (ev->data3 & GKM_CTRL)
|
||||
#endif // __APPLE__
|
||||
{
|
||||
if (data1 == 'C')
|
||||
{ // copy to clipboard
|
||||
|
|
926
src/cocoa/HID_Config_Utilities.c
Normal file
926
src/cocoa/HID_Config_Utilities.c
Normal file
|
@ -0,0 +1,926 @@
|
|||
// File: HID_Config_Utilities.c
|
||||
// Abstract: Implementation of the HID configuration utilities
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#define LOG_SCORING 0
|
||||
|
||||
#include <stdlib.h> // malloc
|
||||
#include <time.h> // clock
|
||||
|
||||
#include <AssertMacros.h>
|
||||
|
||||
#include "HID_Utilities_External.h"
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
// polls single device's elements for a change greater than kPercentMove. Times out after given time
|
||||
// returns 1 and pointer to element if found
|
||||
// returns 0 and NULL for both parameters if not found
|
||||
|
||||
unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout) {
|
||||
if ( !inIOHIDDeviceRef ) {
|
||||
return (0);
|
||||
}
|
||||
if ( 0 == HIDHaveDeviceList() ) { // if we do not have a device list
|
||||
return (0); // return 0
|
||||
}
|
||||
|
||||
Boolean found = FALSE;
|
||||
|
||||
// build list of device and elements to save current values
|
||||
int maxElements = HIDCountDeviceElements(inIOHIDDeviceRef, kHIDElementTypeInput);
|
||||
int *saveValueArray = (int *) calloc( maxElements, sizeof(int) ); // 2D array to save values
|
||||
|
||||
// store initial values on first pass / compare to initial value on subsequent passes
|
||||
Boolean first = TRUE;
|
||||
|
||||
// get all the elements from this device
|
||||
CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(inIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||
// if that worked...
|
||||
if ( elementCFArrayRef ) {
|
||||
clock_t start = clock(), end;
|
||||
|
||||
// poll all devices and elements
|
||||
while ( !found ) {
|
||||
int currElementIndex = 0;
|
||||
CFIndex idx, cnt = CFArrayGetCount(elementCFArrayRef);
|
||||
for ( idx = 0; idx < cnt; idx++ ) {
|
||||
*outIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||
if ( !*outIOHIDElementRef ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// is this an input element?
|
||||
IOHIDElementType type = IOHIDElementGetType(*outIOHIDElementRef);
|
||||
|
||||
switch ( type ) {
|
||||
// these types are inputs
|
||||
case kIOHIDElementTypeInput_Misc:
|
||||
case kIOHIDElementTypeInput_Button:
|
||||
case kIOHIDElementTypeInput_Axis:
|
||||
case kIOHIDElementTypeInput_ScanCodes:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case kIOHIDElementTypeOutput:
|
||||
case kIOHIDElementTypeFeature:
|
||||
case kIOHIDElementTypeCollection:
|
||||
{
|
||||
*outIOHIDElementRef = NULL; // these types are not ( Skip them )
|
||||
break;
|
||||
}
|
||||
} /* switch */
|
||||
if ( !*outIOHIDElementRef ) {
|
||||
continue; // skip this element
|
||||
}
|
||||
|
||||
// get this elements current value
|
||||
int value = 0; // default value is zero
|
||||
IOHIDValueRef tIOHIDValueRef;
|
||||
IOReturn ioReturn = IOHIDDeviceGetValue(inIOHIDDeviceRef, *outIOHIDElementRef, &tIOHIDValueRef);
|
||||
if ( kIOReturnSuccess == ioReturn ) {
|
||||
value = IOHIDValueGetScaledValue(tIOHIDValueRef, kIOHIDValueScaleTypePhysical);
|
||||
}
|
||||
if ( first ) {
|
||||
saveValueArray[currElementIndex] = value;
|
||||
} else {
|
||||
CFIndex min = IOHIDElementGetLogicalMin(*outIOHIDElementRef);
|
||||
CFIndex max = IOHIDElementGetLogicalMax(*outIOHIDElementRef);
|
||||
|
||||
int initialValue = saveValueArray[currElementIndex];
|
||||
int delta = (float)(max - min) * kPercentMove * 0.01;
|
||||
// is the new value within +/- delta of the initial value?
|
||||
if ( ( (initialValue + delta) < value ) || ( (initialValue - delta) > value ) ) {
|
||||
found = 1; // ( yes! ) mark as found
|
||||
break;
|
||||
}
|
||||
} // if ( first )
|
||||
|
||||
currElementIndex++; // bump element index
|
||||
} // next idx
|
||||
|
||||
first = FALSE; // no longer the first pass
|
||||
|
||||
// are we done?
|
||||
end = clock();
|
||||
double secs = (double)(end - start) / CLOCKS_PER_SEC;
|
||||
if ( secs > timeout ) {
|
||||
break; // ( yes ) timeout
|
||||
}
|
||||
} // while ( !found )
|
||||
|
||||
CFRelease(elementCFArrayRef);
|
||||
} // if ( elementCFArrayRef )
|
||||
// return device and element moved
|
||||
if ( found ) {
|
||||
return (1);
|
||||
} else {
|
||||
*outIOHIDElementRef = NULL;
|
||||
return (0);
|
||||
}
|
||||
} // HIDConfigureSingleDeviceAction
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDConfigureAction( outIOHIDDeviceRef, outIOHIDElementRef, inTimeout )
|
||||
//
|
||||
// Purpose: 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
|
||||
//
|
||||
// Inputs: outIOHIDDeviceRef - address where to store the device
|
||||
// outIOHIDElementRef - address where to store the element
|
||||
// inTimeout - the timeout
|
||||
// Returns: Boolean - if successful
|
||||
// outIOHIDDeviceRef - the device
|
||||
// outIOHIDElementRef - the element
|
||||
//
|
||||
|
||||
Boolean HIDConfigureAction(IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float inTimeout) {
|
||||
// param error?
|
||||
if ( !outIOHIDDeviceRef || !outIOHIDElementRef ) {
|
||||
return (0);
|
||||
}
|
||||
if ( !gDeviceCFArrayRef ) { // if we do not have a device list
|
||||
// and we can't build another list
|
||||
if ( !HIDBuildDeviceList(0, 0) || !gDeviceCFArrayRef ) {
|
||||
return (FALSE); // bail
|
||||
}
|
||||
}
|
||||
|
||||
IOHIDDeviceRef tIOHIDDeviceRef;
|
||||
IOHIDElementRef tIOHIDElementRef;
|
||||
|
||||
// remember when we start; used to calculate timeout
|
||||
clock_t start = clock(), end;
|
||||
|
||||
// determine the maximum number of elements
|
||||
CFIndex maxElements = 0;
|
||||
CFIndex devIndex, devCount = CFArrayGetCount(gDeviceCFArrayRef);
|
||||
for ( devIndex = 0; devIndex < devCount; devIndex++ ) {
|
||||
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIndex);
|
||||
if ( !tIOHIDDeviceRef ) {
|
||||
continue; // skip this one
|
||||
}
|
||||
|
||||
CFIndex count = HIDCountDeviceElements(tIOHIDDeviceRef, kHIDElementTypeInput);
|
||||
if ( count > maxElements ) {
|
||||
maxElements = count;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate an array of int's in which to store devCount * maxElements values
|
||||
double *saveValueArray = (double *) calloc( devCount * maxElements, sizeof(double) ); // clear 2D array to save values
|
||||
|
||||
// on first pass store initial values / compare current values to initial values on subsequent passes
|
||||
Boolean found = FALSE, first = TRUE;
|
||||
|
||||
while ( !found ) {
|
||||
double maxDeltaPercent = 0; // we want to find the one that moves the most ( percentage wise )
|
||||
for ( devIndex = 0; devIndex < devCount; devIndex++ ) {
|
||||
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIndex);
|
||||
if ( !tIOHIDDeviceRef ) {
|
||||
continue; // skip this one
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||
#endif
|
||||
gElementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||
if ( gElementCFArrayRef ) {
|
||||
CFIndex eleIndex, eleCount = CFArrayGetCount(gElementCFArrayRef);
|
||||
for ( eleIndex = 0; eleIndex < eleCount; eleIndex++ ) {
|
||||
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gElementCFArrayRef, eleIndex);
|
||||
if ( !tIOHIDElementRef ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IOHIDElementType tIOHIDElementType = IOHIDElementGetType(tIOHIDElementRef);
|
||||
// only care about inputs (no outputs or features)
|
||||
if ( tIOHIDElementType <= kIOHIDElementTypeInput_ScanCodes ) {
|
||||
if ( IOHIDElementIsArray(tIOHIDElementRef) ) {
|
||||
//printf( "ARRAY!\n" );
|
||||
continue; // skip array elements
|
||||
}
|
||||
|
||||
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||
uint32_t reportCount = IOHIDElementGetReportCount(tIOHIDElementRef);
|
||||
#ifdef DEBUG
|
||||
if ( first ) {
|
||||
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||
printf("%s, dev: {ref:%p, ven: 0x%08lX, pro: 0x%08lX}, ele: {ref:%p, cookie: %p, usage:%04lX:%08lX}\n",
|
||||
__PRETTY_FUNCTION__,
|
||||
tIOHIDDeviceRef,
|
||||
vendorID,
|
||||
productID,
|
||||
tIOHIDElementRef,
|
||||
cookie,
|
||||
(long unsigned int) usagePage,
|
||||
(long unsigned int) usage);
|
||||
fflush(stdout);
|
||||
if ( (0x054C == vendorID) && (0x0268 == productID) && (0x001E == (UInt32) cookie) ) {
|
||||
//printf( "DING!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#if 1 // work-around for IOHIDValueGetScaledValue crash (when element report count > 1)
|
||||
if ( reportCount > 1 ) {
|
||||
//printf( "REPORT!\n" );
|
||||
continue; // skip reports
|
||||
}
|
||||
|
||||
#endif
|
||||
// ignore PID elements and arrays
|
||||
if ( (kHIDPage_PID != usagePage) && (((uint32_t)-1) != usage) ) {
|
||||
// get this elements current value
|
||||
double value = 0.0; // default value is zero
|
||||
IOHIDValueRef tIOHIDValueRef;
|
||||
IOReturn ioReturn = IOHIDDeviceGetValue(tIOHIDDeviceRef, tIOHIDElementRef, &tIOHIDValueRef);
|
||||
if ( kIOReturnSuccess == ioReturn ) {
|
||||
value = IOHIDValueGetScaledValue(tIOHIDValueRef, kIOHIDValueScaleTypePhysical);
|
||||
}
|
||||
if ( first ) {
|
||||
saveValueArray[(devIndex * maxElements) + eleIndex] = value;
|
||||
} else {
|
||||
double initialValue = saveValueArray[(devIndex * maxElements) + eleIndex];
|
||||
|
||||
CFIndex valueMin = IOHIDElementGetPhysicalMin(tIOHIDElementRef);
|
||||
CFIndex valueMax = IOHIDElementGetPhysicalMax(tIOHIDElementRef);
|
||||
|
||||
double deltaPercent = fabs( (initialValue - value) * 100.0 / (valueMax - valueMin) );
|
||||
#if 0 // debug code useful to dump out value info for specific (vendorID, productID, usagePage and usage) device
|
||||
if ( !first ) {
|
||||
// Device: 0x13b6a0 = { Logitech Inc. - WingMan Force 3D, vendorID: 0x046D, productID: 0xC283,
|
||||
// usage: 0x0001:0x0004, "Generic Desktop Joystick"
|
||||
if ( (vendorID == 0x046D) && (productID == 0xC283) ) {
|
||||
if ( (kHIDPage_GenericDesktop == usagePage) && (kHIDUsage_GD_Rz == usage) ) {
|
||||
printf("initial: %6.2f, value: %6.2f, diff: %6.2f, delta percent: %6.2f!\n",
|
||||
initialValue,
|
||||
value,
|
||||
fabs(initialValue - value),
|
||||
deltaPercent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deltaPercent = 0.0;
|
||||
#endif
|
||||
if ( deltaPercent >= kPercentMove ) {
|
||||
found = TRUE;
|
||||
if ( deltaPercent > maxDeltaPercent ) {
|
||||
maxDeltaPercent = deltaPercent;
|
||||
|
||||
*outIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||
*outIOHIDElementRef = tIOHIDElementRef;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} // if first
|
||||
|
||||
} // if usage
|
||||
|
||||
} // if type
|
||||
|
||||
} // for elements...
|
||||
|
||||
CFRelease(gElementCFArrayRef);
|
||||
gElementCFArrayRef = NULL;
|
||||
} // if ( gElementCFArrayRef )
|
||||
if ( found ) {
|
||||
// HIDDumpElementInfo( tIOHIDElementRef );
|
||||
break; // DONE!
|
||||
}
|
||||
} // for devices
|
||||
|
||||
first = FALSE; // no longer the first pass
|
||||
|
||||
// are we done?
|
||||
end = clock();
|
||||
double secs = (double)(end - start) / CLOCKS_PER_SEC;
|
||||
if ( secs > inTimeout ) {
|
||||
break; // ( yes ) timeout
|
||||
}
|
||||
} // while ( !found )
|
||||
// return device and element moved
|
||||
if ( !found ) {
|
||||
*outIOHIDDeviceRef = NULL;
|
||||
*outIOHIDElementRef = NULL;
|
||||
}
|
||||
|
||||
return (found);
|
||||
} // HIDConfigureAction
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inIOHIDDeviceRef, inIOHIDElementRef )
|
||||
//
|
||||
// Purpose: Save the device & element values into the specified key in the specified applications preferences
|
||||
//
|
||||
// Inputs: inKeyCFStringRef - the preference key
|
||||
// inAppCFStringRef - the application identifier
|
||||
// inIOHIDDeviceRef - the device
|
||||
// inIOHIDElementRef - the element
|
||||
// Returns: Boolean - if successful
|
||||
//
|
||||
|
||||
Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef,
|
||||
CFStringRef inAppCFStringRef,
|
||||
IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
IOHIDElementRef inIOHIDElementRef) {
|
||||
Boolean success = FALSE;
|
||||
if ( inKeyCFStringRef && inAppCFStringRef && inIOHIDDeviceRef && inIOHIDElementRef ) {
|
||||
long vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef);
|
||||
require(vendorID, Oops);
|
||||
|
||||
long productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef);
|
||||
require(productID, Oops);
|
||||
|
||||
long locID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef);
|
||||
require(locID, Oops);
|
||||
|
||||
uint32_t usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef);
|
||||
uint32_t usage = IOHIDDevice_GetUsage(inIOHIDDeviceRef);
|
||||
if ( !usagePage || !usage ) {
|
||||
usagePage = IOHIDDevice_GetPrimaryUsagePage(inIOHIDDeviceRef);
|
||||
usage = IOHIDDevice_GetPrimaryUsage(inIOHIDDeviceRef);
|
||||
}
|
||||
|
||||
require(usagePage && usage, Oops);
|
||||
|
||||
uint32_t usagePageE = IOHIDElementGetUsagePage(inIOHIDElementRef);
|
||||
uint32_t usageE = IOHIDElementGetUsage(inIOHIDElementRef);
|
||||
IOHIDElementCookie eleCookie = IOHIDElementGetCookie(inIOHIDElementRef);
|
||||
|
||||
CFStringRef prefCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
|
||||
CFSTR("d:{v:%ld, p:%ld, l:%ld, p:%ld, u:%ld}, e:{p:%ld, u:%ld, c:%ld}"),
|
||||
vendorID, productID, locID, usagePage, usage,
|
||||
usagePageE, usageE, eleCookie);
|
||||
if ( prefCFStringRef ) {
|
||||
CFPreferencesSetAppValue(inKeyCFStringRef, prefCFStringRef, inAppCFStringRef);
|
||||
CFRelease(prefCFStringRef);
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Oops: ;
|
||||
return (success);
|
||||
} // HIDSaveElementPref
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outIOHIDDeviceRef, outIOHIDElementRef )
|
||||
//
|
||||
// Purpose: Find the specified preference in the specified application
|
||||
//
|
||||
// Inputs: inKeyCFStringRef - the preference key
|
||||
// inAppCFStringRef - the application identifier
|
||||
// outIOHIDDeviceRef - address where to restore the device
|
||||
// outIOHIDElementRef - address where to restore the element
|
||||
// Returns: Boolean - if successful
|
||||
// outIOHIDDeviceRef - the device
|
||||
// outIOHIDElementRef - the element
|
||||
//
|
||||
|
||||
Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef,
|
||||
CFStringRef inAppCFStringRef,
|
||||
IOHIDDeviceRef * outIOHIDDeviceRef,
|
||||
IOHIDElementRef *outIOHIDElementRef) {
|
||||
Boolean found = FALSE;
|
||||
if ( inKeyCFStringRef && inAppCFStringRef && outIOHIDDeviceRef && outIOHIDElementRef ) {
|
||||
CFPropertyListRef prefCFPropertyListRef = CFPreferencesCopyAppValue(inKeyCFStringRef, inAppCFStringRef);
|
||||
if ( prefCFPropertyListRef ) {
|
||||
if ( CFStringGetTypeID() == CFGetTypeID(prefCFPropertyListRef) ) {
|
||||
char buffer[256];
|
||||
if ( CFStringGetCString( (CFStringRef) prefCFPropertyListRef, buffer, sizeof(buffer),
|
||||
kCFStringEncodingUTF8 ) )
|
||||
{
|
||||
HID_info_rec searchHIDInfo;
|
||||
|
||||
int count = sscanf(buffer,
|
||||
"d:{v:%d, p:%d, l:%d, p:%d, u:%d}, e:{p:%d, u:%d, c:%ld}",
|
||||
&searchHIDInfo.device.vendorID,
|
||||
&searchHIDInfo.device.productID,
|
||||
&searchHIDInfo.device.locID,
|
||||
&searchHIDInfo.device.usagePage,
|
||||
&searchHIDInfo.device.usage,
|
||||
&searchHIDInfo.element.usagePage,
|
||||
&searchHIDInfo.element.usage,
|
||||
(long *) &searchHIDInfo.element.cookie);
|
||||
if ( 8 == count ) { // if we found all eight parameters…
|
||||
// and can find a device & element that matches these…
|
||||
if ( HIDFindDeviceAndElement(&searchHIDInfo, outIOHIDDeviceRef, outIOHIDElementRef) ) {
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We found the entry with this key but it's the wrong type; delete it.
|
||||
CFPreferencesSetAppValue(inKeyCFStringRef, NULL, inAppCFStringRef);
|
||||
(void) CFPreferencesAppSynchronize(inAppCFStringRef);
|
||||
}
|
||||
|
||||
CFRelease(prefCFPropertyListRef);
|
||||
}
|
||||
}
|
||||
|
||||
return (found);
|
||||
} // HIDRestoreElementPref
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement )
|
||||
//
|
||||
// Purpose: find the closest matching device and element for this action
|
||||
//
|
||||
// Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage
|
||||
// matches element: cookie, inUsagePage, usage,
|
||||
//
|
||||
// Inputs: inSearchInfo - the device & element info we searching for
|
||||
// outFoundDevice - the address of the best matching device
|
||||
// outFoundElement - the address of the best matching element
|
||||
//
|
||||
// Returns: Boolean - TRUE if we find a match
|
||||
// outFoundDevice - the best matching device
|
||||
// outFoundElement - the best matching element
|
||||
//
|
||||
|
||||
Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef *outFoundDevice, IOHIDElementRef *outFoundElement) {
|
||||
Boolean result = FALSE;
|
||||
|
||||
IOHIDDeviceRef bestIOHIDDeviceRef = NULL;
|
||||
IOHIDElementRef bestIOHIDElementRef = NULL;
|
||||
long bestScore = 0;
|
||||
|
||||
CFIndex devIndex, devCount = CFArrayGetCount(gDeviceCFArrayRef);
|
||||
for ( devIndex = 0; devIndex < devCount; devIndex++ ) {
|
||||
long deviceScore = 1;
|
||||
|
||||
IOHIDDeviceRef tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIndex);
|
||||
if ( !tIOHIDDeviceRef ) {
|
||||
continue;
|
||||
}
|
||||
// match vendorID, productID (+10, +8)
|
||||
if ( inSearchInfo->device.vendorID ) {
|
||||
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||
if ( vendorID ) {
|
||||
if ( inSearchInfo->device.vendorID == vendorID ) {
|
||||
deviceScore += 10;
|
||||
if ( inSearchInfo->device.productID ) {
|
||||
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||
if ( productID ) {
|
||||
if ( inSearchInfo->device.productID == productID ) {
|
||||
deviceScore += 8;
|
||||
} // if ( inSearchInfo->device.productID == productID )
|
||||
|
||||
} // if ( productID )
|
||||
|
||||
} // if ( inSearchInfo->device.productID )
|
||||
|
||||
} // if (inSearchInfo->device.vendorID == vendorID)
|
||||
|
||||
} // if vendorID
|
||||
|
||||
} // if search->device.vendorID
|
||||
// match usagePage & usage (+9)
|
||||
if ( inSearchInfo->device.usagePage && inSearchInfo->device.usage ) {
|
||||
uint32_t usagePage = IOHIDDevice_GetUsagePage(tIOHIDDeviceRef) ;
|
||||
uint32_t usage = IOHIDDevice_GetUsage(tIOHIDDeviceRef);
|
||||
if ( !usagePage || !usage ) {
|
||||
usagePage = IOHIDDevice_GetPrimaryUsagePage(tIOHIDDeviceRef);
|
||||
usage = IOHIDDevice_GetPrimaryUsage(tIOHIDDeviceRef);
|
||||
}
|
||||
if ( usagePage ) {
|
||||
if ( inSearchInfo->device.usagePage == usagePage ) {
|
||||
if ( usage ) {
|
||||
if ( inSearchInfo->device.usage == usage ) {
|
||||
deviceScore += 9;
|
||||
} // if ( inSearchInfo->usage == usage )
|
||||
|
||||
} // if ( usage )
|
||||
|
||||
} // if ( inSearchInfo->usagePage == usagePage )
|
||||
|
||||
} // if ( usagePage )
|
||||
|
||||
} // if ( inSearchInfo->usagePage && inSearchInfo->usage )
|
||||
// match location ID (+5)
|
||||
if ( inSearchInfo->device.locID ) {
|
||||
long locID = IOHIDDevice_GetLocationID(tIOHIDDeviceRef);
|
||||
if ( locID ) {
|
||||
if ( inSearchInfo->device.locID == locID ) {
|
||||
deviceScore += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over all elements of this device
|
||||
gElementCFArrayRef = IOHIDDeviceCopyMatchingElements(tIOHIDDeviceRef, NULL, 0);
|
||||
if ( gElementCFArrayRef ) {
|
||||
CFIndex eleIndex, eleCount = CFArrayGetCount(gElementCFArrayRef);
|
||||
for ( eleIndex = 0; eleIndex < eleCount; eleIndex++ ) {
|
||||
IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(gElementCFArrayRef, eleIndex);
|
||||
if ( !tIOHIDElementRef ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long score = deviceScore;
|
||||
// match usage page, usage & cookie
|
||||
if ( inSearchInfo->element.usagePage && inSearchInfo->element.usage ) {
|
||||
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||
if ( inSearchInfo->element.usagePage == usagePage ) {
|
||||
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||
if ( inSearchInfo->element.usage == usage ) {
|
||||
score += 5;
|
||||
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||
if ( inSearchInfo->element.cookie == cookie ) {
|
||||
score += 4;
|
||||
} // cookies match
|
||||
|
||||
} else {
|
||||
score = 0;
|
||||
} // usages match
|
||||
|
||||
} else {
|
||||
score = 0;
|
||||
} // usage pages match
|
||||
|
||||
} // if ( search usage page & usage )
|
||||
|
||||
#if LOG_SCORING
|
||||
if ( kHIDPage_KeyboardOrKeypad != tElementRef->usagePage ) { // skip keyboards here
|
||||
printf("%s: ( %ld:%ld )-I-Debug, score: %ld\t",
|
||||
__PRETTY_FUNCTION__,
|
||||
inSearchInfo->element.usagePage,
|
||||
inSearchInfo->element.usage,
|
||||
score);
|
||||
HIDPrintElement(tIOHIDElementRef);
|
||||
}
|
||||
|
||||
#endif // LOG_SCORING
|
||||
if ( score > bestScore ) {
|
||||
bestIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||
bestIOHIDElementRef = tIOHIDElementRef;
|
||||
bestScore = score;
|
||||
#if LOG_SCORING
|
||||
printf("%s: ( %ld:%ld )-I-Debug, better score: %ld\t",
|
||||
__PRETTY_FUNCTION__,
|
||||
inSearchInfo->element.usagePage,
|
||||
inSearchInfo->element.usage,
|
||||
score);
|
||||
HIDPrintElement(bestIOHIDElementRef);
|
||||
#endif // LOG_SCORING
|
||||
}
|
||||
} // for elements...
|
||||
|
||||
CFRelease(gElementCFArrayRef);
|
||||
gElementCFArrayRef = NULL;
|
||||
} // if ( gElementCFArrayRef )
|
||||
|
||||
} // for ( devIndex = 0; devIndex < devCount; devIndex++ )
|
||||
if ( bestIOHIDDeviceRef || bestIOHIDElementRef ) {
|
||||
*outFoundDevice = bestIOHIDDeviceRef;
|
||||
*outFoundElement = bestIOHIDElementRef;
|
||||
#if LOG_SCORING
|
||||
printf("%s: ( %ld:%ld )-I-Debug, best score: %ld\t",
|
||||
__PRETTY_FUNCTION__,
|
||||
inSearchInfo->element.usagePage,
|
||||
inSearchInfo->element.usage,
|
||||
bestScore);
|
||||
HIDPrintElement(bestIOHIDElementRef);
|
||||
#endif // LOG_SCORING
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // HIDFindDeviceAndElement
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
// takes input records, save required info
|
||||
// assume file is open and at correct position.
|
||||
// will always write to file (if file exists) size of HID_info_rec, even if device and or element is bad
|
||||
|
||||
void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef, int actionCookie) {
|
||||
// must save:
|
||||
// actionCookie
|
||||
// Device: serial,vendorID, productID, location, usagePage, usage
|
||||
// Element: cookie, usagePage, usage,
|
||||
HID_info_rec hidInfoRec;
|
||||
HIDSetElementConfig(&hidInfoRec, inIOHIDDeviceRef, inIOHIDElementRef, actionCookie);
|
||||
// write to file
|
||||
if ( fileRef ) {
|
||||
fwrite( (void *)&hidInfoRec, sizeof(HID_info_rec), 1, fileRef );
|
||||
}
|
||||
} // HIDSaveElementConfig
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
// 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
|
||||
|
||||
int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef) {
|
||||
// Device: serial,vendorID, productID, location, usagePage, usage
|
||||
// Element: cookie, usagePage, usage,
|
||||
|
||||
HID_info_rec hidInfoRec;
|
||||
fread( (void *) &hidInfoRec, 1, sizeof(HID_info_rec), fileRef );
|
||||
return ( HIDGetElementConfig(&hidInfoRec, outIOHIDDeviceRef, outIOHIDElementRef) );
|
||||
} // HIDRestoreElementConfig
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
// Set up a config record for saving
|
||||
// takes an input records, returns record user can save as they want
|
||||
// Note: the save rec must be pre-allocated by the calling app and will be filled out
|
||||
void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr,
|
||||
IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
IOHIDElementRef inIOHIDElementRef,
|
||||
int actionCookie) {
|
||||
// must save:
|
||||
// actionCookie
|
||||
// Device: serial,vendorID, productID, location, usagePage, usage
|
||||
// Element: cookie, usagePage, usage,
|
||||
inHIDInfoPtr->actionCookie = actionCookie;
|
||||
// device
|
||||
// need to add serial number when I have a test case
|
||||
if ( inIOHIDDeviceRef && inIOHIDElementRef ) {
|
||||
inHIDInfoPtr->device.vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef);
|
||||
inHIDInfoPtr->device.productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef);
|
||||
inHIDInfoPtr->device.locID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef);
|
||||
inHIDInfoPtr->device.usage = IOHIDDevice_GetUsage(inIOHIDDeviceRef);
|
||||
inHIDInfoPtr->device.usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef);
|
||||
|
||||
inHIDInfoPtr->element.usagePage = IOHIDElementGetUsagePage(inIOHIDElementRef);
|
||||
inHIDInfoPtr->element.usage = IOHIDElementGetUsage(inIOHIDElementRef);
|
||||
inHIDInfoPtr->element.minReport = IOHIDElement_GetCalibrationSaturationMin(inIOHIDElementRef);
|
||||
inHIDInfoPtr->element.maxReport = IOHIDElement_GetCalibrationSaturationMax(inIOHIDElementRef);
|
||||
inHIDInfoPtr->element.cookie = IOHIDElementGetCookie(inIOHIDElementRef);
|
||||
} else {
|
||||
inHIDInfoPtr->device.vendorID = 0;
|
||||
inHIDInfoPtr->device.productID = 0;
|
||||
inHIDInfoPtr->device.locID = 0;
|
||||
inHIDInfoPtr->device.usage = 0;
|
||||
inHIDInfoPtr->device.usagePage = 0;
|
||||
|
||||
inHIDInfoPtr->element.usagePage = 0;
|
||||
inHIDInfoPtr->element.usage = 0;
|
||||
inHIDInfoPtr->element.minReport = 0;
|
||||
inHIDInfoPtr->element.maxReport = 0;
|
||||
inHIDInfoPtr->element.cookie = 0;
|
||||
}
|
||||
} // HIDSetElementConfig
|
||||
|
||||
// ---------------------------------
|
||||
#if 0 // debug utility function to dump config record
|
||||
void HIDDumpConfig(HID_info_ptr inHIDInfoPtr) {
|
||||
printf(
|
||||
"Config Record for action: %d\n\t vendor: %d product: %d location: %d\n\t usage: %d usagePage: %d\n\t element.usagePage: %d element.usage: %d\n\t minReport: %d maxReport: %d\n\t cookie: %d\n",
|
||||
inHIDInfoPtr->actionCookie,
|
||||
inHIDInfoPtr->device.vendorID,
|
||||
inHIDInfoPtr->device.productID,
|
||||
inHIDInfoPtr->locID,
|
||||
inHIDInfoPtr->usage,
|
||||
inHIDInfoPtr->usagePage,
|
||||
inHIDInfoPtr->element.usagePage,
|
||||
inHIDInfoPtr->element.usage,
|
||||
inHIDInfoPtr->minReport,
|
||||
inHIDInfoPtr->maxReport,
|
||||
inHIDInfoPtr->cookie);
|
||||
} // HIDDumpConfig
|
||||
#endif // 0
|
||||
// ---------------------------------
|
||||
|
||||
// Get matching element from config record
|
||||
// takes a pre-allocated and filled out config record
|
||||
// search for matching device
|
||||
// return pDevice, pElement and cookie for action
|
||||
int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef) {
|
||||
if ( !inHIDInfoPtr->device.locID && !inHIDInfoPtr->device.vendorID && !inHIDInfoPtr->device.productID && !inHIDInfoPtr->device.usage
|
||||
&& !inHIDInfoPtr->device.usagePage ) //
|
||||
{ //
|
||||
// early out
|
||||
*outIOHIDDeviceRef = NULL;
|
||||
*outIOHIDElementRef = NULL;
|
||||
return (inHIDInfoPtr->actionCookie);
|
||||
}
|
||||
|
||||
IOHIDDeviceRef tIOHIDDeviceRef, foundIOHIDDeviceRef = NULL;
|
||||
IOHIDElementRef tIOHIDElementRef, foundIOHIDElementRef = NULL;
|
||||
|
||||
CFIndex devIdx, devCnt, idx, cnt;
|
||||
// compare to current device list for matches
|
||||
// look for device
|
||||
if ( inHIDInfoPtr->device.locID && inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID ) { // look for specific device
|
||||
// type plug in to same port
|
||||
devCnt = CFArrayGetCount(gDeviceCFArrayRef);
|
||||
for ( devIdx = 0; devIdx < devCnt; devIdx++ ) {
|
||||
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIdx);
|
||||
if ( !tIOHIDDeviceRef ) {
|
||||
continue; // skip this device
|
||||
}
|
||||
|
||||
long locID = IOHIDDevice_GetLocationID(tIOHIDDeviceRef);
|
||||
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||
if ( (inHIDInfoPtr->device.locID == locID)
|
||||
&& (inHIDInfoPtr->device.vendorID == vendorID)
|
||||
&& (inHIDInfoPtr->device.productID == productID) )
|
||||
{
|
||||
foundIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||
}
|
||||
if ( foundIOHIDDeviceRef ) {
|
||||
break;
|
||||
}
|
||||
} // next devIdx
|
||||
if ( foundIOHIDDeviceRef ) {
|
||||
CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(foundIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||
if ( elementCFArrayRef ) {
|
||||
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||
for ( idx = 0; idx < cnt; idx++ ) {
|
||||
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||
if ( !tIOHIDElementRef ) {
|
||||
continue; // skip this element
|
||||
}
|
||||
|
||||
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||
if ( inHIDInfoPtr->element.cookie == cookie ) {
|
||||
foundIOHIDElementRef = tIOHIDElementRef;
|
||||
}
|
||||
if ( foundIOHIDElementRef ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !foundIOHIDElementRef ) {
|
||||
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||
for ( idx = 0; idx < cnt; idx++ ) {
|
||||
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||
if ( !tIOHIDElementRef ) {
|
||||
continue; // skip this element
|
||||
}
|
||||
|
||||
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||
if ( (inHIDInfoPtr->element.usage == usage) && (inHIDInfoPtr->element.usagePage == usagePage) ) {
|
||||
foundIOHIDElementRef = tIOHIDElementRef;
|
||||
}
|
||||
if ( foundIOHIDElementRef ) {
|
||||
break;
|
||||
}
|
||||
} // next idx
|
||||
|
||||
} // if ( !foundIOHIDElementRef )
|
||||
if ( foundIOHIDElementRef ) { // if same device
|
||||
// setup the calibration
|
||||
IOHIDElement_SetupCalibration(tIOHIDElementRef);
|
||||
|
||||
IOHIDElement_SetCalibrationSaturationMin(tIOHIDElementRef, inHIDInfoPtr->element.minReport);
|
||||
IOHIDElement_SetCalibrationSaturationMax(tIOHIDElementRef, inHIDInfoPtr->element.maxReport);
|
||||
}
|
||||
|
||||
CFRelease(elementCFArrayRef);
|
||||
} // if ( elementCFArrayRef )
|
||||
|
||||
} // if ( foundIOHIDDeviceRef )
|
||||
// if we have not found a match, look at just vendor and product
|
||||
if ( (!foundIOHIDDeviceRef) && (inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID) ) {
|
||||
devCnt = CFArrayGetCount(gDeviceCFArrayRef);
|
||||
for ( devIdx = 0; devIdx < devCnt; devIdx++ ) {
|
||||
tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIdx);
|
||||
if ( !tIOHIDDeviceRef ) {
|
||||
continue; // skip this device
|
||||
}
|
||||
|
||||
long vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef);
|
||||
long productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef);
|
||||
if ( (inHIDInfoPtr->device.vendorID == vendorID)
|
||||
&& (inHIDInfoPtr->device.productID == productID) )
|
||||
{
|
||||
foundIOHIDDeviceRef = tIOHIDDeviceRef;
|
||||
}
|
||||
if ( foundIOHIDDeviceRef ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// match elements by cookie since same device type
|
||||
if ( foundIOHIDDeviceRef ) {
|
||||
CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(foundIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone);
|
||||
if ( elementCFArrayRef ) {
|
||||
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||
for ( idx = 0; idx < cnt; idx++ ) {
|
||||
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||
if ( !tIOHIDElementRef ) {
|
||||
continue; // skip this element
|
||||
}
|
||||
|
||||
IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef);
|
||||
if ( inHIDInfoPtr->element.cookie == cookie ) {
|
||||
foundIOHIDElementRef = tIOHIDElementRef;
|
||||
}
|
||||
if ( foundIOHIDElementRef ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if no cookie match (should NOT occur) match on usage
|
||||
if ( !foundIOHIDElementRef ) {
|
||||
cnt = CFArrayGetCount(elementCFArrayRef);
|
||||
for ( idx = 0; idx < cnt; idx++ ) {
|
||||
tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx);
|
||||
if ( !tIOHIDElementRef ) {
|
||||
continue; // skip this element
|
||||
}
|
||||
|
||||
uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
|
||||
uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef);
|
||||
if ( (inHIDInfoPtr->element.usage == usage)
|
||||
&& (inHIDInfoPtr->element.usagePage == usagePage) )
|
||||
{
|
||||
foundIOHIDElementRef = tIOHIDElementRef;
|
||||
}
|
||||
if ( foundIOHIDElementRef ) {
|
||||
break;
|
||||
}
|
||||
} // next idx
|
||||
|
||||
} // if ( !foundIOHIDElementRef )
|
||||
if ( foundIOHIDElementRef ) { // if same device
|
||||
// setup the calibration
|
||||
IOHIDElement_SetupCalibration(tIOHIDElementRef);
|
||||
IOHIDElement_SetCalibrationSaturationMin(tIOHIDElementRef, inHIDInfoPtr->element.minReport);
|
||||
IOHIDElement_SetCalibrationSaturationMax(tIOHIDElementRef, inHIDInfoPtr->element.maxReport);
|
||||
}
|
||||
|
||||
CFRelease(elementCFArrayRef);
|
||||
} // if ( elementCFArrayRef )
|
||||
|
||||
} // if ( foundIOHIDDeviceRef )
|
||||
|
||||
} // if ( device not found & vendorID & productID )
|
||||
|
||||
} // if ( inHIDInfoPtr->locID && inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID )
|
||||
// can't find matching device return NULL, do not return first device
|
||||
if ( (!foundIOHIDDeviceRef) || (!foundIOHIDElementRef) ) {
|
||||
// no HID device
|
||||
*outIOHIDDeviceRef = NULL;
|
||||
*outIOHIDElementRef = NULL;
|
||||
return (inHIDInfoPtr->actionCookie);
|
||||
} else {
|
||||
// HID device
|
||||
*outIOHIDDeviceRef = foundIOHIDDeviceRef;
|
||||
*outIOHIDElementRef = foundIOHIDElementRef;
|
||||
return (inHIDInfoPtr->actionCookie);
|
||||
}
|
||||
} // HIDGetElementConfig
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
108
src/cocoa/HID_Error_Handler.c
Normal file
108
src/cocoa/HID_Error_Handler.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
// File: HID_Error_Handler.c
|
||||
// Abstract: Implementation of the HID utilities error handlers
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#ifdef DEBUG // not used in release
|
||||
#if !defined (kBuildingLibrary)
|
||||
#define kVerboseErrors
|
||||
|
||||
// system includes ----------------------------------------------------------
|
||||
|
||||
#ifdef kVerboseErrors
|
||||
//#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
#endif // not kBuildingLibrary
|
||||
#endif // DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// project includes ---------------------------------------------------------
|
||||
|
||||
#include "HID_Utilities_External.h"
|
||||
|
||||
// globals (internal/private) -----------------------------------------------
|
||||
|
||||
// prototypes (internal/private) --------------------------------------------
|
||||
|
||||
// functions (internal/private) ---------------------------------------------
|
||||
|
||||
#pragma mark -
|
||||
// -------------------------------------
|
||||
|
||||
// central error reporting
|
||||
|
||||
void HIDReportErrorNum(const char *strError, int numError) {
|
||||
char errMsgCStr[256];
|
||||
|
||||
sprintf(errMsgCStr, "%s #%d (0x%x)", strError, numError, numError);
|
||||
|
||||
// out as debug string
|
||||
#ifdef kVerboseErrors
|
||||
{
|
||||
fputs(errMsgCStr, stderr);
|
||||
}
|
||||
#endif // kVerboseErrors
|
||||
} // HIDReportErrorNum
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
void HIDReportError(const char *strError) {
|
||||
char errMsgCStr[256];
|
||||
|
||||
sprintf(errMsgCStr, "%s", strError);
|
||||
|
||||
// out as debug string
|
||||
#ifdef kVerboseErrors
|
||||
{
|
||||
fputs(errMsgCStr, stderr);
|
||||
}
|
||||
#endif // kVerboseErrors
|
||||
} // HIDReportError
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
1210
src/cocoa/HID_Name_Lookup.c
Normal file
1210
src/cocoa/HID_Name_Lookup.c
Normal file
File diff suppressed because it is too large
Load diff
361
src/cocoa/HID_Queue_Utilities.c
Normal file
361
src/cocoa/HID_Queue_Utilities.c
Normal file
|
@ -0,0 +1,361 @@
|
|||
// File: HID_Queue_Utilities.c
|
||||
// Abstract: HID Queue Utilities.
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#include "HID_Utilities_External.h"
|
||||
|
||||
// ==================================
|
||||
// private functions
|
||||
|
||||
// creates a queue for a device, creates and opens device interface if required
|
||||
static IOReturn HIDCreateQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
|
||||
// do we already have a queue?
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( tIOHIDQueueRef ) { // (yes)
|
||||
assert( IOHIDQueueGetTypeID() == CFGetTypeID(tIOHIDQueueRef) );
|
||||
} else {
|
||||
tIOHIDQueueRef = IOHIDQueueCreate(kCFAllocatorDefault, inIOHIDDeviceRef, kDeviceQueueSize, kIOHIDOptionsTypeNone);
|
||||
if ( tIOHIDQueueRef ) { // did that work
|
||||
IOHIDDevice_SetQueue(inIOHIDDeviceRef, tIOHIDQueueRef);
|
||||
result = kIOReturnSuccess;
|
||||
} else {
|
||||
HIDReportErrorNum("Failed to create queue via create", result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HIDReportErrorNum("HID device ref does not exist for queue creation", result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* HIDCreateQueue */
|
||||
|
||||
// ---------------------------------
|
||||
// returns true if queue is empty false otherwise
|
||||
// error if no device, empty if no queue
|
||||
static unsigned char HIDIsDeviceQueueEmpty(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
if ( inIOHIDDeviceRef ) { // need device and queue
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( tIOHIDQueueRef ) {
|
||||
IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement(inIOHIDDeviceRef, kHIDElementTypeIO);
|
||||
|
||||
while ( tIOHIDElementRef ) {
|
||||
if ( IOHIDQueueContainsElement(tIOHIDQueueRef, tIOHIDElementRef) ) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
tIOHIDElementRef = HIDGetNextDeviceElement(tIOHIDElementRef, kHIDElementTypeIO);
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL device passed to HIDIsDeviceQueueEmpty.");
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL device passed to HIDIsDeviceQueueEmpty.");
|
||||
}
|
||||
|
||||
return (true);
|
||||
} /* HIDIsDeviceQueueEmpty */
|
||||
|
||||
// ---------------------------------
|
||||
|
||||
// disposes and releases queue, sets queue to NULL,.
|
||||
// Note: will have no effect if device or queue do not exist
|
||||
static IOReturn HIDDisposeReleaseQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( tIOHIDQueueRef ) {
|
||||
// stop queue
|
||||
IOHIDQueueStop(tIOHIDQueueRef);
|
||||
|
||||
// release the queue
|
||||
CFRelease(tIOHIDQueueRef);
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL device passed to HIDDisposeReleaseQueue.");
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* HIDDisposeReleaseQueue */
|
||||
|
||||
// ==================================
|
||||
// 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
|
||||
int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
if ( inIOHIDElementRef ) {
|
||||
assert( IOHIDElementGetTypeID() == CFGetTypeID(inIOHIDElementRef) );
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( !tIOHIDQueueRef ) { // if no queue create queue
|
||||
result = HIDCreateQueue(inIOHIDDeviceRef);
|
||||
if ( kIOReturnSuccess == result ) {
|
||||
tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
}
|
||||
}
|
||||
if ( tIOHIDQueueRef ) {
|
||||
// stop queue
|
||||
IOHIDQueueStop(tIOHIDQueueRef);
|
||||
// queue element
|
||||
if ( !IOHIDQueueContainsElement(tIOHIDQueueRef, inIOHIDElementRef) ) {
|
||||
IOHIDQueueAddElement(tIOHIDQueueRef, inIOHIDElementRef);
|
||||
}
|
||||
|
||||
// restart queue
|
||||
IOHIDQueueStart(tIOHIDQueueRef);
|
||||
} else {
|
||||
HIDReportError("No queue for device passed to HIDQueueElement.");
|
||||
if ( kIOReturnSuccess == result ) {
|
||||
result = kIOReturnError;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL element passed to HIDQueueElement.");
|
||||
result = kIOReturnBadArgument;
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL device passed to HIDQueueElement.");
|
||||
result = kIOReturnBadArgument;
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* HIDQueueElement */
|
||||
// ---------------------------------
|
||||
|
||||
// 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
|
||||
int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
// error checking
|
||||
if ( !inIOHIDDeviceRef ) {
|
||||
HIDReportError("Device does not exist, cannot queue device.");
|
||||
return (kIOReturnBadArgument);
|
||||
}
|
||||
if ( !inIOHIDDeviceRef ) { // must have interface
|
||||
HIDReportError("Device does not have hid device ref, cannot queue device.");
|
||||
return (kIOReturnError);
|
||||
}
|
||||
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( !tIOHIDQueueRef ) { // if no queue create queue
|
||||
result = HIDCreateQueue(inIOHIDDeviceRef);
|
||||
if ( kIOReturnSuccess == result ) {
|
||||
tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
}
|
||||
}
|
||||
if ( (kIOReturnSuccess != result) || (!tIOHIDQueueRef) ) {
|
||||
HIDReportErrorNum("Could not queue device due to problem creating queue.", result);
|
||||
if ( kIOReturnSuccess != result ) {
|
||||
return (result);
|
||||
} else {
|
||||
return (kIOReturnError);
|
||||
}
|
||||
}
|
||||
|
||||
// stop queue
|
||||
IOHIDQueueStop(tIOHIDQueueRef);
|
||||
|
||||
// queue element
|
||||
IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement(inIOHIDDeviceRef, kHIDElementTypeIO);
|
||||
|
||||
while ( tIOHIDElementRef ) {
|
||||
if ( !IOHIDQueueContainsElement(tIOHIDQueueRef, tIOHIDElementRef) ) {
|
||||
IOHIDQueueAddElement(tIOHIDQueueRef, tIOHIDElementRef);
|
||||
}
|
||||
|
||||
tIOHIDElementRef = HIDGetNextDeviceElement(tIOHIDElementRef, kHIDElementTypeIO);
|
||||
}
|
||||
|
||||
// restart queue
|
||||
IOHIDQueueStart(tIOHIDQueueRef);
|
||||
|
||||
return (result);
|
||||
} /* HIDQueueDevice */
|
||||
|
||||
// ---------------------------------
|
||||
// removes element for queue, if last element in queue will release queue and closes device interface
|
||||
int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
if ( inIOHIDElementRef ) {
|
||||
assert( IOHIDElementGetTypeID() == CFGetTypeID(inIOHIDElementRef) );
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( tIOHIDQueueRef ) {
|
||||
// stop queue
|
||||
IOHIDQueueStop(tIOHIDQueueRef);
|
||||
// de-queue element
|
||||
if ( IOHIDQueueContainsElement(tIOHIDQueueRef, inIOHIDElementRef) ) {
|
||||
IOHIDQueueRemoveElement(tIOHIDQueueRef, inIOHIDElementRef);
|
||||
}
|
||||
// release device queue and close interface if queue empty
|
||||
if ( HIDIsDeviceQueueEmpty(inIOHIDDeviceRef) ) {
|
||||
result = HIDDisposeReleaseQueue(inIOHIDDeviceRef);
|
||||
if ( kIOReturnSuccess != result ) {
|
||||
HIDReportErrorNum("Failed to dispose and release queue.", result);
|
||||
}
|
||||
} else { // not empty so restart queue
|
||||
IOHIDQueueStart(tIOHIDQueueRef);
|
||||
}
|
||||
} else {
|
||||
HIDReportError("No queue for device passed to HIDDequeueElement.");
|
||||
if ( kIOReturnSuccess == result ) {
|
||||
result = kIOReturnError;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL element passed to HIDDequeueElement.");
|
||||
result = kIOReturnBadArgument;
|
||||
}
|
||||
} else {
|
||||
HIDReportError("NULL device passed to HIDDequeueElement.");
|
||||
result = kIOReturnBadArgument;
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* HIDDequeueElement */
|
||||
|
||||
// ---------------------------------
|
||||
// completely removes all elements from queue and releases queue and closes device interface
|
||||
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
|
||||
int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
// error checking
|
||||
if ( !inIOHIDDeviceRef ) {
|
||||
HIDReportError("Device does not exist, cannot queue device.");
|
||||
return (kIOReturnBadArgument);
|
||||
}
|
||||
if ( !inIOHIDDeviceRef ) { // must have interface
|
||||
HIDReportError("Device does not have hid device ref, cannot queue device.");
|
||||
return (kIOReturnError);
|
||||
}
|
||||
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( tIOHIDQueueRef ) {
|
||||
// iterate through elements and if queued, remove
|
||||
IOHIDElementRef tIOHIDElementRef = HIDGetFirstDeviceElement(inIOHIDDeviceRef, kHIDElementTypeIO);
|
||||
|
||||
while ( tIOHIDElementRef ) {
|
||||
// de-queue element
|
||||
if ( IOHIDQueueContainsElement(tIOHIDQueueRef, tIOHIDElementRef) ) {
|
||||
IOHIDQueueRemoveElement(tIOHIDQueueRef, tIOHIDElementRef);
|
||||
}
|
||||
|
||||
tIOHIDElementRef = HIDGetNextDeviceElement(tIOHIDElementRef, kHIDElementTypeIO);
|
||||
}
|
||||
|
||||
// ensure queue is disposed and released
|
||||
result = HIDDisposeReleaseQueue(inIOHIDDeviceRef);
|
||||
if ( kIOReturnSuccess != result ) {
|
||||
HIDReportErrorNum("Failed to dispose and release queue.", result);
|
||||
}
|
||||
} else {
|
||||
HIDReportError("No queue for device passed to HIDDequeueElement.");
|
||||
if ( kIOReturnSuccess == result ) {
|
||||
result = kIOReturnError;
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* HIDDequeueDevice */
|
||||
// ---------------------------------
|
||||
|
||||
// releases all device queues for quit or rebuild (must be called)
|
||||
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
|
||||
IOReturn HIDReleaseAllDeviceQueues(void) {
|
||||
IOReturn result = kIOReturnSuccess;
|
||||
IOHIDDeviceRef tIOHIDDeviceRef = HIDGetFirstDevice();
|
||||
|
||||
while ( tIOHIDDeviceRef ) {
|
||||
result = HIDDequeueDevice(tIOHIDDeviceRef);
|
||||
if ( kIOReturnSuccess != result ) {
|
||||
HIDReportErrorNum("Could not dequeue device.", result);
|
||||
}
|
||||
|
||||
tIOHIDDeviceRef = HIDGetNextDevice(tIOHIDDeviceRef);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* HIDReleaseAllDeviceQueues */
|
||||
|
||||
// ---------------------------------
|
||||
// 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(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef) {
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
IOHIDQueueRef tIOHIDQueueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef);
|
||||
if ( tIOHIDQueueRef ) {
|
||||
if ( pIOHIDValueRef ) {
|
||||
*pIOHIDValueRef = IOHIDQueueCopyNextValueWithTimeout(tIOHIDQueueRef, 0.0);
|
||||
if ( *pIOHIDValueRef ) {
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HIDReportError("Could not get HID event, hid queue reference does not exist.");
|
||||
}
|
||||
} else {
|
||||
HIDReportError("Could not get HID event, device does not exist.");
|
||||
}
|
||||
|
||||
return (false); // did not get event
|
||||
} /* HIDGetEvent */
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
1068
src/cocoa/HID_Utilities.c
Normal file
1068
src/cocoa/HID_Utilities.c
Normal file
File diff suppressed because it is too large
Load diff
417
src/cocoa/HID_Utilities_External.h
Normal file
417
src/cocoa/HID_Utilities_External.h
Normal file
|
@ -0,0 +1,417 @@
|
|||
// File: HID_Utilities_External.h
|
||||
// Abstract: External interface for HID Utilities, can be used with either library or source.
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
#ifndef _HID_Utilities_External_h_
|
||||
#define _HID_Utilities_External_h_
|
||||
|
||||
// ==================================
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ==================================
|
||||
|
||||
//includes
|
||||
|
||||
#include <stdio.h>
|
||||
#include "IOHIDLib_.h"
|
||||
|
||||
// ==================================
|
||||
|
||||
#ifndef _IOKIT_HID_IOHIDKEYS_H_
|
||||
/*!
|
||||
@typedef IOHIDElementCookie
|
||||
@abstract Abstract data type used as a unique identifier for an element.
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
typedef uint32_t IOHIDElementCookie;
|
||||
#else
|
||||
typedef void *IOHIDElementCookie;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Device and Element Interfaces
|
||||
|
||||
enum HIDElementTypeMask {
|
||||
kHIDElementTypeInput = 1 << 1,
|
||||
kHIDElementTypeOutput = 1 << 2,
|
||||
kHIDElementTypeFeature = 1 << 3,
|
||||
kHIDElementTypeCollection = 1 << 4,
|
||||
kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature,
|
||||
kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection
|
||||
};
|
||||
typedef enum HIDElementTypeMask HIDElementTypeMask;
|
||||
|
||||
// ==================================
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
extern IOHIDManagerRef gIOHIDManagerRef;
|
||||
extern CFMutableArrayRef gDeviceCFArrayRef;
|
||||
extern CFArrayRef gElementCFArrayRef;
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes )
|
||||
//
|
||||
// Purpose: builds list of devices with elements (allocates memory and captures devices) in which
|
||||
// the devices could be of different types/usages list is allocated internally within HID
|
||||
// Utilites and can be accessed via accessor functions structures within list are considered
|
||||
// flat and user accessable, but not 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)
|
||||
// usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages
|
||||
// returns true if succesful
|
||||
//
|
||||
// Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages
|
||||
// inUsages - inNumDeviceTypes sized array of matching usages
|
||||
// inNumDeviceTypes - number of usage pages & usages
|
||||
//
|
||||
// Returns: Boolean - if successful
|
||||
//
|
||||
extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes);
|
||||
|
||||
// same as above but this uses a single usagePage and usage
|
||||
extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage);
|
||||
|
||||
// updates the current device list for any new/removed devices
|
||||
// if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList
|
||||
// usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages
|
||||
// returns true if successful which means if any device were added or removed (the device config changed)
|
||||
extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes);
|
||||
|
||||
// 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);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDRebuildDevices( )
|
||||
//
|
||||
// Purpose: rebuilds the (internal) list of devices
|
||||
//
|
||||
// Inputs: none
|
||||
//
|
||||
// Returns: none
|
||||
//
|
||||
|
||||
extern void HIDRebuildDevices(void);
|
||||
|
||||
// does a device list exist
|
||||
extern unsigned char 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(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask);
|
||||
|
||||
// get the first device in the device list
|
||||
// returns NULL if no list exists
|
||||
extern IOHIDDeviceRef HIDGetFirstDevice(void);
|
||||
|
||||
// get next device in list given current device as parameter
|
||||
// returns NULL if end of list
|
||||
extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
// 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 IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, 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 IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask);
|
||||
|
||||
// get previous element of given device in list given current element as parameter
|
||||
// this walks 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 IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask);
|
||||
|
||||
// returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h )
|
||||
// returns empty string for invalid types
|
||||
extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDCopyUsageName( inUsagePage, inUsage )
|
||||
//
|
||||
// Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h )
|
||||
//
|
||||
// Notes: returns usage page and usage values in CFString form for unknown values
|
||||
//
|
||||
// Inputs: inUsagePage - the usage page
|
||||
// inUsage - the usage
|
||||
//
|
||||
// Returns: CFStringRef - the resultant string
|
||||
//
|
||||
|
||||
extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage);
|
||||
|
||||
// ==================================
|
||||
|
||||
// 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 int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef);
|
||||
|
||||
// adds all elements to queue, performing any device queue set up required
|
||||
extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
// removes element for queue, if last element in queue will release queue and device
|
||||
extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef);
|
||||
|
||||
// completely removes all elements from queue and releases queue and device
|
||||
extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
// releases all device queues for quit or rebuild (must be called)
|
||||
extern int HIDReleaseAllDeviceQueues(void);
|
||||
|
||||
// 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(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef);
|
||||
|
||||
// ==================================
|
||||
|
||||
// Conguration and Save Interfaces
|
||||
|
||||
enum {
|
||||
kPercentMove = 10 // precent of overall range a element must move to register
|
||||
};
|
||||
|
||||
typedef struct HID_info_struct {
|
||||
int actionCookie;
|
||||
// device
|
||||
// need to add serial number when I have a test case
|
||||
struct {
|
||||
int vendorID, productID;
|
||||
int locID;
|
||||
uint32_t usagePage, usage;
|
||||
} device;
|
||||
// elements
|
||||
struct {
|
||||
uint32_t usagePage, usage;
|
||||
int minReport, maxReport;
|
||||
IOHIDElementCookie cookie; // always 32 bits
|
||||
} element;
|
||||
}HID_info_rec, *HID_info_ptr;
|
||||
|
||||
// get vendor name from vendor ID
|
||||
extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName);
|
||||
|
||||
// get product name from vendor/product ID
|
||||
extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName);
|
||||
|
||||
// get element name from vendor id/product id look up ( using element cookie )
|
||||
extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID,
|
||||
int inProductID,
|
||||
IOHIDElementCookie inCookie,
|
||||
char * outCStrName);
|
||||
|
||||
// get element name from vendor id/product id look up ( using element usage page & usage )
|
||||
extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID,
|
||||
long inProductID,
|
||||
long inUsagePage,
|
||||
long inUsage,
|
||||
char *inCStrName);
|
||||
|
||||
// utility routines to dump device or element info
|
||||
extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef);
|
||||
extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef);
|
||||
|
||||
// polls single device's elements for a change greater than kPercentMove. Times out after given time
|
||||
// returns 1 and pointer to element if found
|
||||
// returns 0 and NULL for both parameters if not found
|
||||
extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
IOHIDElementRef *outIOHIDElementRef,
|
||||
float timeout);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDConfigureAction( outDeviceRef, outElementRef, inTimeout )
|
||||
//
|
||||
// Purpose: 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
|
||||
//
|
||||
// Inputs: outDeviceRef - address where to store the device
|
||||
// outElementRef - address where to store the element
|
||||
// inTimeout - the timeout
|
||||
// Returns: Boolean - TRUE if successful
|
||||
// outDeviceRef - the device
|
||||
// outElementRef - the element
|
||||
//
|
||||
|
||||
extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef )
|
||||
//
|
||||
// Purpose: Save the device & element values into the specified key in the specified applications preferences
|
||||
//
|
||||
// Inputs: inKeyCFStringRef - the preference key
|
||||
// inAppCFStringRef - the application identifier
|
||||
// inDeviceRef - the device
|
||||
// inElementRef - the element
|
||||
// Returns: Boolean - if successful
|
||||
//
|
||||
|
||||
extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef,
|
||||
CFStringRef inAppCFStringRef,
|
||||
IOHIDDeviceRef inDeviceRef,
|
||||
IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef )
|
||||
//
|
||||
// Purpose: Find the specified preference in the specified application
|
||||
//
|
||||
// Inputs: inKeyCFStringRef - the preference key
|
||||
// inAppCFStringRef - the application identifier
|
||||
// outDeviceRef - address where to restore the device
|
||||
// outElementRef - address where to restore the element
|
||||
// Returns: Boolean - if successful
|
||||
// outDeviceRef - the device
|
||||
// outElementRef - the element
|
||||
//
|
||||
|
||||
extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef,
|
||||
CFStringRef inAppCFStringRef,
|
||||
IOHIDDeviceRef * outDeviceRef,
|
||||
IOHIDElementRef *outElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement )
|
||||
//
|
||||
// Purpose: find the closest matching device and element for this action
|
||||
//
|
||||
// Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage
|
||||
// matches element: cookie, inUsagePage, usage,
|
||||
//
|
||||
// Inputs: inSearchInfo - the device & element info we searching for
|
||||
// outFoundDevice - the address of the best matching device
|
||||
// outFoundElement - the address of the best matching element
|
||||
//
|
||||
// Returns: Boolean - TRUE if we find a match
|
||||
// outFoundDevice - the best matching device
|
||||
// outFoundElement - the best matching element
|
||||
//
|
||||
|
||||
extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo,
|
||||
IOHIDDeviceRef * outFoundDevice,
|
||||
IOHIDElementRef * outFoundElement);
|
||||
|
||||
// -- These are routines to use if the applcationwants HID Utilities to do the file handling --
|
||||
// Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type.
|
||||
|
||||
// take input records, save required info
|
||||
// assume file is open and at correct position.
|
||||
void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie);
|
||||
|
||||
// takes a file, reads one record (assume file position is correct and file is open)
|
||||
// search for matching device
|
||||
// return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action
|
||||
int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef);
|
||||
|
||||
// -- These are routines to use if the client wants to use their own file handling --
|
||||
|
||||
// Set up a config record for saving
|
||||
// takes an input records, returns record user can save as they want
|
||||
// Note: the save rec must be pre-allocated by the calling app and will be filled out
|
||||
void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr,
|
||||
IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
IOHIDElementRef inIOHidElementRef,
|
||||
int actionCookie);
|
||||
|
||||
// Get matching element from config record
|
||||
// takes a pre-allocated and filled out config record
|
||||
// search for matching device
|
||||
// return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action
|
||||
int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef);
|
||||
|
||||
// ==================================
|
||||
|
||||
// Error reporter, can be set to report however the application desires
|
||||
extern void HIDReportError(const char *strError);
|
||||
|
||||
// Error with numeric code reporter, can be set to report however the application desires
|
||||
extern void HIDReportErrorNum(const char *strError, int numError);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _HID_Utilities_External_h_
|
619
src/cocoa/IOHIDDevice_.c
Normal file
619
src/cocoa/IOHIDDevice_.c
Normal file
|
@ -0,0 +1,619 @@
|
|||
// File: IOHIDDevice_.c
|
||||
// Abstract: convieance functions for IOHIDDeviceGetProperty
|
||||
// Version: 2.0 + 5.3
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#pragma mark - includes & imports
|
||||
//-----------------------------------------------------
|
||||
|
||||
#include "IOHIDDevice_.h"
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||
//-----------------------------------------------------
|
||||
|
||||
#define kIOHIDDevice_TransactionKey "DeviceTransactionRef"
|
||||
#define kIOHIDDevice_QueueKey "DeviceQueueRef"
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - local (static) function prototypes
|
||||
//-----------------------------------------------------
|
||||
|
||||
static Boolean IOHIDDevice_GetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
CFStringRef inKey,
|
||||
uint32_t * outValue);
|
||||
// static void IOHIDDevice_SetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, uint32_t inValue);
|
||||
|
||||
static Boolean IOHIDDevice_GetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
CFStringRef inKey,
|
||||
void ** outValue);
|
||||
static void IOHIDDevice_SetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef,
|
||||
CFStringRef inKey,
|
||||
void * inValue);
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - local (static) globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported function implementations
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDIsValidDevice( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: validate this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: Boolean - TRUE if we find the device in our( internal ) device list
|
||||
//
|
||||
|
||||
Boolean HIDIsValidDevice(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
Boolean result = FALSE; // assume failure (pessimist!)
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
if ( CFGetTypeID(inIOHIDDeviceRef) ==IOHIDDeviceGetTypeID() ) {
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // HIDIsValidDevice
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetTransport( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Transport CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the Transport for this device
|
||||
//
|
||||
|
||||
CFStringRef IOHIDDevice_GetTransport(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDTransportKey) ) );
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetVendorID( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the vendor ID for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the vendor ID for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetVendorID(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetVendorID
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetVendorIDSource( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the VendorIDSource for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the VendorIDSource for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetVendorIDSource(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDSourceKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetVendorIDSource
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetProductID( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the product ID for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the product ID for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetProductID(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetProductID
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetVersionNumber( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the VersionNumber CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the VersionNumber for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetVersionNumber(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDVersionNumberKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetVersionNumber
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetManufacturer( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Manufacturer CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the Manufacturer for this device
|
||||
//
|
||||
|
||||
CFStringRef IOHIDDevice_GetManufacturer(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDManufacturerKey) ) );
|
||||
} // IOHIDDevice_GetManufacturer
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetProduct( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Product CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the Product for this device
|
||||
//
|
||||
|
||||
CFStringRef IOHIDDevice_GetProduct(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDProductKey) ) );
|
||||
} // IOHIDDevice_GetProduct
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetSerialNumber( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the SerialNumber CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the SerialNumber for this device
|
||||
//
|
||||
|
||||
CFStringRef IOHIDDevice_GetSerialNumber(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDSerialNumberKey) ) );
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetCountryCode( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the CountryCode CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the CountryCode for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetCountryCode(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDCountryCodeKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetCountryCode
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetLocationID( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the location ID for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the location ID for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetLocationID(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetLocationID
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUsage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the usage for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the usage for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetUsage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDDeviceUsageKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetUsage
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUsagePage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the usage page for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the usage page for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetUsagePage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDDeviceUsagePageKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetUsagePage
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUsagePairs( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the UsagePairs CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFArrayRef - the UsagePairs for this device
|
||||
//
|
||||
|
||||
CFArrayRef IOHIDDevice_GetUsagePairs(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
return ( IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDDeviceUsagePairsKey) ) );
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetPrimaryUsage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the PrimaryUsage CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the PrimaryUsage for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetPrimaryUsage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsageKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetPrimaryUsage
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetPrimaryUsagePage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the PrimaryUsagePage CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the PrimaryUsagePage for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetPrimaryUsagePage(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDPrimaryUsagePageKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetPrimaryUsagePage
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetMaxInputReportSize( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the MaxInputReportSize CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the MaxInputReportSize for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetMaxInputReportSize(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDMaxInputReportSizeKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetMaxInputReportSize
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetMaxOutputReportSize( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the MaxOutputReportSize for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the MaxOutput for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetMaxOutputReportSize(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDMaxOutputReportSizeKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetMaxOutputReportSize
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetMaxFeatureReportSize( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the MaxFeatureReportSize for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the MaxFeatureReportSize for this device
|
||||
//
|
||||
|
||||
uint32_t IOHIDDevice_GetMaxFeatureReportSize(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDMaxFeatureReportSizeKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetMaxFeatureReportSize
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetReportInterval( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the ReportInterval for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the ReportInterval for this device
|
||||
//
|
||||
#ifndef kIOHIDReportIntervalKey
|
||||
#define kIOHIDReportIntervalKey "ReportInterval"
|
||||
#endif
|
||||
uint32_t IOHIDDevice_GetReportInterval(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
uint32_t result = 0;
|
||||
(void) IOHIDDevice_GetUInt32Property(inIOHIDDeviceRef, CFSTR(kIOHIDReportIntervalKey), &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetReportInterval
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetQueue( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Queue for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: IOHIDQueueRef - the Queue for this device
|
||||
//
|
||||
|
||||
IOHIDQueueRef IOHIDDevice_GetQueue(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
IOHIDQueueRef result = 0;
|
||||
(void) IOHIDDevice_GetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_QueueKey), (void *) &result);
|
||||
if ( result ) {
|
||||
assert( IOHIDQueueGetTypeID() == CFGetTypeID(result) );
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDDevice_GetQueue
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_SetQueue( inIOHIDDeviceRef, inQueueRef )
|
||||
//
|
||||
// Purpose: Set the Queue for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
// inQueueRef - the Queue reference
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDDevice_SetQueue(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDQueueRef inQueueRef) {
|
||||
IOHIDDevice_SetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_QueueKey), inQueueRef);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetTransaction( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Transaction for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: IOHIDTransactionRef - the Transaction for this device
|
||||
//
|
||||
|
||||
IOHIDTransactionRef IOHIDDevice_GetTransaction(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
IOHIDTransactionRef result = 0;
|
||||
(void) IOHIDDevice_GetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_TransactionKey), (void *) &result);
|
||||
return (result);
|
||||
} // IOHIDDevice_GetTransaction
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_SetTransaction( inIOHIDDeviceRef, inTransactionRef )
|
||||
//
|
||||
// Purpose: Set the Transaction for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
// inTransactionRef - the Transaction reference
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDDevice_SetTransaction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDTransactionRef inTransactionRef) {
|
||||
IOHIDDevice_SetPtrProperty(inIOHIDDeviceRef, CFSTR(kIOHIDDevice_TransactionKey), inTransactionRef);
|
||||
}
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - local (static) function implementations
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUInt32Property( inIOHIDDeviceRef, inKey, outValue )
|
||||
//
|
||||
// Purpose: convieance function to return a uint32_t property of a device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the device
|
||||
// inKey - CFString for the
|
||||
// outValue - address where to restore the element
|
||||
// Returns: the action cookie
|
||||
// outValue - the device
|
||||
//
|
||||
|
||||
static Boolean IOHIDDevice_GetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, uint32_t *outValue) {
|
||||
Boolean result = FALSE;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
|
||||
CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
|
||||
if ( tCFTypeRef ) {
|
||||
// if this is a number
|
||||
if ( CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef) ) {
|
||||
// get it's value
|
||||
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, outValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDDevice_GetUInt32Property
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_SetUInt32Property( inIOHIDDeviceRef, inKey, inValue )
|
||||
//
|
||||
// Purpose: convieance function to set a long property of an Device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the Device
|
||||
// inKey - CFString for the key
|
||||
// inValue - the value to set it to
|
||||
// Returns: nothing
|
||||
//
|
||||
#if 0 // unused
|
||||
static void IOHIDDevice_SetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, uint32_t inValue) {
|
||||
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
|
||||
if ( tCFNumberRef ) {
|
||||
IOHIDDeviceSetProperty(inIOHIDDeviceRef, inKey, tCFNumberRef);
|
||||
CFRelease(tCFNumberRef);
|
||||
}
|
||||
} // IOHIDDevice_SetUInt32Property
|
||||
#endif
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetPtrProperty( inIOHIDDeviceRef, inKey, outValue )
|
||||
//
|
||||
// Purpose: convieance function to return a pointer property of a device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the device
|
||||
// inKey - CFString for the
|
||||
// outValue - address where to restore the element
|
||||
// Returns: the action cookie
|
||||
// outValue - the device
|
||||
//
|
||||
|
||||
static Boolean IOHIDDevice_GetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, void **outValue) {
|
||||
Boolean result = FALSE;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
assert( IOHIDDeviceGetTypeID() == CFGetTypeID(inIOHIDDeviceRef) );
|
||||
|
||||
CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, inKey);
|
||||
if ( tCFTypeRef ) {
|
||||
// if this is a number
|
||||
if ( CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef) ) {
|
||||
// get it's value
|
||||
#ifdef __LP64__
|
||||
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt64Type, outValue );
|
||||
#else
|
||||
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, outValue );
|
||||
#endif // ifdef __LP64__
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDDevice_GetPtrProperty
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_SetPtrProperty( inIOHIDDeviceRef, inKey, inValue )
|
||||
//
|
||||
// Purpose: convieance function to set a long property of an Device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the Device
|
||||
// inKey - CFString for the key
|
||||
// inValue - the value to set it to
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
static void IOHIDDevice_SetPtrProperty(IOHIDDeviceRef inIOHIDDeviceRef, CFStringRef inKey, void *inValue) {
|
||||
#ifdef __LP64__
|
||||
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &inValue);
|
||||
#else
|
||||
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
|
||||
#endif // ifdef __LP64__
|
||||
if ( tCFNumberRef ) {
|
||||
IOHIDDeviceSetProperty(inIOHIDDeviceRef, inKey, tCFNumberRef);
|
||||
CFRelease(tCFNumberRef);
|
||||
}
|
||||
} // IOHIDDevice_SetPtrProperty
|
||||
|
||||
//*****************************************************
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
422
src/cocoa/IOHIDDevice_.h
Normal file
422
src/cocoa/IOHIDDevice_.h
Normal file
|
@ -0,0 +1,422 @@
|
|||
// File: IOHIDDevice_.h
|
||||
// Abstract: convieance functions for IOHIDDeviceGetProperty
|
||||
// Version: 2.0 + 5.3
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
#ifndef __IOHIDDevice__
|
||||
#define __IOHIDDevice__
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - includes & imports
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#include "IOHIDLib_.h"
|
||||
|
||||
//*****************************************************
|
||||
#if PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if PRAGMA_IMPORT
|
||||
#pragma import on
|
||||
#endif
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(push, 2)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack(2)
|
||||
#endif
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported function prototypes
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDIsValidDevice( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: validate this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: Boolean - TRUE if we find the device in our( internal ) device list
|
||||
//
|
||||
|
||||
extern Boolean HIDIsValidDevice(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetTransport( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Transport CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the Transport CFString for this device
|
||||
//
|
||||
|
||||
extern CFStringRef IOHIDDevice_GetTransport(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetVendorID( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the vendor ID for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the vendor ID for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetVendorID(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetVendorIDSource( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the VendorIDSource for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the VendorIDSource for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetVendorIDSource(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetProductID( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the product ID for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the product ID for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetProductID(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetVersionNumber( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the VersionNumber CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the VersionNumber for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetVersionNumber(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetManufacturer( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Manufacturer CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the Manufacturer CFString for this device
|
||||
//
|
||||
|
||||
extern CFStringRef IOHIDDevice_GetManufacturer(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetProduct( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Product CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the Product CFString for this device
|
||||
//
|
||||
|
||||
extern CFStringRef IOHIDDevice_GetProduct(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetSerialNumber( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the SerialNumber CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the SerialNumber CFString for this device
|
||||
//
|
||||
|
||||
extern CFStringRef IOHIDDevice_GetSerialNumber(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetCountryCode( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the CountryCode CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the CountryCode for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetCountryCode(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetLocationID( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the location ID for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the location ID for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetLocationID(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUsage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the usage for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the usage for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetUsage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUsagePage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the usage page for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the usage page for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetUsagePage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetUsagePairs( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the UsagePairs CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFArrayRef - the UsagePairs for this device
|
||||
//
|
||||
|
||||
extern CFArrayRef IOHIDDevice_GetUsagePairs(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetPrimaryUsage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the PrimaryUsage CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the PrimaryUsage CFString for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetPrimaryUsage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetPrimaryUsagePage( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the PrimaryUsagePage CFString for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: CFStringRef - the PrimaryUsagePage CFString for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetPrimaryUsagePage(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetMaxInputReportSize( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the MaxInputReportSize for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the MaxInputReportSize for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetMaxInputReportSize(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetMaxOutputReportSize( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the MaxOutputReportSize for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the MaxOutputReportSize for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetMaxOutputReportSize(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetMaxFeatureReportSize( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the MaxFeatureReportSize for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the MaxFeatureReportSize for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetMaxFeatureReportSize(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetReportInterval( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the ReportInterval for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: uint32_t - the ReportInterval for this device
|
||||
//
|
||||
|
||||
extern uint32_t IOHIDDevice_GetReportInterval(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetQueue( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Queue for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: IOHIDQueueRef - the Queue for this device
|
||||
//
|
||||
|
||||
extern IOHIDQueueRef IOHIDDevice_GetQueue(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_SetQueue( inIOHIDDeviceRef, inQueueRef )
|
||||
//
|
||||
// Purpose: Set the Queue for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
// inQueueRef - the Queue
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDDevice_SetQueue(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDQueueRef inQueueRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_GetTransaction( inIOHIDDeviceRef )
|
||||
//
|
||||
// Purpose: get the Transaction for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
//
|
||||
// Returns: IOHIDTransactionRef - the Transaction for this device
|
||||
//
|
||||
|
||||
extern IOHIDTransactionRef IOHIDDevice_GetTransaction(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDDevice_SetTransaction( inIOHIDDeviceRef, inTransactionRef )
|
||||
//
|
||||
// Purpose: Set the Transaction for this device
|
||||
//
|
||||
// Inputs: inIOHIDDeviceRef - the IDHIDDeviceRef for this device
|
||||
// inTransactionRef - the Transaction
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDDevice_SetTransaction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDTransactionRef inTransactionRef);
|
||||
|
||||
//*****************************************************
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(pop)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef PRAGMA_IMPORT_OFF
|
||||
#pragma import off
|
||||
#elif PRAGMA_IMPORT
|
||||
#pragma import reset
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __IOHIDDevice__ //
|
509
src/cocoa/IOHIDElement_.c
Normal file
509
src/cocoa/IOHIDElement_.c
Normal file
|
@ -0,0 +1,509 @@
|
|||
// File: IOHIDElement_.c
|
||||
// Abstract: convieance functions for IOHIDElementGetProperty
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#pragma mark - includes & imports
|
||||
//-----------------------------------------------------
|
||||
|
||||
#include "IOHIDElement_.h"
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - local (static) function prototypes
|
||||
//-----------------------------------------------------
|
||||
|
||||
// static Boolean IOHIDElement_GetLongProperty( IOHIDElementRef inElementRef, CFStringRef inKey, long * outValue );
|
||||
// static void IOHIDElement_SetLongProperty( IOHIDElementRef inElementRef, CFStringRef inKey, long inValue );
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - local (static) globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported function implementations
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDIsValidElement( inIOHIDElementRef )
|
||||
//
|
||||
// Purpose: validate this element
|
||||
//
|
||||
// Inputs: inIOHIDElementRef - the element
|
||||
//
|
||||
// Returns: Boolean - TRUE if this is a valid element ref
|
||||
//
|
||||
Boolean HIDIsValidElement(IOHIDElementRef inIOHIDElementRef) {
|
||||
Boolean result = FALSE; // assume failure (pessimist!)
|
||||
if ( inIOHIDElementRef ) {
|
||||
if ( CFGetTypeID(inIOHIDElementRef) ==IOHIDElementGetTypeID() ) {
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // HIDIsValidElement
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetValue( inElementRef, inIOHIDValueScaleType )
|
||||
//
|
||||
// Purpose: returns the current value for an element( polling )
|
||||
//
|
||||
// Notes: will return 0 on error conditions which should be accounted for by application
|
||||
//
|
||||
// Inputs: inElementRef - the element
|
||||
// inIOHIDValueScaleType - scale type ( calibrated or physical )
|
||||
//
|
||||
// Returns: double - current value for element
|
||||
//
|
||||
double IOHIDElement_GetValue(IOHIDElementRef inElementRef, IOHIDValueScaleType inIOHIDValueScaleType) {
|
||||
long result = 0;
|
||||
IOHIDValueRef tIOHIDValueRef;
|
||||
if ( kIOReturnSuccess == IOHIDDeviceGetValue(IOHIDElementGetDevice(inElementRef), inElementRef, &tIOHIDValueRef) ) {
|
||||
result = IOHIDValueGetScaledValue(tIOHIDValueRef, inIOHIDValueScaleType);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetValue
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationMin( inElementRef )
|
||||
//
|
||||
// Purpose: get the minimum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the minimum Calibration value for this element
|
||||
//
|
||||
|
||||
CFIndex IOHIDElement_GetCalibrationMin(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMinKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMaxKey), &result) ) {
|
||||
result = 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMinKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationMin
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationMin( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the minimum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the minimum bounds for a calibrated value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationMin(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMinKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationMin
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationMax( inElementRef )
|
||||
//
|
||||
// Purpose: get the maximum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
CFIndex IOHIDElement_GetCalibrationMax(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMaxKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||
result = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMaxKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationMax
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationMax( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the maximum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationMax(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationMaxKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationMax
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationSaturationMin( inElementRef )
|
||||
//
|
||||
// Purpose: get the mininum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
CFIndex IOHIDElement_GetCalibrationSaturationMin(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMinKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||
result = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMinKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationSaturationMin
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationSaturationMin( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the mininum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationSaturationMin(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMinKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationSaturationMin
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationSaturationMax( inElementRef )
|
||||
//
|
||||
// Purpose: get the maximum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
CFIndex IOHIDElement_GetCalibrationSaturationMax(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMaxKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||
result = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMaxKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationSaturationMax
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationSaturationMax( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the maximum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationSaturationMax(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationSaturationMaxKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationSaturationMax
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationDeadZoneMin( inElementRef )
|
||||
//
|
||||
// Purpose: get the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
CFIndex IOHIDElement_GetCalibrationDeadZoneMin(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMinKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||
result = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMinKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationDeadZoneMin
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationDeadZoneMin( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationDeadZoneMin(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMinKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationDeadZoneMin
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationDeadZoneMax( inElementRef )
|
||||
//
|
||||
// Purpose: get the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
CFIndex IOHIDElement_GetCalibrationDeadZoneMax(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMaxKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||
result = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMaxKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationDeadZoneMax
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationDeadZoneMax( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationDeadZoneMax(IOHIDElementRef inElementRef, CFIndex inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationDeadZoneMaxKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationDeadZoneMax
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationGranularity( inElementRef )
|
||||
//
|
||||
// Purpose: get the level of detail returned for a calibrated element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: double_t - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
double_t IOHIDElement_GetCalibrationGranularity(IOHIDElementRef inElementRef) {
|
||||
CFIndex result;
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationGranularityKey), &result) ) {
|
||||
if ( !IOHIDElement_GetLongProperty(inElementRef, CFSTR(kIOHIDElementMinKey), &result) ) {
|
||||
result = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationGranularityKey), result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // IOHIDElement_GetCalibrationGranularity
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationGranularity( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the level of detail returned for a calibrated element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the the level of detail for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetCalibrationGranularity(IOHIDElementRef inElementRef, double_t inValue) {
|
||||
IOHIDElement_SetLongProperty(inElementRef, CFSTR(kIOHIDElementCalibrationGranularityKey), inValue);
|
||||
} // IOHIDElement_SetCalibrationGranularity
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetupCalibration( inElementRef )
|
||||
//
|
||||
// Purpose: set default values for the element calibration parameters
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
void IOHIDElement_SetupCalibration(IOHIDElementRef inIOHIDElementRef) {
|
||||
// these are the min/max values returned by IOHIDValueGetScaledValue( v, kIOHIDValueScaleTypeCalibrated );
|
||||
IOHIDElement_SetCalibrationMin( inIOHIDElementRef, IOHIDElementGetLogicalMin(inIOHIDElementRef) );
|
||||
IOHIDElement_SetCalibrationMax( inIOHIDElementRef, IOHIDElementGetLogicalMax(inIOHIDElementRef) );
|
||||
|
||||
// this is the granularity of the values returned by IOHIDValueGetScaledValue( v, kIOHIDValueScaleTypeCalibrated );
|
||||
// for example if set to 0.1 the values returned will be multiples of 0.1 ( 0.1, 0.2, 0.3, etc. )
|
||||
IOHIDElement_SetCalibrationGranularity(inIOHIDElementRef, 0.);
|
||||
|
||||
// these define the dead zone (like in the middel of joystick axis)
|
||||
IOHIDElement_SetCalibrationDeadZoneMin(inIOHIDElementRef, 0);
|
||||
IOHIDElement_SetCalibrationDeadZoneMax(inIOHIDElementRef, 0);
|
||||
#if 1
|
||||
// get the current value of this element
|
||||
double value = IOHIDElement_GetValue(inIOHIDElementRef, kIOHIDValueScaleTypePhysical);
|
||||
// use it as our min/mas saturation
|
||||
IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, value);
|
||||
IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, value);
|
||||
#else
|
||||
// calculate the middle physical value we would expect from this element
|
||||
CFIndex valueMin = IOHIDElementGetPhysicalMin(inIOHIDElementRef);
|
||||
CFIndex valueMax = IOHIDElementGetPhysicalMax(inIOHIDElementRef);
|
||||
CFIndex valueMid = (valueMin + valueMax) / 2;
|
||||
|
||||
// use it as our min/mas saturation
|
||||
// this value determines the min/max values that have been recieved from the device element
|
||||
IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, valueMid);
|
||||
IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, valueMid);
|
||||
|
||||
// get the current value of this element
|
||||
double value = IOHIDElement_GetValue(inIOHIDElementRef, kIOHIDValueScaleTypePhysical);
|
||||
// and use it to adjust the current saturation values if it's outside their range
|
||||
if ( value < IOHIDElement_GetCalibrationSaturationMin(inIOHIDElementRef) ) {
|
||||
IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, value);
|
||||
}
|
||||
if ( value > IOHIDElement_GetCalibrationSaturationMax(inIOHIDElementRef) ) {
|
||||
IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, value);
|
||||
}
|
||||
|
||||
#endif
|
||||
} // IOHIDElement_SetupCalibration
|
||||
//*****************************************************
|
||||
#pragma mark - local (static) function implementations
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetLongProperty( inElementRef, inKey, outValue )
|
||||
//
|
||||
// Purpose: convieance function to return a long property of an element
|
||||
//
|
||||
// Inputs: inElementRef - the element
|
||||
// inKey - CFString for the key
|
||||
// outValue - address where to store the value
|
||||
// Returns: Boolean - TRUE if successful
|
||||
// outValue - the long property's value
|
||||
//
|
||||
|
||||
Boolean IOHIDElement_GetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long *outValue) {
|
||||
Boolean result = FALSE;
|
||||
|
||||
CFTypeRef tCFTypeRef = IOHIDElementGetProperty(inElementRef, inKey);
|
||||
if ( tCFTypeRef ) {
|
||||
// if this is a number
|
||||
if ( CFNumberGetTypeID() == CFGetTypeID(tCFTypeRef) ) {
|
||||
// get it's value
|
||||
result = CFNumberGetValue( (CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, outValue );
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} /* IOHIDElement_GetLongProperty */
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetLongProperty( inElementRef, inKey, inValue )
|
||||
//
|
||||
// Purpose: convieance function to set a long property of an element
|
||||
//
|
||||
// Inputs: inElementRef - the element
|
||||
// inKey - CFString for the key
|
||||
// inValue - the value to set it to
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
void IOHIDElement_SetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long inValue) {
|
||||
CFNumberRef tCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &inValue);
|
||||
if ( tCFNumberRef ) {
|
||||
IOHIDElementSetProperty(inElementRef, inKey, tCFNumberRef);
|
||||
CFRelease(tCFNumberRef);
|
||||
}
|
||||
} // IOHIDElement_SetLongProperty
|
||||
|
||||
//*****************************************************
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
339
src/cocoa/IOHIDElement_.h
Normal file
339
src/cocoa/IOHIDElement_.h
Normal file
|
@ -0,0 +1,339 @@
|
|||
// File: IOHIDElement_.h
|
||||
// Abstract: convieance functions for IOHIDElementGetProperty
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
#ifndef __IOHIDElement___
|
||||
#define __IOHIDElement___
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - includes & imports
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#include "IOHIDLib_.h"
|
||||
//*****************************************************
|
||||
#if PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if PRAGMA_IMPORT
|
||||
#pragma import on
|
||||
#endif
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(push, 2)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack(2)
|
||||
#endif
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported function prototypes
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// HIDIsValidElement( inIOHIDElementRef )
|
||||
//
|
||||
// Purpose: validate this element
|
||||
//
|
||||
// Inputs: inIOHIDElementRef - the element
|
||||
//
|
||||
// Returns: Boolean - TRUE if this is a valid element ref
|
||||
//
|
||||
extern Boolean HIDIsValidElement(IOHIDElementRef inIOHIDElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetValue( inElementRef, inIOHIDValueScaleType )
|
||||
//
|
||||
// Purpose: returns the current value for an element( polling )
|
||||
//
|
||||
// Notes: will return 0 on error conditions which should be accounted for by application
|
||||
//
|
||||
// Inputs: inElementRef - the element
|
||||
// inIOHIDValueScaleType - scale type ( calibrated or physical )
|
||||
//
|
||||
// Returns: double - current value for element
|
||||
//
|
||||
extern double IOHIDElement_GetValue(IOHIDElementRef inElementRef, IOHIDValueScaleType inIOHIDValueScaleType);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationMin( inElementRef )
|
||||
//
|
||||
// Purpose: get the minimum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the minimum Calibration value for this element
|
||||
//
|
||||
|
||||
extern CFIndex IOHIDElement_GetCalibrationMin(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationMin( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the minimum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the minimum bounds for a calibrated value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationMin(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationMax( inElementRef )
|
||||
//
|
||||
// Purpose: get the maximum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
extern CFIndex IOHIDElement_GetCalibrationMax(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationMax( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the maximum bounds for a calibrated value for this element
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationMax(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationSaturationMin( inElementRef )
|
||||
//
|
||||
// Purpose: get the mininum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
extern CFIndex IOHIDElement_GetCalibrationSaturationMin(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationSaturationMin( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the mininum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationSaturationMin(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationSaturationMax( inElementRef )
|
||||
//
|
||||
// Purpose: get the maximum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
extern CFIndex IOHIDElement_GetCalibrationSaturationMax(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationSaturationMax( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the maximum tolerance to be used when calibrating a logical element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationSaturationMax(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationDeadZoneMin( inElementRef )
|
||||
//
|
||||
// Purpose: get the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
extern CFIndex IOHIDElement_GetCalibrationDeadZoneMin(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationDeadZoneMin( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the minimum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationDeadZoneMin(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationDeadZoneMax( inElementRef )
|
||||
//
|
||||
// Purpose: get the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: CFIndex - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
extern CFIndex IOHIDElement_GetCalibrationDeadZoneMax(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationDeadZoneMax( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the maximum bounds near the midpoint of a logical value in which the value is ignored
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the maximum Calibration value for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationDeadZoneMax(IOHIDElementRef inElementRef, CFIndex inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_GetCalibrationGranularity( inElementRef )
|
||||
//
|
||||
// Purpose: get the level of detail returned for a calibrated element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: double_t - the maximum Calibration value for this element
|
||||
//
|
||||
|
||||
extern double_t IOHIDElement_GetCalibrationGranularity(IOHIDElementRef inElementRef);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetCalibrationGranularity( inElementRef, inValue )
|
||||
//
|
||||
// Purpose: set the level of detail returned for a calibrated element value
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
// inValue - the the level of detail for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetCalibrationGranularity(IOHIDElementRef inElementRef, double_t inValue);
|
||||
|
||||
//*************************************************************************
|
||||
//
|
||||
// IOHIDElement_SetupCalibration( inElementRef )
|
||||
//
|
||||
// Purpose: set default values for the element calibration parameters
|
||||
//
|
||||
// Inputs: inElementRef - the IOHIDElementRef for this element
|
||||
//
|
||||
// Returns: nothing
|
||||
//
|
||||
|
||||
extern void IOHIDElement_SetupCalibration(IOHIDElementRef inIOHIDElementRef);
|
||||
|
||||
extern Boolean IOHIDElement_GetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long *outValue);
|
||||
extern void IOHIDElement_SetLongProperty(IOHIDElementRef inElementRef, CFStringRef inKey, long inValue);
|
||||
|
||||
//*****************************************************
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(pop)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef PRAGMA_IMPORT_OFF
|
||||
#pragma import off
|
||||
#elif PRAGMA_IMPORT
|
||||
#pragma import reset
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __IOHIDElement___ //
|
111
src/cocoa/IOHIDLib_.h
Normal file
111
src/cocoa/IOHIDLib_.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
// File: IOHIDLib_.h
|
||||
// Abstract: Single include file for all header files of IOHIDLib
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
#ifndef __IOHIDLib___
|
||||
#define __IOHIDLib___
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - includes & imports
|
||||
//-----------------------------------------------------
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
|
||||
#include "IOHIDDevice_.h"
|
||||
#include "IOHIDElement_.h"
|
||||
|
||||
#include "ImmrHIDUtilAddOn.h"
|
||||
|
||||
//*****************************************************
|
||||
#if PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if PRAGMA_IMPORT
|
||||
#pragma import on
|
||||
#endif
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(push, 2)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack(2)
|
||||
#endif
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - typedef's, struct's, enums, defines, etc.
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported globals
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#pragma mark - exported function prototypes
|
||||
//-----------------------------------------------------
|
||||
|
||||
//*****************************************************
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(pop)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef PRAGMA_IMPORT_OFF
|
||||
#pragma import off
|
||||
#elif PRAGMA_IMPORT
|
||||
#pragma import reset
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __IOHIDLib___
|
108
src/cocoa/ImmrHIDUtilAddOn.c
Normal file
108
src/cocoa/ImmrHIDUtilAddOn.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
// File: ImmrHIDUtilAddOn.c
|
||||
// Abstract: Glue code to convert IOHIDDeviceRef's to (FFB) io_object_t's
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_error.h>
|
||||
|
||||
#include "ImmrHIDUtilAddOn.h"
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// AllocateHIDObjectFromIOHIDDeviceRef( )
|
||||
//
|
||||
// returns:
|
||||
// NULL, or acceptable io_object_t
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
io_service_t AllocateHIDObjectFromIOHIDDeviceRef(IOHIDDeviceRef inIOHIDDeviceRef) {
|
||||
io_service_t result = 0L;
|
||||
if ( inIOHIDDeviceRef ) {
|
||||
// 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.
|
||||
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOHIDDeviceKey);
|
||||
if ( matchingDict ) {
|
||||
// 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.
|
||||
CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty( inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey) );
|
||||
if ( tCFTypeRef ) {
|
||||
CFDictionaryAddValue(matchingDict, CFSTR(kIOHIDLocationIDKey), tCFTypeRef);
|
||||
// CFRelease( tCFTypeRef ); // don't release objects that we "Get".
|
||||
|
||||
// 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
|
||||
result = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
|
||||
}
|
||||
|
||||
// Note: We're not leaking the matchingDict.
|
||||
// One reference is consumed by IOServiceGetMatchingServices
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
} // AllocateHIDObjectFromIOHIDDeviceRef
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
//
|
||||
// FreeHIDObject( )
|
||||
//
|
||||
//---------------------------------------------------------------------------------
|
||||
bool FreeHIDObject(io_service_t inHIDObject) {
|
||||
kern_return_t kr;
|
||||
|
||||
kr = IOObjectRelease(inHIDObject);
|
||||
|
||||
return (kIOReturnSuccess == kr);
|
||||
} // FreeHIDObject
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
50
src/cocoa/ImmrHIDUtilAddOn.h
Normal file
50
src/cocoa/ImmrHIDUtilAddOn.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
// File: ImmrHIDUtilAddOn.h
|
||||
// Abstract: Glue code to convert IOHIDDeviceRef's to (FFB) io_object_t's
|
||||
// Version: 2.0
|
||||
//
|
||||
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
// 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 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.
|
||||
//
|
||||
// Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
||||
//
|
||||
//*****************************************************
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
|
||||
extern io_service_t AllocateHIDObjectFromIOHIDDeviceRef(IOHIDDeviceRef inIOHIDDeviceRef);
|
||||
extern bool FreeHIDObject(io_object_t inHIDObject);
|
2171
src/cocoa/i_backend_cocoa.mm
Normal file
2171
src/cocoa/i_backend_cocoa.mm
Normal file
File diff suppressed because it is too large
Load diff
820
src/cocoa/i_joystick.cpp
Normal file
820
src/cocoa/i_joystick.cpp
Normal file
|
@ -0,0 +1,820 @@
|
|||
/*
|
||||
** i_joystick.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2014 Alexey Lysiuk
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "m_joy.h"
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
|
||||
|
||||
#include "HID_Utilities_External.h"
|
||||
|
||||
#include "d_event.h"
|
||||
#include "doomdef.h"
|
||||
#include "templates.h"
|
||||
#include "i_osversion.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
FString ToFString( const CFStringRef string )
|
||||
{
|
||||
if ( NULL == string )
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
const CFIndex stringLength = CFStringGetLength( string );
|
||||
|
||||
if ( 0 == stringLength )
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
const size_t bufferSize = CFStringGetMaximumSizeForEncoding( stringLength, kCFStringEncodingUTF8 ) + 1;
|
||||
|
||||
char buffer[ bufferSize ];
|
||||
memset( buffer, 0, bufferSize );
|
||||
|
||||
CFStringGetCString( string, buffer, bufferSize, kCFStringEncodingUTF8 );
|
||||
|
||||
return FString( buffer );
|
||||
}
|
||||
|
||||
|
||||
class IOKitJoystick : public IJoystickConfig
|
||||
{
|
||||
public:
|
||||
explicit IOKitJoystick( IOHIDDeviceRef device );
|
||||
virtual ~IOKitJoystick();
|
||||
|
||||
virtual FString GetName();
|
||||
virtual float GetSensitivity();
|
||||
virtual void SetSensitivity( float scale );
|
||||
|
||||
virtual int GetNumAxes();
|
||||
virtual float GetAxisDeadZone( int axis );
|
||||
virtual EJoyAxis GetAxisMap( int axis );
|
||||
virtual const char* GetAxisName( int axis );
|
||||
virtual float GetAxisScale( int axis );
|
||||
|
||||
virtual void SetAxisDeadZone( int axis, float deadZone );
|
||||
virtual void SetAxisMap( int axis, EJoyAxis gameAxis );
|
||||
virtual void SetAxisScale( int axis, float scale );
|
||||
|
||||
virtual bool IsSensitivityDefault();
|
||||
virtual bool IsAxisDeadZoneDefault( int axis );
|
||||
virtual bool IsAxisMapDefault( int axis );
|
||||
virtual bool IsAxisScaleDefault( int axis );
|
||||
|
||||
virtual void SetDefaultConfig();
|
||||
virtual FString GetIdentifier();
|
||||
|
||||
void AddAxes( float axes[ NUM_JOYAXIS ] ) const;
|
||||
|
||||
void Update();
|
||||
|
||||
private:
|
||||
IOHIDDeviceRef m_device;
|
||||
|
||||
float m_sensitivity;
|
||||
|
||||
struct AxisInfo
|
||||
{
|
||||
char name[ 64 ];
|
||||
|
||||
float value;
|
||||
|
||||
float deadZone;
|
||||
float defaultDeadZone;
|
||||
float sensitivity;
|
||||
float defaultSensitivity;
|
||||
|
||||
EJoyAxis gameAxis;
|
||||
EJoyAxis defaultGameAxis;
|
||||
|
||||
IOHIDElementRef element;
|
||||
};
|
||||
|
||||
TArray< AxisInfo > m_axes;
|
||||
|
||||
TArray< IOHIDElementRef > m_buttons;
|
||||
TArray< IOHIDElementRef > m_POVs;
|
||||
|
||||
|
||||
static const float DEFAULT_DEADZONE;
|
||||
static const float DEFAULT_SENSITIVITY;
|
||||
|
||||
|
||||
bool ProcessAxis ( const IOHIDValueRef value );
|
||||
bool ProcessButton( const IOHIDValueRef value );
|
||||
bool ProcessPOV ( const IOHIDValueRef value );
|
||||
|
||||
};
|
||||
|
||||
|
||||
const float IOKitJoystick::DEFAULT_DEADZONE = 0.25f;
|
||||
const float IOKitJoystick::DEFAULT_SENSITIVITY = 1.0f;
|
||||
|
||||
|
||||
IOKitJoystick::IOKitJoystick( IOHIDDeviceRef device )
|
||||
: m_device( device )
|
||||
, m_sensitivity( DEFAULT_SENSITIVITY )
|
||||
{
|
||||
IOHIDElementRef element = HIDGetFirstDeviceElement( device, kHIDElementTypeInput );
|
||||
|
||||
while ( NULL != element )
|
||||
{
|
||||
const uint32_t usagePage = IOHIDElementGetUsagePage( element );
|
||||
|
||||
if ( kHIDPage_GenericDesktop == usagePage )
|
||||
{
|
||||
const uint32_t usage = IOHIDElementGetUsage( element );
|
||||
|
||||
if ( kHIDUsage_GD_Slider == usage
|
||||
|| kHIDUsage_GD_X == usage || kHIDUsage_GD_Y == usage || kHIDUsage_GD_Z == usage
|
||||
|| kHIDUsage_GD_Rx == usage || kHIDUsage_GD_Ry == usage || kHIDUsage_GD_Rz == usage )
|
||||
{
|
||||
AxisInfo axis;
|
||||
memset( &axis, 0, sizeof( axis ) );
|
||||
|
||||
if ( const CFStringRef name = IOHIDElementGetName( element ) )
|
||||
{
|
||||
CFStringGetCString( name, axis.name, sizeof( axis.name ) - 1, kCFStringEncodingUTF8 );
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( axis.name, sizeof( axis.name ), "Axis %i", m_axes.Size() + 1 );
|
||||
}
|
||||
|
||||
axis.element = element;
|
||||
|
||||
m_axes.Push( axis );
|
||||
|
||||
IOHIDElement_SetCalibrationMin( element, -1 );
|
||||
IOHIDElement_SetCalibrationMax( element, 1 );
|
||||
|
||||
HIDQueueElement( m_device, element );
|
||||
}
|
||||
else if ( kHIDUsage_GD_Hatswitch == usage && m_POVs.Size() < 4 )
|
||||
{
|
||||
m_POVs.Push( element );
|
||||
|
||||
HIDQueueElement( m_device, element );
|
||||
}
|
||||
}
|
||||
else if ( kHIDPage_Button == usagePage )
|
||||
{
|
||||
m_buttons.Push( element );
|
||||
|
||||
HIDQueueElement( m_device, element );
|
||||
}
|
||||
|
||||
element = HIDGetNextDeviceElement( element, kHIDElementTypeInput );
|
||||
}
|
||||
|
||||
SetDefaultConfig();
|
||||
}
|
||||
|
||||
IOKitJoystick::~IOKitJoystick()
|
||||
{
|
||||
M_SaveJoystickConfig( this );
|
||||
}
|
||||
|
||||
|
||||
FString IOKitJoystick::GetName()
|
||||
{
|
||||
FString result;
|
||||
|
||||
result += ToFString( IOHIDDevice_GetManufacturer( m_device ) );
|
||||
result += " ";
|
||||
result += ToFString( IOHIDDevice_GetProduct( m_device ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
float IOKitJoystick::GetSensitivity()
|
||||
{
|
||||
return m_sensitivity;
|
||||
}
|
||||
|
||||
void IOKitJoystick::SetSensitivity( float scale )
|
||||
{
|
||||
m_sensitivity = scale;
|
||||
}
|
||||
|
||||
|
||||
int IOKitJoystick::GetNumAxes()
|
||||
{
|
||||
return static_cast< int >( m_axes.Size() );
|
||||
}
|
||||
|
||||
#define IS_AXIS_VALID ( static_cast< unsigned int >( axis ) < m_axes.Size() )
|
||||
|
||||
float IOKitJoystick::GetAxisDeadZone( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID ? m_axes[ axis ].deadZone : 0.0f;
|
||||
}
|
||||
|
||||
EJoyAxis IOKitJoystick::GetAxisMap( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID ? m_axes[ axis ].gameAxis : JOYAXIS_None;
|
||||
}
|
||||
|
||||
const char* IOKitJoystick::GetAxisName( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID ? m_axes[ axis ].name : "Invalid";
|
||||
}
|
||||
|
||||
float IOKitJoystick::GetAxisScale( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID ? m_axes[ axis ].sensitivity : 0.0f;
|
||||
}
|
||||
|
||||
void IOKitJoystick::SetAxisDeadZone( int axis, float deadZone )
|
||||
{
|
||||
if ( IS_AXIS_VALID )
|
||||
{
|
||||
m_axes[ axis ].deadZone = clamp( deadZone, 0.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
void IOKitJoystick::SetAxisMap( int axis, EJoyAxis gameAxis )
|
||||
{
|
||||
if ( IS_AXIS_VALID )
|
||||
{
|
||||
m_axes[ axis ].gameAxis = ( gameAxis > JOYAXIS_None && gameAxis < NUM_JOYAXIS )
|
||||
? gameAxis
|
||||
: JOYAXIS_None;
|
||||
}
|
||||
}
|
||||
|
||||
void IOKitJoystick::SetAxisScale( int axis, float scale )
|
||||
{
|
||||
if ( IS_AXIS_VALID )
|
||||
{
|
||||
m_axes[ axis ].sensitivity = scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IOKitJoystick::IsSensitivityDefault()
|
||||
{
|
||||
return DEFAULT_SENSITIVITY == m_sensitivity;
|
||||
}
|
||||
|
||||
bool IOKitJoystick::IsAxisDeadZoneDefault( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID
|
||||
? ( m_axes[ axis ].deadZone == m_axes[ axis ].defaultDeadZone )
|
||||
: true;
|
||||
}
|
||||
|
||||
bool IOKitJoystick::IsAxisMapDefault( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID
|
||||
? ( m_axes[ axis ].gameAxis == m_axes[ axis ].defaultGameAxis )
|
||||
: true;
|
||||
}
|
||||
|
||||
bool IOKitJoystick::IsAxisScaleDefault( int axis )
|
||||
{
|
||||
return IS_AXIS_VALID
|
||||
? ( m_axes[ axis ].sensitivity == m_axes[ axis ].defaultSensitivity )
|
||||
: true;
|
||||
}
|
||||
|
||||
#undef IS_AXIS_VALID
|
||||
|
||||
void IOKitJoystick::SetDefaultConfig()
|
||||
{
|
||||
m_sensitivity = DEFAULT_SENSITIVITY;
|
||||
|
||||
const size_t axisCount = m_axes.Size();
|
||||
|
||||
for ( size_t i = 0; i < axisCount; ++i )
|
||||
{
|
||||
m_axes[i].deadZone = DEFAULT_DEADZONE;
|
||||
m_axes[i].sensitivity = DEFAULT_SENSITIVITY;
|
||||
m_axes[i].gameAxis = JOYAXIS_None;
|
||||
}
|
||||
|
||||
// Two axes? Horizontal is yaw and vertical is forward.
|
||||
|
||||
if ( 2 == axisCount)
|
||||
{
|
||||
m_axes[0].gameAxis = JOYAXIS_Yaw;
|
||||
m_axes[1].gameAxis = JOYAXIS_Forward;
|
||||
}
|
||||
|
||||
// Three axes? First two are movement, third is yaw.
|
||||
|
||||
else if ( axisCount >= 3 )
|
||||
{
|
||||
m_axes[0].gameAxis = JOYAXIS_Side;
|
||||
m_axes[1].gameAxis = JOYAXIS_Forward;
|
||||
m_axes[2].gameAxis = JOYAXIS_Yaw;
|
||||
|
||||
// Four axes? First two are movement, last two are looking around.
|
||||
|
||||
if ( axisCount >= 4 )
|
||||
{
|
||||
m_axes[3].gameAxis = JOYAXIS_Pitch;
|
||||
// ??? m_axes[3].sensitivity = 0.75f;
|
||||
|
||||
// Five axes? Use the fifth one for moving up and down.
|
||||
|
||||
if ( axisCount >= 5 )
|
||||
{
|
||||
m_axes[4].gameAxis = JOYAXIS_Up;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is only one axis, then we make no assumptions about how
|
||||
// the user might want to use it.
|
||||
|
||||
// Preserve defaults for config saving.
|
||||
|
||||
for ( size_t i = 0; i < axisCount; ++i )
|
||||
{
|
||||
m_axes[i].defaultDeadZone = m_axes[i].deadZone;
|
||||
m_axes[i].defaultSensitivity = m_axes[i].sensitivity;
|
||||
m_axes[i].defaultGameAxis = m_axes[i].gameAxis;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FString IOKitJoystick::GetIdentifier()
|
||||
{
|
||||
char identifier[ 32 ] = {0};
|
||||
|
||||
snprintf( identifier, sizeof( identifier ), "VID_%04x_PID_%04x",
|
||||
IOHIDDevice_GetVendorID( m_device ), IOHIDDevice_GetProductID( m_device ) );
|
||||
|
||||
return FString( identifier );
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystick::AddAxes( float axes[ NUM_JOYAXIS ] ) const
|
||||
{
|
||||
for ( size_t i = 0, count = m_axes.Size(); i < count; ++i )
|
||||
{
|
||||
const EJoyAxis axis = m_axes[i].gameAxis;
|
||||
|
||||
if ( JOYAXIS_None == axis )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
axes[ axis ] -= m_axes[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystick::Update()
|
||||
{
|
||||
IOHIDValueRef value = NULL;
|
||||
|
||||
while ( HIDGetEvent( m_device, &value ) && NULL != value )
|
||||
{
|
||||
ProcessAxis( value ) || ProcessButton( value ) || ProcessPOV( value );
|
||||
|
||||
CFRelease( value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IOKitJoystick::ProcessAxis( const IOHIDValueRef value )
|
||||
{
|
||||
const IOHIDElementRef element = IOHIDValueGetElement( value );
|
||||
|
||||
if ( NULL == element )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( size_t i = 0, count = m_axes.Size(); i < count; ++i )
|
||||
{
|
||||
if ( element != m_axes[i].element )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AxisInfo& axis = m_axes[i];
|
||||
|
||||
const double scaledValue = IOHIDValueGetScaledValue( value, kIOHIDValueScaleTypeCalibrated );
|
||||
const double filteredValue = Joy_RemoveDeadZone( scaledValue, axis.deadZone, NULL );
|
||||
|
||||
axis.value = static_cast< float >( filteredValue * m_sensitivity * axis.sensitivity );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IOKitJoystick::ProcessButton( const IOHIDValueRef value )
|
||||
{
|
||||
const IOHIDElementRef element = IOHIDValueGetElement( value );
|
||||
|
||||
if ( NULL == element )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( size_t i = 0, count = m_buttons.Size(); i < count; ++i )
|
||||
{
|
||||
if ( element != m_buttons[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const int newButton = IOHIDValueGetIntegerValue( value ) & 1;
|
||||
const int oldButton = ~newButton;
|
||||
|
||||
Joy_GenerateButtonEvents( oldButton, newButton, 1,
|
||||
static_cast< int >( KEY_FIRSTJOYBUTTON + i ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IOKitJoystick::ProcessPOV( const IOHIDValueRef value )
|
||||
{
|
||||
const IOHIDElementRef element = IOHIDValueGetElement( value );
|
||||
|
||||
if ( NULL == element )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( size_t i = 0, count = m_POVs.Size(); i < count; ++i )
|
||||
{
|
||||
if ( element != m_POVs[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const CFIndex direction = IOHIDValueGetIntegerValue( value );
|
||||
|
||||
// Default values is for Up/North
|
||||
int oldButtons = 0;
|
||||
int newButtons = 1;
|
||||
int numButtons = 1;
|
||||
int baseButton = KEY_JOYPOV1_UP;
|
||||
|
||||
switch ( direction )
|
||||
{
|
||||
case 0: // N
|
||||
break;
|
||||
|
||||
case 1: // NE
|
||||
newButtons = 3;
|
||||
numButtons = 2;
|
||||
break;
|
||||
|
||||
case 2: // E
|
||||
baseButton = KEY_JOYPOV1_RIGHT;
|
||||
break;
|
||||
|
||||
case 3: // SE
|
||||
newButtons = 3;
|
||||
numButtons = 2;
|
||||
baseButton = KEY_JOYPOV1_RIGHT;
|
||||
break;
|
||||
|
||||
case 4: // S
|
||||
baseButton = KEY_JOYPOV1_DOWN;
|
||||
break;
|
||||
|
||||
case 5: // SW
|
||||
newButtons = 3;
|
||||
numButtons = 2;
|
||||
baseButton = KEY_JOYPOV1_DOWN;
|
||||
break;
|
||||
|
||||
case 6: // W
|
||||
baseButton = KEY_JOYPOV1_LEFT;
|
||||
break;
|
||||
|
||||
case 7: // NW
|
||||
newButtons = 9; // UP and LEFT
|
||||
numButtons = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
// release all four directions
|
||||
oldButtons = 15;
|
||||
newButtons = 0;
|
||||
numButtons = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
Joy_GenerateButtonEvents( oldButtons, newButtons, numButtons,
|
||||
static_cast< int >( baseButton + i * 4 ) );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class IOKitJoystickManager
|
||||
{
|
||||
public:
|
||||
IOKitJoystickManager();
|
||||
~IOKitJoystickManager();
|
||||
|
||||
void GetJoysticks( TArray< IJoystickConfig* >& joysticks ) const;
|
||||
|
||||
void AddAxes( float axes[ NUM_JOYAXIS ] ) const;
|
||||
|
||||
// Updates axes/buttons states
|
||||
void Update();
|
||||
|
||||
// Rebuilds device list
|
||||
void Rescan();
|
||||
|
||||
private:
|
||||
TArray< IOKitJoystick* > m_joysticks;
|
||||
|
||||
static void OnDeviceChanged( void* context, IOReturn result, void* sender, IOHIDDeviceRef device );
|
||||
|
||||
void ReleaseJoysticks();
|
||||
|
||||
void EnableCallbacks();
|
||||
void DisableCallbacks();
|
||||
|
||||
};
|
||||
|
||||
|
||||
IOKitJoystickManager::IOKitJoystickManager()
|
||||
{
|
||||
Rescan();
|
||||
}
|
||||
|
||||
IOKitJoystickManager::~IOKitJoystickManager()
|
||||
{
|
||||
ReleaseJoysticks();
|
||||
DisableCallbacks();
|
||||
|
||||
HIDReleaseDeviceList();
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::GetJoysticks( TArray< IJoystickConfig* >& joysticks ) const
|
||||
{
|
||||
const size_t joystickCount = m_joysticks.Size();
|
||||
|
||||
joysticks.Resize( joystickCount );
|
||||
|
||||
for ( size_t i = 0; i < joystickCount; ++i )
|
||||
{
|
||||
M_LoadJoystickConfig( m_joysticks[i] );
|
||||
|
||||
joysticks[i] = m_joysticks[i];
|
||||
}
|
||||
}
|
||||
|
||||
void IOKitJoystickManager::AddAxes( float axes[ NUM_JOYAXIS ] ) const
|
||||
{
|
||||
for ( size_t i = 0, count = m_joysticks.Size(); i < count; ++i )
|
||||
{
|
||||
m_joysticks[i]->AddAxes( axes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::Update()
|
||||
{
|
||||
for ( size_t i = 0, count = m_joysticks.Size(); i < count; ++i )
|
||||
{
|
||||
m_joysticks[i]->Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::Rescan()
|
||||
{
|
||||
ReleaseJoysticks();
|
||||
DisableCallbacks();
|
||||
|
||||
const int usageCount = 2;
|
||||
|
||||
const UInt32 usagePages[ usageCount ] =
|
||||
{
|
||||
kHIDPage_GenericDesktop,
|
||||
kHIDPage_GenericDesktop
|
||||
};
|
||||
|
||||
const UInt32 usages[ usageCount ] =
|
||||
{
|
||||
kHIDUsage_GD_Joystick,
|
||||
kHIDUsage_GD_GamePad
|
||||
};
|
||||
|
||||
if ( HIDUpdateDeviceList( usagePages, usages, usageCount ) )
|
||||
{
|
||||
IOHIDDeviceRef device = HIDGetFirstDevice();
|
||||
|
||||
while ( NULL != device )
|
||||
{
|
||||
IOKitJoystick* joystick = new IOKitJoystick( device );
|
||||
m_joysticks.Push( joystick );
|
||||
|
||||
device = HIDGetNextDevice( device );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf( "IOKitJoystickManager: Failed to build gamepad/joystick device list.\n" );
|
||||
}
|
||||
|
||||
EnableCallbacks();
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::OnDeviceChanged( void* context, IOReturn result, void* sender, IOHIDDeviceRef device )
|
||||
{
|
||||
event_t event;
|
||||
|
||||
memset( &event, 0, sizeof( event ) );
|
||||
event.type = EV_DeviceChange;
|
||||
|
||||
D_PostEvent( &event );
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::ReleaseJoysticks()
|
||||
{
|
||||
for ( size_t i = 0, count = m_joysticks.Size(); i < count; ++i )
|
||||
{
|
||||
delete m_joysticks[i];
|
||||
}
|
||||
|
||||
m_joysticks.Clear();
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::EnableCallbacks()
|
||||
{
|
||||
if ( NULL == gIOHIDManagerRef )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IOHIDManagerRegisterDeviceMatchingCallback( gIOHIDManagerRef, OnDeviceChanged, this );
|
||||
IOHIDManagerRegisterDeviceRemovalCallback ( gIOHIDManagerRef, OnDeviceChanged, this );
|
||||
IOHIDManagerScheduleWithRunLoop( gIOHIDManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
|
||||
}
|
||||
|
||||
void IOKitJoystickManager::DisableCallbacks()
|
||||
{
|
||||
if ( NULL == gIOHIDManagerRef )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IOHIDManagerUnscheduleFromRunLoop( gIOHIDManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
|
||||
IOHIDManagerRegisterDeviceMatchingCallback( gIOHIDManagerRef, NULL, NULL );
|
||||
IOHIDManagerRegisterDeviceRemovalCallback ( gIOHIDManagerRef, NULL, NULL );
|
||||
}
|
||||
|
||||
|
||||
IOKitJoystickManager* s_joystickManager;
|
||||
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void I_StartupJoysticks()
|
||||
{
|
||||
// HID Manager API is available on 10.5 (Darwin 9.x) or newer
|
||||
|
||||
if (darwinVersion.major >= 9)
|
||||
{
|
||||
s_joystickManager = new IOKitJoystickManager;
|
||||
}
|
||||
}
|
||||
|
||||
void I_ShutdownJoysticks()
|
||||
{
|
||||
delete s_joystickManager;
|
||||
}
|
||||
|
||||
void I_GetJoysticks( TArray< IJoystickConfig* >& sticks )
|
||||
{
|
||||
if ( NULL != s_joystickManager )
|
||||
{
|
||||
s_joystickManager->GetJoysticks( sticks );
|
||||
}
|
||||
}
|
||||
|
||||
void I_GetAxes( float axes[ NUM_JOYAXIS ] )
|
||||
{
|
||||
for ( size_t i = 0; i < NUM_JOYAXIS; ++i )
|
||||
{
|
||||
axes[i] = 0.0f;
|
||||
}
|
||||
|
||||
if ( use_joystick && NULL != s_joystickManager )
|
||||
{
|
||||
s_joystickManager->AddAxes( axes );
|
||||
}
|
||||
}
|
||||
|
||||
IJoystickConfig* I_UpdateDeviceList()
|
||||
{
|
||||
if ( use_joystick && NULL != s_joystickManager )
|
||||
{
|
||||
s_joystickManager->Rescan();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void I_ProcessJoysticks()
|
||||
{
|
||||
if ( use_joystick && NULL != s_joystickManager )
|
||||
{
|
||||
s_joystickManager->Update();
|
||||
}
|
||||
}
|
||||
|
||||
#else // prior to 10.5
|
||||
|
||||
void I_StartupJoysticks()
|
||||
{
|
||||
}
|
||||
|
||||
void I_ShutdownJoysticks()
|
||||
{
|
||||
}
|
||||
|
||||
void I_GetJoysticks(TArray<IJoystickConfig*>& sticks)
|
||||
{
|
||||
sticks.Clear();
|
||||
}
|
||||
|
||||
void I_GetAxes(float axes[NUM_JOYAXIS])
|
||||
{
|
||||
for (size_t i = 0; i < NUM_JOYAXIS; ++i)
|
||||
{
|
||||
axes[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
IJoystickConfig *I_UpdateDeviceList()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void I_ProcessJoysticks()
|
||||
{
|
||||
}
|
||||
|
||||
#endif // 10.5 or higher
|
43
src/cocoa/i_osversion.h
Executable file
43
src/cocoa/i_osversion.h
Executable file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
** i_osversion.h
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2012-2014 Alexey Lysiuk
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct DarwinVersion
|
||||
{
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
uint16_t bugfix;
|
||||
};
|
||||
|
||||
extern const DarwinVersion darwinVersion;
|
52
src/cocoa/i_rbopts.h
Normal file
52
src/cocoa/i_rbopts.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
** i_rbopts.h
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2014 Alexey Lysiuk
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||
#define SRC_COCOA_I_RBOPTS_H_INCLUDED
|
||||
|
||||
struct RenderBufferOptions
|
||||
{
|
||||
float pixelScale;
|
||||
|
||||
float shiftX;
|
||||
float shiftY;
|
||||
|
||||
float width;
|
||||
float height;
|
||||
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
extern RenderBufferOptions rbOpts;
|
||||
|
||||
#endif // SRC_COCOA_I_RBOPTS_H_INCLUDED
|
190
src/cocoa/i_timer.cpp
Normal file
190
src/cocoa/i_timer.cpp
Normal file
|
@ -0,0 +1,190 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "basictypes.h"
|
||||
#include "basicinlines.h"
|
||||
#include "doomdef.h"
|
||||
#include "i_system.h"
|
||||
#include "templates.h"
|
||||
|
||||
|
||||
unsigned int I_MSTime()
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
unsigned int I_FPSTime()
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
|
||||
bool g_isTicFrozen;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
timespec GetNextTickTime()
|
||||
{
|
||||
static const long MILLISECONDS_IN_SECOND = 1000;
|
||||
static const long MICROSECONDS_IN_SECOND = 1000 * MILLISECONDS_IN_SECOND;
|
||||
static const long NANOSECONDS_IN_SECOND = 1000 * MICROSECONDS_IN_SECOND;
|
||||
|
||||
static timespec ts = {};
|
||||
|
||||
if (__builtin_expect((0 == ts.tv_sec), 0))
|
||||
{
|
||||
timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = (tv.tv_usec + MICROSECONDS_IN_SECOND / TICRATE) * MILLISECONDS_IN_SECOND;
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.tv_nsec += (MICROSECONDS_IN_SECOND / TICRATE) * MILLISECONDS_IN_SECOND;
|
||||
}
|
||||
|
||||
if (ts.tv_nsec >= NANOSECONDS_IN_SECOND)
|
||||
{
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= NANOSECONDS_IN_SECOND;
|
||||
}
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
pthread_cond_t s_timerEvent;
|
||||
pthread_mutex_t s_timerMutex;
|
||||
pthread_t s_timerThread;
|
||||
|
||||
bool s_timerInitialized;
|
||||
bool s_timerExitRequested;
|
||||
|
||||
uint32_t s_ticStart;
|
||||
uint32_t s_timerStart;
|
||||
|
||||
int s_tics;
|
||||
|
||||
|
||||
void* TimerThreadFunc(void*)
|
||||
{
|
||||
assert(s_timerInitialized);
|
||||
assert(!s_timerExitRequested);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (s_timerExitRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const timespec timeToNextTick = GetNextTickTime();
|
||||
|
||||
pthread_mutex_lock(&s_timerMutex);
|
||||
pthread_cond_timedwait(&s_timerEvent, &s_timerMutex, &timeToNextTick);
|
||||
|
||||
if (!g_isTicFrozen)
|
||||
{
|
||||
// The following GCC/Clang intrinsic can be used instead of OS X specific function:
|
||||
// __sync_add_and_fetch(&s_tics, 1);
|
||||
// Although it's not supported on all platform/compiler combination,
|
||||
// e.g. GCC 4.0.1 with PowerPC target architecture
|
||||
|
||||
OSAtomicIncrement32(&s_tics);
|
||||
}
|
||||
|
||||
s_timerStart = SDL_GetTicks();
|
||||
|
||||
pthread_cond_broadcast(&s_timerEvent);
|
||||
pthread_mutex_unlock(&s_timerMutex);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int GetTimeThreaded(bool saveMS)
|
||||
{
|
||||
if (saveMS)
|
||||
{
|
||||
s_ticStart = s_timerStart;
|
||||
}
|
||||
|
||||
return s_tics;
|
||||
}
|
||||
|
||||
int WaitForTicThreaded(int prevTic)
|
||||
{
|
||||
assert(!g_isTicFrozen);
|
||||
|
||||
while (s_tics <= prevTic)
|
||||
{
|
||||
pthread_mutex_lock(&s_timerMutex);
|
||||
pthread_cond_wait(&s_timerEvent, &s_timerMutex);
|
||||
pthread_mutex_unlock(&s_timerMutex);
|
||||
}
|
||||
|
||||
return s_tics;
|
||||
}
|
||||
|
||||
void FreezeTimeThreaded(bool frozen)
|
||||
{
|
||||
g_isTicFrozen = frozen;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
fixed_t I_GetTimeFrac(uint32* ms)
|
||||
{
|
||||
const uint32_t now = SDL_GetTicks();
|
||||
|
||||
if (NULL != ms)
|
||||
{
|
||||
*ms = s_ticStart + 1000 / TICRATE;
|
||||
}
|
||||
|
||||
return 0 == s_ticStart
|
||||
? FRACUNIT
|
||||
: clamp<fixed_t>( (now - s_ticStart) * FRACUNIT * TICRATE / 1000, 0, FRACUNIT);
|
||||
}
|
||||
|
||||
|
||||
void I_InitTimer ()
|
||||
{
|
||||
assert(!s_timerInitialized);
|
||||
s_timerInitialized = true;
|
||||
|
||||
pthread_cond_init (&s_timerEvent, NULL);
|
||||
pthread_mutex_init(&s_timerMutex, NULL);
|
||||
|
||||
pthread_create(&s_timerThread, NULL, TimerThreadFunc, NULL);
|
||||
|
||||
I_GetTime = GetTimeThreaded;
|
||||
I_WaitForTic = WaitForTicThreaded;
|
||||
I_FreezeTime = FreezeTimeThreaded;
|
||||
}
|
||||
|
||||
void I_ShutdownTimer ()
|
||||
{
|
||||
if (!s_timerInitialized)
|
||||
{
|
||||
// This might happen if Cancel button was pressed
|
||||
// in the IWAD selector window
|
||||
return;
|
||||
}
|
||||
|
||||
s_timerExitRequested = true;
|
||||
|
||||
pthread_join(s_timerThread, NULL);
|
||||
|
||||
pthread_mutex_destroy(&s_timerMutex);
|
||||
pthread_cond_destroy (&s_timerEvent);
|
||||
}
|
47
src/cocoa/zdoom-info.plist
Normal file
47
src/cocoa/zdoom-info.plist
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//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>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>zdoom.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.zdoom.zdoom</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>ZDoom</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Version 2.8.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.action-games</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.4</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Doom Resource File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>wad</string>
|
||||
<string>pk3</string>
|
||||
<string>zip</string>
|
||||
<string>pk7</string>
|
||||
<string>7z</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
src/cocoa/zdoom.icns
Normal file
BIN
src/cocoa/zdoom.icns
Normal file
Binary file not shown.
|
@ -145,12 +145,20 @@ bool CT_Responder (event_t *ev)
|
|||
CT_BackSpace ();
|
||||
return true;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
else if (ev->data1 == 'C' && (ev->data3 & GKM_META))
|
||||
#else // !__APPLE__
|
||||
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
||||
#endif // __APPLE__
|
||||
{
|
||||
I_PutInClipboard ((char *)ChatQueue);
|
||||
return true;
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
else if (ev->data1 == 'V' && (ev->data3 & GKM_META))
|
||||
#else // !__APPLE__
|
||||
else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL))
|
||||
#endif // __APPLE__
|
||||
{
|
||||
CT_PasteChat(I_GetFromClipboard(false));
|
||||
}
|
||||
|
|
|
@ -70,7 +70,8 @@ enum GUIKeyModifiers
|
|||
GKM_SHIFT = 1,
|
||||
GKM_CTRL = 2,
|
||||
GKM_ALT = 4,
|
||||
GKM_LBUTTON = 8
|
||||
GKM_META = 8,
|
||||
GKM_LBUTTON = 16
|
||||
};
|
||||
|
||||
// Special codes for some GUI keys, including a few real ASCII codes.
|
||||
|
|
|
@ -52,7 +52,7 @@ class FScanner;
|
|||
#define GCC_YSEG
|
||||
#else
|
||||
#define MSVC_YSEG
|
||||
#define GCC_YSEG __attribute__((section(SECTION_YREG)))
|
||||
#define GCC_YSEG __attribute__((section(SECTION_YREG))) __attribute__((used))
|
||||
#endif
|
||||
|
||||
struct FIntermissionDescriptor;
|
||||
|
|
|
@ -516,7 +516,14 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
// with the dragon skin bracers.
|
||||
if (damage < 10000)
|
||||
{
|
||||
#if __APPLE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1
|
||||
// -O1 optimizer bug work around. Only needed for
|
||||
// GCC 4.2.1 on OS X for 10.4/10.5 tools compatibility.
|
||||
volatile fixed_t tmp = 300;
|
||||
Slots[i] -= Scale (damage, SlotsIncrement[i], tmp);
|
||||
#else
|
||||
Slots[i] -= Scale (damage, SlotsIncrement[i], 300);
|
||||
#endif
|
||||
if (Slots[i] < 2*FRACUNIT)
|
||||
{
|
||||
Slots[i] = 0;
|
||||
|
|
|
@ -41,7 +41,7 @@ static inline SDWORD Scale (SDWORD a, SDWORD b, SDWORD c)
|
|||
: "a,a,a,a,a,a" (a),
|
||||
"m,r,m,r,d,d" (b),
|
||||
"r,r,m,m,r,m" (c)
|
||||
: "%cc"
|
||||
: "cc"
|
||||
);
|
||||
|
||||
return result;
|
||||
|
@ -59,7 +59,7 @@ static inline SDWORD MulScale (SDWORD a, SDWORD b, SDWORD c)
|
|||
: "a,a,a,a" (a),
|
||||
"m,r,m,r" (b),
|
||||
"c,c,I,I" (c)
|
||||
: "%cc"
|
||||
: "cc"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ static inline SDWORD DivScale (SDWORD a, SDWORD b, SDWORD c)
|
|||
: "a" (lo),
|
||||
"d" (hi),
|
||||
"r" (b)
|
||||
: "%cc");
|
||||
: "cc");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ static inline SDWORD DivScale1 (SDWORD a, SDWORD b)
|
|||
"=&d,d" (dummy)
|
||||
: "a,a" (a),
|
||||
"r,m" (b)
|
||||
: "%cc");
|
||||
: "cc");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ static inline SDWORD DivScale1 (SDWORD a, SDWORD b)
|
|||
: "a,a" (a<<s), \
|
||||
"d,d" (a>>(32-s)), \
|
||||
"r,m" (b) \
|
||||
: "%cc"); \
|
||||
: "cc"); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ static inline SDWORD DivScale32 (SDWORD a, SDWORD b)
|
|||
"=d,d" (dummy)
|
||||
: "d,d" (a),
|
||||
"r,m" (b)
|
||||
: "%cc");
|
||||
: "cc");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -313,7 +313,7 @@ static inline void clearbufshort (void *buff, unsigned int count, WORD clear)
|
|||
"rep stosw"
|
||||
:"=D" (buff), "=c" (count)
|
||||
:"D" (buff), "c" (count), "a" (clear|(clear<<16))
|
||||
:"%cc");
|
||||
:"cc");
|
||||
}
|
||||
|
||||
static inline SDWORD ksgn (SDWORD a)
|
||||
|
@ -327,6 +327,6 @@ static inline SDWORD ksgn (SDWORD a)
|
|||
"adc $0,%1"
|
||||
:"=r" (dummy), "=r" (result)
|
||||
:"0" (a)
|
||||
:"%cc");
|
||||
:"cc");
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,13 @@ static const int PO_LINE_EXPLICIT = 5;
|
|||
angle_t FNodeBuilder::PointToAngle (fixed_t x, fixed_t y)
|
||||
{
|
||||
const double rad2bam = double(1<<30) / M_PI;
|
||||
#if defined __APPLE__ && !defined __llvm__
|
||||
// Work-around for vectorization issue in Apple's GCC 4.x
|
||||
// See https://gcc.gnu.org/wiki/Math_Optimization_Flags for details
|
||||
long double ang = atan2l (double(y), double(x));
|
||||
#else // !__APPLE__ || __llvm__
|
||||
double ang = atan2 (double(y), double(x));
|
||||
#endif // __APPLE__ && !__llvm__
|
||||
return angle_t(ang * rad2bam) << 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1873,7 +1873,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
|
|||
funcm->HasReturnValue = funcf->HasReturnValue;
|
||||
funcm->ImportNum = funcf->ImportNum;
|
||||
funcm->LocalCount = funcf->LocalCount;
|
||||
funcm->Address = funcf->Address;
|
||||
funcm->Address = LittleLong(funcf->Address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2058,7 +2058,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
|
|||
const char *const parse = (char *)&chunk[2];
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < chunk[1]; )
|
||||
for (i = 0; i < LittleLong(chunk[1]); )
|
||||
{
|
||||
if (parse[i])
|
||||
{
|
||||
|
@ -2351,7 +2351,7 @@ void FBehavior::LoadScriptsDirectory ()
|
|||
scripts.b = FindChunk (MAKE_ID('S','F','L','G'));
|
||||
if (scripts.dw != NULL)
|
||||
{
|
||||
max = scripts.dw[1] / 4;
|
||||
max = LittleLong(scripts.dw[1]) / 4;
|
||||
scripts.dw += 2;
|
||||
for (i = max; i > 0; --i, scripts.w += 2)
|
||||
{
|
||||
|
@ -2367,7 +2367,7 @@ void FBehavior::LoadScriptsDirectory ()
|
|||
scripts.b = FindChunk (MAKE_ID('S','V','C','T'));
|
||||
if (scripts.dw != NULL)
|
||||
{
|
||||
max = scripts.dw[1] / 4;
|
||||
max = LittleLong(scripts.dw[1]) / 4;
|
||||
scripts.dw += 2;
|
||||
for (i = max; i > 0; --i, scripts.w += 2)
|
||||
{
|
||||
|
@ -2681,7 +2681,7 @@ BYTE *FBehavior::FindChunk (DWORD id) const
|
|||
{
|
||||
return chunk;
|
||||
}
|
||||
chunk += ((DWORD *)chunk)[1] + 8;
|
||||
chunk += LittleLong(((DWORD *)chunk)[1]) + 8;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2689,14 +2689,14 @@ BYTE *FBehavior::FindChunk (DWORD id) const
|
|||
BYTE *FBehavior::NextChunk (BYTE *chunk) const
|
||||
{
|
||||
DWORD id = *(DWORD *)chunk;
|
||||
chunk += ((DWORD *)chunk)[1] + 8;
|
||||
chunk += LittleLong(((DWORD *)chunk)[1]) + 8;
|
||||
while (chunk != NULL && chunk < Data + DataSize)
|
||||
{
|
||||
if (((DWORD *)chunk)[0] == id)
|
||||
{
|
||||
return chunk;
|
||||
}
|
||||
chunk += ((DWORD *)chunk)[1] + 8;
|
||||
chunk += LittleLong(((DWORD *)chunk)[1]) + 8;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
131
src/sdl/i_gui.cpp
Normal file
131
src/sdl/i_gui.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
|
||||
// Moved from sdl/i_system.cpp
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bitmap.h"
|
||||
#include "v_palette.h"
|
||||
#include "textures.h"
|
||||
|
||||
extern SDL_Surface *cursorSurface;
|
||||
extern SDL_Rect cursorBlit;
|
||||
|
||||
#ifdef USE_XCURSOR
|
||||
// Xlib has its own GC, so don't let it interfere.
|
||||
#define GC XGC
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#undef GC
|
||||
|
||||
bool UseXCursor;
|
||||
SDL_Cursor *X11Cursor;
|
||||
SDL_Cursor *FirstCursor;
|
||||
|
||||
// Hack! Hack! SDL does not provide a clean way to get the XDisplay.
|
||||
// On the other hand, there are no more planned updates for SDL 1.2,
|
||||
// so we should be fine making assumptions.
|
||||
struct SDL_PrivateVideoData
|
||||
{
|
||||
int local_X11;
|
||||
Display *X11_Display;
|
||||
};
|
||||
|
||||
struct SDL_VideoDevice
|
||||
{
|
||||
const char *name;
|
||||
int (*functions[9])();
|
||||
SDL_VideoInfo info;
|
||||
SDL_PixelFormat *displayformatalphapixel;
|
||||
int (*morefuncs[9])();
|
||||
Uint16 *gamma;
|
||||
int (*somefuncs[9])();
|
||||
unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack!
|
||||
int is_32bit;
|
||||
int (*itsafuncs[13])();
|
||||
SDL_Surface *surfaces[3];
|
||||
SDL_Palette *physpal;
|
||||
SDL_Color *gammacols;
|
||||
char *wm_strings[2];
|
||||
int offsets[2];
|
||||
SDL_GrabMode input_grab;
|
||||
int handles_any_size;
|
||||
SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in?
|
||||
};
|
||||
|
||||
extern SDL_VideoDevice *current_video;
|
||||
#define SDL_Display (current_video->hidden->X11_Display)
|
||||
|
||||
SDL_Cursor *CreateColorCursor(FTexture *cursorpic)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool I_SetCursor(FTexture *cursorpic)
|
||||
{
|
||||
if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
|
||||
{
|
||||
// Must be no larger than 32x32.
|
||||
if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_XCURSOR
|
||||
if (UseXCursor)
|
||||
{
|
||||
if (FirstCursor == NULL)
|
||||
{
|
||||
FirstCursor = SDL_GetCursor();
|
||||
}
|
||||
X11Cursor = CreateColorCursor(cursorpic);
|
||||
if (X11Cursor != NULL)
|
||||
{
|
||||
SDL_SetCursor(X11Cursor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (cursorSurface == NULL)
|
||||
cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));
|
||||
|
||||
SDL_ShowCursor(0);
|
||||
SDL_LockSurface(cursorSurface);
|
||||
BYTE buffer[32*32*4];
|
||||
memset(buffer, 0, 32*32*4);
|
||||
FBitmap bmp(buffer, 32*4, 32, 32);
|
||||
cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
|
||||
memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
|
||||
SDL_UnlockSurface(cursorSurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_ShowCursor(1);
|
||||
|
||||
if (cursorSurface != NULL)
|
||||
{
|
||||
SDL_FreeSurface(cursorSurface);
|
||||
cursorSurface = NULL;
|
||||
}
|
||||
#ifdef USE_XCURSOR
|
||||
if (X11Cursor != NULL)
|
||||
{
|
||||
SDL_SetCursor(FirstCursor);
|
||||
SDL_FreeCursor(X11Cursor);
|
||||
X11Cursor = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void I_SetMainWindowVisible(bool visible)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* I_GetBackEndName()
|
||||
{
|
||||
return "SDL";
|
||||
}
|
|
@ -75,6 +75,10 @@
|
|||
|
||||
extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(char*, char*));
|
||||
|
||||
#ifdef __APPLE__
|
||||
void Mac_I_FatalError(const char* errortext);
|
||||
#endif
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
@ -235,6 +239,8 @@ static void unprotect_rtext()
|
|||
void I_StartupJoysticks();
|
||||
void I_ShutdownJoysticks();
|
||||
|
||||
const char* I_GetBackEndName();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#if !defined (__APPLE__)
|
||||
|
@ -244,8 +250,8 @@ int main (int argc, char **argv)
|
|||
}
|
||||
#endif // !__APPLE__
|
||||
|
||||
printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n",
|
||||
GetVersionString(), GetGitTime(), __DATE__);
|
||||
printf(GAMENAME" %s - %s - %s version\nCompiled on %s\n",
|
||||
GetVersionString(), GetGitTime(), I_GetBackEndName(), __DATE__);
|
||||
|
||||
seteuid (getuid ());
|
||||
std::set_new_handler (NewFailure);
|
||||
|
@ -356,6 +362,11 @@ int main (int argc, char **argv)
|
|||
I_ShutdownJoysticks();
|
||||
if (error.GetMessage ())
|
||||
fprintf (stderr, "%s\n", error.GetMessage ());
|
||||
|
||||
#ifdef __APPLE__
|
||||
Mac_I_FatalError(error.GetMessage());
|
||||
#endif // __APPLE__
|
||||
|
||||
exit (-1);
|
||||
}
|
||||
catch (...)
|
||||
|
|
|
@ -71,12 +71,9 @@
|
|||
#include "m_fixed.h"
|
||||
#include "g_level.h"
|
||||
|
||||
#ifdef USE_XCURSOR
|
||||
// Xlib has its own GC, so don't let it interfere.
|
||||
#define GC XGC
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#undef GC
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif // __APPLE__
|
||||
|
||||
EXTERN_CVAR (String, language)
|
||||
|
||||
|
@ -91,11 +88,6 @@ extern bool GtkAvailable;
|
|||
#elif defined(__APPLE__)
|
||||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
||||
#endif
|
||||
#ifdef USE_XCURSOR
|
||||
bool UseXCursor;
|
||||
SDL_Cursor *X11Cursor;
|
||||
SDL_Cursor *FirstCursor;
|
||||
#endif
|
||||
|
||||
DWORD LanguageIDs[4];
|
||||
|
||||
|
@ -122,185 +114,6 @@ void I_EndRead(void)
|
|||
}
|
||||
|
||||
|
||||
static DWORD TicStart;
|
||||
static DWORD BaseTime;
|
||||
static int TicFrozen;
|
||||
|
||||
// Signal based timer.
|
||||
static Semaphore timerWait;
|
||||
static int tics;
|
||||
static DWORD sig_start;
|
||||
|
||||
void I_SelectTimer();
|
||||
|
||||
// [RH] Returns time in milliseconds
|
||||
unsigned int I_MSTime (void)
|
||||
{
|
||||
unsigned int time = SDL_GetTicks ();
|
||||
return time - BaseTime;
|
||||
}
|
||||
|
||||
// Exactly the same thing, but based does no modification to the time.
|
||||
unsigned int I_FPSTime()
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
//
|
||||
// I_GetTime
|
||||
// returns time in 1/35th second tics
|
||||
//
|
||||
int I_GetTimeSelect (bool saveMS)
|
||||
{
|
||||
I_SelectTimer();
|
||||
return I_GetTime (saveMS);
|
||||
}
|
||||
|
||||
int I_GetTimePolled (bool saveMS)
|
||||
{
|
||||
if (TicFrozen != 0)
|
||||
{
|
||||
return TicFrozen;
|
||||
}
|
||||
|
||||
DWORD tm = SDL_GetTicks();
|
||||
|
||||
if (saveMS)
|
||||
{
|
||||
TicStart = tm;
|
||||
}
|
||||
return Scale(tm - BaseTime, TICRATE, 1000);
|
||||
}
|
||||
|
||||
int I_GetTimeSignaled (bool saveMS)
|
||||
{
|
||||
if (saveMS)
|
||||
{
|
||||
TicStart = sig_start;
|
||||
}
|
||||
return tics;
|
||||
}
|
||||
|
||||
int I_WaitForTicPolled (int prevtic)
|
||||
{
|
||||
int time;
|
||||
|
||||
assert (TicFrozen == 0);
|
||||
while ((time = I_GetTimePolled(false)) <= prevtic)
|
||||
;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
int I_WaitForTicSignaled (int prevtic)
|
||||
{
|
||||
assert (TicFrozen == 0);
|
||||
|
||||
while(tics <= prevtic)
|
||||
{
|
||||
SEMAPHORE_WAIT(timerWait)
|
||||
}
|
||||
|
||||
return tics;
|
||||
}
|
||||
|
||||
void I_FreezeTimeSelect (bool frozen)
|
||||
{
|
||||
I_SelectTimer();
|
||||
return I_FreezeTime (frozen);
|
||||
}
|
||||
|
||||
void I_FreezeTimePolled (bool frozen)
|
||||
{
|
||||
if (frozen)
|
||||
{
|
||||
assert(TicFrozen == 0);
|
||||
TicFrozen = I_GetTimePolled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(TicFrozen != 0);
|
||||
int froze = TicFrozen;
|
||||
TicFrozen = 0;
|
||||
int now = I_GetTimePolled(false);
|
||||
BaseTime += (now - froze) * 1000 / TICRATE;
|
||||
}
|
||||
}
|
||||
|
||||
void I_FreezeTimeSignaled (bool frozen)
|
||||
{
|
||||
TicFrozen = frozen;
|
||||
}
|
||||
|
||||
int I_WaitForTicSelect (int prevtic)
|
||||
{
|
||||
I_SelectTimer();
|
||||
return I_WaitForTic (prevtic);
|
||||
}
|
||||
|
||||
//
|
||||
// I_HandleAlarm
|
||||
// Should be called every time there is an alarm.
|
||||
//
|
||||
void I_HandleAlarm (int sig)
|
||||
{
|
||||
if(!TicFrozen)
|
||||
tics++;
|
||||
sig_start = SDL_GetTicks();
|
||||
SEMAPHORE_SIGNAL(timerWait)
|
||||
}
|
||||
|
||||
//
|
||||
// I_SelectTimer
|
||||
// Sets up the timer function based on if we can use signals for efficent CPU
|
||||
// usage.
|
||||
//
|
||||
void I_SelectTimer()
|
||||
{
|
||||
SEMAPHORE_INIT(timerWait, 0, 0)
|
||||
#ifndef __sun
|
||||
signal(SIGALRM, I_HandleAlarm);
|
||||
#else
|
||||
struct sigaction alrmaction;
|
||||
sigaction(SIGALRM, NULL, &alrmaction);
|
||||
alrmaction.sa_handler = I_HandleAlarm;
|
||||
sigaction(SIGALRM, &alrmaction, NULL);
|
||||
#endif
|
||||
|
||||
struct itimerval itv;
|
||||
itv.it_interval.tv_sec = itv.it_value.tv_sec = 0;
|
||||
itv.it_interval.tv_usec = itv.it_value.tv_usec = 1000000/TICRATE;
|
||||
|
||||
if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
|
||||
{
|
||||
I_GetTime = I_GetTimePolled;
|
||||
I_FreezeTime = I_FreezeTimePolled;
|
||||
I_WaitForTic = I_WaitForTicPolled;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_GetTime = I_GetTimeSignaled;
|
||||
I_FreezeTime = I_FreezeTimeSignaled;
|
||||
I_WaitForTic = I_WaitForTicSignaled;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the fractional amount of a tic passed since the most recent tic
|
||||
fixed_t I_GetTimeFrac (uint32 *ms)
|
||||
{
|
||||
DWORD now = SDL_GetTicks ();
|
||||
if (ms) *ms = TicStart + (1000 / TICRATE);
|
||||
if (TicStart == 0)
|
||||
{
|
||||
return FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t frac = clamp<fixed_t> ((now - TicStart)*FRACUNIT*TICRATE/1000, 0, FRACUNIT);
|
||||
return frac;
|
||||
}
|
||||
}
|
||||
|
||||
void I_WaitVBL (int count)
|
||||
{
|
||||
// I_WaitVBL is never used to actually synchronize to the
|
||||
|
@ -322,6 +135,9 @@ void SetLanguageIDs ()
|
|||
LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang;
|
||||
}
|
||||
|
||||
void I_InitTimer ();
|
||||
void I_ShutdownTimer ();
|
||||
|
||||
//
|
||||
// I_Init
|
||||
//
|
||||
|
@ -330,11 +146,9 @@ void I_Init (void)
|
|||
CheckCPUID (&CPU);
|
||||
DumpCPUInfo (&CPU);
|
||||
|
||||
I_GetTime = I_GetTimeSelect;
|
||||
I_WaitForTic = I_WaitForTicSelect;
|
||||
I_FreezeTime = I_FreezeTimeSelect;
|
||||
atterm (I_ShutdownSound);
|
||||
I_InitSound ();
|
||||
I_InitTimer ();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -350,6 +164,8 @@ void I_Quit (void)
|
|||
G_CheckDemoStatus();
|
||||
|
||||
C_DeinitConsole();
|
||||
|
||||
I_ShutdownTimer();
|
||||
}
|
||||
|
||||
|
||||
|
@ -785,6 +601,10 @@ int I_FindAttr (findstate_t *fileinfo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
static PasteboardRef s_clipboard;
|
||||
#endif // __APPLE__
|
||||
|
||||
// Clipboard support requires GTK+
|
||||
// TODO: GTK+ uses UTF-8. We don't, so some conversions would be appropriate.
|
||||
void I_PutInClipboard (const char *str)
|
||||
|
@ -805,6 +625,23 @@ void I_PutInClipboard (const char *str)
|
|||
}
|
||||
*/
|
||||
}
|
||||
#elif defined __APPLE__
|
||||
if (NULL == s_clipboard)
|
||||
{
|
||||
PasteboardCreate(kPasteboardClipboard, &s_clipboard);
|
||||
}
|
||||
|
||||
PasteboardClear(s_clipboard);
|
||||
PasteboardSynchronize(s_clipboard);
|
||||
|
||||
const CFDataRef textData = CFDataCreate(kCFAllocatorDefault,
|
||||
reinterpret_cast<const UInt8*>(str), strlen(str));
|
||||
|
||||
if (NULL != textData)
|
||||
{
|
||||
PasteboardPutItemFlavor(s_clipboard, PasteboardItemID(1),
|
||||
CFSTR("public.utf8-plain-text"), textData, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -826,6 +663,61 @@ FString I_GetFromClipboard (bool use_primary_selection)
|
|||
}
|
||||
}
|
||||
}
|
||||
#elif defined __APPLE__
|
||||
FString result;
|
||||
|
||||
if (NULL == s_clipboard)
|
||||
{
|
||||
PasteboardCreate(kPasteboardClipboard, &s_clipboard);
|
||||
}
|
||||
|
||||
PasteboardSynchronize(s_clipboard);
|
||||
|
||||
ItemCount itemCount = 0;
|
||||
PasteboardGetItemCount(s_clipboard, &itemCount);
|
||||
|
||||
if (0 == itemCount)
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
PasteboardItemID itemID;
|
||||
|
||||
if (0 != PasteboardGetItemIdentifier(s_clipboard, 1, &itemID))
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
CFArrayRef flavorTypeArray;
|
||||
|
||||
if (0 != PasteboardCopyItemFlavors(s_clipboard, itemID, &flavorTypeArray))
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
const CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
|
||||
|
||||
for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex)
|
||||
{
|
||||
const CFStringRef flavorType = static_cast<const CFStringRef>(
|
||||
CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex));
|
||||
|
||||
if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text")))
|
||||
{
|
||||
CFDataRef flavorData;
|
||||
|
||||
if (0 == PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &flavorData))
|
||||
{
|
||||
result += reinterpret_cast<const char*>(CFDataGetBytePtr(flavorData));
|
||||
}
|
||||
|
||||
CFRelease(flavorData);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(flavorTypeArray);
|
||||
|
||||
return result;
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
@ -851,104 +743,3 @@ unsigned int I_MakeRNGSeed()
|
|||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
#ifdef USE_XCURSOR
|
||||
// Hack! Hack! SDL does not provide a clean way to get the XDisplay.
|
||||
// On the other hand, there are no more planned updates for SDL 1.2,
|
||||
// so we should be fine making assumptions.
|
||||
struct SDL_PrivateVideoData
|
||||
{
|
||||
int local_X11;
|
||||
Display *X11_Display;
|
||||
};
|
||||
|
||||
struct SDL_VideoDevice
|
||||
{
|
||||
const char *name;
|
||||
int (*functions[9])();
|
||||
SDL_VideoInfo info;
|
||||
SDL_PixelFormat *displayformatalphapixel;
|
||||
int (*morefuncs[9])();
|
||||
Uint16 *gamma;
|
||||
int (*somefuncs[9])();
|
||||
unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack!
|
||||
int is_32bit;
|
||||
int (*itsafuncs[13])();
|
||||
SDL_Surface *surfaces[3];
|
||||
SDL_Palette *physpal;
|
||||
SDL_Color *gammacols;
|
||||
char *wm_strings[2];
|
||||
int offsets[2];
|
||||
SDL_GrabMode input_grab;
|
||||
int handles_any_size;
|
||||
SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in?
|
||||
};
|
||||
|
||||
extern SDL_VideoDevice *current_video;
|
||||
#define SDL_Display (current_video->hidden->X11_Display)
|
||||
|
||||
SDL_Cursor *CreateColorCursor(FTexture *cursorpic)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Surface *cursorSurface = NULL;
|
||||
SDL_Rect cursorBlit = {0, 0, 32, 32};
|
||||
bool I_SetCursor(FTexture *cursorpic)
|
||||
{
|
||||
if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null)
|
||||
{
|
||||
// Must be no larger than 32x32.
|
||||
if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_XCURSOR
|
||||
if (UseXCursor)
|
||||
{
|
||||
if (FirstCursor == NULL)
|
||||
{
|
||||
FirstCursor = SDL_GetCursor();
|
||||
}
|
||||
X11Cursor = CreateColorCursor(cursorpic);
|
||||
if (X11Cursor != NULL)
|
||||
{
|
||||
SDL_SetCursor(X11Cursor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (cursorSurface == NULL)
|
||||
cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));
|
||||
|
||||
SDL_ShowCursor(0);
|
||||
SDL_LockSurface(cursorSurface);
|
||||
BYTE buffer[32*32*4];
|
||||
memset(buffer, 0, 32*32*4);
|
||||
FBitmap bmp(buffer, 32*4, 32, 32);
|
||||
cursorpic->CopyTrueColorPixels(&bmp, 0, 0);
|
||||
memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4);
|
||||
SDL_UnlockSurface(cursorSurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_ShowCursor(1);
|
||||
|
||||
if (cursorSurface != NULL)
|
||||
{
|
||||
SDL_FreeSurface(cursorSurface);
|
||||
cursorSurface = NULL;
|
||||
}
|
||||
#ifdef USE_XCURSOR
|
||||
if (X11Cursor != NULL)
|
||||
{
|
||||
SDL_SetCursor(FirstCursor);
|
||||
SDL_FreeCursor(X11Cursor);
|
||||
X11Cursor = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
206
src/sdl/i_timer.cpp
Normal file
206
src/sdl/i_timer.cpp
Normal file
|
@ -0,0 +1,206 @@
|
|||
|
||||
// Moved from sdl/i_system.cpp
|
||||
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "basictypes.h"
|
||||
#include "basicinlines.h"
|
||||
#include "hardware.h"
|
||||
#include "i_system.h"
|
||||
#include "templates.h"
|
||||
|
||||
|
||||
static DWORD TicStart;
|
||||
static DWORD BaseTime;
|
||||
static int TicFrozen;
|
||||
|
||||
// Signal based timer.
|
||||
static Semaphore timerWait;
|
||||
static int tics;
|
||||
static DWORD sig_start;
|
||||
|
||||
void I_SelectTimer();
|
||||
|
||||
// [RH] Returns time in milliseconds
|
||||
unsigned int I_MSTime (void)
|
||||
{
|
||||
unsigned int time = SDL_GetTicks ();
|
||||
return time - BaseTime;
|
||||
}
|
||||
|
||||
// Exactly the same thing, but based does no modification to the time.
|
||||
unsigned int I_FPSTime()
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
//
|
||||
// I_GetTime
|
||||
// returns time in 1/35th second tics
|
||||
//
|
||||
int I_GetTimeSelect (bool saveMS)
|
||||
{
|
||||
I_SelectTimer();
|
||||
return I_GetTime (saveMS);
|
||||
}
|
||||
|
||||
int I_GetTimePolled (bool saveMS)
|
||||
{
|
||||
if (TicFrozen != 0)
|
||||
{
|
||||
return TicFrozen;
|
||||
}
|
||||
|
||||
DWORD tm = SDL_GetTicks();
|
||||
|
||||
if (saveMS)
|
||||
{
|
||||
TicStart = tm;
|
||||
}
|
||||
return Scale(tm - BaseTime, TICRATE, 1000);
|
||||
}
|
||||
|
||||
int I_GetTimeSignaled (bool saveMS)
|
||||
{
|
||||
if (saveMS)
|
||||
{
|
||||
TicStart = sig_start;
|
||||
}
|
||||
return tics;
|
||||
}
|
||||
|
||||
int I_WaitForTicPolled (int prevtic)
|
||||
{
|
||||
int time;
|
||||
|
||||
assert (TicFrozen == 0);
|
||||
while ((time = I_GetTimePolled(false)) <= prevtic)
|
||||
;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
int I_WaitForTicSignaled (int prevtic)
|
||||
{
|
||||
assert (TicFrozen == 0);
|
||||
|
||||
while(tics <= prevtic)
|
||||
{
|
||||
SEMAPHORE_WAIT(timerWait)
|
||||
}
|
||||
|
||||
return tics;
|
||||
}
|
||||
|
||||
void I_FreezeTimeSelect (bool frozen)
|
||||
{
|
||||
I_SelectTimer();
|
||||
return I_FreezeTime (frozen);
|
||||
}
|
||||
|
||||
void I_FreezeTimePolled (bool frozen)
|
||||
{
|
||||
if (frozen)
|
||||
{
|
||||
assert(TicFrozen == 0);
|
||||
TicFrozen = I_GetTimePolled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(TicFrozen != 0);
|
||||
int froze = TicFrozen;
|
||||
TicFrozen = 0;
|
||||
int now = I_GetTimePolled(false);
|
||||
BaseTime += (now - froze) * 1000 / TICRATE;
|
||||
}
|
||||
}
|
||||
|
||||
void I_FreezeTimeSignaled (bool frozen)
|
||||
{
|
||||
TicFrozen = frozen;
|
||||
}
|
||||
|
||||
int I_WaitForTicSelect (int prevtic)
|
||||
{
|
||||
I_SelectTimer();
|
||||
return I_WaitForTic (prevtic);
|
||||
}
|
||||
|
||||
//
|
||||
// I_HandleAlarm
|
||||
// Should be called every time there is an alarm.
|
||||
//
|
||||
void I_HandleAlarm (int sig)
|
||||
{
|
||||
if(!TicFrozen)
|
||||
tics++;
|
||||
sig_start = SDL_GetTicks();
|
||||
SEMAPHORE_SIGNAL(timerWait)
|
||||
}
|
||||
|
||||
//
|
||||
// I_SelectTimer
|
||||
// Sets up the timer function based on if we can use signals for efficent CPU
|
||||
// usage.
|
||||
//
|
||||
void I_SelectTimer()
|
||||
{
|
||||
SEMAPHORE_INIT(timerWait, 0, 0)
|
||||
#ifndef __sun
|
||||
signal(SIGALRM, I_HandleAlarm);
|
||||
#else
|
||||
struct sigaction alrmaction;
|
||||
sigaction(SIGALRM, NULL, &alrmaction);
|
||||
alrmaction.sa_handler = I_HandleAlarm;
|
||||
sigaction(SIGALRM, &alrmaction, NULL);
|
||||
#endif
|
||||
|
||||
struct itimerval itv;
|
||||
itv.it_interval.tv_sec = itv.it_value.tv_sec = 0;
|
||||
itv.it_interval.tv_usec = itv.it_value.tv_usec = 1000000/TICRATE;
|
||||
|
||||
if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
|
||||
{
|
||||
I_GetTime = I_GetTimePolled;
|
||||
I_FreezeTime = I_FreezeTimePolled;
|
||||
I_WaitForTic = I_WaitForTicPolled;
|
||||
}
|
||||
else
|
||||
{
|
||||
I_GetTime = I_GetTimeSignaled;
|
||||
I_FreezeTime = I_FreezeTimeSignaled;
|
||||
I_WaitForTic = I_WaitForTicSignaled;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the fractional amount of a tic passed since the most recent tic
|
||||
fixed_t I_GetTimeFrac (uint32 *ms)
|
||||
{
|
||||
DWORD now = SDL_GetTicks ();
|
||||
if (ms) *ms = TicStart + (1000 / TICRATE);
|
||||
if (TicStart == 0)
|
||||
{
|
||||
return FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t frac = clamp<fixed_t> ((now - TicStart)*FRACUNIT*TICRATE/1000, 0, FRACUNIT);
|
||||
return frac;
|
||||
}
|
||||
}
|
||||
|
||||
void I_InitTimer ()
|
||||
{
|
||||
I_GetTime = I_GetTimeSelect;
|
||||
I_WaitForTic = I_WaitForTicSelect;
|
||||
I_FreezeTime = I_FreezeTimeSelect;
|
||||
}
|
||||
|
||||
void I_ShutdownTimer ()
|
||||
{
|
||||
|
||||
}
|
|
@ -33,9 +33,29 @@
|
|||
**
|
||||
*/
|
||||
|
||||
// Avoid collision between DObject class and Objective-C
|
||||
#define Class ObjectClass
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "d_main.h"
|
||||
#include "version.h"
|
||||
#include "c_cvars.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_misc.h"
|
||||
#include "gameconfigfile.h"
|
||||
|
||||
#undef Class
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <wordexp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
|
||||
// Missing type definition for 10.4 and earlier
|
||||
typedef unsigned int NSUInteger;
|
||||
#endif // prior to 10.5
|
||||
|
||||
CVAR(String, osx_additional_parameters, "", CVAR_ARCHIVE | CVAR_NOSET | CVAR_GLOBALCONFIG);
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -107,6 +127,45 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
|||
|
||||
@end
|
||||
|
||||
static NSDictionary* GetKnownFileTypes()
|
||||
{
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"-file" , @"wad",
|
||||
@"-file" , @"pk3",
|
||||
@"-file" , @"zip",
|
||||
@"-file" , @"pk7",
|
||||
@"-file" , @"7z",
|
||||
@"-deh" , @"deh",
|
||||
@"-bex" , @"bex",
|
||||
@"-exec" , @"cfg",
|
||||
@"-playdemo", @"lmp",
|
||||
nil];
|
||||
}
|
||||
|
||||
static NSArray* GetKnownExtensions()
|
||||
{
|
||||
return [GetKnownFileTypes() allKeys];
|
||||
}
|
||||
|
||||
@interface NSMutableString(AppendKnownFileType)
|
||||
- (void)appendKnownFileType:(NSString *)filePath;
|
||||
@end
|
||||
|
||||
@implementation NSMutableString(AppendKnownFileType)
|
||||
- (void)appendKnownFileType:(NSString *)filePath
|
||||
{
|
||||
NSString* extension = [[filePath pathExtension] lowercaseString];
|
||||
NSString* parameter = [GetKnownFileTypes() objectForKey:extension];
|
||||
|
||||
if (nil == parameter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[self appendFormat:@"%@ \"%@\" ", parameter, filePath];
|
||||
}
|
||||
@end
|
||||
|
||||
// So we can listen for button actions and such we need to have an Obj-C class.
|
||||
@interface IWADPicker : NSObject
|
||||
{
|
||||
|
@ -114,13 +173,18 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
|||
NSWindow *window;
|
||||
NSButton *okButton;
|
||||
NSButton *cancelButton;
|
||||
NSButton *browseButton;
|
||||
NSTextField *parametersTextField;
|
||||
bool cancelled;
|
||||
}
|
||||
|
||||
- (void)buttonPressed:(id) sender;
|
||||
- (void)browseButtonPressed:(id) sender;
|
||||
- (void)doubleClicked:(id) sender;
|
||||
- (void)makeLabel:(NSTextField *)label withString:(const char*) str;
|
||||
- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad;
|
||||
- (NSString*)commandLineParameters;
|
||||
- (void)menuActionSent:(NSNotification*)notification;
|
||||
@end
|
||||
|
||||
@implementation IWADPicker
|
||||
|
@ -134,6 +198,52 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
|||
[app stopModal];
|
||||
}
|
||||
|
||||
- (void)browseButtonPressed:(id) sender
|
||||
{
|
||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||
[openPanel setAllowsMultipleSelection:YES];
|
||||
[openPanel setCanChooseFiles:YES];
|
||||
[openPanel setCanChooseDirectories:YES];
|
||||
[openPanel setResolvesAliases:YES];
|
||||
[openPanel setAllowedFileTypes:GetKnownExtensions()];
|
||||
|
||||
if (NSOKButton == [openPanel runModal])
|
||||
{
|
||||
NSArray* files = [openPanel URLs];
|
||||
NSMutableString* parameters = [NSMutableString string];
|
||||
|
||||
for (NSUInteger i = 0, ei = [files count]; i < ei; ++i)
|
||||
{
|
||||
NSString* filePath = [[files objectAtIndex:i] path];
|
||||
BOOL isDirectory = false;
|
||||
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory] && isDirectory)
|
||||
{
|
||||
[parameters appendFormat:@"-file \"%@\" ", filePath];
|
||||
}
|
||||
else
|
||||
{
|
||||
[parameters appendKnownFileType:filePath];
|
||||
}
|
||||
}
|
||||
|
||||
if ([parameters length] > 0)
|
||||
{
|
||||
NSString* newParameters = [parametersTextField stringValue];
|
||||
|
||||
if ([newParameters length] > 0
|
||||
&& NO == [newParameters hasSuffix:@" "])
|
||||
{
|
||||
newParameters = [newParameters stringByAppendingString:@" "];
|
||||
}
|
||||
|
||||
newParameters = [newParameters stringByAppendingString:parameters];
|
||||
|
||||
[parametersTextField setStringValue: newParameters];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)doubleClicked:(id) sender
|
||||
{
|
||||
if ([sender clickedRow] >= 0)
|
||||
|
@ -159,20 +269,18 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
|||
cancelled = false;
|
||||
|
||||
app = [NSApplication sharedApplication];
|
||||
id windowTitle = [NSString stringWithFormat:@GAMESIG " %s: Select an IWAD to use", GetVersionString()];
|
||||
id windowTitle = [NSString stringWithFormat:@"%s %s", GAMENAME, GetVersionString()];
|
||||
|
||||
NSRect frame = NSMakeRect(0, 0, 440, 450);
|
||||
window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[window setTitle:windowTitle];
|
||||
|
||||
NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(22, 379, 412, 50)];
|
||||
[self makeLabel:description withString:"ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"];
|
||||
NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 384, 402, 50)];
|
||||
[self makeLabel:description withString:GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:"];
|
||||
[[window contentView] addSubview:description];
|
||||
[description release];
|
||||
|
||||
// Commented out version would account for an additional parameters box.
|
||||
//NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 103, 412, 288)];
|
||||
NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 50, 412, 341)];
|
||||
NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 135, 402, 256)];
|
||||
NSTableView *iwadTable = [[NSTableView alloc] initWithFrame:[iwadScroller bounds]];
|
||||
IWADTableData *tableData = [[IWADTableData alloc] init:wads num:numwads];
|
||||
for(int i = 0;i < NUM_COLUMNS;i++)
|
||||
|
@ -200,11 +308,12 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
|||
[iwadTable release];
|
||||
[iwadScroller release];
|
||||
|
||||
/*NSTextField *additionalParametersLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(17, 78, 144, 17)];
|
||||
[self makeLabel:additionalParametersLabel:"Additional Parameters"];
|
||||
NSTextField *additionalParametersLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 108, 144, 17)];
|
||||
[self makeLabel:additionalParametersLabel withString:"Additional Parameters:"];
|
||||
[[window contentView] addSubview:additionalParametersLabel];
|
||||
NSTextField *additionalParameters = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 48, 360, 22)];
|
||||
[[window contentView] addSubview:additionalParameters];*/
|
||||
parametersTextField = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 48, 402, 54)];
|
||||
[parametersTextField setStringValue:[NSString stringWithUTF8String:osx_additional_parameters]];
|
||||
[[window contentView] addSubview:parametersTextField];
|
||||
|
||||
// Doesn't look like the SDL version implements this so lets not show it.
|
||||
/*NSButton *dontAsk = [[NSButton alloc] initWithFrame:NSMakeRect(18, 18, 178, 18)];
|
||||
|
@ -213,39 +322,164 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
|||
[dontAsk setState:(showwin ? NSOffState : NSOnState)];
|
||||
[[window contentView] addSubview:dontAsk];*/
|
||||
|
||||
okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 12, 96, 32)];
|
||||
[okButton setTitle:[NSString stringWithUTF8String:"OK"]];
|
||||
okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 8, 96, 32)];
|
||||
[okButton setTitle:@"OK"];
|
||||
[okButton setBezelStyle:NSRoundedBezelStyle];
|
||||
[okButton setAction:@selector(buttonPressed:)];
|
||||
[okButton setTarget:self];
|
||||
[okButton setKeyEquivalent:@"\r"];
|
||||
[[window contentView] addSubview:okButton];
|
||||
|
||||
cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 12, 96, 32)];
|
||||
[cancelButton setTitle:[NSString stringWithUTF8String:"Cancel"]];
|
||||
cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 8, 96, 32)];
|
||||
[cancelButton setTitle:@"Cancel"];
|
||||
[cancelButton setBezelStyle:NSRoundedBezelStyle];
|
||||
[cancelButton setAction:@selector(buttonPressed:)];
|
||||
[cancelButton setTarget:self];
|
||||
[cancelButton setKeyEquivalent:@"\033"];
|
||||
[[window contentView] addSubview:cancelButton];
|
||||
|
||||
browseButton = [[NSButton alloc] initWithFrame:NSMakeRect(14, 8, 96, 32)];
|
||||
[browseButton setTitle:@"Browse..."];
|
||||
[browseButton setBezelStyle:NSRoundedBezelStyle];
|
||||
[browseButton setAction:@selector(browseButtonPressed:)];
|
||||
[browseButton setTarget:self];
|
||||
[[window contentView] addSubview:browseButton];
|
||||
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:self selector:@selector(menuActionSent:) name:NSMenuDidSendActionNotification object:nil];
|
||||
|
||||
[window center];
|
||||
[app runModalForWindow:window];
|
||||
|
||||
[center removeObserver:self name:NSMenuDidSendActionNotification object:nil];
|
||||
|
||||
[window release];
|
||||
[okButton release];
|
||||
[cancelButton release];
|
||||
[browseButton release];
|
||||
|
||||
return cancelled ? -1 : [iwadTable selectedRow];
|
||||
}
|
||||
|
||||
- (NSString*)commandLineParameters
|
||||
{
|
||||
return [parametersTextField stringValue];
|
||||
}
|
||||
|
||||
- (void)menuActionSent:(NSNotification*)notification
|
||||
{
|
||||
NSDictionary* userInfo = [notification userInfo];
|
||||
NSMenuItem* menuItem = [userInfo valueForKey:@"MenuItem"];
|
||||
|
||||
if ( @selector(terminate:) == [menuItem action] )
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
EXTERN_CVAR(String, defaultiwad)
|
||||
|
||||
static NSString* GetArchitectureString()
|
||||
{
|
||||
#ifdef __i386__
|
||||
return @"i386";
|
||||
#elif defined __x86_64__
|
||||
return @"x86_64";
|
||||
#elif defined __ppc__
|
||||
return @"ppc";
|
||||
#elif defined __ppc64__
|
||||
return @"ppc64";
|
||||
#endif
|
||||
}
|
||||
|
||||
static void RestartWithParameters(const char* iwadPath, NSString* parameters)
|
||||
{
|
||||
assert(nil != parameters);
|
||||
|
||||
defaultiwad = ExtractFileBase(iwadPath);
|
||||
|
||||
GameConfig->DoGameSetup("Doom");
|
||||
M_SaveDefaults(NULL);
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
@try
|
||||
{
|
||||
const int commandLineParametersCount = Args->NumArgs();
|
||||
assert(commandLineParametersCount > 0);
|
||||
|
||||
NSString* executablePath = [NSString stringWithUTF8String:Args->GetArg(0)];
|
||||
NSString* architecture = GetArchitectureString();
|
||||
|
||||
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:commandLineParametersCount + 6];
|
||||
[arguments addObject:@"-arch"];
|
||||
[arguments addObject:architecture];
|
||||
[arguments addObject:executablePath];
|
||||
[arguments addObject:@"-wad_picker_restart"];
|
||||
[arguments addObject:@"-iwad"];
|
||||
[arguments addObject:[NSString stringWithUTF8String:iwadPath]];
|
||||
|
||||
for (int i = 1; i < commandLineParametersCount; ++i)
|
||||
{
|
||||
NSString* currentParameter = [NSString stringWithUTF8String:Args->GetArg(i)];
|
||||
[arguments addObject:currentParameter];
|
||||
}
|
||||
|
||||
wordexp_t expansion = {};
|
||||
|
||||
if (0 == wordexp([parameters UTF8String], &expansion, 0))
|
||||
{
|
||||
for (size_t i = 0; i < expansion.we_wordc; ++i)
|
||||
{
|
||||
NSString* argumentString = [NSString stringWithCString:expansion.we_wordv[i]
|
||||
encoding:NSUTF8StringEncoding];
|
||||
[arguments addObject:argumentString];
|
||||
}
|
||||
|
||||
wordfree(&expansion);
|
||||
}
|
||||
|
||||
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/arch" arguments:arguments];
|
||||
|
||||
_exit(0); // to avoid atexit()'s functions
|
||||
}
|
||||
@catch (NSException* e)
|
||||
{
|
||||
NSLog(@"Cannot restart: %@", [e reason]);
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
void I_SetMainWindowVisible(bool visible);
|
||||
|
||||
// Simple wrapper so we can call this from outside.
|
||||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
I_SetMainWindowVisible(false);
|
||||
|
||||
IWADPicker *picker = [IWADPicker alloc];
|
||||
int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad];
|
||||
[picker release];
|
||||
|
||||
I_SetMainWindowVisible(true);
|
||||
|
||||
NSString* parametersToAppend = [picker commandLineParameters];
|
||||
osx_additional_parameters = [parametersToAppend UTF8String];
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
if (0 != [parametersToAppend length])
|
||||
{
|
||||
RestartWithParameters(wads[ret].Path, parametersToAppend);
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#endif // __APPLE__
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
@ -43,6 +47,8 @@ public:
|
|||
|
||||
friend class SDLVideo;
|
||||
|
||||
virtual void SetVSync (bool vsync);
|
||||
|
||||
private:
|
||||
PalEntry SourcePalette[256];
|
||||
BYTE GammaTable[3][256];
|
||||
|
@ -75,13 +81,15 @@ struct MiniModeInfo
|
|||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern IVideo *Video;
|
||||
extern SDL_Surface *cursorSurface;
|
||||
extern SDL_Rect cursorBlit;
|
||||
extern bool GUICapture;
|
||||
|
||||
SDL_Surface *cursorSurface = NULL;
|
||||
SDL_Rect cursorBlit = {0, 0, 32, 32};
|
||||
|
||||
EXTERN_CVAR (Float, Gamma)
|
||||
EXTERN_CVAR (Int, vid_maxfps)
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
|
@ -326,6 +334,7 @@ SDLFB::SDLFB (int width, int height, bool fullscreen)
|
|||
}
|
||||
memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256);
|
||||
UpdateColors ();
|
||||
SetVSync (vid_vsync);
|
||||
}
|
||||
|
||||
SDLFB::~SDLFB ()
|
||||
|
@ -535,6 +544,26 @@ bool SDLFB::IsFullscreen ()
|
|||
return (Screen->flags & SDL_FULLSCREEN) != 0;
|
||||
}
|
||||
|
||||
void SDLFB::SetVSync (bool vsync)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
if (CGLContextObj context = CGLGetCurrentContext())
|
||||
{
|
||||
// Apply vsync for native backend only (where OpenGL context is set)
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
|
||||
// Inconsistency between 10.4 and 10.5 SDKs:
|
||||
// third argument of CGLSetParameter() is const long* on 10.4 and const GLint* on 10.5
|
||||
// So, GLint typedef'ed to long instead of int to workaround this issue
|
||||
typedef long GLint;
|
||||
#endif // prior to 10.5
|
||||
|
||||
const GLint value = vsync ? 1 : 0;
|
||||
CGLSetParameter(context, kCGLCPSwapInterval, &value);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
}
|
||||
|
||||
ADD_STAT (blit)
|
||||
{
|
||||
FString out;
|
||||
|
|
|
@ -433,7 +433,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
|
|||
}
|
||||
|
||||
int forkres;
|
||||
wordexp_t words;
|
||||
wordexp_t words = {};
|
||||
|
||||
switch (wordexp (CommandLine.GetChars(), &words, 0))
|
||||
{
|
||||
|
|
|
@ -266,11 +266,11 @@ enum EDefinitionType
|
|||
#define GCC_MSEG
|
||||
#else
|
||||
#define MSVC_ASEG
|
||||
#define GCC_ASEG __attribute__((section(SECTION_AREG)))
|
||||
#define GCC_ASEG __attribute__((section(SECTION_AREG))) __attribute__((used))
|
||||
#define MSVC_PSEG
|
||||
#define GCC_PSEG __attribute__((section(SECTION_GREG)))
|
||||
#define GCC_PSEG __attribute__((section(SECTION_GREG))) __attribute__((used))
|
||||
#define MSVC_MSEG
|
||||
#define GCC_MSEG __attribute__((section(SECTION_MREG)))
|
||||
#define GCC_MSEG __attribute__((section(SECTION_MREG))) __attribute__((used))
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue