renaming
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54116 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,732 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: src/mac/corefoundation/cfstring.cpp
|
|
||||||
// Purpose: wxCFStringHolder and other string functions
|
|
||||||
// Author: Stefan Csomor
|
|
||||||
// Modified by:
|
|
||||||
// Created: 2004-10-29 (from code in src/mac/carbon/utils.cpp)
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) Stefan Csomor
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
// Usage: Darwin (base library)
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/string.h"
|
|
||||||
#include "wx/intl.h"
|
|
||||||
#if wxUSE_GUI
|
|
||||||
#include "wx/font.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/mac/corefoundation/cfstring.h"
|
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
|
|
||||||
void wxMacConvertNewlines13To10( char * data )
|
|
||||||
{
|
|
||||||
char * buf = data ;
|
|
||||||
while( (buf=strchr(buf,0x0d)) != NULL )
|
|
||||||
{
|
|
||||||
*buf = 0x0a ;
|
|
||||||
buf++ ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMacConvertNewlines10To13( char * data )
|
|
||||||
{
|
|
||||||
char * buf = data ;
|
|
||||||
while( (buf=strchr(buf,0x0a)) != NULL )
|
|
||||||
{
|
|
||||||
*buf = 0x0d ;
|
|
||||||
buf++ ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString sCR((wxChar)13);
|
|
||||||
const wxString sLF((wxChar)10);
|
|
||||||
|
|
||||||
void wxMacConvertNewlines13To10( wxString * data )
|
|
||||||
{
|
|
||||||
data->Replace( sCR,sLF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMacConvertNewlines10To13( wxString * data )
|
|
||||||
{
|
|
||||||
data->Replace( sLF,sCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxUint32 wxMacGetSystemEncFromFontEnc(wxFontEncoding encoding)
|
|
||||||
{
|
|
||||||
CFStringEncoding enc = 0 ;
|
|
||||||
if ( encoding == wxFONTENCODING_DEFAULT )
|
|
||||||
{
|
|
||||||
#if wxUSE_GUI
|
|
||||||
encoding = wxFont::GetDefaultEncoding() ;
|
|
||||||
#else
|
|
||||||
encoding = wxFONTENCODING_SYSTEM; // to be set below
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( encoding == wxFONTENCODING_SYSTEM )
|
|
||||||
{
|
|
||||||
enc = CFStringGetSystemEncoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( encoding)
|
|
||||||
{
|
|
||||||
case wxFONTENCODING_ISO8859_1 :
|
|
||||||
enc = kCFStringEncodingISOLatin1 ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_2 :
|
|
||||||
enc = kCFStringEncodingISOLatin2;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_3 :
|
|
||||||
enc = kCFStringEncodingISOLatin3 ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_4 :
|
|
||||||
enc = kCFStringEncodingISOLatin4;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_5 :
|
|
||||||
enc = kCFStringEncodingISOLatinCyrillic;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_6 :
|
|
||||||
enc = kCFStringEncodingISOLatinArabic;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_7 :
|
|
||||||
enc = kCFStringEncodingISOLatinGreek;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_8 :
|
|
||||||
enc = kCFStringEncodingISOLatinHebrew;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_9 :
|
|
||||||
enc = kCFStringEncodingISOLatin5;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_10 :
|
|
||||||
enc = kCFStringEncodingISOLatin6;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_13 :
|
|
||||||
enc = kCFStringEncodingISOLatin7;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_14 :
|
|
||||||
enc = kCFStringEncodingISOLatin8;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ISO8859_15 :
|
|
||||||
enc = kCFStringEncodingISOLatin9;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case wxFONTENCODING_KOI8 :
|
|
||||||
enc = kCFStringEncodingKOI8_R;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_ALTERNATIVE : // MS-DOS CP866
|
|
||||||
enc = kCFStringEncodingDOSRussian;
|
|
||||||
break ;
|
|
||||||
/*
|
|
||||||
case wxFONTENCODING_BULGARIAN :
|
|
||||||
enc = ;
|
|
||||||
break ;
|
|
||||||
*/
|
|
||||||
case wxFONTENCODING_CP437 :
|
|
||||||
enc =kCFStringEncodingDOSLatinUS ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP850 :
|
|
||||||
enc = kCFStringEncodingDOSLatin1;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP852 :
|
|
||||||
enc = kCFStringEncodingDOSLatin2;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP855 :
|
|
||||||
enc = kCFStringEncodingDOSCyrillic;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP866 :
|
|
||||||
enc =kCFStringEncodingDOSRussian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP874 :
|
|
||||||
enc = kCFStringEncodingDOSThai;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP932 :
|
|
||||||
enc = kCFStringEncodingDOSJapanese;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP936 :
|
|
||||||
enc = kCFStringEncodingDOSChineseSimplif ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP949 :
|
|
||||||
enc = kCFStringEncodingDOSKorean;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP950 :
|
|
||||||
enc = kCFStringEncodingDOSChineseTrad;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case wxFONTENCODING_CP1250 :
|
|
||||||
enc = kCFStringEncodingWindowsLatin2;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1251 :
|
|
||||||
enc =kCFStringEncodingWindowsCyrillic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1252 :
|
|
||||||
enc =kCFStringEncodingWindowsLatin1 ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1253 :
|
|
||||||
enc = kCFStringEncodingWindowsGreek;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1254 :
|
|
||||||
enc = kCFStringEncodingWindowsLatin5;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1255 :
|
|
||||||
enc =kCFStringEncodingWindowsHebrew ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1256 :
|
|
||||||
enc =kCFStringEncodingWindowsArabic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_CP1257 :
|
|
||||||
enc = kCFStringEncodingWindowsBalticRim;
|
|
||||||
break ;
|
|
||||||
#if 0
|
|
||||||
case wxFONTENCODING_UTF7 :
|
|
||||||
enc = CreateTextEncoding(kCFStringEncodingUnicodeDefault,0,kUnicodeUTF7Format) ;
|
|
||||||
#endif
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_UTF8 :
|
|
||||||
enc = kCFStringEncodingUTF8;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_EUC_JP :
|
|
||||||
enc = kCFStringEncodingEUC_JP;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_UTF16BE :
|
|
||||||
enc = kCFStringEncodingUTF16BE;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_UTF16LE :
|
|
||||||
enc = kCFStringEncodingUTF16LE;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_UTF32BE :
|
|
||||||
enc = kCFStringEncodingUTF32BE;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_UTF32LE :
|
|
||||||
enc = kCFStringEncodingUTF32LE;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case wxFONTENCODING_MACROMAN :
|
|
||||||
enc = kCFStringEncodingMacRoman ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACJAPANESE :
|
|
||||||
enc = kCFStringEncodingMacJapanese ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACCHINESETRAD :
|
|
||||||
enc = kCFStringEncodingMacChineseTrad ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACKOREAN :
|
|
||||||
enc = kCFStringEncodingMacKorean ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACARABIC :
|
|
||||||
enc = kCFStringEncodingMacArabic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACHEBREW :
|
|
||||||
enc = kCFStringEncodingMacHebrew ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACGREEK :
|
|
||||||
enc = kCFStringEncodingMacGreek ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACCYRILLIC :
|
|
||||||
enc = kCFStringEncodingMacCyrillic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACDEVANAGARI :
|
|
||||||
enc = kCFStringEncodingMacDevanagari ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACGURMUKHI :
|
|
||||||
enc = kCFStringEncodingMacGurmukhi ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACGUJARATI :
|
|
||||||
enc = kCFStringEncodingMacGujarati ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACORIYA :
|
|
||||||
enc = kCFStringEncodingMacOriya ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACBENGALI :
|
|
||||||
enc = kCFStringEncodingMacBengali ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACTAMIL :
|
|
||||||
enc = kCFStringEncodingMacTamil ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACTELUGU :
|
|
||||||
enc = kCFStringEncodingMacTelugu ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACKANNADA :
|
|
||||||
enc = kCFStringEncodingMacKannada ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACMALAJALAM :
|
|
||||||
enc = kCFStringEncodingMacMalayalam ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACSINHALESE :
|
|
||||||
enc = kCFStringEncodingMacSinhalese ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACBURMESE :
|
|
||||||
enc = kCFStringEncodingMacBurmese ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACKHMER :
|
|
||||||
enc = kCFStringEncodingMacKhmer ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACTHAI :
|
|
||||||
enc = kCFStringEncodingMacThai ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACLAOTIAN :
|
|
||||||
enc = kCFStringEncodingMacLaotian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACGEORGIAN :
|
|
||||||
enc = kCFStringEncodingMacGeorgian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACARMENIAN :
|
|
||||||
enc = kCFStringEncodingMacArmenian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACCHINESESIMP :
|
|
||||||
enc = kCFStringEncodingMacChineseSimp ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACTIBETAN :
|
|
||||||
enc = kCFStringEncodingMacTibetan ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACMONGOLIAN :
|
|
||||||
enc = kCFStringEncodingMacMongolian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACETHIOPIC :
|
|
||||||
enc = kCFStringEncodingMacEthiopic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACCENTRALEUR :
|
|
||||||
enc = kCFStringEncodingMacCentralEurRoman ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACVIATNAMESE :
|
|
||||||
enc = kCFStringEncodingMacVietnamese ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACARABICEXT :
|
|
||||||
enc = kCFStringEncodingMacExtArabic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACSYMBOL :
|
|
||||||
enc = kCFStringEncodingMacSymbol ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACDINGBATS :
|
|
||||||
enc = kCFStringEncodingMacDingbats ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACTURKISH :
|
|
||||||
enc = kCFStringEncodingMacTurkish ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACCROATIAN :
|
|
||||||
enc = kCFStringEncodingMacCroatian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACICELANDIC :
|
|
||||||
enc = kCFStringEncodingMacIcelandic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACROMANIAN :
|
|
||||||
enc = kCFStringEncodingMacRomanian ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACCELTIC :
|
|
||||||
enc = kCFStringEncodingMacCeltic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACGAELIC :
|
|
||||||
enc = kCFStringEncodingMacGaelic ;
|
|
||||||
break ;
|
|
||||||
case wxFONTENCODING_MACKEYBOARD :
|
|
||||||
enc = 41; /* kTextEncodingMacKeyboardGlyphs ; */
|
|
||||||
break ;
|
|
||||||
default : // to make gcc happy
|
|
||||||
break ;
|
|
||||||
};
|
|
||||||
return enc ;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxFontEncoding wxMacGetFontEncFromSystemEnc(wxUint32 encoding)
|
|
||||||
{
|
|
||||||
wxFontEncoding enc = wxFONTENCODING_DEFAULT ;
|
|
||||||
|
|
||||||
switch( encoding)
|
|
||||||
{
|
|
||||||
case kCFStringEncodingISOLatin1 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_1 ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin2 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_2;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin3 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_3 ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin4 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_4;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatinCyrillic :
|
|
||||||
enc = wxFONTENCODING_ISO8859_5;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatinArabic :
|
|
||||||
enc = wxFONTENCODING_ISO8859_6;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatinGreek :
|
|
||||||
enc = wxFONTENCODING_ISO8859_7;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatinHebrew :
|
|
||||||
enc = wxFONTENCODING_ISO8859_8;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin5 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_9;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin6 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_10;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin7 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_13;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin8 :
|
|
||||||
enc = wxFONTENCODING_ISO8859_14;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingISOLatin9 :
|
|
||||||
enc =wxFONTENCODING_ISO8859_15 ;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case kCFStringEncodingKOI8_R :
|
|
||||||
enc = wxFONTENCODING_KOI8;
|
|
||||||
break ;
|
|
||||||
/*
|
|
||||||
case :
|
|
||||||
enc = wxFONTENCODING_BULGARIAN;
|
|
||||||
break ;
|
|
||||||
*/
|
|
||||||
case kCFStringEncodingDOSLatinUS :
|
|
||||||
enc = wxFONTENCODING_CP437;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSLatin1 :
|
|
||||||
enc = wxFONTENCODING_CP850;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSLatin2 :
|
|
||||||
enc =wxFONTENCODING_CP852 ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSCyrillic :
|
|
||||||
enc = wxFONTENCODING_CP855;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSRussian :
|
|
||||||
enc = wxFONTENCODING_CP866;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSThai :
|
|
||||||
enc =wxFONTENCODING_CP874 ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSJapanese :
|
|
||||||
enc = wxFONTENCODING_CP932;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSChineseSimplif :
|
|
||||||
enc = wxFONTENCODING_CP936;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSKorean :
|
|
||||||
enc = wxFONTENCODING_CP949;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingDOSChineseTrad :
|
|
||||||
enc = wxFONTENCODING_CP950;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case kCFStringEncodingWindowsLatin2 :
|
|
||||||
enc = wxFONTENCODING_CP1250;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsCyrillic :
|
|
||||||
enc = wxFONTENCODING_CP1251;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsLatin1 :
|
|
||||||
enc = wxFONTENCODING_CP1252;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsGreek :
|
|
||||||
enc = wxFONTENCODING_CP1253;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsLatin5 :
|
|
||||||
enc = wxFONTENCODING_CP1254;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsHebrew :
|
|
||||||
enc = wxFONTENCODING_CP1255;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsArabic :
|
|
||||||
enc = wxFONTENCODING_CP1256;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingWindowsBalticRim :
|
|
||||||
enc =wxFONTENCODING_CP1257 ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingEUC_JP :
|
|
||||||
enc = wxFONTENCODING_EUC_JP;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case kCFStringEncodingUTF8 :
|
|
||||||
enc = wxFONTENCODING_UTF8;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingUTF16BE :
|
|
||||||
enc = wxFONTENCODING_UTF16BE;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingUTF16LE :
|
|
||||||
enc = wxFONTENCODING_UTF16LE;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingUTF32BE :
|
|
||||||
enc = wxFONTENCODING_UTF32BE;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingUTF32LE :
|
|
||||||
enc = wxFONTENCODING_UTF32LE;
|
|
||||||
break ;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
case wxFONTENCODING_UTF7 :
|
|
||||||
enc = CreateTextEncoding(kCFStringEncodingUnicodeDefault,0,kUnicodeUTF7Format) ;
|
|
||||||
break ;
|
|
||||||
#endif
|
|
||||||
case kCFStringEncodingMacRoman :
|
|
||||||
enc = wxFONTENCODING_MACROMAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacJapanese :
|
|
||||||
enc = wxFONTENCODING_MACJAPANESE ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacChineseTrad :
|
|
||||||
enc = wxFONTENCODING_MACCHINESETRAD ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacKorean :
|
|
||||||
enc = wxFONTENCODING_MACKOREAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacArabic :
|
|
||||||
enc =wxFONTENCODING_MACARABIC ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacHebrew :
|
|
||||||
enc = wxFONTENCODING_MACHEBREW ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacGreek :
|
|
||||||
enc = wxFONTENCODING_MACGREEK ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacCyrillic :
|
|
||||||
enc = wxFONTENCODING_MACCYRILLIC ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacDevanagari :
|
|
||||||
enc = wxFONTENCODING_MACDEVANAGARI ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacGurmukhi :
|
|
||||||
enc = wxFONTENCODING_MACGURMUKHI ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacGujarati :
|
|
||||||
enc = wxFONTENCODING_MACGUJARATI ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacOriya :
|
|
||||||
enc =wxFONTENCODING_MACORIYA ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacBengali :
|
|
||||||
enc =wxFONTENCODING_MACBENGALI ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacTamil :
|
|
||||||
enc = wxFONTENCODING_MACTAMIL ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacTelugu :
|
|
||||||
enc = wxFONTENCODING_MACTELUGU ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacKannada :
|
|
||||||
enc = wxFONTENCODING_MACKANNADA ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacMalayalam :
|
|
||||||
enc = wxFONTENCODING_MACMALAJALAM ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacSinhalese :
|
|
||||||
enc = wxFONTENCODING_MACSINHALESE ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacBurmese :
|
|
||||||
enc = wxFONTENCODING_MACBURMESE ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacKhmer :
|
|
||||||
enc = wxFONTENCODING_MACKHMER ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacThai :
|
|
||||||
enc = wxFONTENCODING_MACTHAI ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacLaotian :
|
|
||||||
enc = wxFONTENCODING_MACLAOTIAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacGeorgian :
|
|
||||||
enc = wxFONTENCODING_MACGEORGIAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacArmenian :
|
|
||||||
enc = wxFONTENCODING_MACARMENIAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacChineseSimp :
|
|
||||||
enc = wxFONTENCODING_MACCHINESESIMP ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacTibetan :
|
|
||||||
enc = wxFONTENCODING_MACTIBETAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacMongolian :
|
|
||||||
enc = wxFONTENCODING_MACMONGOLIAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacEthiopic :
|
|
||||||
enc = wxFONTENCODING_MACETHIOPIC ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacCentralEurRoman:
|
|
||||||
enc = wxFONTENCODING_MACCENTRALEUR ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacVietnamese:
|
|
||||||
enc = wxFONTENCODING_MACVIATNAMESE ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacExtArabic :
|
|
||||||
enc = wxFONTENCODING_MACARABICEXT ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacSymbol :
|
|
||||||
enc = wxFONTENCODING_MACSYMBOL ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacDingbats :
|
|
||||||
enc = wxFONTENCODING_MACDINGBATS ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacTurkish :
|
|
||||||
enc = wxFONTENCODING_MACTURKISH ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacCroatian :
|
|
||||||
enc = wxFONTENCODING_MACCROATIAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacIcelandic :
|
|
||||||
enc = wxFONTENCODING_MACICELANDIC ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacRomanian :
|
|
||||||
enc = wxFONTENCODING_MACROMANIAN ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacCeltic :
|
|
||||||
enc = wxFONTENCODING_MACCELTIC ;
|
|
||||||
break ;
|
|
||||||
case kCFStringEncodingMacGaelic :
|
|
||||||
enc = wxFONTENCODING_MACGAELIC ;
|
|
||||||
break ;
|
|
||||||
case 41 /* kTextEncodingMacKeyboardGlyphs */ :
|
|
||||||
enc = wxFONTENCODING_MACKEYBOARD ;
|
|
||||||
break ;
|
|
||||||
} ;
|
|
||||||
return enc ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// CFStringRefs
|
|
||||||
//
|
|
||||||
|
|
||||||
// converts this string into a core foundation string with optional pc 2 mac encoding
|
|
||||||
|
|
||||||
wxCFStringRef::wxCFStringRef( const wxString &st , wxFontEncoding WXUNUSED_IN_UNICODE(encoding) )
|
|
||||||
{
|
|
||||||
if (st.IsEmpty())
|
|
||||||
{
|
|
||||||
reset( wxCFRetain( CFSTR("") ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxString str = st ;
|
|
||||||
wxMacConvertNewlines13To10( &str ) ;
|
|
||||||
#if wxUSE_UNICODE
|
|
||||||
#if SIZEOF_WCHAR_T == 2
|
|
||||||
reset( CFStringCreateWithCharacters( kCFAllocatorDefault,
|
|
||||||
(UniChar*)str.wc_str() , str.Len() ) );
|
|
||||||
#else
|
|
||||||
wxMBConvUTF16 converter ;
|
|
||||||
size_t unicharbytes = converter.FromWChar( NULL , 0 , str.wc_str() , str.Length() ) ;
|
|
||||||
wxASSERT( unicharbytes != wxCONV_FAILED );
|
|
||||||
if ( unicharbytes == wxCONV_FAILED )
|
|
||||||
{
|
|
||||||
// create an empty string
|
|
||||||
reset( wxCFRetain( CFSTR("") ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// unicharbytes: number of bytes needed for UTF-16 encoded string (without terminating null)
|
|
||||||
// unichars: number of UTF-16 characters (without terminating null)
|
|
||||||
size_t unichars = unicharbytes / sizeof(UniChar) ;
|
|
||||||
UniChar *unibuf = new UniChar[ unichars ] ;
|
|
||||||
converter.FromWChar( (char*)unibuf , unicharbytes , str.wc_str() , str.Length() ) ;
|
|
||||||
reset( CFStringCreateWithCharacters( kCFAllocatorDefault , unibuf , unichars ) ) ;
|
|
||||||
delete[] unibuf ;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else // not wxUSE_UNICODE
|
|
||||||
reset( CFStringCreateWithCString( kCFAllocatorSystemDefault , str.c_str() ,
|
|
||||||
wxMacGetSystemEncFromFontEnc( encoding ) ) );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxCFStringRef::AsString(wxFontEncoding WXUNUSED_IN_UNICODE(encoding))
|
|
||||||
{
|
|
||||||
if ( !get() )
|
|
||||||
return wxEmptyString ;
|
|
||||||
|
|
||||||
Size cflen = CFStringGetLength( get() ) ;
|
|
||||||
size_t noChars ;
|
|
||||||
wxChar* buf = NULL ;
|
|
||||||
|
|
||||||
#if wxUSE_UNICODE
|
|
||||||
#if SIZEOF_WCHAR_T == 2
|
|
||||||
buf = new wxChar[ cflen + 1 ] ;
|
|
||||||
CFStringGetCharacters( get() , CFRangeMake( 0 , cflen ) , (UniChar*) buf ) ;
|
|
||||||
noChars = cflen ;
|
|
||||||
#else
|
|
||||||
UniChar* unibuf = new UniChar[ cflen + 1 ] ;
|
|
||||||
CFStringGetCharacters( get() , CFRangeMake( 0 , cflen ) , (UniChar*) unibuf ) ;
|
|
||||||
unibuf[cflen] = 0 ;
|
|
||||||
wxMBConvUTF16 converter ;
|
|
||||||
noChars = converter.MB2WC( NULL , (const char*)unibuf , 0 ) ;
|
|
||||||
wxASSERT_MSG( noChars != wxCONV_FAILED, _T("Unable to count the number of characters in this string!") );
|
|
||||||
buf = new wxChar[ noChars + 1 ] ;
|
|
||||||
noChars = converter.MB2WC( buf , (const char*)unibuf , noChars + 1 ) ;
|
|
||||||
wxASSERT_MSG( noChars != wxCONV_FAILED, _T("Conversion of string failed!") );
|
|
||||||
delete[] unibuf ;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
CFIndex cStrLen ;
|
|
||||||
CFStringGetBytes( get() , CFRangeMake(0, cflen) , wxMacGetSystemEncFromFontEnc( encoding ) ,
|
|
||||||
'?' , false , NULL , 0 , &cStrLen ) ;
|
|
||||||
buf = new wxChar[ cStrLen + 1 ] ;
|
|
||||||
CFStringGetBytes( get() , CFRangeMake(0, cflen) , wxMacGetSystemEncFromFontEnc( encoding ) ,
|
|
||||||
'?' , false , (unsigned char*) buf , cStrLen , &cStrLen) ;
|
|
||||||
noChars = cStrLen ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buf[noChars] = 0 ;
|
|
||||||
wxString result(buf) ;
|
|
||||||
delete[] buf ;
|
|
||||||
wxMacConvertNewlines10To13( &result);
|
|
||||||
return result ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// wxMacUniCharBuffer
|
|
||||||
//
|
|
||||||
|
|
||||||
wxMacUniCharBuffer::wxMacUniCharBuffer( const wxString &str )
|
|
||||||
{
|
|
||||||
m_chars = str.length() ;
|
|
||||||
m_ubuf = NULL ;
|
|
||||||
|
|
||||||
#if SIZEOF_WCHAR_T == 4
|
|
||||||
wxMBConvUTF16 converter ;
|
|
||||||
#if wxUSE_UNICODE
|
|
||||||
size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
|
|
||||||
m_ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
|
|
||||||
converter.WC2MB( (char*) m_ubuf , str.wc_str(), unicharlen + 2 ) ;
|
|
||||||
#else
|
|
||||||
const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
|
|
||||||
size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
|
|
||||||
m_ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
|
|
||||||
converter.WC2MB( (char*) m_ubuf , wchar.data() , unicharlen + 2 ) ;
|
|
||||||
#endif
|
|
||||||
m_chars = unicharlen / 2 ;
|
|
||||||
#else // SIZEOF_WCHAR_T is then 2
|
|
||||||
#if wxUSE_UNICODE
|
|
||||||
m_ubuf = malloc( m_chars * 2 + 2 ) ;
|
|
||||||
memcpy( m_ubuf , (UniChar*) str.wc_str() , m_chars * 2 + 2 ) ;
|
|
||||||
#else
|
|
||||||
wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
|
|
||||||
m_chars = wxWcslen( wchar.data() ) ;
|
|
||||||
m_ubuf = malloc( m_chars * 2 + 2 ) ;
|
|
||||||
memcpy( m_ubuf , (UniChar*) wchar.data() , m_chars * 2 + 2 ) ;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMacUniCharBuffer::~wxMacUniCharBuffer()
|
|
||||||
{
|
|
||||||
free( m_ubuf ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
UniCharPtr wxMacUniCharBuffer::GetBuffer()
|
|
||||||
{
|
|
||||||
return m_ubuf ;
|
|
||||||
}
|
|
||||||
|
|
||||||
UniCharCount wxMacUniCharBuffer::GetChars()
|
|
||||||
{
|
|
||||||
return m_chars ;
|
|
||||||
}
|
|
@@ -1,318 +0,0 @@
|
|||||||
/* -------------------------------------------------------------------------
|
|
||||||
* Project: GSocket (Generic Socket) for WX
|
|
||||||
* Name: src/mac/corefoundation/gsockosx.c
|
|
||||||
* Purpose: GSocket: Mac OS X mach-o part
|
|
||||||
* CVSID: $Id$
|
|
||||||
* Mac code by Brian Victor, February 2002. Email comments to bhv1@psu.edu
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#if wxUSE_SOCKETS
|
|
||||||
|
|
||||||
#include "wx/gsocket.h"
|
|
||||||
#include "wx/apptrait.h"
|
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Mac-specific data associated with each socket by GSocketCFManager
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class MacGSocketData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// default ctor creates the object in uninitialized state, use Initialize()
|
|
||||||
// later to make it usable
|
|
||||||
MacGSocketData()
|
|
||||||
{
|
|
||||||
m_socket = NULL;
|
|
||||||
m_source = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the data associated with the given socket
|
|
||||||
bool Initialize(GSocket *socket)
|
|
||||||
{
|
|
||||||
wxASSERT_MSG( !IsInitialized(), "shouldn't be called twice" );
|
|
||||||
|
|
||||||
// we need a valid Unix socket to create a CFSocket
|
|
||||||
if ( socket->m_fd < 0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CFSocketContext cont;
|
|
||||||
cont.version = 0; // this currently must be 0
|
|
||||||
cont.info = socket; // pointer passed to our callback
|
|
||||||
cont.retain = NULL; // no need to retain/release/copy the
|
|
||||||
cont.release = NULL; // socket pointer, so all callbacks
|
|
||||||
cont.copyDescription = NULL; // can be left NULL
|
|
||||||
|
|
||||||
m_socket = CFSocketCreateWithNative
|
|
||||||
(
|
|
||||||
NULL, // default allocator
|
|
||||||
socket->m_fd,
|
|
||||||
kCFSocketReadCallBack |
|
|
||||||
kCFSocketWriteCallBack |
|
|
||||||
kCFSocketConnectCallBack,
|
|
||||||
SocketCallback,
|
|
||||||
&cont
|
|
||||||
);
|
|
||||||
if ( !m_socket )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_source = CFSocketCreateRunLoopSource(NULL, m_socket, 0);
|
|
||||||
|
|
||||||
return m_source != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// free the objects created by Initialize()
|
|
||||||
~MacGSocketData()
|
|
||||||
{
|
|
||||||
if ( m_source )
|
|
||||||
CFRelease(m_source);
|
|
||||||
if ( m_socket )
|
|
||||||
CFRelease(m_socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if Initialize() had already been called successfully
|
|
||||||
bool IsInitialized() const { return m_source && m_socket; }
|
|
||||||
|
|
||||||
|
|
||||||
// accessors: should only be called if IsInitialized()
|
|
||||||
CFSocketRef GetSocket() const
|
|
||||||
{
|
|
||||||
wxASSERT( IsInitialized() );
|
|
||||||
|
|
||||||
return m_socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFRunLoopSourceRef GetSource() const
|
|
||||||
{
|
|
||||||
wxASSERT( IsInitialized() );
|
|
||||||
|
|
||||||
return m_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void SocketCallback(CFSocketRef WXUNUSED(s),
|
|
||||||
CFSocketCallBackType callbackType,
|
|
||||||
CFDataRef WXUNUSED(address),
|
|
||||||
const void* data,
|
|
||||||
void* info)
|
|
||||||
{
|
|
||||||
GSocket * const socket = wx_static_cast(GSocket *, info);
|
|
||||||
MacGSocketData * const
|
|
||||||
macdata = wx_static_cast(MacGSocketData *, socket->m_gui_dependent);
|
|
||||||
if ( !macdata )
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (callbackType)
|
|
||||||
{
|
|
||||||
case kCFSocketConnectCallBack:
|
|
||||||
wxASSERT(!socket->m_server);
|
|
||||||
// KH: If data is non-NULL, the connect failed, do not call Detected_Write,
|
|
||||||
// which will only end up creating a spurious connect event because the
|
|
||||||
// call to getsocketopt SO_ERROR inexplicably returns no error.
|
|
||||||
// The change in behavior cannot be traced to any particular commit or
|
|
||||||
// timeframe so I'm not sure what to think, but after so many hours,
|
|
||||||
// this seems to address the issue and it's time to move on.
|
|
||||||
if (data == NULL)
|
|
||||||
socket->Detected_Write();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kCFSocketReadCallBack:
|
|
||||||
socket->Detected_Read();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kCFSocketWriteCallBack:
|
|
||||||
socket->Detected_Write();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( "unexpected socket callback" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CFSocketRef m_socket;
|
|
||||||
CFRunLoopSourceRef m_source;
|
|
||||||
|
|
||||||
DECLARE_NO_COPY_CLASS(MacGSocketData);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// CoreFoundation implementation of GSocketManager
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class GSocketCFManager : public GSocketManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool OnInit();
|
|
||||||
virtual void OnExit();
|
|
||||||
|
|
||||||
virtual bool Init_Socket(GSocket *socket);
|
|
||||||
virtual void Destroy_Socket(GSocket *socket);
|
|
||||||
|
|
||||||
virtual void Install_Callback(GSocket *socket, GSocketEvent event);
|
|
||||||
virtual void Uninstall_Callback(GSocket *socket, GSocketEvent event);
|
|
||||||
|
|
||||||
virtual void Enable_Events(GSocket *socket);
|
|
||||||
virtual void Disable_Events(GSocket *socket);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// retrieve our custom data associated with the given socket
|
|
||||||
//
|
|
||||||
// this is a low level function, use GetInitializedData() instead if the
|
|
||||||
// data pointer should also be correctly initialized if it hadn't been done
|
|
||||||
// yet
|
|
||||||
//
|
|
||||||
// may return NULL if we hadn't created the data for this socket yet
|
|
||||||
MacGSocketData *GetData(GSocket *socket) const
|
|
||||||
{
|
|
||||||
return wx_static_cast(MacGSocketData *, socket->m_gui_dependent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the custom data pointer initializing it if it hadn't been done
|
|
||||||
// yet
|
|
||||||
//
|
|
||||||
// may return NULL if there is no associated data
|
|
||||||
MacGSocketData *GetInitializedData(GSocket *socket) const
|
|
||||||
{
|
|
||||||
MacGSocketData * const data = GetData(socket);
|
|
||||||
if ( data && !data->IsInitialized() )
|
|
||||||
{
|
|
||||||
if ( !data->Initialize(socket) )
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return CFSocket callback mask corresponding to the given event (the
|
|
||||||
// socket parameter is needed because some events are interpreted
|
|
||||||
// differently depending on whether they happen on a server or on a client
|
|
||||||
// socket)
|
|
||||||
static int GetCFCallback(GSocket *socket, GSocketEvent event);
|
|
||||||
|
|
||||||
|
|
||||||
// Sockets must use the event loop on the main thread so we store a
|
|
||||||
// reference to the main loop here in OnInit()
|
|
||||||
static CFRunLoopRef ms_mainRunLoop;
|
|
||||||
};
|
|
||||||
|
|
||||||
CFRunLoopRef GSocketCFManager::ms_mainRunLoop = NULL;
|
|
||||||
|
|
||||||
bool GSocketCFManager::OnInit()
|
|
||||||
{
|
|
||||||
// No need to store the main loop again
|
|
||||||
if (ms_mainRunLoop != NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Get the loop for the main thread so our events will actually fire.
|
|
||||||
// The common socket.cpp code will assert if initialize is called from a
|
|
||||||
// secondary thread, otherwise Mac would have the same problems as MSW
|
|
||||||
ms_mainRunLoop = CFRunLoopGetCurrent();
|
|
||||||
if ( !ms_mainRunLoop )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CFRetain(ms_mainRunLoop);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocketCFManager::OnExit()
|
|
||||||
{
|
|
||||||
// Release the reference count, and set the reference back to NULL
|
|
||||||
CFRelease(ms_mainRunLoop);
|
|
||||||
ms_mainRunLoop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GSocketCFManager::Init_Socket(GSocket *socket)
|
|
||||||
{
|
|
||||||
socket->m_gui_dependent = new MacGSocketData;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocketCFManager::Destroy_Socket(GSocket *socket)
|
|
||||||
{
|
|
||||||
MacGSocketData * const data = GetData(socket);
|
|
||||||
if ( data )
|
|
||||||
{
|
|
||||||
delete data;
|
|
||||||
socket->m_gui_dependent = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
int GSocketCFManager::GetCFCallback(GSocket *socket, GSocketEvent event)
|
|
||||||
{
|
|
||||||
switch ( event )
|
|
||||||
{
|
|
||||||
case GSOCK_CONNECTION:
|
|
||||||
return socket->m_server ? kCFSocketReadCallBack
|
|
||||||
: kCFSocketConnectCallBack;
|
|
||||||
|
|
||||||
case GSOCK_LOST:
|
|
||||||
case GSOCK_INPUT:
|
|
||||||
return kCFSocketReadCallBack;
|
|
||||||
|
|
||||||
case GSOCK_OUTPUT:
|
|
||||||
return kCFSocketWriteCallBack;
|
|
||||||
|
|
||||||
case GSOCK_MAX_EVENT:
|
|
||||||
wxFAIL_MSG( "invalid GSocketEvent" );
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( "unknown GSocketEvent" );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocketCFManager::Install_Callback(GSocket *socket, GSocketEvent event)
|
|
||||||
{
|
|
||||||
const MacGSocketData * const data = GetInitializedData(socket);
|
|
||||||
if ( !data )
|
|
||||||
return;
|
|
||||||
|
|
||||||
CFSocketEnableCallBacks(data->GetSocket(), GetCFCallback(socket, event));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocketCFManager::Uninstall_Callback(GSocket *socket, GSocketEvent event)
|
|
||||||
{
|
|
||||||
const MacGSocketData * const data = GetInitializedData(socket);
|
|
||||||
if ( !data )
|
|
||||||
return;
|
|
||||||
|
|
||||||
CFSocketDisableCallBacks(data->GetSocket(), GetCFCallback(socket, event));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocketCFManager::Enable_Events(GSocket *socket)
|
|
||||||
{
|
|
||||||
const MacGSocketData * const data = GetInitializedData(socket);
|
|
||||||
if ( !data )
|
|
||||||
return;
|
|
||||||
|
|
||||||
CFRunLoopAddSource(ms_mainRunLoop, data->GetSource(), kCFRunLoopCommonModes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GSocketCFManager::Disable_Events(GSocket *socket)
|
|
||||||
{
|
|
||||||
const MacGSocketData * const data = GetInitializedData(socket);
|
|
||||||
if ( !data )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// CFSocketInvalidate does CFRunLoopRemoveSource anyway
|
|
||||||
CFRunLoopRemoveSource(ms_mainRunLoop, data->GetSource(), kCFRunLoopCommonModes);
|
|
||||||
CFSocketInvalidate(data->GetSocket());
|
|
||||||
|
|
||||||
// CFSocketInvalidate has closed the socket so we want to make sure GSocket knows this
|
|
||||||
socket->m_fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
GSocketManager *wxAppTraits::GetSocketManager()
|
|
||||||
{
|
|
||||||
static GSocketCFManager s_manager;
|
|
||||||
|
|
||||||
return &s_manager;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // wxUSE_SOCKETS
|
|
@@ -1,741 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: src/mac/corefoundation/hid.cpp
|
|
||||||
// Purpose: DARWIN HID layer for WX Implementation
|
|
||||||
// Author: Ryan Norton
|
|
||||||
// Modified by:
|
|
||||||
// Created: 11/11/2003
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) Ryan Norton
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// ===========================================================================
|
|
||||||
// declarations
|
|
||||||
// ===========================================================================
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// headers
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//DARWIN _ONLY_
|
|
||||||
#ifdef __DARWIN__
|
|
||||||
|
|
||||||
#include "wx/mac/corefoundation/hid.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/dynarray.h"
|
|
||||||
#include "wx/string.h"
|
|
||||||
#include "wx/log.h"
|
|
||||||
#include "wx/utils.h"
|
|
||||||
#include "wx/module.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/mac/corefoundation/cfstring.h"
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// implementation
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxHIDDevice
|
|
||||||
//
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::Create
|
|
||||||
//
|
|
||||||
// nClass is the HID Page such as
|
|
||||||
// kHIDPage_GenericDesktop
|
|
||||||
// nType is the HID Usage such as
|
|
||||||
// kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard
|
|
||||||
// nDev is the device number to use
|
|
||||||
//
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
bool wxHIDDevice::Create (int nClass, int nType, int nDev)
|
|
||||||
{
|
|
||||||
//Create the mach port
|
|
||||||
if(IOMasterPort(bootstrap_port, &m_pPort) != kIOReturnSuccess)
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Could not create mach port"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Dictionary that will hold first
|
|
||||||
//the matching dictionary for determining which kind of devices we want,
|
|
||||||
//then later some registry properties from an iterator (see below)
|
|
||||||
//
|
|
||||||
//The call to IOServiceMatching filters down the
|
|
||||||
//the services we want to hid services (and also eats the
|
|
||||||
//dictionary up for us (consumes one reference))
|
|
||||||
CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey);
|
|
||||||
if(pDictionary == NULL)
|
|
||||||
{
|
|
||||||
wxLogSysError( _T("IOServiceMatching(kIOHIDDeviceKey) failed") );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Here we'll filter down the services to what we want
|
|
||||||
if (nType != -1)
|
|
||||||
{
|
|
||||||
CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault,
|
|
||||||
kCFNumberIntType, &nType);
|
|
||||||
CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType);
|
|
||||||
CFRelease(pType);
|
|
||||||
}
|
|
||||||
if (nClass != -1)
|
|
||||||
{
|
|
||||||
CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault,
|
|
||||||
kCFNumberIntType, &nClass);
|
|
||||||
CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass);
|
|
||||||
CFRelease(pClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Now get the maching services
|
|
||||||
io_iterator_t pIterator;
|
|
||||||
if( IOServiceGetMatchingServices(m_pPort,
|
|
||||||
pDictionary, &pIterator) != kIOReturnSuccess )
|
|
||||||
{
|
|
||||||
wxLogSysError(_T("No Matching HID Services"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Were there any devices matched?
|
|
||||||
if(pIterator == 0)
|
|
||||||
return false; // No devices found
|
|
||||||
|
|
||||||
//Now we iterate through them
|
|
||||||
io_object_t pObject;
|
|
||||||
while ( (pObject = IOIteratorNext(pIterator)) != 0)
|
|
||||||
{
|
|
||||||
if(--nDev != 0)
|
|
||||||
{
|
|
||||||
IOObjectRelease(pObject);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( IORegistryEntryCreateCFProperties
|
|
||||||
(
|
|
||||||
pObject,
|
|
||||||
&pDictionary,
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
kNilOptions
|
|
||||||
) != KERN_SUCCESS )
|
|
||||||
{
|
|
||||||
wxLogDebug(_T("IORegistryEntryCreateCFProperties failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Now we get the attributes of each "product" in the iterator
|
|
||||||
//
|
|
||||||
|
|
||||||
//Get [product] name
|
|
||||||
CFStringRef cfsProduct = (CFStringRef)
|
|
||||||
CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey));
|
|
||||||
m_szProductName =
|
|
||||||
wxCFStringRef( wxCFRetain(cfsProduct)
|
|
||||||
).AsString();
|
|
||||||
|
|
||||||
//Get the Product ID Key
|
|
||||||
CFNumberRef cfnProductId = (CFNumberRef)
|
|
||||||
CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey));
|
|
||||||
if (cfnProductId)
|
|
||||||
{
|
|
||||||
CFNumberGetValue(cfnProductId, kCFNumberIntType, &m_nProductId);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the Vendor ID Key
|
|
||||||
CFNumberRef cfnVendorId = (CFNumberRef)
|
|
||||||
CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey));
|
|
||||||
if (cfnVendorId)
|
|
||||||
{
|
|
||||||
CFNumberGetValue(cfnVendorId, kCFNumberIntType, &m_nManufacturerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// End attribute getting
|
|
||||||
//
|
|
||||||
|
|
||||||
//Create the interface (good grief - long function names!)
|
|
||||||
SInt32 nScore;
|
|
||||||
IOCFPlugInInterface** ppPlugin;
|
|
||||||
if(IOCreatePlugInInterfaceForService(pObject,
|
|
||||||
kIOHIDDeviceUserClientTypeID,
|
|
||||||
kIOCFPlugInInterfaceID, &ppPlugin,
|
|
||||||
&nScore) != kIOReturnSuccess)
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Could not create HID Interface for product"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Now, the final thing we can check before we fall back to asserts
|
|
||||||
//(because the dtor only checks if the device is ok, so if anything
|
|
||||||
//fails from now on the dtor will delete the device anyway, so we can't break from this).
|
|
||||||
|
|
||||||
//Get the HID interface from the plugin to the mach port
|
|
||||||
if((*ppPlugin)->QueryInterface(ppPlugin,
|
|
||||||
CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
|
|
||||||
(void**) &m_ppDevice) != S_OK)
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Could not get device interface from HID interface"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//release the plugin
|
|
||||||
(*ppPlugin)->Release(ppPlugin);
|
|
||||||
|
|
||||||
//open the HID interface...
|
|
||||||
if ( (*m_ppDevice)->open(m_ppDevice, 0) != S_OK )
|
|
||||||
wxLogDebug(_T("HID device: open failed"));
|
|
||||||
|
|
||||||
//
|
|
||||||
//Now the hard part - in order to scan things we need "cookies"
|
|
||||||
//
|
|
||||||
CFArrayRef cfaCookies = (CFArrayRef)CFDictionaryGetValue(pDictionary,
|
|
||||||
CFSTR(kIOHIDElementKey));
|
|
||||||
BuildCookies(cfaCookies);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
CFRelease(pDictionary);
|
|
||||||
IOObjectRelease(pObject);
|
|
||||||
|
|
||||||
//iterator cleanup
|
|
||||||
IOObjectRelease(pIterator);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//iterator cleanup
|
|
||||||
IOObjectRelease(pIterator);
|
|
||||||
|
|
||||||
return false; //no device
|
|
||||||
}//end Create()
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::GetCount [static]
|
|
||||||
//
|
|
||||||
// Obtains the number of devices on a system for a given HID Page (nClass)
|
|
||||||
// and HID Usage (nType).
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
size_t wxHIDDevice::GetCount (int nClass, int nType)
|
|
||||||
{
|
|
||||||
//Create the mach port
|
|
||||||
mach_port_t pPort;
|
|
||||||
if(IOMasterPort(bootstrap_port, &pPort) != kIOReturnSuccess)
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Could not create mach port"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Dictionary that will hold first
|
|
||||||
//the matching dictionary for determining which kind of devices we want,
|
|
||||||
//then later some registry properties from an iterator (see below)
|
|
||||||
CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey);
|
|
||||||
if(pDictionary == NULL)
|
|
||||||
{
|
|
||||||
wxLogSysError( _T("IOServiceMatching(kIOHIDDeviceKey) failed") );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Here we'll filter down the services to what we want
|
|
||||||
if (nType != -1)
|
|
||||||
{
|
|
||||||
CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault,
|
|
||||||
kCFNumberIntType, &nType);
|
|
||||||
CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType);
|
|
||||||
CFRelease(pType);
|
|
||||||
}
|
|
||||||
if (nClass != -1)
|
|
||||||
{
|
|
||||||
CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault,
|
|
||||||
kCFNumberIntType, &nClass);
|
|
||||||
CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass);
|
|
||||||
CFRelease(pClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Now get the maching services
|
|
||||||
io_iterator_t pIterator;
|
|
||||||
if( IOServiceGetMatchingServices(pPort,
|
|
||||||
pDictionary, &pIterator) != kIOReturnSuccess )
|
|
||||||
{
|
|
||||||
wxLogSysError(_T("No Matching HID Services"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If the iterator doesn't exist there are no devices :)
|
|
||||||
if ( !pIterator )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
//Now we iterate through them
|
|
||||||
size_t nCount = 0;
|
|
||||||
io_object_t pObject;
|
|
||||||
while ( (pObject = IOIteratorNext(pIterator)) != 0)
|
|
||||||
{
|
|
||||||
++nCount;
|
|
||||||
IOObjectRelease(pObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
IOObjectRelease(pIterator);
|
|
||||||
mach_port_deallocate(mach_task_self(), pPort);
|
|
||||||
|
|
||||||
return nCount;
|
|
||||||
}//end Create()
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::AddCookie
|
|
||||||
//
|
|
||||||
// Adds a cookie to the internal cookie array from a CFType
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void wxHIDDevice::AddCookie(CFTypeRef Data, int i)
|
|
||||||
{
|
|
||||||
CFNumberGetValue(
|
|
||||||
(CFNumberRef) CFDictionaryGetValue ( (CFDictionaryRef) Data
|
|
||||||
, CFSTR(kIOHIDElementCookieKey)
|
|
||||||
),
|
|
||||||
kCFNumberIntType,
|
|
||||||
&m_pCookies[i]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::AddCookieInQueue
|
|
||||||
//
|
|
||||||
// Adds a cookie to the internal cookie array from a CFType and additionally
|
|
||||||
// adds it to the internal HID Queue
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, int i)
|
|
||||||
{
|
|
||||||
//3rd Param flags (none yet)
|
|
||||||
AddCookie(Data, i);
|
|
||||||
if ( (*m_ppQueue)->addElement(m_ppQueue, m_pCookies[i], 0) != S_OK )
|
|
||||||
wxLogDebug(_T("HID device: adding element failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::InitCookies
|
|
||||||
//
|
|
||||||
// Create the internal cookie array, optionally creating a HID Queue
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void wxHIDDevice::InitCookies(size_t dwSize, bool bQueue)
|
|
||||||
{
|
|
||||||
m_pCookies = new IOHIDElementCookie[dwSize];
|
|
||||||
if (bQueue)
|
|
||||||
{
|
|
||||||
wxASSERT( m_ppQueue == NULL);
|
|
||||||
m_ppQueue = (*m_ppDevice)->allocQueue(m_ppDevice);
|
|
||||||
if ( !m_ppQueue )
|
|
||||||
{
|
|
||||||
wxLogDebug(_T("HID device: allocQueue failed"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Param 2, flags, none yet
|
|
||||||
if ( (*m_ppQueue)->create(m_ppQueue, 0, 512) != S_OK )
|
|
||||||
{
|
|
||||||
wxLogDebug(_T("HID device: create failed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//make sure that cookie array is clear
|
|
||||||
memset(m_pCookies, 0, sizeof(*m_pCookies) * dwSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::IsActive
|
|
||||||
//
|
|
||||||
// Returns true if a cookie of the device is active - for example if a key is
|
|
||||||
// held down, joystick button pressed, caps lock active, etc..
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
bool wxHIDDevice::IsActive(int nIndex)
|
|
||||||
{
|
|
||||||
if(!HasElement(nIndex))
|
|
||||||
{
|
|
||||||
//cookie at index does not exist - getElementValue
|
|
||||||
//could return true which would be incorrect so we
|
|
||||||
//check here
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IOHIDEventStruct Event;
|
|
||||||
(*m_ppDevice)->getElementValue(m_ppDevice, m_pCookies[nIndex], &Event);
|
|
||||||
return !!Event.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice::HasElement
|
|
||||||
//
|
|
||||||
// Returns true if the element in the internal cookie array exists
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
bool wxHIDDevice::HasElement(int nIndex)
|
|
||||||
{
|
|
||||||
return m_pCookies[nIndex] != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDDevice Destructor
|
|
||||||
//
|
|
||||||
// Frees all memory and objects from the structure
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
wxHIDDevice::~wxHIDDevice()
|
|
||||||
{
|
|
||||||
if (m_ppDevice != NULL)
|
|
||||||
{
|
|
||||||
if (m_ppQueue != NULL)
|
|
||||||
{
|
|
||||||
(*m_ppQueue)->stop(m_ppQueue);
|
|
||||||
(*m_ppQueue)->dispose(m_ppQueue);
|
|
||||||
(*m_ppQueue)->Release(m_ppQueue);
|
|
||||||
}
|
|
||||||
(*m_ppDevice)->close(m_ppDevice);
|
|
||||||
(*m_ppDevice)->Release(m_ppDevice);
|
|
||||||
mach_port_deallocate(mach_task_self(), m_pPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pCookies != NULL)
|
|
||||||
{
|
|
||||||
delete [] m_pCookies;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxHIDKeyboard
|
|
||||||
//
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
//There are no right shift, alt etc. in the wx headers yet so just sort
|
|
||||||
//of "define our own" for now
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
WXK_RSHIFT = 400,
|
|
||||||
WXK_RALT,
|
|
||||||
WXK_RCONTROL,
|
|
||||||
WXK_RMENU
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDKeyboard::GetCount [static]
|
|
||||||
//
|
|
||||||
// Get number of HID keyboards available
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
int wxHIDKeyboard::GetCount()
|
|
||||||
{
|
|
||||||
return wxHIDDevice::GetCount(kHIDPage_GenericDesktop,
|
|
||||||
kHIDUsage_GD_Keyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDKeyboard::Create
|
|
||||||
//
|
|
||||||
// Create the HID Keyboard
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
bool wxHIDKeyboard::Create(int nDev /* = 1*/)
|
|
||||||
{
|
|
||||||
return wxHIDDevice::Create(kHIDPage_GenericDesktop,
|
|
||||||
kHIDUsage_GD_Keyboard,
|
|
||||||
nDev);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDKeyboard::AddCookie
|
|
||||||
//
|
|
||||||
// Overloaded version of wxHIDDevice::AddCookie that simply does not
|
|
||||||
// add a cookie if a duplicate is found
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void wxHIDKeyboard::AddCookie(CFTypeRef Data, int i)
|
|
||||||
{
|
|
||||||
if(!HasElement(i))
|
|
||||||
wxHIDDevice::AddCookie(Data, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxHIDKeyboard::BuildCookies
|
|
||||||
//
|
|
||||||
// Callback from Create() to build the HID cookies for the internal cookie
|
|
||||||
// array
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
void wxHIDKeyboard::BuildCookies(CFArrayRef Array)
|
|
||||||
{
|
|
||||||
//Create internal cookie array
|
|
||||||
InitCookies(500);
|
|
||||||
|
|
||||||
//Begin recursing in array
|
|
||||||
DoBuildCookies(Array);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxHIDKeyboard::DoBuildCookies(CFArrayRef Array)
|
|
||||||
{
|
|
||||||
//Now go through each possible cookie
|
|
||||||
int i,
|
|
||||||
nUsage;
|
|
||||||
// bool bEOTriggered = false;
|
|
||||||
for (i = 0; i < CFArrayGetCount(Array); ++i)
|
|
||||||
{
|
|
||||||
const void* ref = CFDictionaryGetValue(
|
|
||||||
(CFDictionaryRef)CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementKey)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ref != NULL)
|
|
||||||
{
|
|
||||||
DoBuildCookies((CFArrayRef) ref);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the usage #
|
|
||||||
//
|
|
||||||
CFNumberGetValue(
|
|
||||||
(CFNumberRef)
|
|
||||||
CFDictionaryGetValue((CFDictionaryRef)
|
|
||||||
CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementUsageKey)
|
|
||||||
),
|
|
||||||
kCFNumberLongType,
|
|
||||||
&nUsage);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Now translate the usage # into a wx keycode
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// OK, this is strange - basically this kind of strange -
|
|
||||||
// Starting from 0xEO these elements (like shift) appear twice in
|
|
||||||
// the array! The ones at the end are bogus I guess - the funny part
|
|
||||||
// is that besides the fact that the ones at the front have a Unit
|
|
||||||
// and UnitExponent key with a value of 0 and a different cookie value,
|
|
||||||
// there is no discernable difference between the two...
|
|
||||||
//
|
|
||||||
// Will the real shift please stand up?
|
|
||||||
//
|
|
||||||
// Something to spend a support request on, if I had one, LOL.
|
|
||||||
//
|
|
||||||
//if(nUsage == 0xE0)
|
|
||||||
//{
|
|
||||||
// if(bEOTriggered)
|
|
||||||
// break;
|
|
||||||
// bEOTriggered = true;
|
|
||||||
//}
|
|
||||||
//Instead of that though we now just don't add duplicate keys
|
|
||||||
|
|
||||||
if (nUsage >= kHIDUsage_KeyboardA && nUsage <= kHIDUsage_KeyboardZ)
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), 'A' + (nUsage - kHIDUsage_KeyboardA) );
|
|
||||||
else if (nUsage >= kHIDUsage_Keyboard1 && nUsage <= kHIDUsage_Keyboard9)
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), '1' + (nUsage - kHIDUsage_Keyboard1) );
|
|
||||||
else if (nUsage >= kHIDUsage_KeyboardF1 && nUsage <= kHIDUsage_KeyboardF12)
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_F1 + (nUsage - kHIDUsage_KeyboardF1) );
|
|
||||||
else if (nUsage >= kHIDUsage_KeyboardF13 && nUsage <= kHIDUsage_KeyboardF24)
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_F13 + (nUsage - kHIDUsage_KeyboardF13) );
|
|
||||||
else if (nUsage >= kHIDUsage_Keypad1 && nUsage <= kHIDUsage_Keypad9)
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_NUMPAD1 + (nUsage - kHIDUsage_Keypad1) );
|
|
||||||
else switch (nUsage)
|
|
||||||
{
|
|
||||||
//0's (wx & ascii go 0-9, but HID goes 1-0)
|
|
||||||
case kHIDUsage_Keyboard0:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), '0');
|
|
||||||
break;
|
|
||||||
case kHIDUsage_Keypad0:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_NUMPAD0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Basic
|
|
||||||
case kHIDUsage_KeyboardReturnOrEnter:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_RETURN);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardEscape:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_ESCAPE);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardDeleteOrBackspace:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_BACK);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardTab:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_TAB);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardSpacebar:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_SPACE);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardPageUp:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_PAGEUP);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardEnd:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_END);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardPageDown:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_PAGEDOWN);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardRightArrow:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_RIGHT);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardLeftArrow:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_LEFT);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardDownArrow:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_DOWN);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardUpArrow:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i), WXK_UP);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//LEDS
|
|
||||||
case kHIDUsage_KeyboardCapsLock:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_CAPITAL);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeypadNumLock:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_NUMLOCK);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardScrollLock:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_SCROLL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Menu keys, Shift, other specials
|
|
||||||
case kHIDUsage_KeyboardLeftControl:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_CONTROL);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardLeftShift:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_SHIFT);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardLeftAlt:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_ALT);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardLeftGUI:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_MENU);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardRightControl:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RCONTROL);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardRightShift:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RSHIFT);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardRightAlt:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RALT);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_KeyboardRightGUI:
|
|
||||||
AddCookie(CFArrayGetValueAtIndex(Array, i),WXK_RMENU);
|
|
||||||
break;
|
|
||||||
|
|
||||||
//Default
|
|
||||||
default:
|
|
||||||
//not in wx keycodes - do nothing....
|
|
||||||
break;
|
|
||||||
} //end mightly long switch
|
|
||||||
} //end if the current element is not an array...
|
|
||||||
} //end for loop for Array
|
|
||||||
}//end buildcookies
|
|
||||||
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxHIDModule
|
|
||||||
//
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
class wxHIDModule : public wxModule
|
|
||||||
{
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxHIDModule)
|
|
||||||
|
|
||||||
public:
|
|
||||||
static wxArrayPtrVoid sm_keyboards;
|
|
||||||
virtual bool OnInit()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
virtual void OnExit()
|
|
||||||
{
|
|
||||||
for(size_t i = 0; i < sm_keyboards.GetCount(); ++i)
|
|
||||||
delete (wxHIDKeyboard*) sm_keyboards[i];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxHIDModule, wxModule)
|
|
||||||
|
|
||||||
wxArrayPtrVoid wxHIDModule::sm_keyboards;
|
|
||||||
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxGetKeyState()
|
|
||||||
//
|
|
||||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
bool wxGetKeyState (wxKeyCode key)
|
|
||||||
{
|
|
||||||
wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
|
|
||||||
WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
|
|
||||||
|
|
||||||
if (wxHIDModule::sm_keyboards.GetCount() == 0)
|
|
||||||
{
|
|
||||||
int nKeyboards = wxHIDKeyboard::GetCount();
|
|
||||||
|
|
||||||
for(int i = 1; i <= nKeyboards; ++i)
|
|
||||||
{
|
|
||||||
wxHIDKeyboard* keyboard = new wxHIDKeyboard();
|
|
||||||
if(keyboard->Create(i))
|
|
||||||
{
|
|
||||||
wxHIDModule::sm_keyboards.Add(keyboard);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete keyboard;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT_MSG(wxHIDModule::sm_keyboards.GetCount() != 0,
|
|
||||||
wxT("No keyboards found!"));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = 0; i < wxHIDModule::sm_keyboards.GetCount(); ++i)
|
|
||||||
{
|
|
||||||
wxHIDKeyboard* keyboard = (wxHIDKeyboard*)
|
|
||||||
wxHIDModule::sm_keyboards[i];
|
|
||||||
|
|
||||||
switch(key)
|
|
||||||
{
|
|
||||||
case WXK_SHIFT:
|
|
||||||
if( keyboard->IsActive(WXK_SHIFT) ||
|
|
||||||
keyboard->IsActive(WXK_RSHIFT) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WXK_ALT:
|
|
||||||
if( keyboard->IsActive(WXK_ALT) ||
|
|
||||||
keyboard->IsActive(WXK_RALT) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WXK_CONTROL:
|
|
||||||
if( keyboard->IsActive(WXK_CONTROL) ||
|
|
||||||
keyboard->IsActive(WXK_RCONTROL) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WXK_MENU:
|
|
||||||
if( keyboard->IsActive(WXK_MENU) ||
|
|
||||||
keyboard->IsActive(WXK_RMENU) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if( keyboard->IsActive(key) )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; //not down/error
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //__DARWIN__
|
|
@@ -1,905 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: src/mac/corefoundation/joystick.cpp
|
|
||||||
// Purpose: wxJoystick class
|
|
||||||
// Author: Ryan Norton
|
|
||||||
// Modified by:
|
|
||||||
// Created: 2/13/2005
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) Ryan Norton
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// DECLARATIONS
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Pre-compiled header stuff
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Guard
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//we only support HID on OSX (DARWIN), since it requires DARWIN...
|
|
||||||
#if wxUSE_JOYSTICK && wxUSE_THREADS
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Includes
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/log.h"
|
|
||||||
#include "wx/event.h" //joystick wxEvents
|
|
||||||
#include "wx/window.h" //for wxWindow to "capture" joystick
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/joystick.h" //...
|
|
||||||
#include "wx/thread.h" //wxThread for polling thread/ wxCriticalSection
|
|
||||||
|
|
||||||
//private headers
|
|
||||||
#include "wx/mac/corefoundation/hid.h" //private mac hid stuff
|
|
||||||
|
|
||||||
//mac headers
|
|
||||||
#include <CoreServices/CoreServices.h>
|
|
||||||
#include <mach/mach.h>
|
|
||||||
#include <mach/mach_time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Definitions/Enumerations
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define wxJS_MAX_AXES 10 /*max number of axes*/
|
|
||||||
#define wxJS_MAX_BUTTONS 40 /*max number of buttons*/
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
//These are positions within the cookie array
|
|
||||||
//in wxHIDJoystick that the cookies that store the axis' are
|
|
||||||
wxJS_AXIS_X = 40,
|
|
||||||
wxJS_AXIS_Y,
|
|
||||||
wxJS_AXIS_Z,
|
|
||||||
wxJS_AXIS_RUDDER,
|
|
||||||
wxJS_AXIS_U,
|
|
||||||
wxJS_AXIS_V,
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxHIDJoystick
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
class wxHIDJoystick : public wxHIDDevice
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
wxHIDJoystick();
|
|
||||||
virtual ~wxHIDJoystick();
|
|
||||||
|
|
||||||
bool Create(int nWhich);
|
|
||||||
virtual void BuildCookies(CFArrayRef Array);
|
|
||||||
void MakeCookies(CFArrayRef Array);
|
|
||||||
IOHIDElementCookie* GetCookies();
|
|
||||||
IOHIDQueueInterface** GetQueue();
|
|
||||||
|
|
||||||
int m_nXMax, m_nYMax, m_nZMax, m_nRudderMax, m_nUMax, m_nVMax,
|
|
||||||
m_nXMin, m_nYMin, m_nZMin, m_nRudderMin, m_nUMin, m_nVMin;
|
|
||||||
|
|
||||||
friend class wxJoystick;
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystickThread
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
class wxJoystickThread : public wxThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
wxJoystickThread(wxHIDJoystick* hid, int joystick);
|
|
||||||
void* Entry();
|
|
||||||
static void HIDCallback(void* target, IOReturn res, void* context, void* sender);
|
|
||||||
|
|
||||||
private:
|
|
||||||
wxHIDJoystick* m_hid;
|
|
||||||
int m_joystick;
|
|
||||||
wxPoint m_lastposition;
|
|
||||||
int m_axe[wxJS_MAX_AXES];
|
|
||||||
int m_buttons;
|
|
||||||
wxWindow* m_catchwin;
|
|
||||||
int m_polling;
|
|
||||||
|
|
||||||
friend class wxJoystick;
|
|
||||||
};
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// IMPLEMENTATION
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
// wxGetIntFromCFDictionary
|
|
||||||
//
|
|
||||||
// Helper function that gets a integer from a dictionary key
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
void wxGetIntFromCFDictionary(CFTypeRef cfDict, CFStringRef key, int* pOut)
|
|
||||||
{
|
|
||||||
CFNumberGetValue(
|
|
||||||
(CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) cfDict,
|
|
||||||
key),
|
|
||||||
kCFNumberIntType, pOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxJoystick
|
|
||||||
//
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick Constructor
|
|
||||||
//
|
|
||||||
// 1) Initializes member variables
|
|
||||||
// 2) Attempts to create the native HID joystick implementation - if none
|
|
||||||
// could be found (no joysticks, etc.) then it sets it to NULL
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
wxJoystick::wxJoystick(int joystick)
|
|
||||||
: m_joystick(joystick),
|
|
||||||
m_thread(NULL)
|
|
||||||
{
|
|
||||||
m_hid = new wxHIDJoystick();
|
|
||||||
|
|
||||||
if (m_hid->Create(m_joystick+1)) //wxHIDDevice is 1-based while this is 0
|
|
||||||
{
|
|
||||||
m_thread = new wxJoystickThread(m_hid, m_joystick);
|
|
||||||
m_thread->Create();
|
|
||||||
m_thread->Run();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete m_hid;
|
|
||||||
m_hid = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick Destructor
|
|
||||||
//
|
|
||||||
// Releases the capture of the thread, deletes it, and deletes
|
|
||||||
// the native implementation.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
wxJoystick::~wxJoystick()
|
|
||||||
{
|
|
||||||
ReleaseCapture();
|
|
||||||
if (m_thread)
|
|
||||||
m_thread->Delete(); // It's detached so it will delete itself
|
|
||||||
|
|
||||||
if (m_hid)
|
|
||||||
delete m_hid;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::Get[XXX]Position
|
|
||||||
//
|
|
||||||
// Returns the value of an axis that was polled from the thread. In the
|
|
||||||
// case of GetPosition returns the X and Y values in a wxPoint
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
wxPoint wxJoystick::GetPosition() const
|
|
||||||
{
|
|
||||||
wxPoint pos(wxDefaultPosition);
|
|
||||||
if (m_thread) pos = m_thread->m_lastposition;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
int wxJoystick::GetZPosition() const
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
return m_thread->m_axe[wxJS_AXIS_Z];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int wxJoystick::GetRudderPosition() const
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
return m_thread->m_axe[wxJS_AXIS_RUDDER];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int wxJoystick::GetUPosition() const
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
return m_thread->m_axe[wxJS_AXIS_U];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int wxJoystick::GetVPosition() const
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
return m_thread->m_axe[wxJS_AXIS_V];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::GetButtonState
|
|
||||||
//
|
|
||||||
// Returns the state of the buttons in a bitmask as dictated by the
|
|
||||||
// wx manual (the real work takes place in the thread, as always)
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetButtonState() const
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
return m_thread->m_buttons;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::IsOk
|
|
||||||
//
|
|
||||||
// Returns whether the joystick initialized successfully - in this case
|
|
||||||
// if the native implementation doesn't exist (in constructor)
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
bool wxJoystick::IsOk() const
|
|
||||||
{
|
|
||||||
return m_hid != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::Get[XXX](Id/Name)
|
|
||||||
//
|
|
||||||
// Simple accessors to the native HID implementation
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetManufacturerId() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nManufacturerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetProductId() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nProductId;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxJoystick::GetProductName() const
|
|
||||||
{
|
|
||||||
return m_hid->m_szProductName;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::GetNumberButtons
|
|
||||||
// wxJoystick::GetNumberAxes
|
|
||||||
//
|
|
||||||
// Queries the joystick for an active number of buttons/axes.
|
|
||||||
//
|
|
||||||
// In the native HID implementation, the cookies:
|
|
||||||
// 0-40 are the buttons of the joystick
|
|
||||||
// 40-50 are the axes of the joystick
|
|
||||||
//
|
|
||||||
// These just query the native HID implementation as above.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetNumberButtons() const
|
|
||||||
{
|
|
||||||
int nCount = 0;
|
|
||||||
|
|
||||||
for(int nIndex = 0; nIndex < 40; ++nIndex)
|
|
||||||
{
|
|
||||||
if(m_hid->HasElement(nIndex))
|
|
||||||
++nCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nCount;
|
|
||||||
}
|
|
||||||
int wxJoystick::GetNumberAxes() const
|
|
||||||
{
|
|
||||||
int nCount = 0;
|
|
||||||
|
|
||||||
for(int nIndex = 40; nIndex < 50; ++nIndex)
|
|
||||||
{
|
|
||||||
if(m_hid->HasElement(nIndex))
|
|
||||||
++nCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::GetNumberJoysticks
|
|
||||||
//
|
|
||||||
// Gets the number of joysticks on the system. In HID that
|
|
||||||
// is all devices with the kHIDUsage_GD_Joystick or kHIDUsage_GD_GamePad
|
|
||||||
// identifiers.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetNumberJoysticks()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick) +
|
|
||||||
wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::SetCapture
|
|
||||||
//
|
|
||||||
// Stops sending events from the thread to the window set in
|
|
||||||
// SetCapture and stops polling the joystick
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq)
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
{
|
|
||||||
m_thread->m_catchwin = win;
|
|
||||||
m_thread->m_polling = pollingFreq;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::ReleaseCapture
|
|
||||||
//
|
|
||||||
// Stops sending events from the thread to the window set in
|
|
||||||
// SetCapture and stops polling the joystick
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
bool wxJoystick::ReleaseCapture()
|
|
||||||
{
|
|
||||||
if (m_thread)
|
|
||||||
{
|
|
||||||
m_thread->m_catchwin = NULL;
|
|
||||||
m_thread->m_polling = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::Get[XXX]
|
|
||||||
//
|
|
||||||
// Gets the minimum and maximum values for each axis, returning 0 if the
|
|
||||||
// axis doesn't exist.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetXMin() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nXMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetYMin() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nYMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetZMin() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nZMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetRudderMin() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nRudderMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetUMin() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nUMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetVMin() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nVMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetXMax() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nXMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetYMax() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nYMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetZMax() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nZMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetRudderMax() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nRudderMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetUMax() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nUMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetVMax() const
|
|
||||||
{
|
|
||||||
return m_hid->m_nVMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::Get[XXX]
|
|
||||||
//
|
|
||||||
// Min/Max values for buttons, axes, etc.. Polling in this case is just
|
|
||||||
// what the linux port has.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetMaxButtons() const
|
|
||||||
{
|
|
||||||
return wxJS_MAX_BUTTONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetMaxAxes() const
|
|
||||||
{
|
|
||||||
return wxJS_MAX_AXES;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetPollingMin() const
|
|
||||||
{
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetPollingMax() const
|
|
||||||
{
|
|
||||||
return 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystick::Has[XXX]
|
|
||||||
//
|
|
||||||
// Just queries the native hid implementation if the cookie was found
|
|
||||||
// when enumerating the cookies of the joystick device
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
bool wxJoystick::HasZ() const
|
|
||||||
{
|
|
||||||
return m_hid->HasElement(wxJS_AXIS_Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxJoystick::HasRudder() const
|
|
||||||
{
|
|
||||||
return m_hid->HasElement(wxJS_AXIS_RUDDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxJoystick::HasU() const
|
|
||||||
{
|
|
||||||
return m_hid->HasElement(wxJS_AXIS_U);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxJoystick::HasV() const
|
|
||||||
{
|
|
||||||
return m_hid->HasElement(wxJS_AXIS_V);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// UNSUPPORTED
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
int wxJoystick::GetPOVPosition() const
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetPOVCTSPosition() const
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxJoystick::GetMovementThreshold() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxJoystick::SetMovementThreshold(int WXUNUSED(threshold))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxJoystick::HasPOV() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxJoystick::HasPOV4Dir() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxJoystick::HasPOVCTS() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxHIDJoystick
|
|
||||||
//
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxHIDJoystick ctor
|
|
||||||
//
|
|
||||||
// Initializes the min/max members
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
wxHIDJoystick::wxHIDJoystick() :
|
|
||||||
m_nXMax(0), m_nYMax(0), m_nZMax(0), m_nRudderMax(0), m_nUMax(0), m_nVMax(0),
|
|
||||||
m_nXMin(0), m_nYMin(0), m_nZMin(0), m_nRudderMin(0), m_nUMin(0), m_nVMin(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxHIDJoystick dtor
|
|
||||||
//
|
|
||||||
// Nothing...
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
wxHIDJoystick::~wxHIDJoystick()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxHIDJoystick::Create
|
|
||||||
//
|
|
||||||
// Creates the native HID device (joysticks are of either
|
|
||||||
// kHIDUsage_GD_Joystick or kHIDUsage_GD_GamePad)
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
bool wxHIDJoystick::Create(int nWhich)
|
|
||||||
{
|
|
||||||
int nJoysticks = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
|
||||||
|
|
||||||
if (nWhich <= nJoysticks)
|
|
||||||
return wxHIDDevice::Create(kHIDPage_GenericDesktop,
|
|
||||||
kHIDUsage_GD_Joystick,
|
|
||||||
nWhich);
|
|
||||||
else
|
|
||||||
nWhich -= nJoysticks;
|
|
||||||
|
|
||||||
int nGamePads = GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);
|
|
||||||
|
|
||||||
if (nWhich <= nGamePads)
|
|
||||||
return wxHIDDevice::Create(kHIDPage_GenericDesktop,
|
|
||||||
kHIDUsage_GD_GamePad,
|
|
||||||
nWhich);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxHIDJoystick::BuildCookies
|
|
||||||
// wxHIDJoystick::MakeCookies
|
|
||||||
//
|
|
||||||
// Sets up the cookies for the HID device (called from Create) - as
|
|
||||||
// mentioned 0-40 are the buttons and 40-50 are the axes.
|
|
||||||
//
|
|
||||||
// MakeCookies is just a recursive function for each array within
|
|
||||||
// BuildCookies.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
void wxHIDJoystick::BuildCookies(CFArrayRef Array)
|
|
||||||
{
|
|
||||||
InitCookies(50, true);
|
|
||||||
|
|
||||||
//
|
|
||||||
// I wasted two hours of my life on this line :(
|
|
||||||
// accidently removed it during some source cleaning...
|
|
||||||
//
|
|
||||||
MakeCookies(Array);
|
|
||||||
|
|
||||||
//paranoid debugging stuff
|
|
||||||
#if 0
|
|
||||||
for(int i = 0; i < 50; ++i)
|
|
||||||
wxPrintf(wxT("\nVAL #%i:[%i]"), i, m_pCookies[i]);
|
|
||||||
#endif
|
|
||||||
}//end buildcookies
|
|
||||||
|
|
||||||
void wxHIDJoystick::MakeCookies(CFArrayRef Array)
|
|
||||||
{
|
|
||||||
int i, nUsage, nPage;
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(Array); ++i)
|
|
||||||
{
|
|
||||||
const void* ref = CFDictionaryGetValue(
|
|
||||||
(CFDictionaryRef)CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementKey)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ref != NULL)
|
|
||||||
{
|
|
||||||
MakeCookies((CFArrayRef) ref);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CFNumberGetValue(
|
|
||||||
(CFNumberRef)
|
|
||||||
CFDictionaryGetValue(
|
|
||||||
(CFDictionaryRef) CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementUsageKey)
|
|
||||||
),
|
|
||||||
kCFNumberIntType,
|
|
||||||
&nUsage );
|
|
||||||
|
|
||||||
CFNumberGetValue(
|
|
||||||
(CFNumberRef)
|
|
||||||
CFDictionaryGetValue(
|
|
||||||
(CFDictionaryRef) CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementUsagePageKey)
|
|
||||||
),
|
|
||||||
kCFNumberIntType,
|
|
||||||
&nPage );
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
wxLogSysError(wxT("[%i][%i]"), nUsage, nPage);
|
|
||||||
#endif
|
|
||||||
if (nPage == kHIDPage_Button && nUsage <= 40)
|
|
||||||
AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), nUsage-1 );
|
|
||||||
else if (nPage == kHIDPage_GenericDesktop)
|
|
||||||
{
|
|
||||||
//axis...
|
|
||||||
switch(nUsage)
|
|
||||||
{
|
|
||||||
case kHIDUsage_GD_X:
|
|
||||||
AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_X);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMaxKey),
|
|
||||||
&m_nXMax);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMinKey),
|
|
||||||
&m_nXMin);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_GD_Y:
|
|
||||||
AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_Y);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMaxKey),
|
|
||||||
&m_nYMax);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMinKey),
|
|
||||||
&m_nYMin);
|
|
||||||
break;
|
|
||||||
case kHIDUsage_GD_Z:
|
|
||||||
AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_Z);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMaxKey),
|
|
||||||
&m_nZMax);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMinKey),
|
|
||||||
&m_nZMin);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder)
|
|
||||||
{
|
|
||||||
//rudder...
|
|
||||||
AddCookieInQueue(CFArrayGetValueAtIndex(Array, i), wxJS_AXIS_RUDDER );
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMaxKey),
|
|
||||||
&m_nRudderMax);
|
|
||||||
wxGetIntFromCFDictionary(CFArrayGetValueAtIndex(Array, i),
|
|
||||||
CFSTR(kIOHIDElementMinKey),
|
|
||||||
&m_nRudderMin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxHIDJoystick::Get[XXX]
|
|
||||||
//
|
|
||||||
// Simple accessors so that the HID callback and the thread procedure
|
|
||||||
// can access members from wxHIDDevice (our parent here).
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
IOHIDElementCookie* wxHIDJoystick::GetCookies()
|
|
||||||
{ return m_pCookies; }
|
|
||||||
IOHIDQueueInterface** wxHIDJoystick::GetQueue()
|
|
||||||
{ return m_ppQueue; }
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxJoystickThread
|
|
||||||
//
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystickThread Constructor
|
|
||||||
//
|
|
||||||
// Just initializes members
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
wxJoystickThread::wxJoystickThread(wxHIDJoystick* hid, int joystick)
|
|
||||||
: m_hid(hid),
|
|
||||||
m_joystick(joystick),
|
|
||||||
m_lastposition(127,127),
|
|
||||||
m_buttons(0),
|
|
||||||
m_catchwin(NULL),
|
|
||||||
m_polling(0)
|
|
||||||
{
|
|
||||||
memset(m_axe, 0, sizeof(int) * wxJS_MAX_AXES);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystickThread::Entry
|
|
||||||
//
|
|
||||||
// Thread procedure
|
|
||||||
//
|
|
||||||
// Runs a CFRunLoop for polling. Basically, it sets the HID queue to
|
|
||||||
// call wxJoystickThread::HIDCallback in the context of this thread
|
|
||||||
// when something changes on the device. It polls as long as the user
|
|
||||||
// wants, or a certain amount if the user wants to "block". Note that
|
|
||||||
// we don't actually block here since this is in a secondary thread.
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
void* wxJoystickThread::Entry()
|
|
||||||
{
|
|
||||||
CFRunLoopSourceRef pRLSource = NULL;
|
|
||||||
|
|
||||||
if ((*m_hid->GetQueue())->createAsyncEventSource(
|
|
||||||
m_hid->GetQueue(), &pRLSource) != kIOReturnSuccess )
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Couldn't create async event source"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT(pRLSource != NULL);
|
|
||||||
|
|
||||||
//attach runloop source to main run loop in thread
|
|
||||||
CFRunLoopRef pRL = CFRunLoopGetCurrent();
|
|
||||||
CFRunLoopAddSource(pRL, pRLSource, kCFRunLoopDefaultMode);
|
|
||||||
wxASSERT( CFRunLoopContainsSource(pRL, pRLSource, kCFRunLoopDefaultMode) );
|
|
||||||
|
|
||||||
|
|
||||||
if( (*m_hid->GetQueue())->setEventCallout(m_hid->GetQueue(),
|
|
||||||
wxJoystickThread::HIDCallback, this, this) != kIOReturnSuccess )
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Could not set event callout for queue"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (*m_hid->GetQueue())->start(m_hid->GetQueue()) != kIOReturnSuccess )
|
|
||||||
{
|
|
||||||
wxLogSysError(wxT("Could not start queue"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
double dTime;
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
if (TestDestroy())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (m_polling)
|
|
||||||
dTime = 0.0001 * m_polling;
|
|
||||||
else
|
|
||||||
dTime = 0.0001 * 10; // check at least every 10 msec in "blocking" case
|
|
||||||
|
|
||||||
//true just "handles and returns" - false forces it to stay the time
|
|
||||||
//amount
|
|
||||||
#if 1
|
|
||||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, true);
|
|
||||||
#else
|
|
||||||
IOReturn ret = NULL;
|
|
||||||
HIDCallback(this, ret, this, this);
|
|
||||||
Sleep(3000);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxASSERT( CFRunLoopContainsSource(pRL, pRLSource, kCFRunLoopDefaultMode) );
|
|
||||||
|
|
||||||
CFRunLoopRemoveSource(pRL, pRLSource, kCFRunLoopDefaultMode);
|
|
||||||
CFRelease(pRLSource);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// wxJoystickThread::HIDCallback (static)
|
|
||||||
//
|
|
||||||
// Callback for the native HID device when it recieves input.
|
|
||||||
//
|
|
||||||
// This is where the REAL dirty work gets done.
|
|
||||||
//
|
|
||||||
// 1) Loops through each event the queue has recieved
|
|
||||||
// 2) First, checks if the thread that is running the loop for
|
|
||||||
// the polling has ended - if so it breaks out
|
|
||||||
// 3) Next, it checks if there was an error getting this event from
|
|
||||||
// the HID queue, if there was, it logs an error and returns
|
|
||||||
// 4) Now it does the real dirty work by getting the button states
|
|
||||||
// from cookies 0-40 and axes positions/states from cookies 40-50
|
|
||||||
// in the native HID device by quering cookie values.
|
|
||||||
// 5) Sends the event to the polling window (if any)
|
|
||||||
// 6) Gets the next event and goes back to (1)
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
/*static*/ void wxJoystickThread::HIDCallback(void* WXUNUSED(target),
|
|
||||||
IOReturn WXUNUSED(res),
|
|
||||||
void* context,
|
|
||||||
void* WXUNUSED(sender))
|
|
||||||
{
|
|
||||||
IOHIDEventStruct hidevent;
|
|
||||||
AbsoluteTime bogustime = {0,0};
|
|
||||||
IOReturn ret;
|
|
||||||
wxJoystickThread* pThis = (wxJoystickThread*) context;
|
|
||||||
wxHIDJoystick* m_hid = pThis->m_hid;
|
|
||||||
|
|
||||||
//Get the "first" event from the queue
|
|
||||||
//bogustime tells it we don't care at what time to start
|
|
||||||
//where it gets the next from
|
|
||||||
ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
|
|
||||||
&hidevent, bogustime, 0);
|
|
||||||
|
|
||||||
while (ret != kIOReturnUnderrun)
|
|
||||||
{
|
|
||||||
if (pThis->TestDestroy())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(ret != kIOReturnSuccess)
|
|
||||||
{
|
|
||||||
wxLogSysError(wxString::Format(wxT("wxJoystick Error:[%i]"), ret));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxJoystickEvent wxevent;
|
|
||||||
|
|
||||||
//Find the cookie that changed
|
|
||||||
int nIndex = 0;
|
|
||||||
IOHIDElementCookie* pCookies = m_hid->GetCookies();
|
|
||||||
while(nIndex < 50)
|
|
||||||
{
|
|
||||||
if(hidevent.elementCookie == pCookies[nIndex])
|
|
||||||
break;
|
|
||||||
|
|
||||||
++nIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
//debugging stuff
|
|
||||||
#if 0
|
|
||||||
if(nIndex == 50)
|
|
||||||
{
|
|
||||||
wxLogSysError(wxString::Format(wxT("wxJoystick Out Of Bounds Error")));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//is the cookie a button?
|
|
||||||
if (nIndex < 40)
|
|
||||||
{
|
|
||||||
if (hidevent.value)
|
|
||||||
{
|
|
||||||
pThis->m_buttons |= (1 << nIndex);
|
|
||||||
wxevent.SetEventType(wxEVT_JOY_BUTTON_DOWN);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pThis->m_buttons &= ~(1 << nIndex);
|
|
||||||
wxevent.SetEventType(wxEVT_JOY_BUTTON_UP);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxevent.SetButtonChange(nIndex+1);
|
|
||||||
}
|
|
||||||
else if (nIndex == wxJS_AXIS_X)
|
|
||||||
{
|
|
||||||
pThis->m_lastposition.x = hidevent.value;
|
|
||||||
wxevent.SetEventType(wxEVT_JOY_MOVE);
|
|
||||||
pThis->m_axe[0] = hidevent.value;
|
|
||||||
}
|
|
||||||
else if (nIndex == wxJS_AXIS_Y)
|
|
||||||
{
|
|
||||||
pThis->m_lastposition.y = hidevent.value;
|
|
||||||
wxevent.SetEventType(wxEVT_JOY_MOVE);
|
|
||||||
pThis->m_axe[1] = hidevent.value;
|
|
||||||
}
|
|
||||||
else if (nIndex == wxJS_AXIS_Z)
|
|
||||||
{
|
|
||||||
wxevent.SetEventType(wxEVT_JOY_ZMOVE);
|
|
||||||
pThis->m_axe[2] = hidevent.value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
wxevent.SetEventType(wxEVT_JOY_MOVE);
|
|
||||||
|
|
||||||
Nanoseconds timestamp = AbsoluteToNanoseconds(hidevent.timestamp);
|
|
||||||
|
|
||||||
wxULongLong llTime(timestamp.hi, timestamp.lo);
|
|
||||||
|
|
||||||
llTime /= 1000000;
|
|
||||||
|
|
||||||
wxevent.SetTimestamp(llTime.GetValue());
|
|
||||||
wxevent.SetJoystick(pThis->m_joystick);
|
|
||||||
wxevent.SetButtonState(pThis->m_buttons);
|
|
||||||
wxevent.SetPosition(pThis->m_lastposition);
|
|
||||||
wxevent.SetZPosition(pThis->m_axe[2]);
|
|
||||||
wxevent.SetEventObject(pThis->m_catchwin);
|
|
||||||
|
|
||||||
if (pThis->m_catchwin)
|
|
||||||
pThis->m_catchwin->AddPendingEvent(wxevent);
|
|
||||||
|
|
||||||
ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(),
|
|
||||||
&hidevent, bogustime, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // wxUSE_JOYSTICK
|
|
@@ -1,217 +0,0 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: mac/corefoundation/stdpaths.cpp
|
|
||||||
// Purpose: wxStandardPaths implementation for CoreFoundation systems
|
|
||||||
// Author: David Elliott
|
|
||||||
// Modified by:
|
|
||||||
// Created: 2004-10-27
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) 2004 David Elliott <dfe@cox.net>
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// declarations
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// headers
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#if wxUSE_STDPATHS
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/intl.h"
|
|
||||||
#endif //ndef WX_PRECOMP
|
|
||||||
|
|
||||||
#include "wx/stdpaths.h"
|
|
||||||
#include "wx/filename.h"
|
|
||||||
#ifdef __WXMAC__
|
|
||||||
#include "wx/mac/private.h"
|
|
||||||
#endif
|
|
||||||
#include "wx/mac/corefoundation/cfstring.h"
|
|
||||||
|
|
||||||
#include <CoreFoundation/CFBundle.h>
|
|
||||||
#include <CoreFoundation/CFURL.h>
|
|
||||||
|
|
||||||
#define kDefaultPathStyle kCFURLPOSIXPathStyle
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// implementation
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxStandardPathsCF ctors/dtor
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wxStandardPathsCF::wxStandardPathsCF()
|
|
||||||
: m_bundle(CFBundleGetMainBundle())
|
|
||||||
{
|
|
||||||
CFRetain(m_bundle);
|
|
||||||
UseAppInfo(AppInfo_AppName | AppInfo_VendorName);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxStandardPathsCF::wxStandardPathsCF(wxCFBundleRef bundle)
|
|
||||||
: m_bundle(bundle)
|
|
||||||
{
|
|
||||||
CFRetain(m_bundle);
|
|
||||||
UseAppInfo(AppInfo_AppName | AppInfo_VendorName);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxStandardPathsCF::~wxStandardPathsCF()
|
|
||||||
{
|
|
||||||
CFRelease(m_bundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxStandardPathsCF Mac-specific methods
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void wxStandardPathsCF::SetBundle(wxCFBundleRef bundle)
|
|
||||||
{
|
|
||||||
CFRetain(bundle);
|
|
||||||
CFRelease(m_bundle);
|
|
||||||
m_bundle = bundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// generic functions in terms of which the other ones are implemented
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static wxString BundleRelativeURLToPath(CFURLRef relativeURL)
|
|
||||||
{
|
|
||||||
CFURLRef absoluteURL = CFURLCopyAbsoluteURL(relativeURL);
|
|
||||||
wxCHECK_MSG(absoluteURL, wxEmptyString, wxT("Failed to resolve relative URL to absolute URL"));
|
|
||||||
CFStringRef cfStrPath = CFURLCopyFileSystemPath(absoluteURL,kDefaultPathStyle);
|
|
||||||
CFRelease(absoluteURL);
|
|
||||||
return wxCFStringRef(cfStrPath).AsString(wxLocale::GetSystemEncoding());
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetFromFunc(wxCFURLRef (*func)(wxCFBundleRef)) const
|
|
||||||
{
|
|
||||||
wxCHECK_MSG(m_bundle, wxEmptyString,
|
|
||||||
wxT("wxStandardPaths for CoreFoundation only works with bundled apps"));
|
|
||||||
CFURLRef relativeURL = (*func)(m_bundle);
|
|
||||||
wxCHECK_MSG(relativeURL, wxEmptyString, wxT("Couldn't get URL"));
|
|
||||||
wxString ret(BundleRelativeURLToPath(relativeURL));
|
|
||||||
CFRelease(relativeURL);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetDocumentsDir() const
|
|
||||||
{
|
|
||||||
#if defined( __WXMAC__ ) && !defined(__WXOSX_IPHONE__)
|
|
||||||
return wxMacFindFolderNoSeparator
|
|
||||||
(
|
|
||||||
kUserDomain,
|
|
||||||
kDocumentsFolderType,
|
|
||||||
kCreateFolder
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
return wxFileName::GetHomeDir() + wxT("/Documents");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxStandardPathsCF public API
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetConfigDir() const
|
|
||||||
{
|
|
||||||
#if defined( __WXMAC__ ) && !defined(__WXOSX_IPHONE__)
|
|
||||||
return wxMacFindFolder((short)kLocalDomain, kPreferencesFolderType, kCreateFolder);
|
|
||||||
#else
|
|
||||||
return wxT("/Library/Preferences");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetUserConfigDir() const
|
|
||||||
{
|
|
||||||
#if defined( __WXMAC__ ) && !defined(__WXOSX_IPHONE__)
|
|
||||||
return wxMacFindFolder((short)kUserDomain, kPreferencesFolderType, kCreateFolder);
|
|
||||||
#else
|
|
||||||
return wxFileName::GetHomeDir() + wxT("/Library/Preferences");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetDataDir() const
|
|
||||||
{
|
|
||||||
return GetFromFunc(CFBundleCopySharedSupportURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetExecutablePath() const
|
|
||||||
{
|
|
||||||
#ifdef __WXMAC__
|
|
||||||
#if 1
|
|
||||||
return GetFromFunc(CFBundleCopyBundleURL);
|
|
||||||
#else
|
|
||||||
// TODO remove if cf implementation ok
|
|
||||||
ProcessInfoRec processinfo;
|
|
||||||
ProcessSerialNumber procno ;
|
|
||||||
#ifdef __LP64__
|
|
||||||
FSRef fsRef;
|
|
||||||
#else
|
|
||||||
FSSpec fsSpec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
procno.highLongOfPSN = 0 ;
|
|
||||||
procno.lowLongOfPSN = kCurrentProcess ;
|
|
||||||
processinfo.processInfoLength = sizeof(ProcessInfoRec);
|
|
||||||
processinfo.processName = NULL;
|
|
||||||
#ifdef __LP64__
|
|
||||||
processinfo.processAppRef = &fsRef;
|
|
||||||
#else
|
|
||||||
processinfo.processAppSpec = &fsSpec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GetProcessInformation( &procno , &processinfo ) ;
|
|
||||||
#ifdef __LP64__
|
|
||||||
return wxMacFSRefToPath(&fsRef);
|
|
||||||
#else
|
|
||||||
return wxMacFSSpec2MacFilename(&fsSpec);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
return wxStandardPathsBase::GetExecutablePath();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetLocalDataDir() const
|
|
||||||
{
|
|
||||||
#if defined( __WXMAC__ ) && !defined(__WXOSX_IPHONE__)
|
|
||||||
return AppendAppInfo(wxMacFindFolder((short)kLocalDomain, kApplicationSupportFolderType, kCreateFolder));
|
|
||||||
#else
|
|
||||||
return AppendAppInfo(wxT("/Library/Application Support"));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetUserDataDir() const
|
|
||||||
{
|
|
||||||
#if defined( __WXMAC__ ) && !defined(__WXOSX_IPHONE__)
|
|
||||||
return AppendAppInfo(wxMacFindFolder((short)kUserDomain, kApplicationSupportFolderType, kCreateFolder));
|
|
||||||
#else
|
|
||||||
return AppendAppInfo(wxFileName::GetHomeDir() + _T("/Library/Application Support"));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetPluginsDir() const
|
|
||||||
{
|
|
||||||
return GetFromFunc(CFBundleCopyBuiltInPlugInsURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxStandardPathsCF::GetResourcesDir() const
|
|
||||||
{
|
|
||||||
return GetFromFunc(CFBundleCopyResourcesDirectoryURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString
|
|
||||||
wxStandardPathsCF::GetLocalizedResourcesDir(const wxString& lang,
|
|
||||||
ResourceCat category) const
|
|
||||||
{
|
|
||||||
return wxStandardPathsBase::
|
|
||||||
GetLocalizedResourcesDir(lang, category) + _T(".lproj");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // wxUSE_STDPATHS
|
|
@@ -1,228 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: src/mac/corefoundation/strconv.cpp
|
|
||||||
// Purpose: Unicode conversion classes
|
|
||||||
// Author: David Elliott
|
|
||||||
// Modified by:
|
|
||||||
// Created: 2007-07-06
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) 2007 David Elliott
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/string.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wx/strconv.h"
|
|
||||||
#include "wx/fontmap.h"
|
|
||||||
|
|
||||||
#ifdef __DARWIN__
|
|
||||||
|
|
||||||
#include "wx/mac/corefoundation/private/strconv_cf.h"
|
|
||||||
#include "wx/mac/corefoundation/cfref.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// CoreFoundation conversion classes
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
/* Provide factory functions for unit tests. Not in any header. Do not
|
|
||||||
* assume ABI compatibility even within a given wxWidgets release.
|
|
||||||
*/
|
|
||||||
|
|
||||||
WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf( const char* name)
|
|
||||||
{
|
|
||||||
wxMBConv_cf *result = new wxMBConv_cf(name);
|
|
||||||
if(!result->IsOk())
|
|
||||||
{
|
|
||||||
delete result;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
|
|
||||||
{
|
|
||||||
wxMBConv_cf *result = new wxMBConv_cf(encoding);
|
|
||||||
if(!result->IsOk())
|
|
||||||
{
|
|
||||||
delete result;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide a constant for the wchat_t encoding used by the host platform.
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
static const CFStringEncoding wxCFStringEncodingWcharT = kCFStringEncodingUTF32BE;
|
|
||||||
#else
|
|
||||||
static const CFStringEncoding wxCFStringEncodingWcharT = kCFStringEncodingUTF32LE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t wxMBConv_cf::ToWChar(wchar_t * dst, size_t dstSize, const char * src, size_t srcSize) const
|
|
||||||
{
|
|
||||||
wxCHECK(src, wxCONV_FAILED);
|
|
||||||
|
|
||||||
/* NOTE: This is wrong if the source encoding has an element size
|
|
||||||
* other than char (e.g. it's kCFStringEncodingUnicode)
|
|
||||||
* If the user specifies it, it's presumably right though.
|
|
||||||
* Right now we don't support UTF-16 in anyway since wx can do a better job.
|
|
||||||
*/
|
|
||||||
if(srcSize == wxNO_LEN)
|
|
||||||
srcSize = strlen(src) + 1;
|
|
||||||
|
|
||||||
// First create the temporary CFString
|
|
||||||
wxCFRef<CFStringRef> theString( CFStringCreateWithBytes (
|
|
||||||
NULL, //the allocator
|
|
||||||
(const UInt8*)src,
|
|
||||||
srcSize,
|
|
||||||
m_encoding,
|
|
||||||
false //no BOM/external representation
|
|
||||||
));
|
|
||||||
|
|
||||||
wxCHECK(theString != NULL, wxCONV_FAILED);
|
|
||||||
|
|
||||||
/* NOTE: The string content includes the NULL element if the source string did
|
|
||||||
* That means we have to do nothing special because the destination will have
|
|
||||||
* the NULL element iff the source did and the NULL element will be included
|
|
||||||
* in the count iff it was included in the source count.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* If we're compiling against Tiger headers we can support direct conversion
|
|
||||||
* to UTF32. If we are then run against a pre-Tiger system, the encoding
|
|
||||||
* won't be available so we'll defer to the string->UTF-16->UTF-32 conversion.
|
|
||||||
*/
|
|
||||||
if(CFStringIsEncodingAvailable(wxCFStringEncodingWcharT))
|
|
||||||
{
|
|
||||||
CFRange fullStringRange = CFRangeMake(0, CFStringGetLength(theString));
|
|
||||||
CFIndex usedBufLen;
|
|
||||||
|
|
||||||
CFIndex charsConverted = CFStringGetBytes(
|
|
||||||
theString,
|
|
||||||
fullStringRange,
|
|
||||||
wxCFStringEncodingWcharT,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
// if dstSize is 0 then pass NULL to get required length in usedBufLen
|
|
||||||
dstSize != 0?(UInt8*)dst:NULL,
|
|
||||||
dstSize * sizeof(wchar_t),
|
|
||||||
&usedBufLen);
|
|
||||||
|
|
||||||
// charsConverted is > 0 iff conversion succeeded
|
|
||||||
if(charsConverted <= 0)
|
|
||||||
return wxCONV_FAILED;
|
|
||||||
|
|
||||||
/* usedBufLen is the number of bytes written, so we divide by
|
|
||||||
* sizeof(wchar_t) to get the number of elements written.
|
|
||||||
*/
|
|
||||||
wxASSERT( (usedBufLen % sizeof(wchar_t)) == 0 );
|
|
||||||
|
|
||||||
// CFStringGetBytes does exactly the right thing when buffer
|
|
||||||
// pointer is NULL and returns the number of bytes required
|
|
||||||
return usedBufLen / sizeof(wchar_t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// NOTE: Includes NULL iff source did
|
|
||||||
/* NOTE: This is an approximation. The eventual UTF-32 will
|
|
||||||
* possibly have less elements but certainly not more.
|
|
||||||
*/
|
|
||||||
size_t returnSize = CFStringGetLength(theString);
|
|
||||||
|
|
||||||
if (dstSize == 0 || dst == NULL)
|
|
||||||
{
|
|
||||||
return returnSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the entire string.. too hard to figure out how many UTF-16 we'd need
|
|
||||||
// for an undersized UTF-32 destination buffer.
|
|
||||||
CFRange fullStringRange = CFRangeMake(0, CFStringGetLength(theString));
|
|
||||||
UniChar *szUniCharBuffer = new UniChar[fullStringRange.length];
|
|
||||||
|
|
||||||
CFStringGetCharacters(theString, fullStringRange, szUniCharBuffer);
|
|
||||||
|
|
||||||
wxMBConvUTF16 converter;
|
|
||||||
returnSize = converter.ToWChar( dst, dstSize, (const char*)szUniCharBuffer, fullStringRange.length );
|
|
||||||
delete [] szUniCharBuffer;
|
|
||||||
|
|
||||||
return returnSize;
|
|
||||||
}
|
|
||||||
// NOTREACHED
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t wxMBConv_cf::FromWChar(char *dst, size_t dstSize, const wchar_t *src, size_t srcSize) const
|
|
||||||
{
|
|
||||||
wxCHECK(src, wxCONV_FAILED);
|
|
||||||
|
|
||||||
if(srcSize == wxNO_LEN)
|
|
||||||
srcSize = wxStrlen(src) + 1;
|
|
||||||
|
|
||||||
// Temporary CFString
|
|
||||||
wxCFRef<CFStringRef> theString;
|
|
||||||
|
|
||||||
/* If we're compiling against Tiger headers we can support direct conversion
|
|
||||||
* from UTF32. If we are then run against a pre-Tiger system, the encoding
|
|
||||||
* won't be available so we'll defer to the UTF-32->UTF-16->string conversion.
|
|
||||||
*/
|
|
||||||
if(CFStringIsEncodingAvailable(wxCFStringEncodingWcharT))
|
|
||||||
{
|
|
||||||
theString = wxCFRef<CFStringRef>(CFStringCreateWithBytes(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
(UInt8*)src,
|
|
||||||
srcSize * sizeof(wchar_t),
|
|
||||||
wxCFStringEncodingWcharT,
|
|
||||||
false));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxMBConvUTF16 converter;
|
|
||||||
size_t cbUniBuffer = converter.FromWChar( NULL, 0, src, srcSize );
|
|
||||||
wxASSERT(cbUniBuffer % sizeof(UniChar));
|
|
||||||
|
|
||||||
// Will be free'd by kCFAllocatorMalloc when CFString is released
|
|
||||||
UniChar *tmpUniBuffer = (UniChar*)malloc(cbUniBuffer);
|
|
||||||
|
|
||||||
cbUniBuffer = converter.FromWChar( (char*) tmpUniBuffer, cbUniBuffer, src, srcSize );
|
|
||||||
wxASSERT(cbUniBuffer % sizeof(UniChar));
|
|
||||||
|
|
||||||
theString = wxCFRef<CFStringRef>(CFStringCreateWithCharactersNoCopy(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
tmpUniBuffer,
|
|
||||||
cbUniBuffer / sizeof(UniChar),
|
|
||||||
kCFAllocatorMalloc
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
wxCHECK(theString != NULL, wxCONV_FAILED);
|
|
||||||
|
|
||||||
CFIndex usedBufLen;
|
|
||||||
|
|
||||||
CFIndex charsConverted = CFStringGetBytes(
|
|
||||||
theString,
|
|
||||||
CFRangeMake(0, CFStringGetLength(theString)),
|
|
||||||
m_encoding,
|
|
||||||
0, // FAIL on unconvertible characters
|
|
||||||
false, // not an external representation
|
|
||||||
// if dstSize is 0 then pass NULL to get required length in usedBufLen
|
|
||||||
(dstSize != 0)?(UInt8*)dst:NULL,
|
|
||||||
dstSize,
|
|
||||||
&usedBufLen
|
|
||||||
);
|
|
||||||
|
|
||||||
// charsConverted is > 0 iff conversion succeeded
|
|
||||||
if(charsConverted <= 0)
|
|
||||||
return wxCONV_FAILED;
|
|
||||||
|
|
||||||
return usedBufLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __DARWIN__
|
|
||||||
|
|
||||||
|
|
@@ -1,229 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: mac/corefoundation/utilsexc_base.cpp
|
|
||||||
// Purpose: wxMacLaunch
|
|
||||||
// Author: Ryan Norton
|
|
||||||
// Modified by:
|
|
||||||
// Created: 2005-06-21
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) Ryan Norton
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
// Notes: Source was originally in utilsexc_cf.cpp,1.6 then moved
|
|
||||||
// to totally unrelated hid.cpp,1.8.
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// DECLARATIONS
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Pre-compiled header stuff
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
// WX includes
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/string.h"
|
|
||||||
#include "wx/log.h"
|
|
||||||
#include "wx/intl.h"
|
|
||||||
#include "wx/utils.h"
|
|
||||||
#include "wx/wxcrt.h"
|
|
||||||
#endif // WX_PRECOMP
|
|
||||||
|
|
||||||
// Mac Includes
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#ifndef __WXOSX_IPHONE__
|
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// More WX Includes
|
|
||||||
#include "wx/filename.h"
|
|
||||||
#include "wx/mac/corefoundation/cfstring.h"
|
|
||||||
|
|
||||||
// Default path style
|
|
||||||
#define kDefaultPathStyle kCFURLPOSIXPathStyle
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
// IMPLEMENTATION
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
//
|
|
||||||
// wxMacLaunch
|
|
||||||
//
|
|
||||||
// argv is the command line split up, with the application path first
|
|
||||||
// flags are the flags from wxExecute
|
|
||||||
// process is the process passed from wxExecute for pipe streams etc.
|
|
||||||
// returns -1 on error for wxEXEC_SYNC and 0 on error for wxEXEC_ASYNC
|
|
||||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
bool wxMacLaunch(char **argv)
|
|
||||||
{
|
|
||||||
// Obtains the number of arguments for determining the size of
|
|
||||||
// the CFArray used to hold them
|
|
||||||
CFIndex cfiCount = 0;
|
|
||||||
for(char** argvcopy = argv; *argvcopy != NULL ; ++argvcopy)
|
|
||||||
{
|
|
||||||
++cfiCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is not a single argument then there is no application
|
|
||||||
// to launch
|
|
||||||
if(cfiCount == 0)
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("wxMacLaunch No file to launch!"));
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path to bundle
|
|
||||||
wxString path = *argv++;
|
|
||||||
|
|
||||||
// Create a CFURL for the application path
|
|
||||||
// Created this way because we are opening a bundle which is a directory
|
|
||||||
CFURLRef cfurlApp =
|
|
||||||
CFURLCreateWithFileSystemPath(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
wxCFStringRef(path),
|
|
||||||
kDefaultPathStyle,
|
|
||||||
true); //false == not a directory
|
|
||||||
|
|
||||||
// Check for error from the CFURL
|
|
||||||
if(!cfurlApp)
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("wxMacLaunch Can't open path: %s"), path.c_str());
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a CFBundle from the CFURL created earlier
|
|
||||||
CFBundleRef cfbApp = CFBundleCreate(kCFAllocatorDefault, cfurlApp);
|
|
||||||
|
|
||||||
// Check to see if CFBundleCreate returned an error,
|
|
||||||
// and if it did this was an invalid bundle or not a bundle
|
|
||||||
// at all (maybe a simple directory etc.)
|
|
||||||
if(!cfbApp)
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("wxMacLaunch Bad bundle: %s"), path.c_str());
|
|
||||||
CFRelease(cfurlApp);
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the bundle type and make sure its an 'APPL' bundle
|
|
||||||
// Otherwise we're dealing with something else here...
|
|
||||||
UInt32 dwBundleType, dwBundleCreator;
|
|
||||||
CFBundleGetPackageInfo(cfbApp, &dwBundleType, &dwBundleCreator);
|
|
||||||
if(dwBundleType != 'APPL')
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("wxMacLaunch Not an APPL bundle: %s"), path.c_str());
|
|
||||||
CFRelease(cfbApp);
|
|
||||||
CFRelease(cfurlApp);
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a CFArray for dealing with the command line
|
|
||||||
// arguments to the bundle
|
|
||||||
CFMutableArrayRef cfaFiles = CFArrayCreateMutable(kCFAllocatorDefault,
|
|
||||||
cfiCount-1, &kCFTypeArrayCallBacks);
|
|
||||||
if(!cfaFiles) //This should never happen
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("wxMacLaunch Could not create CFMutableArray"));
|
|
||||||
CFRelease(cfbApp);
|
|
||||||
CFRelease(cfurlApp);
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through command line arguments to the bundle,
|
|
||||||
// turn them into CFURLs and then put them in cfaFiles
|
|
||||||
// For use to launch services call
|
|
||||||
for( ; *argv != NULL ; ++argv)
|
|
||||||
{
|
|
||||||
// Check for '<' as this will ring true for
|
|
||||||
// CFURLCreateWithString but is generally not considered
|
|
||||||
// typical on mac but is usually passed here from wxExecute
|
|
||||||
if (wxStrcmp(*argv, wxT("<")) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
|
||||||
CFURLRef cfurlCurrentFile; // CFURL to hold file path
|
|
||||||
wxFileName argfn(*argv); // Filename for path
|
|
||||||
|
|
||||||
if(argfn.DirExists())
|
|
||||||
{
|
|
||||||
// First, try creating as a directory
|
|
||||||
cfurlCurrentFile = CFURLCreateWithFileSystemPath(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
wxCFStringRef(*argv),
|
|
||||||
kDefaultPathStyle,
|
|
||||||
true); //true == directory
|
|
||||||
}
|
|
||||||
else if(argfn.FileExists())
|
|
||||||
{
|
|
||||||
// And if it isn't a directory try creating it
|
|
||||||
// as a regular file
|
|
||||||
cfurlCurrentFile = CFURLCreateWithFileSystemPath(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
wxCFStringRef(*argv),
|
|
||||||
kDefaultPathStyle,
|
|
||||||
false); //false == regular file
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Argument did not refer to
|
|
||||||
// an entry in the local filesystem,
|
|
||||||
// so try creating it through CFURLCreateWithString
|
|
||||||
cfurlCurrentFile = CFURLCreateWithString(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
wxCFStringRef(*argv),
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue in the loop if the CFURL could not be created
|
|
||||||
if(!cfurlCurrentFile)
|
|
||||||
{
|
|
||||||
wxLogDebug(
|
|
||||||
wxT("wxMacLaunch Could not create CFURL for argument:%s"),
|
|
||||||
*argv);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the valid CFURL to the argument array and then
|
|
||||||
// release it as the CFArray adds a ref count to it
|
|
||||||
CFArrayAppendValue(
|
|
||||||
cfaFiles,
|
|
||||||
cfurlCurrentFile
|
|
||||||
);
|
|
||||||
CFRelease(cfurlCurrentFile); // array has retained it
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a LSLaunchURLSpec for use with LSOpenFromURLSpec
|
|
||||||
// Note that there are several flag options (launchFlags) such
|
|
||||||
// as kLSLaunchDontSwitch etc. and maybe we could be more
|
|
||||||
// picky about the flags we choose
|
|
||||||
LSLaunchURLSpec launchspec;
|
|
||||||
launchspec.appURL = cfurlApp;
|
|
||||||
launchspec.itemURLs = cfaFiles;
|
|
||||||
launchspec.passThruParams = NULL; //AEDesc*
|
|
||||||
launchspec.launchFlags = kLSLaunchDefaults;
|
|
||||||
launchspec.asyncRefCon = NULL;
|
|
||||||
|
|
||||||
// Finally, call LSOpenFromURL spec with our arguments
|
|
||||||
// 2nd parameter is a pointer to a CFURL that gets
|
|
||||||
// the actual path launched by the function
|
|
||||||
OSStatus status = LSOpenFromURLSpec(&launchspec, NULL);
|
|
||||||
|
|
||||||
// Cleanup corefoundation references
|
|
||||||
CFRelease(cfbApp);
|
|
||||||
CFRelease(cfurlApp);
|
|
||||||
CFRelease(cfaFiles);
|
|
||||||
|
|
||||||
// Check for error from LSOpenFromURLSpec
|
|
||||||
if(status != noErr)
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("wxMacLaunch LSOpenFromURLSpec Error: %d"),
|
|
||||||
(int)status);
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No error from LSOpenFromURLSpec, so app was launched
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,118 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Name: src/mac/corefoundation/utilsexec_cf.cpp
|
|
||||||
// Purpose: Execution-related utilities for Darwin
|
|
||||||
// Author: David Elliott, Ryan Norton (wxMacExecute)
|
|
||||||
// Modified by: Stefan Csomor (added necessary wxT for unicode builds)
|
|
||||||
// Created: 2004-11-04
|
|
||||||
// RCS-ID: $Id$
|
|
||||||
// Copyright: (c) David Elliott, Ryan Norton
|
|
||||||
// Licence: wxWindows licence
|
|
||||||
// Notes: This code comes from src/mac/carbon/utilsexc.cpp,1.11
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/log.h"
|
|
||||||
#include "wx/utils.h"
|
|
||||||
#endif //ndef WX_PRECOMP
|
|
||||||
#include "wx/unix/execute.h"
|
|
||||||
#include "wx/stdpaths.h"
|
|
||||||
#include "wx/app.h"
|
|
||||||
#include "wx/apptrait.h"
|
|
||||||
#include "wx/thread.h"
|
|
||||||
#include "wx/process.h"
|
|
||||||
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
#include <CoreFoundation/CFSocket.h>
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Called due to source signal detected by the CFRunLoop.
|
|
||||||
This is nearly identical to the wxGTK equivalent.
|
|
||||||
*/
|
|
||||||
extern "C" void WXCF_EndProcessDetector(CFSocketRef s,
|
|
||||||
CFSocketCallBackType WXUNUSED(callbackType),
|
|
||||||
CFDataRef WXUNUSED(address),
|
|
||||||
void const *WXUNUSED(data),
|
|
||||||
void *info)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Either our pipe was closed or the process ended successfully. Either way,
|
|
||||||
we're done. It's not if waitpid is going to magically succeed when
|
|
||||||
we get fired again. CFSocketInvalidate closes the fd for us and also
|
|
||||||
invalidates the run loop source for us which should cause it to
|
|
||||||
release the CFSocket (thus causing it to be deallocated) and remove
|
|
||||||
itself from the runloop which should release it and cause it to also
|
|
||||||
be deallocated. Of course, it's possible the RunLoop hangs onto
|
|
||||||
one or both of them by retaining/releasing them within its stack
|
|
||||||
frame. However, that shouldn't be depended on. Assume that s is
|
|
||||||
deallocated due to the following call.
|
|
||||||
*/
|
|
||||||
CFSocketInvalidate(s);
|
|
||||||
|
|
||||||
// Now tell wx that the process has ended.
|
|
||||||
wxHandleProcessTermination(static_cast<wxEndProcessData *>(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Implements the GUI-specific AddProcessCallback() for both wxMac and
|
|
||||||
wxCocoa using the CFSocket/CFRunLoop API which is available to both.
|
|
||||||
Takes advantage of the fact that sockets on UNIX are just regular
|
|
||||||
file descriptors and thus even a non-socket file descriptor can
|
|
||||||
apparently be used with CFSocket so long as you only tell CFSocket
|
|
||||||
to do things with it that would be valid for a non-socket fd.
|
|
||||||
*/
|
|
||||||
int wxGUIAppTraits::AddProcessCallback(wxEndProcessData *proc_data, int fd)
|
|
||||||
{
|
|
||||||
static int s_last_tag = 0;
|
|
||||||
CFSocketContext context =
|
|
||||||
{ 0
|
|
||||||
, static_cast<void*>(proc_data)
|
|
||||||
, NULL
|
|
||||||
, NULL
|
|
||||||
, NULL
|
|
||||||
};
|
|
||||||
CFSocketRef cfSocket = CFSocketCreateWithNative(kCFAllocatorDefault,fd,kCFSocketReadCallBack,&WXCF_EndProcessDetector,&context);
|
|
||||||
if(cfSocket == NULL)
|
|
||||||
{
|
|
||||||
wxLogError(wxT("Failed to create socket for end process detection"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
CFRunLoopSourceRef runLoopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, cfSocket, /*highest priority:*/0);
|
|
||||||
if(runLoopSource == NULL)
|
|
||||||
{
|
|
||||||
wxLogError(wxT("Failed to create CFRunLoopSource from CFSocket for end process detection"));
|
|
||||||
// closes the fd.. we can't really stop it, nor do we necessarily want to.
|
|
||||||
CFSocketInvalidate(cfSocket);
|
|
||||||
CFRelease(cfSocket);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Now that the run loop source has the socket retained and we no longer
|
|
||||||
// need to refer to it within this method, we can release it.
|
|
||||||
CFRelease(cfSocket);
|
|
||||||
|
|
||||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
|
|
||||||
// Now that the run loop has the source retained we can release it.
|
|
||||||
CFRelease(runLoopSource);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Feed wx some bullshit.. we don't use it since CFSocket helpfully passes
|
|
||||||
itself into our callback and that's enough to be able to
|
|
||||||
CFSocketInvalidate it which is all we need to do to get everything we
|
|
||||||
just created to be deallocated.
|
|
||||||
*/
|
|
||||||
return ++s_last_tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// NOTE: This doesn't really belong here but this was a handy file to
|
|
||||||
// put it in because it's already compiled for wxCocoa and wxMac GUI lib.
|
|
||||||
#if wxUSE_STDPATHS
|
|
||||||
static wxStandardPathsCF gs_stdPaths;
|
|
||||||
wxStandardPathsBase& wxGUIAppTraits::GetStandardPaths()
|
|
||||||
{
|
|
||||||
return gs_stdPaths;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
Reference in New Issue
Block a user