]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Mon, 20 Jun 1994 07:49:28 +0000 (07:49 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 20 Jun 1994 07:49:28 +0000 (07:49 +0000)
13 files changed:
Demo/tkinter/guido/MimeViewer.py [new file with mode: 0755]
Demo/tkinter/guido/dialog.py [new file with mode: 0755]
Demo/tkinter/guido/mbox.py [new file with mode: 0755]
Demo/tkinter/guido/rmt.py [new file with mode: 0755]
Demo/tkinter/guido/tst.py [new file with mode: 0755]
Demo/tkinter/guido/wish.py [new file with mode: 0755]
Lib/lib-tk/Canvas.py [new file with mode: 0644]
Lib/lib-tk/ScrolledText.py [new file with mode: 0644]
Lib/lib-tk/Tkinter.py [new file with mode: 0644]
Lib/tkinter/Canvas.py [new file with mode: 0755]
Lib/tkinter/ScrolledText.py [new file with mode: 0755]
Lib/tkinter/Tkinter.py [new file with mode: 0755]
Modules/_tkinter.c [new file with mode: 0644]

diff --git a/Demo/tkinter/guido/MimeViewer.py b/Demo/tkinter/guido/MimeViewer.py
new file mode 100755 (executable)
index 0000000..5bf194a
--- /dev/null
@@ -0,0 +1,143 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# View a single MIME multipart message.
+# Display each part as a box.
+
+import string
+from types import *
+from Tkinter import *
+from ScrolledText import ScrolledText
+
+class MimeViewer:
+       def __init__(self, parent, title, msg):
+               self.title = title
+               self.msg = msg
+               self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
+               self.frame.packing = {'expand': 0, 'fill': 'both'}
+               self.button = Checkbutton(self.frame,
+                                    {'text': title,
+                                     'command': self.toggle})
+               self.button.pack({'anchor': 'w'})
+               headertext = msg.getheadertext(
+                       lambda x: x != 'received' and x[:5] != 'x400-')
+               height = countlines(headertext, 4)
+               if height:
+                       self.htext = ScrolledText(self.frame,
+                                         {'height': height,
+                                          'width': 80,
+                                          'wrap': 'none',
+                                          'relief': 'raised',
+                                          'bd': 2})
+                       self.htext.packing = {'expand': 1, 'fill': 'both',
+                                             'after': self.button}
+                       self.htext.insert('end', headertext)
+               else:
+                       self.htext = Frame(self.frame,
+                                          {'relief': 'raised', 'bd': 2})
+                       self.htext.packing = {'side': 'top',
+                                             'ipady': 2,
+                                             'fill': 'x',
+                                             'after': self.button}
+               body = msg.getbody()
+               if type(body) == StringType:
+                       self.pad = None
+                       height = countlines(body, 10)
+                       if height:
+                               self.btext = ScrolledText(self.frame,
+                                                 {'height': height,
+                                                  'width': 80,
+                                                  'wrap': 'none',
+                                                  'relief': 'raised',
+                                                  'bd': 2})
+                               self.btext.packing = {'expand': 1,
+                                                     'fill': 'both'}
+                               self.btext.insert('end', body)
+                       else:
+                               self.btext = None
+                       self.parts = None
+               else:
+                       self.pad = Frame(self.frame,
+                                        {'relief': 'flat', 'bd': 2})
+                       self.pad.packing = {'side': 'left', 'ipadx': 10,
+                                           'fill': 'y', 'after': self.htext}
+                       self.parts = []
+                       for i in range(len(body)):
+                               p = MimeViewer(self.frame,
+                                              '%s.%d' % (title, i+1),
+                                              body[i])
+                               self.parts.append(p)
+                       self.btext = None
+               self.collapsed = 1
+       def pack(self):
+               self.frame.pack(self.frame.packing)
+       def destroy(self):
+               self.frame.destroy()
+       def show(self):
+               if self.collapsed:
+                       self.button.invoke()
+       def toggle(self):
+               if self.collapsed:
+                       self.explode()
+               else:
+                       self.collapse()
+       def collapse(self):
+               self.collapsed = 1
+               for comp in self.htext, self.btext, self.pad:
+                       if comp:
+                               comp.forget()
+               if self.parts:
+                       for part in self.parts:
+                               part.frame.forget()
+               self.frame.pack({'expand': 0})
+       def explode(self):
+               self.collapsed = 0
+               for comp in self.htext, self.btext, self.pad:
+                       if comp: comp.pack(comp.packing)
+               if self.parts:
+                       for part in self.parts:
+                               part.pack()
+               self.frame.pack({'expand': 1})
+
+def countlines(str, limit):
+       i = 0
+       n = 0
+       while  n < limit:
+               i = string.find(str, '\n', i)
+               if i < 0: break
+               n = n+1
+               i = i+1
+       return n
+
+def main():
+       import sys
+       import getopt
+       import mhlib
+       opts, args = getopt.getopt(sys.argv[1:], '')
+       for o, a in opts:
+               pass
+       message = None
+       folder = 'inbox'
+       for arg in args:
+               if arg[:1] == '+':
+                       folder = arg[1:]
+               else:
+                       message = string.atoi(arg)
+
+       mh = mhlib.MH()
+       f = mh.openfolder(folder)
+       if not message:
+               message = f.getcurrent()
+       m = f.openmessage(message)
+
+       root = Tk()
+       tk = root.tk
+
+       top = MimeViewer(root, '+%s/%d' % (folder, message), m)
+       top.pack()
+       top.show()
+
+       root.minsize(1, 1)
+
+       tk.mainloop()
+
+if __name__ == '__main__': main()
diff --git a/Demo/tkinter/guido/dialog.py b/Demo/tkinter/guido/dialog.py
new file mode 100755 (executable)
index 0000000..31f5340
--- /dev/null
@@ -0,0 +1,119 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# A Python function that generates dialog boxes with a text message,
+# optional bitmap, and any number of buttons.
+# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
+
+from Tkinter import *
+
+def dialog(master, title, text, bitmap, default, *args):
+
+    # 1. Create the top-level window and divide it into top
+    # and bottom parts.
+
+    w = Toplevel(master, {'class': 'Dialog'})
+    w.tk.call('global', 'button')
+    w.title(title)
+    w.iconname('Dialog')
+
+    top = Frame(w, {'relief': 'raised', 'bd': 1,
+                   Pack: {'side': 'top', 'fill': 'both'}})
+    bot = Frame(w, {'relief': 'raised', 'bd': 1,
+                   Pack: {'side': 'bottom', 'fill': 'both'}})
+
+    # 2. Fill the top part with the bitmap and message.
+
+    msg = Message(top,
+                 {'width': '3i',
+                  'text': text,
+                  'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
+                  Pack: {'side': 'right', 'expand': 1,
+                         'fill': 'both',
+                         'padx': '3m', 'pady': '3m'}})
+    if bitmap:
+       bm = Label(top, {'bitmap': bitmap,
+                        Pack: {'side': 'left',
+                               'padx': '3m', 'pady': '3m'}})
+
+    # 3. Create a row of buttons at the bottom of the dialog.
+
+    buttons = []
+    i = 0
+    for but in args:
+       b = Button(bot, {'text': but,
+                        'command': ('set', 'button', i)})
+       buttons.append(b)
+       if i == default:
+           bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
+                            Pack: {'side': 'left', 'expand': 1,
+                                   'padx': '3m', 'pady': '2m'}})
+           w.tk.call('raise', b)
+           b.pack ({'in': bd, 'side': 'left',
+                    'padx': '2m', 'pady': '2m',
+                    'ipadx': '2m', 'ipady': '1m'})
+       else:
+           b.pack ({'side': 'left', 'expand': 1,
+                    'padx': '3m', 'pady': '3m',
+                    'ipady': '2m', 'ipady': '1m'})
+       i = i+1
+
+    # 4. Set up a binding for <Return>, if there's a default,
+    # set a grab, and claim the focus too.
+
+    if default >= 0:
+       w.bind('<Return>',
+              lambda b=buttons[default], i=default:
+              (b.cmd('flash'),
+               b.tk.call('set', 'button', i)))
+
+    oldFocus = w.tk.call('focus')
+    w.tk.call('grab', 'set', w)
+    w.tk.call('focus', w)
+
+    # 5. Wait for the user to respond, then restore the focus
+    # and return the index of the selected button.
+
+    w.tk.call('tkwait', 'variable', 'button')
+    w.tk.call('destroy', w)
+    w.tk.call('focus', oldFocus)
+    return w.tk.call('set', 'button')
+
+# The rest is the test program.
+
+def go():
+    i = dialog(mainWidget,
+              'Not Responding',
+              "The file server isn't responding right now; "
+              "I'll keep trying.",
+              '',
+              -1,
+              'OK')
+    print 'pressed button', i
+    i = dialog(mainWidget,
+              'File Modified',
+              'File "tcl.h" has been modified since '
+              'the last time it was saved. '
+              'Do you want to save it before exiting the application?',
+              'warning',
+              0,
+              'Save File',
+              'Discard Changes',
+              'Return To Editor')
+    print 'pressed button', i
+
+def test():
+    import sys
+    global mainWidget
+    mainWidget = Frame()
+    Pack.config(mainWidget)
+    start = Button(mainWidget,
+                  {'text': 'Press Here To Start', 'command': go})
+    start.pack()
+    endit = Button(mainWidget,
+                  {'text': 'Exit',
+                   'command': 'exit',
+                   Pack: {'fill' : 'both'}})
+    mainWidget.tk.mainloop()
+
+if __name__ == '__main__':
+    test()
diff --git a/Demo/tkinter/guido/mbox.py b/Demo/tkinter/guido/mbox.py
new file mode 100755 (executable)
index 0000000..a4e86da
--- /dev/null
@@ -0,0 +1,288 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# Scan MH folder, display results in window
+
+import os
+import sys
+import regex
+import getopt
+import string
+import mhlib
+
+from Tkinter import *
+
+from dialog import dialog
+
+mailbox = os.environ['HOME'] + '/Mail'
+
+def main():
+       global root, tk, top, mid, bot
+       global folderbox, foldermenu, scanbox, scanmenu, viewer
+       global folder, seq
+       global mh, mhf
+
+       # Parse command line options
+
+       folder = 'inbox'
+       seq = 'all'
+       try:
+               opts, args = getopt.getopt(sys.argv[1:], '')
+       except getopt.error, msg:
+               print msg
+               sys.exit(2)
+       for arg in args:
+               if arg[:1] == '+':
+                       folder = arg[1:]
+               else:
+                       seq = arg
+
+       # Initialize MH
+
+       mh = mhlib.MH()
+       mhf = mh.openfolder(folder)
+
+       # Build widget hierarchy
+
+       root = Tk()
+       tk = root.tk
+
+       top = Frame(root)
+       top.pack({'expand': 1, 'fill': 'both'})
+
+       # Build right part: folder list
+
+       right = Frame(top)
+       right.pack({'fill': 'y', 'side': 'right'})
+
+       folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
+       folderbar.pack({'fill': 'y', 'side': 'right'})
+
+       folderbox = Listbox(right)
+       folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
+
+       foldermenu = Menu(root)
+       foldermenu.add('command',
+                      {'label': 'Open Folder',
+                       'command': open_folder})
+       foldermenu.add('separator')
+       foldermenu.add('command',
+                      {'label': 'Quit',
+                       'command': 'exit'})
+       foldermenu.bind('<ButtonRelease-3>', folder_unpost)
+
+       folderbox['yscrollcommand'] = (folderbar, 'set')
+       folderbar['command'] = (folderbox, 'yview')
+       folderbox.bind('<Double-1>', open_folder, 1)
+       folderbox.bind('<3>', folder_post)
+
+       # Build left part: scan list
+
+       left = Frame(top)
+       left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
+
+       scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
+       scanbar.pack({'fill': 'y', 'side': 'right'})
+
+       scanbox = Listbox(left, {'font': 'fixed'})
+       scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
+
+       scanmenu = Menu(root)
+       scanmenu.add('command',
+                    {'label': 'Open Message',
+                     'command': open_message})
+       scanmenu.add('command',
+                    {'label': 'Remove Message',
+                     'command': remove_message})
+       scanmenu.add('command',
+                    {'label': 'Refile Message',
+                     'command': refile_message})
+       scanmenu.add('separator')
+       scanmenu.add('command',
+                    {'label': 'Quit',
+                     'command': 'exit'})
+       scanmenu.bind('<ButtonRelease-3>', scan_unpost)
+
+       scanbox['yscrollcommand'] = (scanbar, 'set')
+       scanbar['command'] = (scanbox, 'yview')
+       scanbox.bind('<Double-1>', open_message)
+       scanbox.bind('<3>', scan_post)
+
+       # Separator between middle and bottom part
+
+       rule2 = Frame(root, {'bg': 'black'})
+       rule2.pack({'fill': 'x'})
+
+       # Build bottom part: current message
+
+       bot = Frame(root)
+       bot.pack({'expand': 1, 'fill': 'both'})
+       #
+       viewer = None
+
+       # Window manager commands
+
+       root.minsize(800, 1) # Make window resizable
+
+       # Fill folderbox with text
+
+       setfolders()
+
+       # Fill scanbox with text
+
+       rescan()
+
+       # Enter mainloop
+
+       root.mainloop()
+
+def folder_post(e):
+       x, y = e.x_root, e.y_root
+       foldermenu.post(x - 10, y - 10)
+       foldermenu.grab_set()
+
+def folder_unpost(e):
+       tk.call('update', 'idletasks')
+       foldermenu.grab_release()
+       foldermenu.unpost()
+       foldermenu.invoke('active')
+
+def scan_post(e):
+       x, y = e.x_root, e.y_root
+       scanmenu.post(x - 10, y - 10)
+       scanmenu.grab_set()
+
+def scan_unpost(e):
+       tk.call('update', 'idletasks')
+       scanmenu.grab_release()
+       scanmenu.unpost()
+       scanmenu.invoke('active')
+
+scanparser = regex.compile('^ *\([0-9]+\)')
+
+def open_folder(*e):
+       global folder, mhf
+       sel = folderbox.curselection()
+       if len(sel) != 1:
+               if len(sel) > 1:
+                       msg = "Please open one folder at a time"
+               else:
+                       msg = "Please select a folder to open"
+               dialog(root, "Can't Open Folder", msg, "", 0, "OK")
+               return
+       i = sel[0]
+       folder = folderbox.get(i)
+       mhf = mh.openfolder(folder)
+       rescan()
+
+def open_message(*e):
+       global viewer
+       sel = scanbox.curselection()
+       if len(sel) != 1:
+               if len(sel) > 1:
+                       msg = "Please open one message at a time"
+               else:
+                       msg = "Please select a message to open"
+               dialog(root, "Can't Open Message", msg, "", 0, "OK")
+               return
+       cursor = scanbox['cursor']
+       scanbox['cursor'] = 'watch'
+       tk.call('update', 'idletasks')
+       i = sel[0]
+       line = scanbox.get(i)
+       if scanparser.match(line) >= 0:
+               num = string.atoi(scanparser.group(1))
+               m = mhf.openmessage(num)
+               if viewer: viewer.destroy()
+               from MimeViewer import MimeViewer
+               viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
+               viewer.pack()
+               viewer.show()
+       scanbox['cursor'] = cursor
+
+def interestingheader(header):
+       return header != 'received'
+
+def remove_message():
+       itop = scanbox.nearest(0)
+       sel = scanbox.curselection()
+       if not sel:
+               dialog(root, "No Message To Remove",
+                      "Please select a message to remove", "", 0, "OK")
+               return
+       todo = []
+       for i in sel:
+               line = scanbox.get(i)
+               if scanparser.match(line) >= 0:
+                       todo.append(string.atoi(scanparser.group(1)))
+       mhf.removemessages(todo)
+       rescan()
+       fixfocus(min(todo), itop)
+
+lastrefile = ''
+tofolder = None
+def refile_message():
+       global lastrefile, tofolder
+       itop = scanbox.nearest(0)
+       sel = scanbox.curselection()
+       if not sel:
+               dialog(root, "No Message To Refile",
+                      "Please select a message to refile", "", 0, "OK")
+               return
+       foldersel = folderbox.curselection()
+       if len(foldersel) != 1:
+               if not foldersel:
+                       msg = "Please select a folder to refile to"
+               else:
+                       msg = "Please select exactly one folder to refile to"
+               dialog(root, "No Folder To Refile", msg, "", 0, "OK")
+               return
+       refileto = folderbox.get(foldersel[0])
+       todo = []
+       for i in sel:
+               line = scanbox.get(i)
+               if scanparser.match(line) >= 0:
+                       todo.append(string.atoi(scanparser.group(1)))
+       print 'refile', todo, tofolder
+       if lastrefile != refileto or not tofolder:
+               print 'new folder'
+               lastrefile = refileto
+               tofolder = None
+               tofolder = mh.openfolder(lastrefile)
+       mhf.refilemessages(todo, tofolder)
+       rescan()
+       fixfocus(min(todo), itop)
+
+def fixfocus(near, itop):
+       n = scanbox.size()
+       for i in range(n):
+               line = scanbox.get(`i`)
+               if scanparser.match(line) >= 0:
+                       num = string.atoi(scanparser.group(1))
+                       if num >= near:
+                               break
+       else:
+               i = 'end'
+       scanbox.select_from(i)
+       print 'yview', `itop`
+       scanbox.yview(itop)
+
+def setfolders():
+       folderbox.delete(0, 'end')
+       for fn in mh.listallfolders():
+               folderbox.insert('end', fn)
+
+def rescan():
+       global viewer
+       if viewer:
+               viewer.destroy()
+               viewer = None
+       scanbox.delete(0, 'end')
+       for line in scanfolder(folder, seq):
+               scanbox.insert('end', line)
+
+def scanfolder(folder = 'inbox', sequence = 'all'):
+       return map(
+               lambda line: line[:-1],
+               os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
+
+main()
diff --git a/Demo/tkinter/guido/rmt.py b/Demo/tkinter/guido/rmt.py
new file mode 100755 (executable)
index 0000000..2ac2408
--- /dev/null
@@ -0,0 +1,152 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# A Python program implementing rmt, an application for remotely
+# controlling other Tk applications.
+# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.
+
+# Note that because of forward references in the original, we
+# sometimes delay bindings until after the corresponding procedure is
+# defined.  We also introduce names for some unnamed code blocks in
+# the original because of restrictions on lambda forms in Python.
+
+from Tkinter import *
+
+# 1. Create basic application structure: menu bar on top of
+# text widget, scrollbar on right.
+
+root = Tk()
+tk = root.tk
+mBar = Frame(root, {'relief': 'raised', 'bd': 2,
+                   Pack: {'side': 'top', 'fill': 'x'}})
+f = Frame(root)
+f.pack({'expand': 1, 'fill': 'both'})
+s = Scrollbar(f, {'relief': 'flat',
+                 Pack: {'side': 'right', 'fill': 'y'}})
+t = Text(f, {'relief': 'raised', 'bd': 2, 'yscrollcommand': (s, 'set'),
+            'setgrid': 1,
+            Pack: {'side': 'left', 'fill': 'both', 'expand': 1}})
+
+t.tag_config('bold', {'font': '-Adobe-Courier-Bold-R-Normal-*-120-*'}) 
+s['command'] = (t, 'yview')
+root.title('Tk Remote Controller')
+root.iconname('Tk Remote')
+
+# 2. Create menu button and menus.
+
+file = Menubutton(mBar, {'text': 'File', 'underline': 0,
+                        Pack: {'side': 'left'}})
+file_m = Menu(file)
+file['menu'] = file_m
+file_m_apps = Menu(file_m)
+file_m.add('cascade', {'label': 'Select Application', 'underline': 0,
+                      'menu': file_m_apps})
+file_m.add('command', {'label': 'Quit', 'underline': 0, 'command': 'exit'})
+
+# 3. Create bindings for text widget to allow commands to be
+# entered and information to be selected.  New characters
+# can only be added at the end of the text (can't ever move
+# insertion point).
+
+def single1(e):
+       x = e.x
+       y = e.y
+       tk.setvar('tk_priv(selectMode)', 'char')
+       t.mark_set('anchor', At(x, y))
+       # Should focus W
+t.bind('<1>', single1)
+
+def double1(e):
+       x = e.x
+       y = e.y
+       tk.setvar('tk_priv(selectMode)', 'word')
+       tk.call('tk_textSelectTo', t, At(x, y))
+t.bind('<Double-1>', double1)
+
+def triple1(e):
+       x = e.x
+       y = e.y
+       tk.setvar('tk_priv(selectMode)', 'line')
+       tk.call('tk_textSelectTo', t, At(x, y))
+t.bind('<Triple-1>', triple1)
+
+def returnkey(e):
+       t.insert('insert', '\n')
+       invoke()
+t.bind('<Return>', returnkey)
+
+def controlv(e):
+       t.insert('insert', tk.call('selection', 'get'))
+       t.yview_pickplace('insert')
+       if t.index('insert')[-2:] == '.0':
+               invoke()
+t.bind('<Control-v>', controlv)
+
+# 4. Procedure to backspace over one character, as long as
+# the character isn't part of the prompt.
+
+def backspace(e):
+       if t.index('promptEnd') != t.index('insert - 1 char'):
+               t.delete('insert - 1 char', 'insert')
+               t.yview_pickplace('insert')
+t.bind('<BackSpace>', backspace)
+t.bind('<Control-h>', backspace)
+t.bind('<Delete>', backspace)
+
+
+# 5. Procedure that's invoked when return is typed:  if
+# there's not yet a complete command (e.g. braces are open)
+# then do nothing.  Otherwise, execute command (locally or
+# remotely), output the result or error message, and issue
+# a new prompt.
+
+def invoke():
+       cmd = t.get('promptEnd + 1 char', 'insert')
+       if tk.getboolean(tk.call('info', 'complete', cmd)):
+               if app == tk.call('winfo', 'name', '.'):
+                       msg = tk.call('eval', cmd)
+               else:
+                       msg = tk.call('send', app, cmd)
+               if msg:
+                       t.insert('insert', msg + '\n')
+               prompt()
+       t.yview_pickplace('insert')
+
+def prompt():
+       t.insert('insert', app + ': ')
+       t.mark_set('promptEnd', 'insert - 1 char')
+       t.tag_add('bold', 'insert linestart', 'promptEnd')
+
+# 6. Procedure to select a new application.  Also changes
+# the prompt on the current command line to reflect the new
+# name.
+
+def newApp(appName):
+       global app
+       app = appName
+       t.delete('promptEnd linestart', 'promptEnd')
+       t.insert('promptEnd', appName + ':')
+       t.tag_add('bold', 'promptEnd linestart', 'promptEnd')
+
+newApp_tcl = `id(newApp)`
+tk.createcommand(newApp_tcl, newApp)
+
+def fillAppsMenu():
+       file_m_apps.add('command')
+       file_m_apps.delete(0, 'last')
+       names = tk.splitlist(tk.call('winfo', 'interps'))
+       names = map(None, names) # convert tuple to list
+       names.sort()
+       for name in names:
+               file_m_apps.add('command', {'label': name,
+                                           'command': (newApp_tcl, name)})
+
+file_m_apps['postcommand'] = fillAppsMenu
+mBar.tk_menuBar(file)
+
+# 7. Miscellaneous initialization.
+
+app = tk.call('winfo', 'name', '.')
+prompt()
+tk.call('focus', t)
+
+root.mainloop()
diff --git a/Demo/tkinter/guido/tst.py b/Demo/tkinter/guido/tst.py
new file mode 100755 (executable)
index 0000000..ea573d2
--- /dev/null
@@ -0,0 +1,81 @@
+# tst.py
+from Tkinter import *
+import sys
+
+def do_hello():
+       print 'Hello world!'
+
+class Quit(Button):
+       def action(self):
+               self.quit()
+       def __init__(self, master=None, cnf={}):
+               Button.__init__(self, master, 
+                               {'text': 'Quit', 
+                                'command': self.action})
+               Button.config(self, cnf)
+
+class Stuff(Canvas):
+       def enter(self, e):
+               print 'Enter'
+               self.itemconfig('current', {'fill': 'red'})
+       def leave(self, e):
+               print 'Leave'
+               self.itemconfig('current', {'fill': 'blue'})
+       def __init__(self, master=None, cnf={}):
+               Canvas.__init__(self, master, 
+                               {'width': 100, 'height': 100})
+               Canvas.config(self, cnf)
+               self.create_rectangle(30, 30, 70, 70, 
+                                     {'fill': 'red', 'tags': 'box'})
+               Canvas.bind(self, 'box', '<Enter>', self.enter)
+               Canvas.bind(self, 'box', '<Leave>', self.leave)
+
+class Test(Frame):
+       text = 'Testing'
+       num = 1
+       def do_xy(self, e):
+               print (e.x, e.y)
+       def do_test(self):
+               if not self.num % 10:
+                       self.text = 'Testing 1 ...'
+               self.text = self.text + ' ' + `self.num`
+               self.num = self.num + 1
+               self.testing['text'] = self.text
+       def do_err(self):
+               1/0
+       def do_after(self):
+               self.testing.invoke()
+               self.after(10000, self.do_after)
+       def __init__(self, master=None):
+               Frame.__init__(self, master)
+               self['bd'] = 30
+               Pack.config(self)
+               self.bind('<Motion>', self.do_xy)
+               self.hello = Button(self, {'name': 'hello', 
+                                          'text': 'Hello', 
+                                          'command': do_hello,
+                                          Pack: {'fill': 'both'}})
+               self.testing = Button(self)
+               self.testing['text'] = self.text
+               self.testing['command'] = self.do_test
+               Pack.config(self.testing, {'fill': 'both'})
+               self.err = Button(self, {'text': 'Error', 
+                                        'command': self.do_err,
+                                        Pack: {'fill': 'both'}})
+               self.quit = Quit(self, {Pack: {'fill': 'both'}})
+               self.exit = Button(self, 
+                                  {'text': 'Exit', 
+                                   'command': lambda: sys.exit(0),
+                                   Pack: {'fill': 'both'}})
+               self.stuff = Stuff(self, {Pack: {'padx': 2, 'pady': 2}})
+               self.do_after()
+
+test = Test()
+test.master.title('Tkinter Test')
+test.master.iconname('Test')
+test.master.maxsize(500, 500)
+test.testing.invoke()
+
+# Use the -i option and type ^C to get a prompt
+test.mainloop()
+
diff --git a/Demo/tkinter/guido/wish.py b/Demo/tkinter/guido/wish.py
new file mode 100755 (executable)
index 0000000..16cacde
--- /dev/null
@@ -0,0 +1,26 @@
+# This is about all it requires to write a wish shell in Python!
+
+import tkinter
+
+tk = tkinter.create(':0', 'wish', 'Tk', 1)
+tk.call('update')
+
+cmd = ''
+
+while 1:
+       if cmd: prompt = ''
+       else: prompt = '% '
+       try:
+               line = raw_input(prompt)
+       except EOFError:
+               break
+       cmd = cmd + (line + '\n')
+       tk.record(line)
+       if tk.getboolean(tk.call('info', 'complete', cmd)):
+               try:
+                       result = tk.call('eval', cmd)
+               except tkinter.TclError, msg:
+                       print 'TclError:', msg
+               else:
+                       if result: print result
+               cmd = ''
diff --git a/Lib/lib-tk/Canvas.py b/Lib/lib-tk/Canvas.py
new file mode 100644 (file)
index 0000000..4d21928
--- /dev/null
@@ -0,0 +1,115 @@
+# This module exports classes for the various canvas item types
+
+# vi:set tabsize=4:
+
+from Tkinter import Canvas, _isfunctype
+
+class CanvasItem:
+       def __init__(self, canvas, itemType, args = (), cnf={}):
+               self.canvas = canvas
+               self.id = canvas._create(itemType, args + (cnf,))
+       def __str__(self):
+               return str(self.id)
+       def __repr__(self):
+               return '<%s, id=%d>' % (self.__class__.__name__, self.id)
+       def __del__(self):
+               self.canvas.delete(self.id)
+       delete = __del__
+       def __getitem__(self, key):
+               v = self.canvas.tk.split(self.canvas.tk.call(self.canvas.pathName, 
+                                                            'itemconfigure',
+                                                            str(self.id),
+                                                            '-' + key))
+               return v[4]
+       def __setitem__(self, key, value):
+               self.canvas._itemconfig(self.id, {key: value})
+       def keys(self):
+               if not hasattr(self, '_keys'):
+                       self._keys = map(lambda x, tk=self.canvas.tk:
+                                                               tk.splitlist(x)[0][1:],
+                                                        self.canvas._splitlist(
+                                                                self.canvas.cmd('itemconfigure', self.id)))
+                       return self._keys
+       def has_key(self, key):
+               return key in self.keys()
+       def addtag(self, tag, option='withtag'):
+               self.canvas.addtag(tag, option, self.id)
+       def bbox(self):
+               x1, y1, x2, y2 = self.canvas.bbox(self.id)
+               return (x1, y1), (x2, y2)
+       def bind(self, sequence=None, command=None):
+               return self.canvas.bind(self.id, sequence, command)
+       def coords(self, pts = ()):
+               flat = ()
+               for x, y in pts: flat = flat + (x, y)
+               return apply(self.canvas.coords, (self.id,) + flat)
+       def dchars(self, first, last=None):
+               self.canvas.dchars(self.id, first, last)
+       def dtag(self, ttd):
+               self.canvas.dtag(self.id, ttd)
+       def focus(self):
+               self.canvas.focus(self.id)
+       def gettags(self):
+               return self.canvas.gettags(self.id)
+       def icursor(self):
+               self.canvas.icursor(self.id)
+       def index(self):
+               return self.canvas.index(self.id)
+       def insert(self, beforethis, string):
+               self.canvas.insert(self.id, beforethis, string)
+       def lower(self, belowthis=None):
+               self.canvas.lower(self.id, belowthis)
+       def move(self, xamount, yamount):
+               self.canvas.move(self.id, xamount, yamount)
+       def raise_(self, abovethis=None):
+               self.canvas.raise_(self.id, abovethis)
+       def scale(self, xorigin, yorigin, xscale, yscale):
+               self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale)
+       def type(self):
+               return self.canvas.type(self.id)
+
+class Arc(CanvasItem):
+       def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+               CanvasItem.__init__(self, canvas, 'arc',
+                                                       (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Bitmap(CanvasItem):
+       def __init__(self, canvas, (x1, y1), cnf={}):
+               CanvasItem.__init__(self, canvas, 'bitmap', (str(x1), str(y1)), cnf)
+
+class Line(CanvasItem):
+       def __init__(self, canvas, pts, cnf={}):
+               pts = reduce(lambda a, b: a+b,
+                                        map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+               CanvasItem.__init__(self, canvas, 'line', pts, cnf)
+
+class Oval(CanvasItem):
+       def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+               CanvasItem.__init__(self, canvas, 'oval',
+                                                       (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Polygon(CanvasItem):
+       def __init__(self, canvas, pts, cnf={}):
+               pts = reduce(lambda a, b: a+b,
+                                        map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+               CanvasItem.__init__(self, canvas, 'polygon', pts, cnf)
+
+class Curve(Polygon):
+       def __init__(self, canvas, pts, cnf={}):
+               cnf['smooth'] = 'yes'
+               Polygon.__init__(self, canvas, pts, cnf)
+
+class Rectangle(CanvasItem):
+       def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+               CanvasItem.__init__(self, canvas, 'rectangle',
+                                                       (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+# XXX Can't use name "Text" since that is already taken by the Text widget...
+class String(CanvasItem):
+       def __init__(self, canvas, (x1, y1), cnf={}):
+               CanvasItem.__init__(self, canvas, 'text', (str(x1), str(y1)), cnf)
+
+class Window(CanvasItem):
+       def __init__(self, canvas, where, cnf={}):
+               CanvasItem.__init__(self, canvas, 'window',
+                                                       (str(where[0]), str(where[1])), cnf)
diff --git a/Lib/lib-tk/ScrolledText.py b/Lib/lib-tk/ScrolledText.py
new file mode 100644 (file)
index 0000000..9effae0
--- /dev/null
@@ -0,0 +1,35 @@
+# A ScrolledText widget feels like a text widget but also has a
+# vertical scroll bar on its right.  (Later, options may be added to
+# add a horizontal bar as well, to make the bars disappear
+# automatically when not needed, to move them to the other side of the
+# window, etc.)
+#
+# Configuration options are passed to the Text widget.
+# A Frame widget is inserted between the master and the text, to hold
+# the Scrollbar widget.
+# Most methods calls are passed to the Text widget; the pack command
+# is redirected to the Frame widget however.
+
+from Tkinter import *
+
+class ScrolledText(Pack, Place):
+       def __init__(self, master=None, cnf={}):
+               fcnf = {}
+               self.frame = Frame(master, {})
+               if cnf.has_key(Pack):
+                       self.frame.pack(cnf[Pack])
+                       del cnf[Pack]
+               self.vbar = Scrollbar(self.frame, {})
+               self.vbar.pack({'side': 'right', 'fill': 'y'})
+               cnf[Pack] = {'side': 'left', 'fill': 'both',
+                            'expand': 'yes'}
+               self.text = Text(self.frame, cnf)
+               self.text['yscrollcommand'] = (self.vbar, 'set')
+               self.vbar['command'] = (self.text, 'yview')
+               self.insert = self.text.insert
+               # XXX should do all Text methods...
+               self.pack = self.frame.pack
+               self.forget = self.frame.forget
+               self.tk = master.tk
+       def __str__(self):
+               return str(self.frame)
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
new file mode 100644 (file)
index 0000000..e9e641c
--- /dev/null
@@ -0,0 +1,874 @@
+# Tkinter.py -- Tk/Tcl widget wrappers
+import tkinter
+from tkinter import TclError
+
+class _Dummy:
+       def meth(self): return
+
+def _isfunctype(func):
+       return type(func) in (type(_Dummy.meth), type(_isfunctype))     
+
+FunctionType = type(_isfunctype)
+ClassType = type(_Dummy)
+MethodType = type(_Dummy.meth)
+
+def tkerror(err):
+       pass
+
+class Event:
+       pass
+
+class Misc:
+       def tk_strictMotif(self, boolean=None):
+               self.tk.getboolean(self.tk.call(
+                       'set', 'tk_strictMotif', boolean))
+       def waitvar(self, name='VAR'):
+               self.tk.call('tkwait', 'variable', name)
+       def setvar(self, name='VAR', value='1'):
+               self.tk.setvar(name, value)
+       def focus(self):
+               self.tk.call('focus', self._w)
+       def focus_default(self):
+               self.tk.call('focus', 'default', self._w)
+       def focus_none(self):
+               self.tk.call('focus', 'none')
+       #XXX focus_get?
+       def after(self, ms, func=None, *args):
+               if not func:
+                       self.tk.call('after', ms)
+               else:
+                       name = self._register(func)
+                       apply(self.tk.call, ('after', ms, name) + args)
+       #XXX grab_current
+       def grab_release(self):
+               self.tk.call('grab', 'release', self._w)
+       def grab_set(self):
+               self.tk.call('grab', 'set', self._w)
+       def grab_set_global(self):
+               self.tk.call('grab', 'set', '-global', self._w)
+       def grab_status(self):
+               self.tk.call('grab', 'status', self._w)
+       def lower(self, belowThis=None):
+               self.tk.call('lower', self._w, belowThis)
+       def selection_clear(self):
+               self.tk.call('selection', 'clear', self._w)
+       def selection_get(self, type=None):
+               self.tk.call('selection', 'get', type)
+       def selection_handle(self, func, type=None, format=None):
+               name = self._register(func)
+               self.tk.call('selection', 'handle',
+                            self._w, name, type, format)
+       #XXX def selection_own(self):
+       #       self.tk.call('selection', 'own', self._w)
+       def send(self, interp, cmd, *args): #XXX
+               return apply(self.tk.call, ('send', interp, cmd) + args)
+       def colormodel(self, value=None):
+               return self.tk.call('tk', 'colormodel', self._w, value)
+       def winfo_atom(self, name):
+               return self.tk.getint(self.tk.call('winfo', 'atom', name))
+       def winfo_atomname(self, id):
+               return self.tk.call('winfo', 'atomname', id)
+       def winfo_cells(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'cells', self._w))
+       #XXX winfo_children
+       def winfo_class(self):
+               return self.tk.call('winfo', 'class', self._w)
+       def winfo_containing(self, rootX, rootY):
+               return self.tk.call('winfo', 'containing', rootx, rootY)
+       def winfo_depth(self):
+               return self.tk.getint(self.tk.call('winfo', 'depth', self._w))
+       def winfo_exists(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'exists', self._w))
+       def winfo_fpixels(self, number):
+               return self.tk.getdouble(self.tk.call(
+                       'winfo', 'fpixels', self._w, number))
+       def winfo_geometry(self):
+               return self.tk.call('winfo', 'geometry', self._w)
+       def winfo_height(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'height', self._w))
+       def winfo_id(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'id', self._w))
+       def winfo_interps(self):
+               return self.tk.splitlist(
+                       self.tk.call('winfo', 'interps'))
+       def winfo_ismapped(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'ismapped', self._w))
+       def winfo_name(self):
+               return self.tk.call('winfo', 'name', self._w)
+       def winfo_parent(self):
+               return self.tk.call('winfo', 'parent', self._w)
+       def winfo_pathname(self, id):
+               return self.tk.call('winfo', 'pathname', id)
+       def winfo_pixels(self, number):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'pixels', self._w, number))
+       def winfo_reqheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'reqheight', self._w))
+       def winfo_reqwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'reqwidth', self._w))
+       def winfo_rgb(self, color):
+               return self._getints(
+                       self.tk.call('winfo', 'rgb', self._w, color))
+       def winfo_rootx(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'rootx', self._w))
+       def winfo_rooty(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'rooty', self._w))
+       def winfo_screen(self):
+               return self.tk.call('winfo', 'screen', self._w)
+       def winfo_screencells(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screencells', self._w))
+       def winfo_screendepth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screendepth', self._w))
+       def winfo_screenheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenheight', self._w))
+       def winfo_screenmmheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenmmheight', self._w))
+       def winfo_screenmmwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenmmwidth', self._w))
+       def winfo_screenvisual(self):
+               return self.tk.call('winfo', 'screenvisual', self._w)
+       def winfo_screenwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenwidth', self._w))
+       def winfo_toplevel(self):
+               return self.tk.call('winfo', 'toplevel', self._w)
+       def winfo_visual(self):
+               return self.tk.call('winfo', 'visual', self._w)
+       def winfo_vrootheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrootheight', self._w))
+       def winfo_vrootwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrootwidth', self._w))
+       def winfo_vrootx(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrootx', self._w))
+       def winfo_vrooty(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrooty', self._w))
+       def winfo_width(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'width', self._w))
+       def winfo_x(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'x', self._w))
+       def winfo_y(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'y', self._w))
+       def update(self):
+               self.tk.call('update')
+       def update_idletasks(self):
+               self.tk.call('update', 'idletasks')
+       def bind(self, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add = '+'
+               name = self._register(func, _substitute)
+               self.tk.call('bind', self._w, sequence, 
+                            (add + name,) + _subst_prefix)
+       def bind_all(self, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add = '+'
+               name = self._register(func, _substitute)
+               self.tk.call('bind', 'all' , sequence, 
+                            (add + `name`,) + _subst_prefix)
+       def bind_class(self, className, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add = '+'
+               name = self._register(func, _substitute)
+               self.tk.call('bind', className , sequence, 
+                            (add + name,) + _subst_prefix)
+       def mainloop(self):
+               self.tk.mainloop()
+       def quit(self):
+               self.tk.quit()
+       # Utilities
+       def _getints(self, string):
+               if string:
+                       res = ()
+                       for v in self.tk.split(string):
+                               res = res +  (self.tk.getint(v),)
+                       return res
+               else:
+                       return string
+       def _getboolean(self, string):
+               if string:
+                       return self.tk.getboolean(string)
+               else:
+                       return string
+       def _options(self, cnf):
+               res = ()
+               for k, v in cnf.items():
+                       if _isfunctype(v):
+                               v = self._register(v)
+                       res = res + ('-'+k, v)
+               return res
+       def _register(self, func, subst=None):
+               f = func
+               f = _CallSafely(func, subst).__call__
+               name = `id(f)`
+               if hasattr(func, 'im_func'):
+                       func = func.im_func
+               if hasattr(func, 'func_name') and \
+                  type(func.func_name) == type(''):
+                       name = name + func.func_name
+               self.tk.createcommand(name, f)
+               return name
+
+_subst_prefix = ('%#', '%b', '%f', '%h', '%k', 
+                '%s', '%t', '%w', '%x', '%y',
+                '%A', '%E', '%K', '%N', '%T', '%X', '%Y')
+
+def _substitute(*args):
+       global default_root
+       global _subst_prefix
+       tk = default_root.tk
+       if len(args) != len(_subst_prefix): return args
+       nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, T, X, Y = args
+       # Missing: (a, c, d, m, o, v, B, R, W)
+       #XXX Convert %W (_w) to class instance?
+       e = Event()
+       e.serial = tk.getint(nsign)
+       e.num = tk.getint(b)
+       try: e.focus = tk.getboolean(f)
+       except TclError: pass
+       e.height = tk.getint(h)
+       e.keycode = tk.getint(k)
+       e.state = tk.getint(s)
+       e.time = tk.getint(t)
+       e.width = tk.getint(w)
+       e.x = tk.getint(x)
+       e.y = tk.getint(y)
+       e.char = A
+       try: e.send_event = tk.getboolean(E)
+       except TclError: pass
+       e.keysym = K
+       e.keysym_num = tk.getint(N)
+       e.type = T
+       #XXX %W stuff
+       e.x_root = tk.getint(X)
+       e.y_root = tk.getint(Y)
+       return (e,)
+
+class _CallSafely:
+       def __init__(self, func, subst=None):
+               self.func = func
+               self.subst = subst
+       def __call__(self, *args):
+               if self.subst:
+                       args = self.apply_func(self.subst, args)
+               args = self.apply_func(self.func, args)
+       def apply_func(self, func, args):
+               import sys
+               try:
+                       return apply(func, args)
+               except:
+                       try:
+                               try:
+                                       t = sys.exc_traceback
+                                       while t:
+                                               sys.stderr.write(
+                                                       '  %s, line %s\n' %
+                                                       (t.tb_frame.f_code,
+                                                        t.tb_lineno))
+                                               t = t.tb_next
+                               finally:
+                                       sys.stderr.write('%s: %s\n' %
+                                                        (sys.exc_type,
+                                                         sys.exc_value))
+                       except:
+                               print '*** Error in error handling ***'
+                               print sys.exc_type, ':', sys.exc_value
+
+class Wm:
+       def aspect(self, 
+                  minNumer=None, minDenom=None, 
+                  maxNumer=None, maxDenom=None):
+               return self._getints(
+                       self.tk.call('wm', 'aspect', self._w, 
+                                    minNumer, minDenom, 
+                                    maxNumer, maxDenom))
+       def client(self, name=None):
+               return self.tk.call('wm', 'client', self._w, name)
+       def command(self, value=None):
+               return self.tk.call('wm', 'command', self._w, value)
+       def deiconify(self):
+               return self.tk.call('wm', 'deiconify', self._w)
+       def focusmodel(self, model=None):
+               return self.tk.call('wm', 'focusmodel', self._w, model)
+       def frame(self):
+               return self.tk.call('wm', 'frame', self._w)
+       def geometry(self, newGeometry=None):
+               return self.tk.call('wm', 'geometry', self._w, newGeometry)
+       def grid(self,
+                baseWidht=None, baseHeight=None, 
+                widthInc=None, heightInc=None):
+               return self._getints(self.tk.call(
+                       'wm', 'grid', self._w,
+                       baseWidht, baseHeight, widthInc, heightInc))
+       def group(self, pathName=None):
+               return self.tk.call('wm', 'group', self._w, pathName)
+       def iconbitmap(self, bitmap=None):
+               return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
+       def iconify(self):
+               return self.tk.call('wm', 'iconify', self._w)
+       def iconmask(self, bitmap=None):
+               return self.tk.call('wm', 'iconmask', self._w, bitmap)
+       def iconname(self, newName=None):
+               return self.tk.call('wm', 'iconname', self._w, newName)
+       def iconposition(self, x=None, y=None):
+               return self._getints(self.tk.call(
+                       'wm', 'iconposition', self._w, x, y))
+       def iconwindow(self, pathName=None):
+               return self.tk.call('wm', 'iconwindow', self._w, pathName)
+       def maxsize(self, width=None, height=None):
+               return self._getints(self.tk.call(
+                       'wm', 'maxsize', self._w, width, height))
+       def minsize(self, width=None, height=None):
+               return self._getints(self.tk.call(
+                       'wm', 'minsize', self._w, width, height))
+       def overrideredirect(self, boolean=None):
+               return self._getboolean(self.tk.call(
+                       'wm', 'overrideredirect', self._w, boolean))
+       def positionfrom(self, who=None):
+               return self.tk.call('wm', 'positionfrom', self._w, who)
+       def protocol(self, name=None, func=None):
+               if _isfunctype(func):
+                       command = self._register(func)
+               else:
+                       command = func
+               return self.tk.call(
+                       'wm', 'protocol', self._w, name, command)
+       def sizefrom(self, who=None):
+               return self.tk.call('wm', 'sizefrom', self._w, who)
+       def state(self):
+               return self.tk.call('wm', 'state', self._w)
+       def title(self, string=None):
+               return self.tk.call('wm', 'title', self._w, string)
+       def transient(self, master=None):
+               return self.tk.call('wm', 'transient', self._w, master)
+       def withdraw(self):
+               return self.tk.call('wm', 'withdraw', self._w)
+
+class Tk(Misc, Wm):
+       _w = '.'
+       def __init__(self, screenName=None, baseName=None, className='Tk'):
+               if baseName is None:
+                       import sys, os
+                       baseName = os.path.basename(sys.argv[0])
+                       if baseName[-3:] == '.py': baseName = baseName[:-3]
+               self.tk = tkinter.create(screenName, baseName, className)
+               self.tk.createcommand('tkerror', tkerror)
+       def __del__(self):
+               self.tk.call('destroy', '.')
+       def __str__(self):
+               return '.'
+
+class Pack:
+       def config(self, cnf={}):
+               apply(self.tk.call, 
+                     ('pack', 'configure', self._w) 
+                     + self._options(cnf))
+       pack = config
+       def __setitem__(self, key, value):
+               Pack.config({key: value})
+       def forget(self):
+               self.tk.call('pack', 'forget', self._w)
+       def newinfo(self):
+               return self.tk.call('pack', 'newinfo', self._w)
+       info = newinfo
+       def propagate(self, boolean=None):
+               if boolean:
+                       self.tk.call('pack', 'propagate', self._w)
+               else:
+                       return self._getboolean(self.tk.call(
+                               'pack', 'propagate', self._w))
+       def slaves(self):
+               return self.tk.splitlist(self.tk.call(
+                       'pack', 'slaves', self._w))
+
+class Place:
+       def config(self, cnf={}):
+               apply(self.tk.call, 
+                     ('place', 'configure', self._w) 
+                     + self._options(cnf))
+       place = config
+       def __setitem__(self, key, value):
+               Place.config({key: value})
+       def forget(self):
+               self.tk.call('place', 'forget', self._w)
+       def info(self):
+               return self.tk.call('place', 'info', self._w)
+       def slaves(self):
+               return self.tk.splitlist(self.tk.call(
+                       'place', 'slaves', self._w))
+
+default_root = None
+
+class Widget(Misc, Pack, Place):
+       def __init__(self, master, widgetName, cnf={}, extra=()):
+               global default_root
+               if not master:
+                       if not default_root:
+                               default_root = Tk()
+                       master = default_root
+               if not default_root:
+                       default_root = master
+               self.master = master
+               self.tk = master.tk
+               if cnf.has_key('name'):
+                       name = cnf['name']
+                       del cnf['name']
+               else:
+                       name = `id(self)`
+               if master._w=='.':
+                       self._w = '.' + name
+               else:
+                       self._w = master._w + '.' + name
+               self.widgetName = widgetName
+               apply(self.tk.call, (widgetName, self._w) + extra)
+               Widget.config(self, cnf)
+       def config(self, cnf={}):
+               for k in cnf.keys():
+                       if type(k) == ClassType:
+                               k.config(self, cnf[k])
+                               del cnf[k]
+               apply(self.tk.call, (self._w, 'configure')
+                     + self._options(cnf))
+       def __getitem__(self, key):
+               v = self.tk.split(self.tk.call(
+                       self._w, 'configure', '-' + key))
+               return v[4]
+       def __setitem__(self, key, value):
+               Widget.config(self, {key: value})
+       def __str__(self):
+               return self._w
+       def __del__(self):
+               self.tk.call('destroy', self._w)
+       destroy = __del__
+       def _do(self, name, args=()):
+               apply(self.tk.call, (self._w, name) + args) 
+
+class Toplevel(Widget, Wm):
+       def __init__(self, master=None, cnf={}):
+               extra = ()
+               if cnf.has_key('screen'):
+                       extra = ('-screen', cnf['screen'])
+                       del cnf['screen']
+               if cnf.has_key('class'):
+                       extra = extra + ('-class', cnf['class'])
+                       del cnf['class']
+               Widget.__init__(self, master, 'toplevel', cnf, extra)
+               self.iconname(self.tk.call('wm', 'iconname', '.'))
+               self.title(self.tk.call('wm', 'title', '.'))
+
+class Button(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'button', cnf)
+       def tk_butEnter(self):
+               self.tk.call('tk_butEnter', self._w)
+       def tk_butLeave(self):
+               self.tk.call('tk_butLeave', self._w)
+       def tk_butDown(self):
+               self.tk.call('tk_butDown', self._w)
+       def tk_butUp(self):
+               self.tk.call('tk_butUp', self._w)
+       def flash(self):
+               self.tk.call(self._w, 'flash')
+       def invoke(self):
+               self.tk.call(self._w, 'invoke')
+
+# Indices:
+def AtEnd():
+       return 'end'
+def AtInsert():
+       return 'insert'
+def AtSelFirst():
+       return 'sel.first'
+def AtSelLast():
+       return 'sel.last'
+def At(x, y=None):
+       if y:
+               return '@' + `x` + ',' + `y`
+       else:
+               return '@' + `x` 
+
+class Canvas(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'canvas', cnf)
+       def addtag(self, *args):
+               self._do('addtag', args)
+       def bbox(self, *args):
+               return self._getints(self._do('bbox', args))
+       def bind(self, tagOrId, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add='+'
+               name = self._register(func, _substitute)
+               self.tk.call(self._w, 'bind', tagOrId, sequence, 
+                            (add + name,) + _subst_prefix)
+       def canvasx(self, screenx, gridspacing=None):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'canvasx', screenx, gridspacing))
+       def canvasy(self, screeny, gridspacing=None):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'canvasy', screeny, gridspacing))
+       def coords(self, *args):
+               return self._do('coords', args)
+       def _create(self, itemType, args): # Args: (value, value, ..., cnf={})
+               cnf = args[-1]
+               if type(cnf) == type({}):
+                       args = args[:-1]
+               else:
+                       cnf = {}
+               v = (self._w, 'create', itemType) + args
+               for k in cnf.keys():
+                       v = v + ('-' + k, cnf[k])
+               return self.tk.getint(apply(self.tk.call, v))
+       def create_arc(self, *args):
+               Canvas._create(self, 'arc', args)
+       def create_bitmap(self, *args):
+               Canvas._create(self, 'bitmap', args)
+       def create_line(self, *args):
+               Canvas._create(self, 'line', args)
+       def create_oval(self, *args):
+               Canvas._create(self, 'oval', args)
+       def create_polygon(self, *args):
+               Canvas._create(self, 'polygon', args)
+       def create_rectangle(self, *args):
+               Canvas._create(self, 'rectangle', args)
+       def create_text(self, *args):
+               Canvas._create(self, 'text', args)
+       def create_window(self, *args):
+               Canvas._create(self, 'window', args)
+       def dchars(self, *args):
+               self._do('dchars', args)
+       def delete(self, *args):
+               self._do('delete', args)
+       def dtag(self, *args):
+               self._do('dtag', args)
+       def find(self, *args):
+               self.tk.splitlist(self._do('find', args))
+       def focus(self, *args):
+               return self._do('focus', args)
+       def gettags(self, *args):
+               return self.tk.splitlist(self._do('gettags', args))
+       def icursor(self, *args):
+               self._do('icursor', args)
+       def index(self, *args):
+               return self.tk.getint(self._do('index', args))
+       def insert(self, *args):
+               self._do('insert', args)
+       def itemconfig(self, tagOrId, cnf={}):
+               self._do('itemconfigure', (tagOrId,) + self._options(cnf))
+       def lower(self, *args):
+               self._do('lower', args)
+       def move(self, *args):
+               self._do('move', args)
+       def postscript(self, cnf={}):
+               return self._do('postscript', self._options(cnf))
+       def tkraise(self, *args):
+               self._do('raise', args)
+       def scale(self, *args):
+               self._do('scale', args)
+       def scan_mark(self, x, y):
+               self.tk.call(self._w, 'scan', 'mark', x, y)
+       def scan_dragto(self, x, y):
+               self.tk.call(self._w, 'scan', 'dragto', x, y)
+       def select_adjust(self, tagOrId, index):
+               self.tk.call(
+                       self._w, 'select', 'adjust', tagOrId, index)
+       def select_clear(self):
+               self.tk.call(self._w, 'select', 'clear')
+       def select_from(self, tagOrId, index):
+               self.tk.call(
+                       self._w, 'select', 'from', tagOrId, index)
+       def select_item(self):
+               self.tk.call(self._w, 'select', 'item')
+       def select_to(self, tagOrId, index):
+               self.tk.call(
+                       self._w, 'select', 'to', tagOrId, index)
+       def type(self, tagOrId):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'type', tagOrId))
+       def xview(self, index):
+               self.tk.call(self._w, 'xview', index)
+       def yview(self, index):
+               self.tk.call(self._w, 'yview', index)
+
+class Checkbutton(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'checkbutton', cnf)
+       def deselect(self):
+               self.tk.call(self._w, 'deselect')
+       def flash(self):
+               self.tk.call(self._w, 'flash')
+       def invoke(self):
+               self.tk.call(self._w, 'invoke')
+       def select(self):
+               self.tk.call(self._w, 'select')
+       def toggle(self):
+               self.tk.call(self._w, 'toggle')
+
+class Entry(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'entry', cnf)
+       def tk_entryBackspace(self):
+               self.tk.call('tk_entryBackspace', self._w)
+       def tk_entryBackword(self):
+               self.tk.call('tk_entryBackword', self._w)
+       def tk_entrySeeCaret(self):
+               self.tk.call('tk_entrySeeCaret', self._w)
+       def delete(self, first, last=None):
+               self.tk.call(self._w, 'delete', first, last)
+       def get(self):
+               return self.tk.call(self._w, 'get')
+       def icursor(self, index):
+               self.tk.call(self._w, 'icursor', index)
+       def index(self, index):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'index', index))
+       def insert(self, index, string):
+               self.tk.call(self._w, 'insert', index, string)
+       def scan_mark(self, x):
+               self.tk.call(self._w, 'scan', 'mark', x)
+       def scan_dragto(self, x):
+               self.tk.call(self._w, 'scan', 'dragto', x)
+       def select_adjust(self, index):
+               self.tk.call(self._w, 'select', 'adjust', index)
+       def select_clear(self):
+               self.tk.call(self._w, 'select', 'clear')
+       def select_from(self, index):
+               self.tk.call(self._w, 'select', 'from', index)
+       def select_to(self, index):
+               self.tk.call(self._w, 'select', 'to', index)
+       def select_view(self, index):
+               self.tk.call(self._w, 'select', 'view', index)
+
+class Frame(Widget):
+       def __init__(self, master=None, cnf={}):
+               extra = ()
+               if cnf.has_key('class'):
+                       extra = ('-class', cnf['class'])
+                       del cnf['class']
+               Widget.__init__(self, master, 'frame', cnf, extra)
+       def tk_menuBar(self, *args):
+               apply(self.tk.call, ('tk_menuBar', self._w) + args)
+
+class Label(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'label', cnf)
+
+class Listbox(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'listbox', cnf)
+       def tk_listboxSingleSelect(self):
+               self.tk.call('tk_listboxSingleSelect', self._w) 
+       def curselection(self):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'curselection'))
+       def delete(self, first, last=None):
+               self.tk.call(self._w, 'delete', first, last)
+       def get(self, index):
+               return self.tk.call(self._w, 'get', index)
+       def insert(self, index, *elements):
+               apply(self.tk.call,
+                     (self._w, 'insert', index) + elements)
+       def nearest(self, y):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'nearest', y))
+       def scan_mark(self, x, y):
+               self.tk.call(self._w, 'scan', 'mark', x, y)
+       def scan_dragto(self, x, y):
+               self.tk.call(self._w, 'scan', 'dragto', x, y)
+       def select_adjust(self, index):
+               self.tk.call(self._w, 'select', 'adjust', index)
+       def select_clear(self):
+               self.tk.call(self._w, 'select', 'clear')
+       def select_from(self, index):
+               self.tk.call(self._w, 'select', 'from', index)
+       def select_to(self, index):
+               self.tk.call(self._w, 'select', 'to', index)
+       def size(self):
+               return self.tk.getint(self.tk.call(self._w, 'size'))
+       def xview(self, index):
+               self.tk.call(self._w, 'xview', index)
+       def yview(self, index):
+               self.tk.call(self._w, 'yview', index)
+
+class Menu(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'menu', cnf)
+       def tk_menuBar(self, *args):
+               apply(self.tk.call, ('tk_menuBar', self._w) + args)
+       def tk_bindForTraversal(self):
+               self.tk.call('tk_bindForTraversal', self._w)
+       def tk_mbPost(self):
+               self.tk.call('tk_mbPost', self._w)
+       def tk_mbUnpost(self):
+               self.tk.call('tk_mbUnpost')
+       def tk_traverseToMenu(self, char):
+               self.tk.call('tk_traverseToMenu', self._w, char)
+       def tk_traverseWithinMenu(self, char):
+               self.tk.call('tk_traverseWithinMenu', self._w, char)
+       def tk_getMenuButtons(self):
+               return self.tk.call('tk_getMenuButtons', self._w)
+       def tk_nextMenu(self, count):
+               self.tk.call('tk_nextMenu', count)
+       def tk_nextMenuEntry(self, count):
+               self.tk.call('tk_nextMenuEntry', count)
+       def tk_invokeMenu(self):
+               self.tk.call('tk_invokeMenu', self._w)
+       def tk_firstMenu(self):
+               self.tk.call('tk_firstMenu', self._w)
+       def tk_mbButtonDown(self):
+               self.tk.call('tk_mbButtonDown', self._w)
+       def activate(self, index):
+               self.tk.call(self._w, 'activate', index)
+       def add(self, itemType, cnf={}):
+               apply(self.tk.call, (self._w, 'add', itemType) 
+                     + self._options(cnf))
+       def delete(self, index1, index2=None):
+               self.tk.call(self._w, 'delete', index1, index2)
+       def entryconfig(self, index, cnf={}):
+               apply(self.tk.call, (self._w, 'entryconfigure', index)
+                     + self._options(cnf))
+       def index(self, index):
+               return self.tk.call(self._w, 'index', index)
+       def invoke(self, index):
+               return self.tk.call(self._w, 'invoke', index)
+       def post(self, x, y):
+               self.tk.call(self._w, 'post', x, y)
+       def unpost(self):
+               self.tk.call(self._w, 'unpost')
+       def yposition(self, index):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'yposition', index))
+
+class Menubutton(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'menubutton', cnf)
+
+class Message(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'message', cnf)
+
+class Radiobutton(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'radiobutton', cnf)
+       def deselect(self):
+               self.tk.call(self._w, 'deselect')
+       def flash(self):
+               self.tk.call(self._w, 'flash')
+       def invoke(self):
+               self.tk.call(self._w, 'invoke')
+       def select(self):
+               self.tk.call(self._w, 'select')
+
+class Scale(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'scale', cnf)
+       def get(self):
+               return self.tk.getint(self.tk.call(self._w, 'get'))
+       def set(self, value):
+               self.tk.call(self._w, 'set', value)
+
+class Scrollbar(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'scrollbar', cnf)
+       def get(self):
+               return self.tk.getints(self.tk.call(self._w, 'get'))
+       def set(self, totalUnits, windowUnits, firstUnit, lastUnit):
+               self.tk.call(self._w, 'set', 
+                            totalUnits, windowUnits, firstUnit, lastUnit)
+
+class Text(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'text', cnf)
+       def tk_textSelectTo(self, index):
+               self.tk.call('tk_textSelectTo', self._w, index)
+       def tk_textBackspace(self):
+               self.tk.call('tk_textBackspace', self._w)
+       def tk_textIndexCloser(self, a, b, c):
+               self.tk.call('tk_textIndexCloser', self._w, a, b, c)
+       def tk_textResetAnchor(self, index):
+               self.tk.call('tk_textResetAnchor', self._w, index)
+       def compare(self, index1, op, index2):
+               return self.tk.getboolean(self.tk.call(
+                       self._w, 'compare', index1, op, index2))
+       def debug(self, boolean=None):
+               return self.tk.getboolean(self.tk.call(
+                       self._w, 'debug', boolean))
+       def delete(self, index1, index2=None):
+               self.tk.call(self._w, 'delete', index1, index2)
+       def get(self, index1, index2=None):
+               return self.tk.call(self._w, 'get', index1, index2)
+       def index(self, index):
+               return self.tk.call(self._w, 'index', index)
+       def insert(self, index, chars):
+               self.tk.call(self._w, 'insert', index, chars)
+       def mark_names(self):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'mark', 'names'))
+       def mark_set(self, markName, index):
+               self.tk.call(self._w, 'mark', 'set', markName, index)
+       def mark_unset(self, markNames):
+               apply(self.tk.call, (self._w, 'mark', 'unset') + markNames)
+       def scan_mark(self, y):
+               self.tk.call(self._w, 'scan', 'mark', y)
+       def scan_dragto(self, y):
+               self.tk.call(self._w, 'scan', 'dragto', y)
+       def tag_add(self, tagName, index1, index2=None):
+               self.tk.call(
+                       self._w, 'tag', 'add', tagName, index1, index2)
+       def tag_bind(self, tagName, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add='+'
+               name = self._register(func, _substitute)
+               self.tk.call(self._w, 'tag', 'bind', 
+                            tagName, sequence, 
+                            (add + name,) + _subst_prefix)
+       def tag_config(self, tagName, cnf={}):
+               apply(self.tk.call, 
+                     (self._w, 'tag', 'configure', tagName) 
+                     + self._options(cnf))
+       def tag_delete(self, tagNames):
+               apply(self.tk.call, (self._w, 'tag', 'delete') 
+                     + tagNames)
+       def tag_lower(self, tagName, belowThis=None):
+               self.tk.call(self._w, 'tag', 'lower', 
+                            tagName, belowThis)
+       def tag_names(self, index=None):
+               return self.tk.splitlist(
+                       self.tk.call(self._w, 'tag', 'names', index))
+       def tag_nextrange(self, tagName, index1, index2=None):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'tag', 'nextrange', index1, index2))
+       def tag_raise(self, tagName, aboveThis=None):
+               self.tk.call(
+                       self._w, 'tag', 'raise', tagName, aboveThis)
+       def tag_ranges(self, tagName):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'tag', 'ranges', tagName))
+       def tag_remove(self, tagName, index1, index2=None):
+               self.tk.call(
+                       self._w, 'tag', 'remove', index1, index2)
+       def yview(self, what):
+               self.tk.call(self._w, 'yview', what)
+       def yview_pickplace(self, what):
+               self.tk.call(self._w, 'yview', '-pickplace', what)
+
+#class Dialog:
+       
diff --git a/Lib/tkinter/Canvas.py b/Lib/tkinter/Canvas.py
new file mode 100755 (executable)
index 0000000..4d21928
--- /dev/null
@@ -0,0 +1,115 @@
+# This module exports classes for the various canvas item types
+
+# vi:set tabsize=4:
+
+from Tkinter import Canvas, _isfunctype
+
+class CanvasItem:
+       def __init__(self, canvas, itemType, args = (), cnf={}):
+               self.canvas = canvas
+               self.id = canvas._create(itemType, args + (cnf,))
+       def __str__(self):
+               return str(self.id)
+       def __repr__(self):
+               return '<%s, id=%d>' % (self.__class__.__name__, self.id)
+       def __del__(self):
+               self.canvas.delete(self.id)
+       delete = __del__
+       def __getitem__(self, key):
+               v = self.canvas.tk.split(self.canvas.tk.call(self.canvas.pathName, 
+                                                            'itemconfigure',
+                                                            str(self.id),
+                                                            '-' + key))
+               return v[4]
+       def __setitem__(self, key, value):
+               self.canvas._itemconfig(self.id, {key: value})
+       def keys(self):
+               if not hasattr(self, '_keys'):
+                       self._keys = map(lambda x, tk=self.canvas.tk:
+                                                               tk.splitlist(x)[0][1:],
+                                                        self.canvas._splitlist(
+                                                                self.canvas.cmd('itemconfigure', self.id)))
+                       return self._keys
+       def has_key(self, key):
+               return key in self.keys()
+       def addtag(self, tag, option='withtag'):
+               self.canvas.addtag(tag, option, self.id)
+       def bbox(self):
+               x1, y1, x2, y2 = self.canvas.bbox(self.id)
+               return (x1, y1), (x2, y2)
+       def bind(self, sequence=None, command=None):
+               return self.canvas.bind(self.id, sequence, command)
+       def coords(self, pts = ()):
+               flat = ()
+               for x, y in pts: flat = flat + (x, y)
+               return apply(self.canvas.coords, (self.id,) + flat)
+       def dchars(self, first, last=None):
+               self.canvas.dchars(self.id, first, last)
+       def dtag(self, ttd):
+               self.canvas.dtag(self.id, ttd)
+       def focus(self):
+               self.canvas.focus(self.id)
+       def gettags(self):
+               return self.canvas.gettags(self.id)
+       def icursor(self):
+               self.canvas.icursor(self.id)
+       def index(self):
+               return self.canvas.index(self.id)
+       def insert(self, beforethis, string):
+               self.canvas.insert(self.id, beforethis, string)
+       def lower(self, belowthis=None):
+               self.canvas.lower(self.id, belowthis)
+       def move(self, xamount, yamount):
+               self.canvas.move(self.id, xamount, yamount)
+       def raise_(self, abovethis=None):
+               self.canvas.raise_(self.id, abovethis)
+       def scale(self, xorigin, yorigin, xscale, yscale):
+               self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale)
+       def type(self):
+               return self.canvas.type(self.id)
+
+class Arc(CanvasItem):
+       def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+               CanvasItem.__init__(self, canvas, 'arc',
+                                                       (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Bitmap(CanvasItem):
+       def __init__(self, canvas, (x1, y1), cnf={}):
+               CanvasItem.__init__(self, canvas, 'bitmap', (str(x1), str(y1)), cnf)
+
+class Line(CanvasItem):
+       def __init__(self, canvas, pts, cnf={}):
+               pts = reduce(lambda a, b: a+b,
+                                        map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+               CanvasItem.__init__(self, canvas, 'line', pts, cnf)
+
+class Oval(CanvasItem):
+       def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+               CanvasItem.__init__(self, canvas, 'oval',
+                                                       (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Polygon(CanvasItem):
+       def __init__(self, canvas, pts, cnf={}):
+               pts = reduce(lambda a, b: a+b,
+                                        map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+               CanvasItem.__init__(self, canvas, 'polygon', pts, cnf)
+
+class Curve(Polygon):
+       def __init__(self, canvas, pts, cnf={}):
+               cnf['smooth'] = 'yes'
+               Polygon.__init__(self, canvas, pts, cnf)
+
+class Rectangle(CanvasItem):
+       def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+               CanvasItem.__init__(self, canvas, 'rectangle',
+                                                       (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+# XXX Can't use name "Text" since that is already taken by the Text widget...
+class String(CanvasItem):
+       def __init__(self, canvas, (x1, y1), cnf={}):
+               CanvasItem.__init__(self, canvas, 'text', (str(x1), str(y1)), cnf)
+
+class Window(CanvasItem):
+       def __init__(self, canvas, where, cnf={}):
+               CanvasItem.__init__(self, canvas, 'window',
+                                                       (str(where[0]), str(where[1])), cnf)
diff --git a/Lib/tkinter/ScrolledText.py b/Lib/tkinter/ScrolledText.py
new file mode 100755 (executable)
index 0000000..9effae0
--- /dev/null
@@ -0,0 +1,35 @@
+# A ScrolledText widget feels like a text widget but also has a
+# vertical scroll bar on its right.  (Later, options may be added to
+# add a horizontal bar as well, to make the bars disappear
+# automatically when not needed, to move them to the other side of the
+# window, etc.)
+#
+# Configuration options are passed to the Text widget.
+# A Frame widget is inserted between the master and the text, to hold
+# the Scrollbar widget.
+# Most methods calls are passed to the Text widget; the pack command
+# is redirected to the Frame widget however.
+
+from Tkinter import *
+
+class ScrolledText(Pack, Place):
+       def __init__(self, master=None, cnf={}):
+               fcnf = {}
+               self.frame = Frame(master, {})
+               if cnf.has_key(Pack):
+                       self.frame.pack(cnf[Pack])
+                       del cnf[Pack]
+               self.vbar = Scrollbar(self.frame, {})
+               self.vbar.pack({'side': 'right', 'fill': 'y'})
+               cnf[Pack] = {'side': 'left', 'fill': 'both',
+                            'expand': 'yes'}
+               self.text = Text(self.frame, cnf)
+               self.text['yscrollcommand'] = (self.vbar, 'set')
+               self.vbar['command'] = (self.text, 'yview')
+               self.insert = self.text.insert
+               # XXX should do all Text methods...
+               self.pack = self.frame.pack
+               self.forget = self.frame.forget
+               self.tk = master.tk
+       def __str__(self):
+               return str(self.frame)
diff --git a/Lib/tkinter/Tkinter.py b/Lib/tkinter/Tkinter.py
new file mode 100755 (executable)
index 0000000..e9e641c
--- /dev/null
@@ -0,0 +1,874 @@
+# Tkinter.py -- Tk/Tcl widget wrappers
+import tkinter
+from tkinter import TclError
+
+class _Dummy:
+       def meth(self): return
+
+def _isfunctype(func):
+       return type(func) in (type(_Dummy.meth), type(_isfunctype))     
+
+FunctionType = type(_isfunctype)
+ClassType = type(_Dummy)
+MethodType = type(_Dummy.meth)
+
+def tkerror(err):
+       pass
+
+class Event:
+       pass
+
+class Misc:
+       def tk_strictMotif(self, boolean=None):
+               self.tk.getboolean(self.tk.call(
+                       'set', 'tk_strictMotif', boolean))
+       def waitvar(self, name='VAR'):
+               self.tk.call('tkwait', 'variable', name)
+       def setvar(self, name='VAR', value='1'):
+               self.tk.setvar(name, value)
+       def focus(self):
+               self.tk.call('focus', self._w)
+       def focus_default(self):
+               self.tk.call('focus', 'default', self._w)
+       def focus_none(self):
+               self.tk.call('focus', 'none')
+       #XXX focus_get?
+       def after(self, ms, func=None, *args):
+               if not func:
+                       self.tk.call('after', ms)
+               else:
+                       name = self._register(func)
+                       apply(self.tk.call, ('after', ms, name) + args)
+       #XXX grab_current
+       def grab_release(self):
+               self.tk.call('grab', 'release', self._w)
+       def grab_set(self):
+               self.tk.call('grab', 'set', self._w)
+       def grab_set_global(self):
+               self.tk.call('grab', 'set', '-global', self._w)
+       def grab_status(self):
+               self.tk.call('grab', 'status', self._w)
+       def lower(self, belowThis=None):
+               self.tk.call('lower', self._w, belowThis)
+       def selection_clear(self):
+               self.tk.call('selection', 'clear', self._w)
+       def selection_get(self, type=None):
+               self.tk.call('selection', 'get', type)
+       def selection_handle(self, func, type=None, format=None):
+               name = self._register(func)
+               self.tk.call('selection', 'handle',
+                            self._w, name, type, format)
+       #XXX def selection_own(self):
+       #       self.tk.call('selection', 'own', self._w)
+       def send(self, interp, cmd, *args): #XXX
+               return apply(self.tk.call, ('send', interp, cmd) + args)
+       def colormodel(self, value=None):
+               return self.tk.call('tk', 'colormodel', self._w, value)
+       def winfo_atom(self, name):
+               return self.tk.getint(self.tk.call('winfo', 'atom', name))
+       def winfo_atomname(self, id):
+               return self.tk.call('winfo', 'atomname', id)
+       def winfo_cells(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'cells', self._w))
+       #XXX winfo_children
+       def winfo_class(self):
+               return self.tk.call('winfo', 'class', self._w)
+       def winfo_containing(self, rootX, rootY):
+               return self.tk.call('winfo', 'containing', rootx, rootY)
+       def winfo_depth(self):
+               return self.tk.getint(self.tk.call('winfo', 'depth', self._w))
+       def winfo_exists(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'exists', self._w))
+       def winfo_fpixels(self, number):
+               return self.tk.getdouble(self.tk.call(
+                       'winfo', 'fpixels', self._w, number))
+       def winfo_geometry(self):
+               return self.tk.call('winfo', 'geometry', self._w)
+       def winfo_height(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'height', self._w))
+       def winfo_id(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'id', self._w))
+       def winfo_interps(self):
+               return self.tk.splitlist(
+                       self.tk.call('winfo', 'interps'))
+       def winfo_ismapped(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'ismapped', self._w))
+       def winfo_name(self):
+               return self.tk.call('winfo', 'name', self._w)
+       def winfo_parent(self):
+               return self.tk.call('winfo', 'parent', self._w)
+       def winfo_pathname(self, id):
+               return self.tk.call('winfo', 'pathname', id)
+       def winfo_pixels(self, number):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'pixels', self._w, number))
+       def winfo_reqheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'reqheight', self._w))
+       def winfo_reqwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'reqwidth', self._w))
+       def winfo_rgb(self, color):
+               return self._getints(
+                       self.tk.call('winfo', 'rgb', self._w, color))
+       def winfo_rootx(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'rootx', self._w))
+       def winfo_rooty(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'rooty', self._w))
+       def winfo_screen(self):
+               return self.tk.call('winfo', 'screen', self._w)
+       def winfo_screencells(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screencells', self._w))
+       def winfo_screendepth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screendepth', self._w))
+       def winfo_screenheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenheight', self._w))
+       def winfo_screenmmheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenmmheight', self._w))
+       def winfo_screenmmwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenmmwidth', self._w))
+       def winfo_screenvisual(self):
+               return self.tk.call('winfo', 'screenvisual', self._w)
+       def winfo_screenwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'screenwidth', self._w))
+       def winfo_toplevel(self):
+               return self.tk.call('winfo', 'toplevel', self._w)
+       def winfo_visual(self):
+               return self.tk.call('winfo', 'visual', self._w)
+       def winfo_vrootheight(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrootheight', self._w))
+       def winfo_vrootwidth(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrootwidth', self._w))
+       def winfo_vrootx(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrootx', self._w))
+       def winfo_vrooty(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'vrooty', self._w))
+       def winfo_width(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'width', self._w))
+       def winfo_x(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'x', self._w))
+       def winfo_y(self):
+               return self.tk.getint(
+                       self.tk.call('winfo', 'y', self._w))
+       def update(self):
+               self.tk.call('update')
+       def update_idletasks(self):
+               self.tk.call('update', 'idletasks')
+       def bind(self, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add = '+'
+               name = self._register(func, _substitute)
+               self.tk.call('bind', self._w, sequence, 
+                            (add + name,) + _subst_prefix)
+       def bind_all(self, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add = '+'
+               name = self._register(func, _substitute)
+               self.tk.call('bind', 'all' , sequence, 
+                            (add + `name`,) + _subst_prefix)
+       def bind_class(self, className, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add = '+'
+               name = self._register(func, _substitute)
+               self.tk.call('bind', className , sequence, 
+                            (add + name,) + _subst_prefix)
+       def mainloop(self):
+               self.tk.mainloop()
+       def quit(self):
+               self.tk.quit()
+       # Utilities
+       def _getints(self, string):
+               if string:
+                       res = ()
+                       for v in self.tk.split(string):
+                               res = res +  (self.tk.getint(v),)
+                       return res
+               else:
+                       return string
+       def _getboolean(self, string):
+               if string:
+                       return self.tk.getboolean(string)
+               else:
+                       return string
+       def _options(self, cnf):
+               res = ()
+               for k, v in cnf.items():
+                       if _isfunctype(v):
+                               v = self._register(v)
+                       res = res + ('-'+k, v)
+               return res
+       def _register(self, func, subst=None):
+               f = func
+               f = _CallSafely(func, subst).__call__
+               name = `id(f)`
+               if hasattr(func, 'im_func'):
+                       func = func.im_func
+               if hasattr(func, 'func_name') and \
+                  type(func.func_name) == type(''):
+                       name = name + func.func_name
+               self.tk.createcommand(name, f)
+               return name
+
+_subst_prefix = ('%#', '%b', '%f', '%h', '%k', 
+                '%s', '%t', '%w', '%x', '%y',
+                '%A', '%E', '%K', '%N', '%T', '%X', '%Y')
+
+def _substitute(*args):
+       global default_root
+       global _subst_prefix
+       tk = default_root.tk
+       if len(args) != len(_subst_prefix): return args
+       nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, T, X, Y = args
+       # Missing: (a, c, d, m, o, v, B, R, W)
+       #XXX Convert %W (_w) to class instance?
+       e = Event()
+       e.serial = tk.getint(nsign)
+       e.num = tk.getint(b)
+       try: e.focus = tk.getboolean(f)
+       except TclError: pass
+       e.height = tk.getint(h)
+       e.keycode = tk.getint(k)
+       e.state = tk.getint(s)
+       e.time = tk.getint(t)
+       e.width = tk.getint(w)
+       e.x = tk.getint(x)
+       e.y = tk.getint(y)
+       e.char = A
+       try: e.send_event = tk.getboolean(E)
+       except TclError: pass
+       e.keysym = K
+       e.keysym_num = tk.getint(N)
+       e.type = T
+       #XXX %W stuff
+       e.x_root = tk.getint(X)
+       e.y_root = tk.getint(Y)
+       return (e,)
+
+class _CallSafely:
+       def __init__(self, func, subst=None):
+               self.func = func
+               self.subst = subst
+       def __call__(self, *args):
+               if self.subst:
+                       args = self.apply_func(self.subst, args)
+               args = self.apply_func(self.func, args)
+       def apply_func(self, func, args):
+               import sys
+               try:
+                       return apply(func, args)
+               except:
+                       try:
+                               try:
+                                       t = sys.exc_traceback
+                                       while t:
+                                               sys.stderr.write(
+                                                       '  %s, line %s\n' %
+                                                       (t.tb_frame.f_code,
+                                                        t.tb_lineno))
+                                               t = t.tb_next
+                               finally:
+                                       sys.stderr.write('%s: %s\n' %
+                                                        (sys.exc_type,
+                                                         sys.exc_value))
+                       except:
+                               print '*** Error in error handling ***'
+                               print sys.exc_type, ':', sys.exc_value
+
+class Wm:
+       def aspect(self, 
+                  minNumer=None, minDenom=None, 
+                  maxNumer=None, maxDenom=None):
+               return self._getints(
+                       self.tk.call('wm', 'aspect', self._w, 
+                                    minNumer, minDenom, 
+                                    maxNumer, maxDenom))
+       def client(self, name=None):
+               return self.tk.call('wm', 'client', self._w, name)
+       def command(self, value=None):
+               return self.tk.call('wm', 'command', self._w, value)
+       def deiconify(self):
+               return self.tk.call('wm', 'deiconify', self._w)
+       def focusmodel(self, model=None):
+               return self.tk.call('wm', 'focusmodel', self._w, model)
+       def frame(self):
+               return self.tk.call('wm', 'frame', self._w)
+       def geometry(self, newGeometry=None):
+               return self.tk.call('wm', 'geometry', self._w, newGeometry)
+       def grid(self,
+                baseWidht=None, baseHeight=None, 
+                widthInc=None, heightInc=None):
+               return self._getints(self.tk.call(
+                       'wm', 'grid', self._w,
+                       baseWidht, baseHeight, widthInc, heightInc))
+       def group(self, pathName=None):
+               return self.tk.call('wm', 'group', self._w, pathName)
+       def iconbitmap(self, bitmap=None):
+               return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
+       def iconify(self):
+               return self.tk.call('wm', 'iconify', self._w)
+       def iconmask(self, bitmap=None):
+               return self.tk.call('wm', 'iconmask', self._w, bitmap)
+       def iconname(self, newName=None):
+               return self.tk.call('wm', 'iconname', self._w, newName)
+       def iconposition(self, x=None, y=None):
+               return self._getints(self.tk.call(
+                       'wm', 'iconposition', self._w, x, y))
+       def iconwindow(self, pathName=None):
+               return self.tk.call('wm', 'iconwindow', self._w, pathName)
+       def maxsize(self, width=None, height=None):
+               return self._getints(self.tk.call(
+                       'wm', 'maxsize', self._w, width, height))
+       def minsize(self, width=None, height=None):
+               return self._getints(self.tk.call(
+                       'wm', 'minsize', self._w, width, height))
+       def overrideredirect(self, boolean=None):
+               return self._getboolean(self.tk.call(
+                       'wm', 'overrideredirect', self._w, boolean))
+       def positionfrom(self, who=None):
+               return self.tk.call('wm', 'positionfrom', self._w, who)
+       def protocol(self, name=None, func=None):
+               if _isfunctype(func):
+                       command = self._register(func)
+               else:
+                       command = func
+               return self.tk.call(
+                       'wm', 'protocol', self._w, name, command)
+       def sizefrom(self, who=None):
+               return self.tk.call('wm', 'sizefrom', self._w, who)
+       def state(self):
+               return self.tk.call('wm', 'state', self._w)
+       def title(self, string=None):
+               return self.tk.call('wm', 'title', self._w, string)
+       def transient(self, master=None):
+               return self.tk.call('wm', 'transient', self._w, master)
+       def withdraw(self):
+               return self.tk.call('wm', 'withdraw', self._w)
+
+class Tk(Misc, Wm):
+       _w = '.'
+       def __init__(self, screenName=None, baseName=None, className='Tk'):
+               if baseName is None:
+                       import sys, os
+                       baseName = os.path.basename(sys.argv[0])
+                       if baseName[-3:] == '.py': baseName = baseName[:-3]
+               self.tk = tkinter.create(screenName, baseName, className)
+               self.tk.createcommand('tkerror', tkerror)
+       def __del__(self):
+               self.tk.call('destroy', '.')
+       def __str__(self):
+               return '.'
+
+class Pack:
+       def config(self, cnf={}):
+               apply(self.tk.call, 
+                     ('pack', 'configure', self._w) 
+                     + self._options(cnf))
+       pack = config
+       def __setitem__(self, key, value):
+               Pack.config({key: value})
+       def forget(self):
+               self.tk.call('pack', 'forget', self._w)
+       def newinfo(self):
+               return self.tk.call('pack', 'newinfo', self._w)
+       info = newinfo
+       def propagate(self, boolean=None):
+               if boolean:
+                       self.tk.call('pack', 'propagate', self._w)
+               else:
+                       return self._getboolean(self.tk.call(
+                               'pack', 'propagate', self._w))
+       def slaves(self):
+               return self.tk.splitlist(self.tk.call(
+                       'pack', 'slaves', self._w))
+
+class Place:
+       def config(self, cnf={}):
+               apply(self.tk.call, 
+                     ('place', 'configure', self._w) 
+                     + self._options(cnf))
+       place = config
+       def __setitem__(self, key, value):
+               Place.config({key: value})
+       def forget(self):
+               self.tk.call('place', 'forget', self._w)
+       def info(self):
+               return self.tk.call('place', 'info', self._w)
+       def slaves(self):
+               return self.tk.splitlist(self.tk.call(
+                       'place', 'slaves', self._w))
+
+default_root = None
+
+class Widget(Misc, Pack, Place):
+       def __init__(self, master, widgetName, cnf={}, extra=()):
+               global default_root
+               if not master:
+                       if not default_root:
+                               default_root = Tk()
+                       master = default_root
+               if not default_root:
+                       default_root = master
+               self.master = master
+               self.tk = master.tk
+               if cnf.has_key('name'):
+                       name = cnf['name']
+                       del cnf['name']
+               else:
+                       name = `id(self)`
+               if master._w=='.':
+                       self._w = '.' + name
+               else:
+                       self._w = master._w + '.' + name
+               self.widgetName = widgetName
+               apply(self.tk.call, (widgetName, self._w) + extra)
+               Widget.config(self, cnf)
+       def config(self, cnf={}):
+               for k in cnf.keys():
+                       if type(k) == ClassType:
+                               k.config(self, cnf[k])
+                               del cnf[k]
+               apply(self.tk.call, (self._w, 'configure')
+                     + self._options(cnf))
+       def __getitem__(self, key):
+               v = self.tk.split(self.tk.call(
+                       self._w, 'configure', '-' + key))
+               return v[4]
+       def __setitem__(self, key, value):
+               Widget.config(self, {key: value})
+       def __str__(self):
+               return self._w
+       def __del__(self):
+               self.tk.call('destroy', self._w)
+       destroy = __del__
+       def _do(self, name, args=()):
+               apply(self.tk.call, (self._w, name) + args) 
+
+class Toplevel(Widget, Wm):
+       def __init__(self, master=None, cnf={}):
+               extra = ()
+               if cnf.has_key('screen'):
+                       extra = ('-screen', cnf['screen'])
+                       del cnf['screen']
+               if cnf.has_key('class'):
+                       extra = extra + ('-class', cnf['class'])
+                       del cnf['class']
+               Widget.__init__(self, master, 'toplevel', cnf, extra)
+               self.iconname(self.tk.call('wm', 'iconname', '.'))
+               self.title(self.tk.call('wm', 'title', '.'))
+
+class Button(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'button', cnf)
+       def tk_butEnter(self):
+               self.tk.call('tk_butEnter', self._w)
+       def tk_butLeave(self):
+               self.tk.call('tk_butLeave', self._w)
+       def tk_butDown(self):
+               self.tk.call('tk_butDown', self._w)
+       def tk_butUp(self):
+               self.tk.call('tk_butUp', self._w)
+       def flash(self):
+               self.tk.call(self._w, 'flash')
+       def invoke(self):
+               self.tk.call(self._w, 'invoke')
+
+# Indices:
+def AtEnd():
+       return 'end'
+def AtInsert():
+       return 'insert'
+def AtSelFirst():
+       return 'sel.first'
+def AtSelLast():
+       return 'sel.last'
+def At(x, y=None):
+       if y:
+               return '@' + `x` + ',' + `y`
+       else:
+               return '@' + `x` 
+
+class Canvas(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'canvas', cnf)
+       def addtag(self, *args):
+               self._do('addtag', args)
+       def bbox(self, *args):
+               return self._getints(self._do('bbox', args))
+       def bind(self, tagOrId, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add='+'
+               name = self._register(func, _substitute)
+               self.tk.call(self._w, 'bind', tagOrId, sequence, 
+                            (add + name,) + _subst_prefix)
+       def canvasx(self, screenx, gridspacing=None):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'canvasx', screenx, gridspacing))
+       def canvasy(self, screeny, gridspacing=None):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'canvasy', screeny, gridspacing))
+       def coords(self, *args):
+               return self._do('coords', args)
+       def _create(self, itemType, args): # Args: (value, value, ..., cnf={})
+               cnf = args[-1]
+               if type(cnf) == type({}):
+                       args = args[:-1]
+               else:
+                       cnf = {}
+               v = (self._w, 'create', itemType) + args
+               for k in cnf.keys():
+                       v = v + ('-' + k, cnf[k])
+               return self.tk.getint(apply(self.tk.call, v))
+       def create_arc(self, *args):
+               Canvas._create(self, 'arc', args)
+       def create_bitmap(self, *args):
+               Canvas._create(self, 'bitmap', args)
+       def create_line(self, *args):
+               Canvas._create(self, 'line', args)
+       def create_oval(self, *args):
+               Canvas._create(self, 'oval', args)
+       def create_polygon(self, *args):
+               Canvas._create(self, 'polygon', args)
+       def create_rectangle(self, *args):
+               Canvas._create(self, 'rectangle', args)
+       def create_text(self, *args):
+               Canvas._create(self, 'text', args)
+       def create_window(self, *args):
+               Canvas._create(self, 'window', args)
+       def dchars(self, *args):
+               self._do('dchars', args)
+       def delete(self, *args):
+               self._do('delete', args)
+       def dtag(self, *args):
+               self._do('dtag', args)
+       def find(self, *args):
+               self.tk.splitlist(self._do('find', args))
+       def focus(self, *args):
+               return self._do('focus', args)
+       def gettags(self, *args):
+               return self.tk.splitlist(self._do('gettags', args))
+       def icursor(self, *args):
+               self._do('icursor', args)
+       def index(self, *args):
+               return self.tk.getint(self._do('index', args))
+       def insert(self, *args):
+               self._do('insert', args)
+       def itemconfig(self, tagOrId, cnf={}):
+               self._do('itemconfigure', (tagOrId,) + self._options(cnf))
+       def lower(self, *args):
+               self._do('lower', args)
+       def move(self, *args):
+               self._do('move', args)
+       def postscript(self, cnf={}):
+               return self._do('postscript', self._options(cnf))
+       def tkraise(self, *args):
+               self._do('raise', args)
+       def scale(self, *args):
+               self._do('scale', args)
+       def scan_mark(self, x, y):
+               self.tk.call(self._w, 'scan', 'mark', x, y)
+       def scan_dragto(self, x, y):
+               self.tk.call(self._w, 'scan', 'dragto', x, y)
+       def select_adjust(self, tagOrId, index):
+               self.tk.call(
+                       self._w, 'select', 'adjust', tagOrId, index)
+       def select_clear(self):
+               self.tk.call(self._w, 'select', 'clear')
+       def select_from(self, tagOrId, index):
+               self.tk.call(
+                       self._w, 'select', 'from', tagOrId, index)
+       def select_item(self):
+               self.tk.call(self._w, 'select', 'item')
+       def select_to(self, tagOrId, index):
+               self.tk.call(
+                       self._w, 'select', 'to', tagOrId, index)
+       def type(self, tagOrId):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'type', tagOrId))
+       def xview(self, index):
+               self.tk.call(self._w, 'xview', index)
+       def yview(self, index):
+               self.tk.call(self._w, 'yview', index)
+
+class Checkbutton(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'checkbutton', cnf)
+       def deselect(self):
+               self.tk.call(self._w, 'deselect')
+       def flash(self):
+               self.tk.call(self._w, 'flash')
+       def invoke(self):
+               self.tk.call(self._w, 'invoke')
+       def select(self):
+               self.tk.call(self._w, 'select')
+       def toggle(self):
+               self.tk.call(self._w, 'toggle')
+
+class Entry(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'entry', cnf)
+       def tk_entryBackspace(self):
+               self.tk.call('tk_entryBackspace', self._w)
+       def tk_entryBackword(self):
+               self.tk.call('tk_entryBackword', self._w)
+       def tk_entrySeeCaret(self):
+               self.tk.call('tk_entrySeeCaret', self._w)
+       def delete(self, first, last=None):
+               self.tk.call(self._w, 'delete', first, last)
+       def get(self):
+               return self.tk.call(self._w, 'get')
+       def icursor(self, index):
+               self.tk.call(self._w, 'icursor', index)
+       def index(self, index):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'index', index))
+       def insert(self, index, string):
+               self.tk.call(self._w, 'insert', index, string)
+       def scan_mark(self, x):
+               self.tk.call(self._w, 'scan', 'mark', x)
+       def scan_dragto(self, x):
+               self.tk.call(self._w, 'scan', 'dragto', x)
+       def select_adjust(self, index):
+               self.tk.call(self._w, 'select', 'adjust', index)
+       def select_clear(self):
+               self.tk.call(self._w, 'select', 'clear')
+       def select_from(self, index):
+               self.tk.call(self._w, 'select', 'from', index)
+       def select_to(self, index):
+               self.tk.call(self._w, 'select', 'to', index)
+       def select_view(self, index):
+               self.tk.call(self._w, 'select', 'view', index)
+
+class Frame(Widget):
+       def __init__(self, master=None, cnf={}):
+               extra = ()
+               if cnf.has_key('class'):
+                       extra = ('-class', cnf['class'])
+                       del cnf['class']
+               Widget.__init__(self, master, 'frame', cnf, extra)
+       def tk_menuBar(self, *args):
+               apply(self.tk.call, ('tk_menuBar', self._w) + args)
+
+class Label(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'label', cnf)
+
+class Listbox(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'listbox', cnf)
+       def tk_listboxSingleSelect(self):
+               self.tk.call('tk_listboxSingleSelect', self._w) 
+       def curselection(self):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'curselection'))
+       def delete(self, first, last=None):
+               self.tk.call(self._w, 'delete', first, last)
+       def get(self, index):
+               return self.tk.call(self._w, 'get', index)
+       def insert(self, index, *elements):
+               apply(self.tk.call,
+                     (self._w, 'insert', index) + elements)
+       def nearest(self, y):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'nearest', y))
+       def scan_mark(self, x, y):
+               self.tk.call(self._w, 'scan', 'mark', x, y)
+       def scan_dragto(self, x, y):
+               self.tk.call(self._w, 'scan', 'dragto', x, y)
+       def select_adjust(self, index):
+               self.tk.call(self._w, 'select', 'adjust', index)
+       def select_clear(self):
+               self.tk.call(self._w, 'select', 'clear')
+       def select_from(self, index):
+               self.tk.call(self._w, 'select', 'from', index)
+       def select_to(self, index):
+               self.tk.call(self._w, 'select', 'to', index)
+       def size(self):
+               return self.tk.getint(self.tk.call(self._w, 'size'))
+       def xview(self, index):
+               self.tk.call(self._w, 'xview', index)
+       def yview(self, index):
+               self.tk.call(self._w, 'yview', index)
+
+class Menu(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'menu', cnf)
+       def tk_menuBar(self, *args):
+               apply(self.tk.call, ('tk_menuBar', self._w) + args)
+       def tk_bindForTraversal(self):
+               self.tk.call('tk_bindForTraversal', self._w)
+       def tk_mbPost(self):
+               self.tk.call('tk_mbPost', self._w)
+       def tk_mbUnpost(self):
+               self.tk.call('tk_mbUnpost')
+       def tk_traverseToMenu(self, char):
+               self.tk.call('tk_traverseToMenu', self._w, char)
+       def tk_traverseWithinMenu(self, char):
+               self.tk.call('tk_traverseWithinMenu', self._w, char)
+       def tk_getMenuButtons(self):
+               return self.tk.call('tk_getMenuButtons', self._w)
+       def tk_nextMenu(self, count):
+               self.tk.call('tk_nextMenu', count)
+       def tk_nextMenuEntry(self, count):
+               self.tk.call('tk_nextMenuEntry', count)
+       def tk_invokeMenu(self):
+               self.tk.call('tk_invokeMenu', self._w)
+       def tk_firstMenu(self):
+               self.tk.call('tk_firstMenu', self._w)
+       def tk_mbButtonDown(self):
+               self.tk.call('tk_mbButtonDown', self._w)
+       def activate(self, index):
+               self.tk.call(self._w, 'activate', index)
+       def add(self, itemType, cnf={}):
+               apply(self.tk.call, (self._w, 'add', itemType) 
+                     + self._options(cnf))
+       def delete(self, index1, index2=None):
+               self.tk.call(self._w, 'delete', index1, index2)
+       def entryconfig(self, index, cnf={}):
+               apply(self.tk.call, (self._w, 'entryconfigure', index)
+                     + self._options(cnf))
+       def index(self, index):
+               return self.tk.call(self._w, 'index', index)
+       def invoke(self, index):
+               return self.tk.call(self._w, 'invoke', index)
+       def post(self, x, y):
+               self.tk.call(self._w, 'post', x, y)
+       def unpost(self):
+               self.tk.call(self._w, 'unpost')
+       def yposition(self, index):
+               return self.tk.getint(self.tk.call(
+                       self._w, 'yposition', index))
+
+class Menubutton(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'menubutton', cnf)
+
+class Message(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'message', cnf)
+
+class Radiobutton(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'radiobutton', cnf)
+       def deselect(self):
+               self.tk.call(self._w, 'deselect')
+       def flash(self):
+               self.tk.call(self._w, 'flash')
+       def invoke(self):
+               self.tk.call(self._w, 'invoke')
+       def select(self):
+               self.tk.call(self._w, 'select')
+
+class Scale(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'scale', cnf)
+       def get(self):
+               return self.tk.getint(self.tk.call(self._w, 'get'))
+       def set(self, value):
+               self.tk.call(self._w, 'set', value)
+
+class Scrollbar(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'scrollbar', cnf)
+       def get(self):
+               return self.tk.getints(self.tk.call(self._w, 'get'))
+       def set(self, totalUnits, windowUnits, firstUnit, lastUnit):
+               self.tk.call(self._w, 'set', 
+                            totalUnits, windowUnits, firstUnit, lastUnit)
+
+class Text(Widget):
+       def __init__(self, master=None, cnf={}):
+               Widget.__init__(self, master, 'text', cnf)
+       def tk_textSelectTo(self, index):
+               self.tk.call('tk_textSelectTo', self._w, index)
+       def tk_textBackspace(self):
+               self.tk.call('tk_textBackspace', self._w)
+       def tk_textIndexCloser(self, a, b, c):
+               self.tk.call('tk_textIndexCloser', self._w, a, b, c)
+       def tk_textResetAnchor(self, index):
+               self.tk.call('tk_textResetAnchor', self._w, index)
+       def compare(self, index1, op, index2):
+               return self.tk.getboolean(self.tk.call(
+                       self._w, 'compare', index1, op, index2))
+       def debug(self, boolean=None):
+               return self.tk.getboolean(self.tk.call(
+                       self._w, 'debug', boolean))
+       def delete(self, index1, index2=None):
+               self.tk.call(self._w, 'delete', index1, index2)
+       def get(self, index1, index2=None):
+               return self.tk.call(self._w, 'get', index1, index2)
+       def index(self, index):
+               return self.tk.call(self._w, 'index', index)
+       def insert(self, index, chars):
+               self.tk.call(self._w, 'insert', index, chars)
+       def mark_names(self):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'mark', 'names'))
+       def mark_set(self, markName, index):
+               self.tk.call(self._w, 'mark', 'set', markName, index)
+       def mark_unset(self, markNames):
+               apply(self.tk.call, (self._w, 'mark', 'unset') + markNames)
+       def scan_mark(self, y):
+               self.tk.call(self._w, 'scan', 'mark', y)
+       def scan_dragto(self, y):
+               self.tk.call(self._w, 'scan', 'dragto', y)
+       def tag_add(self, tagName, index1, index2=None):
+               self.tk.call(
+                       self._w, 'tag', 'add', tagName, index1, index2)
+       def tag_bind(self, tagName, sequence, func, add=''):
+               global _substitute, _subst_prefix
+               if add: add='+'
+               name = self._register(func, _substitute)
+               self.tk.call(self._w, 'tag', 'bind', 
+                            tagName, sequence, 
+                            (add + name,) + _subst_prefix)
+       def tag_config(self, tagName, cnf={}):
+               apply(self.tk.call, 
+                     (self._w, 'tag', 'configure', tagName) 
+                     + self._options(cnf))
+       def tag_delete(self, tagNames):
+               apply(self.tk.call, (self._w, 'tag', 'delete') 
+                     + tagNames)
+       def tag_lower(self, tagName, belowThis=None):
+               self.tk.call(self._w, 'tag', 'lower', 
+                            tagName, belowThis)
+       def tag_names(self, index=None):
+               return self.tk.splitlist(
+                       self.tk.call(self._w, 'tag', 'names', index))
+       def tag_nextrange(self, tagName, index1, index2=None):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'tag', 'nextrange', index1, index2))
+       def tag_raise(self, tagName, aboveThis=None):
+               self.tk.call(
+                       self._w, 'tag', 'raise', tagName, aboveThis)
+       def tag_ranges(self, tagName):
+               return self.tk.splitlist(self.tk.call(
+                       self._w, 'tag', 'ranges', tagName))
+       def tag_remove(self, tagName, index1, index2=None):
+               self.tk.call(
+                       self._w, 'tag', 'remove', index1, index2)
+       def yview(self, what):
+               self.tk.call(self._w, 'yview', what)
+       def yview_pickplace(self, what):
+               self.tk.call(self._w, 'yview', '-pickplace', what)
+
+#class Dialog:
+       
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
new file mode 100644 (file)
index 0000000..2bb7060
--- /dev/null
@@ -0,0 +1,1056 @@
+/* tkintermodule.c -- Interface to libtk.a and libtcl.a.
+   Copyright (C) 1994 Steen Lumholt */
+
+#if 0
+#include <Py/Python.h>
+#else
+
+#include "allobjects.h"
+#include "pythonrun.h"
+#include "intrcheck.h"
+#include "modsupport.h"
+#include "sysmodule.h"
+
+#define PyObject object
+typedef struct methodlist PyMethodDef;
+#define PyInit_tkinter inittkinter
+
+#undef Py_True
+#define Py_True ((object *) &TrueObject)
+#undef True
+
+#undef Py_False
+#define Py_False ((object *) &FalseObject)
+#undef False
+
+#undef Py_None
+#define Py_None (&NoObject)
+#undef None
+
+#endif /* 0 */
+
+#include <tcl.h>
+#include <tk.h>
+
+extern char *getprogramname ();
+extern int tk_NumMainWindows;
+
+/**** Tkapp Object Declaration ****/
+
+staticforward PyTypeObject Tkapp_Type;
+
+typedef struct
+  {
+    PyObject_HEAD
+    Tcl_Interp *interp;
+    Tk_Window tkwin;
+  }
+TkappObject;
+
+#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
+#define Tkapp_Tkwin(v)  (((TkappObject *) (v))->tkwin)
+#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
+#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
+
+#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
+                                (void *) v, ((PyObject *) v)->ob_refcnt))
+
+/**** Error Handling ****/
+
+static PyObject *Tkinter_TclError;
+static int errorInCmd = 0;
+static PyObject *excInCmd;
+static PyObject *valInCmd;
+
+static PyObject *
+Tkinter_Error (v)
+     PyObject *v;
+{
+  if (Tkapp_Check (v))
+    PyErr_BadInternalCall ();
+  PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
+  return NULL;
+}
+
+int
+PythonCmd_Error (interp)
+     Tcl_Interp *interp;
+{
+  errorInCmd = 1;
+  PyErr_GetAndClear (&excInCmd, &valInCmd);
+  return TCL_ERROR;
+}
+
+/**** Utils ****/
+
+static char *
+AsString (value, tmp)
+     PyObject *value;
+     PyObject *tmp;
+{
+  if (PyString_Check (value))
+    return PyString_AsString (value);
+  else
+    {
+      PyObject *v;
+
+      v = strobject (value);
+      PyList_Append (tmp, v);
+      Py_DECREF (v);
+      return PyString_AsString (v);
+    }
+}
+
+#define ARGSZ 64
+
+static char *
+Merge (args)
+     PyObject *args;
+{
+  PyObject *tmp;
+  char *argvStore[ARGSZ];
+  char **argv;
+  int fvStore[ARGSZ];
+  int *fv;
+  int argc;
+  char *res;
+  int i;
+
+  tmp = PyList_New (0);
+  argv = argvStore;
+  fv = fvStore;
+
+  if (!PyTuple_Check (args))
+    {
+      argc = 1;
+      fv[0] = 0;
+      argv[0] = AsString (args, tmp);
+    }
+  else
+    {
+      PyObject *v;
+
+      if (PyTuple_Size (args) > ARGSZ)
+       {
+         argv = malloc (PyTuple_Size (args) * sizeof (char *));
+         fv = malloc (PyTuple_Size (args) * sizeof (int));
+         if (argv == NULL || fv == NULL)
+           PyErr_NoMemory ();
+       }
+
+      argc = PyTuple_Size (args);
+      for (i = 0; i < argc; i++)
+       {
+         v = PyTuple_GetItem (args, i);
+         if (PyTuple_Check (v))
+           {
+             fv[i] = 1;
+             argv[i] = Merge (v);
+           }
+         else if (v == Py_None)
+           {
+             argc = i;
+             break;
+           }
+         else
+           {
+             fv[i] = 0;
+             argv[i] = AsString (v, tmp);
+           }
+       }
+    }
+
+  res = Tcl_Merge (argc, argv);
+
+  Py_DECREF (tmp);
+  for (i = 0; i < argc; i++)
+    if (fv[i]) free (argv[i]);
+  if (argv != argvStore)
+    free (argv);
+  if (fv != fvStore)
+    free (fv);
+
+  return res;
+}
+
+static PyObject *
+Split (self, list)
+     PyObject *self;
+     char *list;
+{
+  int argc;
+  char **argv;
+  PyObject *v;
+
+  if (list == NULL)
+    {
+      Py_INCREF (Py_None);
+      return Py_None;
+    }
+
+  if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
+    return Tkinter_Error (self);
+
+  if (argc == 0)
+    v = PyString_FromString ("");
+  else if (argc == 1)
+    v = PyString_FromString (argv[0]);
+  else
+    {
+      int i;
+
+      v = PyTuple_New (argc);
+      for (i = 0; i < argc; i++)
+       PyTuple_SetItem (v, i, Split (self, argv[i]));
+    }
+
+  free (argv);
+  return v;
+}
+
+/**** Tkapp Object ****/
+
+#ifndef WITH_APPINIT
+int
+Tcl_AppInit (interp)
+     Tcl_Interp *interp;
+{
+  if (Tcl_Init (interp) == TCL_ERROR)
+    return TCL_ERROR;
+  if (Tk_Init (interp) == TCL_ERROR)
+    return TCL_ERROR;
+  return TCL_OK;
+}
+#endif /* !WITH_APPINIT */
+
+/* Initialize the Tk application; see the `main' function in
+   `tkMain.c'.  */
+static TkappObject *
+Tkapp_New (screenName, baseName, className, interactive)
+     char *screenName;
+     char *baseName;
+     char *className;
+     int interactive;
+{
+  TkappObject *v;
+  
+  v = PyObject_NEW (TkappObject, &Tkapp_Type);
+  if (v == NULL)
+    return NULL;
+
+  v->interp = Tcl_CreateInterp ();
+  v->tkwin = Tk_CreateMainWindow (v->interp, screenName, 
+                                 baseName, className);
+  if (v->tkwin == NULL)
+    return (TkappObject *) Tkinter_Error ((PyObject *) v);
+
+  Tk_GeometryRequest (v->tkwin, 200, 200);
+
+  if (screenName != NULL)
+    Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
+
+  if (interactive)
+    Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
+  else
+    Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+#ifndef WITH_APPINIT
+  if (Tcl_AppInit (v->interp) != TCL_OK)
+    {
+      PyErr_SetString (Tkinter_TclError, "Tcl_AppInit failed"); /* XXX */
+      return NULL;
+    }
+#endif /* !WITH_APPINIT */
+
+  return v;
+}
+
+/** Tcl Eval **/
+
+static PyObject *
+Tkapp_Call (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *cmd;
+
+  cmd = Merge (args);
+  if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
+    {
+      free (cmd);
+      return Tkinter_Error (self);
+    }
+
+  free (cmd);
+  return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_GlobalCall (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *cmd;
+
+  cmd = Merge (args);
+  if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
+    {
+      free (cmd);
+      return Tkinter_Error (self);
+    }
+  
+  free (cmd);
+  return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_Eval (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *script;
+  
+  if (!PyArg_Parse (args, "s", &script))
+    return NULL;
+
+  if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
+    return Tkinter_Error (self);
+  
+  return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_GlobalEval (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *script;
+  
+  if (!PyArg_Parse (args, "s", &script))
+    return NULL;
+
+  if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
+    return Tkinter_Error (self);
+
+  return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_EvalFile (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *fileName;
+
+  if (!PyArg_Parse (args, "s", &fileName))
+    return NULL;
+
+  if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
+    return Tkinter_Error (self);
+
+  return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_Record (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *script;
+
+  if (!PyArg_Parse (args, "s", &script))
+    return NULL;
+
+  if (Tcl_RecordAndEval (Tkapp_Interp (self), 
+                        script, TCL_NO_EVAL) == TCL_ERROR)
+    return Tkinter_Error (self);
+
+  return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_AddErrorInfo (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *msg;
+
+  if (!PyArg_Parse (args, "s", &msg))
+    return NULL;
+  Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+/** Tcl Variable **/
+
+static PyObject *
+SetVar (self, args, flags)
+     PyObject *self;
+     PyObject *args;
+     int flags;
+{
+  char *name1, *name2, *ok;
+  PyObject *newValue;
+  PyObject *tmp;
+
+  tmp = PyList_New (0);
+
+  if (PyArg_Parse (args, "(sO)", &name1, &newValue))
+    ok = Tcl_SetVar (Tkapp_Interp (self), name1, 
+                    AsString (newValue, tmp), flags); /* XXX Merge? */
+  else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
+    ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2, 
+                     AsString (newValue, tmp), flags);
+  else
+    {
+      Py_DECREF (tmp);
+      return NULL;
+    }
+  Py_DECREF (tmp);
+
+  if (!ok)
+    return Tkinter_Error (self);
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
+Tkapp_SetVar (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  return SetVar (self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalSetVar (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+static PyObject *
+GetVar (self, args, flags)
+     PyObject *self;
+     PyObject *args;
+     int flags;
+{
+  char *name1, *name2, *s;
+
+  if (PyArg_Parse (args, "s", &name1))
+    s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
+  else if (PyArg_Parse (args, "(ss)", &name1, &name2))
+    s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
+  else
+    return NULL;
+
+  if (s == NULL)
+    return Tkinter_Error (self);
+
+  return PyString_FromString (s);
+}
+
+static PyObject *
+Tkapp_GetVar (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  return GetVar (self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalGetVar (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+static PyObject *
+UnsetVar (self, args, flags)
+     PyObject *self;
+     PyObject *args;
+     int flags;
+{
+  char *name1, *name2;
+  int code;
+
+  if (PyArg_Parse (args, "s", &name1))
+    code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
+  else if (PyArg_Parse (args, "(ss)", &name1, &name2))
+    code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
+  else
+    return NULL;
+
+  if (code == TCL_ERROR)
+    return Tkinter_Error (self);
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
+Tkapp_UnsetVar (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalUnsetVar (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+/** Tcl to Python **/
+
+static PyObject *
+Tkapp_GetInt (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  int v;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("i", v);
+}
+
+static PyObject *
+Tkapp_GetDouble (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  double v;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("d", v);
+}
+
+static PyObject *
+Tkapp_GetBoolean (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  int v;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("i", v);
+}
+
+static PyObject *
+Tkapp_ExprString (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("s", Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_ExprLong (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  long v;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("l", v);
+}
+
+static PyObject *
+Tkapp_ExprDouble (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  double v;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("d", v);
+}
+
+static PyObject *
+Tkapp_ExprBoolean (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  int v;
+
+  if (!PyArg_Parse (args, "s", &s))
+    return NULL;
+  if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+    return Tkinter_Error (self);
+  return Py_BuildValue ("i", v);
+}
+
+static PyObject *
+Tkapp_SplitList (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *list;
+  int argc;
+  char **argv;
+  PyObject *v;
+  int i;
+
+  if (!PyArg_Parse (args, "s", &list))
+    return NULL;
+
+  if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
+    return Tkinter_Error (self);
+
+  v = PyTuple_New (argc);
+  for (i = 0; i < argc; i++)
+    PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
+
+  free (argv);
+  return v;
+}
+
+static PyObject *
+Tkapp_Split (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *list;
+
+  if (!PyArg_Parse (args, "s", &list))
+    return NULL;
+  return Split (self, list);
+}
+
+static PyObject *
+Tkapp_Merge (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *s;
+  PyObject *v;
+
+  s = Merge (args);
+  v = PyString_FromString (s);
+  free (s);
+  return v;
+}
+
+/** Tcl Command **/
+
+/* This is the Tcl command that acts as a wrapper for Python
+   function or method.  */
+static int
+PythonCmd (clientData, interp, argc, argv)
+     ClientData clientData;    /* Is (self, func) */
+     Tcl_Interp *interp;
+     int argc;
+     char *argv[];
+{
+  PyObject *self, *func, *arg, *res, *tmp;
+  int i;
+
+  self = PyTuple_GetItem ((PyObject *) clientData, 0);
+  func = PyTuple_GetItem ((PyObject *) clientData, 1);
+
+  /* Create argument list (argv1, ..., argvN) */
+  arg = PyTuple_New (argc - 1);
+  for (i = 0; i < (argc - 1); i++)
+    PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
+  
+  res = PyEval_CallObject (func, arg);
+  Py_DECREF (arg);
+  if (res == NULL)
+    return PythonCmd_Error (interp);
+
+  tmp = PyList_New (0);
+  Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
+  Py_DECREF (res);
+  Py_DECREF (tmp);
+
+  return TCL_OK;
+}
+
+static void
+PythonCmdDelete (clientData)
+     ClientData clientData;    /* Is (self, func) */
+{
+  Py_DECREF ((PyObject *) clientData);
+}
+
+static PyObject *
+Tkapp_CreateCommand (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *cmdName;
+  PyObject *data;
+  PyObject *func;
+  
+  /* Args is: (cmdName, func) */
+  if (!PyTuple_Check (args) 
+      || !(PyTuple_Size (args) == 2)
+      || !PyString_Check (PyTuple_GetItem (args, 0))
+      || !(PyMethod_Check (PyTuple_GetItem (args, 1)) 
+          || PyFunction_Check (PyTuple_GetItem (args, 1))))
+    {
+      PyErr_SetString (PyExc_TypeError, "bad argument list");
+      return NULL;
+    }
+
+  cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
+  func = PyTuple_GetItem (args, 1);
+
+  data = PyTuple_New (2);   /* ClientData is: (self, func) */
+
+  Py_INCREF (self);
+  PyTuple_SetItem (data, 0, self);
+
+  Py_INCREF (func);
+  PyTuple_SetItem (data, 1, func);
+
+  Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
+                    (ClientData) data, PythonCmdDelete);
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteCommand (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *cmdName;
+
+  if (!PyArg_Parse (args, "s", &cmdName))
+    return NULL;
+  if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
+    {
+      PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
+      return NULL;
+    }
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+/** File Handler **/
+
+void
+FileHandler (clientData, mask)
+     ClientData clientData;    /* Is: func */
+     int mask;
+{
+  PyObject *func;
+  PyObject *arg, *res;
+
+  func = (PyObject *) clientData;
+
+  arg = PyInt_FromLong ((long) mask);
+  res = PyEval_CallObject (func, arg);
+  Py_DECREF (arg);
+  if (res == NULL)
+    {
+      errorInCmd = 1;
+      PyErr_GetAndClear (&excInCmd, &valInCmd);
+    }
+}
+
+static PyObject *
+Tkapp_CreateFileHandler (self, args)
+     PyObject *self;
+     PyObject *args;           /* Is (file, mask, func) */
+{
+  PyObject *file;
+  int mask;
+  PyObject *func;
+  int id;
+
+  if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
+    return NULL;
+  if (!PyFile_Check (file) 
+      || !(PyMethod_Check(func) || PyFunction_Check(func)))
+    {
+      PyErr_SetString (PyExc_TypeError, "bad argument list");
+      return NULL;
+    }
+
+  id = fileno (PyFile_AsFile (file));
+  Py_DECREF (file);
+  Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) func);
+  /* XXX fileHandlerDict */
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteFileHandler (self, args)
+     PyObject *self;
+     PyObject *args;           /* Args: file */
+{
+  int id;
+
+  if (!PyFile_Check (args))
+    {
+      PyErr_SetString (PyExc_TypeError, "bad argument list");
+      return NULL;
+    }
+
+  id = fileno (PyFile_AsFile (args));
+  Tk_DeleteFileHandler (id);
+  /* XXX fileHandlerDict */
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+/** Event Loop **/
+
+static int quitMainLoop;
+
+static PyObject *
+Tkapp_MainLoop (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  if (!PyArg_Parse (args, ""))
+    return NULL;
+
+  quitMainLoop = 0;
+  while (tk_NumMainWindows > 0 && !quitMainLoop && !errorInCmd)
+    {
+      if (PyOS_InterruptOccurred ())
+       {
+         PyErr_SetNone (PyExc_KeyboardInterrupt);
+         return NULL;
+       }
+      Tk_DoOneEvent (0);
+    }
+
+  if (errorInCmd)
+    {
+      errorInCmd = 0;
+      PyErr_SetObject (excInCmd, valInCmd);
+      return NULL;
+    }
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
+Tkapp_Quit (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+
+  if (!PyArg_Parse (args, ""))
+    return NULL;
+  quitMainLoop = 1;
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+/**** Tkapp Method List ****/
+
+static PyMethodDef Tkapp_methods[] =
+{
+  {"call", Tkapp_Call},
+  {"globalcall", Tkapp_GlobalCall},
+  {"eval", Tkapp_Eval},
+  {"globaleval", Tkapp_GlobalEval},
+  {"evalfile", Tkapp_EvalFile},
+  {"record", Tkapp_Record},
+  {"adderrorinfo", Tkapp_AddErrorInfo},
+  {"setvar", Tkapp_SetVar},
+  {"globalsetvar", Tkapp_GlobalSetVar},
+  {"getvar", Tkapp_GetVar},
+  {"globalgetvar", Tkapp_GlobalGetVar},
+  {"unsetvar", Tkapp_UnsetVar},
+  {"globalunsetvar", Tkapp_GlobalUnsetVar},
+  {"getint", Tkapp_GetInt},
+  {"getdouble", Tkapp_GetDouble},
+  {"getboolean", Tkapp_GetBoolean},
+  {"exprstring", Tkapp_ExprString},
+  {"exprlong", Tkapp_ExprLong},
+  {"exprdouble", Tkapp_ExprDouble},
+  {"exprboolean", Tkapp_ExprBoolean},
+  {"splitlist", Tkapp_SplitList},
+  {"split", Tkapp_Split},
+  {"merge", Tkapp_Merge},
+  {"createcommand", Tkapp_CreateCommand},
+  {"deletecommand", Tkapp_DeleteCommand},
+  {"createfilehandler", Tkapp_CreateFileHandler},
+  {"deletefilehandler", Tkapp_DeleteFileHandler},
+  {"mainloop", Tkapp_MainLoop},
+  {"quit", Tkapp_Quit},
+  {NULL, NULL}
+};
+
+/**** Tkapp Type Methods ****/
+
+static void
+Tkapp_Dealloc (self)
+     PyObject *self;
+{
+  Tk_DestroyWindow (Tkapp_Tkwin (self));
+  Tcl_DeleteInterp (Tkapp_Interp (self));
+  PyMem_DEL (self);
+}
+
+static PyObject *
+Tkapp_GetAttr (self, name)
+     PyObject *self;
+     char *name;
+{
+  return Py_FindMethod (Tkapp_methods, self, name);
+}
+
+static PyTypeObject Tkapp_Type =
+{
+  OB_HEAD_INIT (&PyType_Type)
+  0,                           /*ob_size */
+  "tkapp",                     /*tp_name */
+  sizeof (TkappObject),                /*tp_basicsize */
+  0,                           /*tp_itemsize */
+  Tkapp_Dealloc,               /*tp_dealloc */
+  0,                           /*tp_print */
+  Tkapp_GetAttr,               /*tp_getattr */
+  0,                           /*tp_setattr */
+  0,                           /*tp_compare */
+  0,                           /*tp_repr */
+  0,                           /*tp_as_number */
+  0,                           /*tp_as_sequence */
+  0,                           /*tp_as_mapping */
+  0,                           /*tp_hash */
+};
+
+/**** Tkinter Module ****/
+
+static PyObject *
+Tkinter_Create (self, args)
+     PyObject *self;
+     PyObject *args;
+{
+  char *screenName = NULL;
+  char *baseName;
+  char *className;
+  int interactive = 0;
+
+  baseName = strrchr (getprogramname (), '/');
+  if (baseName != NULL)
+    baseName++;
+  else
+    baseName = getprogramname ();
+  className = "Tk";
+  
+  if (PyArg_Parse (args, ""))
+    /* VOID */ ;
+  else if (PyArg_Parse (args, "z", 
+                       &screenName))
+    /* VOID */ ;
+  else if (PyArg_Parse (args, "(zs)", 
+                       &screenName, &baseName))
+    /* VOID */ ;
+  else if (PyArg_Parse (args, "(zss)", 
+                       &screenName, &baseName, &className))
+    /* VOID */ ;
+  else if (PyArg_Parse (args, "(zssi)", 
+                       &screenName, &baseName, &className, &interactive))
+    /* VOID */ ;
+  else
+    return NULL;
+
+  return (PyObject *) Tkapp_New (screenName, baseName, className, 
+                                interactive);
+}
+
+static PyMethodDef moduleMethods[] =
+{
+  {"create", Tkinter_Create},
+  {NULL, NULL}
+};
+
+#ifdef WITH_READLINE
+static int
+EventHook ()
+{
+  if (errorInCmd)              /* XXX Reset tty */
+    {
+      errorInCmd = 0;
+      PyErr_SetObject (excInCmd, valInCmd);
+      PyErr_Print ();
+     }
+  if (tk_NumMainWindows > 0)
+    Tk_DoOneEvent (0);
+  return 0;
+}
+#endif /* WITH_READLINE */
+
+static void
+StdinProc (clientData, mask)
+     ClientData clientData;
+     int mask;
+{
+  /* Do nothing. */
+}
+
+void
+PyInit_tkinter ()
+{
+#ifdef WITH_READLINE
+  extern int (*rl_event_hook) ();
+#endif /* WITH_READLINE */
+  PyObject *m, *d, *v;
+
+  m = Py_InitModule ("tkinter", moduleMethods);
+
+  d = PyModule_GetDict (m);
+  Tkinter_TclError = Py_BuildValue ("s", "TclError");
+  PyDict_SetItemString (d, "TclError", Tkinter_TclError);
+
+  v = Py_BuildValue ("i", TK_READABLE);
+  PyDict_SetItemString (d, "READABLE", v);
+  v = Py_BuildValue ("i", TK_WRITABLE);
+  PyDict_SetItemString (d, "WRITABLE", v);
+  v = Py_BuildValue ("i", TK_EXCEPTION);
+  PyDict_SetItemString (d, "EXCEPTION", v);
+
+  /* Unblock stdin. */
+  Tk_CreateFileHandler (0, TK_READABLE, StdinProc, (ClientData) 0);
+
+#ifdef WITH_READLINE
+  rl_event_hook = EventHook;
+#endif /* WITH_READLINE */
+
+  if (PyErr_Occurred ())
+    Py_FatalError ("can't initialize module tkinter");
+}