~ubuntu-branches/ubuntu/feisty/basilisk2/feisty

« back to all changes in this revision

Viewing changes to src/MacOSX/sys_darwin.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2006-06-01 01:11:16 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060601011116-xjhegbgyfsxag5fl
Tags: 0.9.20060529-1
* New upstream CVS snapshot.
* Update local cdbs snippet copyright-check.mk:
  + Broaden scan to also look for "(c)" by default.
  + Make egrep options configurable.
  + Ignore auto-tools files.
* Bump up standards-version to 3.7.2 (no changes needed).
* Let dh_strip do the stripping (not the make install target).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *      $Id: sys_darwin.cpp,v 1.8 2005/06/12 23:36:33 gbeauche Exp $
 
2
 *      $Id: sys_darwin.cpp,v 1.9 2006/05/08 12:15:58 gbeauche Exp $
3
3
 *
4
4
 *      sys_darwin.cpp - Extra Darwin system dependant routines. Called by:
5
5
 *
38
38
#import <IOKit/storage/IOCDMediaBSDClient.h>
39
39
#import <CoreFoundation/CoreFoundation.h>
40
40
 
41
 
#import "sysdeps.h"
 
41
#include "sysdeps.h"
42
42
 
43
 
#import "prefs.h"
 
43
#include "sys.h"
 
44
#include "prefs.h"
44
45
 
45
46
#define DEBUG 0
46
47
#import "debug.h"
47
48
 
48
49
 
49
 
 
50
 
/*
51
 
 *  This gets called when no "cdrom" prefs items are found
52
 
 *  It scans for available CD-ROM drives and adds appropriate prefs items
53
 
 */
54
 
 
55
 
void DarwinAddCDROMPrefs(void)
56
 
