home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_2327 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  21.8 KB  |  698 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import sys
  5. import traceback
  6. import re
  7. from pyreadline.logger import log, log_sock
  8. from pyreadline.unicode_helper import ensure_unicode, ensure_str
  9. import pyreadline.unicode_helper as unicode_helper
  10.  
  11. try:
  12.     from ctypes import *
  13.     from _ctypes import call_function
  14. except ImportError:
  15.     raise ImportError('You need ctypes to run this code')
  16.  
  17. from pyreadline.keysyms import make_KeyPress
  18. from pyreadline.console.ansi import AnsiState, AnsiWriter
  19. STD_INPUT_HANDLE = -10
  20. STD_OUTPUT_HANDLE = -11
  21. ENABLE_WINDOW_INPUT = 8
  22. ENABLE_MOUSE_INPUT = 16
  23. ENABLE_PROCESSED_INPUT = 1
  24. WHITE = 7
  25. BLACK = 0
  26. MENU_EVENT = 8
  27. KEY_EVENT = 1
  28. MOUSE_MOVED = 1
  29. MOUSE_EVENT = 2
  30. WINDOW_BUFFER_SIZE_EVENT = 4
  31. FOCUS_EVENT = 16
  32. MENU_EVENT = 8
  33. VK_SHIFT = 16
  34. VK_CONTROL = 17
  35. VK_MENU = 18
  36. GENERIC_READ = int(0x80000000L)
  37. GENERIC_WRITE = 1073741824
  38.  
  39. class COORD(Structure):
  40.     _fields_ = [
  41.         ('X', c_short),
  42.         ('Y', c_short)]
  43.  
  44.  
  45. class SMALL_RECT(Structure):
  46.     _fields_ = [
  47.         ('Left', c_short),
  48.         ('Top', c_short),
  49.         ('Right', c_short),
  50.         ('Bottom', c_short)]
  51.  
  52.  
  53. class CONSOLE_SCREEN_BUFFER_INFO(Structure):
  54.     _fields_ = [
  55.         ('dwSize', COORD),
  56.         ('dwCursorPosition', COORD),
  57.         ('wAttributes', c_short),
  58.         ('srWindow', SMALL_RECT),
  59.         ('dwMaximumWindowSize', COORD)]
  60.  
  61.  
  62. class CHAR_UNION(Union):
  63.     _fields_ = [
  64.         ('UnicodeChar', c_wchar),
  65.         ('AsciiChar', c_char)]
  66.  
  67.  
  68. class CHAR_INFO(Structure):
  69.     _fields_ = [
  70.         ('Char', CHAR_UNION),
  71.         ('Attributes', c_short)]
  72.  
  73.  
  74. class KEY_EVENT_RECORD(Structure):
  75.     _fields_ = [
  76.         ('bKeyDown', c_byte),
  77.         ('pad2', c_byte),
  78.         ('pad1', c_short),
  79.         ('wRepeatCount', c_short),
  80.         ('wVirtualKeyCode', c_short),
  81.         ('wVirtualScanCode', c_short),
  82.         ('uChar', CHAR_UNION),
  83.         ('dwControlKeyState', c_int)]
  84.  
  85.  
  86. class MOUSE_EVENT_RECORD(Structure):
  87.     _fields_ = [
  88.         ('dwMousePosition', COORD),
  89.         ('dwButtonState', c_int),
  90.         ('dwControlKeyState', c_int),
  91.         ('dwEventFlags', c_int)]
  92.  
  93.  
  94. class WINDOW_BUFFER_SIZE_RECORD(Structure):
  95.     _fields_ = [
  96.         ('dwSize', COORD)]
  97.  
  98.  
  99. class MENU_EVENT_RECORD(Structure):
  100.     _fields_ = [
  101.         ('dwCommandId', c_uint)]
  102.  
  103.  
  104. class FOCUS_EVENT_RECORD(Structure):
  105.     _fields_ = [
  106.         ('bSetFocus', c_byte)]
  107.  
  108.  
  109. class INPUT_UNION(Union):
  110.     _fields_ = [
  111.         ('KeyEvent', KEY_EVENT_RECORD),
  112.         ('MouseEvent', MOUSE_EVENT_RECORD),
  113.         ('WindowBufferSizeEvent', WINDOW_BUFFER_SIZE_RECORD),
  114.         ('MenuEvent', MENU_EVENT_RECORD),
  115.         ('FocusEvent', FOCUS_EVENT_RECORD)]
  116.  
  117.  
  118. class INPUT_RECORD(Structure):
  119.     _fields_ = [
  120.         ('EventType', c_short),
  121.         ('Event', INPUT_UNION)]
  122.  
  123.  
  124. class CONSOLE_CURSOR_INFO(Structure):
  125.     _fields_ = [
  126.         ('dwSize', c_int),
  127.         ('bVisible', c_byte)]
  128.  
  129. funcs = [
  130.     'AllocConsole',
  131.     'CreateConsoleScreenBuffer',
  132.     'FillConsoleOutputAttribute',
  133.     'FillConsoleOutputCharacterW',
  134.     'FreeConsole',
  135.     'GetConsoleCursorInfo',
  136.     'GetConsoleMode',
  137.     'GetConsoleScreenBufferInfo',
  138.     'GetConsoleTitleW',
  139.     'GetProcAddress',
  140.     'GetStdHandle',
  141.     'PeekConsoleInputW',
  142.     'ReadConsoleInputW',
  143.     'ScrollConsoleScreenBufferW',
  144.     'SetConsoleActiveScreenBuffer',
  145.     'SetConsoleCursorInfo',
  146.     'SetConsoleCursorPosition',
  147.     'SetConsoleMode',
  148.     'SetConsoleScreenBufferSize',
  149.     'SetConsoleTextAttribute',
  150.     'SetConsoleTitleW',
  151.     'SetConsoleWindowInfo',
  152.     'WriteConsoleW',
  153.     'WriteConsoleOutputCharacterW']
  154. key_modifiers = {
  155.     VK_SHIFT: 1,
  156.     VK_CONTROL: 1,
  157.     VK_MENU: 1,
  158.     91: 1 }
  159.  
  160. class Console(object):
  161.     
  162.     def __init__(self, newbuffer = 0):
  163.         if newbuffer:
  164.             self.hout = self.CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, None, 1, None)
  165.             self.SetConsoleActiveScreenBuffer(self.hout)
  166.         else:
  167.             self.hout = self.GetStdHandle(STD_OUTPUT_HANDLE)
  168.         self.hin = self.GetStdHandle(STD_INPUT_HANDLE)
  169.         self.inmode = c_int(0)
  170.         self.GetConsoleMode(self.hin, byref(self.inmode))
  171.         self.SetConsoleMode(self.hin, 15)
  172.         info = CONSOLE_SCREEN_BUFFER_INFO()
  173.         self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  174.         self.attr = info.wAttributes
  175.         self.saveattr = info.wAttributes
  176.         self.defaultstate = AnsiState()
  177.         self.defaultstate.winattr = info.wAttributes
  178.         self.ansiwriter = AnsiWriter(self.defaultstate)
  179.         background = self.attr & 240
  180.         for escape in self.escape_to_color:
  181.             if self.escape_to_color[escape] is not None:
  182.                 self.escape_to_color[escape] |= background
  183.                 continue
  184.         
  185.         log('initial attr=%x' % self.attr)
  186.         self.softspace = 0
  187.         self.serial = 0
  188.         self.pythondll = CDLL('python%s%s' % (sys.version[0], sys.version[2]))
  189.         self.inputHookPtr = c_int.from_address(addressof(self.pythondll.PyOS_InputHook)).value
  190.         setattr(Console, 'PyMem_Malloc', self.pythondll.PyMem_Malloc)
  191.  
  192.     
  193.     def __del__(self):
  194.         self.SetConsoleTextAttribute(self.hout, self.saveattr)
  195.         self.SetConsoleMode(self.hin, self.inmode)
  196.         self.FreeConsole()
  197.  
  198.     
  199.     def _get_top_bot(self):
  200.         info = CONSOLE_SCREEN_BUFFER_INFO()
  201.         self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  202.         rect = info.srWindow
  203.         top = rect.Top
  204.         bot = rect.Bottom
  205.         return (top, bot)
  206.  
  207.     
  208.     def fixcoord(self, x, y):
  209.         if x < 0 or y < 0:
  210.             info = CONSOLE_SCREEN_BUFFER_INFO()
  211.             self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  212.             if x < 0:
  213.                 x = info.srWindow.Right - x
  214.                 y = info.srWindow.Bottom + y
  215.             
  216.         
  217.         return c_int(y << 16 | x)
  218.  
  219.     
  220.     def pos(self, x = None, y = None):
  221.         if x is None:
  222.             info = CONSOLE_SCREEN_BUFFER_INFO()
  223.             self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  224.             return (info.dwCursorPosition.X, info.dwCursorPosition.Y)
  225.         return self.SetConsoleCursorPosition(self.hout, self.fixcoord(x, y))
  226.  
  227.     
  228.     def home(self):
  229.         self.pos(0, 0)
  230.  
  231.     terminal_escape = re.compile('(\x01?\x1b\\[[0-9;]+m\x02?)')
  232.     escape_parts = re.compile('\x01?\x1b\\[([0-9;]+)m\x02?')
  233.     escape_to_color = {
  234.         '0;30': 0,
  235.         '0;31': 4,
  236.         '0;32': 2,
  237.         '0;33': 6,
  238.         '0;34': 1,
  239.         '0;35': 5,
  240.         '0;36': 6,
  241.         '0;37': 7,
  242.         '1;30': 7,
  243.         '1;31': 12,
  244.         '1;32': 10,
  245.         '1;33': 14,
  246.         '1;34': 9,
  247.         '1;35': 13,
  248.         '1;36': 11,
  249.         '1;37': 15,
  250.         '0': None }
  251.     motion_char_re = re.compile('([\n\r\t\x08\x07])')
  252.     
  253.     def write_scrolling(self, text, attr = None):
  254.         (x, y) = self.pos()
  255.         (w, h) = self.size()
  256.         scroll = 0
  257.         chunks = self.motion_char_re.split(text)
  258.         for chunk in chunks:
  259.             log('C:' + chunk)
  260.             n = self.write_color(chunk, attr)
  261.             if len(chunk) == 1:
  262.                 if chunk[0] == '\n':
  263.                     x = 0
  264.                     y += 1
  265.                 elif chunk[0] == '\r':
  266.                     x = 0
  267.                 elif chunk[0] == '\t':
  268.                     x = 8 * (int(x / 8) + 1)
  269.                     if x > w:
  270.                         x -= w
  271.                         y += 1
  272.                     
  273.                 elif chunk[0] == '\x07':
  274.                     pass
  275.                 elif chunk[0] == '\x08':
  276.                     x -= 1
  277.                     if x < 0:
  278.                         y -= 1
  279.                     
  280.                 else:
  281.                     x += 1
  282.                 if x == w:
  283.                     x = 0
  284.                     y += 1
  285.                 
  286.                 if y == h:
  287.                     scroll += 1
  288.                     y = h - 1
  289.                 
  290.             y == h
  291.             x += n
  292.             l = int(x / w)
  293.             x = x % w
  294.             y += l
  295.             if y >= h:
  296.                 scroll += (y - h) + 1
  297.                 y = h - 1
  298.                 continue
  299.         
  300.         return scroll
  301.  
  302.     
  303.     def write_color(self, text, attr = None):
  304.         log('write_color("%s", %s)' % (text, attr))
  305.         chunks = self.terminal_escape.split(text)
  306.         log('chunks=%s' % repr(chunks))
  307.         junk = c_int(0)
  308.         n = 0
  309.         for chunk in chunks:
  310.             m = self.escape_parts.match(chunk)
  311.             if m:
  312.                 attr = self.escape_to_color[m.group(1)]
  313.                 continue
  314.             
  315.             n += len(chunk)
  316.             log('attr=%s' % attr)
  317.             if attr is None:
  318.                 attr = self.attr
  319.             
  320.             self.SetConsoleTextAttribute(self.hout, attr)
  321.         
  322.         return n
  323.  
  324.     
  325.     def write_color(self, text, attr = None):
  326.         text = ensure_unicode(text)
  327.         (n, res) = self.ansiwriter.write_color(text, attr)
  328.         junk = c_int(0)
  329.         for attr, chunk in res:
  330.             log(unicode(attr))
  331.             log(unicode(chunk))
  332.             self.SetConsoleTextAttribute(self.hout, attr.winattr)
  333.             self.WriteConsoleW(self.hout, chunk, len(chunk), byref(junk), None)
  334.         
  335.         return n
  336.  
  337.     
  338.     def write_plain(self, text, attr = None):
  339.         log('write("%s", %s)' % (text, attr))
  340.         if attr is None:
  341.             attr = self.attr
  342.         
  343.         n = c_int(0)
  344.         self.SetConsoleTextAttribute(self.hout, attr)
  345.         self.WriteConsoleW(self.hout, ensure_unicode(chunk), len(chunk), byref(junk), None)
  346.         return len(text)
  347.  
  348.     
  349.     def write(self, text):
  350.         log('write("%s")' % text)
  351.         return self.write_color(text)
  352.  
  353.     
  354.     def isatty(self):
  355.         return True
  356.  
  357.     
  358.     def flush(self):
  359.         pass
  360.  
  361.     
  362.     def page(self, attr = None, fill = ' '):
  363.         if attr is None:
  364.             attr = self.attr
  365.         
  366.         if len(fill) != 1:
  367.             raise ValueError
  368.         len(fill) != 1
  369.         info = CONSOLE_SCREEN_BUFFER_INFO()
  370.         self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  371.         if info.dwCursorPosition.X != 0 or info.dwCursorPosition.Y != 0:
  372.             self.SetConsoleCursorPosition(self.hout, self.fixcoord(0, 0))
  373.         
  374.         w = info.dwSize.X
  375.         n = c_int(0)
  376.         for y in range(info.dwSize.Y):
  377.             self.FillConsoleOutputAttribute(self.hout, attr, w, self.fixcoord(0, y), byref(n))
  378.             self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]), w, self.fixcoord(0, y), byref(n))
  379.         
  380.         self.attr = attr
  381.  
  382.     
  383.     def text(self, x, y, text, attr = None):
  384.         if attr is None:
  385.             attr = self.attr
  386.         
  387.         pos = self.fixcoord(x, y)
  388.         n = c_int(0)
  389.         self.WriteConsoleOutputCharacterW(self.hout, text, len(text), pos, byref(n))
  390.         self.FillConsoleOutputAttribute(self.hout, attr, n, pos, byref(n))
  391.  
  392.     
  393.     def clear_to_end_of_window(self):
  394.         (top, bot) = self._get_top_bot()
  395.         pos = self.pos()
  396.         (w, h) = self.size()
  397.         self.rectangle((pos[0], pos[1], w, pos[1] + 1))
  398.         if pos[1] < bot:
  399.             self.rectangle((0, pos[1] + 1, w, bot + 1))
  400.         
  401.  
  402.     
  403.     def rectangle(self, rect, attr = None, fill = ' '):
  404.         (x0, y0, x1, y1) = rect
  405.         n = c_int(0)
  406.         if attr is None:
  407.             attr = self.attr
  408.         
  409.         for y in range(y0, y1):
  410.             pos = self.fixcoord(x0, y)
  411.             self.FillConsoleOutputAttribute(self.hout, attr, x1 - x0, pos, byref(n))
  412.             self.FillConsoleOutputCharacterW(self.hout, ord(fill[0]), x1 - x0, pos, byref(n))
  413.         
  414.  
  415.     
  416.     def scroll(self, rect, dx, dy, attr = None, fill = ' '):
  417.         if attr is None:
  418.             attr = self.attr
  419.         
  420.         (x0, y0, x1, y1) = rect
  421.         source = SMALL_RECT(x0, y0, x1 - 1, y1 - 1)
  422.         dest = self.fixcoord(x0 + dx, y0 + dy)
  423.         style = CHAR_INFO()
  424.         style.Char.AsciiChar = fill[0]
  425.         style.Attributes = attr
  426.         return self.ScrollConsoleScreenBufferW(self.hout, byref(source), byref(source), dest, byref(style))
  427.  
  428.     
  429.     def scroll_window(self, lines):
  430.         info = CONSOLE_SCREEN_BUFFER_INFO()
  431.         self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  432.         rect = info.srWindow
  433.         log('sw: rtop=%d rbot=%d' % (rect.Top, rect.Bottom))
  434.         top = rect.Top + lines
  435.         bot = rect.Bottom + lines
  436.         h = bot - top
  437.         maxbot = info.dwSize.Y - 1
  438.         if top < 0:
  439.             top = 0
  440.             bot = h
  441.         
  442.         if bot > maxbot:
  443.             bot = maxbot
  444.             top = bot - h
  445.         
  446.         nrect = SMALL_RECT()
  447.         nrect.Top = top
  448.         nrect.Bottom = bot
  449.         nrect.Left = rect.Left
  450.         nrect.Right = rect.Right
  451.         log('sn: top=%d bot=%d' % (top, bot))
  452.         r = self.SetConsoleWindowInfo(self.hout, True, byref(nrect))
  453.         log('r=%d' % r)
  454.  
  455.     
  456.     def get(self):
  457.         inputHookFunc = c_int.from_address(self.inputHookPtr).value
  458.         Cevent = INPUT_RECORD()
  459.         count = c_int(0)
  460.         while inputHookFunc:
  461.             call_function(inputHookFunc, ())
  462.         status = self.ReadConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
  463.         if status and count.value == 1:
  464.             e = event(self, Cevent)
  465.             log_sock(ensure_unicode(e.keyinfo), 'keypress')
  466.             return e
  467.         continue
  468.  
  469.     
  470.     def getkeypress(self):
  471.         while None:
  472.             e = self.get()
  473.             if e.type == 'KeyPress' and e.keycode not in key_modifiers:
  474.                 log(e)
  475.                 if e.keyinfo.keyname == 'next':
  476.                     self.scroll_window(12)
  477.                 elif e.keyinfo.keyname == 'prior':
  478.                     self.scroll_window(-12)
  479.                 else:
  480.                     return e
  481.             if e.type == 'KeyRelease' and e.keyinfo == (True, False, False, 83):
  482.                 log('getKeypress:%s,%s,%s' % (e.keyinfo, e.keycode, e.type))
  483.                 return e
  484.             continue
  485.             return None
  486.  
  487.     
  488.     def getchar(self):
  489.         Cevent = INPUT_RECORD()
  490.         count = c_int(0)
  491.         while None:
  492.             status = self.ReadConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
  493.             if status and count.value == 1 and Cevent.EventType == 1 and Cevent.Event.KeyEvent.bKeyDown:
  494.                 sym = keysym(Cevent.Event.KeyEvent.wVirtualKeyCode)
  495.                 if len(sym) == 0:
  496.                     sym = Cevent.Event.KeyEvent.uChar.AsciiChar
  497.                 
  498.                 return sym
  499.             continue
  500.             return None
  501.  
  502.     
  503.     def peek(self):
  504.         Cevent = INPUT_RECORD()
  505.         count = c_int(0)
  506.         status = self.PeekConsoleInputW(self.hin, byref(Cevent), 1, byref(count))
  507.         if status and count == 1:
  508.             return event(self, Cevent)
  509.  
  510.     
  511.     def title(self, txt = None):
  512.         pass
  513.  
  514.     
  515.     def size(self, width = None, height = None):
  516.         info = CONSOLE_SCREEN_BUFFER_INFO()
  517.         status = self.GetConsoleScreenBufferInfo(self.hout, byref(info))
  518.         if not status:
  519.             return None
  520.         if width is not None and height is not None:
  521.             wmin = (info.srWindow.Right - info.srWindow.Left) + 1
  522.             hmin = (info.srWindow.Bottom - info.srWindow.Top) + 1
  523.             width = max(width, wmin)
  524.             height = max(height, hmin)
  525.             self.SetConsoleScreenBufferSize(self.hout, self.fixcoord(width, height))
  526.         else:
  527.             return (info.dwSize.X, info.dwSize.Y)
  528.         return status
  529.  
  530.     
  531.     def cursor(self, visible = None, size = None):
  532.         info = CONSOLE_CURSOR_INFO()
  533.         if self.GetConsoleCursorInfo(self.hout, byref(info)):
  534.             if visible is not None:
  535.                 info.bVisible = visible
  536.             
  537.             if size is not None:
  538.                 info.dwSize = size
  539.             
  540.             self.SetConsoleCursorInfo(self.hout, byref(info))
  541.         
  542.  
  543.     
  544.     def bell(self):
  545.         self.write('\x07')
  546.  
  547.     
  548.     def next_serial(self):
  549.         self.serial += 1
  550.         return self.serial
  551.  
  552.  
  553. for func in funcs:
  554.     setattr(Console, func, getattr(windll.kernel32, func))
  555.  
  556. windll.kernel32.SetConsoleTitleW.argtypes = [
  557.     c_wchar_p]
  558. windll.kernel32.GetConsoleTitleW.argtypes = [
  559.     c_wchar_p,
  560.     c_short]
  561. from event import Event
  562. VkKeyScan = windll.user32.VkKeyScanA
  563.  
  564. class event(Event):
  565.     
  566.     def __init__(self, console, input):
  567.         self.type = '??'
  568.         self.serial = console.next_serial()
  569.         self.width = 0
  570.         self.height = 0
  571.         self.x = 0
  572.         self.y = 0
  573.         self.char = ''
  574.         self.keycode = 0
  575.         self.keysym = '??'
  576.         self.keyinfo = None
  577.         self.width = None
  578.         if input.EventType == KEY_EVENT:
  579.             if input.Event.KeyEvent.bKeyDown:
  580.                 self.type = 'KeyPress'
  581.             else:
  582.                 self.type = 'KeyRelease'
  583.             self.char = input.Event.KeyEvent.uChar.UnicodeChar
  584.             self.keycode = input.Event.KeyEvent.wVirtualKeyCode
  585.             self.state = input.Event.KeyEvent.dwControlKeyState
  586.             self.keyinfo = make_KeyPress(self.char, self.state, self.keycode)
  587.         elif input.EventType == MOUSE_EVENT:
  588.             if input.Event.MouseEvent.dwEventFlags & MOUSE_MOVED:
  589.                 self.type = 'Motion'
  590.             else:
  591.                 self.type = 'Button'
  592.             self.x = input.Event.MouseEvent.dwMousePosition.X
  593.             self.y = input.Event.MouseEvent.dwMousePosition.Y
  594.             self.state = input.Event.MouseEvent.dwButtonState
  595.         elif input.EventType == WINDOW_BUFFER_SIZE_EVENT:
  596.             self.type = 'Configure'
  597.             self.width = input.Event.WindowBufferSizeEvent.dwSize.X
  598.             self.height = input.Event.WindowBufferSizeEvent.dwSize.Y
  599.         elif input.EventType == FOCUS_EVENT:
  600.             if input.Event.FocusEvent.bSetFocus:
  601.                 self.type = 'FocusIn'
  602.             else:
  603.                 self.type = 'FocusOut'
  604.         elif input.EventType == MENU_EVENT:
  605.             self.type = 'Menu'
  606.             self.state = input.Event.MenuEvent.dwCommandId
  607.         
  608.  
  609.  
  610.  
  611. def getconsole(buffer = 1):
  612.     c = Console(buffer)
  613.     return c
  614.  
  615. HOOKFUNC22 = CFUNCTYPE(c_char_p, c_char_p)
  616. HOOKFUNC23 = CFUNCTYPE(c_char_p, c_void_p, c_void_p, c_char_p)
  617. readline_hook = None
  618. readline_ref = None
  619.  
  620. def hook_wrapper_23(stdin, stdout, prompt):
  621.     
  622.     try:
  623.         res = ensure_str(readline_hook(prompt))
  624.         if res and not isinstance(res, str):
  625.             raise TypeError, 'readline must return a string.'
  626.         not isinstance(res, str)
  627.     except KeyboardInterrupt:
  628.         return 0
  629.         except EOFError:
  630.             res = ''
  631.         except:
  632.             None<EXCEPTION MATCH>EOFError
  633.             print >>sys.stderr, 'Readline internal error'
  634.             traceback.print_exc()
  635.             res = '\n'
  636.         
  637.  
  638.     n = len(res)
  639.     p = Console.PyMem_Malloc(n + 1)
  640.     cdll.msvcrt.strncpy(p, res, n + 1)
  641.     return p
  642.  
  643.  
  644. def hook_wrapper(prompt):
  645.     
  646.     try:
  647.         res = ensure_str(readline_hook(prompt))
  648.         if res and not isinstance(res, str):
  649.             raise TypeError, 'readline must return a string.'
  650.         not isinstance(res, str)
  651.     except KeyboardInterrupt:
  652.         return 0
  653.         except EOFError:
  654.             res = ''
  655.         except:
  656.             None<EXCEPTION MATCH>EOFError
  657.             print >>sys.stderr, 'Readline internal error'
  658.             traceback.print_exc()
  659.             res = '\n'
  660.         
  661.  
  662.     p = cdll.msvcrt._strdup(res)
  663.     return p
  664.  
  665.  
  666. def install_readline(hook):
  667.     global readline_hook, readline_ref, readline_ref
  668.     readline_hook = hook
  669.     PyOS_RFP = c_int.from_address(Console.GetProcAddress(sys.dllhandle, 'PyOS_ReadlineFunctionPointer'))
  670.     if sys.version < '2.3':
  671.         readline_ref = HOOKFUNC22(hook_wrapper)
  672.     else:
  673.         readline_ref = HOOKFUNC23(hook_wrapper_23)
  674.     func_start = c_int.from_address(addressof(readline_ref)).value
  675.     PyOS_RFP.value = func_start
  676.  
  677. if __name__ == '__main__':
  678.     import time
  679.     import sys
  680.     
  681.     def p(char):
  682.         return chr(VkKeyScan(ord(char)) & 255)
  683.  
  684.     c = Console(0)
  685.     sys.stdout = c
  686.     sys.stderr = c
  687.     c.page()
  688.     print p('d'), p('D')
  689.     c.pos(5, 10)
  690.     c.write('hi there')
  691.     print 'some printed output'
  692.     for i in range(10):
  693.         q = c.getkeypress()
  694.         print q
  695.     
  696.     del c
  697.  
  698.