]> git.saurik.com Git - wxWidgets.git/commitdiff
Finalize wxJoystick on mac. Note change. Pretty up joystick sample a bit. Don...
authorRyan Norton <wxprojects@comcast.net>
Mon, 14 Feb 2005 20:12:11 +0000 (20:12 +0000)
committerRyan Norton <wxprojects@comcast.net>
Mon, 14 Feb 2005 20:12:11 +0000 (20:12 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32045 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/mac/corefoundation/hid.h
samples/joytest/joytest.cpp
src/mac/carbon/sound.cpp
src/mac/corefoundation/hid.cpp
src/mac/corefoundation/hidjoystick.cpp

index 01a2089d0b19676943a55a52588c0fcee639f57a..6977466302d1a3cbcef8bf410ddf63c1874a6546 100644 (file)
@@ -101,6 +101,7 @@ wxMac:
 - Vertical sliders oriented consistent with MSW/GTK (0 at top) (Kevin Hock)
 - wxDynamicLibrary::GetDllExt() now returns ".bundle", not ".dylib"
 - wxDynamicLibrary::GetSymbol() now prepends underscore to the symbol name
+- wxJoystick now works on OSX
 
 wxMSW:
 
index 52e661eb63a6bfad68c1cd6f1a9055700ad3eb5b..3789e81ff31e7b810d997719b4a39bd5740df260 100644 (file)
@@ -24,7 +24,7 @@
 #endif
 
 #include "wx/defs.h"
-
+#include "wx/string.h"
 
 // ---------------------------------------------------------------------------
 // definitions
@@ -91,7 +91,9 @@ protected:
        IOHIDQueueInterface**   m_ppQueue;  //queue (if we want one)
        IOHIDElementCookie*     m_pCookies; //cookies
 
-       const char*                     m_szName; //(product) name
+       wxString                                m_szProductName; //product name
+       int                                             m_nProductId; //product id
+       int                                             m_nManufacturerId; //manufacturer id
        mach_port_t                     m_pPort;
 };
 
index bb31b257a3bbfed0c9c27b6be38597bb1fcbb0ae..403ea91a8eaa7b902947e1ddc406195897ab911f 100644 (file)
@@ -39,6 +39,7 @@ long ypos = -1;
 
 int winNumber = 1;
 
+int nButtons = 0;
 // Initialise this in OnInit, not statically
 bool MyApp::OnInit()
 {
@@ -85,7 +86,7 @@ bool MyApp::OnInit()
 
 #if wxUSE_STATUSBAR
     frame->CreateStatusBar();
-    frame->SetStatusText(wxT("Ready..."));
+    frame->SetStatusText(wxString::Format(wxT("Device [%s] (PID:[%i] MID:[%i]) Ready... # of joysticks:[%i]"), stick.GetProductName().c_str(), stick.GetProductId(), stick.GetManufacturerId(), stick.GetNumberJoysticks()));
 #endif // wxUSE_STATUSBAR
 
     frame->CenterOnScreen();
@@ -105,6 +106,7 @@ MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size):
     wxScrolledWindow(parent, wxID_ANY, pos, size, wxSUNKEN_BORDER)
 {
     m_stick = new wxJoystick(wxJOYSTICK1);
+    nButtons = m_stick->GetNumberButtons();
     m_stick->SetCapture(this, 10);
 }
 
@@ -153,10 +155,18 @@ void MyCanvas::OnJoystickEvent(wxJoystickEvent& event)
 #if wxUSE_STATUSBAR
     wxString buf;
     if (event.ButtonDown())
-        buf.Printf(_T("Joystick (%d, %d) Fire!"), pt.x, pt.y);
+        buf.Printf(_T("Joystick (%d, %d) #%i Fire!"), pt.x, pt.y, event.GetButtonChange());
     else
-        buf.Printf(_T("Joystick (%d, %d)"), pt.x, pt.y);
+        buf.Printf(_T("Joystick (%d, %d)  "), pt.x, pt.y);
 
+/*
+    for(int i = 0; i < nButtons; ++i)
+    {
+        buf += wxString(wxT("[")) + 
+        ((event.GetButtonState() & (1 << i)) ? wxT("Y") : wxT("N")) + wxString(wxT("]"));
+    }
+*/
+    
     frame->SetStatusText(buf);
 #endif // wxUSE_STATUSBAR
 
index 93e36c103c395acf57c858fd741b28c62aa0e0b0..6533416d1fd24de3532e6e4853f2df3f72fdaf1b 100644 (file)
@@ -422,8 +422,10 @@ bool wxSound::DoPlay(unsigned flags) const
                 int nError;
                 if ((nError = NativePathNameToFSSpec ((char*) m_sndname.c_str(), &sfFile, 0)) != noErr)
                 {
+/*
                     wxLogSysError(wxString::Format(wxT("File:%s does not exist\nError:%i"),
                                     m_sndname.c_str(), nError));
+*/
                     return false;
                 }
 #endif
