Mac Client: revert to using older API NXIdleTime() to get user idle time

svn path=/trunk/boinc/; revision=14456
This commit is contained in:
Charlie Fenton 2008-01-02 11:15:20 +00:00
parent 3899174501
commit aa2629a8e0
4 changed files with 36 additions and 93 deletions

View File

@ -25,3 +25,16 @@ David Jan 1 2008
profile_rate.php
show_user.php
view_profile.php
Charlie Jan 2 2008
- Mac Client: revert to using older API NXIdleTime() to get user
idle time because the newer APIs CGSSecondsSinceLastInputEvent()
and CGEventSourceSecondsSinceLastEventType() don't work properly
when running as a daemon.
client/
hostinf_unix.C
main.C
lib/
hostinfo.h

View File

@ -91,6 +91,8 @@ extern "C" {
#ifdef __cplusplus
} // extern "C"
#endif
NXEventHandle gEventHandle;
#endif // __APPLE__
#ifdef _HPUX_SOURCE
@ -855,103 +857,11 @@ inline bool all_logins_idle(time_t t) {
#endif // HAVE_UTMP_H
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#if defined(__i386__) || defined(__x86_64__)
#include <ApplicationServices/ApplicationServices.h>
// Returns the system idle time in seconds
static double GetOSXIdleTime(void) {
return (double)CGEventSourceSecondsSinceLastEventType (kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
}
#else
// CGEventSourceSecondsSinceLastEventType() is available only in OS 10.4 and later.
// Since the OS10.3.9 SDK doesn't have this function, the PowerPC build would fail
// with a link error even with weak linking. So we have to do this the hard way.
extern "C" {
extern double CGSSecondsSinceLastInputEvent(long evType); // private API for pre-10.4 systems
}
enum {
kCGEventSourceStatePrivate = -1,
kCGEventSourceStateCombinedSessionState = 0,
kCGEventSourceStateHIDSystemState = 1
};
#define kCGAnyInputEventType ((CGEventType)(~0))
typedef uint32_t CGEventSourceStateID;
typedef uint32_t CGEventType;
CG_EXTERN CFTimeInterval CGEventSourceSecondsSinceLastEventType( CGEventSourceStateID source, CGEventType eventType );
typedef CFTimeInterval (*GetIdleTimeProc)( CGEventSourceStateID source, CGEventType eventType );
// Returns the system idle time in seconds
static double GetOSXIdleTime(void) {
static CFBundleRef bundleRef = NULL;
static GetIdleTimeProc GetSysIdleTime = NULL;
CFURLRef frameworkURL = NULL;
double idleTime = 0;
static bool tryNewAPI = true;
if (tryNewAPI) {
if (bundleRef == NULL) {
frameworkURL = CFURLCreateWithFileSystemPath(
kCFAllocatorSystemDefault,
CFSTR("/System/Library/Frameworks/ApplicationServices.framework"),
kCFURLPOSIXPathStyle, true
);
if (frameworkURL) {
bundleRef = CFBundleCreate(kCFAllocatorSystemDefault, frameworkURL);
CFRelease( frameworkURL );
}
}
if (bundleRef) {
if ((GetSysIdleTime == NULL) || !CFBundleIsExecutableLoaded(bundleRef)
) {
// Is this test necessary ?
GetSysIdleTime = (GetIdleTimeProc) CFBundleGetFunctionPointerForName(
bundleRef, CFSTR("CGEventSourceSecondsSinceLastEventType")
);
}
}
if (GetSysIdleTime) {
idleTime = (double)GetSysIdleTime (kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
} else {
CFRelease( bundleRef );
bundleRef = NULL;
tryNewAPI = false;
// CGEventSourceSecondsSinceLastEventType() API is not available on this system
}
if (GetSysIdleTime) {
return idleTime;
}
} // if (tryNewAPI)
// On 10.3 use this SPI
// From Adium:
// On MDD Powermacs, the above function will return a large value when the machine
// is active (-1?). 18446744073.0 is the lowest I've seen on my MDD -ai
// Here we check for that value and correctly return a 0 idle time.
//
idleTime = CGSSecondsSinceLastInputEvent (-1);
if (idleTime >= 18446744000.0) idleTime = 0.0;
return idleTime;
// return (double)NXIdleTime(gEventHandle); // Very old and very slow API
}
#endif // ! (__i386__ || __x86_64__)
bool HOST_INFO::users_idle(
bool check_all_logins, double idle_time_to_run, double *actual_idle_time
) {
double idleTime = GetOSXIdleTime();
double idleTime = NXIdleTime(gEventHandle);
if (actual_idle_time) {
*actual_idle_time = idleTime;

View File

@ -771,6 +771,11 @@ int main(int argc, char** argv) {
}
#endif // SANDBOX
#ifdef __APPLE__
// Initialize Mac OS X idle time measurement / idle detection
gEventHandle = NXOpenEventStatus();
#endif // __APPLE__
retval = boinc_main_loop();
#endif

View File

@ -82,4 +82,19 @@ public:
void generate_host_cpid();
};
#ifdef __APPLE__
#ifdef __cplusplus
extern "C" {
#endif
#include <mach/port.h>
typedef mach_port_t NXEventHandle;
NXEventHandle NXOpenEventStatus(void);
extern double NXIdleTime(NXEventHandle handle);
#ifdef __cplusplus
} // extern "C"
#endif
extern NXEventHandle gEventHandle;
#endif
#endif