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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tk/] [mac/] [tkMacHLEvents.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/*
2
 * tkMacHLEvents.c --
3
 *
4
 *      Implements high level event support for the Macintosh.  Currently,
5
 *      the only event that really does anything is the Quit event.
6
 *
7
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tkMacHLEvents.c,v 1.1.1.1 2002-01-16 10:25:55 markom Exp $
13
 */
14
 
15
#include "tcl.h"
16
#include "tclMacInt.h"
17
#include "tkMacInt.h"
18
 
19
#include <Aliases.h>
20
#include <AppleEvents.h>
21
#include <SegLoad.h>
22
#include <ToolUtils.h>
23
 
24
/*
25
 * This is a Tcl_Event structure that the Quit AppleEvent handler
26
 * uses to schedule the tkReallyKillMe function.
27
 */
28
 
29
typedef struct KillEvent {
30
    Tcl_Event header;           /* Information that is standard for
31
                                 * all events. */
32
    Tcl_Interp *interp;         /* Interp that was passed to the
33
                                 * Quit AppleEvent */
34
} KillEvent;
35
 
36
/*
37
 * Static functions used only in this file.
38
 */
39
 
40
static pascal OSErr QuitHandler _ANSI_ARGS_((AppleEvent* event,
41
        AppleEvent* reply, long refcon));
42
static pascal OSErr OappHandler _ANSI_ARGS_((AppleEvent* event,
43
        AppleEvent* reply, long refcon));
44
static pascal OSErr OdocHandler _ANSI_ARGS_((AppleEvent* event,
45
        AppleEvent* reply, long refcon));
46
static pascal OSErr PrintHandler _ANSI_ARGS_((AppleEvent* event,
47
        AppleEvent* reply, long refcon));
48
static pascal OSErr ScriptHandler _ANSI_ARGS_((AppleEvent* event,
49
        AppleEvent* reply, long refcon));
50
static int MissedAnyParameters _ANSI_ARGS_((AppleEvent *theEvent));
51
static int ReallyKillMe _ANSI_ARGS_((Tcl_Event *eventPtr, int flags));
52
 
53
/*
54
 *----------------------------------------------------------------------
55
 *
56
 * TkMacInitAppleEvents --
57
 *
58
 *      Initilize the Apple Events on the Macintosh.  This registers the
59
 *      core event handlers.
60
 *
61
 * Results:
62
 *      None.
63
 *
64
 * Side effects:
65
 *      None.
66
 *
67
 *----------------------------------------------------------------------
68
 */
69
 
70
void
71
TkMacInitAppleEvents(
72
    Tcl_Interp *interp)         /* Interp to handle basic events. */
73
{
74
    OSErr err;
75
    AEEventHandlerUPP   OappHandlerUPP, OdocHandlerUPP,
76
        PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP;
77
 
78
    /*
79
     * Install event handlers for the core apple events.
80
     */
81
    QuitHandlerUPP = NewAEEventHandlerProc(QuitHandler);
82
    err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
83
            QuitHandlerUPP, (long) interp, false);
84
 
85
    OappHandlerUPP = NewAEEventHandlerProc(OappHandler);
86
    err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
87
            OappHandlerUPP, (long) interp, false);
88
 
89
    OdocHandlerUPP = NewAEEventHandlerProc(OdocHandler);
90
    err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
91
            OdocHandlerUPP, (long) interp, false);
92
 
93
    PrintHandlerUPP = NewAEEventHandlerProc(PrintHandler);
94
    err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
95
            PrintHandlerUPP, (long) interp, false);
96
 
97
    if (interp != NULL) {
98
        ScriptHandlerUPP = NewAEEventHandlerProc(ScriptHandler);
99
        err = AEInstallEventHandler('misc', 'dosc',
100
            ScriptHandlerUPP, (long) interp, false);
101
    }
102
}
103
 
104
/*
105
 *----------------------------------------------------------------------
106
 *
107
 * TkMacDoHLEvent --
108
 *
109
 *      Dispatch incomming highlevel events.
110
 *
111
 * Results:
112
 *      None.
113
 *
114
 * Side effects:
115
 *      Depends on the incoming event.
116
 *
117
 *----------------------------------------------------------------------
118
 */
119
 
120
void
121
TkMacDoHLEvent(
122
    EventRecord *theEvent)
123
{
124
    AEProcessAppleEvent(theEvent);
125
 
126
    return;
127
}
128
 
129
/*
130
 *----------------------------------------------------------------------
131
 *
132
 * QuitHandler, OappHandler, etc. --
133
 *
134
 *      These are the core Apple event handlers.  Only the Quit event does
135
 *      anything interesting.
136
 *
137
 * Results:
138
 *      None.
139
 *
140
 * Side effects:
141
 *      None.
142
 *
143
 *----------------------------------------------------------------------
144
 */
145
 