index 735895bbf5f8787ddad40d6b47cf93170004237f..75eec3cbc1f30093be8835bd6064f470bbb0c54a 100644 (file)
@@ -34,6 +34,7 @@
 #include "wx/mac/corefoundation/hid.h"
 #include "wx/string.h"
 #include "wx/log.h"
+#include "wx/mac/corefoundation/cfstring.h"
 
 
 // ---------------------------------------------------------------------------
@@ -118,7 +119,7 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
        //Now get the maching services
        io_iterator_t pIterator;
        wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services");
-       wxASSERT(pIterator != 0);
+       wxASSERT_MSG(pIterator != 0, wxT("No devices found!"));
 
        //Now we iterate through them
        io_object_t pObject;
@@ -133,11 +134,36 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
                //Just for sanity :)
                wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey))) == CFStringGetTypeID());
                        
+/*
+        kIOHIDTransportKey;
+        kIOHIDVendorIDKey;
+        kIOHIDProductIDKey;
+        kIOHIDVersionNumberKey;
+        kIOHIDManufacturerKey;
+        kIOHIDSerialNumberKey;
+        if !kIOHIDLocationIDKey
+            kUSBDevicePropertyLocationID
+        kIOHIDPrimaryUsageKey
+kIOHIDPrimaryUsagePageKey
+idProduct
+idVendor
+USB Product Name
+*/
                //Get [product] name
-               m_szName = CFStringGetCStringPtr        (
-                                               (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)), 
-                                               CFStringGetSystemEncoding()
-                                                                               );
+               m_szProductName = wxMacCFStringHolder( (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)), false ).AsString();
+        
+       CFNumberGetValue(
+                               (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)),     
+                               kCFNumberIntType,
+                &m_nProductId
+                               );
+
+
+       CFNumberGetValue(
+                               (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)),      
+                               kCFNumberIntType,
+                &m_nManufacturerId
+                               );
 
                //Create the interface (good grief - long function names!)
                SInt32 nScore;
@@ -164,8 +190,6 @@ bool wxHIDDevice::Create (int nClass, int nType, int nDev)
                //
                wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey));
                BuildCookies(CookieArray);
-               if (m_ppQueue != NULL)
-                       wxVERIFY((*m_ppQueue)->start(m_ppQueue) == S_OK);
 
                //cleanup
                CFRelease(pDictionary);
@@ -215,7 +239,9 @@ int wxHIDDevice::GetCount (int nClass, int nType)
        //Now get the maching services
        io_iterator_t pIterator;
        wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services");
-       wxASSERT(pIterator != 0);
+       
+    if(pIterator == NULL)
+        return 0;
 
        //Now we iterate through them
        io_object_t pObject;
index eacceb050797493a2586a5d2ffc81744483ed4c2..780c1b5ca6457541a43e4a2a3f44e2f53f0f150e 100644 (file)
 #include <unistd.h>
 
 enum {
-    wxJS_AXIS_X = 41,
+    wxJS_AXIS_X = 40,
     wxJS_AXIS_Y,
     wxJS_AXIS_Z,
     wxJS_AXIS_RUDDER,
     wxJS_AXIS_U,
     wxJS_AXIS_V,
 
-    wxJS_AXIS_MAX = 32767,
-    wxJS_AXIS_MIN = -32767
+    wxJS_AXIS_MAX = 255, //32767,
+    wxJS_AXIS_MIN = 0, //-32767
 };
 
 class wxHIDJoystick : public wxHIDDevice
@@ -49,9 +49,11 @@ class wxHIDJoystick : public wxHIDDevice
 public:
        bool Create(int nWhich);
        virtual void BuildCookies(wxCFArray& Array);
+       void MakeCookies(wxCFArray& Array);
     IOHIDElementCookie* GetCookies() {return m_pCookies;}
-    
     IOHIDQueueInterface** GetQueue() {return m_ppQueue;}
+    
+    friend class wxJoystick;
 };
 
 
@@ -76,43 +78,63 @@ void wxHIDJoystick::BuildCookies(wxCFArray& Array)
 {
        Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey));
        InitCookies(50, true);
