Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 1 | """argvemulator - create sys.argv from OSA events. Used by applets that |
| 2 | want unix-style arguments. |
| 3 | """ |
| 4 | |
| 5 | import sys |
| 6 | import traceback |
| 7 | from Carbon import AE |
| 8 | from Carbon.AppleEvents import * |
| 9 | from Carbon import Evt |
| 10 | from Carbon.Events import * |
| 11 | import aetools |
| 12 | |
| 13 | class ArgvCollector: |
Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 14 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 15 | """A minimal FrameWork.Application-like class""" |
Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 16 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 17 | def __init__(self): |
| 18 | self.quitting = 0 |
| 19 | self.ae_handlers = {} |
| 20 | # Remove the funny -psn_xxx_xxx argument |
| 21 | if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn': |
| 22 | del sys.argv[1] |
| 23 | self.installaehandler('aevt', 'oapp', self.open_app) |
| 24 | self.installaehandler('aevt', 'odoc', self.open_file) |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 25 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 26 | def installaehandler(self, classe, type, callback): |
| 27 | AE.AEInstallEventHandler(classe, type, self.callback_wrapper) |
| 28 | self.ae_handlers[(classe, type)] = callback |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 29 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 30 | def close(self): |
| 31 | for classe, type in self.ae_handlers.keys(): |
| 32 | AE.AERemoveEventHandler(classe, type) |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 33 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 34 | def mainloop(self, mask = highLevelEventMask, timeout = 1*60): |
| 35 | stoptime = Evt.TickCount() + timeout |
| 36 | while not self.quitting and Evt.TickCount() < stoptime: |
| 37 | self.dooneevent(mask, timeout) |
| 38 | self.close() |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 39 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 40 | def _quit(self): |
| 41 | self.quitting = 1 |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 42 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 43 | def dooneevent(self, mask = highLevelEventMask, timeout = 1*60): |
| 44 | got, event = Evt.WaitNextEvent(mask, timeout) |
| 45 | if got: |
| 46 | self.lowlevelhandler(event) |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 47 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 48 | def lowlevelhandler(self, event): |
| 49 | what, message, when, where, modifiers = event |
| 50 | h, v = where |
| 51 | if what == kHighLevelEvent: |
| 52 | try: |
| 53 | AE.AEProcessAppleEvent(event) |
| 54 | except AE.Error, err: |
Walter Dörwald | 70a6b49 | 2004-02-12 17:35:32 +0000 | [diff] [blame] | 55 | msg = "High Level Event: %r %r" % (hex(message), hex(h | (v<<16))) |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 56 | print 'AE error: ', err |
| 57 | print 'in', msg |
| 58 | traceback.print_exc() |
| 59 | return |
| 60 | else: |
| 61 | print "Unhandled event:", event |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 62 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 63 | def callback_wrapper(self, _request, _reply): |
| 64 | _parameters, _attributes = aetools.unpackevent(_request) |
| 65 | _class = _attributes['evcl'].type |
| 66 | _type = _attributes['evid'].type |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 67 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 68 | if self.ae_handlers.has_key((_class, _type)): |
| 69 | _function = self.ae_handlers[(_class, _type)] |
| 70 | elif self.ae_handlers.has_key((_class, '****')): |
| 71 | _function = self.ae_handlers[(_class, '****')] |
| 72 | elif self.ae_handlers.has_key(('****', '****')): |
| 73 | _function = self.ae_handlers[('****', '****')] |
| 74 | else: |
| 75 | raise 'Cannot happen: AE callback without handler', (_class, _type) |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 76 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 77 | # XXXX Do key-to-name mapping here |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 78 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 79 | _parameters['_attributes'] = _attributes |
| 80 | _parameters['_class'] = _class |
| 81 | _parameters['_type'] = _type |
| 82 | if _parameters.has_key('----'): |
| 83 | _object = _parameters['----'] |
| 84 | del _parameters['----'] |
| 85 | # The try/except that used to be here can mask programmer errors. |
| 86 | # Let the program crash, the programmer can always add a **args |
| 87 | # to the formal parameter list. |
| 88 | rv = _function(_object, **_parameters) |
| 89 | else: |
| 90 | #Same try/except comment as above |
| 91 | rv = _function(**_parameters) |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 92 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 93 | if rv == None: |
| 94 | aetools.packevent(_reply, {}) |
| 95 | else: |
| 96 | aetools.packevent(_reply, {'----':rv}) |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 97 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 98 | def open_app(self, **args): |
| 99 | self._quit() |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 100 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 101 | def open_file(self, _object=None, **args): |
| 102 | for alias in _object: |
| 103 | fsr = alias.FSResolveAlias(None)[0] |
| 104 | pathname = fsr.as_pathname() |
| 105 | sys.argv.append(pathname) |
| 106 | self._quit() |
Raymond Hettinger | ff41c48 | 2003-04-06 09:01:11 +0000 | [diff] [blame] | 107 | |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 108 | def other(self, _object=None, _class=None, _type=None, **args): |
| 109 | print 'Ignore AppleEvent', (_class, _type), 'for', _object, 'Other args:', args |
Jack Jansen | f4f6d48 | 2002-08-02 11:12:15 +0000 | [diff] [blame] | 110 | |
| 111 | if __name__ == '__main__': |
Just van Rossum | 35b50e2 | 2003-06-21 14:41:32 +0000 | [diff] [blame] | 112 | ArgvCollector().mainloop() |
| 113 | print "sys.argv=", sys.argv |