~pyreadline/pyreadline/trunk

« back to all changes in this revision

Viewing changes to pyreadline/console/console.py

  • Committer: Jorgen Stenarson
  • Date: 2011-10-06 17:48:11 UTC
  • mfrom: (104.1.5 pyreadline-64bit)
  • Revision ID: jorgen.stenarson@bostream.nu-20111006174811-79sxaq072z0lpt0l
Merging fixes for 64-bit

Thanks to Christoph Gohlke for helping with the fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
from pyreadline.console.ansi import AnsiState,AnsiWriter
26
26
 
27
27
try:
 
28
    import ctypes.util
28
29
    from ctypes import *
29
30
    from _ctypes import call_function
 
31
    from ctypes.wintypes import *
30
32
except ImportError:
31
33
    raise ImportError(u"You need ctypes to run this code")
32
34
 
192
194
            self.hout = self.GetStdHandle(STD_OUTPUT_HANDLE)
193
195
 
194
196
        self.hin = self.GetStdHandle(STD_INPUT_HANDLE)
195
 
        self.inmode = c_int(0)
 
197
        self.inmode = DWORD(0)
196
198
        self.GetConsoleMode(self.hin, byref(self.inmode))
197
199
        self.SetConsoleMode(self.hin, 0xf)
198
200
        info = CONSOLE_SCREEN_BUFFER_INFO()
199
201
        self.GetConsoleScreenBufferInfo(self.hout, byref(info))
200
202
        self.attr = info.wAttributes
201
203
        self.saveattr = info.wAttributes # remember the initial colors
202
 
 
203
204
        self.defaultstate = AnsiState()
204
205
        self.defaultstate.winattr = info.wAttributes
205
206
        self.ansiwriter = AnsiWriter(self.defaultstate)
214
215
 
215
216
        self.pythondll = \
216
217
            CDLL(u'python%s%s' % (sys.version[0], sys.version[2]))
 
218
        self.pythondll.PyMem_Malloc.restype = c_size_t
 
219
        self.pythondll.PyMem_Malloc.argtypes = [c_size_t]
217
220
        self.inputHookPtr = \
218
 
            c_int.from_address(addressof(self.pythondll.PyOS_InputHook)).value
 
221
            c_void_p.from_address(addressof(self.pythondll.PyOS_InputHook)).value
219
222
        setattr(Console, u'PyMem_Malloc', self.pythondll.PyMem_Malloc)
220
223
 
221
224
    def __del__(self):
347
350
    def write_color(self, text, attr=None):
348
351
        text = ensure_unicode(text)
349
352
        n, res= self.ansiwriter.write_color(text, attr)
350
 
        junk = c_int(0)
 
353
        junk = DWORD(0)
351
354
        for attr,chunk in res:
352
355
            log(u"console.attr:%s"%unicode(attr))
353
356
            log(u"console.chunk:%s"%unicode(chunk))
363
366
        log(u'write("%s", %s)' %(text, attr))
364
367
        if attr is None:
365
368
            attr = self.attr
366
 
        n = c_int(0)
 
369
        junk = DWORD(0)
367
370
        self.SetConsoleTextAttribute(self.hout, attr)
368
371
        for short_chunk in split_block(chunk):