+
+    memset(m_pCookies, 0, sizeof(*m_pCookies) * 50);
+    MakeCookies(Array);
+    
+//    for(int i = 0; i < 50; ++i)
+//        wxPrintf(wxT("\nVAL #%i:[%i]"), i, m_pCookies[i]);
+}//end buildcookies
+
+void wxHIDJoystick::MakeCookies(wxCFArray& Array)
+{
        int i,
                nUsage,
         nPage;
        for (i = 0; i < Array.Count(); ++i)
        {
-               CFNumberGetValue(
+        const void* ref = CFDictionaryGetValue((CFDictionaryRef)Array[i], CFSTR(kIOHIDElementKey));
+
+//        wxPrintf(wxT("ELM\n"));
+        if (ref  != NULL)
+        {
+            wxCFArray newarray(ref);
+            MakeCookies(newarray);
+        }
+        else
+        {
+            CFNumberGetValue(
                        (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)), 
                                kCFNumberLongType, &nUsage);
                        
-               CFNumberGetValue(
+            CFNumberGetValue(
                        (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsagePageKey)), 
                                kCFNumberLongType, &nPage);
 
-               if (nPage == kHIDPage_Button && nUsage <= 40)
-                       AddCookieInQueue(Array[i], nUsage );
-               else if (nPage == kHIDPage_GenericDesktop)
-        {
-            switch(nUsage)
+            if (nPage == kHIDPage_Button && nUsage <= 40)
+                AddCookieInQueue(Array[i], nUsage-1 );
+            else if (nPage == kHIDPage_GenericDesktop)
             {
-                case kHIDUsage_GD_X:
-                    AddCookieInQueue(Array[i], wxJS_AXIS_X);
-                    break;                    
-                case kHIDUsage_GD_Y:
-                    AddCookieInQueue(Array[i], wxJS_AXIS_Y);
-                    break;
-                case kHIDUsage_GD_Z:
-                    AddCookieInQueue(Array[i], wxJS_AXIS_Z);
-                    break;
-                default:
-                    break;
+                switch(nUsage)
+                {
+                    case kHIDUsage_GD_X:
+                        AddCookieInQueue(Array[i], wxJS_AXIS_X);
+                        break;                    
+                    case kHIDUsage_GD_Y:
+                        AddCookieInQueue(Array[i], wxJS_AXIS_Y);
+                        break;
+                    case kHIDUsage_GD_Z:
+                        AddCookieInQueue(Array[i], wxJS_AXIS_Z);
+                        break;
+                    default:
+                        break;
+                }
             }
+            else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder)
+                AddCookieInQueue(Array[i], wxJS_AXIS_RUDDER );
         }
-        else if (nPage == kHIDPage_Simulation && nUsage == kHIDUsage_Sim_Rudder)
-                       AddCookieInQueue(Array[i], wxJS_AXIS_RUDDER );
        }
-}//end buildcookies
-
+}
 
 
 
@@ -129,6 +151,107 @@ public:
     wxJoystickThread(wxHIDJoystick* hid, int joystick);
     void* Entry();
 
+    static void HIDCallback(void* target, IOReturn res, void* context, void* sender)
+    {
+        IOHIDEventStruct hidevent;
+        AbsoluteTime bogustime = {0,0};
+        IOReturn ret;
+        wxJoystickThread* pThis = (wxJoystickThread*) context;
+        wxHIDJoystick* m_hid = pThis->m_hid;
+        
+//        wxMutexGuiEnter();
+        ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(), 
+                        &hidevent, bogustime, 0);
+  //      wxMutexGuiLeave(); 
+        while (    ret != kIOReturnUnderrun )
+        {
+            if (pThis->TestDestroy())
+                break;
+
+//            wxPrintf(wxT("ENTER\n"));
+            if(ret != kIOReturnSuccess)
+            {
+                wxLogSysError(wxString::Format(wxT("wxJoystick Error:[%i]"), ret));
+                return;
+            }  
+                
+            wxJoystickEvent wxevent;
+            
+            int nIndex = 0;
+            IOHIDElementCookie* pCookies = m_hid->GetCookies();
+            while(nIndex < 50)
+            {
+                if(hidevent.elementCookie == pCookies[nIndex])
+                    break;
+                    
+                ++nIndex;
+            } 
+            if(nIndex == 50)
+            {
+                wxLogSysError(wxString::Format(wxT("wxJoystick Out Of Bounds Error")));
+                break;
+            }  
+            
+            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);
+
+//            wxPrintf(wxT("SEND\n"));
+
+            if (pThis->m_catchwin)
+                pThis->m_catchwin->AddPendingEvent(wxevent);            
+
+         //   wxMutexGuiEnter();
+            ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(), 
+                        &hidevent, bogustime, 0);
+           // wxMutexGuiLeave(); 
+        }
+    }
+    
 private:
     wxHIDJoystick*       m_hid;
     int       m_joystick;
