KUtils
macpoller.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2009 Dario Freddi <drf at kde.org> 00003 Copyright (C) 2003 Tarkvara Design Inc. (from KVIrc source code) 00004 Copyright (c) 2008 Roman Jarosz <kedgedev at centrum.cz> 00005 Copyright (c) 2008 the Kopete developers <kopete-devel at kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "macpoller.h" 00023 00024 // Why does Apple have to make this so complicated? 00025 static OSStatus LoadFrameworkBundle(CFStringRef framework, CFBundleRef *bundlePtr) 00026 { 00027 OSStatus err; 00028 FSRef frameworksFolderRef; 00029 CFURLRef baseURL; 00030 CFURLRef bundleURL; 00031 00032 if (bundlePtr == nil) 00033 return(-1); 00034 00035 *bundlePtr = nil; 00036 00037 baseURL = nil; 00038 bundleURL = nil; 00039 00040 err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef); 00041 if (err == noErr) { 00042 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef); 00043 if (baseURL == nil) 00044 err = coreFoundationUnknownErr; 00045 } 00046 00047 if (err == noErr) { 00048 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, framework, false); 00049 if (bundleURL == nil) 00050 err = coreFoundationUnknownErr; 00051 } 00052 00053 if (err == noErr) { 00054 *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL); 00055 if (*bundlePtr == nil) 00056 err = coreFoundationUnknownErr; 00057 } 00058 00059 if (err == noErr) { 00060 if (!CFBundleLoadExecutable(*bundlePtr)) 00061 err = coreFoundationUnknownErr; 00062 } 00063 00064 // Clean up. 00065 if (err != noErr && *bundlePtr != nil) { 00066 CFRelease(*bundlePtr); 00067 *bundlePtr = nil; 00068 } 00069 00070 if (bundleURL != nil) 00071 CFRelease(bundleURL); 00072 00073 if (baseURL != nil) 00074 CFRelease(baseURL); 00075 00076 return err; 00077 } 00078 00079 pascal void MacPoller::IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData) 00080 { 00081 switch (inState) { 00082 case kEventLoopIdleTimerStarted: 00083 case kEventLoopIdleTimerStopped: 00084 // Get invoked with this constant at the start of the idle period, 00085 // or whenever user activity cancels the idle. 00086 ((MacPoller*)inUserData)->m_secondsIdle = 0; 00087 ((MacPoller*)inUserData)->triggerResume(); 00088 break; 00089 case kEventLoopIdleTimerIdling: 00090 // Called every time the timer fires (i.e. every second). 00091 ((MacPoller*)inUserData)->m_secondsIdle++; 00092 ((MacPoller*)inUserData)->poll(); 00093 break; 00094 } 00095 } 00096 00097 // Typedef for the function we're getting back from CFBundleGetFunctionPointerForName. 00098 typedef OSStatus(*InstallEventLoopIdleTimerPtr)(EventLoopRef inEventLoop, 00099 EventTimerInterval inFireDelay, 00100 EventTimerInterval inInterval, 00101 EventLoopIdleTimerUPP inTimerProc, 00102 void * inTimerData, 00103 EventLoopTimerRef * outTimer); 00104 00105 MacPoller::MacPoller(QWidget *parent) 00106 : AbstractSystemPoller(parent) 00107 , m_timerRef(0) 00108 , m_secondsIdle(0) 00109 , m_catch(false) 00110 { 00111 } 00112 00113 MacPoller::~MacPoller() 00114 { 00115 } 00116 00117 void MacPoller::unloadPoller() 00118 { 00119 RemoveEventLoopTimer(m_timerRef); 00120 } 00121 00122 bool MacPoller::isAvailable() 00123 { 00124 return true; 00125 } 00126 00127 bool MacPoller::setUpPoller() 00128 { 00129 // May already be init'ed. 00130 if (m_timerRef) { 00131 return true; 00132 } 00133 00134 // According to the docs, InstallEventLoopIdleTimer is new in 10.2. 00135 // According to the headers, it has been around since 10.0. 00136 // One of them is lying. We'll play it safe and weak-link the function. 00137 00138 // Load the "Carbon.framework" bundle. 00139 CFBundleRef carbonBundle; 00140 00141 if (LoadFrameworkBundle(CFSTR("Carbon.framework"), &carbonBundle) != noErr) { 00142 return false; 00143 } 00144 00145 // Load the Mach-O function pointers for the routine we will be using. 00146 InstallEventLoopIdleTimerPtr myInstallEventLoopIdleTimer = 00147 (InstallEventLoopIdleTimerPtr)CFBundleGetFunctionPointerForName(carbonBundle, CFSTR("InstallEventLoopIdleTimer")); 00148 00149 if (myInstallEventLoopIdleTimer == 0) { 00150 return false; 00151 } 00152 00153 EventLoopIdleTimerUPP timerUPP = NewEventLoopIdleTimerUPP(IdleTimerAction); 00154 if ((*myInstallEventLoopIdleTimer)(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, timerUPP, 0, &m_timerRef)) { 00155 return true; 00156 } 00157 00158 return false; 00159 } 00160 00161 QList<int> MacPoller::timeouts() const 00162 { 00163 return m_timeouts; 00164 } 00165 00166 void MacPoller::addTimeout(int nextTimeout) 00167 { 00168 m_timeouts.append(nextTimeout); 00169 poll(); 00170 } 00171 00172 int MacPoller::poll() 00173 { 00174 int idle = m_secondsIdle * 1000; 00175 00176 // Check if we reached a timeout.. 00177 foreach(int i, m_timeouts) { 00178 if ((i - idle < 1000 && i > idle) || (idle - i < 1000 && idle > i)) { 00179 // Bingo! 00180 emit timeoutReached(i); 00181 } 00182 } 00183 00184 return idle; 00185 } 00186 00187 int MacPoller::forcePollRequest() 00188 { 00189 return poll(); 00190 } 00191 00192 void MacPoller::removeTimeout(int timeout) 00193 { 00194 m_timeouts.removeOne(timeout); 00195 poll(); 00196 } 00197 00198 void MacPoller::catchIdleEvent() 00199 { 00200 m_catch = true; 00201 } 00202 00203 void MacPoller::stopCatchingIdleEvents() 00204 { 00205 m_catch = false; 00206 } 00207 00208 void MacPoller::triggerResume() 00209 { 00210 if (m_catch) { 00211 emit resumingFromIdle(); 00212 stopCatchingIdleEvents(); 00213 } 00214 } 00215 00216 void MacPoller::simulateUserActivity() 00217 { 00218 // TODO 00219 } 00220 00221 #include "macpoller.moc"
KDE 4.6 API Reference