~ubuntu-branches/ubuntu/lucid/lastfm/lucid

« back to all changes in this revision

Viewing changes to src/libUnicorn/UnicornCommonMac.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Devid Filoni
  • Date: 2008-07-14 16:46:20 UTC
  • mfrom: (1.1.7 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080714164620-67hoz9fs177wpgmr
Tags: 1:1.5.1.31879.dfsg-1ubuntu1
* Merge from Debian unstable (LP: #248100), remaining changes:
  - debian/rules: add dh_icons call
  + debian/control:
    - switch iceweasel to firefox in Recommends field
    - modify debhelper version to >= 5.0.51~
    - modify Maintainer to Ubuntu MOTU Developers

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "UnicornCommonMac.h"
22
22
 
 
23
#include "AppleScript.h"
 
24
 
 
25
#include <QDebug>
23
26
#include <QDir>
24
 
 
25
27
#include <Carbon/Carbon.h>
26
28
 
27
 
namespace UnicornUtils
28
 
{
 
29
#include <sys/sysctl.h>
29
30
 
30
31
 
31
32
QString
32
 
applicationSupportFolderPath()
 
33
UnicornUtils::applicationSupportFolderPath()
33
34
{
34
35
    std::string outString;
35
36
 
72
73
 
73
74
 
74
75
QLocale::Language
75
 
osxLanguageCode()
 
76
UnicornUtils::osxLanguageCode()
76
77
{
77
78
    CFArrayRef languages;
78
79
    languages = (CFArrayRef)CFPreferencesCopyValue( CFSTR( "AppleLanguages" ),
91
92
    return QLocale( langCode ).language();
92
93
}
93
94
 
94
 
} // namespace UnicornUtils
 
95
 
 
96
QByteArray
 
97
UnicornUtils::CFStringToUtf8( CFStringRef s )
 
98
{
 
99
    QByteArray result;
 
100
 
 
101
    if (s != NULL) 
 
102
    {
 
103
        CFIndex length;
 
104
        length = CFStringGetLength( s );
 
105
        length = CFStringGetMaximumSizeForEncoding( length, kCFStringEncodingUTF8 ) + 1;
 
106
        char* buffer = new char[length];
 
107
 
 
108
        if (CFStringGetCString( s, buffer, length, kCFStringEncodingUTF8 ))
 
109
            result = QByteArray( buffer );
 
110
        else
 
111
            qWarning() << "CFString conversion failed.";
 
112
 
 
113
        delete[] buffer;
 
114
    }
 
115
 
 
116
    return result;
 
117
}
 
118
 
 
119
 
 
120
/** Returns a list of all BSD processes on the system.  This routine
 
121
  * allocates the list and puts it in *procList and a count of the
 
122
  * number of entries in *procCount.  You are responsible for freeing
 
123
  * this list (use "free" from System framework).
 
124
  * On success, the function returns 0.
 
125
  * On error, the function returns a BSD errno value. 
 
126
  */
 
127
int
 
128
getBsdProcessList( kinfo_proc **procList, size_t *procCount )
 
129
{
 
130
    int                 err;
 
131
    kinfo_proc *        result;
 
132
    bool                done;
 
133
    static const int    name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
 
134
    // Declaring name as const requires us to cast it when passing it to
 
135
    // sysctl because the prototype doesn't include the const modifier.
 
136
    size_t              length;
 
137
 
 
138
    // We start by calling sysctl with result == NULL and length == 0.
 
139
    // That will succeed, and set length to the appropriate length.
 
140
    // We then allocate a buffer of that size and call sysctl again
 
141
    // with that buffer.  If that succeeds, we're done.  If that fails
 
142
    // with ENOMEM, we have to throw away our buffer and loop.  Note
 
143
    // that the loop causes use to call sysctl with NULL again; this
 
144
    // is necessary because the ENOMEM failure case sets length to
 
145
    // the amount of data returned, not the amount of data that
 
146
    // could have been returned.
 
147
    result = NULL;
 
148
    done = false;
 
149
    *procCount = 0;
 
150
 
 
151
    do
 
152
    {
 
153
        // Call sysctl with a NULL buffer.
 
154
        length = 0;
 
155
        err = sysctl( (int *) name, ( sizeof( name ) / sizeof( *name ) ) - 1, NULL, &length, NULL, 0 );
 
156
        if (err == -1)
 
157
        {
 
158
            err = errno;
 
159
        }
 
160
 
 
161
        // Allocate an appropriately sized buffer based on the results
 
162
        // from the previous call.
 
163
        if ( err == 0 )
 
164
        {
 
165
            result = (kinfo_proc*)malloc( length );
 
166
            if ( result == NULL )
 
167
            {
 
168
                err = ENOMEM;
 
169
            }
 
170
        }
 
171
 
 
172
        // Call sysctl again with the new buffer.  If we get an ENOMEM
 
173
        // error, toss away our buffer and start again.
 
174
        if ( err == 0 )
 
175
        {
 
176
            err = sysctl( (int *) name, ( sizeof( name ) / sizeof( *name ) ) - 1, result, &length, NULL, 0 );
 
177
            if ( err == -1 )
 
178
            {
 
179
                err = errno;
 
180
            }
 
181
            if (err == 0)
 
182
            {
 
183
                done = true;
 
184
            } else if ( err == ENOMEM )
 
185
            {
 
186
                free( result );
 
187
                result = NULL;
 
188
                err = 0;
 
189
            }
 
190
        }
 
191
    } while ( err == 0 && !done );
 
192
 
 
193
    // Clean up and establish post conditions.
 
194
    if ( err != 0 && result != NULL )
 
195
    {
 
196
        free( result );
 
197
        result = NULL;
 
198
    }
 
199
 
 
200
    *procList = result;
 
201
    if ( err == 0 )
 
202
    {
 
203
        *procCount = length / sizeof( kinfo_proc );
 
204
    }
 
205
 
 
206
    return err;
 
207
}
 
208
 
 
209
 
 
210
bool
 
211
isProcessRunning( const QString& processName )
 
212
{
 
213
    bool found = false;
 
214
    
 
215
    kinfo_proc* processList = NULL;
 
216
    size_t processCount = 0;
 
217
 
 
218
    if ( getBsdProcessList( &processList, &processCount ) )
 
219
    {
 
220
        return false;
 
221
    }
 
222
 
 
223
    uint const uid = ::getuid();
 
224
    for ( size_t processIndex = 0; processIndex < processCount; processIndex++ )
 
225
    {
 
226
        if ( processList[processIndex].kp_eproc.e_pcred.p_ruid == uid )
 
227
        {
 
228
            if ( strcmp( processList[processIndex].kp_proc.p_comm, 
 
229
                         processName.toLocal8Bit() ) == 0 )
 
230
            {
 
231
                found = true;
 
232
                break;
 
233
            }
 
234
        }
 
235
    }
 
236
 
 
237
    free( processList );
 
238
    return found;
 
239
}
 
240
 
 
241
 
 
242
bool
 
243
UnicornUtils::isGrowlInstalled()
 
244
{
 
245
    return isProcessRunning( "GrowlHelperApp" );
 
246
}
 
247
 
 
248
 
 
249
bool
 
250
UnicornUtils::iTunesIsOpen()
 
251
{
 
252
    return isProcessRunning( "iTunes" );
 
253
}
 
254
 
 
255
 
 
256
bool
 
257
UnicornUtils::setPreferredAppForUrlScheme( const QUrl& url, const QString& app )
 
258
{
 
259
    QString scheme = url.scheme();
 
260
    CFStringRef urlStr = CFStringCreateWithCharacters( NULL, reinterpret_cast<const UniChar *>( scheme.unicode() ), scheme.length() );
 
261
    CFStringRef bundleStr = CFStringCreateWithCharacters( NULL, reinterpret_cast<const UniChar *>( app.unicode() ), app.length() );
 
262
 
 
263
    CFURLRef bundleURL;
 
264
    CFBundleRef bundleRef;
 
265
    bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, bundleStr, kCFURLPOSIXPathStyle, true );
 
266
    bundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL );
 
267
 
 
268
    CFStringRef appIdentifier = CFBundleGetIdentifier( bundleRef );
 
269
    OSStatus err = LSSetDefaultHandlerForURLScheme( urlStr, appIdentifier );
 
270
 
 
271
    CFRelease( urlStr );
 
272
    CFRelease( bundleStr );
 
273
    CFRelease( bundleURL );
 
274
    CFRelease( bundleRef );
 
275
 
 
276
    return ( err == noErr );
 
277
}
 
278
 
 
279
 
 
280
QString
 
281
UnicornUtils::preferredAppForUrlScheme( const QUrl& url )
 
282
{
 
283
    QString app;
 
284
    QString scheme = url.scheme() + "://";
 
285
 
 
286
    CFStringRef urlStr = CFStringCreateWithCharacters( NULL, reinterpret_cast<const UniChar *>( scheme.unicode() ), scheme.length() );
 
287
    CFURLRef urlRef = CFURLCreateWithString( NULL, urlStr, NULL );
 
288
 
 
289
    FSRef appRef;
 
290
    OSStatus err = LSGetApplicationForURL( urlRef, kLSRolesAll, &appRef, NULL );
 
291
 
 
292
    if ( err == noErr )
 
293
    {
 
294
        unsigned char path[512];
 
295
        err = ::FSRefMakePath( &appRef, path, 512 );
 
296
 
 
297
        if ( err == noErr )
 
298
            app = (const char*)path;
 
299
    }
 
300
 
 
301
    CFRelease( urlStr );
 
302
    CFRelease( urlRef );
 
303
 
 
304
    return QDir::cleanPath( app );
 
305
}