146
static pascal OSErr
147
QuitHandler(
148
    AppleEvent *theAppleEvent,
149
    AppleEvent *reply,
150
    long handlerRefcon)
151
{
152
    Tcl_Interp  *interp = (Tcl_Interp *) handlerRefcon;
153
    KillEvent *eventPtr;
154
 
155
    /*
156
     * Call the exit command from the event loop, since you are not supposed
157
     * to call ExitToShell in an Apple Event Handler.  We put this at the head
158
     * of Tcl's event queue because this message usually comes when the Mac is
159
     * shutting down, and we want to kill the shell as quickly as possible.
160
     */
161
 
162
    eventPtr = (KillEvent *) ckalloc(sizeof(KillEvent));
163
    eventPtr->header.proc = ReallyKillMe;
164
    eventPtr->interp = interp;
165
 
166
    Tcl_QueueEvent((Tcl_Event *) eventPtr, TCL_QUEUE_HEAD);
167
 
168
    return noErr;
169
}
170
 
171
static pascal OSErr
172
OappHandler(
173
    AppleEvent *theAppleEvent,
174
    AppleEvent *reply,
175
    long handlerRefcon)
176
{
177
    return noErr;
178
}
179
 
180
static pascal OSErr
181
OdocHandler(
182
    AppleEvent *theAppleEvent,
183
    AppleEvent *reply,
184
    long handlerRefcon)
185
{
186
    Tcl_Interp  *interp = (Tcl_Interp *) handlerRefcon;
187
    AEDescList fileSpecList;
188
    FSSpec file;
189
    OSErr err;
190
    DescType type;
191
    Size actual;
192
    long count;
193
    AEKeyword keyword;
194
    long index;
195
    Tcl_DString command;
196
    Tcl_DString pathName;
197
    Tcl_CmdInfo dummy;
198
 
199
    /*
200
     * Don't bother if we don't have an interp or
201
     * the open document procedure doesn't exist.
202
     */
203
 
204
    if ((interp == NULL) ||
205
        (Tcl_GetCommandInfo(interp, "tkOpenDocument", &dummy)) == 0) {
206
        return noErr;
207
    }
208
 
209
    /*
210
     * If we get any errors wil retrieving our parameters
211
     * we just return with no error.
212
     */
213
 
214
    err = AEGetParamDesc(theAppleEvent, keyDirectObject,
215
            typeAEList, &fileSpecList);
216
    if (err != noErr) {
217
        return noErr;
218
    }
219
 
220
    err = MissedAnyParameters(theAppleEvent);
221
    if (err != noErr) {
222
        return noErr;
223
    }
224
 
225
    err = AECountItems(&fileSpecList, &count);
226
    if (err != noErr) {
227
        return noErr;
228
    }
229
 
230
    Tcl_DStringInit(&command);
231
    Tcl_DStringInit(&pathName);
232
    Tcl_DStringAppend(&command, "tkOpenDocument", -1);
233
    for (index = 1; index <= count; index++) {
234
        int length;
235
        Handle fullPath;
236
 
237
        Tcl_DStringSetLength(&pathName, 0);
238
        err = AEGetNthPtr(&fileSpecList, index, typeFSS,
239
                &keyword, &type, (Ptr) &file, sizeof(FSSpec), &actual);
240
        if ( err != noErr ) {
241
            continue;
242
        }
243
 
244
        err = FSpPathFromLocation(&file, &length, &fullPath);
245
        HLock(fullPath);
246
        Tcl_DStringAppend(&pathName, *fullPath, length);
247
        HUnlock(fullPath);
248
        DisposeHandle(fullPath);
249
 
250
        Tcl_DStringAppendElement(&command, pathName.string);
251
    }
252
 
253
    Tcl_GlobalEval(interp, command.string);
254
 
255
    Tcl_DStringFree(&command);
256
    Tcl_DStringFree(&pathName);
257
    return noErr;
258
}
259
 
260
static pascal OSErr
261
PrintHandler(
262
    AppleEvent *theAppleEvent,
263
    AppleEvent *reply,
264
    long handlerRefcon)
265
{
266
    return noErr;
267
}
268
 
269
/*
270
 *----------------------------------------------------------------------
271
 *
272
 * DoScriptHandler --
273
 *
274
 *      This handler process the do script event.
275
 *
276
 * Results:
277
 *      Scedules the given event to be processed.
278
 *
279
 * Side effects:
280
 *      None.
281
 *
282
 *----------------------------------------------------------------------
283
 */
284
 
285
static pascal OSErr
286
ScriptHandler(
287
    AppleEvent *theAppleEvent,
288
    AppleEvent *reply,
289
    long handlerRefcon)
290
{
291
    OSErr theErr;
292
    AEDescList theDesc;
293
    int tclErr = -1;
294
    Tcl_Interp *interp;
295
    char errString[128];
296
 
297
    interp = (Tcl_Interp *) handlerRefcon;
298
 
299
    /*
300
     * The do script event receives one parameter that should be data or a file.
301
     */
302
    theErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard,
303
            &theDesc);
