diff --git a/Mac/Lib/EasyDialogs.py b/Mac/Lib/EasyDialogs.py
new file mode 100644
index 0000000..41edd7e
--- /dev/null
+++ b/Mac/Lib/EasyDialogs.py
@@ -0,0 +1,110 @@
+"""Easy to use dialogs.
+
+Message(msg) -- display a message and an OK button.
+AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
+AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
+
+More documentation in each function.
+This module uses DLOG resources 256, 257 and 258.
+Based upon STDWIN dialogs with the same names and functions.
+"""
+
+from Dlg import GetNewDialog, SetIText, GetIText, ModalDialog
+
+
+def Message(msg):
+	"""Display a MESSAGE string.
+	
+	Return when the user clicks the OK button or presses Return.
+	
+	The MESSAGE string can be at most 255 characters long.
+	"""
+	
+	id = 256
+	d = GetNewDialog(id, -1)
+	if not d:
+		print "Can't get DLOG resource with id =", id
+		return
+	tp, h, rect = d.GetDItem(2)
+	SetIText(h, msg)
+	while 1:
+		n = ModalDialog(None)
+		if n == 1:
+			return
+
+
+def AskString(prompt, default = ""):
+	"""Display a PROMPT string and a text entry field with a DEFAULT string.
+	
+	Return the contents of the text entry field when the user clicks the
+	OK button or presses Return.
+	Return None when the user clicks the Cancel button.
+	
+	If omitted, DEFAULT is empty.
+	
+	The PROMPT and DEFAULT strings, as well as the return value,
+	can be at most 255 characters long.
+	"""
+	
+	id = 257
+	d = GetNewDialog(id, -1)
+	if not d:
+		print "Can't get DLOG resource with id =", id
+		return
+	tp, h, rect = d.GetDItem(3)
+	SetIText(h, prompt)
+	tp, h, rect = d.GetDItem(4)
+	SetIText(h, default)
+	d.SelIText(4, 0, 255)
+	while 1:
+		n = ModalDialog(None)
+		if n == 1:
+			tp, h, rect = d.GetDItem(4)
+			return GetIText(h)
+		if n == 2: return None
+
+
+def AskYesNoCancel(question, default = 0):
+##	"""Display a QUESTION string which can be answered with Yes or No.
+##	
+##	Return 1 when the user clicks the Yes button.
+##	Return 0 when the user clicks the No button.
+##	Return -1 when the user clicks the Cancel button.
+##	
+##	When the user presses Return, the DEFAULT value is returned.
+##	If omitted, this is 0 (No).
+##	
+##	The QUESTION strign ca be at most 255 characters.
+##	"""
+	
+	id = 258
+	d = GetNewDialog(id, -1)
+	if not d:
+		print "Can't get DLOG resource with id =", id
+		return
+	# Button assignments:
+	# 1 = default (invisible)
+	# 2 = Yes
+	# 3 = No
+	# 4 = Cancel
+	# The question string is item 5
+	tp, h, rect = d.GetDItem(5)
+	SetIText(h, question)
+	while 1:
+		n = ModalDialog(None)
+		if n == 1: return default
+		if n == 2: return 1
+		if n == 3: return 0
+		if n == 4: return -1
+
+
+def test():
+	Message("Testing EasyDialogs.")
+	ok = AskYesNoCancel("Do you want to proceed?")
+	if ok > 0:
+		s = AskString("Enter your first name")
+		Message("Thank you,\015%s" % `s`)
+
+
+if __name__ == '__main__':
+	test()
diff --git a/Mac/Lib/FrameWork.py b/Mac/Lib/FrameWork.py
new file mode 100644
index 0000000..3e60f70
--- /dev/null
+++ b/Mac/Lib/FrameWork.py
@@ -0,0 +1,480 @@
+"A sort of application framework for the Mac"
+
+
+import MacOS
+import traceback
+
+from addpack import addpack
+addpack('Demo')
+addpack('bgen')
+addpack('ae')
+#addpack('ctl')
+addpack('dlg')
+addpack('evt')
+addpack('menu')
+#addpack('qd')
+#addpack('res')
+#addpack('snd')
+addpack('win')
+
+from AE import *
+from AppleEvents import *
+#from Ctl import *
+#from Controls import *
+from Dlg import *
+from Dialogs import *
+from Evt import *
+from Events import *
+from Menu import *
+from Menus import *
+#from Qd import *
+#from QuickDraw import *
+#from Res import *
+#from Resources import *
+#from Snd import *
+#from Sound import *
+from Win import *
+from Windows import *
+
+import EasyDialogs
+
+kHighLevelEvent = 23	# Don't know what header file this should come from
+
+
+# Map event 'what' field to strings
+eventname = {}
+eventname[1] = 'mouseDown'
+eventname[2] = 'mouseUp'
+eventname[3] = 'keyDown'
+eventname[4] = 'keyUp'
+eventname[5] = 'autoKey'
+eventname[6] = 'updateEvt'
+eventname[7] = 'diskEvt'
+eventname[8] = 'activateEvt'
+eventname[15] = 'osEvt'
+eventname[23] = 'kHighLevelEvent'
+
+# Map part codes returned by WhichWindow() to strings
+partname = {}
+partname[0] = 'inDesk'
+partname[1] = 'inMenuBar'
+partname[2] = 'inSysWindow'
+partname[3] = 'inContent'
+partname[4] = 'inDrag'
+partname[5] = 'inGrow'
+partname[6] = 'inGoAway'
+partname[7] = 'inZoomIn'
+partname[8] = 'inZoomOut'
+
+# A rectangle that's bigger than the screen,
+# but not so big that adding the screen size to it will cause 16-bit overflow
+everywhere = (-16000, -16000, 16000, 16000)
+
+
+class Application:
+	
+	"Application framework -- your application should be a derived class"
+	
+	def __init__(self):
+		self.makemenubar()
+	
+	def makemenubar(self):
+		self.menubar = MenuBar()
+		AppleMenu(self.menubar, self.getabouttext(), self.do_about)
+		self.makeusermenus()
+	
+	def getabouttext(self):
+		return "About %s..." % self.__class__.__name__
+	
+	def do_about(self, id, item, window, event):
+		EasyDialogs.Message("Hello, world!" + "\015(%s)" % self.__class__.__name__)
+	
+	# The main event loop is broken up in several simple steps.
+	# This is done so you can override each individual part,
+	# if you have a need to do extra processing independent of the
+	# event type.
+	# Normally, however, you'd just define handlers for individual
+	# events.
+	# (XXX I'm not sure if using default parameter values is the right
+	# way to define the mask and wait time passed to WaitNextEvent.)
+	
+	def mainloop(self, mask = everyEvent, wait = 0):
+		saveyield = MacOS.EnableAppswitch(self.yield)
+		try:
+			while 1:
+				try:
+					self.do1event(mask, wait)
+				except (Application, SystemExit):
+					break
+		finally:
+			MacOS.EnableAppswitch(saveyield)
+	
+	yield = -1
+	
+	def do1event(self, mask = everyEvent, wait = 0):
+		event = self.getevent(mask, wait)
+		if event:
+			self.dispatch(event)
+	
+	def getevent(self, mask = everyEvent, wait = 0):
+		ok, event = WaitNextEvent(mask, wait)
+		if ok:
+			return event
+		else:
+			return None
+	
+	def dispatch(self, event):
+		(what, message, when, where, modifiers) = event
+		if eventname.has_key(what):
+			name = "do_" + eventname[what]
+		else:
+			name = "do_%d" % what
+		try:
+			handler = getattr(self, name)
+		except AttributeError:
+			handler = self.do_unknownevent
+		handler(event)
+	
+	def do_mouseDown(self, event):
+		(what, message, when, where, modifiers) = event
+		partcode, window = FindWindow(where)
+		if partname.has_key(partcode):
+			name = "do_" + partname[partcode]
+		else:
+			name = "do_%d" % partcode
+		try:
+			handler = getattr(self, name)
+		except AttrinuteError:
+			handler = self.do_unknownpartcode
+		handler(partcode, window, event)
+	
+	def do_inDrag(self, partcode, window, event):
+		window.DragWindow(where, self.draglimit)
+	
+	draglimit = everywhere
+	
+	def do_inGoAway(self, partcode, window, event):
+		if window.TrackGoAway(where):
+			self.do_close(window)
+	
+	def do_close(self, window):
+		print "Should close window:", window
+	
+	def do_inZoom(self, partcode, window, event):
+		(what, message, when, where, modifiers) = event
+		if window.TrackBox(where, partcode):
+			window.ZoomWindow(partcode, 1)
+	
+	def do_inZoomIn(self, partcode, window, event):
+		SetPort(window) # !!!
+		self.do_inZoom(partcode, window, event)
+	
+	def do_inZoomOut(self, partcode, window, event):
+		SetPort(window) # !!!
+		self.do_inZoom(partcode, window, event)
+	
+	def do_inSysWindow(self, partcode, window, event):
+		print "SystemClick", event, window
+		# SystemClick(event, window) # XXX useless, window is None
+	
+	def do_inDesk(self, partcode, window, event):
+		print "inDesk"
+		# XXX what to do with it?
+	
+	def do_inMenuBar(self, partcode, window, event):
+		(what, message, when, where, modifiers) = event
+		result = MenuSelect(where)
+		id = (result>>16) & 0xffff	# Hi word
+		item = result & 0xffff		# Lo word
+		self.do_rawmenu(id, item, window, event)
+	
+	def do_rawmenu(self, id, item, window, event):
+		try:
+			self.do_menu(id, item, window, event)
+		finally:
+			HiliteMenu(0)
+	
+	def do_menu(self, id, item, window, event):
+		self.menubar.dispatch(id, item, window, event)
+	
+	def do_inGrow(self, partcode, window, event):
+		(what, message, when, where, modifiers) = event
+		result = window.GrowWindow(where, self.growlimit)
+		if result:
+			height = (result>>16) & 0xffff	# Hi word
+			width = result & 0xffff		# Lo word
+			self.do_resize(width, height, window)
+	
+	growlimit = everywhere
+	
+	def do_resize(self, width, height, window):
+		window.SizeWindow(width, height, 0)
+		self.do_postresize(width, height, window)
+	
+	def do_postresize(self, width, height, window):
+		SetPort(window)
+		InvalRect(everywhere)
+	
+	def do_inContent(self, partcode, window, event):
+		(what, message, when, where, modifiers) = event
+		local = GlobalToLocal(where)
+		ctltype, control = FindControl(local, window)
+		if ctltype and control:
+			pcode = control.TrackControl(local)
+			if pcode:
+				self.do_controlhit(window, control, pcode, event)
+		else:
+			print "FindControl(%s, %s) -> (%s, %s)" % \
+				(local, window, ctltype, control)
+	
+	def do_controlhit(self, window, control, pcode, event):
+		print "control hit in", window, "on", control, "; pcode =", pcode
+	
+	def do_unknownpartcode(self, partcode, window, event):
+		(what, message, when, where, modifiers) = event
+		print "Mouse down at global:", where
+		print "\tUnknown part code:", partcode
+	
+	def do_keyDown(self, event):
+		self.do_key(event)
+	
+	def do_autoKey(self, event):
+		if not event[-1] & cmdKey:
+			self.do_key(event)
+	
+	def do_key(self, event):
+		(what, message, when, where, modifiers) = event
+		c = chr(message & charCodeMask)
+		if modifiers & cmdKey:
+			if c == '.':
+				raise self
+			else:
+				result = MenuKey(ord(c))
+				id = (result>>16) & 0xffff	# Hi word
+				item = result & 0xffff		# Lo word
+				if id:
+					self.do_rawmenu(id, item, None, event)
+				elif c == 'w':
+					w = FrontWindow()
+					if w:
+						self.do_close(w)
+					else:
+						print 'Command-W without front window'
+				else:
+					print "Command-" +`c`
+		else:
+			self.do_char(c, event)
+	
+	def do_char(self, c, event):
+		print "Character", `c`
+	
+	def do_updateEvt(self, event):
+		print "do_update",
+		self.printevent(event)
+		window = FrontWindow() # XXX This is wrong!
+		if window:
+			self.do_rawupdate(window, event)
+		else:
+			print "no window for do_updateEvt"
+	
+	def do_rawupdate(self, window, event):
+		print "raw update for", window
+		window.BeginUpdate()
+		self.do_update(window, event)
+		DrawControls(window)
+		window.DrawGrowIcon()
+		window.EndUpdate()
+	
+	def do_update(self, window, event):
+		EraseRect(everywhere)
+	
+	def do_kHighLevelEvent(self, event):
+		(what, message, when, where, modifiers) = event
+		print "High Level Event:",
+		self.printevent(event)
+		try:
+			AEProcessAppleEvent(event)
+		except:
+			print "AEProcessAppleEvent error:"
+			traceback.print_exc()
+	
+	def do_unknownevent(self, event):
+		print "Unknown event:",
+		self.printevent(event)
+	
+	def printevent(self, event):
+		(what, message, when, where, modifiers) = event
+		nicewhat = `what`
+		if eventname.has_key(what):
+			nicewhat = eventname[what]
+		print nicewhat,
+		if what == kHighLevelEvent:
+			h, v = where
+			print `ostypecode(message)`, hex(when), `ostypecode(h | (v<<16))`,
+		else:
+			print hex(message), hex(when), where,
+		print hex(modifiers)
+
+
+class MenuBar:
+	"""Represent a set of menus in a menu bar.
+	
+	Interface:
+	
+	- (constructor)
+	- (destructor)
+	- addmenu
+	- addpopup (normally used internally)
+	- dispatch (called from Application)
+	"""
+	
+	nextid = 1	# Necessarily a class variable
+	
+	def getnextid(self):
+		id = self.nextid
+		self.nextid = id+1
+		return id
+	
+	def __init__(self):
+		ClearMenuBar()
+		self.bar = GetMenuBar()
+		self.menus = {}
+	
+	def addmenu(self, title, after = 0):
+		id = self.getnextid()
+		m = NewMenu(id, title)
+		m.InsertMenu(after)
+		DrawMenuBar()
+		return id, m
+	
+	def addpopup(self, title = ''):
+		return self.addmenu(title, -1)
+	
+	def install(self):
+		self.bar.SetMenuBar()
+		DrawMenuBar()
+	
+	def dispatch(self, id, item, window, event):
+		if self.menus.has_key(id):
+			self.menus[id].dispatch(id, item, window, event)
+		else:
+			print "MenuBar.dispatch(%d, %d, %s, %s)" % \
+				(id, item, window, event)
+	
+
+# XXX Need a way to get menus as resources and bind them to callbacks
+
+class Menu:
+	"One menu."
+	
+	def __init__(self, bar, title, after=0):
+		self.bar = bar
+		self.id, self.menu = self.bar.addmenu(title, after)
+		bar.menus[self.id] = self
+		self.items = []
+	
+	def additem(self, label, shortcut=None, callback=None, kind=None):
+		self.menu.AppendMenu('x')		# add a dummy string
+		self.items.append(label, shortcut, callback, kind)
+		item = len(self.items)
+		self.menu.SetItem(item, label)		# set the actual text
+		if shortcut:
+			self.menu.SetItemCmd(item, ord(shortcut))
+		return item
+	
+	def addcheck(self, label, shortcut=None, callback=None):
+		return self.additem(label, shortcut, callback, 'check')
+	
+	def addradio(self, label, shortcut=None, callback=None):
+		return self.additem(label, shortcut, callback, 'radio')
+	
+	def addseparator(self):
+		self.menu.AppendMenu('(-')
+		self.items.append('', None, None, 'separator')
+	
+	def addsubmenu(self, label, title=''):
+		sub = Menu(self.bar, title, -1)
+		item = self.additem(label, '\x1B', None, 'submenu')
+		self.menu.SetItemMark(item, sub.id)
+		return sub
+	
+	def dispatch(self, id, item, window, event):
+		title, shortcut, callback, type = self.items[item-1]
+		if callback:
+			callback(id, item, window, event)
+
+
+class MenuItem:
+	def __init__(self, menu, title, shortcut=None, callback=None, kind=None):
+		self.item = menu.additem(title, shortcut, callback)
+
+class RadioItem(MenuItem):
+	def __init__(self, menu, title, shortcut=None, callback=None):
+		MenuItem.__init__(self, menu, title, shortcut, callback, 'radio')
+
+class CheckItem(MenuItem):
+	def __init__(self, menu, title, shortcut=None, callback=None):
+		MenuItem.__init__(self, menu, title, shortcut, callback, 'check')
+
+def Separator(menu):
+	menu.addseparator()
+
+def SubMenu(menu, label, title=''):
+	return menu.addsubmenu(label, title)
+
+
+class AppleMenu(Menu):
+	
+	def __init__(self, bar, abouttext="About me...", aboutcallback=None):
+		Menu.__init__(self, bar, "\024")
+		self.additem(abouttext, None, aboutcallback)
+		self.addseparator()
+		self.menu.AddResMenu('DRVR')
+	
+	def dispatch(self, id, item, window, event):
+		if item == 1:
+			Menu.dispatch(self, id, item, window, event)
+		else:
+			name = self.menu.GetItem(item)
+			OpenDeskAcc(name)
+
+
+def ostypecode(x):
+	"Convert a long int to the 4-character code it really is"
+	s = ''
+	for i in range(4):
+		x, c = divmod(x, 256)
+		s = chr(c) + s
+	return s
+
+
+class TestApp(Application):
+	
+	"This class is used by the test() function"
+	
+	def makeusermenus(self):
+		self.filemenu = m = Menu(self.menubar, "File")
+		self.saveitem = MenuItem(m, "Save", "S", self.save)
+		Separator(m)
+		self.optionsmenu = mm = SubMenu(m, "Options")
+		self.opt1 = CheckItem(mm, "Arguments")
+		self.opt2 = CheckItem(mm, "Being hit on the head lessons")
+		self.opt3 = CheckItem(mm, "Complaints")
+		Separator(m)
+		self.quititem = MenuItem(m, "Quit", "Q", self.quit)
+	
+	def save(self, *args):
+		print "Save"
+	
+	def quit(self, *args):
+		raise self
+
+
+def test():
+	"Test program"
+	app = TestApp()
+	app.mainloop()
+
+
+if __name__ == '__main__':
+	test()
