]>
Commit | Line | Data |
---|---|---|
5cd99866 VZ |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: src/osx/core/evtloop_cf.cpp | |
3 | // Purpose: wxEventLoop implementation common to both Carbon and Cocoa | |
4 | // Author: Vadim Zeitlin | |
5 | // Created: 2009-10-18 | |
6 | // RCS-ID: $Id: wxhead.cpp,v 1.10 2009-06-29 10:23:04 zeitlin Exp $ | |
7 | // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org> | |
8 | // Licence: wxWindows licence | |
9 | /////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | // ============================================================================ | |
12 | // declarations | |
13 | // ============================================================================ | |
14 | ||
15 | // ---------------------------------------------------------------------------- | |
16 | // headers | |
17 | // ---------------------------------------------------------------------------- | |
18 | ||
19 | // for compilers that support precompilation, includes "wx.h". | |
20 | #include "wx/wxprec.h" | |
21 | ||
22 | #ifdef __BORLANDC__ | |
23 | #pragma hdrstop | |
24 | #endif | |
25 | ||
26 | #include "wx/evtloop.h" | |
27 | ||
28 | #if wxUSE_EVENTLOOP_SOURCE | |
29 | ||
fe5816f0 VZ |
30 | #ifndef WX_PRECOMP |
31 | #include "wx/log.h" | |
32 | #endif | |
33 | ||
5cd99866 VZ |
34 | #include "wx/evtloopsrc.h" |
35 | ||
36 | #include "wx/scopedptr.h" | |
37 | ||
38 | #include "wx/osx/private.h" | |
39 | #include "wx/osx/core/cfref.h" | |
40 | ||
41 | // ============================================================================ | |
42 | // wxCFEventLoopSource and wxCFEventLoop implementation | |
43 | // ============================================================================ | |
44 | ||
45 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 | |
46 | namespace | |
47 | { | |
48 | ||
49 | void EnableDescriptorCallBacks(CFFileDescriptorRef cffd, int flags) | |
50 | { | |
51 | if ( flags & wxEVENT_SOURCE_INPUT ) | |
52 | CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack); | |
53 | if ( flags & wxEVENT_SOURCE_OUTPUT ) | |
54 | CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack); | |
55 | } | |
56 | ||
57 | void | |
58 | wx_cffiledescriptor_callback(CFFileDescriptorRef cffd, | |
59 | CFOptionFlags flags, | |
60 | void *ctxData) | |
61 | { | |
62 | wxLogTrace(wxTRACE_EVT_SOURCE, | |
63 | "CFFileDescriptor callback, flags=%d", flags); | |
64 | ||
65 | wxCFEventLoopSource * const | |
66 | source = static_cast<wxCFEventLoopSource *>(ctxData); | |
67 | ||
68 | wxEventLoopSourceHandler * const | |
69 | handler = source->GetHandler(); | |
70 | if ( flags & kCFFileDescriptorReadCallBack ) | |
71 | handler->OnReadWaiting(); | |
72 | if ( flags & kCFFileDescriptorWriteCallBack ) | |
73 | handler->OnWriteWaiting(); | |
74 | ||
75 | // we need to re-enable callbacks to be called again | |
76 | EnableDescriptorCallBacks(cffd, source->GetFlags()); | |
77 | } | |
78 | ||
79 | } // anonymous namespace | |
80 | ||
81 | wxEventLoopSource * | |
82 | wxCFEventLoop::AddSourceForFD(int fd, | |
83 | wxEventLoopSourceHandler *handler, | |
84 | int flags) | |
85 | { | |
86 | wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" ); | |
87 | ||
88 | wxScopedPtr<wxCFEventLoopSource> | |
89 | source(new wxCFEventLoopSource(handler, flags)); | |
90 | ||
91 | CFFileDescriptorContext ctx = { 0, source.get(), NULL, NULL, NULL }; | |
92 | wxCFRef<CFFileDescriptorRef> | |
93 | cffd(CFFileDescriptorCreate | |
94 | ( | |
95 | kCFAllocatorDefault, | |
96 | fd, | |
97 | true, // close on invalidate | |
98 | wx_cffiledescriptor_callback, | |
99 | &ctx | |
100 | )); | |
101 | if ( !cffd ) | |
102 | return NULL; | |
103 | ||
104 | source->SetFileDescriptor(cffd.release()); | |
105 | ||
106 | wxCFRef<CFRunLoopSourceRef> | |
107 | cfsrc(CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0)); | |
108 | if ( !cfsrc ) | |
109 | return NULL; | |
110 | ||
111 | CFRunLoopRef cfloop = CFGetCurrentRunLoop(); | |
112 | CFRunLoopAddSource(cfloop, cfsrc, kCFRunLoopDefaultMode); | |
113 | ||
114 | return source.release(); | |
115 | } | |
116 | ||
117 | void wxCFEventLoopSource::SetFileDescriptor(CFFileDescriptorRef cffd) | |
118 | { | |
119 | wxASSERT_MSG( !m_cffd, "shouldn't be called more than once" ); | |
120 | ||
121 | m_cffd = cffd; | |
122 | } | |
123 | ||
124 | wxCFEventLoopSource::~wxCFEventLoopSource() | |
125 | { | |
126 | if ( m_cffd ) | |
127 | CFRelease(m_cffd); | |
128 | } | |
129 | ||
130 | #else // OS X < 10.5 | |
131 | ||
132 | wxEventLoopSource * | |
133 | wxCFEventLoop::AddSourceForFD(int WXUNUSED(fd), | |
134 | wxEventLoopSourceHandler * WXUNUSED(handler), | |
135 | int WXUNUSED(flags)) | |
136 | { | |
137 | return NULL; | |
138 | } | |
139 | ||
140 | #endif // MAC_OS_X_VERSION_MAX_ALLOWED | |
141 | ||
142 | #endif // wxUSE_EVENTLOOP_SOURCE |