304
    if (theErr != noErr) {
305
        sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", theErr);
306
        theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString,
307
                strlen(errString));
308
    } else if (MissedAnyParameters(theAppleEvent)) {
309
        sprintf(errString, "AEDoScriptHandler: extra parameters");
310
        AEPutParamPtr(reply, keyErrorString, typeChar, errString,
311
                strlen(errString));
312
        theErr = -1771;
313
    } else {
314
        if (theDesc.descriptorType == (DescType)'TEXT') {
315
            short length, i;
316
 
317
            length = GetHandleSize(theDesc.dataHandle);
318
            SetHandleSize(theDesc.dataHandle, length + 1);
319
            *(*theDesc.dataHandle + length) = '\0';
320
            for (i=0; i<length; i++) {
321
                if ((*theDesc.dataHandle)[i] == '\r') {
322
                    (*theDesc.dataHandle)[i] = '\n';
323
                }
324
            }
325
 
326
            HLock(theDesc.dataHandle);
327
            tclErr = Tcl_GlobalEval(interp, *theDesc.dataHandle);
328
            HUnlock(theDesc.dataHandle);
329
        } else if (theDesc.descriptorType == (DescType)'alis') {
330
            Boolean dummy;
331
            FSSpec theFSS;
332
            Handle fullPath;
333
            int length;
334
 
335
            theErr = ResolveAlias(NULL, (AliasHandle)theDesc.dataHandle,
336
                    &theFSS, &dummy);
337
            if (theErr == noErr) {
338
                FSpPathFromLocation(&theFSS, &length, &fullPath);
339
                HLock(fullPath);
340
                Tcl_EvalFile(interp, *fullPath);
341
                HUnlock(fullPath);
342
                DisposeHandle(fullPath);
343
            } else {
344
                sprintf(errString, "AEDoScriptHandler: file not found");
345
                AEPutParamPtr(reply, keyErrorString, typeChar,
346
                        errString, strlen(errString));
347
            }
348
        } else {
349
            sprintf(errString,
350
                    "AEDoScriptHandler: invalid script type '%-4.4s', must be 'alis' or 'TEXT'",
351
                    &theDesc.descriptorType);
352
            AEPutParamPtr(reply, keyErrorString, typeChar,
353
                    errString, strlen(errString));
354
            theErr = -1770;
355
        }
356
    }
357
 
358
    /*
359
     * If we actually go to run Tcl code - put the result in the reply.
360
     */
361
    if (tclErr >= 0) {
362
        if (tclErr == TCL_OK)  {
363
            AEPutParamPtr(reply, keyDirectObject, typeChar,
364
                interp->result, strlen(interp->result));
365
        } else {
366
            AEPutParamPtr(reply, keyErrorString, typeChar,
367
                interp->result, strlen(interp->result));
368
            AEPutParamPtr(reply, keyErrorNumber, typeInteger,
369
                (Ptr) &tclErr, sizeof(int));
370
        }
371
    }
372
 
373
    AEDisposeDesc(&theDesc);
374
 
375
    return theErr;
376
}
377
 
378
/*
379
 *----------------------------------------------------------------------
380
 *
381
 * ReallyKillMe --
382
 *
383
 *      This proc tries to kill the shell by running exit, and if that
384
 *      has not succeeded (e.g. because someone has renamed the exit
385
 *      command), calls Tcl_Exit to really kill the shell.  Called from
386
 *      an event scheduled by the "Quit" AppleEvent handler.
387
 *
388
 * Results:
389
 *      Kills the shell.
390
 *
391
 * Side effects:
392
 *      None.
393
 *
394
 *----------------------------------------------------------------------
395
 */
396
 
397
int
398
ReallyKillMe(Tcl_Event *eventPtr, int flags)
399
{
400
    Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp;
401
    if (interp != NULL) {
402
        Tcl_GlobalEval(interp, "exit");
403
    }
404
    Tcl_Exit(0);
405
 
406
    return 1;
407
}
408
 
409
/*
410
 *----------------------------------------------------------------------
411
 *
412
 * MissedAnyParameters --
413
 *
414
 *      Checks to see if parameters are still left in the event.
415
 *
416
 * Results:
417
 *      True or false.
418
 *
419
 * Side effects:
420
 *      None.
421
 *
422
 *----------------------------------------------------------------------
423
 */
424
 
425
static int
426
MissedAnyParameters(
427
    AppleEvent *theEvent)
428
{
429
   DescType returnedType;
430
   Size actualSize;
431
   OSErr err;
432
 
433
   err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard,
434
                &returnedType, NULL, 0, &actualSize);
435
 
436
   return (err != errAEDescNotFound);
437
}

powered by: WebSVN 2.1.0

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