OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [mac/] [tclMacUtil.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclMacUtil.c --
3
 *
4
 *  This contains utility functions used to help with
5
 *  implementing Macintosh specific portions of the Tcl port.
6
 *
7
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
8
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
9
 *
10
 * See the file "license.terms" for information on usage and redistribution
11
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
 *
13
 * RCS: @(#) $Id: tclMacUtil.c,v 1.1.1.1 2002-01-16 10:25:35 markom Exp $
14
 */
15
 
16
#include "tcl.h"
17
#include "tclInt.h"
18
#include "tclMacInt.h"
19
#include "tclMath.h"
20
#include "tclMacPort.h"
21
 
22
#include <Aliases.h>
23
#include <Errors.h>
24
#include <Files.h>
25
#include <Folders.h>
26
#include <FSpCompat.h>
27
#include <Strings.h>
28
#include <TextUtils.h>
29
#include <MoreFilesExtras.h>
30
 
31
/*
32
 * The following two Includes are from the More Files package.
33
 */
34
#include <FileCopy.h>
35
#include <MoreFiles.h>
36
 
37
/*
38
 *----------------------------------------------------------------------
39
 *
40
 * hypotd --
41
 *
42
 *      The standard math function hypot is not supported by Think C.
43
 *      It is included here so everything works. It is supported by
44
 *      CodeWarrior Pro 1, but the 68K version does not support doubles.
45
 *      So we hack it in.
46
 *
47
 * Results:
48
 *      Result of computation.
49
 *
50
 * Side effects:
51
 *      None.
52
 *
53
 *----------------------------------------------------------------------
54
 */
55
 
56
#if defined(THINK_C) || defined(__MWERKS__)
57
double hypotd(double x, double y);
58
 
59
double
60
hypotd(
61
    double x,           /* X value */
62
    double y)           /* Y value */
63
{
64
    double sum;
65
 
66
    sum = x*x + y*y;
67
    return sqrt(sum);
68
}
69
#endif
70
 
71
/*
72
 *----------------------------------------------------------------------
73
 *
74
 * FSpGetDefaultDir --
75
 *
76
 *      This function gets the current default directory.
77
 *
78
 * Results:
79
 *      The provided FSSpec is changed to point to the "default"
80
 *      directory.  The function returns what ever errors
81
 *      FSMakeFSSpecCompat may encounter.
82
 *
83
 * Side effects:
84
 *      None.
85
 *
86
 *----------------------------------------------------------------------
87
 */
88
 
89
int
90
FSpGetDefaultDir(
91
        FSSpecPtr dirSpec)      /* On return the default directory. */
92
{
93
    OSErr err;
94
    short vRefNum = 0;
95
    long int dirID = 0;
96
 
97
    err = HGetVol(NULL, &vRefNum, &dirID);
98
 
99
    if (err == noErr) {
100
        err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL,
101
                dirSpec);
102
    }
103
 
104
    return err;
105
}
106
 
107
/*
108
 *----------------------------------------------------------------------
109
 *
110
 * FSpSetDefaultDir --
111
 *
112
 *      This function sets the default directory to the directory
113
 *      pointed to by the provided FSSpec.
114
 *
115
 * Results:
116
 *      The function returns what ever errors HSetVol may encounter.
117
 *
118
 * Side effects:
119
 *      None.
120
 *
121
 *----------------------------------------------------------------------
122
 */
123
 
124
int
125
FSpSetDefaultDir(
126
        FSSpecPtr dirSpec)      /* The new default directory. */
127
{
128
    OSErr err;
129
 
130
    /*
131
     * The following special case is needed to work around a bug
132
     * in the Macintosh OS.  (Acutally PC Exchange.)
133
     */
134
 
135
    if (dirSpec->parID == fsRtParID) {
136
        err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID);
137
    } else {
138
        err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID);
139
    }
140
 
141
    return err;
142
}
143
 
144
/*
145
 *----------------------------------------------------------------------
146
 *
147
 * FSpFindFolder --
148
 *
149
 *      This function is a version of the FindFolder function that
150
 *      returns the result as a FSSpec rather than a vRefNum and dirID.
151
 *
152
 * Results:
153
 *      Results will be simaler to that of the FindFolder function.
154
 *
155
 * Side effects:
156
 *      None.
157
 *
158
 *----------------------------------------------------------------------
159
 */