369
372
            self.WriteConsoleW(self.hout, ensure_unicode(short_chunk), 
375
378
    if os.environ.has_key(u"EMACS"):
376
379
        def write_color(self, text, attr=None):
377
380
            text = ensure_str(text)
378
 
            junk = c_int(0)
 
381
            junk = DWORD(0)
379
382
            self.WriteFile(self.hout, text, len(text), byref(junk), None)
380
383
            return len(text)
381
384
        write_plain = write_color
406
409
            self.SetConsoleCursorPosition(self.hout, self.fixcoord(0, 0))
407
410
 
408
411
        w = info.dwSize.X
409
 
        n = c_int(0)
 
412
        n = DWORD(0)
410
413
        for y in range(info.dwSize.Y):
411
414
            self.FillConsoleOutputAttribute(self.hout, attr, 
412
415
                                            w, self.fixcoord(0, y), byref(n))
421
424
            attr = self.attr
422
425
 
423
426
        pos = self.fixcoord(x, y)
424
 
        n = c_int(0)
 
427
        n = DWORD(0)
425
428
        self.WriteConsoleOutputCharacterW(self.hout, text, 
426
429
                                          len(text), pos, byref(n))
427
430
        self.FillConsoleOutputAttribute(self.hout, attr, n, pos, byref(n))
437
440
    def rectangle(self, rect, attr=None, fill=u' '):
438
441
        u'''Fill Rectangle.'''
439
442
        x0, y0, x1, y1 = rect
440
 
        n = c_int(0)
 
443
        n = DWORD(0)
441
444
        if attr is None:
442
445
            attr = self.attr
443
446
        for y in range(y0, y1):
489
492
 
490
493
    def get(self):
491
494
        u'''Get next event from queue.'''
492
 
        inputHookFunc = c_int.from_address(self.inputHookPtr).value
 
495
        inputHookFunc = c_void_p.from_address(self.inputHookPtr).value
493
496
 
494
497
        Cevent = INPUT_RECORD()
495
 
        count = c_int(0)
 
498
        count = DWORD(0)
496
499
        while 1:
497
500
            if inputHookFunc:
498
501
                call_function(inputHookFunc, ())
524
527
        u'''Get next character from queue.'''
525
528
 
526
529
        Cevent = INPUT_RECORD()
527
 
        count = c_int(0)
 
530
        count = DWORD(0)
528
531
        while 1:
529
532
            status = self.ReadConsoleInputW(self.hin, 
530
533
                                            byref(Cevent), 1, byref(count))
540
543
    def peek(self):
541
544
        u'''Check event queue.'''
542
545
        Cevent = INPUT_RECORD()
543
 
        count = c_int(0)
 
546
        count = DWORD(0)
544
547
        status = self.PeekConsoleInputW(self.hin, 
545
548
                                byref(Cevent), 1, byref(count))
546
549
        if status and count == 1:
595
598
# add the functions from the dll to the class
596
599
for func in funcs:
597
600
    setattr(Console, func, getattr(windll.kernel32, func))
598
 
windll.kernel32.SetConsoleTitleW.argtypes = [c_wchar_p]
599
 
windll.kernel32.GetConsoleTitleW.argtypes = [c_wchar_p,c_short]
 
601
 
 
602
if sys.version_info[:2] < (2, 6):
 
603
    msvcrt = cdll.msvcrt
 
604
else:
 
605
    msvcrt = cdll.LoadLibrary(ctypes.util.find_msvcrt())
 
606
_strncpy = msvcrt.strncpy
 
607
_strncpy.restype = c_char_p
 
608
_strncpy.argtypes = [c_char_p, c_char_p, c_size_t]
 
609
_strdup = msvcrt._strdup
 
610
_strdup.restype = c_char_p
 
611
_strdup.argtypes = [c_char_p]
 
612
 
 
613
LPVOID = c_void_p
 
614
LPCVOID = c_void_p
 
615
FARPROC = c_void_p
 
616
LPDWORD = POINTER(DWORD)
 
617
 
 
618
Console.AllocConsole.restype = BOOL
 
619
Console.AllocConsole.argtypes = [] #void
 
620
Console.CreateConsoleScreenBuffer.restype = HANDLE
 
621
Console.CreateConsoleScreenBuffer.argtypes = [DWORD, DWORD, c_void_p, DWORD, LPVOID] #DWORD, DWORD, SECURITY_ATTRIBUTES*, DWORD, LPVOID  
 
622
Console.FillConsoleOutputAttribute.restype = BOOL 
 
623
Console.FillConsoleOutputAttribute.argtypes = [HANDLE, WORD, DWORD, c_int, LPDWORD] #HANDLE, WORD, DWORD, COORD, LPDWORD
 
624
Console.FillConsoleOutputCharacterW.restype = BOOL
 
625
Console.FillConsoleOutputCharacterW.argtypes = [HANDLE, c_ushort, DWORD, c_int, LPDWORD] #HANDLE, TCHAR, DWORD, COORD, LPDWORD
 
626
Console.FreeConsole.restype = BOOL
 
627
Console.FreeConsole.argtypes = [] #void
 
628
Console.GetConsoleCursorInfo.restype = BOOL
 
629
Console.GetConsoleCursorInfo.argtypes = [HANDLE, c_void_p] #HANDLE, PCONSOLE_CURSOR_INFO  
 
630
Console.GetConsoleMode.restype = BOOL
 
631
Console.GetConsoleMode.argtypes = [HANDLE, LPDWORD] #HANDLE, LPDWORD  
 
632
Console.GetConsoleScreenBufferInfo.restype = BOOL
 
633
Console.GetConsoleScreenBufferInfo.argtypes = [HANDLE, c_void_p] #HANDLE, PCONSOLE_SCREEN_BUFFER_INFO 
 
634
Console.GetConsoleTitleW.restype = DWORD
 
635
Console.GetConsoleTitleW.argtypes = [c_wchar_p, DWORD] #LPTSTR , DWORD
 
636
Console.GetProcAddress.restype = FARPROC
 
637
Console.GetProcAddress.argtypes = [HMODULE, c_char_p] #HMODULE , LPCSTR 
 
638
Console.GetStdHandle.restype = HANDLE
 
639
Console.GetStdHandle.argtypes = [DWORD]
 
640
Console.PeekConsoleInputW.restype = BOOL
 
641
Console.PeekConsoleInputW.argtypes = [HANDLE, c_void_p, DWORD, LPDWORD] #HANDLE, PINPUT_RECORD, DWORD, LPDWORD
 
642
Console.ReadConsoleInputW.restype = BOOL
 
643
Console.ReadConsoleInputW.argtypes = [HANDLE, c_void_p, DWORD, LPDWORD] #HANDLE, PINPUT_RECORD, DWORD, LPDWORD
 
644
Console.ScrollConsoleScreenBufferW.restype = BOOL
 
645
Console.ScrollConsoleScreenBufferW.argtypes = [HANDLE, c_void_p, c_void_p, c_int, c_void_p] #HANDLE, SMALL_RECT*, SMALL_RECT*, COORD, LPDWORD
 
646
Console.SetConsoleActiveScreenBuffer.restype = BOOL
 
647
Console.SetConsoleActiveScreenBuffer.argtypes = [HANDLE] #HANDLE
 
648
Console.SetConsoleCursorInfo.restype = BOOL
 
649
Console.SetConsoleCursorInfo.argtypes = [HANDLE, c_void_p] #HANDLE, CONSOLE_CURSOR_INFO* 
 
650
Console.SetConsoleCursorPosition.restype = BOOL
 
651
Console.SetConsoleCursorPosition.argtypes = [HANDLE, c_int] #HANDLE, COORD 
 
652
Console.SetConsoleMode.restype = BOOL
 
653
Console.SetConsoleMode.argtypes = [HANDLE, DWORD] #HANDLE, DWORD
 
654
Console.SetConsoleScreenBufferSize.restype = BOOL
 
655
Console.SetConsoleScreenBufferSize.argtypes = [HANDLE, c_int] #HANDLE, COORD 
 
656
Console.SetConsoleTextAttribute.restype = BOOL
 
657
Console.SetConsoleTextAttribute.argtypes = [HANDLE, WORD] #HANDLE, WORD 
 
658
Console.SetConsoleTitleW.restype = BOOL
 
659
Console.SetConsoleTitleW.argtypes = [c_wchar_p] #LPCTSTR
 
660
Console.SetConsoleWindowInfo.restype = BOOL
 
661
Console.SetConsoleWindowInfo.argtypes = [HANDLE, BOOL, c_void_p] #HANDLE, BOOL, SMALL_RECT*
 
662
Console.WriteConsoleW.restype = BOOL
 
663
Console.WriteConsoleW.argtypes = [HANDLE, c_void_p, DWORD, LPDWORD, LPVOID] #HANDLE, VOID*, DWORD, LPDWORD, LPVOID
 
664
Console.WriteConsoleOutputCharacterW.restype = BOOL
 
665
Console.WriteConsoleOutputCharacterW.argtypes = [HANDLE, c_wchar_p, DWORD, c_int, LPDWORD] #HANDLE, LPCTSTR, DWORD, COORD, LPDWORD
 
666
Console.WriteFile.restype = BOOL
 
667
Console.WriteFile.argtypes = [HANDLE, LPCVOID, DWORD, LPDWORD, c_void_p] #HANDLE, LPCVOID , DWORD, LPDWORD , LPOVERLAPPED 
 
668
 
 
669
 
600
670
 
601
671
from event import Event
602
672
 
705
775
    # we have to make a copy because the caller expects to free the result
706
776
    n = len(res)
707
777
    p = Console.PyMem_Malloc(n + 1)
708
 
    cdll.msvcrt.strncpy(p, res, n + 1)
 
778
    _strncpy(cast(p, c_char_p), res, n + 1)
709
779
    return p
710
780
 
711
781
def hook_wrapper(prompt):
727
797
        traceback.print_exc()
728
798
        res = u'\n'
729
799
    # we have to make a copy because the caller expects to free the result
730
 
    p = cdll.msvcrt._strdup(res)
 
800
    p = _strdup(res)
731
801
    return p
732
802
 
733
803
def install_readline(hook):
737
807
    # save the hook so the wrapper can call it
738
808
    readline_hook = hook
739
809
    # get the address of PyOS_ReadlineFunctionPointer so we can update it
740
 
    PyOS_RFP = c_int.from_address(Console.GetProcAddress(sys.dllhandle,
 
810
    PyOS_RFP = c_void_p.from_address(Console.GetProcAddress(sys.dllhandle,
741
811
                                            "PyOS_ReadlineFunctionPointer"))
742
812
    # save a reference to the generated C-callable so it doesn't go away
743
813
    if sys.version < '2.3':
745
815
    else:
746
816
        readline_ref = HOOKFUNC23(hook_wrapper_23)
747
817
    # get the address of the function
748
 
    func_start = c_int.from_address(addressof(readline_ref)).value
 
818
    func_start = c_void_p.from_address(addressof(readline_ref)).value
749
819
    # write the function address into PyOS_ReadlineFunctionPointer
750
820
    PyOS_RFP.value = func_start
751
821