source: psi/trunk/src/tools/idle/idle_mac.cpp

Last change on this file was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 4.5 KB
Line 
1/*
2 * idle_mac.cpp - detect desktop idle time
3 * Copyright (C) 2003 Tarkvara Design Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include"idle.h"
22#include <Carbon/Carbon.h>
23
24
25// Why does Apple have to make this so complicated?
26static OSStatus LoadFrameworkBundle(CFStringRef framework, CFBundleRef *bundlePtr) {
27 OSStatus err;
28 FSRef frameworksFolderRef;
29 CFURLRef baseURL;
30 CFURLRef bundleURL;
31
32 if ( bundlePtr == nil ) return( -1 );
33
34 *bundlePtr = nil;
35
36 baseURL = nil;
37 bundleURL = nil;
38
39 err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef);
40 if (err == noErr) {
41 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef);
42 if (baseURL == nil) {
43 err = coreFoundationUnknownErr;
44 }
45 }
46 if (err == noErr) {
47 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, framework, false);
48 if (bundleURL == nil) {
49 err = coreFoundationUnknownErr;
50 }
51 }
52 if (err == noErr) {
53 *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL);
54 if (*bundlePtr == nil) {
55 err = coreFoundationUnknownErr;
56 }
57 }
58 if (err == noErr) {
59 if ( ! CFBundleLoadExecutable( *bundlePtr ) ) {
60 err = coreFoundationUnknownErr;
61 }
62 }
63
64 // Clean up.
65 if (err != noErr && *bundlePtr != nil) {
66 CFRelease(*bundlePtr);
67 *bundlePtr = nil;
68 }
69 if (bundleURL != nil) {
70 CFRelease(bundleURL);
71 }
72 if (baseURL != nil) {
73 CFRelease(baseURL);
74 }
75
76 return err;
77}
78
79
80class IdlePlatform::Private {
81public:
82 EventLoopTimerRef mTimerRef;
83 int mSecondsIdle;
84
85 Private() : mTimerRef(0), mSecondsIdle(0) {}
86
87 static pascal void IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData);
88
89};
90
91
92pascal void IdlePlatform::Private::IdleTimerAction(EventLoopTimerRef, EventLoopIdleTimerMessage inState, void* inUserData) {
93 switch (inState) {
94 case kEventLoopIdleTimerStarted:
95 case kEventLoopIdleTimerStopped:
96 // Get invoked with this constant at the start of the idle period,
97 // or whenever user activity cancels the idle.
98 ((IdlePlatform::Private*)inUserData)->mSecondsIdle = 0;
99 break;
100 case kEventLoopIdleTimerIdling:
101 // Called every time the timer fires (i.e. every second).
102 ((IdlePlatform::Private*)inUserData)->mSecondsIdle++;
103 break;
104 }
105}
106
107
108IdlePlatform::IdlePlatform() {
109 d = new Private();
110}
111
112IdlePlatform::~IdlePlatform() {
113 RemoveEventLoopTimer(d->mTimerRef);
114 delete d;
115}
116
117
118// Typedef for the function we're getting back from CFBundleGetFunctionPointerForName.
119typedef OSStatus (*InstallEventLoopIdleTimerPtr)(EventLoopRef inEventLoop,
120 EventTimerInterval inFireDelay,
121 EventTimerInterval inInterval,
122 EventLoopIdleTimerUPP inTimerProc,
123 void * inTimerData,
124 EventLoopTimerRef * outTimer);
125
126
127bool IdlePlatform::init() {
128 // May already be init'ed.
129 if (d->mTimerRef) {
130 return true;
131 }
132
133 // According to the docs, InstallEventLoopIdleTimer is new in 10.2.
134 // According to the headers, it has been around since 10.0.
135 // One of them is lying. We'll play it safe and weak-link the function.
136
137 // Load the "Carbon.framework" bundle.
138 CFBundleRef carbonBundle;
139 if (LoadFrameworkBundle( CFSTR("Carbon.framework"), &carbonBundle ) != noErr) {
140 return false;
141 }
142
143 // Load the Mach-O function pointers for the routine we will be using.
144 InstallEventLoopIdleTimerPtr myInstallEventLoopIdleTimer = (InstallEventLoopIdleTimerPtr)CFBundleGetFunctionPointerForName(carbonBundle, CFSTR("InstallEventLoopIdleTimer"));
145 if (myInstallEventLoopIdleTimer == 0) {
146 return false;
147 }
148
149 EventLoopIdleTimerUPP timerUPP = NewEventLoopIdleTimerUPP(Private::IdleTimerAction);
150 if ((*myInstallEventLoopIdleTimer)(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, timerUPP, 0, &d->mTimerRef)) {
151 return true;
152 }
153
154 return false;
155}
156
157
158int IdlePlatform::secondsIdle() {
159 return d->mSecondsIdle;
160}
Note: See TracBrowser for help on using the repository browser.