160
 
161
OSErr
162
FSpFindFolder(
163
    short vRefNum,              /* Volume reference number. */
164
    OSType folderType,          /* Folder type taken by FindFolder. */
165
    Boolean createFolder,       /* Should we create it if non-existant. */
166
    FSSpec *spec)               /* Pointer to resulting directory. */
167
{
168
    short foundVRefNum;
169
    long foundDirID;
170
    OSErr err;
171
 
172
    err = FindFolder(vRefNum, folderType, createFolder,
173
            &foundVRefNum, &foundDirID);
174
    if (err != noErr) {
175
        return err;
176
    }
177
 
178
    err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec);
179
    return err;
180
}
181
 
182
/*
183
 *----------------------------------------------------------------------
184
 *
185
 * FSpLocationFromPath --
186
 *
187
 *      This function obtains an FSSpec for a given macintosh path.
188
 *      Unlike the More Files function FSpLocationFromFullPath, this
189
 *      function will also accept partial paths and resolve any aliases
190
 *      along the path.
191
 *
192
 * Results:
193
 *      OSErr code.
194
 *
195
 * Side effects:
196
 *      None.
197
 *
198
 *----------------------------------------------------------------------
199
 */
200
 
201
int
202
FSpLocationFromPath(
203
    int length,                 /* Length of path. */
204
    CONST char *path,           /* The path to convert. */
205
    FSSpecPtr fileSpecPtr)      /* On return the spec for the path. */
206
{
207
    Str255 fileName;
208
    OSErr err;
209
    short vRefNum;
210
    long dirID;
211
    int pos, cur;
212
    Boolean isDirectory;
213
    Boolean wasAlias;
214
 
215
    /*
216
     * Check to see if this is a full path.  If partial
217
     * we assume that path starts with the current working
218
     * directory.  (Ie. volume & dir = 0)
219
     */
220
    vRefNum = 0;
221
    dirID = 0;
222
    cur = 0;
223
    if (length == 0) {
224
        return fnfErr;
225
    }
226
    if (path[cur] == ':') {
227
        cur++;
228
        if (cur >= length) {
229
            /*
230
             * If path = ":", just return current directory.
231
             */
232
            FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr);
233
            return noErr;
234
        }
235
    } else {
236
        while (path[cur] != ':' && cur < length) {
237
            cur++;
238
        }
239
        if (cur > 255) {
240
            return bdNamErr;
241
        }
242
        if (cur < length) {
243
            /*
244
             * This is a full path
245
             */
246
            cur++;
247
            strncpy((char *) fileName + 1, path, cur);
248
            fileName[0] = cur;
249
            err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr);
250
            if (err != noErr) return err;
251
            FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
252
            vRefNum = fileSpecPtr->vRefNum;
253
        } else {
254
            cur = 0;
255
        }
256
    }
257
 
258
    isDirectory = 1;
259
    while (cur < length) {
260
        if (!isDirectory) {
261
            return dirNFErr;
262
        }
263
        pos = cur;
264
        while (path[pos] != ':' && pos < length) {
265
            pos++;
266
        }
267
        if (pos == cur) {
268
            /* Move up one dir */
269
            /* cur++; */
270
            strcpy((char *) fileName + 1, "::");
271
            fileName[0] = 2;
272
        } else if (pos - cur > 255) {
273
            return bdNamErr;
274
        } else {
275
            strncpy((char *) fileName + 1, &path[cur], pos - cur);
276
            fileName[0] = pos - cur;
277
        }
278
        err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr);
279
        if (err != noErr) return err;
280
        err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias);
281
        if (err != noErr) return err;
282
        FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
283
        vRefNum = fileSpecPtr->vRefNum;
284
        cur = pos;
285
        if (path[cur] == ':') {
286
            cur++;
287
        }
288
    }
289
 
290
    return noErr;
291
}
292
 
293
/*
294
 *----------------------------------------------------------------------
295
 *
296
 * FSpPathFromLocation --
297
 *
298
 *      This function obtains a full path name for a given macintosh
299
 *      FSSpec.  Unlike the More Files function FSpGetFullPath, this
300
 *      function will return a C string in the Handle.  It also will
301
 *      create paths for FSSpec that do not yet exist.
302
 *
303
 * Results:
304
 *      OSErr code.
305
 *
306
 * Side effects:
307
 *      None.
308
 *
309
 *----------------------------------------------------------------------
310
 */