@@ -145,7 +268,7 @@ private:
 wxJoystickThread::wxJoystickThread(wxHIDJoystick* hid, int joystick)
     : m_hid(hid),
       m_joystick(joystick),
-      m_lastposition(wxDefaultPosition),
+      m_lastposition(127,127),
       m_buttons(0),
       m_catchwin(NULL),
       m_polling(0)
@@ -170,12 +293,10 @@ void* wxJoystickThread::Entry()
     CFRunLoopRef pRL = CFRunLoopGetCurrent();  
     CFRunLoopAddSource(pRL, pRLSource, kCFRunLoopDefaultMode);
       
-//    wxJSVERIFY( (*m_hid->GetQueue())->start(m_hid->GetQueue()) == kIOReturnSuccess ); 
+    wxJSVERIFY( (*m_hid->GetQueue())->start(m_hid->GetQueue()) == kIOReturnSuccess ); 
+    wxJSVERIFY( (*m_hid->GetQueue())->setEventCallout(m_hid->GetQueue(), &wxJoystickThread::HIDCallback, this, this) == kIOReturnSuccess ); 
     
     double dTime;
-    IOHIDEventStruct hidevent;
-    AbsoluteTime bogustime = {0,0};
-    IOReturn ret;
     
     while(true)
     {
@@ -187,78 +308,13 @@ void* wxJoystickThread::Entry()
         else
             dTime = 0.0001 * 10;  // check at least every 10 msec in blocking case
 
-        CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, m_polling);        
-        
-        while (    (ret = (*m_hid->GetQueue())->getNextEvent(m_hid->GetQueue(), 
-                        &hidevent, bogustime, 0)) != kIOReturnUnderrun )
-        {
-            if (TestDestroy())
-                break;
-
-            wxJSASSERT(ret == kIOReturnSuccess);
-            wxJoystickEvent wxevent;
-            
-            int nIndex = 0;
-            IOHIDElementCookie* pCookies = m_hid->GetCookies();
-            while(nIndex < 50)
-            {
-                if(hidevent.elementCookie == pCookies[nIndex])
-                    break;
-            } 
-            wxASSERT(nIndex != 50);
-            
-            if (nIndex < 40)
-            {
-                if (hidevent.value)
-                {
-                    m_buttons |= (1 << nIndex);
-                    wxevent.SetEventType(wxEVT_JOY_BUTTON_DOWN);
-                }
-                else
-                {
-                    m_buttons &= ~(1 << nIndex);
-                    wxevent.SetEventType(wxEVT_JOY_BUTTON_UP);
-                }
-
-                wxevent.SetButtonChange(nIndex);
-            }
-            else if (nIndex == wxJS_AXIS_X)
-            {
-                m_lastposition.x = hidevent.value;
-                wxevent.SetEventType(wxEVT_JOY_MOVE);
-                m_axe[nIndex - 39] = hidevent.value;
-            }
-            else if (nIndex == wxJS_AXIS_Y)
-            {
-                m_lastposition.y = hidevent.value;
-                wxevent.SetEventType(wxEVT_JOY_MOVE);
-                m_axe[nIndex - 39] = hidevent.value;
-            }
-            else if (nIndex == wxJS_AXIS_Z)
-            {
-                wxevent.SetEventType(wxEVT_JOY_ZMOVE);
-                m_axe[nIndex - 39] = 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(m_joystick);
-            wxevent.SetButtonState(m_buttons);
-            wxevent.SetPosition(m_lastposition);
-            wxevent.SetZPosition(m_axe[3]);
-            wxevent.SetEventObject(m_catchwin);
-
-            if (m_catchwin)
-                m_catchwin->AddPendingEvent(wxevent);            
-        }
+        CFRunLoopRunInMode(kCFRunLoopDefaultMode, dTime, true);        
     }
+    
+    wxJSASSERT( CFRunLoopContainsSource(pRL, pRLSource, kCFRunLoopDefaultMode) );
+    CFRunLoopRemoveSource(pRL, pRLSource, kCFRunLoopDefaultMode);
+    CFRelease(pRLSource);
+
     return NULL;
 }
 
@@ -366,13 +422,13 @@ int wxJoystick::GetNumberJoysticks() const
             wxHIDDevice::GetCount(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad);   }
     
 int wxJoystick::GetManufacturerId() const
-{      return 0;                               }       
+{      return m_hid->m_nManufacturerId;                                }
 
 int wxJoystick::GetProductId() const
-{      return 0;                               }
+{      return m_hid->m_nProductId;                             }
 
 wxString wxJoystick::GetProductName() const
-{      return wxT("unknown");  }
+{      return m_hid->m_szProductName;                          }
 
 int wxJoystick::GetXMin() const
 {      return wxJS_AXIS_MIN;   }