{
57
 
        mach_port_t                             masterPort;     // The way to talk to the kernel
58
 
        io_iterator_t                   allCDs;         // List of CD drives on the system
59
 
        CFMutableDictionaryRef  classesToMatch;
60
 
        io_object_t                             nextCD;
61
 
 
62
 
 
63
 
        // Don't scan for drives if nocdrom option given
64
 
        if ( PrefsFindBool("nocdrom") )
65
 
                return;
66
 
 
67
 
 
68
 
        // Let this task talk to the guts of the kernel:
69
 
        if ( IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS )
70
 
                bug("IOMasterPort failed. Won't be able to do anything with CD drives\n");
71
 
 
72
 
 
73
 
        // CD media are instances of class kIOCDMediaClass
74
 
        classesToMatch = IOServiceMatching(kIOCDMediaClass); 
75
 
        if ( classesToMatch )
76
 
        {
77
 
                // Narrow the search a little further. Each IOMedia object
78
 
                // has a property with key kIOMediaEjectable.  We limit
79
 
                // the match only to those CDs that are actually ejectable
80
 
                CFDictionarySetValue(classesToMatch,
81
 
                                                         CFSTR(kIOMediaEjectableKey), kCFBooleanTrue); 
82
 
        }
83
 
 
84
 
        if ( IOServiceGetMatchingServices(masterPort,
85
 
                                                                          classesToMatch, &allCDs) != KERN_SUCCESS )
86
 
        {
87
 
                D(bug("IOServiceGetMatchingServices failed. No CD media drives found?\n"));
88
 
                return;
89
 
        }
90
 
 
91
 
 
92
 
        // Iterate through each CD drive
93
 
        while ( nextCD = IOIteratorNext(allCDs))
94
 
        {
95
 
                char            bsdPath[MAXPATHLEN];
96
 
                CFTypeRef       bsdPathAsCFString =
97
 
                                                IORegistryEntryCreateCFProperty(nextCD,
98
 
                                                                                                                CFSTR(kIOBSDNameKey),
99
 
                                                                                                                kCFAllocatorDefault, 0);
100
 
                *bsdPath = '\0';
101
 
                if ( bsdPathAsCFString )
102
 
                {
103
 
                        size_t devPathLength;
104
 
 
105
 
                        strcpy(bsdPath, "/dev/");
106
 
                        devPathLength = strlen(bsdPath);
107
 
 
108
 
                        if ( CFStringGetCString((const __CFString *)bsdPathAsCFString,
109
 
                                                                         bsdPath + devPathLength,
110
 
                                                                         MAXPATHLEN - devPathLength,
111
 
                                                                         kCFStringEncodingASCII) )
112
 
                        {
113
 
                                D(bug("CDROM BSD path: %s\n", bsdPath));
114
 
                                PrefsAddString("cdrom", bsdPath);
115
 
                        }
116
 
                        else
117
 
                                D(bug("Could not get BSD device path for CD\n"));
118
 
 
119
 
                        CFRelease(bsdPathAsCFString);
120
 
                }
121
 
                else
122
 
                        D(bug("Cannot determine bsdPath for CD\n"));
123
 
        }
124
 
 
125
 
        IOObjectRelease(nextCD);
126
 
        IOObjectRelease(allCDs);
 
50
// Global variables
 
51
static CFRunLoopRef media_poll_loop = NULL;
 
52
static bool media_thread_active = false;
 
53
static pthread_t media_thread;
 
54
 
 
55
// Prototypes
 
56
static void *media_poll_func(void *);
 
57
 
 
58
// From sys_unix.cpp
 
59
extern void SysMediaArrived(const char *path, int type);
 
60
extern void SysMediaRemoved(const char *path, int type);
 
61
 
 
62
 
 
63
/*
 
64
 *  Initialization
 
65
 */
 
66
 
 
67
void DarwinSysInit(void)
 
68
{
 
69
        media_thread_active = (pthread_create(&media_thread, NULL, media_poll_func, NULL) == 0);
 
70
        D(bug("Media poll thread installed (%ld)\n", media_thread));
 
71
}
 
72
 
 
73
 
 
74
/*
 
75
 *  Deinitialization
 
76
 */
 
77
 
 
78
void DarwinSysExit(void)
 
79
{
 
80
        // Stop media poll thread
 
81
        if (media_poll_loop)
 
82
                CFRunLoopStop(media_poll_loop);
 
83
        if (media_thread_active)
 
84
                pthread_join(media_thread, NULL);
 
85
}
 
86
 
 
87
 
 
88
/*
 
89
 *  Get the BSD-style path of specified object
 
90
 */
 
91
 
 
92
static kern_return_t get_device_path(io_object_t obj, char *path, size_t maxPathLength)
 
93
{
 
94
        kern_return_t kernResult = KERN_FAILURE;
 
95
        CFTypeRef pathAsCFString = IORegistryEntryCreateCFProperty(obj, CFSTR(kIOBSDNameKey),
 
96
                                                                                                                           kCFAllocatorDefault, 0);
 
97
        if (pathAsCFString) {
 
98
                strcpy(path, "/dev/");
 
99
                size_t pathLength = strlen(path);
 
100
                if (CFStringGetCString((const __CFString *)pathAsCFString,
 
101
                                                           path + pathLength,
 
102
                                                           maxPathLength - pathLength,
 
103
                                                           kCFStringEncodingASCII))
 
104
                        kernResult = KERN_SUCCESS;
 
105
                CFRelease(pathAsCFString);
 
106
        }
 
107
        return kernResult;
 
108
}
 
109
 
 
110
 
 
111
/*
 
112
 *  kIOMatchedNotification handler
 
113
 */
 
114
 
 
115
static void media_arrived(int type, io_iterator_t iterator)
 
116
{
 
117
        io_object_t obj;
 
118
        while ((obj = IOIteratorNext(iterator)) != NULL) {
 
119
                char path[MAXPATHLEN];
 
120
                kern_return_t kernResult = get_device_path(obj, path, sizeof(path));
 
121
                if (kernResult == KERN_SUCCESS) {
 
122
                        D(bug("Media Arrived: %s\n", path));
 
123
                        SysMediaArrived(path, type);
 
124
                }
 
125
                kernResult = IOObjectRelease(obj);
 
126
                if (kernResult != KERN_SUCCESS) {
 
127
                        fprintf(stderr, "IOObjectRelease() returned %d\n", kernResult);
 
128
                }
 
129
        }
 
130
}
 
131
 
 
132
 
 
133
/*
 
134
 *  kIOTerminatedNotification handler
 
135
 */
 
136
 
 
137
static void media_removed(int type, io_iterator_t iterator)
 
138
{
 
139
        io_object_t obj;
 
140
        while ((obj = IOIteratorNext(iterator)) != NULL) {
 
141
                char path[MAXPATHLEN];
 
142
                kern_return_t kernResult = get_device_path(obj, path, sizeof(path));
 
143
                if (kernResult == KERN_SUCCESS) {
 
144
                        D(bug("Media Removed: %s\n", path));
 
145
                        SysMediaRemoved(path, type);
 
146
                }
 
147
                kernResult = IOObjectRelease(obj);
 
148
                if (kernResult != KERN_SUCCESS) {
 
149
                        fprintf(stderr, "IOObjectRelease() returned %d\n", kernResult);
 
150
                }
 
151
        }
 
152
}
 
153
 
 
154
 
 
155
/*
 
156
 *  Media poll function
 
157
 */
 
158
 
 
159
static void *media_poll_func(void *)
 
160
{
 
161
        media_poll_loop = CFRunLoopGetCurrent();
 
162
 
 
163
        mach_port_t masterPort;
 
164
        kern_return_t kernResult = IOMasterPort(bootstrap_port, &masterPort);
 
165
        if (kernResult != KERN_SUCCESS) {
 
166
                fprintf(stderr, "IOMasterPort() returned %d\n", kernResult);
 
167
                return NULL;
 
168
        }
 
169
 
 
170
        CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOCDMediaClass);
 
171
        if (matchingDictionary == NULL) {
 
172
                fprintf(stderr, "IOServiceMatching() returned a NULL dictionary\n");
 
173
                return NULL;
 
174
        }
 
175
        matchingDictionary = (CFMutableDictionaryRef)CFRetain(matchingDictionary);
 
176
 
 
177
        IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
 
178
        CFRunLoopAddSource(media_poll_loop,
 
179
                                           IONotificationPortGetRunLoopSource(notificationPort),
 
180
                                           kCFRunLoopDefaultMode);
 
181
 
 
182
        io_iterator_t mediaArrivedIterator;
 
183
        kernResult = IOServiceAddMatchingNotification(notificationPort,
 
184
                                                                                                  kIOMatchedNotification,
 
185
                                                                                                  matchingDictionary,
 
186
                                                                                                  (IOServiceMatchingCallback)media_arrived,
 
187
                                                                                                  (void *)MEDIA_CD, &mediaArrivedIterator);
 
188
        if (kernResult != KERN_SUCCESS)
 
189
                fprintf(stderr, "IOServiceAddMatchingNotification() returned %d\n", kernResult);
 
190
        media_arrived(MEDIA_CD, mediaArrivedIterator);
 
191
 
 
192
        io_iterator_t mediaRemovedIterator;
 
193
        kernResult = IOServiceAddMatchingNotification(notificationPort,
 
194
                                                                                                  kIOTerminatedNotification,
 
195
                                                                                                  matchingDictionary,
 
196
                                                                                                  (IOServiceMatchingCallback)media_removed,
 
197
                                                                                                  (void *)MEDIA_CD, &mediaRemovedIterator);
 
198
        if (kernResult != KERN_SUCCESS)
 
199
                fprintf(stderr, "IOServiceAddMatchingNotification() returned %d\n", kernResult);
 
200
        media_removed(MEDIA_CD, mediaRemovedIterator);
 
201
 
 
202
        CFRunLoopRun();
 
203
        return NULL;
127
204
}
128
205
 
129
206