311
 
312
OSErr
313
FSpPathFromLocation(
314
    FSSpec *spec,               /* The location we want a path for. */
315
    int *length,                /* Length of the resulting path. */
316
    Handle *fullPath)           /* Handle to path. */
317
{
318
    OSErr err;
319
    FSSpec tempSpec;
320
    CInfoPBRec pb;
321
 
322
    *fullPath = NULL;
323
 
324
    /*
325
     * Make a copy of the input FSSpec that can be modified.
326
     */
327
    BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
328
 
329
    if (tempSpec.parID == fsRtParID) {
330
        /*
331
         * The object is a volume.  Add a colon to make it a full
332
         * pathname.  Allocate a handle for it and we are done.
333
         */
334
        tempSpec.name[0] += 2;
335
        tempSpec.name[tempSpec.name[0] - 1] = ':';
336
        tempSpec.name[tempSpec.name[0]] = '\0';
337
 
338
        err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
339
    } else {
340
        /*
341
         * The object isn't a volume.  Is the object a file or a directory?
342
         */
343
        pb.dirInfo.ioNamePtr = tempSpec.name;
344
        pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
345
        pb.dirInfo.ioDrDirID = tempSpec.parID;
346
        pb.dirInfo.ioFDirIndex = 0;
347
        err = PBGetCatInfoSync(&pb);
348
 
349
        if ((err == noErr) || (err == fnfErr)) {
350
            /*
351
             * If the file doesn't currently exist we start over.  If the
352
             * directory exists everything will work just fine.  Otherwise we
353
             * will just fail later.  If the object is a directory, append a
354
             * colon so full pathname ends with colon.
355
             */
356
            if (err == fnfErr) {
357
                BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
358
            } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) {
359
                tempSpec.name[0] += 1;
360
                tempSpec.name[tempSpec.name[0]] = ':';
361
            }
362
 
363
            /*
364
             * Create a new Handle for the object - make it a C string.
365
             */
366
            tempSpec.name[0] += 1;
367
            tempSpec.name[tempSpec.name[0]] = '\0';
368
            err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
369
            if (err == noErr) {
370
                /*
371
                 * Get the ancestor directory names - loop until we have an
372
                 * error or find the root directory.
373
                 */
374
                pb.dirInfo.ioNamePtr = tempSpec.name;
375
                pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
376
                pb.dirInfo.ioDrParID = tempSpec.parID;
377
                do {
378
                    pb.dirInfo.ioFDirIndex = -1;
379
                    pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
380
                    err = PBGetCatInfoSync(&pb);
381
                    if (err == noErr) {
382
                        /*
383
                         * Append colon to directory name and add
384
                         * directory name to beginning of fullPath.
385
                         */
386
                        ++tempSpec.name[0];
387
                        tempSpec.name[tempSpec.name[0]] = ':';
388
 
389
                        (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1],
390
                                tempSpec.name[0]);
391
                        err = MemError();
392
                    }
393
                } while ( (err == noErr) &&
394
                        (pb.dirInfo.ioDrDirID != fsRtDirID) );
395
            }
396
        }
397
    }
398
 
399
    /*
400
     * On error Dispose the handle, set it to NULL & return the err.
401
     * Otherwise, set the length & return.
402
     */
403
    if (err == noErr) {
404
        *length = GetHandleSize(*fullPath) - 1;
405
    } else {
406
        if ( *fullPath != NULL ) {
407
            DisposeHandle(*fullPath);
408
        }
409
        *fullPath = NULL;
410
        *length = 0;
411
    }
412
 
413
    return err;
414
}
415
 
416
/*
417
 *----------------------------------------------------------------------
418
 *
419
 * GetGlobalMouse --
420
 *
421
 *      This procedure obtains the current mouse position in global
422
 *      coordinates.
423
 *
424
 * Results:
425
 *      None.
426
 *
427
 * Side effects:
428
 *      None.
429
 *
430
 *----------------------------------------------------------------------
431
 */
432
 
433
void
434
GetGlobalMouse(
435
    Point *mouse)               /* Mouse position. */
436
{
437
    EventRecord event;
438
 
439
    OSEventAvail(0, &event);
440
    *mouse = event.where;
441
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.