diff options
author | Jack Jansen <jack.jansen@cwi.nl> | 1998-08-18 14:54:11 (GMT) |
---|---|---|
committer | Jack Jansen <jack.jansen@cwi.nl> | 1998-08-18 14:54:11 (GMT) |
commit | 7cc5735ef26a60df9d1bc3554c1912f951a90308 (patch) | |
tree | 5c391a5a9b8e4f6d1932205d9d8ff1283542caef /Mac | |
parent | 1d6a6ea1a819a645a3a8841205b10cf33eb04493 (diff) | |
download | cpython-7cc5735ef26a60df9d1bc3554c1912f951a90308.zip cpython-7cc5735ef26a60df9d1bc3554c1912f951a90308.tar.gz cpython-7cc5735ef26a60df9d1bc3554c1912f951a90308.tar.bz2 |
Initial revision
Diffstat (limited to 'Mac')
24 files changed, 5316 insertions, 0 deletions
diff --git a/Mac/Contrib/BBPy/PythonSlave.py b/Mac/Contrib/BBPy/PythonSlave.py new file mode 100644 index 0000000..cc63e1d --- /dev/null +++ b/Mac/Contrib/BBPy/PythonSlave.py @@ -0,0 +1,129 @@ +"""PythonSlave.py +An application that responds to three types of apple event: + 'pyth'/'EXEC': execute direct parameter as Python + 'aevt', 'quit': quit + 'aevt', 'odoc': perform python scripts + +Copyright © 1996, Just van Rossum, Letterror +""" + +__version__ = "0.1.3" + +import FrameWork +import sys +import traceback +import aetools +import string +import AE +import EasyDialogs +import os +import Qd +from Types import * +from Events import charCodeMask, cmdKey +import MacOS +import Evt + +def dummyfunc(): pass + +modulefilename = dummyfunc.func_code.co_filename + +def Interact(timeout = 50000000): # timeout after 10 days... + AE.AEInteractWithUser(timeout) + + +class PythonSlave(FrameWork.Application): + def __init__(self): + FrameWork.Application.__init__(self) + AE.AEInstallEventHandler('pyth', 'EXEC', ExecHandler) + AE.AEInstallEventHandler('aevt', 'quit', QuitHandler) + AE.AEInstallEventHandler('aevt', 'odoc', OpenDocumentHandler) + + def makeusermenus(self): + self.filemenu = m = FrameWork.Menu(self.menubar, "File") + self._quititem = FrameWork.MenuItem(m, "Quit", "Q", self._quit) + + def do_kHighLevelEvent(self, event): + (what, message, when, where, modifiers) = event + try: + AE.AEProcessAppleEvent(event) + except AE.Error, detail: + print "Apple Event was not handled, error:", detail + + def do_key(self, event): + (what, message, when, where, modifiers) = event + c = chr(message & charCodeMask) + if modifiers & cmdKey and c == '.': + return + FrameWork.Application.do_key(self, event) + + def idle(self, event): + Qd.InitCursor() + + def quit(self, *args): + raise self + + def getabouttext(self): + return "About PythonSlaveŠ" + + def do_about(self, id, item, window, event): + EasyDialogs.Message("PythonSlave " + __version__ + "\rCopyright © 1996, Letterror, JvR") + + +def ExecHandler(theAppleEvent, theReply): + parameters, args = aetools.unpackevent(theAppleEvent) + if parameters.has_key('----'): + if parameters.has_key('NAME'): + print '--- executing "' + parameters['NAME'] + '" ---' + else: + print '--- executing "<unknown>" ---' + stuff = parameters['----'] + MyExec(stuff + "\n") # execute input + print '--- done ---' + return 0 + +def MyExec(stuff): + stuff = string.splitfields(stuff, '\r') # convert return chars + stuff = string.joinfields(stuff, '\n') # to newline chars + Interact() + saveyield = MacOS.EnableAppswitch(1) + try: + exec stuff in {} + except: + MacOS.EnableAppswitch(saveyield) + traceback.print_exc() + MacOS.EnableAppswitch(saveyield) + +def OpenDocumentHandler(theAppleEvent, theReply): + parameters, args = aetools.unpackevent(theAppleEvent) + docs = parameters['----'] + if type(docs) <> ListType: + docs = [docs] + for doc in docs: + fss, a = doc.Resolve() + path = fss.as_pathname() + if path <> modulefilename: + MyExecFile(path) + return 0 + +def MyExecFile(path): + saveyield = MacOS.EnableAppswitch(1) + savewd = os.getcwd() + os.chdir(os.path.split(path)[0]) + print '--- Executing file "' + os.path.split(path)[1] + '"' + try: + execfile(path, {"__name__": "__main__"}) + except: + traceback.print_exc() + MacOS.EnableAppswitch(saveyield) + MacOS.EnableAppswitch(saveyield) + os.chdir(savewd) + print "--- done ---" + +def QuitHandler(theAppleEvent, theReply): + slave.quit() + return 0 + + +slave = PythonSlave() +print "PythonSlave", __version__, "ready." +slave.mainloop() diff --git a/Mac/Contrib/BBPy/README b/Mac/Contrib/BBPy/README new file mode 100644 index 0000000..6f0a2a0 --- /dev/null +++ b/Mac/Contrib/BBPy/README @@ -0,0 +1,41 @@ +"Run as Python" -- a BBEdit extension to make the Python interpreter execute the +contents of the current window. + +version 0.2.3, 18 september 1996 + +contents: +- "Run as Python" -- the extension +- PythonSlave.py -- the "slave" script that handles the AppleEvents + +- source -- source code & CW9 project for the extension + +quickstart: +- drop "Run as Python" in BBEdit extensions folder +- double-click PythonSlave.py +- start BBEdit +- type some code +- go to Extensions menu: "Run as Python" +- be happy + +warning: + since PythonSlave.py runs its own event loop and we have no interface + to SIOUX you *cannot* copy from the console. Duh. + +extra feature: + while PythonSlave.py is running you can still double-click Python + documents, they will get executed as if Python was not already running. + +bugs: + perhaps + +acknowledgements: +- Thanks to Joseph Strout for valuable input and beta testing. +- Thanks to Mark Roseman for providing code that can launch + PythonSlave.py from BBEdit. + + +Have fun with it! +Please report bugs, or fix 'em. Suggestions are always welcome. + +Just van Rossum, Letterror +<just@knoware.nl> diff --git a/Mac/Contrib/BBPy/source/BB stuff/ExternalInterface.h b/Mac/Contrib/BBPy/source/BB stuff/ExternalInterface.h new file mode 100644 index 0000000..51d206d --- /dev/null +++ b/Mac/Contrib/BBPy/source/BB stuff/ExternalInterface.h @@ -0,0 +1,716 @@ +#pragma once + +#include <MixedMode.h> +#include <Dialogs.h> +#include <Files.h> +#include <Windows.h> +#include <AppleEvents.h> +#include <StandardFile.h> + +#if defined(powerc) || defined (__powerc) +#pragma options align=mac68k +#endif + +typedef struct +{ + FSSpec spec; // designates file on disk + long key; // reserved for future expansion + + char tree; // 0 for absolute, 1 for project, 2 for system + Boolean found; // FALSE if file couldn't be located; if so, all other info is moot + + OSType type; // file type of found file + OSType crtr; // signature of found file's creator + + short spare0; // reserved for future expansion + long spare1; +} ProjectEntry; + +enum +{ + kNeitherTree, + kProjectTree, + kSystemTree +}; + +enum +{ + kTHINKCProject, + kTHINKPascalProject, + kCodeWarriorProject +}; + +// masks for the "flags" argument to new-convention interfaces + +#define xfWindowOpen 0x00000001 +#define xfWindowChangeable 0x00000002 +#define xfHasSelection 0x00000004 +#define xfUseDefaults 0x00000008 +#define xfIsBBEditLite 0x00000040 +#define xfIsBBEditDemo 0x00000080 + +typedef struct +{ + FSSpec spec; + OSType key; + + short error_kind; + long line_number; + + Str255 message; +} ErrorEntry; + +typedef enum +{ + kNote = 0, + kError, + kWarning +} ErrorKind; + +#define kCurrentExternalVersion 5 // current version of callbacks + +// Universal callback interfaces + +#if USESROUTINEDESCRIPTORS + +#define ExtensionUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr)))) + +#define NewExtensionUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(AppleEvent *))) \ + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(AppleEvent *)))) + +#define GetWindowContentsUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))) + +#define GetSelectionUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *)))) + +#define SetSelectionUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))) + +#define GetDocInfoUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long *)))) + +#define GetModDateUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))) + +#define CopyUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle)))) + +#define PasteUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Handle)))) + +#define GetLastLineUPPInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))) + +#define GetLineNumberUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define GetLineStartUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define GetLineEndUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define GetLinePosUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define InsertUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))) + +#define DeleteUPPInfo (kPascalStackBased) + +#define SetWindowContentsUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))) + +#define ContentsChangedUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))) + +#define GetFileTextUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))) + +#define GetFolderUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *)))) + +#define OpenSeveralUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StandardFileReply ***)))) + +#define CenterDialogUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(DialogPtr))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))) + +#define StandardFilterUPPInfo uppModalFilterProcInfo + +#define FrameDialogItemUPPInfo uppUserItemProcInfo + +#define NewDocumentUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr)))) + +#define OpenDocumentUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr)))) + +#define AllocateUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)))) + +#define FindPatternUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(char *))) \ + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(Boolean)))) + +#define ReportOSErrorUPPInfo (kPascalStackBased) + +#define GetPreferenceUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *)))) + +#define SetPreferenceUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *)))) + +#define StartProgressUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean)))) + +#define DoProgressUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define DoneProgressUPPInfo (kPascalStackBased) + +#define GetProjectListUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ProjectEntry***)))) + +#define ProjectTextListUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle *)))) + +#define PresetUndoUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))) + +#define SetUndoUPPInfo (kPascalStackBased) + +#define OpenFileUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr *)))) + +#define PrepareUndoUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))) + +#define CommitUndoUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define CreateResultsUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(WindowPtr *)))) + +typedef UniversalProcPtr GetWindowContentsProc; +typedef UniversalProcPtr GetSelectionProc; +typedef UniversalProcPtr SetSelectionProc; +typedef UniversalProcPtr GetDocInfoProc; +typedef UniversalProcPtr GetModDateProc; +typedef UniversalProcPtr CopyProc; +typedef UniversalProcPtr PasteProc; + +typedef UniversalProcPtr GetLastLineProc; +typedef UniversalProcPtr GetLineNumberProc; +typedef UniversalProcPtr GetLineStartProc; +typedef UniversalProcPtr GetLineEndProc; +typedef UniversalProcPtr GetLinePosProc; + +typedef UniversalProcPtr InsertProc; +typedef UniversalProcPtr DeleteProc; + +typedef UniversalProcPtr SetWindowContentsProc; +typedef UniversalProcPtr ContentsChangedProc; + +typedef UniversalProcPtr GetFileTextProc; + +typedef UniversalProcPtr GetFolderProc; +typedef UniversalProcPtr OpenSeveralProc; + +typedef UniversalProcPtr CenterDialogProc; +typedef UniversalProcPtr StandardFilterProc; +typedef UniversalProcPtr FrameDialogItemProc; + +typedef UniversalProcPtr NewDocumentProc; +typedef UniversalProcPtr OpenDocumentProc; + +typedef UniversalProcPtr AllocateProc; +typedef UniversalProcPtr FindPatternProc; + +typedef UniversalProcPtr ReportOSErrorProc; + +typedef UniversalProcPtr GetPreferenceProc; +typedef UniversalProcPtr SetPreferenceProc; + +typedef UniversalProcPtr StartProgressProc; +typedef UniversalProcPtr DoProgressProc; +typedef UniversalProcPtr DoneProgressProc; + +typedef UniversalProcPtr GetProjectListProc; +typedef UniversalProcPtr ProjectTextListProc; + +typedef UniversalProcPtr PresetUndoProc; +typedef UniversalProcPtr SetUndoProc; + +typedef UniversalProcPtr OpenFileProc; + +typedef UniversalProcPtr PrepareUndoProc; +typedef UniversalProcPtr CommitUndoProc; + +typedef UniversalProcPtr CreateResultsProc; + +#define CallGetWindowContents(proc, w) \ + (Handle)(CallUniversalProc(proc, GetWindowContentsUPPInfo, (w))) + +#define CallGetSelection(proc, selStart, selEnd, firstChar) \ + (CallUniversalProc(proc, GetSelectionUPPInfo, (selStart), (selEnd), (firstChar))) + +#define CallSetSelection(proc, selStart, selEnd, firstChar) \ + (CallUniversalProc(proc, SetSelectionUPPInfo, (selStart), (selEnd), (firstChar))) + +#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \ + (CallUniversalProc(proc, GetDocInfoUPPInfo, (w), (name), (vRefNum), (dirID))) + +#define CallGetModDate(proc, w) \ + (CallUniversalProc(proc, GetModDateUPPInfo, (w))) + +#define CallCopy(proc) \ + (Handle)(CallUniversalProc(proc, CopyUPPInfo)) + +#define CallPaste(proc, h) \ + (CallUniversalProc(proc, PasteUPPInfo, (h))) + +#define CallGetLastLine(proc) \ + (CallUniversalProc(proc, GetLastLineUPPInfo)) + +#define CallGetLineNumber(proc, sel) \ + (CallUniversalProc(proc, GetLineNumberUPPInfo, (sel))) + +#define CallGetLineStart(proc, sel) \ + (CallUniversalProc(proc, GetLineStartUPPInfo, (sel))) + +#define CallGetLineEnd(proc, sel) \ + (CallUniversalProc(proc, GetLineEndUPPInfo, (sel))) + +#define CallGetLinePos(proc, sel) \ + (CallUniversalProc(proc, GetLinePosUPPInfo, (sel))) + +#define CallInsert(proc, text, len) \ + (CallUniversalProc(proc, InsertUPPInfo, (text), (len))) + +#define CallDelete(proc) \ + (CallUniversalProc(proc, DeleteUPPInfo)) + +#define CallSetWindowContents(proc, w, h) \ + (CallUniversalProc(proc, SetWindowContentsUPPInfo, (w), (h))) + +#define CallContentsChanged(proc, w) \ + (CallUniversalProc(proc, ContentsChangedUPPInfo, (w))) + +#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \ + (Handle)(CallUniversalProc(proc, GetFileTextUPPInfo, (vRefNum), (dirID), (name), (canDispose))) + +#define CallGetFolder(proc, prompt, vRefNum, dirID) \ + (Boolean)(CallUniversalProc(proc, GetFolderUPPInfo, (prompt), (vRefNum), (dirID))) + +#define CallOpenSeveral(proc, sort, file_count, files) \ + (Boolean)(CallUniversalProc(proc, OpenSeveralUPPInfo, (sort), (file_count), (files))) + +#define CallCenterDialog(proc, dialogID) \ + (DialogPtr)(CallUniversalProc(proc, CenterDialogUPPInfo, (dialogID))) + +#define CallStandardFilter(proc, d, event, item) \ + CallModalFilterProc(proc, (d), (event), (item)) + +#define CallFrameDialogItem(proc, d, item) \ + CallUserItemProc(proc, (d), (item)) + +#define CallNewDocument(proc) \ + (WindowPtr)(CallUniversalProc(proc, NewDocumentUPPInfo)) + +#define CallOpenDocument(proc) \ + (WindowPtr)(CallUniversalProc(proc, OpenDocumentUPPInfo)) + +#define CallAllocate(proc, size, clear) \ + (Handle)(CallUniversalProc(proc, AllocateUPPInfo, (size), (clear))) + +#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \ + (CallUniversalProc(proc, FindPatternUPPInfo, (text), (text_len), (text_offset), \ + (pat), (pat_len), (case_sens))) + +#define CallReportOSError(proc, code) \ + (CallUniversalProc(proc, ReportOSErrorUPPInfo, (code))) + +#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \ + (CallUniversalProc(proc, GetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len))) + +#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \ + (CallUniversalProc(proc, SetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len))) + +#define CallStartProgress(proc, str, total, cancel_allowed) \ + (CallUniversalProc(proc, StartProgressUPPInfo, (str), (total), (cancel_allowed))) + +#define CallDoProgress(proc, done) \ + (Boolean)(CallUniversalProc(proc, DoProgressUPPInfo, (done))) + +#define CallDoneProgress(proc) \ + (CallUniversalProc(proc, DoneProgressUPPInfo)) + +#define CallGetProjectList(proc, spec, kind, count, entries) \ + (Boolean)(CallUniversalProc(proc, GetProjectListUPPInfo, (spec), (kind), (count), (entries))) + +#define CallProjectTextList(proc, spec, text) \ + (Boolean)(CallUniversalProc(proc, ProjectTextListUPPInfo, (spec), (text))) + +#define CallPresetUndo(proc) \ + (Boolean)(CallUniversalProc(proc, PresetUndoUPPInfo)) + +#define CallSetUndo(proc) \ + (CallUniversalProc(proc, SetUndoUPPInfo)) + +#define CallOpenFile(proc, spec, w) \ + (Boolean)(CallUniversalProc(proc, OpenFileUPPInfo, (spec), (w))) + +#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \ + (Boolean)(CallUniversalProc(proc, PrepareUndoUPPInfo, (undo_start), (undo_end), \ + (sel_start), (sel_end))) + +#define CallCommitUndo(proc, new_end) \ + (CallUniversalProc(proc, CommitUndoUPPInfo, (new_end))) + +#define CallCreateResults(proc, title, count, results, w) \ + (Boolean)(CallUniversalProc(proc, CreateResultsUPPInfo, (title), (count), (results), (w))) + +#else + +typedef pascal Handle (*GetWindowContentsProc)(WindowPtr w); +typedef pascal void (*GetSelectionProc)(long *selStart, long *selEnd, long *firstChar); +typedef pascal void (*SetSelectionProc)(long selStart, long selEnd, long firstChar); +typedef pascal void (*GetDocInfoProc)(WindowPtr w, Str255 fName, short *vRefNum, long *dirID); +typedef pascal long (*GetModDateProc)(WindowPtr w); +typedef pascal Handle (*CopyProc)(void); +typedef pascal void (*PasteProc)(Handle pasteText); + +typedef pascal long (*GetLastLineProc)(void); +typedef pascal long (*GetLineNumberProc)(long selection); +typedef pascal long (*GetLineStartProc)(long selection); +typedef pascal long (*GetLineEndProc)(long selection); +typedef pascal long (*GetLinePosProc)(long line); + +typedef pascal void (*InsertProc)(char *text, long len); +typedef pascal void (*DeleteProc)(void); + +typedef pascal void (*SetWindowContentsProc)(WindowPtr w, Handle h); +typedef pascal void (*ContentsChangedProc)(WindowPtr w); + +typedef pascal Handle (*GetFileTextProc)(short vRefNum, long dirID, Str255 fName, Boolean *canDispose); + +typedef pascal Boolean (*GetFolderProc)(Str255 prompt, short *vRefNum, long *dirID); +typedef pascal Boolean (*OpenSeveralProc)(Boolean sort, short *file_count, StandardFileReply ***files); + +typedef pascal DialogPtr (*CenterDialogProc)(short dialogID); +typedef pascal Boolean (*StandardFilterProc)(DialogPtr d, EventRecord *event, short *item); +typedef pascal void (*FrameDialogItemProc)(DialogPtr d, short item); + +typedef pascal WindowPtr (*NewDocumentProc)(void); +typedef pascal WindowPtr (*OpenDocumentProc)(void); + +typedef pascal Handle (*AllocateProc)(long size, Boolean clear); +typedef pascal long (*FindPatternProc)(char *text, long text_len, long text_offset, + char *pat, long pat_len, + Boolean case_sensitive); + +typedef pascal void (*ReportOSErrorProc)(short code); + +typedef pascal void (*GetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len); +typedef pascal void (*SetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len); + +typedef pascal void (*StartProgressProc)(Str255 str, long total, Boolean cancel_allowed); +typedef pascal Boolean (*DoProgressProc)(long done); +typedef pascal void (*DoneProgressProc)(void); + +typedef pascal Boolean (*GetProjectListProc)(FSSpec *spec, short *kind, short *count, ProjectEntry ***entries); +typedef pascal Boolean (*ProjectTextListProc)(FSSpec *spec, Handle *text); + +typedef pascal Boolean (*PresetUndoProc)(void); +typedef pascal void (*SetUndoProc)(void); + +typedef pascal Boolean (*OpenFileProc)(FSSpec *spec, WindowPtr *w); + +typedef pascal Boolean (*PrepareUndoProc)(long undo_start, long undo_end, + long sel_start, long sel_end); +typedef pascal void (*CommitUndoProc)(long new_end); + +typedef pascal Boolean (*CreateResultsProc)(Str255 title, short count, Handle results, WindowPtr *w); + +#define CallGetWindowContents(proc, w) \ + ((proc))((w)) + +#define CallGetSelection(proc, selStart, selEnd, firstChar) \ + ((proc))((selStart), (selEnd), (firstChar)) + +#define CallSetSelection(proc, selStart, selEnd, firstChar) \ + ((proc))((selStart), (selEnd), (firstChar)) + +#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \ + ((proc))((w), (name), (vRefNum), (dirID)) + +#define CallGetModDate(proc, w) \ + ((proc))((w)) + +#define CallCopy(proc) \ + ((proc))() + +#define CallPaste(proc, h) \ + ((proc))((h)) + +#define CallGetLastLine(proc) \ + ((proc))() + +#define CallGetLineNumber(proc, sel) \ + ((proc))((sel)) + +#define CallGetLineStart(proc, sel) \ + ((proc))((sel)) + +#define CallGetLineEnd(proc, sel) \ + ((proc))((sel)) + +#define CallGetLinePos(proc, sel) \ + ((proc))((sel)) + +#define CallInsert(proc, text, len) \ + ((proc))((text), (len)) + +#define CallDelete(proc) \ + ((proc))() + +#define CallSetWindowContents(proc, w, h) \ + ((proc))((w), (h)) + +#define CallContentsChanged(proc, w) \ + ((proc))((w)) + +#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \ + ((proc))((vRefNum), (dirID), (name), (canDispose)) + +#define CallGetFolder(proc, prompt, vRefNum, dirID) \ + ((proc))((prompt), (vRefNum), (dirID)) + +#define CallOpenSeveral(proc, sort, file_count, files) \ + ((proc))((sort), (file_count), (files)) + +#define CallCenterDialog(proc, dialogID) \ + ((proc))((dialogID)) + +#define CallStandardFilter(proc, d, event, item) \ + ((proc))((d), (event), (item)) + +#define CallFrameDialogItem(proc, d, item) \ + ((proc))((d), (item)) + +#define CallNewDocument(proc) \ + ((proc))() + +#define CallOpenDocument(proc) \ + ((proc))() + +#define CallAllocate(proc, size, clear) \ + ((proc))((size), (clear)) + +#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \ + ((proc))((text), (text_len), (text_offset), (pat), (pat_len), (case_sens)) + +#define CallReportOSError(proc, code) \ + ((proc))((code)) + +#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \ + ((proc))((prefType), (req_len), (buffer), (act_len)) + +#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \ + ((proc))((prefType), (req_len), (buffer), (act_len)) + +#define CallStartProgress(proc, str, total, cancel_allowed) \ + ((proc))((str), (total), (cancel_allowed)) + +#define CallDoProgress(proc, done) \ + ((proc))((done)) + +#define CallDoneProgress(proc) \ + ((proc))() + +#define CallGetProjectList(proc, spec, kind, count, entries) \ + ((proc))((spec), (kind), (count), (entries)) + +#define CallProjectTextList(proc, spec, text) \ + ((proc))((spec), (text)) + +#define CallPresetUndo(proc) \ + ((proc))() + +#define CallSetUndo(proc) \ + ((proc))() + +#define CallOpenFile(proc, spec, w) \ + ((proc))((spec), (w)) + +#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \ + ((proc))((undo_start), (undo_end), (sel_start), (sel_end)) + +#define CallCommitUndo(proc, new_end) \ + ((proc))((new_end)) + +#define CallCreateResults(proc, title, count, results, w) \ + ((proc))((title), (count), (results), (w)) + +#endif + + +typedef struct +{ + short version; + + // version 1 callbacks + + GetWindowContentsProc GetWindowContents; + GetSelectionProc GetSelection; + SetSelectionProc SetSelection; + GetDocInfoProc GetDocInfo; + GetModDateProc GetModDate; + CopyProc Copy; + PasteProc Paste; + + // version 2 callbacks + + /* Text-Editing stuff */ + GetLastLineProc GetLastLine; + GetLineNumberProc GetLineNumber; + GetLineStartProc GetLineStart; + GetLineEndProc GetLineEnd; + GetLinePosProc GetLinePos; + + InsertProc Insert; + DeleteProc Delete; + + /* Getting and Setting window text */ + SetWindowContentsProc SetWindowContents; + ContentsChangedProc ContentsChanged; + + /* Reading file text */ + GetFileTextProc GetFileText; + + /* Direct user-interface calls */ + GetFolderProc GetFolder; + OpenSeveralProc OpenSeveral; + + CenterDialogProc CenterDialog; + StandardFilterProc StandardFilter; + FrameDialogItemProc FrameDialogItem; + + NewDocumentProc NewDocument; + OpenDocumentProc OpenDocument; + + /* Utility Routines */ + AllocateProc Allocate; + FindPatternProc FindPattern; + + ReportOSErrorProc ReportOSError; + + /* Preference routines */ + GetPreferenceProc GetPreference; + SetPreferenceProc SetPreference; + + /* Progress routines */ + StartProgressProc StartProgress; + DoProgressProc DoProgress; + DoneProgressProc DoneProgress; + + // Version 3 callbacks + GetProjectListProc GetProjectList; + ProjectTextListProc ProjectTextList; + + // version 4 callbacks + + PresetUndoProc PresetUndo; + SetUndoProc SetUndo; + + OpenFileProc OpenFile; + + // version 5 callbacks + + PrepareUndoProc PrepareUndo; + CommitUndoProc CommitUndo; + + CreateResultsProc CreateResults; + +} ExternalCallbackBlock; + +#if defined(powerc) || defined (__powerc) +#pragma options align=reset +#endif + +/* + 'main' for a BBXT is declared: + +pascal void main(ExternalCallbackBlock *callbacks, WindowPtr w); [C] + + The 'new' calling convention, which passes more information + and allows scriptability, is this: + +pascal OSErr main(ExternalCallbackBlock *callbacks, WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply); +*/ diff --git a/Mac/Contrib/BBPy/source/BB-stuff/ExternalInterface.h b/Mac/Contrib/BBPy/source/BB-stuff/ExternalInterface.h new file mode 100644 index 0000000..51d206d --- /dev/null +++ b/Mac/Contrib/BBPy/source/BB-stuff/ExternalInterface.h @@ -0,0 +1,716 @@ +#pragma once + +#include <MixedMode.h> +#include <Dialogs.h> +#include <Files.h> +#include <Windows.h> +#include <AppleEvents.h> +#include <StandardFile.h> + +#if defined(powerc) || defined (__powerc) +#pragma options align=mac68k +#endif + +typedef struct +{ + FSSpec spec; // designates file on disk + long key; // reserved for future expansion + + char tree; // 0 for absolute, 1 for project, 2 for system + Boolean found; // FALSE if file couldn't be located; if so, all other info is moot + + OSType type; // file type of found file + OSType crtr; // signature of found file's creator + + short spare0; // reserved for future expansion + long spare1; +} ProjectEntry; + +enum +{ + kNeitherTree, + kProjectTree, + kSystemTree +}; + +enum +{ + kTHINKCProject, + kTHINKPascalProject, + kCodeWarriorProject +}; + +// masks for the "flags" argument to new-convention interfaces + +#define xfWindowOpen 0x00000001 +#define xfWindowChangeable 0x00000002 +#define xfHasSelection 0x00000004 +#define xfUseDefaults 0x00000008 +#define xfIsBBEditLite 0x00000040 +#define xfIsBBEditDemo 0x00000080 + +typedef struct +{ + FSSpec spec; + OSType key; + + short error_kind; + long line_number; + + Str255 message; +} ErrorEntry; + +typedef enum +{ + kNote = 0, + kError, + kWarning +} ErrorKind; + +#define kCurrentExternalVersion 5 // current version of callbacks + +// Universal callback interfaces + +#if USESROUTINEDESCRIPTORS + +#define ExtensionUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr)))) + +#define NewExtensionUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(AppleEvent *))) \ + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(AppleEvent *)))) + +#define GetWindowContentsUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))) + +#define GetSelectionUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *)))) + +#define SetSelectionUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))) + +#define GetDocInfoUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long *)))) + +#define GetModDateUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))) + +#define CopyUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle)))) + +#define PasteUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Handle)))) + +#define GetLastLineUPPInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))) + +#define GetLineNumberUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define GetLineStartUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define GetLineEndUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define GetLinePosUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define InsertUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))) + +#define DeleteUPPInfo (kPascalStackBased) + +#define SetWindowContentsUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))) + +#define ContentsChangedUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr)))) + +#define GetFileTextUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *)))) + +#define GetFolderUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *)))) + +#define OpenSeveralUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StandardFileReply ***)))) + +#define CenterDialogUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(DialogPtr))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))) + +#define StandardFilterUPPInfo uppModalFilterProcInfo + +#define FrameDialogItemUPPInfo uppUserItemProcInfo + +#define NewDocumentUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr)))) + +#define OpenDocumentUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr)))) + +#define AllocateUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean)))) + +#define FindPatternUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(char *))) \ + | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(Boolean)))) + +#define ReportOSErrorUPPInfo (kPascalStackBased) + +#define GetPreferenceUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *)))) + +#define SetPreferenceUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *)))) + +#define StartProgressUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean)))) + +#define DoProgressUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define DoneProgressUPPInfo (kPascalStackBased) + +#define GetProjectListUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ProjectEntry***)))) + +#define ProjectTextListUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle *)))) + +#define PresetUndoUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))) + +#define SetUndoUPPInfo (kPascalStackBased) + +#define OpenFileUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr *)))) + +#define PrepareUndoUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))) + +#define CommitUndoUPPInfo (kPascalStackBased \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))) + +#define CreateResultsUPPInfo (kPascalStackBased \ + | RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \ + | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \ + | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \ + | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Handle))) \ + | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(WindowPtr *)))) + +typedef UniversalProcPtr GetWindowContentsProc; +typedef UniversalProcPtr GetSelectionProc; +typedef UniversalProcPtr SetSelectionProc; +typedef UniversalProcPtr GetDocInfoProc; +typedef UniversalProcPtr GetModDateProc; +typedef UniversalProcPtr CopyProc; +typedef UniversalProcPtr PasteProc; + +typedef UniversalProcPtr GetLastLineProc; +typedef UniversalProcPtr GetLineNumberProc; +typedef UniversalProcPtr GetLineStartProc; +typedef UniversalProcPtr GetLineEndProc; +typedef UniversalProcPtr GetLinePosProc; + +typedef UniversalProcPtr InsertProc; +typedef UniversalProcPtr DeleteProc; + +typedef UniversalProcPtr SetWindowContentsProc; +typedef UniversalProcPtr ContentsChangedProc; + +typedef UniversalProcPtr GetFileTextProc; + +typedef UniversalProcPtr GetFolderProc; +typedef UniversalProcPtr OpenSeveralProc; + +typedef UniversalProcPtr CenterDialogProc; +typedef UniversalProcPtr StandardFilterProc; +typedef UniversalProcPtr FrameDialogItemProc; + +typedef UniversalProcPtr NewDocumentProc; +typedef UniversalProcPtr OpenDocumentProc; + +typedef UniversalProcPtr AllocateProc; +typedef UniversalProcPtr FindPatternProc; + +typedef UniversalProcPtr ReportOSErrorProc; + +typedef UniversalProcPtr GetPreferenceProc; +typedef UniversalProcPtr SetPreferenceProc; + +typedef UniversalProcPtr StartProgressProc; +typedef UniversalProcPtr DoProgressProc; +typedef UniversalProcPtr DoneProgressProc; + +typedef UniversalProcPtr GetProjectListProc; +typedef UniversalProcPtr ProjectTextListProc; + +typedef UniversalProcPtr PresetUndoProc; +typedef UniversalProcPtr SetUndoProc; + +typedef UniversalProcPtr OpenFileProc; + +typedef UniversalProcPtr PrepareUndoProc; +typedef UniversalProcPtr CommitUndoProc; + +typedef UniversalProcPtr CreateResultsProc; + +#define CallGetWindowContents(proc, w) \ + (Handle)(CallUniversalProc(proc, GetWindowContentsUPPInfo, (w))) + +#define CallGetSelection(proc, selStart, selEnd, firstChar) \ + (CallUniversalProc(proc, GetSelectionUPPInfo, (selStart), (selEnd), (firstChar))) + +#define CallSetSelection(proc, selStart, selEnd, firstChar) \ + (CallUniversalProc(proc, SetSelectionUPPInfo, (selStart), (selEnd), (firstChar))) + +#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \ + (CallUniversalProc(proc, GetDocInfoUPPInfo, (w), (name), (vRefNum), (dirID))) + +#define CallGetModDate(proc, w) \ + (CallUniversalProc(proc, GetModDateUPPInfo, (w))) + +#define CallCopy(proc) \ + (Handle)(CallUniversalProc(proc, CopyUPPInfo)) + +#define CallPaste(proc, h) \ + (CallUniversalProc(proc, PasteUPPInfo, (h))) + +#define CallGetLastLine(proc) \ + (CallUniversalProc(proc, GetLastLineUPPInfo)) + +#define CallGetLineNumber(proc, sel) \ + (CallUniversalProc(proc, GetLineNumberUPPInfo, (sel))) + +#define CallGetLineStart(proc, sel) \ + (CallUniversalProc(proc, GetLineStartUPPInfo, (sel))) + +#define CallGetLineEnd(proc, sel) \ + (CallUniversalProc(proc, GetLineEndUPPInfo, (sel))) + +#define CallGetLinePos(proc, sel) \ + (CallUniversalProc(proc, GetLinePosUPPInfo, (sel))) + +#define CallInsert(proc, text, len) \ + (CallUniversalProc(proc, InsertUPPInfo, (text), (len))) + +#define CallDelete(proc) \ + (CallUniversalProc(proc, DeleteUPPInfo)) + +#define CallSetWindowContents(proc, w, h) \ + (CallUniversalProc(proc, SetWindowContentsUPPInfo, (w), (h))) + +#define CallContentsChanged(proc, w) \ + (CallUniversalProc(proc, ContentsChangedUPPInfo, (w))) + +#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \ + (Handle)(CallUniversalProc(proc, GetFileTextUPPInfo, (vRefNum), (dirID), (name), (canDispose))) + +#define CallGetFolder(proc, prompt, vRefNum, dirID) \ + (Boolean)(CallUniversalProc(proc, GetFolderUPPInfo, (prompt), (vRefNum), (dirID))) + +#define CallOpenSeveral(proc, sort, file_count, files) \ + (Boolean)(CallUniversalProc(proc, OpenSeveralUPPInfo, (sort), (file_count), (files))) + +#define CallCenterDialog(proc, dialogID) \ + (DialogPtr)(CallUniversalProc(proc, CenterDialogUPPInfo, (dialogID))) + +#define CallStandardFilter(proc, d, event, item) \ + CallModalFilterProc(proc, (d), (event), (item)) + +#define CallFrameDialogItem(proc, d, item) \ + CallUserItemProc(proc, (d), (item)) + +#define CallNewDocument(proc) \ + (WindowPtr)(CallUniversalProc(proc, NewDocumentUPPInfo)) + +#define CallOpenDocument(proc) \ + (WindowPtr)(CallUniversalProc(proc, OpenDocumentUPPInfo)) + +#define CallAllocate(proc, size, clear) \ + (Handle)(CallUniversalProc(proc, AllocateUPPInfo, (size), (clear))) + +#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \ + (CallUniversalProc(proc, FindPatternUPPInfo, (text), (text_len), (text_offset), \ + (pat), (pat_len), (case_sens))) + +#define CallReportOSError(proc, code) \ + (CallUniversalProc(proc, ReportOSErrorUPPInfo, (code))) + +#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \ + (CallUniversalProc(proc, GetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len))) + +#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \ + (CallUniversalProc(proc, SetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len))) + +#define CallStartProgress(proc, str, total, cancel_allowed) \ + (CallUniversalProc(proc, StartProgressUPPInfo, (str), (total), (cancel_allowed))) + +#define CallDoProgress(proc, done) \ + (Boolean)(CallUniversalProc(proc, DoProgressUPPInfo, (done))) + +#define CallDoneProgress(proc) \ + (CallUniversalProc(proc, DoneProgressUPPInfo)) + +#define CallGetProjectList(proc, spec, kind, count, entries) \ + (Boolean)(CallUniversalProc(proc, GetProjectListUPPInfo, (spec), (kind), (count), (entries))) + +#define CallProjectTextList(proc, spec, text) \ + (Boolean)(CallUniversalProc(proc, ProjectTextListUPPInfo, (spec), (text))) + +#define CallPresetUndo(proc) \ + (Boolean)(CallUniversalProc(proc, PresetUndoUPPInfo)) + +#define CallSetUndo(proc) \ + (CallUniversalProc(proc, SetUndoUPPInfo)) + +#define CallOpenFile(proc, spec, w) \ + (Boolean)(CallUniversalProc(proc, OpenFileUPPInfo, (spec), (w))) + +#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \ + (Boolean)(CallUniversalProc(proc, PrepareUndoUPPInfo, (undo_start), (undo_end), \ + (sel_start), (sel_end))) + +#define CallCommitUndo(proc, new_end) \ + (CallUniversalProc(proc, CommitUndoUPPInfo, (new_end))) + +#define CallCreateResults(proc, title, count, results, w) \ + (Boolean)(CallUniversalProc(proc, CreateResultsUPPInfo, (title), (count), (results), (w))) + +#else + +typedef pascal Handle (*GetWindowContentsProc)(WindowPtr w); +typedef pascal void (*GetSelectionProc)(long *selStart, long *selEnd, long *firstChar); +typedef pascal void (*SetSelectionProc)(long selStart, long selEnd, long firstChar); +typedef pascal void (*GetDocInfoProc)(WindowPtr w, Str255 fName, short *vRefNum, long *dirID); +typedef pascal long (*GetModDateProc)(WindowPtr w); +typedef pascal Handle (*CopyProc)(void); +typedef pascal void (*PasteProc)(Handle pasteText); + +typedef pascal long (*GetLastLineProc)(void); +typedef pascal long (*GetLineNumberProc)(long selection); +typedef pascal long (*GetLineStartProc)(long selection); +typedef pascal long (*GetLineEndProc)(long selection); +typedef pascal long (*GetLinePosProc)(long line); + +typedef pascal void (*InsertProc)(char *text, long len); +typedef pascal void (*DeleteProc)(void); + +typedef pascal void (*SetWindowContentsProc)(WindowPtr w, Handle h); +typedef pascal void (*ContentsChangedProc)(WindowPtr w); + +typedef pascal Handle (*GetFileTextProc)(short vRefNum, long dirID, Str255 fName, Boolean *canDispose); + +typedef pascal Boolean (*GetFolderProc)(Str255 prompt, short *vRefNum, long *dirID); +typedef pascal Boolean (*OpenSeveralProc)(Boolean sort, short *file_count, StandardFileReply ***files); + +typedef pascal DialogPtr (*CenterDialogProc)(short dialogID); +typedef pascal Boolean (*StandardFilterProc)(DialogPtr d, EventRecord *event, short *item); +typedef pascal void (*FrameDialogItemProc)(DialogPtr d, short item); + +typedef pascal WindowPtr (*NewDocumentProc)(void); +typedef pascal WindowPtr (*OpenDocumentProc)(void); + +typedef pascal Handle (*AllocateProc)(long size, Boolean clear); +typedef pascal long (*FindPatternProc)(char *text, long text_len, long text_offset, + char *pat, long pat_len, + Boolean case_sensitive); + +typedef pascal void (*ReportOSErrorProc)(short code); + +typedef pascal void (*GetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len); +typedef pascal void (*SetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len); + +typedef pascal void (*StartProgressProc)(Str255 str, long total, Boolean cancel_allowed); +typedef pascal Boolean (*DoProgressProc)(long done); +typedef pascal void (*DoneProgressProc)(void); + +typedef pascal Boolean (*GetProjectListProc)(FSSpec *spec, short *kind, short *count, ProjectEntry ***entries); +typedef pascal Boolean (*ProjectTextListProc)(FSSpec *spec, Handle *text); + +typedef pascal Boolean (*PresetUndoProc)(void); +typedef pascal void (*SetUndoProc)(void); + +typedef pascal Boolean (*OpenFileProc)(FSSpec *spec, WindowPtr *w); + +typedef pascal Boolean (*PrepareUndoProc)(long undo_start, long undo_end, + long sel_start, long sel_end); +typedef pascal void (*CommitUndoProc)(long new_end); + +typedef pascal Boolean (*CreateResultsProc)(Str255 title, short count, Handle results, WindowPtr *w); + +#define CallGetWindowContents(proc, w) \ + ((proc))((w)) + +#define CallGetSelection(proc, selStart, selEnd, firstChar) \ + ((proc))((selStart), (selEnd), (firstChar)) + +#define CallSetSelection(proc, selStart, selEnd, firstChar) \ + ((proc))((selStart), (selEnd), (firstChar)) + +#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \ + ((proc))((w), (name), (vRefNum), (dirID)) + +#define CallGetModDate(proc, w) \ + ((proc))((w)) + +#define CallCopy(proc) \ + ((proc))() + +#define CallPaste(proc, h) \ + ((proc))((h)) + +#define CallGetLastLine(proc) \ + ((proc))() + +#define CallGetLineNumber(proc, sel) \ + ((proc))((sel)) + +#define CallGetLineStart(proc, sel) \ + ((proc))((sel)) + +#define CallGetLineEnd(proc, sel) \ + ((proc))((sel)) + +#define CallGetLinePos(proc, sel) \ + ((proc))((sel)) + +#define CallInsert(proc, text, len) \ + ((proc))((text), (len)) + +#define CallDelete(proc) \ + ((proc))() + +#define CallSetWindowContents(proc, w, h) \ + ((proc))((w), (h)) + +#define CallContentsChanged(proc, w) \ + ((proc))((w)) + +#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \ + ((proc))((vRefNum), (dirID), (name), (canDispose)) + +#define CallGetFolder(proc, prompt, vRefNum, dirID) \ + ((proc))((prompt), (vRefNum), (dirID)) + +#define CallOpenSeveral(proc, sort, file_count, files) \ + ((proc))((sort), (file_count), (files)) + +#define CallCenterDialog(proc, dialogID) \ + ((proc))((dialogID)) + +#define CallStandardFilter(proc, d, event, item) \ + ((proc))((d), (event), (item)) + +#define CallFrameDialogItem(proc, d, item) \ + ((proc))((d), (item)) + +#define CallNewDocument(proc) \ + ((proc))() + +#define CallOpenDocument(proc) \ + ((proc))() + +#define CallAllocate(proc, size, clear) \ + ((proc))((size), (clear)) + +#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \ + ((proc))((text), (text_len), (text_offset), (pat), (pat_len), (case_sens)) + +#define CallReportOSError(proc, code) \ + ((proc))((code)) + +#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \ + ((proc))((prefType), (req_len), (buffer), (act_len)) + +#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \ + ((proc))((prefType), (req_len), (buffer), (act_len)) + +#define CallStartProgress(proc, str, total, cancel_allowed) \ + ((proc))((str), (total), (cancel_allowed)) + +#define CallDoProgress(proc, done) \ + ((proc))((done)) + +#define CallDoneProgress(proc) \ + ((proc))() + +#define CallGetProjectList(proc, spec, kind, count, entries) \ + ((proc))((spec), (kind), (count), (entries)) + +#define CallProjectTextList(proc, spec, text) \ + ((proc))((spec), (text)) + +#define CallPresetUndo(proc) \ + ((proc))() + +#define CallSetUndo(proc) \ + ((proc))() + +#define CallOpenFile(proc, spec, w) \ + ((proc))((spec), (w)) + +#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \ + ((proc))((undo_start), (undo_end), (sel_start), (sel_end)) + +#define CallCommitUndo(proc, new_end) \ + ((proc))((new_end)) + +#define CallCreateResults(proc, title, count, results, w) \ + ((proc))((title), (count), (results), (w)) + +#endif + + +typedef struct +{ + short version; + + // version 1 callbacks + + GetWindowContentsProc GetWindowContents; + GetSelectionProc GetSelection; + SetSelectionProc SetSelection; + GetDocInfoProc GetDocInfo; + GetModDateProc GetModDate; + CopyProc Copy; + PasteProc Paste; + + // version 2 callbacks + + /* Text-Editing stuff */ + GetLastLineProc GetLastLine; + GetLineNumberProc GetLineNumber; + GetLineStartProc GetLineStart; + GetLineEndProc GetLineEnd; + GetLinePosProc GetLinePos; + + InsertProc Insert; + DeleteProc Delete; + + /* Getting and Setting window text */ + SetWindowContentsProc SetWindowContents; + ContentsChangedProc ContentsChanged; + + /* Reading file text */ + GetFileTextProc GetFileText; + + /* Direct user-interface calls */ + GetFolderProc GetFolder; + OpenSeveralProc OpenSeveral; + + CenterDialogProc CenterDialog; + StandardFilterProc StandardFilter; + FrameDialogItemProc FrameDialogItem; + + NewDocumentProc NewDocument; + OpenDocumentProc OpenDocument; + + /* Utility Routines */ + AllocateProc Allocate; + FindPatternProc FindPattern; + + ReportOSErrorProc ReportOSError; + + /* Preference routines */ + GetPreferenceProc GetPreference; + SetPreferenceProc SetPreference; + + /* Progress routines */ + StartProgressProc StartProgress; + DoProgressProc DoProgress; + DoneProgressProc DoneProgress; + + // Version 3 callbacks + GetProjectListProc GetProjectList; + ProjectTextListProc ProjectTextList; + + // version 4 callbacks + + PresetUndoProc PresetUndo; + SetUndoProc SetUndo; + + OpenFileProc OpenFile; + + // version 5 callbacks + + PrepareUndoProc PrepareUndo; + CommitUndoProc CommitUndo; + + CreateResultsProc CreateResults; + +} ExternalCallbackBlock; + +#if defined(powerc) || defined (__powerc) +#pragma options align=reset +#endif + +/* + 'main' for a BBXT is declared: + +pascal void main(ExternalCallbackBlock *callbacks, WindowPtr w); [C] + + The 'new' calling convention, which passes more information + and allows scriptability, is this: + +pascal OSErr main(ExternalCallbackBlock *callbacks, WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply); +*/ diff --git a/Mac/Contrib/BBPy/source/BBPy.h b/Mac/Contrib/BBPy/source/BBPy.h new file mode 100644 index 0000000..22974ea --- /dev/null +++ b/Mac/Contrib/BBPy/source/BBPy.h @@ -0,0 +1,17 @@ +/* BBPython + A simple menu command to send the contents of a window to the Python interpreter + + copyright © 1996 Just van Rossum, Letterror: just@knoware.nl + + All Rights Reserved +*/ + +#include <MacHeaders68K> +#include <A4Stuff.h> +#include <SetUpA4.h> // for global variables, multiple segments, etc. +#include "ExternalInterface.h" +#include <Memory.h> + +extern OSErr SendTextAsAE(ExternalCallbackBlock *callbacks, Ptr theText, long theSize, Str255 windowTitle); +extern OSErr LaunchPythonSlave(FSSpec * docSpec); +extern Boolean GetPythonSlaveSpec(FSSpec * docSpec); diff --git a/Mac/Contrib/BBPy/source/BBPy.rsrc.hqx b/Mac/Contrib/BBPy/source/BBPy.rsrc.hqx new file mode 100644 index 0000000..33e0d1a --- /dev/null +++ b/Mac/Contrib/BBPy/source/BBPy.rsrc.hqx @@ -0,0 +1,15 @@ +(This file must be converted with BinHex 4.0) + +:#8*#8(NZFR0bB`"bFh*M8P0&4!#3#!*eepN!N!3"!!!!!I-!!!$c!!!!JJ$l!&` +"6F!#!!X!N!@N!$3!a!"N"J#3"U3!I!P#3P"j,R*cFQ0ZG'9bCQ&MC5jSF(*U,QK +aH(PiHA0X!!"3BA*d8dP8)3#3',&VJKm!N!B#G@jMC@`!N!8j!%i!63#H"!T%Efl +9G#"6BACP!*!&$!"1!#`"GBJh8f&fC5"MD'&ZCf9c)(4[)(4SC5"0CA4bEhGPFQY +c)%4[Bh9YC@jd)0*H-0-JBQ9QEh*P)&ia2`)!N!8-!"F!,!!hS!)!!J#3$)%%!!% +!!!!1!#J!+!#-!C!!!)"996!+!!!!"!!!!N%!!!#!!!-!N!9!!33!9!&8"!0CCA- +!N!C!!+S!9!$k"!*1E`#3"3J!2!!f!95)2Y*3HA4SEfj6E'&fC5j`HG-JDA-JEQp +d)(*eEQjTEQFX)!ehEh9XC#"jEh8JE'PVC5"dEb"XEf0KG'8JDA3r!*!&#!!+!#J +!+U!#!!%!!!!'!3!!8J#3"8F!)b!!!!!'GM!Z-Lic1AB`,M)Z-b#T)%TeFh3JGQ& +Z)&*[Fh0eE5![)%aPG(4PFR*[FL`J2'TeFh4!E'9dG'9bFQpb,QjX2J!!!3!!!!( +c!!!!m`!!!)))r"0%*d`!!!!F!))!"(CPFR-!!!!U4%P86!!!!$C"6&*8!!!!3N* +#@%B!!!"13N*B5`!!!&S!!Irr!!!!U!Mm%I`!J2rr!!!!'J#3"B$rr`#3#B$rr`! +!!")!N!@!rrm!!!#H!*!%red: diff --git a/Mac/Contrib/BBPy/source/BBPy_lauch.c b/Mac/Contrib/BBPy/source/BBPy_lauch.c new file mode 100644 index 0000000..f9b964c --- /dev/null +++ b/Mac/Contrib/BBPy/source/BBPy_lauch.c @@ -0,0 +1,94 @@ +/* + * Launch the PythonSlave.py script. + * This works exactly as if you'd double clicked on the file in the Finder, which + * not surprisingly is how its implemented (via the AppleEvents route of course). + * + * Largely based on code submitted by Mark Roseman <roseman@cpsc.ucalgary.ca> + * Thanks! + */ + +#include "BBPy.h" + +pascal Boolean MyFileFilter(CInfoPBPtr PB); +FileFilterUPP gMyFileFilterUPP = NULL; + +Boolean GetPythonSlaveSpec(FSSpec * docSpec) { + StandardFileReply reply; + SFTypeList typeList; + + typeList[0] = 'TEXT'; + + //if (!gMyFileFilterUPP) + gMyFileFilterUPP = NewFileFilterProc( MyFileFilter ); + + StandardGetFile(gMyFileFilterUPP, 0, typeList, &reply); + + DisposePtr((Ptr)gMyFileFilterUPP); + + if(!reply.sfGood) + return 0; /* user cancelled */ + + docSpec->vRefNum = reply.sfFile.vRefNum; + docSpec->parID = reply.sfFile.parID; + BlockMove(reply.sfFile.name, docSpec->name, 64); + return 1; +} + +pascal Boolean MyFileFilter(CInfoPBPtr PB) { + OSType fType; /* file type */ + OSType fCreator; /* file creator */ + + fType =((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdType; + fCreator = ((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdCreator; + + if (fType == 'TEXT' && + fCreator == 'Pyth') + return 0; + return 1; +} + +OSErr LaunchPythonSlave(FSSpec * docSpec) { + OSErr err; + FSSpec dirSpec; + AEAddressDesc finderAddress; + AppleEvent theEvent, theReply; + OSType finderSig = 'MACS'; + AliasHandle DirAlias, FileAlias; + AEDesc fileList; + AEDesc aeDirDesc, listElem; + + err = AECreateDesc(typeApplSignature, (Ptr)&finderSig, 4, &finderAddress); + if(err != noErr) return err; + + err = AECreateAppleEvent('FNDR', 'sope', &finderAddress, + kAutoGenerateReturnID, kAnyTransactionID, &theEvent); + if(err != noErr) return err; + + FSMakeFSSpec(docSpec->vRefNum, docSpec->parID, NULL, &dirSpec); + NewAlias(NULL, &dirSpec, &DirAlias); + NewAlias(NULL, docSpec, &FileAlias); + err = AECreateList(NULL, 0, 0, &fileList); + HLock((Handle)DirAlias); + AECreateDesc(typeAlias, (Ptr)*DirAlias, GetHandleSize((Handle)DirAlias), &aeDirDesc); + HUnlock((Handle)DirAlias); + if ((err = AEPutParamDesc(&theEvent, keyDirectObject, &aeDirDesc)) == noErr) { + AEDisposeDesc(&aeDirDesc); + HLock((Handle)FileAlias); + AECreateDesc(typeAlias, (Ptr)*FileAlias, GetHandleSize((Handle)FileAlias), &listElem); + HLock((Handle)FileAlias); + err = AEPutDesc(&fileList, 0, &listElem); + } + AEDisposeDesc(&listElem); + err = AEPutParamDesc(&theEvent, 'fsel', &fileList); + AEDisposeDesc(&fileList); + + err = AESend(&theEvent, &theReply, kAENoReply+kAENeverInteract, + kAENormalPriority, kAEDefaultTimeout, 0L, 0L); + if(err != noErr) return err; + + err = AEDisposeDesc(&theEvent); + if(err != noErr) return err; + + err = AEDisposeDesc(&theReply); + return err; +} diff --git a/Mac/Contrib/BBPy/source/BBPy_launch.c b/Mac/Contrib/BBPy/source/BBPy_launch.c new file mode 100644 index 0000000..f9b964c --- /dev/null +++ b/Mac/Contrib/BBPy/source/BBPy_launch.c @@ -0,0 +1,94 @@ +/* + * Launch the PythonSlave.py script. + * This works exactly as if you'd double clicked on the file in the Finder, which + * not surprisingly is how its implemented (via the AppleEvents route of course). + * + * Largely based on code submitted by Mark Roseman <roseman@cpsc.ucalgary.ca> + * Thanks! + */ + +#include "BBPy.h" + +pascal Boolean MyFileFilter(CInfoPBPtr PB); +FileFilterUPP gMyFileFilterUPP = NULL; + +Boolean GetPythonSlaveSpec(FSSpec * docSpec) { + StandardFileReply reply; + SFTypeList typeList; + + typeList[0] = 'TEXT'; + + //if (!gMyFileFilterUPP) + gMyFileFilterUPP = NewFileFilterProc( MyFileFilter ); + + StandardGetFile(gMyFileFilterUPP, 0, typeList, &reply); + + DisposePtr((Ptr)gMyFileFilterUPP); + + if(!reply.sfGood) + return 0; /* user cancelled */ + + docSpec->vRefNum = reply.sfFile.vRefNum; + docSpec->parID = reply.sfFile.parID; + BlockMove(reply.sfFile.name, docSpec->name, 64); + return 1; +} + +pascal Boolean MyFileFilter(CInfoPBPtr PB) { + OSType fType; /* file type */ + OSType fCreator; /* file creator */ + + fType =((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdType; + fCreator = ((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdCreator; + + if (fType == 'TEXT' && + fCreator == 'Pyth') + return 0; + return 1; +} + +OSErr LaunchPythonSlave(FSSpec * docSpec) { + OSErr err; + FSSpec dirSpec; + AEAddressDesc finderAddress; + AppleEvent theEvent, theReply; + OSType finderSig = 'MACS'; + AliasHandle DirAlias, FileAlias; + AEDesc fileList; + AEDesc aeDirDesc, listElem; + + err = AECreateDesc(typeApplSignature, (Ptr)&finderSig, 4, &finderAddress); + if(err != noErr) return err; + + err = AECreateAppleEvent('FNDR', 'sope', &finderAddress, + kAutoGenerateReturnID, kAnyTransactionID, &theEvent); + if(err != noErr) return err; + + FSMakeFSSpec(docSpec->vRefNum, docSpec->parID, NULL, &dirSpec); + NewAlias(NULL, &dirSpec, &DirAlias); + NewAlias(NULL, docSpec, &FileAlias); + err = AECreateList(NULL, 0, 0, &fileList); + HLock((Handle)DirAlias); + AECreateDesc(typeAlias, (Ptr)*DirAlias, GetHandleSize((Handle)DirAlias), &aeDirDesc); + HUnlock((Handle)DirAlias); + if ((err = AEPutParamDesc(&theEvent, keyDirectObject, &aeDirDesc)) == noErr) { + AEDisposeDesc(&aeDirDesc); + HLock((Handle)FileAlias); + AECreateDesc(typeAlias, (Ptr)*FileAlias, GetHandleSize((Handle)FileAlias), &listElem); + HLock((Handle)FileAlias); + err = AEPutDesc(&fileList, 0, &listElem); + } + AEDisposeDesc(&listElem); + err = AEPutParamDesc(&theEvent, 'fsel', &fileList); + AEDisposeDesc(&fileList); + + err = AESend(&theEvent, &theReply, kAENoReply+kAENeverInteract, + kAENormalPriority, kAEDefaultTimeout, 0L, 0L); + if(err != noErr) return err; + + err = AEDisposeDesc(&theEvent); + if(err != noErr) return err; + + err = AEDisposeDesc(&theReply); + return err; +} diff --git a/Mac/Contrib/BBPy/source/BBPy_main.c b/Mac/Contrib/BBPy/source/BBPy_main.c new file mode 100644 index 0000000..a96b271 --- /dev/null +++ b/Mac/Contrib/BBPy/source/BBPy_main.c @@ -0,0 +1,104 @@ +/* BBPython + A simple menu command to send the contents of a window to the Python interpreter + + copyright © 1996 Just van Rossum, Letterror: just@knoware.nl + + All Rights Reserved +*/ + +#include "BBPy.h" + +OSErr SendTextAsAE(ExternalCallbackBlock *callbacks, Ptr theText, long theSize, Str255 windowTitle) +{ + OSErr err; + AEDesc theEvent; + AEAddressDesc theTarget; + AppleEvent theReply; + AEDesc theTextDesc; + AEDesc theNameDesc; + OSType pythonSig = 'Pyth'; + FSSpec docSpec; + short itemHit; + long time; + EventRecord theDummyEvent; + + /* initialize AE descriptor for python's signature */ + err = AECreateDesc (typeApplSignature, &pythonSig, sizeof(OSType), &theTarget); + if(err != noErr) return err; + + /* initialize AE descriptor for the title of our window */ + err = AECreateDesc (typeChar, &windowTitle[1], windowTitle[0], &theNameDesc); + if(err != noErr) return err; + + /* initialize AE descriptor for the content of our window */ + err = AECreateDesc ('TEXT', theText, theSize, &theTextDesc); + if(err != noErr) return err; + + /* initialize AppleEvent */ + err = AECreateAppleEvent ('pyth', 'EXEC', &theTarget, kAutoGenerateReturnID, kAnyTransactionID, &theEvent); + if(err != noErr) return err; + + /* add the content of our window to the AppleEvent */ + err = AEPutParamDesc (&theEvent, keyDirectObject, &theTextDesc); + if(err != noErr) return err; + + /* add the title of our window to the AppleEvent */ + err = AEPutParamDesc (&theEvent, 'NAME', &theNameDesc); + if(err != noErr) return err; + + /* send the AppleEvent */ + err = AESend (&theEvent, &theReply, kAEWaitReply, kAEHighPriority, kNoTimeOut, NULL, NULL); + if(err == connectionInvalid) { + // launch PythonSlave.py + itemHit = Alert(128, NULL); + if(itemHit == 2) return noErr; /* user cancelled */ + + if( ! GetPythonSlaveSpec(&docSpec) ) + return noErr; /* user cancelled */ + + err = LaunchPythonSlave(&docSpec); + if(err != noErr) return err; + } else if(err != noErr) + return err; + + /* clean up */ + err = AEDisposeDesc (&theTarget); + if(err != noErr) return err; + + err = AEDisposeDesc (&theNameDesc); + if(err != noErr) return err; + + err = AEDisposeDesc (&theTextDesc); + if(err != noErr) return err; + + err = AEDisposeDesc (&theEvent); + if(err != noErr) return err; + + err = AEDisposeDesc (&theReply); + if(err != noErr) return err; + + /* everything is cool */ + return noErr; +} + +pascal void main(ExternalCallbackBlock *callbacks, WindowPtr theWindow) +{ + long oldA4; + OSErr err; + Handle windowContents; + Str255 windowTitle; + + //RememberA0(); /* Can't find header file for this. Seems to work anyway. */ + + oldA4 = SetUpA4(); + + GetWTitle(theWindow, windowTitle); + windowContents = callbacks->GetWindowContents(theWindow); + + HLock(windowContents); + err = SendTextAsAE(callbacks, *windowContents, GetHandleSize(windowContents), windowTitle); + if(err != noErr) callbacks->ReportOSError(err); + HUnlock(windowContents); + + RestoreA4(oldA4); +} diff --git a/Mac/Contrib/PythonScript/PyScriptTest.py b/Mac/Contrib/PythonScript/PyScriptTest.py new file mode 100644 index 0000000..fee3203 --- /dev/null +++ b/Mac/Contrib/PythonScript/PyScriptTest.py @@ -0,0 +1,25 @@ +''' +Minimal test module +'''# + +import sys +import PythonScript + +SIGNATURE = 'MACS' +TIMEOUT = 10*60*60 + +PythonScript.PsScript(SIGNATURE, TIMEOUT) +p = PythonScript.PyScript +ev = PythonScript.PsEvents +pc = PythonScript.PsClass +pp = PythonScript.PsProperties + +startup = str(p(ev.Get, pc.Desktopobject(1).Startup_disk().Name())) +print 'startup',startup, type(startup) +print p(ev.Get, pc.Disk(startup).Folder(7).File(1).Name()) +print p(ev.Get, pc.Disk(1).Name()) +print p(ev.Get, pc.Disk('every').Name()) +print p(ev.Make, None, New='Alias_file', At=pp.Desktop(''), To=pp.System_folder(1)) + +sys.exit(1) + diff --git a/Mac/Contrib/PythonScript/PythonScript.py b/Mac/Contrib/PythonScript/PythonScript.py new file mode 100644 index 0000000..b6077ae --- /dev/null +++ b/Mac/Contrib/PythonScript/PythonScript.py @@ -0,0 +1,301 @@ +""" +Python script a module to comunicate with apple events + +v 0.1a2 +v.0.2 16 april 1998 + + +""" +import sys +import getaete +import baetools +import baetypes +import AE +import AppleEvents +import macfs +from types import * +#from aetypes import InstanceType +from aepack import AEDescType + +ordinal = { +'every': 'all ', +'first' : 'firs', +'last' : 'last', +'any' : 'any ', +'middle' : 'midd'} + + +Error = 'PythonScript.Error' + + +class PsEvents: + pass + + +class PsClasses: + + + def __getattr__(self, name): + try: + return DCItem(name, self) + except: + pass + + def __repr__(self): + if self.form != 'prop': + t = type(self.seld) + if t == StringType: + self.form = 'name' + elif baetypes.IsRange(self.seld): + self.form = 'rang' + elif baetypes.IsComparison(self.seld) or baetypes.IsLogical(self.seld): + self.form = 'test' + elif t == TupleType: + # Breakout: specify both form and seld in a tuple + # (if you want ID or rele or somesuch) + self.form, self.seld = self.seld + elif t == IntType: + self.form = 'indx' + else: + pass + + if self.seld in ordinal.keys(): + self.seld = baetypes.Ordinal(ordinal[self.seld]) + self.form = 'indx' + + s = "baetypes.ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`) + if `self.fr`: + s = s + ", %s)" % `self.fr` + else: + s = s + ")" + return s + + def __str__(self): + return self.want + + +def template(self, seld=None, fr=None): + self.seld = seld + self.fr = fr + +def template1(self, which, fr=None): + self.want = 'prop' + self.form = 'prop' + self.fr = fr + +class DCItem: + def __init__(self, comp, fr): + self.compclass = comp + self.fr = fr + + def __call__(self, which=None): + if which: + self.compclass = eval('PsClass.%s' % self.compclass) + else: + try: + self.compclass = eval('PsProperties.%s' % self.compclass) + except AttributeError: + self.compclass = eval('PsClass.%s' % self.compclass) + return self.compclass(which, self.fr) + +class PsClass: + pass + +class PsProperties: + pass + + +class PsEnumerations: + pass + + +def PsScript(sig=None, Timeout=0, Ignoring=0): + elements = {} + if sig: + target, sig = Signature(sig) + pyscript = getaete.Getaete(sig) + else: + target, sig = Signature('Pyth') + pyscript = getaete.Getaete() + setattr(PyScript, 'timeout', Timeout) + setattr(PyScript, 'ignoring', Ignoring) + setattr(PyScript, 'target', target) + for key, value in pyscript[0].items(): + setattr(PsEvents, key, value) + for key, value in pyscript[1].items(): + CreateClass(key, 'PsClasses', value) + for val in value[2]: + CreateProperty(val[0], 'PsClasses', `val[1]`) + + if value[3]: + for val in value[3]: + if val[0] not in elements.keys(): + elements[val[0]] = val[1] + elif len(val[1]) > len(elements[val[0]]): + elements[val[0]] = val[1] + + for key, value in pyscript[2].items(): + for val in value: + setattr(PsEnumerations, val[0], val[1]) + +def CreateClass(newClassName, superClassName, value): + parentDict = PsClass.__dict__ + exec "class %s(%s): pass" % (newClassName, superClassName) in \ + globals(), parentDict + newClassObj = parentDict[newClassName] + newClassObj.__init__ = template + exec "setattr(newClassObj, 'want', %s)" % `value[0]` + if value[2] and value[2][0][0] == 'every': + exec "setattr(newClassObj, 'plur', 1)" + +def CreateProperty(newClassName, superClassName, value): + parentDict = PsProperties.__dict__ + exec "class %s(%s): pass" % (newClassName, superClassName) in \ + globals(), parentDict + newClassObj = parentDict[newClassName] + if newClassName == 'Every': + value = "baetypes.mkOrdinal('every')" + newClassObj.__init__ = template1 + exec "setattr(newClassObj, 'seld', %s)" % value + +def Signature(signature): + if type(signature) == AEDescType: + target = signature + elif type(signature) == InstanceType and hasattr(signature, '__aepack__'): + target = signature.__aepack__() + elif type(signature) == StringType: + if len(signature) == 4: + target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature) + target_signature = signature + else: + #This should ready be made persistant, so PythonScript 'remembered' where applications were + fss, ok = macfs.PromptGetFile('Find the aplication %s' % signature, 'APPL') + if ok: + target_signature = fss.GetCreatorType()[0] + target = AE.AECreateDesc(AppleEvents.typeApplSignature, target_signature) + else: + raise TypeError, "signature should be 4-char string or AEDesc" + return target, target_signature + + + + +class PyScript(PsEvents): + def __init__(self, name, obj=None, **args): + desc, code, subcode, rply, message, keywds = name +# print 'code', code +# print 'subcode', subcode +# print 'rply', rply +# print 'message', message +# print 'keywds', keywds +# print 'name', name +# print 'obj', obj +# print 'args', args + self.code = code + self.subcode = subcode + self.attributes ={} + self.arguments = {} + if keywds: + self.arguments = self.keyargs(keywds, args) + self.arguments['----'] = self.keyfms(message[0], obj) + + ##XXXX Eudora needs this XXXX## + if self.arguments['----'] == None: + del self.arguments['----'] +# print 'arguments', self.arguments + if self.ignoring or rply[0] == 'null': + self.send_flags = AppleEvents.kAENoReply + else: + self.send_flags = AppleEvents.kAEWaitReply + self.send_priority = AppleEvents.kAENormalPriority + if self.timeout: + self.send_timeout = self.timeout + else: + self.send_timeout = AppleEvents.kAEDefaultTimeout + + + def keyargs(self, ats, args): +# print 'keyargs', ats, args + output = {} + for arg in args.keys(): + for at in ats: + if at[0] == arg: + output[at[1]] = self.keyfms(at[2][0], args[arg]) + return output + + def keyfms(self, key, value): +# print 'keyfms', 'key', key, `value` + if key == 'obj ' or key == 'insl': + return eval(`value`) + elif key == 'TEXT': + return value + elif key == 'null': + return + elif key == 'bool': + return baetypes.mkboolean(value) + elif key == 'type': + try: + val = eval('PsClass.%s()' % value) + return baetypes.mktype(str(val)) + except: + return baetypes.mktype(value) + else: + print "I don't know what to put here -- script.keyargs" + print key, `value` + sys.exit[1] + + def newevent(self, code, subcode, parameters = {}, attributes = {}): + """Create a complete structure for an apple event""" +# print code, subcode, parameters, attributes + event = AE.AECreateAppleEvent(code, subcode, self.target, + AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID) + baetools.packevent(event, parameters, attributes) + return event + + def sendevent(self, event): + """Send a pre-created appleevent, await the reply and unpack it""" + + reply = event.AESend(self.send_flags, self.send_priority, + self.send_timeout) + parameters, attributes = baetools.unpackevent(reply) + return reply, parameters, attributes + + def send(self, code, subcode, parameters = {}, attributes = {}): + """Send an appleevent given code/subcode/pars/attrs and unpack the reply""" +# print code, subcode, parameters, attributes + return self.sendevent(self.newevent(code, subcode, parameters, attributes)) + + def __str__(self): + _reply, _arguments, _attributes = self.send(self.code, self.subcode, self.arguments, self.attributes) + + if _arguments.has_key('errn'): + raise baetools.Error, baetools.decodeerror(_arguments) + # XXXX Optionally decode result + if _arguments.has_key('----'): + return str(_arguments['----']) + else: + return + + + +def test(): + Simp = 'Hermit:Applications:SimpleText' + PsScript('MACS', Timeout=60*60*3) +# PsScript('CSOm', Timeout=60*60*3) +# PsScript('', Timeout=60*60*3) +# PyScript('macsoup') + ev = PsEvents + ps = PsClass +# print PsProperties.__dict__ +# y = script(ev.Open, File('Hermit:Desktop Folder:Lincolnshire Imp'), using=Application_file(Simp)) +# print baetypes.NProperty('prop', 'prop', 'pnam', baetypes.ObjectSpecifier('cdis', 'indx', 1, None)) +# y = PyScript(ev.Get, Disk("Hermit").Folder(7).File(1).Name()) +# y = PyScript(ev.Get, Disk("Hermit").Size(), As='Integer') +# y = PyScript(ev.Get, ps.Desktopobject(1).Startup_disk()) +# y = PyScript(ev.Get, Mailbox(1).File(), as='TEXT') +# print 'y', y, type(y) + +if __name__ == '__main__': + test() +# sys.exit(1) + diff --git a/Mac/Contrib/PythonScript/ReadMe.txt b/Mac/Contrib/PythonScript/ReadMe.txt new file mode 100644 index 0000000..3518423 --- /dev/null +++ b/Mac/Contrib/PythonScript/ReadMe.txt @@ -0,0 +1,86 @@ + +PythonScript +------------ +v0.5 beta 1 24/04/98 + +author: Bill Bedford, <billb@mousa.demon.co.uk> + +This suite of modules is a first attempt at writing a more user friendly +python/appleevent interface. The files in the suite are: + +PythonScript +------------ + +Loads three dictionaries generated by getaete into __dict__'s of three +classes and thus gives us direct assess to all the methods in the aete. +Each method now contains all the information needed to build apple events. + +The general usage is + +>>>PythonScript.PsScript(SIGNATURE, TIMEOUT, IGNORING) + +where +SIGNATURE is the target application +TIMEOUT is in ticks +and IGNORING is a boolean and determines whether the script waits for a reply +from the target before going on to the next event + +>>>PythonScript.PyScript(Event, Object, keywdarg1..., keywdarg2...etc) + +Object is a appleevent object specifier and is of the form + +PythonScript.PsClass.Class1(arg).Class2(arg)Š.Property() + +All applescript event, class and property names are capitalised to +distinguish them from python methods. + +getaete +------- + +Reads the aete of the target application and returns it as a list of three +dictionaries, which represent all the events, properties and enumeration in +the aete. (the fourth dictionary, comparisons, has never been implemented +in applescript so I have not used it) It also reads the applescript aeut +and adds any suites that are missing (ie where the application author has +set his suite to inherit from the aeut.) and the applescript suite, which +gives the language methods + +printaete +--------- + +Produces a text file with the aete set out in a human readable form, +similar to the Open Dictionary command in the applescript editor. + + +baetools, baepack, baetypes +--------------------------- + +These are direct equivalents of aetools, aepack, aetypes in the standard +distribution. Some methods and classes have been enhanced others are +redundant + +PyScriptTest, testeudora +------------------------ + +A couple of test scripts. Testeudora is an updated version of the one in +the standard distribution. + + + + + +Still To Do (in no particular order) +----------- + +These modules are much slower than applescript. I believe they could be +made faster by rewriting the aete parser in getaete and/or by putting in +some form of persistent storage so that the class dictionaries can be cached. + +The parsing of the appleevent replies need rewriting. + +Support for the use of scripting additions. + +A Python aeut needs to be written, much of the applescript one is redundant +in python. + +Probably a few other things I haven't thought of yet. diff --git a/Mac/Contrib/PythonScript/baepack.py b/Mac/Contrib/PythonScript/baepack.py new file mode 100644 index 0000000..a0bbe50 --- /dev/null +++ b/Mac/Contrib/PythonScript/baepack.py @@ -0,0 +1,385 @@ +"""Tools for use in AppleEvent clients and servers: +conversion between AE types and python types + +pack(x) converts a Python object to an AEDesc object +unpack(desc) does the reverse +coerce(x, wanted_sample) coerces a python object to another python object +""" + +# +# This code was originally written by Guido, and modified/extended by Jack +# to include the various types that were missing. The reference used is +# Apple Event Registry, chapter 9. +# + +import struct +import string +import types +from string import strip +from types import * +import AE +from AppleEvents import * +from AERegistry import * +from AEObjects import * +import MacOS +import macfs +import StringIO +import baetypes +from baetypes import mkenum, mktype + +import calldll + +OSL = calldll.getlibrary('ObjectSupportLib') + +# These ones seem to be missing from AppleEvents +# (they're in AERegistry.h) + +#typeColorTable = 'clrt' +#typeDrawingArea = 'cdrw' +#typePixelMap = 'cpix' +#typePixelMapMinus = 'tpmm' +#typeRotation = 'trot' +#typeTextStyles = 'tsty' +#typeStyledText = 'STXT' +#typeAEText = 'tTXT' +#typeEnumeration = 'enum' + +# +# Some AE types are immedeately coerced into something +# we like better (and which is equivalent) +# +unpacker_coercions = { + typeComp : typeExtended, + typeColorTable : typeAEList, + typeDrawingArea : typeAERecord, + typeFixed : typeExtended, + typeFloat : typeExtended, + typePixelMap : typeAERecord, + typeRotation : typeAERecord, + typeStyledText : typeAERecord, + typeTextStyles : typeAERecord, +}; + +# +# Some python types we need in the packer: +# +AEDescType = type(AE.AECreateDesc('TEXT', '')) +_sample_fss = macfs.FSSpec(':') +_sample_alias = _sample_fss.NewAliasMinimal() +FSSType = type(_sample_fss) +AliasType = type(_sample_alias) + +def pack(x, forcetype = None): + """Pack a python object into an AE descriptor""" +# print 'aepack', x, type(x), forcetype +# if type(x) == TupleType: +# forcetype, x = x + if forcetype: + print x, forcetype + if type(x) is StringType: + return AE.AECreateDesc(forcetype, x) + else: + return pack(x).AECoerceDesc(forcetype) + + if x == None: + return AE.AECreateDesc('null', '') + + t = type(x) + if t == AEDescType: + return x + if t == FSSType: + return AE.AECreateDesc('fss ', x.data) + if t == AliasType: + return AE.AECreateDesc('alis', x.data) + if t == IntType: + return AE.AECreateDesc('long', struct.pack('l', x)) + if t == FloatType: + # + # XXXX (note by Guido) Weird thing -- Think C's "double" is 10 bytes, but + # struct.pack('d') return 12 bytes (and struct.unpack requires + # them, too). The first 2 bytes seem to be repeated... + # Probably an alignment problem + # XXXX (note by Jack) haven't checked this under MW + # +# return AE.AECreateDesc('exte', struct.pack('d', x)[2:]) + return AE.AECreateDesc('exte', struct.pack('d', x)) + if t == StringType: + return AE.AECreateDesc('TEXT', x) + if t == ListType: + list = AE.AECreateList('', 0) + for item in x: + list.AEPutDesc(0, pack(item)) + return list + if t == DictionaryType: + record = AE.AECreateList('', 1) + for key, value in x.items(): + record.AEPutParamDesc(key, pack(value)) + return record + if t == InstanceType and hasattr(x, '__aepack__'): + return x.__aepack__() + return AE.AECreateDesc('TEXT', repr(x)) # Copout + +def unpack(desc): + """Unpack an AE descriptor to a python object""" + t = desc.type +# print t + + if unpacker_coercions.has_key(t): + desc = desc.AECoerceDesc(unpacker_coercions[t]) + t = desc.type # This is a guess by Jack.... + + if t == typeAEList: + l = [] + for i in range(desc.AECountItems()): + keyword, item = desc.AEGetNthDesc(i+1, '****') + l.append(unpack(item)) + return l + if t == typeAERecord: + d = {} + for i in range(desc.AECountItems()): + keyword, item = desc.AEGetNthDesc(i+1, '****') + d[keyword] = unpack(item) + return d + if t == typeAEText: + record = desc.AECoerceDesc('reco') + return mkaetext(unpack(record)) + if t == typeAlias: + return macfs.RawAlias(desc.data) + # typeAppleEvent returned as unknown + if t == typeBoolean: + return struct.unpack('b', desc.data)[0] + if t == typeChar: + return desc.data + # typeColorTable coerced to typeAEList + # typeComp coerced to extended + # typeData returned as unknown + # typeDrawingArea coerced to typeAERecord + if t == typeEnumeration: + return mkenum(desc.data) + # typeEPS returned as unknown + if t == typeExtended: +# print desc, type(desc), len(desc) + data = desc.data +# print `data[:8]`, type(data), len(data[:8]) +# print struct.unpack('=d', data[:8])[0] +# print string.atoi(data), type(data), len(data) +# print struct.calcsize(data) + # XXX See corresponding note for pack() +# return struct.unpack('d', data[:2] + data)[0] + return struct.unpack('d', data[:8])[0] + if t == typeFalse: + return 0 + # typeFixed coerced to extended + # typeFloat coerced to extended + if t == typeFSS: + return macfs.RawFSSpec(desc.data) + if t == typeInsertionLoc: + record = desc.AECoerceDesc('reco') + return mkinsertionloc(unpack(record)) + # typeInteger equal to typeLongInteger + if t == typeIntlText: + script, language = struct.unpack('hh', desc.data[:4]) + return baetypes.IntlText(script, language, desc.data[4:]) + if t == typeIntlWritingCode: + script, language = struct.unpack('hh', desc.data) + return baetypes.IntlWritingCode(script, language) + if t == typeKeyword: + return mkkeyword(desc.data) + # typeLongFloat is equal to typeFloat + if t == typeLongInteger: +# print t, struct.unpack('l', desc.data) + return struct.unpack('l', desc.data)[0] + if t == typeNull: + return None + if t == typeMagnitude: + v = struct.unpack('l', desc.data) + if v < 0: + v = 0x100000000L + v + return v + if t == typeObjectSpecifier: + import Res +# print desc, type(desc) +# print desc.__members__ +# print desc.data, desc.type +# print unpack(desc) +# getOSL = calldll.newcall(OSL.AEResolve, 'OSErr', 'InHandle', 'InShort')#, 'InString') +# print 'OSL', getOSL(rdesc, 0)#, desc.data) + record = desc.AECoerceDesc('reco') +# print record + return mkobject(unpack(record)) + # typePict returned as unknown + # typePixelMap coerced to typeAERecord + # typePixelMapMinus returned as unknown + # typeProcessSerialNumber returned as unknown + if t == typeQDPoint: + v, h = struct.unpack('hh', desc.data) + return baetypes.QDPoint(v, h) + if t == typeQDRectangle: + v0, h0, v1, h1 = struct.unpack('hhhh', desc.data) + return baetypes.QDRectangle(v0, h0, v1, h1) + if t == typeRGBColor: + r, g, b = struct.unpack('hhh', desc.data) + return baetypes.RGBColor(r, g, b) + # typeRotation coerced to typeAERecord + # typeScrapStyles returned as unknown + # typeSessionID returned as unknown + if t == typeShortFloat: + return struct.unpack('f', desc.data)[0] + if t == typeShortInteger: +# print t, desc.data +# print struct.unpack('h', desc.data)[0] + return struct.unpack('h', desc.data)[0] + # typeSMFloat identical to typeShortFloat + # typeSMInt indetical to typeShortInt + # typeStyledText coerced to typeAERecord + if t == typeTargetID: + return mktargetid(desc.data) + # typeTextStyles coerced to typeAERecord + # typeTIFF returned as unknown + if t == typeTrue: + return 1 + if t == typeType: +# print t, desc.data + return mktype(desc.data) + # + # The following are special + # + if t == 'rang': + record = desc.AECoerceDesc('reco') + return mkrange(unpack(record)) + if t == 'cmpd': + record = desc.AECoerceDesc('reco') + return mkcomparison(unpack(record)) + if t == 'logi': + record = desc.AECoerceDesc('reco') + return mklogical(unpack(record)) + return mkunknown(desc.type, desc.data) + +def coerce(data, egdata): + """Coerce a python object to another type using the AE coercers""" + pdata = pack(data) + pegdata = pack(egdata) + pdata = pdata.AECoerceDesc(pegdata.type) + return unpack(pdata) + +# +# Helper routines for unpack +# +def mktargetid(data): + sessionID = getlong(data[:4]) + name = mkppcportrec(data[4:4+72]) + location = mklocationnamerec(data[76:76+36]) + rcvrName = mkppcportrec(data[112:112+72]) + return sessionID, name, location, rcvrName + +def mkppcportrec(rec): + namescript = getword(rec[:2]) + name = getpstr(rec[2:2+33]) + portkind = getword(rec[36:38]) + if portkind == 1: + ctor = rec[38:42] + type = rec[42:46] + identity = (ctor, type) + else: + identity = getpstr(rec[38:38+33]) + return namescript, name, portkind, identity + +def mklocationnamerec(rec): + kind = getword(rec[:2]) + stuff = rec[2:] + if kind == 0: stuff = None + if kind == 2: stuff = getpstr(stuff) + return kind, stuff + +def mkunknown(type, data): + return baetypes.Unknown(type, data) + +def getpstr(s): + return s[1:1+ord(s[0])] + +def getlong(s): + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def getword(s): + return (ord(s[0])<<8) | (ord(s[1])<<0) + +def mkkeyword(keyword): + return baetypes.Keyword(keyword) + +def mkrange(dict): + return baetypes.Range(dict['star'], dict['stop']) + +def mkcomparison(dict): + return baetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2']) + +def mklogical(dict): + return baetypes.Logical(dict['logc'], dict['term']) + +def mkstyledtext(dict): + return baetypes.StyledText(dict['ksty'], dict['ktxt']) + +def mkaetext(dict): + return baetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText]) + +def mkinsertionloc(dict): + return baetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition]) + +def mkobject(dict): + want = dict['want'].type + form = dict['form'].enum + seld = dict['seld'] + fr = dict['from'] + if form in ('name', 'indx', 'rang', 'test'): + if want == 'text': return baetypes.Text(seld, fr) + if want == 'cha ': return baetypes.Character(seld, fr) + if want == 'cwor': return baetypes.Word(seld, fr) + if want == 'clin': return baetypes.Line(seld, fr) + if want == 'cpar': return baetypes.Paragraph(seld, fr) + if want == 'cwin': return baetypes.Window(seld, fr) + if want == 'docu': return baetypes.Document(seld, fr) + if want == 'file': return baetypes.File(seld, fr) + if want == 'cins': return baetypes.InsertionPoint(seld, fr) + if want == 'prop' and form == 'prop' and baetypes.IsType(seld): + return baetypes.Property(seld.type, fr) + return baetypes.ObjectSpecifier(want, form, seld, fr) + +def _test(): + """Test program. Pack and unpack various things""" + objs = [ + 'a string', + 12, + 12.0, + None, + ['a', 'list', 'of', 'strings'], + {'key1': 'value1', 'key2':'value2'}, + macfs.FSSpec(':'), + macfs.FSSpec(':').NewAliasMinimal(), + baetypes.Enum('enum'), + baetypes.Type('type'), + baetypes.Keyword('kwrd'), + baetypes.Range(1, 10), + baetypes.Comparison(1, '< ', 10), + baetypes.Logical('not ', 1), + # Cannot do StyledText + # Cannot do AEText + baetypes.IntlText(0, 0, 'international text'), + baetypes.IntlWritingCode(0,0), + baetypes.QDPoint(50,100), + baetypes.QDRectangle(50,100,150,200), + baetypes.RGBColor(0x7000, 0x6000, 0x5000), + baetypes.Unknown('xxxx', 'unknown type data'), + baetypes.Character(1), + baetypes.Character(2, baetypes.Line(2)), + ] + for o in objs: + print 'BEFORE', o, `o` + print type(o) + packed = pack(o) + unpacked = unpack(packed) + print 'AFTER ', unpacked, `unpacked` + import sys + sys.exit(1) + +if __name__ == '__main__': + _test() + diff --git a/Mac/Contrib/PythonScript/baetools.py b/Mac/Contrib/PythonScript/baetools.py new file mode 100644 index 0000000..8f0bb04 --- /dev/null +++ b/Mac/Contrib/PythonScript/baetools.py @@ -0,0 +1,263 @@ +"""Tools for use in AppleEvent clients and servers. + +pack(x) converts a Python object to an AEDesc object +unpack(desc) does the reverse + +packevent(event, parameters, attributes) sets params and attrs in an AEAppleEvent record +unpackevent(event) returns the parameters and attributes from an AEAppleEvent record + +Plus... Lots of classes and routines that help representing AE objects, +ranges, conditionals, logicals, etc., so you can write, e.g.: + + x = Character(1, Document("foobar")) + +and pack(x) will create an AE object reference equivalent to AppleScript's + + character 1 of document "foobar" + +Some of the stuff that appears to be exported from this module comes from other +files: the pack stuff from aepack, the objects from aetypes. + +""" + +from types import * +import AE +import AppleEvents +import MacOS +import sys + +from baetypes import * +from baepack import pack, unpack, coerce, AEDescType + +Error = 'baetools.Error' + +# Special code to unpack an AppleEvent (which is *not* a disguised record!) +# Note by Jack: No??!? If I read the docs correctly it *is*.... + +aekeywords = [ + 'tran', + 'rtid', + 'evcl', + 'evid', + 'addr', + 'optk', + 'timo', + 'inte', # this attribute is read only - will be set in AESend + 'esrc', # this attribute is read only + 'miss', # this attribute is read only + 'from' # new in 1.0.1 +] + +def missed(ae): + try: + desc = ae.AEGetAttributeDesc('miss', 'keyw') + except AE.Error, msg: + return None + return desc.data + +def unpackevent(ae): + parameters = {} + while 1: + key = missed(ae) + if not key: break + parameters[key] = unpack(ae.AEGetParamDesc(key, '****')) + attributes = {} + for key in aekeywords: + try: + desc = ae.AEGetAttributeDesc(key, '****') + except (AE.Error, MacOS.Error), msg: + if msg[0] != -1701 and msg[0] != -1704: + raise sys.exc_type, sys.exc_value + continue + attributes[key] = unpack(desc) + return parameters, attributes + +def packevent(ae, parameters = {}, attributes = {}): + for key, value in parameters.items(): + ae.AEPutParamDesc(key, pack(value)) + for key, value in attributes.items(): + ae.AEPutAttributeDesc(key, pack(value)) + +# +# Support routine for automatically generated Suite interfaces +# These routines are also useable for the reverse function. +# +def keysubst(arguments, keydict): + """Replace long name keys by their 4-char counterparts, and check""" + ok = keydict.values() + for k in arguments.keys(): + if keydict.has_key(k): + v = arguments[k] + del arguments[k] + arguments[keydict[k]] = v + elif k != '----' and k not in ok: + raise TypeError, 'Unknown keyword argument: %s'%k + +def enumsubst(arguments, key, edict): + """Substitute a single enum keyword argument, if it occurs""" + if not arguments.has_key(key): + return + v = arguments[key] + ok = edict.values() + if edict.has_key(v): + arguments[key] = edict[v] + elif not v in ok: + raise TypeError, 'Unknown enumerator: %s'%v + +def decodeerror(arguments): + """Create the 'best' argument for a raise MacOS.Error""" + errn = arguments['errn'] + err_a1 = errn + if arguments.has_key('errs'): + err_a2 = arguments['errs'] + else: + err_a2 = MacOS.GetErrorString(errn) + if arguments.has_key('erob'): + err_a3 = arguments['erob'] + else: + err_a3 = None + + return (err_a1, err_a2, err_a3) + +class TalkTo: + """An AE connection to an application""" + + def __init__(self, signature, start=0, timeout=0): + """Create a communication channel with a particular application. + Addressing the application is done by specifying either a + 4-byte signature, an AEDesc or an object that will __aepack__ + to an AEDesc. + """ + self.target_signature = None + if type(signature) == AEDescType: + self.target = signature + elif type(signature) == InstanceType and hasattr(signature, '__aepack__'): + self.target = signature.__aepack__() + elif type(signature) == StringType and len(signature) == 4: + self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature) + self.target_signature = signature + else: + raise TypeError, "signature should be 4-char string or AEDesc" + self.send_flags = AppleEvents.kAEWaitReply + self.send_priority = AppleEvents.kAENormalPriority + if timeout: + self.send_timeout = timeout + else: + self.send_timeout = AppleEvents.kAEDefaultTimeout + if start: + self.start() + + def start(self): + """Start the application, if it is not running yet""" + self.send_flags = AppleEvents.kAENoReply + _launch(self.target_signature) + + def newevent(self, code, subcode, parameters = {}, attributes = {}): + """Create a complete structure for an apple event""" + event = AE.AECreateAppleEvent(code, subcode, self.target, + AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID) +# print parameters, attributes + packevent(event, parameters, attributes) + return event + + def sendevent(self, event): + """Send a pre-created appleevent, await the reply and unpack it""" + + reply = event.AESend(self.send_flags, self.send_priority, + self.send_timeout) + parameters, attributes = unpackevent(reply) + return reply, parameters, attributes + + def send(self, code, subcode, parameters = {}, attributes = {}): + """Send an appleevent given code/subcode/pars/attrs and unpack the reply""" + return self.sendevent(self.newevent(code, subcode, parameters, attributes)) + + # + # The following events are somehow "standard" and don't seem to appear in any + # suite... + # + def activate(self): + """Send 'activate' command""" + self.send('misc', 'actv') + + def _get(self, _object, as=None, _attributes={}): + """_get: get data from an object + Required argument: the object + Keyword argument _attributes: AppleEvent attribute dictionary + Returns: the data + """ + _code = 'core' + _subcode = 'getd' + + _arguments = {'----':_object} + if as: + _arguments['rtyp'] = mktype(as) + + _reply, _arguments, _attributes = self.send(_code, _subcode, + _arguments, _attributes) + if _arguments.has_key('errn'): + raise Error, decodeerror(_arguments) + + if _arguments.has_key('----'): + return _arguments['----'] + +# Tiny Finder class, for local use only + +class _miniFinder(TalkTo): + def open(self, _object, _attributes={}, **_arguments): + """open: Open the specified object(s) + Required argument: list of objects to open + Keyword argument _attributes: AppleEvent attribute dictionary + """ + _code = 'aevt' + _subcode = 'odoc' + + if _arguments: raise TypeError, 'No optional args expected' + _arguments['----'] = _object + + + _reply, _arguments, _attributes = self.send(_code, _subcode, + _arguments, _attributes) + if _arguments.has_key('errn'): + raise aetools.Error, aetools.decodeerror(_arguments) + # XXXX Optionally decode result + if _arguments.has_key('----'): + return _arguments['----'] +#pass + +_finder = _miniFinder('MACS') + +def _launch(appfile): + """Open a file thru the finder. Specify file by name or fsspec""" + _finder.open(_application_file(('ID ', appfile))) + + +class _application_file(ComponentItem): + """application file - An application's file on disk""" + want = 'appf' + +_application_file._propdict = { +} +_application_file._elemdict = { +} + +# Test program +# XXXX Should test more, really... + +def test(): + target = AE.AECreateDesc('sign', 'quil') + ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0) + print unpackevent(ae) + raw_input(":") + ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0) + obj = Character(2, Word(1, Document(1))) + print obj + print repr(obj) + packevent(ae, {'----': obj}) + params, attrs = unpackevent(ae) + print params['----'] + raw_input(":") + +if __name__ == '__main__': + test() + sys.exit(1) diff --git a/Mac/Contrib/PythonScript/baetypes.py b/Mac/Contrib/PythonScript/baetypes.py new file mode 100644 index 0000000..b087548 --- /dev/null +++ b/Mac/Contrib/PythonScript/baetypes.py @@ -0,0 +1,564 @@ +"""aetypes - Python objects representing various AE types.""" + +from AppleEvents import * +from AERegistry import * +from AEObjects import * +import struct +from types import * +import string + +# +# convoluted, since there are cyclic dependencies between this file and +# aetools_convert. +# +def pack(*args): + from aepack import pack + return apply(pack, args) + +def IsSubclass(cls, base): + """Test whether CLASS1 is the same as or a subclass of CLASS2""" + # Loop to optimize for single inheritance + while 1: + if cls is base: return 1 + if len(cls.__bases__) <> 1: break + cls = cls.__bases__[0] + # Recurse to cope with multiple inheritance + for c in cls.__bases__: + if IsSubclass(c, base): return 1 + return 0 + +def IsInstance(x, cls): + """Test whether OBJECT is an instance of (a subclass of) CLASS""" + return type(x) is InstanceType and IsSubclass(x.__class__, cls) + +def nice(s): + """'nice' representation of an object""" + if type(s) is StringType: return repr(s) + else: return str(s) + +class Unknown: + """An uninterpreted AE object""" + + def __init__(self, type, data): + self.type = type + self.data = data + + def __repr__(self): + return "Unknown(%s, %s)" % (`self.type`, `self.data`) + + def __aepack__(self): + return pack(self.data, self.type) + +class Enum: + """An AE enumeration value""" + + def __init__(self, enum): + self.enum = "%-4.4s" % str(enum) + + def __repr__(self): + return "Enum(%s)" % `self.enum` + + def __str__(self): + return string.strip(self.enum) + + def __aepack__(self): + return pack(self.enum, typeEnumeration) + +def IsEnum(x): + return IsInstance(x, Enum) + +def mkenum(enum): +# print enum + if IsEnum(enum): return enum + return Enum(enum) + +class Boolean: + """An AE boolean value""" + + def __init__(self, bool): + if bool: + self.bool = "%-4.4s" % str(typeTrue) + else: + self.bool = "%-4.4s" % str(typeFalse) + + def __repr__(self): + return "Boolean(%s)" % self.bool + + def __str__(self): + return self.bool + + def __aepack__(self): + if self.bool == 'true': + return pack('', typeTrue) + else: + return pack('', typeFalse) + +def IsBoolean(x): + return IsInstance(x, Boolean) + +def mkboolean(bool): +# print bool + if IsBoolean(bool): return bool + return Boolean(bool) + +class Type: + """An AE 4-char typename object""" + + def __init__(self, _type): + self.type = "%-4.4s" % str(_type) + + def __repr__(self): + return "Type(%s)" % `self.type` + + def __str__(self): + return string.strip(self.type) + + def __aepack__(self): +# print self.type, typeType + return pack(self.type, typeType) + +def IsType(x): + return IsInstance(x, Type) + +def mktype(_type): + # Should check for apple ID codes, will allow + if IsType(_type): return _type + if type(_type) <> StringType: return _type + if len(_type) <> 4: return Type(eval('type' + _type)) + return Type(_type) + + +class Keyword: + """An AE 4-char keyword object""" + + def __init__(self, keyword): + self.keyword = "%-4.4s" % str(keyword) + + def __repr__(self): + return "Keyword(%s)" % `self.keyword` + + def __str__(self): + return string.strip(self.keyword) + + def __aepack__(self): + return pack(self.keyword, typeKeyword) + +def IsKeyword(x): + return IsInstance(x, Keyword) + +class Range: + """An AE range object""" + + def __init__(self, start, stop): + self.start = start + self.stop = stop + + def __repr__(self): + return "Range(%s, %s)" % (`self.start`, `self.stop`) + + def __str__(self): + return "%s thru %s" % (nice(self.start), nice(self.stop)) + + def __aepack__(self): + return pack({'star': self.start, 'stop': self.stop}, 'rang') + +def IsRange(x): + return IsInstance(x, Range) + +class Comparison: + """An AE Comparison""" + + def __init__(self, obj1, relo, obj2): + self.obj1 = obj1 + self.relo = "%-4.4s" % str(relo) + self.obj2 = obj2 + + def __repr__(self): + return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`) + + def __str__(self): + return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2)) + + def __aepack__(self): + return pack({'obj1': self.obj1, + 'relo': mkenum(self.relo), + 'obj2': self.obj2}, + 'cmpd') + +def IsComparison(x): + return IsInstance(x, Comparison) + +class NComparison(Comparison): + # The class attribute 'relo' must be set in a subclass + + def __init__(self, obj1, obj2): + Comparison.__init__(obj1, self.relo, obj2) + +class Ordinal: + """An AE Ordinal""" + + def __init__(self, ord): + self.ord = ord + + def __repr__(self): + return "baetypes.Ordinal(%s)" % `self.ord` + + def __str__(self): + return "%s" % (string.strip(self.ord)) + + def __aepack__(self): + return pack(self.ord, typeAbsoluteOrdinal) + +def IsOrdinal(x): +# print 'IsOrdinal', x, IsInstance(x, Ordinal) + return IsInstance(x, Ordinal) + +def mkOrdinal(Ord): + if IsOrdinal(Ord): return Ord + return Ordinal(Ord) + + + +class NOrdinal(Ordinal): + # The class attribute 'abso' must be set in a subclass + + def __init__(self ): +# print 'NOrdinal', self.abso + Ordinal.__init__(self, self.abso) + +class Logical: + """An AE logical expression object""" + + def __init__(self, logc, term): + self.logc = "%-4.4s" % str(logc) + self.term = term + + def __repr__(self): + return "Logical(%s, %s)" % (`self.logc`, `self.term`) + + def __str__(self): + if type(self.term) == ListType and len(self.term) == 2: + return "%s %s %s" % (nice(self.term[0]), + string.strip(self.logc), + nice(self.term[1])) + else: + return "%s(%s)" % (string.strip(self.logc), nice(self.term)) + + def __aepack__(self): + return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi') + +def IsLogical(x): + return IsInstance(x, Logical) + +class StyledText: + """An AE object respresenting text in a certain style""" + + def __init__(self, style, text): + self.style = style + self.text = text + + def __repr__(self): + return "StyledText(%s, %s)" % (`self.style`, `self.text`) + + def __str__(self): + return self.text + + def __aepack__(self): + return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT') + +def IsStyledText(x): + return IsInstance(x, StyledText) + +class AEText: + """An AE text object with style, script and language specified""" + + def __init__(self, script, style, text): + self.script = script + self.style = style + self.text = text + + def __repr__(self): + return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`) + + def __str__(self): + return self.text + + def __aepack__(self): + return pack({keyAEScriptTag: self.script, keyAEStyles: self.style, + keyAEText: self.text}, typeAEText) + +def IsAEText(x): + return IsInstance(x, AEText) + +class IntlText: + """A text object with script and language specified""" + + def __init__(self, script, language, text): + self.script = script + self.language = language + self.text = text + + def __repr__(self): + return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`) + + def __str__(self): + return self.text + + def __aepack__(self): + return pack(struct.pack('hh', self.script, self.language)+self.text, + typeIntlText) + +def IsIntlText(x): + return IsInstance(x, IntlText) + +class IntlWritingCode: + """An object representing script and language""" + + def __init__(self, script, language): + self.script = script + self.language = language + + def __repr__(self): + return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`) + + def __str__(self): + return "script system %d, language %d"%(self.script, self.language) + + def __aepack__(self): + return pack(struct.pack('hh', self.script, self.language), + typeIntlWritingCode) + +def IsIntlWritingCode(x): + return IsInstance(x, IntlWritingCode) + +class QDPoint: + """A point""" + + def __init__(self, v, h): + self.v = v + self.h = h + + def __repr__(self): + return "QDPoint(%s, %s)" % (`self.v`, `self.h`) + + def __str__(self): + return "(%d, %d)"%(self.v, self.h) + + def __aepack__(self): + return pack(struct.pack('hh', self.v, self.h), + typeQDPoint) + +def IsQDPoint(x): + return IsInstance(x, QDPoint) + +class QDRectangle: + """A rectangle""" + + def __init__(self, v0, h0, v1, h1): + self.v0 = v0 + self.h0 = h0 + self.v1 = v1 + self.h1 = h1 + + def __repr__(self): + return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`, + `self.v1`, `self.h1`) + + def __str__(self): + return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1) + + def __aepack__(self): + return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1), + typeQDRectangle) + +def IsQDRectangle(x): + return IsInstance(x, QDRectangle) + +class RGBColor: + """An RGB color""" + + def __init__(self, r, g, b): + self.r = r + self.g = g + self.b = b + + def __repr__(self): + return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`) + + def __str__(self): + return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b) + + def __aepack__(self): + return pack(struct.pack('hhh', self.r, self.g, self.b), + typeRGBColor) + +def IsRGBColor(x): + return IsInstance(x, RGBColor) + +class ObjectSpecifier: + + """A class for constructing and manipulation AE object specifiers in python. + + An object specifier is actually a record with four fields: + + key type description + --- ---- ----------- + + 'want' type 4-char class code of thing we want, + e.g. word, paragraph or property + + 'form' enum how we specify which 'want' thing(s) we want, + e.g. by index, by range, by name, or by property specifier + + 'seld' any which thing(s) we want, + e.g. its index, its name, or its property specifier + + 'from' object the object in which it is contained, + or null, meaning look for it in the application + + Note that we don't call this class plain "Object", since that name + is likely to be used by the application. + """ + + def __init__(self, want, form, seld, fr = None): + self.want = want + self.form = form + self.seld = seld + self.fr = fr + + def __repr__(self): + s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`) + if self.fr: + s = s + ", %s)" % `self.fr` + else: + s = s + ")" + return s + + def __aepack__(self): + return pack({'want': mktype(self.want), + 'form': mkenum(self.form), + 'seld': self.seld, + 'from': self.fr}, + 'obj ') + +def IsObjectSpecifier(x): + return IsInstance(x, ObjectSpecifier) + + +# Backwards compatability, sigh... +class Property(ObjectSpecifier): + + def __init__(self, which, fr = None, want='prop'): + ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr) + + def __repr__(self): + if self.fr: + return "Property_r(%s, %s)" % (`self.seld.type`, `self.fr`) + else: + return "Property_r(%s)" % `self.seld.type` + + def __str__(self): + if self.fr: + return "Property %s of %s" % (str(self.seld), str(self.fr)) + else: + return "Property_s %s" % str(self.seld) + + +class NProperty(ObjectSpecifier): + # Subclasses *must* self baseclass attributes: + # want is the type of this property + # which is the property name of this property + + def __init__(self, want, form, seld, fr = None): + ObjectSpecifier.__init__(self, want, form, + mktype(seld), fr) + + +class SelectableItem(ObjectSpecifier): + + def __init__(self, want, seld, fr = None): + t = type(seld) + if t == StringType: + form = 'name' + elif IsRange(seld): + form = 'rang' + elif IsComparison(seld) or IsLogical(seld): + form = 'test' + elif t == TupleType: + # Breakout: specify both form and seld in a tuple + # (if you want ID or rele or somesuch) + form, seld = seld + else: + form = 'indx' + ObjectSpecifier.__init__(self, want, form, seld, fr) + + +class ComponentItem(SelectableItem): + # Derived classes *must* set the *class attribute* 'want' to some constant + # Also, dictionaries _propdict and _elemdict must be set to map property + # and element names to the correct classes + + def __init__(self, want, which, fr = None): + SelectableItem.__init__(self, want, which, fr) + + def __repr__(self): + if not self.fr: + return "%s(%s)" % (self.__class__.__name__, `self.seld`) + return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`) + + def __str__(self): + seld = self.seld + if type(seld) == StringType: + ss = repr(seld) + elif IsRange(seld): + start, stop = seld.start, seld.stop + if type(start) == InstanceType == type(stop) and \ + start.__class__ == self.__class__ == stop.__class__: + ss = str(start.seld) + " thru " + str(stop.seld) + else: + ss = str(seld) + else: + ss = str(seld) + s = "%s %s" % (self.__class__.__name__, ss) + if self.fr: s = s + " of %s" % str(self.fr) + return s + +# def __getattr__(self, name): +# print name +# if self._elemdict.has_key(name): +# cls = self._elemdict[name] +# return DelayedComponentItem(cls, self) +# if self._propdict.has_key(name): +# cls = self._propdict[name] +# return cls(self) +# raise AttributeError, name + + +class DelayedComponentItem: + def __init__(self, compclass, fr): + self.compclass = compclass + self.fr = fr + + def __call__(self, which): + return self.compclass(which, self.fr) + + def __repr__(self): + return "%s(???, %s)" % (self.__class__.__name__, `self.fr`) + + def __str__(self): + return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr)) + +template = """ +class %s(ComponentItem): want = '%s' +""" + +exec template % ("Text", 'text') +exec template % ("Character", 'cha ') +exec template % ("Word", 'cwor') +exec template % ("Line", 'clin') +exec template % ("paragraph", 'cpar') +exec template % ("Window", 'cwin') +exec template % ("Document", 'docu') +exec template % ("File", 'file') +exec template % ("InsertionPoint", 'cins') + diff --git a/Mac/Contrib/PythonScript/getaete.py b/Mac/Contrib/PythonScript/getaete.py new file mode 100644 index 0000000..14beb32 --- /dev/null +++ b/Mac/Contrib/PythonScript/getaete.py @@ -0,0 +1,406 @@ +""" +Produces a 3 dictionaries from application aete's +to be read by PythonScript + +v.02 january 31, 1998 added support for inheriting suites from aeut +v.03 february 16, 1998 changes to identify +v.04 february 26, 1998 simplified decode +v.05 23/04/98 simplified _launch + +""" +import baetools +import macpath +import sys +import os +import MacOS +import StringIO +import types +from MACFS import * +import macfs +import string +from Res import * +import struct + +# for testing only +app ='CSOm' #'ezVu'# 'nwSP'#MACS'# + +#Restrict the application suites to the dialect we want to use. +LANG = 0 # 0 = English, 1 = French, 11 = Japanese +lang = {0:'English', 1:'French', 11:'Japanese'} + +#The following are neaded to open the application aete +kASAppleScriptSuite = 'ascr' +kGetAETE = 'gdte' +attributes = {} +arguments = {} + +class AETE(baetools.TalkTo): + pass + +def Getaete(app): + try: + data = openaete(app) + except MacOS.Error, msg: + if msg[0] == -609: + _launch(app) + data = openaete(app) + data = decode(data['----'].data) + data = compileaete(data) + return data + + +def decode(data): + """Decode an aete into a python data structure""" + f = StringIO.StringIO(data) + aete = generic(getaete, f) + return aete + +def simplify(item): + """Recursively replace singleton tuples by their constituent item""" + if type(item) is types.ListType: + return map(simplify, item) + elif type(item) == types.TupleType and len(item) == 2: + return simplify(item[1]) + else: + return item + + +## Here follows the aete resource decoder. +## It is presented bottom-up instead of top-down because there are direct +## references to the lower-level part-decoders from the high-level part-decoders. +# +def getflag(f, *args): + m = '' + c = f.read(2) + print `c` + if not c: + raise EOFError, 'in getflag' + str(args) + for n in c: + m = m + `ord(n)` + +def getbyte(f, *args): + c = f.read(1) + if not c: + raise EOFError, 'in getbyte' + str(args) + return ord(c) + +def getword(f, *args): + getalign(f) + s = f.read(2) + if len(s) < 2: + raise EOFError, 'in getword' + str(args) + return (ord(s[0])<<8) | ord(s[1]) + +def getlong(f, *args): + getalign(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getlong' + str(args) + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def getostype(f, *args): + getalign(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getostype' + str(args) + return s + +def getpstr(f, *args): + c = f.read(1) + if len(c) < 1: + raise EOFError, 'in getpstr[1]' + str(args) + nbytes = ord(c) + if nbytes == 0: return '' + s = f.read(nbytes) + if len(s) < nbytes: + raise EOFError, 'in getpstr[2]' + str(args) + return s + +def getalign(f): + if f.tell() & 1: + c = f.read(1) + ##if c <> '\0': + ## print 'align:', `c` + +def getlist(f, description, getitem): + count = getword(f) + list = [] + for i in range(count): + list.append(generic(getitem, f)) + getalign(f) + return list + +def alt_generic(what, f, *args): + print "generic", `what`, args + res = vageneric(what, f, args) + print '->', `res` + return res + +def generic(what, f, *args): + if type(what) == types.FunctionType: + return apply(what, (f,) + args) + if type(what) == types.ListType: + record = [] + for thing in what: + item = apply(generic, thing[:1] + (f,) + thing[1:]) + record.append(item) + return record + return "BAD GENERIC ARGS: %s" % `what` + +getdata = [ + (getostype, "type"), + (getpstr, "description"), + (getword, "flags") + ] +getargument = [ + (getpstr, "name"), + (getostype, "keyword"), + (getdata, "what") + ] +getevent = [ + (getpstr, "name"), + (getpstr, "description"), + (getostype, "suite code"), + (getostype, "event code"), + (getdata, "returns"), + (getdata, "accepts"), + (getlist, "optional arguments", getargument) + ] +getproperty = [ + (getpstr, "name"), + (getostype, "code"), + (getdata, "what") + ] +getelement = [ + (getostype, "type"), + (getlist, "keyform", getostype) + ] +getclass = [ + (getpstr, "name"), + (getostype, "class code"), + (getpstr, "description"), + (getlist, "properties", getproperty), + (getlist, "elements", getelement) + ] +getcomparison = [ + (getpstr, "operator name"), + (getostype, "operator ID"), + (getpstr, "operator comment"), + ] +getenumerator = [ + (getpstr, "enumerator name"), + (getostype, "enumerator ID"), + (getpstr, "enumerator comment") + ] +getenumeration = [ + (getostype, "enumeration ID"), + (getlist, "enumerator", getenumerator) + ] +getsuite = [ + (getpstr, "suite name"), + (getpstr, "suite description"), + (getostype, "suite ID"), + (getword, "suite level"), + (getword, "suite version"), + (getlist, "events", getevent), + (getlist, "classes", getclass), + (getlist, "comparisons", getcomparison), + (getlist, "enumerations", getenumeration) + ] +getaete = [ + (getbyte, "major version in BCD"), + (getbyte, "minor version in BCD"), + (getword, "language code"), + (getword, "script code"), + (getlist, "suites", getsuite) + ] + +def compileaete(aete): + """Generate dictionary for a full aete resource.""" + [major, minor, language, script, suites] = aete + suitedict = {} + gsuites = openaeut() + for gsuite in gsuites: + if gsuite[0] == 'AppleScript Suite': + suite = gsuite + suite = compilesuite(suite) + suitedict[identify(suite[0])] = suite[1:] + for suite in suites: + if language == LANG: + suitecode = suite[2] + if suite[5] == []: + for gsuite in gsuites: + if suitecode == gsuite[2]: + suite = gsuite + suite = compilesuite(suite) + suitedict[identify(suite[0])] = suite[1:] + suitedict = combinesuite(suitedict) + return suitedict + +def compilesuite(suite): + """Generate dictionary for a single suite""" + [name, desc, code, level, version, events, classes, comps, enums] = suite + eventdict ={} + classdict = {} + enumdict ={} + for event in events: + if event[6]: + for ev in event[6]: + ev[0] = identify(ev[:2]) + eventdict[identify(event[:2])] = event[1:] + for klass in classes: + if klass[3]: + for kl in klass[3]: + kl[0] = identify(kl[:2]) + classdict[identify(klass[:2])] = klass[1:] + for enum in enums: + enumdict[enum[0]] = enum[1] + return name, eventdict, classdict, enumdict + +def combinesuite(suite): + """Combines suite dictionaries to seperate event, class, enumeration dictionaries + """ + + suitelist = [] + eventDict ={} + classDict ={} + enumDict ={} + for value in suite.values(): + for key in value[0].keys(): + val = value[0][key] + eventDict[key] = val + for key in value[1].keys(): + val = value[1][key] + if key in classDict.keys(): + nval = classDict[key][2] + val[2] = val[2] + nval + classDict[key] = val + for key in value[2].keys(): + val = value[2][key] + enumDict[key] = val + return eventDict, classDict, enumDict + + +illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return", + "def", "name", 'data' ] + +def identify(str): + """Turn any string into an identifier: + - replace space by _ + - remove ',' and '-' + capitalise + """ + if not str[0]: + if str[1] == 'c@#!': + return "Every" + else: + return 'Any' + rv = string.replace(str[0], ' ', '_') + rv = string.replace(rv, '-', '') + rv = string.replace(rv, ',', '') + rv = string.capitalize(rv) + return rv + + +def openaete(app): + """open and read the aete of the target application""" + arguments['----'] = LANG + _aete = AETE(app) + _reply, _arguments, _attributes = _aete.send(kASAppleScriptSuite, kGetAETE, arguments, attributes) + if _arguments.has_key('errn'): + raise baetools.Error, baetools.decodeerror(_arguments) + return _arguments + +def openaeut(): + """Open and read a aeut file. + XXXXX This has been temporarily hard coded until a Python aeut is written XXXX""" + + fullname = dialect + rf = OpenRFPerm(fullname, 0, 1) + try: + UseResFile(rf) + resources = [] + for i in range(Count1Resources('aeut')): + res = Get1IndResource('aeut', 1+i) + resources.append(res) + for res in resources: + data = res.data + data = decode(data)[4] + finally: + CloseResFile(rf) + return data + +def dialect(): + """find the correct Dialect file""" + + dialect = lang[LANG] + " Dialect" + try: + ##System 8 + vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kScriptingAdditionsFolderType, 0) + fss = macfs.FSSpec((vRefNum, dirID, '')) + fss = fss.as_pathname() + except macfs.error: + ##Sytem 7 + vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0) + fss = macfs.FSSpec((vRefNum, dirID, '')) + fss = fss.as_pathname() + fss = macpath.join(fss, "Scripting Additions") + fss = macpath.join(fss, "Dialect") + fss = macpath.join(fss, dialect) + return fss + + +#def openosax(): +# """Open and read the aetes of osaxen in the scripting additions folder""" +# +# # System 7.x +# aete = [] +# vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0) +# fss = macfs.FSSpec((vRefNum, dirID, '')) +# fss = fss.as_pathname() +# osax = macpath.join(fss, "Scripting Additions") +# for file in os.listdir(osax): +# fullname = macpath.join(osax, file) +# print fullname +# rf = OpenRFPerm(fullname, 0, 1) +# try: +# UseResFile(rf) +# resources = [] +# for i in range(Count1Resources('aete')): +# res = Get1IndResource('aete', 1+i) +# resources.append(res) +# for res in resources: +# data = res.data +# data = decode(data)[4] +# finally: +# CloseResFile(rf) +# aete.append(data) +# print data + + +#The following should be replaced by direct access to a python 'aeut' + +def _launch(appfile): + """Open a file thru the finder. Specify file by name or fsspec""" + +# from PythonScript import PyScript + import baetypes + _finder = AETE('MACS') + parameters ={} + parameters['----'] = eval("baetypes.ObjectSpecifier('%s', '%s', %s)" % ('appf', 'ID ', `appfile`)) + _reply, _arguments, _attributes = _finder.send( 'aevt', 'odoc', parameters , attributes = {}) + if _arguments.has_key('errn'): + raise baetools.Error, baetools.decodeerror(_arguments) + # XXXX Optionally decode result + if _arguments.has_key('----'): + return _arguments['----'] + + + +if __name__ == '__main__': +# import profile +# profile.run('Getaete(app)', 'Getaeteprof') + Getaete(app) +# openosax() +# openaete('ascr') +# sys.exit(1) diff --git a/Mac/Contrib/PythonScript/printaete.py b/Mac/Contrib/PythonScript/printaete.py new file mode 100644 index 0000000..a7fe8e0 --- /dev/null +++ b/Mac/Contrib/PythonScript/printaete.py @@ -0,0 +1,346 @@ +""" +Produces a human readable file of an application's aete + +v.02 january 29, 1998 bug fix Main() +v.03 january 31, 1998 added support for inheriting suites from aeut +v.04 april 16, 1998 Changed identify to match getaete +""" + +import aetools +import sys +import MacOS +import StringIO +import types +import macfs +import string +import macpath +from Res import * + +# for testing only +app = 'MACS'#CSOm'#'nwSP'#'ezVu'# + +#Dialect file hard coded as a tempoary measure +DIALECT = 'Hermit:System Folder:Scripting Additions:Dialects:English Dialect' + +#Restrict the application suites to the dialect we want to use. +LANG = 0 # 0 = English, 1 = French, 11 = Japanese + +#The following are neaded to open the application aete +kASAppleScriptSuite = 'ascr' +kGetAETE = 'gdte' +attributes = {} +arguments = {} + +class AETE(aetools.TalkTo): + pass + +def Main(appl): + fss, ok = macfs.PromptGetFile('Application to work on', 'FNDR', 'APPL')# + if not ok: + return + app = fss.GetCreatorType()[0] + path = macpath.split(sys.argv[0])[0] + appname = macpath.split(fss.as_pathname())[1] + appname = appname + '.aete' + appname = macpath.join(path, appname) + try: + data = Getaete(app) + except MacOS.Error, msg: + if msg[0] == -609: + _launch(app) + data = Getaete(app) +# print data + data = decode(data['----'].data) + data = compileaete(data, appname) + + +def decode(data): + """Decode an aete into a python data structure""" + f = StringIO.StringIO(data) + aete = generic(getaete, f) + aete = simplify(aete) + return aete + +def simplify(item): + """Recursively replace singleton tuples by their constituent item""" + if type(item) is types.ListType: + return map(simplify, item) + elif type(item) == types.TupleType and len(item) == 2: + return simplify(item[1]) + else: + return item + + +## Here follows the aete resource decoder. +## It is presented bottom-up instead of top-down because there are direct +## references to the lower-level part-decoders from the high-level part-decoders. +# +def getbyte(f, *args): + c = f.read(1) + if not c: + raise EOFError, 'in getbyte' + str(args) + return ord(c) + +def getword(f, *args): + getalign(f) + s = f.read(2) + if len(s) < 2: + raise EOFError, 'in getword' + str(args) + return (ord(s[0])<<8) | ord(s[1]) + +def getlong(f, *args): + getalign(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getlong' + str(args) + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def getostype(f, *args): + getalign(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getostype' + str(args) + return s + +def getpstr(f, *args): + c = f.read(1) + if len(c) < 1: + raise EOFError, 'in getpstr[1]' + str(args) + nbytes = ord(c) + if nbytes == 0: return '' + s = f.read(nbytes) + if len(s) < nbytes: + raise EOFError, 'in getpstr[2]' + str(args) + return s + +def getalign(f): + if f.tell() & 1: + c = f.read(1) + ##if c <> '\0': + ## print 'align:', `c` + +def getlist(f, description, getitem): + count = getword(f) + list = [] + for i in range(count): + list.append(generic(getitem, f)) + getalign(f) + return list + +def alt_generic(what, f, *args): + print "generic", `what`, args + res = vageneric(what, f, args) + print '->', `res` + return res + +def generic(what, f, *args): + if type(what) == types.FunctionType: + return apply(what, (f,) + args) + if type(what) == types.ListType: + record = [] + for thing in what: +# print thing + item = apply(generic, thing[:1] + (f,) + thing[1:]) + record.append((thing[1], item)) + return record + return "BAD GENERIC ARGS: %s" % `what` + +getdata = [ + (getostype, "type"), + (getpstr, "description"), + (getword, "flags") + ] +getargument = [ + (getpstr, "name"), + (getostype, "keyword"), + (getdata, "what") + ] +getevent = [ + (getpstr, "name"), + (getpstr, "description"), + (getostype, "suite code"), + (getostype, "event code"), + (getdata, "returns"), + (getdata, "accepts"), + (getlist, "optional arguments", getargument) + ] +getproperty = [ + (getpstr, "name"), + (getostype, "code"), + (getdata, "what") + ] +getelement = [ + (getostype, "type"), + (getlist, "keyform", getostype) + ] +getclass = [ + (getpstr, "name"), + (getostype, "class code"), + (getpstr, "description"), + (getlist, "properties", getproperty), + (getlist, "elements", getelement) + ] +getcomparison = [ + (getpstr, "operator name"), + (getostype, "operator ID"), + (getpstr, "operator comment"), + ] +getenumerator = [ + (getpstr, "enumerator name"), + (getostype, "enumerator ID"), + (getpstr, "enumerator comment") + ] +getenumeration = [ + (getostype, "enumeration ID"), + (getlist, "enumerator", getenumerator) + ] +getsuite = [ + (getpstr, "suite name"), + (getpstr, "suite description"), + (getostype, "suite ID"), + (getword, "suite level"), + (getword, "suite version"), + (getlist, "events", getevent), + (getlist, "classes", getclass), + (getlist, "comparisons", getcomparison), + (getlist, "enumerations", getenumeration) + ] +getaete = [ + (getword, "major/minor version in BCD"), + (getword, "language code"), + (getword, "script code"), + (getlist, "suites", getsuite) + ] + +def compileaete(aete, appname): + """Generate dictionary file for a full aete resource.""" + [version, language, script, suites] = aete + major, minor = divmod(version, 256) + fp = open(appname, 'w') + + fp.write('%s:\n' % (appname)) + fp.write("AETE resource version %d/%d, language %d, script %d\n" % \ + (major, minor, language, script)) + fp.write('\n\n') + gsuites = openaeut() + for suite in suites: + if language == LANG: + suitecode = suite[2] + if suite[5] == []: + for gsuite in gsuites: + if suitecode == gsuite[2]: + suite = gsuite + [name, desc, code, level, version, events, classes, comps, enums] = suite + fp.write('\n%s Suite: %s\n' % (name, desc)) + fp.write('\n\tEvents:\n') + for event in events: + fp.write('\n\t%s: %s\n' % (identify(event[0]), event[1])) + fp.write('\t\t%s: %s -- %s\n' % (identify(event[0]), event[5][1], event[5][0])) + fp.write('\t\tResult: %s -- %s\n' % (event[4][1], event[4][0])) + for ev in event[6]: + fp.write('\t\t\t%s: %s -- %s\n' % (identify(ev[0]), ev[2][0], ev[2][1])) + fp.write('\n\tClasses') + for klass in classes: + fp.write('\n\t%s: %s\n' % (identify(klass[0]), klass[2])) + if klass[3]: + if not klass[3][0][0]: continue + fp.write('\t\tProperties\n') + for cl in klass[3]: + fp.write('\t\t\t%s: %s -- %s\n' % (identify(cl[0]), cl[2][1], cl[2][0]))#,, cl[3][3][1])) + if klass[4]: + fp.write('\n\t\t\tElements\n') + for cl in klass[4]: + fp.write('\t\t\t\t%s: %s\n' % (identify(cl[0]), cl[1])) + + + + + + +illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return", + "def", "name" ] + +def identify(str): + """Turn any string into an identifier: + - replace space by _ + - prepend _ if the result is a python keyword + """ + + rv = string.replace(str, ' ', '_') + rv = string.replace(rv, '-', '') + rv = string.replace(rv, ',', '') + rv = string.capitalize(rv) + return rv + + +def Getaete(app): + '''Read the target aete''' + arguments['----'] = LANG + _aete = AETE(app) + _reply, _arguments, _attributes = _aete.send('ascr', 'gdte', arguments, attributes) + if _arguments.has_key('errn'): + raise aetools.Error, aetools.decodeerror(_arguments) + return _arguments + +def openaeut(): + """Open and read a aeut file. + XXXXX This has been temporarily hard coded until a Python aeut is written XXXX""" + + fullname = DIALECT + + rf = OpenRFPerm(fullname, 0, 1) + try: + UseResFile(rf) + resources = [] + for i in range(Count1Resources('aeut')): + res = Get1IndResource('aeut', 1+i) + resources.append(res) + for res in resources: + data = res.data + data = decode(data)[3] + finally: + CloseResFile(rf) + return data + + +#The following should be replaced by direct access to a python 'aeut' + +class _miniFinder(aetools.TalkTo): + def open(self, _object, _attributes={}, **_arguments): + """open: Open the specified object(s) + Required argument: list of objects to open + Keyword argument _attributes: AppleEvent attribute dictionary + """ + _code = 'aevt' + _subcode = 'odoc' + + if _arguments: raise TypeError, 'No optional args expected' + _arguments['----'] = _object + + + _reply, _arguments, _attributes = self.send(_code, _subcode, + _arguments, _attributes) + if _arguments.has_key('errn'): + raise aetools.Error, aetools.decodeerror(_arguments) + # XXXX Optionally decode result + if _arguments.has_key('----'): + return _arguments['----'] + +_finder = _miniFinder('MACS') + +def _launch(appfile): + """Open a file thru the finder. Specify file by name or fsspec""" + _finder.open(_application_file(('ID ', appfile))) + + +class _application_file(aetools.ComponentItem): + """application file - An application's file on disk""" + want = 'appf' + +_application_file._propdict = { +} +_application_file._elemdict = { +} + +Main(app) +sys.exit(1) diff --git a/Mac/Contrib/PythonScript/testeudora.py b/Mac/Contrib/PythonScript/testeudora.py new file mode 100644 index 0000000..ba676a3 --- /dev/null +++ b/Mac/Contrib/PythonScript/testeudora.py @@ -0,0 +1,44 @@ +"""A test program that allows us to control Eudora""" + +import sys +import MacOS +import PythonScript + +# The Creator signature of eudora: +SIGNATURE="CSOm" +TIMEOUT = 10*60*60 + + + +def main(): + PythonScript.PsScript(SIGNATURE, TIMEOUT) + talker = PythonScript.PyScript + ev = PythonScript.PsEvents + pc = PythonScript.PsClass + while 1: + print 'get, put, name (of first folder), list (foldernames), quit (eudora) or exit (this program) ?' + line = sys.stdin.readline() + try: + if line[0] == 'g': + print 'check' + print talker(ev.Activate) + print talker(ev.Connect, Checking=1) + elif line[0] == 'p': + print talker(ev.Connect, Sending=1) + elif line[0] == 'n': + id = talker(ev.Get, pc.Mail_folder("").Mailbox(1).Name()) + print "It is called", id, "\n" + elif line[0] == 'l': + id = talker(ev.Count, pc.Mail_folder(""), Each='Mailbox') + print "There are", id, "mailboxes" + elif line[0] == 'q': + print talker(ev.Quit) + elif line[0] == 'e': + break + except MacOS.Error, arg: + if arg[0] == -609: + print 'Connection invalid, is eudora running?' + else: + print 'MacOS Error:', arg[1] + +main() diff --git a/Mac/Contrib/osam/OSAm.c b/Mac/Contrib/osam/OSAm.c new file mode 100644 index 0000000..a9c3445 --- /dev/null +++ b/Mac/Contrib/osam/OSAm.c @@ -0,0 +1,262 @@ +/* + * + * This is a simple module to allow the + * user to compile and execute an applescript + * which is passed in as a text item. + * + * Sean Hummel <seanh@prognet.com> + * 1/20/98 + * RealNetworks + * + * Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com> + * + * + */ +#include "OSAm.h" +#include "ScriptRunner.h" +#include <AppleEvents.h> + + + +/* + * Boiler plate generated from "genmodule.py" + */ +static PyObject *ErrorObject; +static char OSAm_DoCommand__doc__[] = ""; + + + +static PyObject * +OSAm_RunCompiledScript (self, args) + PyObject *self; + PyObject *args; +{ + char *commandStr = NULL; + char *outpath = NULL; + OSErr myErr; + AEDesc temp; + EventRecord event; + + temp.dataHandle = NULL; + + if (!PyArg_ParseTuple (args, "s", &commandStr)) + return NULL; + + myErr = ExecuteScriptFile (commandStr, NULL, &temp); + + if (temp.dataHandle != NULL && temp.descriptorType == 'TEXT') + { + char *line; + DescType typeCode; + long dataSize = 0; + + HLock (temp.dataHandle); + + dataSize = GetHandleSize (temp.dataHandle); + + if (dataSize > 0) + { + PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), + dataSize); + + AEDisposeDesc (&temp); + + if (!result) + { + printf ("OSAm.error Out of memory.\n"); + Py_INCREF (Py_None); + return Py_None; + } + + return result; + } + } + + if (myErr != noErr) + { + PyErr_Mac (ErrorObject, myErr); + return NULL; + } + + + Py_INCREF (Py_None); + return Py_None; +} + + + + +static PyObject * +OSAm_CompileAndSave (self, args) + PyObject *self; + PyObject *args; +{ + char *commandStr = NULL; + char *outpath = NULL; + OSErr myErr; + AEDesc temp; + EventRecord event; + + temp.dataHandle = NULL; + + if (!PyArg_ParseTuple (args, "ss", &commandStr, &outpath)) + return NULL; + + myErr = CompileAndSave (commandStr, outpath, NULL, &temp); + + + if (temp.dataHandle != NULL && temp.descriptorType == 'TEXT') + { + char *line; + DescType typeCode; + long dataSize = 0; + + HLock (temp.dataHandle); + + dataSize = GetHandleSize (temp.dataHandle); + + if (dataSize > 0) + { + PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), + dataSize); + + AEDisposeDesc (&temp); + + if (!result) + { + printf ("OSAm.error Out of memory.\n"); + Py_INCREF (Py_None); + return Py_None; + } + + return result; + } + + } + + if (myErr != noErr) + { + + PyErr_Mac (ErrorObject, myErr); + return NULL; + } + + + Py_INCREF (Py_None); + return Py_None; +} + + + +static PyObject * +OSAm_CompileAndExecute (self, args) + PyObject *self; + PyObject *args; +{ + char *commandStr; + OSErr myErr; + AEDesc temp; + EventRecord event; + + temp.dataHandle = NULL; + + if (!PyArg_ParseTuple (args, "s", &commandStr)) + return NULL; + + myErr = CompileAndExecute (commandStr, &temp, NULL); + + if (temp.dataHandle != NULL && temp.descriptorType == 'TEXT') + { + char *line; + DescType typeCode; + long dataSize = 0; + + HLock (temp.dataHandle); + + dataSize = GetHandleSize (temp.dataHandle); + + if (dataSize > 0) + { + PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle), + dataSize); + + AEDisposeDesc (&temp); + + if (!result) + { + printf ("OSAm.error Out of memory.\n"); + Py_INCREF (Py_None); + return Py_None; + } + + return result; + } + } + + if (myErr != noErr) + { + + PyErr_Mac (ErrorObject, myErr); + return NULL; + } + + + Py_INCREF (Py_None); + return Py_None; +} + + + +/* + * List of methods defined in the module + */ +static struct PyMethodDef OSAm_methods[] = +{ + {"CompileAndExecute", + (PyCFunction) OSAm_CompileAndExecute, + METH_VARARGS, + OSAm_DoCommand__doc__}, + + {"CompileAndSave", + (PyCFunction) OSAm_CompileAndSave, + METH_VARARGS, + OSAm_DoCommand__doc__}, + + {"RunCompiledScript", + (PyCFunction) OSAm_RunCompiledScript, + METH_VARARGS, + OSAm_DoCommand__doc__}, + + {NULL, (PyCFunction) NULL, 0, NULL} +}; + + + +static char OSAm_module_documentation[] = ""; + + +/* + * PYTHON Module Initalization + */ +void +initOSAm () +{ + PyObject *m, *d; + + /* Create the module and add the functions */ + m = Py_InitModule4 ("OSAm", + OSAm_methods, + OSAm_module_documentation, + (PyObject *) NULL, PYTHON_API_VERSION); + + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict (m); + ErrorObject = PyString_FromString ("OSAm.error"); + PyDict_SetItemString (d, "error", ErrorObject); + + + /* Check for errors */ + if (PyErr_Occurred ()) + Py_FatalError ("can't initialize module OSAm"); +} diff --git a/Mac/Contrib/osam/OSAm.exp b/Mac/Contrib/osam/OSAm.exp new file mode 100644 index 0000000..d567a95 --- /dev/null +++ b/Mac/Contrib/osam/OSAm.exp @@ -0,0 +1 @@ +initOSAm diff --git a/Mac/Contrib/osam/OSAm.h b/Mac/Contrib/osam/OSAm.h new file mode 100644 index 0000000..2fd0469 --- /dev/null +++ b/Mac/Contrib/osam/OSAm.h @@ -0,0 +1,30 @@ +/* + * + * This is a simple module to allow the + * user to compile and execute an applescript + * which is passed in as a text item. + * + * Sean Hummel <seanh@prognet.com> + * 1/20/98 + * RealNetworks + * + * Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com> + * + * + */ + +#pragma once + + +/* Python API */ +#include "Python.h" +#include "macglue.h" + + +/* Macintosh API */ +#include <Types.h> +#include <AppleEvents.h> +#include <Processes.h> +#include <Files.h> +#include <Gestalt.h> +#include <Events.h> diff --git a/Mac/Contrib/osam/OSAm.prj.hqx b/Mac/Contrib/osam/OSAm.prj.hqx new file mode 100644 index 0000000..a744952 --- /dev/null +++ b/Mac/Contrib/osam/OSAm.prj.hqx @@ -0,0 +1,358 @@ +(This file must be converted with BinHex 4.0) + +:#%p63@dZF(*U!%e08(*$9dP&!3!!!-f(!*!%llTMEfpX!!!!!`!!!5J!!--A!!$ +%2`!!#8J!!!"M!3)"!*!*3fpNC9GKFR*TEh)J8(*[DQ9MG!#3lJ3!N!N'!3$rr`# +3#2rr!C!&!*!%(J%"!*!)QCN!!$rr2rmrr`%!!!%!#3CYEfjKBfm!N"`%!#J!#J( +#!S!!+!!+!F)#J!#3%!%!!!%!V!&A!4N#HJ$J!!#XC3!!IV-!!!#4!!!!S!!!$1S +!!"!!N!54!'*KFf9XD@jP3DmM*@3!)MSJEA8"!!!'!3!!"`%!!!J"!!!*!3!!#J% +!!!X"!!!$!!!!"`!!!#3"!!!!!3!!#`)!!!-#!!!'!J!!"`)!!!J#!!!*!J!!#J) +!!!X!!!!(!!!!*!)!!!!#!!!,!!!!33!!!'!!!!0T!!!%!*!%33"K!*!%!@%!N!3 +"B3#3"!&K!*!(!3!!!!)!!!!$!!!!"!!!!!8!!!!'!*"d!3!!!`!!!!8!!!!N!3! +!!!%!!!P#Tb!%!!%"!!!"!3!"!!!"!3%!N!S%!*!*"J%!rrm!N!Mrr`'3"3#3""i +"!3#3#*QC!!!rrcrr2rm"!!!"!!N'E@pZB@0[!*!F"!!S!!S"`J+!!#J!#J(#!S! +!N"!"!!!"!&J!VJ$&!KS"0`!!V'8!!"fdH(JZ3dC00MK,1P"bEfTPBh3J6@PcB`" +iH#j$4Ndf1%Xk4@4TG'pb!(Ki,N0'66Bi5cT'Efjd!(Ki,N0'66Bi5cT3FQpUC@0 +d)%9iG(*KF`"iH#j$4Ndf1%Xk3h9cG'pY)%YPHAG[FQ4c!(Ki,N0'66Bi5cT"Bf0 +PFh-J8'&dD(-!H(JZ3dC00MK,1N*eD@aN)%9iG(*KF`"iH#j$4Ndf1%Xk0MK,)%0 +[C'9(C@i!H(JZ3dC00MK,1MBi5b"%DA0KFh0PE@*XCA)!H(JZ3dC00MK,1MBi5b" +-D@jVCA)!H(JZ3dC00MK,1MBi5b"3FQpUC@0d!(Ki,N0'66Bi5cT$,d-V+b"$Efe +`D@aPFJ"iH#j$4Ndf1%Xk3bp$+bXJ9f&bEQPZCh-!H(JZ3dC00MK,1N0'66Bi5`" +iH#j$4Ndf1%Xk8'&cBf&X)%0[EA"TE'9b!(Ki,N0'66Bi5cT3BA0MB@`J9f&bEQP +ZCh-!H(JZ3dC00MK,1P"33b"$Ef4P4f9Z!(Ki,N0'66Bi5cT38%-J4'PcBA0cC@e +LE'9b!(Ki,N0'66Bi5cT38%-J6'PZDf9b!(Ki,N0'66Bi5cT38%-J8%9'!(Ki,N0 +'66Bi5cT38%-J8(*[DQ9MG!"iH#j$4Ndf1%Xk8&"$3A0Y)&"KEQ9X!(Ki,N0'66B +i5cT5CASJ3fpYF'PXCA)!H(JZ3dC00MK,1P4KFQGPG#"6CA4dD@jRF`"iH#j$4Nd +f1%Xk4QPXC5"0BA"`D@jRF`"iH#j`F'-k8(*[DQ9MG#"0DA0M!(Ki,R"`BcT&C'P +dEh)!H(JZF("M1NC[ER3!H(JZF("M1P"bEfTPBh3J4AKdFQ&c!(Ki,R"`BcT$GA0 +dEfdJ5f9jGfpbC(-!H(JZF("M1N&MBf9cFb"3BA4SF`"iH#j`F'-k3R9TE'3J4AK +dFQ&c!(Ki,R"`BcSf1%XJ3fpNC8GPEJ"iH#j`F'-k0MK,)%4TFf&cFf9YBQaPFJ" +iH#j`F'-k0MK,)%aTEQYPFJ"iH#j`F'-k0MK,)&"bEfTPBh3!H(JZF("M1N-[3bX +V)%0[EA"TE'9b!(Ki,R"`BcT$,d-V+b"ABA*ZD@jRF`"iH#j`F'-k3dC00MK,!(K +i,R"`BcT3BA0MB@`J3fpYF'PXCA)!H(JZF("M1P"KFf0KE#"ABA*ZD@jRF`"iH#j +`F'-k8&"$)%0[C'9(C@i!H(JZF("M1P"33b"%DA0KFh0PE@*XCA)!H(JZF("M1P" +33b"-D@jVCA)!H(JZF("M1P"33b"348B!H(JZF("M1P"33b"3FQpUC@0d!(Ki,R" +`BcT38%0"FfdJ8'&ZC@`!H(JZF("M1P*PHL"$Efe`D@aPFJ"iH#j`F'-k9'&bCf9 +d)&0PG(4TEQGc!(Ki,R"`BcT'D@aP)%eKF("TEQGc!&"bEfTPBh3J4QPXC5"-DA0 +d!(Ki,N0'66Bi5cT*8L"2F(4TE@PkCA)!H(JZ3dC00MK,1NeKBdp6)%ePFQGP)&" +KEQ9X!(Ki,R"`BcT*8L"2F(4TE@PkCA)!H(JZF("M1NeKBdp6)%ePFQGP)&"KEQ9 +X!(Ki,N0'66Bi5cT%C@*eCfGPFL"8BA*RCA3!H(JZ3dC00MK,1NC88#"3B@jPE!" +iH#j$4Ndf1%Xk5Q&fB5"-B@jRG@&RC3"iH#j$4Ndf1%Xk5Q&fB5"2GA4`GA3!H(J +Z3dC00MK,1NTKGQ%J8(*[DQ9MG!"iH#j$4Ndf1%Xk5Q&fB84[Bb"3FQpUC@0d!(K +i,N0'66Bi5cTAD@j53b"$Efe`D@aPFJ"iH#j$4Ndf1%XkH$Jf)%0[C'9(C@i!H(J +Z3dC00MK,1RJi0L"&H'0PF(4TEfjc)&"KEQ9X!(Ki,N0'66Bi5cTi1$BJ6'PZDf9 +b!(Ki,N0'66Bi5cTi1$BJ8(*[DQ9MG!"iH#j`F'-k4'9LG@GRCA)J9'&bCf9d!(K +i,R"`BcT'9&!J8'&ZC@`!H(JZF("M1NTKGQ%J6'&ZCh9KCf8!H(JZF("M1NTKGQ% +J6h9dF(9d!(Ki,R"`BcT+BACK)&"bEfTPBh3!H(JZF("M1NTKGQ&%Ef-J8(*[DQ9 +MG!"iH#j`F'-k9fPZ8N-J3fpYF'PXCA)!H(JZF("M1RJi0L"$Ef4P4f9Z!(Ki,R" +`BcTi1$BJ4AKMCA"dD@pZFb"3B@jPE!"iH#j`F'-kH$Jf)%aTEQYPFJ"iH#j`F'- +kH$Jf)&"bEfTPBh3!6e0"E5j$4Ndf1%Xk3h9cG'pY)%YPHAG[FQ4c!%p63@dZ3dC +00MK,1N&MBf9cFb"3BA4SF`"28d&Y,N0'66Bi5cT8BA*RCA3J8f9dG'PZCh-!6e0 +"E5j$4Ndf1%Xk4QPXC5"0BA"`D@jRF`"28d&Y,N0'66Bi5cT#G@PXC#"&H(4bBA- +!6e0"E5j$4Ndf1%Xk4'9LG@GRCA)J9'&bCf9d!%p63@dZ3dC00MK,1MBi5b"$Ef4 +P4f9Z!%p63@dZ3dC00MK,1MBi5b"%DA0KFh0PE@*XCA)!6e0"E5j$4Ndf1%Xk0MK +,)%aTEQYPFJ"28d&Y,N0'66Bi5cSf1%XJ8(*[DQ9MG!"28d&Y,N0'66Bi5cT$,d- +V+b"$Efe`D@aPFJ"28d&Y,N0'66Bi5cT$,d-V+b"ABA*ZD@jRF`"28d&Y,N0'66B +i5cT$4Ndf1%X!6e0"E5j$4Ndf1%Xk4P43)&"KEQ9X!%p63@dZ3dC00MK,1NP5)%p +`G'PYDATPFJ"28d&Y,N0'66Bi5cT+BACK)%aKEQGeB@GP!%p63@dZ3dC00MK,1NT +KGQ%J6h9dF(9d!%p63@dZ3dC00MK,1NTKGQ%J8(*[DQ9MG!"28d&Y,N0'66Bi5cT ++BACK4'pM)&"bEfTPBh3!6e0"E5j$4Ndf1%Xk6@&M6e-J6@9bCf8J8'&ZC@`!6e0 +"E5j$4Ndf1%Xk8'&cBf&X)%0[EA"TE'9b!%p63@dZ3dC00MK,1P"KFf0KE#"ABA* +ZD@jRF`"28d&Y,N0'66Bi5cT38%-J3fpNC8GPEJ"28d&Y,N0'66Bi5cT38%-J4'P +cBA0cC@eLE'9b!%p63@dZ3dC00MK,1P"33b"-D@jVCA)!6e0"E5j$4Ndf1%Xk8&" +$)&"&4J"28d&Y,N0'66Bi5cT38%-J8(*[DQ9MG!"28d&Y,N0'66Bi5cT38%0"Ffd +J8'&ZC@`!6e0"E5j$4Ndf1%Xk8Q9k)%0[EA"TE'9b!%p63@dZ3dC00MK,1PGTEP* +$)%0[EA"TE'9b!%p63@dZ3dC00MK,1RJi0L"$Ef4P4f9Z!%p63@dZ3dC00MK,1RJ +i0L"&H'0PF(4TEfjc)&"KEQ9X!%p63@dZ3dC00MK,1RJi0L"-D@jVCA)!6e0"E5j +$4Ndf1%XkH$Jf)&"bEfTPBh3!6e0"E5j`F'-k3h9cG'pY)%YPHAG[FQ4c!%p63@d +ZF("M1N&MBf9cFb"3BA4SF`"28d&Y,R"`BcT8BA*RCA3J8f9dG'PZCh-!6e0"E5j +`F'-k4QPXC5"0BA"`D@jRF`"28d&Y,R"`BcT#G@PXC#"&H(4bBA-!6e0"E5j`F'- +k4'9LG@GRCA)J9'&bCf9d!%p63@dZF("M1MBi5b"$Ef4P4f9Z!%p63@dZF("M1MB +i5b"%DA0KFh0PE@*XCA)!6e0"E5j`F'-k0MK,)%aTEQYPFJ"28d&Y,R"`BcSf1%X +J8(*[DQ9MG!"28d&Y,R"`BcT$,d-V+b"$Efe`D@aPFJ"28d&Y,R"`BcT$,d-V+b" +ABA*ZD@jRF`"28d&Y,R"`BcT$4Ndf1%X!6e0"E5j`F'-k4P43)&"KEQ9X!%p63@d +ZF("M1NP5)%p`G'PYDATPFJ"28d&Y,R"`BcT+BACK)%aKEQGeB@GP!%p63@dZF(" +M1NTKGQ%J6h9dF(9d!%p63@dZF("M1NTKGQ%J8(*[DQ9MG!"28d&Y,R"`BcT+BAC +K4'pM)&"bEfTPBh3!6e0"E5j`F'-k6@&M6e-J6@9bCf8J8'&ZC@`!6e0"E5j`F'- +k8'&cBf&X)%0[EA"TE'9b!%p63@dZF("M1P"KFf0KE#"ABA*ZD@jRF`"28d&Y,R" +`BcT38%-J3fpNC8GPEJ"28d&Y,R"`BcT38%-J4'PcBA0cC@eLE'9b!%p63@dZF(" +M1P"33b"-D@jVCA)!6e0"E5j`F'-k8&"$)&"&4J"28d&Y,R"`BcT38%-J8(*[DQ9 +MG!"28d&Y,R"`BcT38%0"FfdJ8'&ZC@`!6e0"E5j`F'-k8Q9k)%0[EA"TE'9b!%p +63@dZF("M1PGTEP*$)%0[EA"TE'9b!%p63@dZF("M1RJi0L"$Ef4P4f9Z!%p63@d +ZF("M1RJi0L"&H'0PF(4TEfjc)&"KEQ9X!%p63@dZF("M1RJi0L"-D@jVCA)!6e0 +"E5j`F'-kH$Jf)&"bEfTPBh3!N2m!N2m!N2m!N#%"!*!(&`!!!!)!N!FS!!!!!`# +3"cF!!!!%!*!(8!!!!!8!N!GU!!!!"J#3"i%!!!!(!*!(Q!!!!!J!N!HZ!!!!#3# +3"mN!!!!+!*!(hJ!!!!X!N!Id!!!!$!#3"J%0!!!!$3#3"J%Q!!!!$J#3"J%h!!! +!$`#3"J&4!!!!%!#3"J&V!!!!%3#3"J'"!!!!%J#3"J'F!!!!%`#3"J'a!!!!&!# +3"J($!!!!&3#3"J(C!!!!&J#3"J(`!!!!&`#3"J)(!!!!'!#3"J)K!!!!'3#3"J) +j!!!!'J#3"J*0!!!!'`#3"J*E!!!!(!#3"J*R!!!!(3#3"J*p!!!!(J#3"J+8!!! +!(`#3"J+S!!!!)!#3"J+m!!!!)3#3"J,2!!!!)J#3"J,R!!!!)`#3"J,j!!!!*!# +3"J--!!!!*3#3"J-L!!!!*J#3"J-i!!!!*`#3"J0'!!!!+!#3"J0G!!!!+3#3"J0 +d!!!!+J#3"J1(!!!!+`#3"J1I!!!!,!#3"J1a!!!!,3#3"J2!!!!!,J#3"J26!!! +!,`#3"J2R!!!!-!#3"J2l!!!!-3#3"J35!!!!-J#3"J3R!!!!-`#3"J3j!!!!0!# +3"J43!!!!03#3"J4X!!!!0J#3"J5!!!!!0`#3"J5C!!!!1!#3"J5c!!!!13#3"J6 +(!!!!1J#3"J6I!!!!1`#3"J6e!!!!2!#3"J8-!!!!23#3"J8Q!!!!2J#3"J8r!!! +!2`#3"J99!!!!3!#3"J9d!!!!33#3"J@*!!!!3J#3"J@I!!!!3`#3"J@f!!!!4!# +3"JA(!!!!43#3"JAF!!!!4J#3"JA[!!!!4`#3"JB$!!!!5!#3"JBD!!!!53#3"JB +`!!!!5J#3"JC$!!!!5`#3"JCI!!!!6!#3"JCa!!!!63#3"JD%!!!!6J#3"JDJ!!! +!6`#3"JDj!!!!8!#3"JE9!!!!83#3"JE[!!!!8J#3"JF)!!!!8`#3"JFN!!!!9!# +3"JFm!!!!93#3"JGC!!!!9J#3"JG`!!!!9`#3"JH)!!!!@!#3"JHM!!!!@3#3"JH +q!!!!@J#3"JI4!!!!@`#3"JIR!!!!A!#3"JJ!N!4G!*!'#"S!!!"H!*!'#$)!!!" +I!*!'#%X!!!"J!*!'#'F!!!"K!*!'#)8!!!"L!*!'#+%!!!"M!*!'#,d!!!"N!*! +'#08!!!"P!*!'#2)!!!"Q!*!'#3N!!!"R!*!'#4d!!!"S!*!'#68!!!"T!*!'#8i +!!!"U!*!'#@F!!!"V!*!'#B)!!!"X!*!'#CS!!!"Y!*!'#EX!!!"Z!*!'#G)!!!" +[!*!'#HS!!!"`!*!'#J-!!!"a!*!'#KN!!!"b!*!'#M)!!!"c!*!'#NN!!!"d!*! +'#Pm!!!"e!*!'#RJ!!!"f!*!'#Sd!!!"h!*!'#UF!!!"i!*!'#VX!!!"j!*!'#Y! +!!!"k!*!'#ZJ!!!"l!*!'#`#3"(`!N!B,%!!!!(d!N!B,)`!!!(i!N!B,13!!!(m +!N!B,8!!!!)!!N!B,C3!!!)%!N!B,H`!!!))!N!B,P!!!!)-!N!B,V`!!!)3!N!B +,b!!!!)8!N!B,i3!!!)B!N!B,pJ!!!)F!N!B-%!!!!)J!N!B-*!!!!)N!N!B-03! +!!)S!N!B-5J!!!)X!N!B-B!!!!)`!N!B-GJ!!!)d!N!B-MJ!!!)i!N!B-S`!!!)m +!N!B-`3!!!*!!!*!'$08!!!#4!*#l8`!!!&3!!!"9!!!!9J!!!%i!!!"4!!!!9`! +!!&J!!!"C!!!!63!!!&)!!!"3!!!!@J!!!&X!!!"F!!!!A3!!!&i!!!"I!!!!B!! +!!'%!!!"L!!!!B`!!!'3!!!"P!!!!CJ!!!'F!!!"S!!!!D3!!!%m!!!"U!!!!D`! +!!'`!!!"Y!!!!EJ!!!(8!!!"f!!!!G`!!!(J!!!"`!!!!F`!!!(N!!!"k!!!!H`! +!!'m!!!"d!!!!FJ!!!(`!!!"p!!!!IJ!!!(m!!!#!!!!!J3!!!))!!!#$!!!!K!! +!!)8!!!#'!!!!K`!!!)J!!!#*!!!!LJ!!!)X!!!"a!!!!M!!!!)d!!!#1!!!!M`! +!!*!!!!!!-J!!!!F!!!!)!!!!#3!!!!S!!!!&!!!!"J!!!!X!!!!-!!!!$3!!!!3 +!!!!h!!!!!3!!!"J!!!!#!!!!1!!!!$-!!!!j!!!!1J!!!$X!!!!m!!!!0!!!!!i +!!!!2!!!!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!!`#3"aB!!!!A!!!!23!!!$i +!!!!r!!!!3!!!!%%!!!!J!!!!)3!!!#)!!!!M!!!!(J!!!"m!!!!N!!!!*3!!!#B +!!!!G!!!!3J!!!"S!!!!a!!!!'`!!!%-!!!!e!!!!4!!!!%8!!!"'!!!!4`!!!$B +!!!!R!!!!+!!!!#N!!!!U!!!!+`!!!#`!!!!Y!!!!,J!!!"`!!!!C!!!!,`!!!$! +!!!")!!!!53!!!%S!!!",!!!!6!#323%!!!!#8Np29!#3$!*(8P93!*!(!3G6Eh9 +bBf9c!!!!!dC*6%8#!!!(4NP-43)!!!K'58a&!J!!#8G599!!N!F##8aTBR*KFQP +PF`!!!!9'58a&!J!!!dC*6%8"!!!$4NP-43)!!!C'58a&!J!!#dC*6%8#!!!+!!" +!"V%#8!#3$!&*%A!!N#-r!!!!3!!!!dd!!!3!N!3r!#"LBA0PE'PZC5`JBQmJG+K +[E5`!"J%!N!F"!*!*!3#3"LF!!!!S!!!!+3!!!#S!!!!F!!!!13!!!$i!!!!H!!! +!#`!!!"-!!!!G!!!!)J!!!%!!!!!1!!!!*3!!!#X!!!!X!!!!,3!!!#%!!!!Q!!! +!*!!!!$m!!!!Z!!!!$!!!!"3!!!!#!!!!(`!!!#!!!!!0!!!!#3!!!!8!!!!2!!! +!&3!!!"!!!!!@!!!!%3!!!$S!!!!i!!!!1`!!!$d!!!![!!!!-!!!!")!!!!C!!! +!-J!!!$-!!!!d!!!!03!!!$B!!!!A!!!!0`!!!"X!!!!'!!!!#J!!!$%!!!!m!!! +!!3!!!#-!!!!B!*!("!!!!!F!!!!)!!!!'J!!!!-!N)-"!!!!!J!!!!-!!!!%!!! +!"3!!!!B!N(B#1`!!!#S!N!B#4J!!!#X!N!B#8J!!!#`!N!B#B3!!!#d!N!B#F!! +!!#i!N!B#G`!!!#m!N!B#K!!!!$!!N!B#P!!!!$%!N!B#T!!!!$)!N!B#X3!!!$- +!N!B#[3!!!$3!N!B#cJ!!!$8!N!B#f3!!!$B!N!B#i3!!!$F!N!B#l3!!!$J!N!B +#qJ!!!$N!N!B$"J!!!$S!N!B$&`!!!$X!N!B$(J!!!$`!N!B$*`!!!$d!N!B$0J! +!!$i!N!B$2`!!!$m!N"%$!!#CQ3#3"(rr!*!%Irm!N!4rr`!!!!%"!!!"!3!"!!F +ZP5!!N!X"!!!!!J!!!!-!!!!%!!!!"3!!!!B!N(8(!3!"!3!"!3!!!!%!!!`!N!F +@EAGPFQYcAh"XG@GTEPpMEfjQD@FZD!#3#`%"!!%!N!i"!3%!!!%"!!%!!3%"!!! +"!3!"!!3!N!d"!3%!N"%"!!!!!J!!!!-!!!!%!!!!"3!!!!B!N(6r!*!(!`!!QCN +!N!4rr`#3"(rr!*!%Irm!!!!'!3%!!3%!!!!"!3%!!!!"!!!!!3#3"!F"!!%"!!% +"!!!!!3!!$!#3"aCYGf9bDh0IF'aeCfPZAf0[EQCTCbjS!*!,!3#3%3-!!!p+BAC +K3faKFh0PFbjUBA)!N""D59!J69GD8!#3"3%!$J#3"`%!N!3+99"*,R"bC@CTH!# +3&J%!N!8"!!%!N!m#!!%!(!#3'33!N!d$!!!25Q&fB80XBA0cCA-ZDQ&b!*!3@NP +3)%eA@P!!N!8"!!i!N!F"!*!%#P9355j`FQ9QDAJ!N"B"!*!&!3!"!!!!!`!!!!S +!!!!$!!!!#,&Q2'crrjJ%!*$r!*$r!*!A!J#3$!-#!3%"!!!"!3-"!*!*"3%!!!- +!!3#3$JJ!!!!#!!)!!!!&"!!!!`!"!!%k!*$r!*$r!!%!!!$rN!3!!!!#!!%!!6U +3"!#3r`#3r3%!!!$rN!3!!!!%!!)!!6T0CA4bEhGPFQYc)&0dB@jNBA*N)%aTBR* +KFRNk690-)%-k!*$r!*$H!3!!!2q3"%!!!!%!!J!"1NeKBdp6)&0eF("[FR3k!*$ +r!*$b!3!!!2q3"%!!!!)!"3%!!!%!N2m!!!!"!!!*6@9bCf8J6h9d!*!f2j!%39" +36!!"!3!!"%4-4eKMDfPN8(*[DPG68%-!!J#3$!-#!!%"!!!"!3-"!*!*!J!!!!) +!!J#3*`)!N#%&!3!!!`!"!*!)H(JZ3dC00MK,!&0[GA*MCA-!6'PLFQ&bD@9c!(K +iE@pNG@aP,Q-!H(JZ3dC00MK,,V8ZCAK`!%e66#"6D%aTBP*eER4TE@9$4Ndf1%X +Z6'PL!&"jG'K[EN0[FQ9$4Ndf1%X!H(JZF("M!(Ki,R"`Bbke,Q9iF!"08d`J8fK +-D@*5G@jdD@eP,NaTBJ"3HA4SEfj$Eh*P8&"$!$TiH#j$4Ndf1%XZFfaL!%aTBL" +*EA"[FR3J0MK,!%e39b"*EA"[FR3J0MK,!%*KE'a[EfiJ5'9XF!"09b"$,d-V+b! +f1%X!69FJ8'&cBf&X)$Bi5`"09b"5CAS!8%9')%PYF'pbG#!f1'X!1RKi,R"`Bbj +cE')!6'PL)%PYF'pbG#"38%-!69FJ3bp$+bXJ8&"$!%eA)&"KFf0KE#"38%-!8&" +$3A0Y!&K$6dC')%PYF'pbG#"38%-!8%9')%PYF'pbG#"38%-!H(JZF(*U,Q9iF!" +3HA4SEfj$Eh*P!$T0Ef4eE'9c1RKiE@pNG@aP,Q-!1RKi,R"bDLjPH(!!1P"jG'K +[EN0[FQ8!6@&M6e-J0MK,)%aTEQYPFJ"0B@028b"38%-J6'PZDf9b!%0eFh4[E5" +,CAPhEh*NF`""Bf0PFh-J8'&dD(-!9'&bCf9d)&0PG(4TEQGc!%CTE'8J6@&`F'P +ZCh-!3R9TE'3J4AKdFQ&c!%4PBR9RCf9b)&4KFQGPG!!f1%XJ3fpNC8GPEJ!f1%X +J4'PcBA0cC@eLE'9b!$Bi5b"-D@jVCA)!0MK,)&"bEfTPBh3!3bp$+bXJ3fpYF'P +XCA)!3bp$+bXJ9f&bEQPZCh-!3dC00MK,!%P5)%p`G'PYDATPFJ"3BA0MB@`J3fp +YF'PXCA)!8'&cBf&X)&GKFQjTEQGc!&*PHL"$Efe`D@aPFJ"38%-J3fpNC8GPEJ" +38%-J4'PcBA0cC@eLE'9b!&"33b"-D@jVCA)!8&"$)&"&4J"38%-J8(*[DQ9MG!" +38%0"FfdJ8'&ZC@`!6e0"E5j$4Ndf1%X!1Np63@dZ3dC00MK,,R0XBJ"28d&Y,Q- +!6e0"E5jPH(!!8f0bDA"d8R9ZEQ9b,Q-!6e0"E5j`F'-!1Np63@dZF("M,R0XBJ" +*ER4PFQCKBf9-D@)!3A"`E'96Bh*TF(4-D@)!N*X#!!!!13%!!!)!N!N%!!%!!!! +kX@Bm2[rrk')!N2m!N2`q!J!!!J#3#33!!3!!!$qaCM`rrrqE$`#3r`#3qJJ!!!! +#!!)!!!!&"!!!"!!"!!%k!*$r!*$r!!%!!!$rN!3!!!!#!!%!!6U3"!#3r`#3r3% +!!!$rN!3!!!!%!!)!!6T0CA4bEhGPFQYc)&0dB@jNBA*N)%aTBR*KFRNk690-)%- +k!*$r!*$H!3!!!2q3"%!!!!)!!J!"1NeKBdp6)&0eF("[FR3k!*$r!*$b!3!!!2q +3"%!!!!-!"3%!!!%!N2m!!!!*!!!!B5j[GA3!N$SrN!4"8&"-!!!"J&L!!*"#2j! +%!*!*93'3!!%*!RX!N!i"J!#36`%!!!P0CA*RC5"2GA3!N$BrN!4"8&"-!!%"!!! +%4%a(@'0VD@43FQpU9e033`!#!!!!!J!#!*!R!J#3)3%!N$3"!*!BC'9QD@jPC#" +[FL"TFb!!!3%"!*!*!3%"!*!*!J!!#Nj26N&045j&@%8!N"C!!*!%"!#3"!3!!!3 +!N!3%!&8"N!!"#3*l!*!,!J!!#Nj26N&045j&@%8!N"C!!*!%"!#3"!3!!!3!N!3 +%!&8"N!!"#3*l!*!@2j!%39"36!!"!3!!"%4-4eKMDfPN8(*[DPG68%-!"3%!!!- +!!3#3#%8"!!!'!!!!!J!"!"`!N"X$!!)!+!#3(`%!N!F+!!!!!J#3"a)!!!!$!*! +((!!!!!3!N!FR!!!!"3#3"cF!!!!'!*!(8J!!!!F!N!GM!!!!#!#3"fS!!!!*!*! +(G`!!!!S!N!H-!!!!#`#3"jS!!!!-!*!(U3!!!!d!N!Hi!!!!$J#3"mF!!!!2!*! +(e!!!!"!!N!IK!!!!%3#3"qm!!!!5!*!(pJ!!!"-!N!B""3!!!"3!N!B"%3!!!"8 +!N!B")!!!!"B!N!B",3!!!"F!N!B"1`!!!"J!N!B"3J!!!"N!N!B"8`!!!"S!N!B +"BJ!!!"X!N!B"E3!!!"`!N!B"H!!!!"d!N!B"M!!!!"i!N!B"Q!!!!"m!N!B"T!! +!!#!!N!B"Y3!!!#%!N!B"aJ!!!#)!N!B"eJ!!!#-!N!B"i`!!!#3!N!B"m`!!!#8 +!N!B#!3!!!#B!N!B#$J!!!#F!N!B#(J!!!#J!N!B#+J!!!#N!N!B#1`!!!#S!N!B +#4J!!!#X!N!B#8J!!!#`!N!B#B3!!!#d!N!B#F!!!!#i!N!B#G`!!!#m!N!B#K!! +!!$!!N!B#P!!!!$%!N!B#T!!!!$)!N!B#X3!!!$-!N!B#[3!!!$3!N!B#cJ!!!$8 +!N!B#f3!!!$B!N!B#i3!!!$F!N!B#l3!!!$J!N!B#qJ!!!$N!N!B$"J!!!$S!N!B +$&`!!!$X!N!B$(J!!!$`!N!B$*`!!!$d!N!B$0J!!!$i!N!B$2`!!!$m!N!B$63! +!!%!!N!B$@J!!!%%!N2m!N)N"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#! +"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!C"`!!6@&M6e- +J0MK,)%aTEQYPFJ#3r`#3r`#3mNp63@dZ3dC00MK,!*$f!3!"1J#3r`#3r`#3"J% +!!3#3r`#3r`#3"`N!"!p28d&Y,N0'66Bi5bjcE')!N$"3HA4SFfKXBJ#35$q3"!# +3#98"N!!"#3*l!*!8!3#35J3!!3#3$J%!)!#3r`!!AepTEQPdD@&XDATP!*!eAh0 +dBA*d!*!jAepdCA*YD@jKG'8!N$J"!!%!N2m!N2m!N2m!N#`9!3%!N!8$!*$r!*! +,!3#3"!J!N2m!N2m!N!4%4Na8$dePG(*[Gf9bDh-J5Q&fB3#3-%PZG'9bEQ9d)%9 +iF'a[FQ9b!*$r!*$d4%C-9!#3r`!!"`%"!*!%!3#31fPZDA4iD@jTG(Ki!*"f#!! +"!*!)-XJ!!$,)!!!bb!CcG'4hD@i!N2`(!!"0B@028b"38%-J6'PZDf9b!*$r!*$ +r!*$b6e0"E5j`F'-!N2N"!!%k!*$r!*$r!*!F!J'3"3!"!*!&690*43#3r`#3r`! +!D(4dF$S[,fTKGQ%ZFh9Z,Q0[E5p`FQpNG@0dFbpUC'X[-5ia,f4[Bh-[BA"T,`# +3d`8!!3aiH'e[C(9XC5jcE')!N"03@94)FfKXBJ#3F3%rN!3!N!F#!&!!!3!"!!% +!!3#3r`!8*d024%8R)#G%394"*b!R8%P$9#F!N1`%!!%!N%%#!!3!N%J"!!%!!!- +!!!!'!J%!N!8"!!)$!*!-!30Z!*!'!3!!"J!!!"`#!3#3"3%!!3-!N!`"!*!)!3! +!"`!!!$X#!3#3"3%!!3%!N!`"!*!)!3!!#!!!!$`#!3#3"3%!!3%!N!`"!*!)!3! +!#3!!!$d#!3#3"3%!!3%!N!`"!*!)!3!!#J!!!%!#!3#3"3%!!3-!N!`"!*!)!3! +!#`!!!%%#!3#3"3%!!3-!N!`"!*!3!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj! +%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$ +rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3% +!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#! +"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!# +3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj! +%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N"Mrr`#3)!%"!!$rN!3!N#!"!3!!rj!%!*! +C!3!"!*$r!*$r!*!9!3#3'3)!!!T16dj"688Z49K&!*!@3!#3"!3!N!3%!!!%!*! +%"!"9!C!!!3N#H`#3$3)!!!!J!!!!)3!#!!C0B@028b"38%-J6'PZDf9b!*!4'N& +38%`!N%"J!!!!3A"`E!#33'!!!!"068a#!*!J6'PL)%PYF'pbG#"38%-!N"C08%a +'!*!J6'PL)%PYF'pbG#"38%-!N"C09d0%!*"!B!!!!&*68N-!N%"J!!!!9%9B9#j +LD!"MbUY3!!-`b!!8VG!!!!&q!FUV8!!8CF!!!!,@3Q&XE'p[EL")C@a`!*!'(33 +"bUZ!!"4P`!'(PY3!N!4849K8,Q-!N"j09b"$,d-V+b"38%-!N"K849K8,Q-V+`# +3(%eA)%-[3bXV)&"33`#3'&4&@&3ZBf-!N"e09b"$,d-V+b"38%-!N"K849K8,Q0 +`!*!G69FJ3bp$+bXJ8&"$!*!B9%9B9#jMF(!!N"a09b"$,d-V+b"38%-!N"K849K +8,Q9iF!#33&4&@&3ZD!#3(NeA)%-[3bXV)&"33`#3&"!!!!"849K8,R!!N"j09b" +3BA0MB@`J8&"$!*!A9%9B9#j`BA-!N"a09b"3BA0MB@`J8&"$!*!A9%9B9#j`BfJ +!N"a09b"$,d-V+b"38%-!N"5!!!!!9%9B9#j`BfJV+`#3'NeA)%-[3bXV)&"33`# +3&)!!!!"849K8,R)!N"j09b"5CAS!N"j849K8,R-!D'2+Ue!!!c$)!"5Yd!!!!Ai +"bUY3!"4P`!!!!YC38%0"Ffd!EL")C@`!N!BG"!(+Ui!!&'A!!BH@e!#3"&K$6dB +!N#"B3dp'4L"*EA"[FR3J8&"$!*!8C'pMG3#33'!!!!"bFh*M!*"!B!!!!(0SE') +!N#"348BJ5@e`Eh*d)&"33`#3&R0dG@)!N#"348BJ5@e`Eh*d)&"33`#3'LjNEf- +!N$a3!!!!6@&M6e-J0MK,)%aTEQYPFJ#3%4T"8&"-!*"!B!!!!%&`F'`!N%"J!!! +!68e-3J#3)%aTBL"*EA"[FR3J0MK,!*!@69"-4J#3)%aTBL"*EA"[FR3J0MK,!*! +@69G$4!#33'!!!!"23NSJ!*!J69"A)%PYF'pbG#!f1%X!N"C58e*$!*"!B!!!!&4 +&@&3ZBQJ!BmUV8!!$--J!&+h3!!!"IJ(+Ue!!&'A!!!!#eN*KE'a[EfiJ5'9XF!# +3"Kd%!FUVJ!!8CF!"KjE8!*!%9%9B9#jM!*!H69FJ3bp$+bXJ0MK,!*!B9%9B9#j +M+bX!N"a09b"$,d-V+b!f1%X!N"K849K8,Q0M!*!G69FJ3bp$+bXJ0MK,!*!B9%9 +B9#jMF!#3(8eA)%-[3bXV)$Bi5`#3'&4&@&3ZBh"`!*!F69FJ3bp$+bXJ0MK,!*! +B9%9B9#jPH(!!bUY3!!-`b!!8VG!!!!&q!FUV8!!8CF!!!!,@!-FUG!aiUi!"bUj +%!"199!!!(33"bUZ!!"4P`!'(SM`!N!4849K8,QJ!N"j09b"$,d-V+b!f1%X!N"3 +3!!!!9%9B9#j`!*!H69FJ8'&cBf&X)$Bi5`#3&e4&@&3ZF'&c!*!F69FJ8'&cBf& +X)$Bi5`#3&e4&@&3ZF'0S!*!F69FJ3bp$+bXJ0MK,!*!8J!!!!&4&@&3ZF'0S+bX +!N"T09b"$,d-V+b!f1%X!N"5!!!!!9%9B9#jb!*!H69FJ8Q9k!*!H9%9B9#jcC@F +!bUY3!!-`b!!8VG!!!!&q!FUV8!!8CF!!!!,@!-FUG!aiUi!"bUj%!"199!!!(33 +"bUZ!!"4P`!'(SM`!N!4NEf0e!*"!B!!!!(*cFQ-!N%"J!!!!FfKXBJ#3)&"&4L" +*EA"[FR3J0MKV!*!@Fh4eBJ#3)&"&4L"*EA"[FR3J0MKV!*!D,Q4[B`#32&!!!!" +AD@ic-L"i1$BJ6'PZDf9b!*!4#94&@&3ZB`#3(NeA)%-[3bXV)(Ji0J#3'&4&@&3 +ZBbXV!*!F69FJ3bp$+bXJH$Jf!*!B9%9B9#jMF!#3(8eA)%-[3bXV)(Ji0J#3'&4 +&@&3ZBh"`!*!F69FJ3bp$+bXJH$Jf!*!B9%9B9#j`BfJ!N"a09b"$,d-V+b"i1$B +!N"5!!!!!9%9B9#j`BfJV+`#3'NeA)%-[3bXV)(Ji0J#3&)!!!!"849K8,R*M!*! +G69FJ9fPZ8N-!N#!ZE'PL!*!F6'PL)%PYF'pbG#"i1$B!N"SZEf*U!*!F6f*U)%P +YF'pbG#"i1$B!N"C03b"-D@jVCA)!N"J)68e$5!#34&4&@&3ZB`#3(Ne$)%-[3bX +V!*!F9%9B9#jME(-!N"a03b"$E'&cFb"$Efe`D@aPFJ#3$i!!!!"849K8,Q4PCJ# +33&4&@&3ZC'pM!*!m%!!!!&4&@&3ZD!#32K!!!!"849K8,R"MD!#3(%e$)%-[3bX +V!*!BJ!!!!&4&@&3ZG(-!N%&1EfjP!*!G!8e08()!N%"!!!!!6@&M6e-J6@9bCf8 +!N"B(39"36!#33'!!!!""F("X!*"!B!!!!&*68N-!N%"J!!!!9%9B9#jLD!#3(8* +KE'a[EfiJ5'9XF!#3'&4&@&3ZFJ#3(P*PHJ#3)A*cFQ-!N%"J!!!!FfKXBJ#3433 +!N"!"!*$r!*"%AepcG'&bG!#3I!%!!3#3r`#3r`#3r`#3,"8"!3#3"3-!N2m!N!X +"!*!%#!#3r`#3r`#3"%4'6&326@9dFQphCA*VFb"+BACK!*!`5@jdCA*ZCA3J4AK +`E'pbCA)!N2m!N24%4Na8!*$r!!!#!C!&!!%!N!908dP&!*$r!*$r!!"SG(4`1Lm +[DQ&fB5jcG@iZBfpY,h"bEf4eBh4c,fTNDbma,M%[C'pMFbpKF'N[!*$6"`%"!*! +%!9pID@jTG'PKE'PkC3#3EepIG'9bAepdCA*YD@jKG'8!N$%)!!%!N!JkMJ!!1Si +!!$U1!*$r!*!%"3!"$%p63@dZF("M,R0XBJ#3%e"jG'KcD'aL!*"a!6q3"!#3"`) +!8!!"!!%!!3!"!*$r!"3R3dp%45FJ*d4"9%%R)#G35808*`#3l!3!!3#333)!"!# +35!%!!J!!!`!!!!S#!3#3"3%!!3-!N!`"!fi!N!B#!!!'!!!!(!)"!*!&!3!"!`# +3$!%!N!J#!!!(!!!!1`)"!*!&!3!"!3#3$!%!N!J#!!!)!!!!2!)"!*!&!3!"!3# +3$!%!N!J#!!!*!!!!23)"!*!&!3!"!3#3$!%!N!J#!!!+!!!!3!)"!*!&!3!"!`# +3$!%!N!J#!!!,!!!!33)"!*!&!3!"!`#3$!%!N"!"!3!!rj!%!*!J!3%!!2q3"!# +3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj! +%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$ +rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3% +!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#! +"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!# +3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3r`#3&d4'6&3!N2m!!!)"N!8 +!!3#3"8e6588!N2m!N2m!!'KdG(!k,bpUBACK,R0eELjMEfd[F(*[C(9MG(-[DQ4 +V,c%Z-5pNEf0c,f&`D5m!N0-%!!%!N%%#!!3!N%J"!*!%&`!!!#)!!`#3"5-!#!# +3"53!"`#3"58!!J#3"5B!"3#3"5F!!3#3"5J!"J#3"5N!!3#3"5S!"`#3"5X!#3# +3"5`!$!#3"5d!"!#3"5i!"!#3"5m!!3#3"6!!$J#3"6%!!J#3"6)!!J#3"6-!!`# +3"63!!3#3"68!"`#3"6B!#!#3"6F!"3#3"6J!!J!!!!)!"NeKBdp6)&"33b"-D@j +VCA)!N"%D39"36!#33'!!!!""F("X!*"!B!!!!%e06%)!N#"-D@)J5@e`Eh*d)&" +33`#3&Ne36%B!N#"-D@)J5@e`Eh*d)&"33`#3&NeA3d3!N%"J!!!!8P053`#33'! +!!!"849K8,Q*S!'2&ET!!!!-`b!!8VH!!!!&j!F9ZN!!!&'A3!!!#eN*KE'a[Efi +J5'9XF!#3"L@a!F9Z`!!8CG!"JPD8!*!%9%9B9#jM!*!H69FJ3bp$+bXJ8&"$!*! +B9%9B9#jM+bX!N"a09b"$,d-V+b"38%-!N"K849K8,Q0M!*!G69FJ3bp$+bXJ8&" +$!*!B9%9B9#jMF!#3(8eA)%-[3bXV)&"33`#3'&4&@&3ZBh"`!*!F69FJ3bp$+bX +J8&"$!*!B9%9B9#jPH(!!a@k3!!!$--J!&+hJ!!!"H3(&ET!!!"4Pd!!!!YB!8Q9 +kYLKZ`!(&FB3!N!BPX3(&EX!!&'A3!B*Kr!#3"&4&@&3ZD!#3(NeA)%-[3bXV)&" +33`#3&"!!!!"849K8,R!!N"j09b"3BA0MB@`J8&"$!*!A9%9B9#j`BA-!N"a09b" +3BA0MB@`J8&"$!*!A9%9B9#j`BfJ!N"a09b"$,d-V+b"38%-!N"5!!!!!9%9B9#j +`BfJV+`#3'NeA)%-[3bXV)&"33`#3&)!!!!"849K8,R)!N"j09b"5CAS!N"j849K +8,R-!D'2&ET!!!!-`b!!8VH!!!!&j!F9ZN!!!&'A3!!!#eP"33d&cE3"Z)%KPE!# +3"L@a!F9Z`!!8CG!"JPD8!*!%@%024J#3)&K$6dC')%PYF'pbG#"38%-!N"4NEf0 +e!*"!B!!!!(*cFQ-!N%"J!!!!FfKXBJ#3)&"&4L"*EA"[FR3J8&"$!*!@Fh4eBJ# +3)&"&4L"*EA"[FR3J8&"$!*!D,Q4[B`#32&!!!!"0B@028b!f1%XJ6'PZDf9b!*! +4'N&38%`!N%"J!!!!3A"`E!#33'!!!!"068a#!*!J6'PL)%PYF'pbG#!f1%X!N"C +08%a'!*!J6'PL)%PYF'pbG#!f1%X!N"C09d0%!*"!B!!!!%p#5L!!N#"08&FJ5@e +`Eh*d)$Bi5`#3&P*68N-!N%"J!!!!9%9B9#jLD!"MhJ!#&,a!J*S+!80Uj3%j9'm +!!!!"!*!%!80#B@aXEfpZ)%KPE(!!bJ&U!)J"194Z!80Uj!!j!@K-FJ#3"&4&@&3 +ZB`#3(NeA)%-[3bXV)$Bi5`#3'&4&@&3ZBbXV!*!F69FJ3bp$+bXJ0MK,!*!B9%9 +B9#jMB`#3(8eA)%-[3bXV)$Bi5`#3'&4&@&3ZBh!!N"e09b"$,d-V+b!f1%X!N"K +849K8,Q0`F!#3(%eA)%-[3bXV)$Bi5`#3'&4&@&3ZCAK`!,a!J*S+!6PAl`&$Bpm +!N!J"3f2H)!3!1J%k,S!"1&!L!3!!!!&$Bpi"19IZ!Hi!N!B4!*!&9%9B9#jS!*! +H69FJ3bp$+bXJ0MK,!*!8%!!!!&4&@&3ZF!#3(NeA)&"KFf0KE#!f1%X!N"G849K +8,R"KF`#3(%eA)&"KFf0KE#!f1%X!N"G849K8,R"MD!#3(%eA)%-[3bXV)$Bi5`# +3&)!!!!"849K8,R"MD#XV!*!D69FJ3bp$+bXJ0MK,!*!8J!!!!&4&@&3ZFJ#3(Ne +A)&*PHJ#3(P4&@&3ZFf9R!,a!J*S+!6PAl`&$Bpm!N!J"3f2H)!3!1J%k,S!"1&! +L!3!!!!&$Bpi"19IZ!Hi!N!B4!*!&C'pMG3#33'!!!!"bFh*M!*"!B!!!!(0SE') +!N#"348BJ5@e`Eh*d)$BiD`#3&R0dG@)!N#"348BJ5@e`Eh*d)$BiD`#3'LjNEf- +!N$a3!!!!9fPZ-c)JH$Jf)%aTEQYPFJ#3%3P849K8,Q-!N"j09b"$,d-V+b"i1$B +!N"K849K8,Q-V+`#3(%eA)%-[3bXV)(Ji0J#3'&4&@&3ZBh!!N"e09b"$,d-V+b" +i1$B!N"K849K8,Q0`F!#3(%eA)%-[3bXV)(Ji0J#3'&4&@&3ZF'0S!*!F69FJ3bp +$+bXJH$Jf!*!8J!!!!&4&@&3ZF'0S+bX!N"T09b"$,d-V+b"i1$B!N"5!!!!!9%9 +B9#jbB`#3(8eA)>EP*$!*!J,QaTBJ#3(%aTBL"*EA"[FR3JH$Jf!*!D,QpLDJ# +3(%pLDL"*EA"[FR3JH$Jf!*!@68-J6'PZDf9b!*!B#%e03dJ!N%4849K8,Q-!N"j +03b"$,d-V+`#3(&4&@&3ZBfac!*!F68-J3faKFh-J3fpYF'PXCA)!N!q!!!!!9%9 +B9#jNC@B!N%"849K8,Q4[B`#32"!!!!"849K8,QJ!N$i3!!!!9%9B9#j`BfJ!N"a +03b"$,d-V+`#3')!!!!"849K8,R4c!*""6QpZC3#3(3&069"b!*"!3!!!!%eKBdp +6)%ePFQGP!*!@"d&38%`!N%"J!!!!3A"`E!#33'!!!!"58e*$!*"!B!!!!&4&@&3 +ZBQJ!N"e#B@aXEfpZ)%KPE(!!N"K849K8,R)!N"j5CAS!N#&bFh*M!*"!B!!!!(0 +SE')!N%B$[`!!%!"YFh4b!*!1%lm!!!H!EA0dE!#3$KXr!!!#J'ecG'i!N!i"`!! +!!#KYFh4T!*!1-GB!!!3!EA0dFJ!!!qJ!N!T'S3!!")"YFh4X!!!$k!#3#Kkr!!! +"J'ecG'i!!!2S!*!+!bF!!!!+F(*PCJ#Ja-S!!!!"!*!'!c%!!!!`F(*PCJ#J[K3 +!!!!#!*!'!f%!!!"+F(*PCJ#J,r`!!!!$!*!'!kX!!!!8F(*PCJ#JMdd!!!!%!*! +'4Q%!!!"!EA4cE!!!!!%!N!T[(3!!"D"YG("X!!!!!3#3#J(S!!!!('edE'm!!!! +"!*!+!J3!!!!3EA4`D3!!!!%!N!S"+!!!!!T`FQ9Q!+$U+`!!!"S!N!B"-J!!!$" +`FQ9Q!+!%S3!!!"X!N!B"BJ!!!%T`FQ9Q!+!K$!!!!"`!N!B"V!!!!"4`FQ9Q!+$ +k[J!!!"d!N!BNSJ!!!#"YG(0X!!!!!J#3#U(&!!!&S'edF'`!!!!#!*!+!K3!!!! +FEA4XE`!!!!)!N!S#-!!!!""YG("T!!!!!J#3#MA@!!!%0'edCf`!!!2S!*!+*6S +!!!)XEA"cD3!!!qJ!N!SG[`!!!-"36(0d!+!$I!!!!$-!N!B#3!!!!#KYFh4T!!! +$k!#3#J*S!!!!N!"YG("c!!!!!3#3#L!r!!!!N!"YG("c!!!!!J#3#RHK!!!!$'e +KE'`!N!kY#`!!!,aYBA"X!*!1)l!!!!!DF(*PCJ!rkbJ!!!"1!*!'*j`!!!K3F(* +PCJ"!$`-!!!"2!*!'6%%!!!B-F(*PCJ"!#r!!!!"3!*!'VFF!!"CiF(*PCJ"!2@% +!!!"4!*!',q`!!!%(F(*PCJ"!0B!!!!"5!*!'8Nd!!!))F(*PCJ!rk"i!!!"6!*! +')mS!!!!BF(*PCJ!rMGB!!!"8!*!'!a!!!!!+F(*PCJ!r@[m!!!"9!*!')q)!!!! +1F(*PCJ!rQAX!!!"@!*!'9&8!!!%'F(*PCJ!rJFX!!!"A!*!')r!!!!!mF(*PCJ! +r8%J!!!"B!*!'*-)!!!!1F(*PCJ!rcC)!!!"C!*!'99X!!!(DF(*PCJ!r9+8!!!" +D!*!'9c8!!!-bF(*PCJ!rA'`!!!"E!*!'!aS!!!!-F(*PCJ!rm0N!!!"F!*!'@QF +!!!%3F(*PCJ!rK!J!!!"G!*!'*0!!!!!bF(*PCJ"!3BS!!!"H!*!'@hF!!!93F(* +PCJ"!'Zi!!!"I!*!'D-8!!!-5F(*PCJ"!,N`!!!"J!*!'-2-!!!"LF(*PCJ!rZ@S +!!!"K!*!'*3)!!!!iF(*PCJ"!(Z)!!!"L!*!'-98!!!!0F(*PCJ!rY68!!!"M!*! +'-@)!!!!8F(*PCJ!rrHB!!!"N!*!')[-!!!!+F(*PCJ"!*4X!!!"P!*!'B-F!!!$ +%F(*PCJ"!6f!!!!"Q!*!'BBX!!!%BF(*PCJ!r8CN!!!"R!*!'DpF!!!#SF(*PCJ" +!5ZS!!!"S!*!'-AB!!!!ZF(*PCJ!rCL!!!!"T!*!'E(m!!!)-F(*PCJ!rdYd!!!" +U!*!'-D3!!!!LF(*PCJ!rffm!!!"V!*!'-FB!!!!3F(*PCJ!rIMJ!!!"X!*!'48i +!!!!DF(*PCJ!re$F!!!"Y!*!'ESX!!!#5F(*PCJ!rT`#3"'i!N!C&MJ!!!%T`FQ9 +Q!%!PP!!!!'m!N!BKi`!!!"T`FQ9Q!$q4R`!!!(!!N!Bk#J!!#&"`FQ9Q!%!PI`! +!!(%!N!CLS`!!"Ja`FQ9Q!$p[*`!!!()!N!ChV3!!&RK`FQ9Q!%!NAJ!!!(-!N!C +#@J!!!3G`FQ9Q!$ppZJ!!!(3!N!Ce*`!!!JK`FQ9Q!%!$%!!!!(8!N!BHT`!!!"K +`FQ9Q!$qq5`!!!(B!N!BKr3!!!!T`FQ9Q!%!9T3!!!(F!N!BLR`!!!!j`FQ9Q!$r +CV3!!!(J!N!C$B3!!!3C`FQ9Q!$r8CJ!!!(N!N!BLV3!!!$a`FQ9Q!%!MP!!!!(S +!N!BLr3!!!!j`FQ9Q!$qhFJ!!!(X!N!D1*3!!!GT`FQ9Q!$pd93!!!(`!N!D2r`! +!!c*`FQ9Q!%"41`!!!(d!N!BM#`!!!!a`FQ9Q!$r@)!!!!(i!N!D6-3!!!4"`FQ9 +Q!$qC@!!!!(m!N!BN,!!!!$*`FQ9Q!%!DXJ!!!)!!N!D833!!"9"`FQ9Q!%"IJ3! +!!)%!N!DCN3!!!a*`FQ9Q!$r)Z3!!!))!N!C%C`!!!'*`FQ9Q!$qkI!!!!)-!N!B +NAJ!!!$K`FQ9Q!$qX'`!!!)3!N!BRCJ!!!!e`FQ9Q!$qk(J!!!)8!N!BRF`!!!"4 +`FQ9Q!$qEi3!!!)B!N!BLk3!!!!T`FQ9Q!%"(#3!!!)F!N!DFS`!!!-4`FQ9Q!%! +Vh`!!!)J!N!DGC`!!!4K`FQ9Q!$rP`!!!!)N!N!DHI`!!!+K`FQ9Q!%!`-J!!!)S +!N!C%b3!!!#j`FQ9Q!$qiXJ!!!)X!N!DI*`!!!Ja`FQ9Q!%!Y3!!!!)`!N!C%p`! +!!#*`FQ9Q!%!r(J!!!)d!N!BRK`!!!""`FQ9Q!$pS)J!!!)i!N!C&'3!!!"T`FQ9 +Q!%!J1`!!!)m!N!DK-`!!!**`FQ9Q!$paGJ!!!*!!!*!'4GJ!!!"+F(*PCJ!rGJ8 +!!!#4!*!%H3N!!!: diff --git a/Mac/Contrib/osam/ScriptRunner.c b/Mac/Contrib/osam/ScriptRunner.c new file mode 100644 index 0000000..7fd68f6 --- /dev/null +++ b/Mac/Contrib/osam/ScriptRunner.c @@ -0,0 +1,289 @@ +/* + * + * This is a simple module to allow the + * user to compile and execute an applescript + * which is passed in as a text item. + * + * Sean Hummel <seanh@prognet.com> + * 1/20/98 + * RealNetworks + * + * Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com> + * + * + */ + +#include <Resources.h> +#include <Files.h> +#include <OSA.h> +#include <string.h> +#include "ScriptRunner.h" +#include <script.h> +#include <resources.h> + + + +OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent); + + +/* + * store the script as a compile script so that OSA + * components may load and execute the script easily + */ +OSAError +CompileAndSave (const char *text, + const char *outfile, + OSAActiveUPP proc, + AEDesc * result) +{ + + OSAError err2 = 0; + AEDesc theScript; + OSAID compiledScriptID = 0; + ComponentInstance scriptingComponent; + FSSpec outfilespec; + AEDesc theCompiledScript; + OSAID scriptid = kOSANullScript; + short saveres = 0; + + + + /* Initialize theScript here because it is a struct */ + theScript.dataHandle = NULL; + theCompiledScript.dataHandle = NULL; + + + /* open the component manager */ + err2 = LoadScriptingComponent (&scriptingComponent); + if (err2) + return err2; /* <<< Fail quietly?? */ + + + /* construct the AppleEvent Descriptor to contain the text of script */ + AECreateDesc ('TEXT', text, strlen (text), &theScript); + + err2 = OSACompile (scriptingComponent, + &theScript, + kOSAModeCompileIntoContext, + &scriptid); + if (err2) + { + OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result); + goto CleanUp; + } + + + err2 = OSAStore (scriptingComponent, + scriptid, + typeOSAGenericStorage, + kOSAModeCompileIntoContext, + &theCompiledScript); + if (err2) + { + OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result); + goto CleanUp; + } + + + c2pstr (outfile); + FSMakeFSSpec (0, 0, (StringPtr) outfile, &outfilespec); + p2cstr ((StringPtr) outfile); + + FSpDelete (&outfilespec); + + FSpCreateResFile (&outfilespec, 'ToyS', 'osas', smRoman); + + saveres = CurResFile (); + + if (saveres) + { + short myres = 0; + myres = FSpOpenResFile (&outfilespec, fsWrPerm); + + UseResFile (myres); + AddResource (theCompiledScript.dataHandle, 'scpt', 128, "\p"); + CloseResFile (myres); + UseResFile (saveres); + } + + +CleanUp: + + if (theScript.dataHandle) + AEDisposeDesc (&theScript); + + if (theCompiledScript.dataHandle) + AEDisposeDesc (&theCompiledScript); + + if (scriptid) + OSADispose (scriptingComponent, scriptid); + + if (scriptingComponent != 0) + CloseComponent (scriptingComponent); + + + return err2; +} + + +OSAError +CompileAndExecute (const char *text, + AEDesc * result, + OSAActiveUPP proc) +{ + OSAError err2 = 0; + AEDesc theScript; + OSAID compiledScriptID = 0; + ComponentInstance scriptingComponent; + + + /* initialize theScript here because it is a struct */ + theScript.dataHandle = NULL; + + /* Open the component manager */ + err2 = LoadScriptingComponent (&scriptingComponent); + if (err2) + return err2; /* <<< Fail quietly?? */ + + + /* construct the AppleEvent Descriptor to contain the text of script */ + AECreateDesc ('TEXT', text, strlen (text), &theScript); + + + err2 = OSASetActiveProc (scriptingComponent, proc, NULL); + if (err2) + goto CleanUp; + + + err2 = OSADoScript (scriptingComponent, &theScript, kOSANullScript, 'TEXT', 0, result); + if (err2) + { + OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result); + goto CleanUp; + } + + +CleanUp: + + if (theScript.dataHandle) + AEDisposeDesc (&theScript); + + if (scriptingComponent != 0) + CloseComponent (scriptingComponent); + + + return err2; +} + + +/* + * This routine reads in a saved script file and executes + * the script contained within (from a 'scpt' resource.) + */ +OSAError +ExecuteScriptFile (const char *theFilePath, + OSAActiveUPP proc, + AEDesc * result) +{ + OSAError err2; + short resRefCon; + AEDesc theScript; + OSAID compiledScriptID, scriptResultID; + ComponentInstance scriptingComponent; + FSSpec theFile; + + + c2pstr (theFilePath); + FSMakeFSSpec (0, 0, (StringPtr) theFilePath, &theFile); + p2cstr ((StringPtr) theFilePath); + + + /* open a connection to the OSA */ + err2 = LoadScriptingComponent (&scriptingComponent); + if (err2) + return err2; /* <<< Fail quietly?? */ + + + err2 = OSASetActiveProc (scriptingComponent, proc, NULL); + if (err2) + goto error; + + + /* now, try and read in the script + * Open the script file and get the resource + */ + resRefCon = FSpOpenResFile (&theFile, fsRdPerm); + if (resRefCon == -1) + return ResError (); + + theScript.dataHandle = Get1IndResource (typeOSAGenericStorage, 1); + + if ((err2 = ResError ()) || (err2 = resNotFound, theScript.dataHandle == NULL)) + { + CloseResFile (resRefCon); + return err2; + } + + theScript.descriptorType = typeOSAGenericStorage; + DetachResource (theScript.dataHandle); + CloseResFile (resRefCon); + err2 = noErr; + + + /* give a copy of the script to AppleScript */ + err2 = OSALoad (scriptingComponent, + &theScript, + 0L, + &compiledScriptID); + if (err2) + goto error; + + AEDisposeDesc (&theScript); + theScript.dataHandle = NULL; + + + err2 = OSAExecute (scriptingComponent, + compiledScriptID, + kOSANullScript, + 0, + &scriptResultID); + + if (compiledScriptID) + OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result); + + if (err2) + goto error; + + /* If there was an error, return it. If there was a result, return it. */ + (void) OSADispose (scriptingComponent, compiledScriptID); + + if (err2) + goto error; + else + goto done; + +error: + if (theScript.dataHandle) + AEDisposeDesc (&theScript); + + +done: + + + return err2; +} + + +OSAError +LoadScriptingComponent (ComponentInstance * scriptingComponent) +{ + OSAError err2; + + /* Open a connection to the Open Scripting Architecture */ + *scriptingComponent = OpenDefaultComponent (kOSAComponentType, + kOSAGenericScriptingComponentSubtype); + + err2 = GetComponentInstanceError (*scriptingComponent); + + return err2; +} diff --git a/Mac/Contrib/osam/ScriptRunner.h b/Mac/Contrib/osam/ScriptRunner.h new file mode 100644 index 0000000..dda7bbb --- /dev/null +++ b/Mac/Contrib/osam/ScriptRunner.h @@ -0,0 +1,30 @@ +/* + * + * This is a simple module to allow the + * user to compile and execute an applescript + * which is passed in as a text item. + * + * Sean Hummel <seanh@prognet.com> + * 1/20/98 + * RealNetworks + * + * Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com> + * + * + */ +#pragma once + +#include <OSA.h> + +OSAError CompileAndExecute (const char *text, + AEDesc *result, + OSAActiveUPP proc); + +OSAError CompileAndSave (const char *text, + const char *outfile, + OSAActiveUPP proc, + AEDesc *result); + +OSAError ExecuteScriptFile (const char *theFile, + OSAActiveUPP proc, + AEDesc *result); |