summaryrefslogtreecommitdiffstats
path: root/Demo/cwilib
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2000-05-11 18:27:21 (GMT)
committerGuido van Rossum <guido@python.org>2000-05-11 18:27:21 (GMT)
commit81b4e41cd9c4587c56f4ff87c04864c8bc532921 (patch)
tree19001bebf38062adce6317d37eafcf2938d22324 /Demo/cwilib
parent9ab06ee7b2c89a38adf462a9ce894f016b381b77 (diff)
downloadcpython-81b4e41cd9c4587c56f4ff87c04864c8bc532921.zip
cpython-81b4e41cd9c4587c56f4ff87c04864c8bc532921.tar.gz
cpython-81b4e41cd9c4587c56f4ff87c04864c8bc532921.tar.bz2
removing more stdwin users
Diffstat (limited to 'Demo/cwilib')
-rwxr-xr-xDemo/cwilib/cwilib.py213
-rwxr-xr-xDemo/cwilib/form.py170
-rwxr-xr-xDemo/cwilib/vt100.py328
-rwxr-xr-xDemo/cwilib/vt100win.py78
4 files changed, 0 insertions, 789 deletions
diff --git a/Demo/cwilib/cwilib.py b/Demo/cwilib/cwilib.py
deleted file mode 100755
index 2b19637..0000000
--- a/Demo/cwilib/cwilib.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Interface to the interactive CWI library catalog.
-
-import sys
-import stdwin
-from stdwinevents import *
-import select
-import telnetlib
-import vt100win
-from form import Form
-
-
-# Main program
-
-def main():
- vt = vt100win.VT100win()
- #
- host = 'biefstuk.cwi.nl'
- tn = telnetlib.Telnet(host, 0)
- #
- try:
- vt.send(tn.read_until('login: ', 10))
- tn.write('cwilib\r')
- #
- vt.send(tn.read_until('Hit <RETURN> to continue...', 10))
- tn.write('\r')
- #
- vt.send(tn.read_until('QUIT', 20))
- except EOFError:
- sys.stderr.write('Connection closed prematurely\n')
- sys.exit(1)
- #
- define_screens(vt)
- matches = vt.which_screens()
- if 'menu' not in matches:
- sys.stderr.write('Main menu does not appear\n')
- sys.exit(1)
- #
- tn.write('\r\r')
- vt.open('Progress -- CWI Library')
- vt.set_debuglevel(0)
- ui = UserInterface()
- #
- while 1:
- try:
- data = tn.read_very_eager()
- except EOFError:
- stdwin.message('Connection closed--goodbye')
- break
- if data:
- print 'send...'
- vt.send(data)
- print 'send...done'
- continue
- event = stdwin.pollevent()
- if event:
- type, window, detail = event
- if window == None and type == WE_LOST_SEL:
- window = ui.queryform.window
- event = type, window, detail
- if type == WE_CLOSE:
- break
- if window in ui.windows:
- ui.dispatch(type, window, detail)
- elif window == vt.window:
- if type == WE_NULL:
- pass
- elif type == WE_COMMAND:
- if detail == WC_RETURN:
- tn.write('\r')
- elif detail == WC_BACKSPACE:
- tn.write('\b')
- elif detail == WC_TAB:
- tn.write('\t')
- elif detail == WC_UP:
- tn.write('\033[A')
- elif detail == WC_DOWN:
- tn.write('\033[B')
- elif detail == WC_RIGHT:
- tn.write('\033[C')
- elif detail == WC_LEFT:
- tn.write('\033[D')
- else:
- print '*** Command:', detail
- elif type == WE_CHAR:
- tn.write(detail)
- elif type == WE_DRAW:
- vt.draw(detail)
- elif type in (WE_ACTIVATE, WE_DEACTIVATE):
- pass
- else:
- print '*** VT100 event:', type, detail
- else:
- print '*** Alien event:', type, window, detail
- continue
- rfd, wfd, xfd = select.select([tn, stdwin], [], [])
-
-
-# Subroutine to define our screen recognition patterns
-
-def define_screens(vt):
- vt.define_screen('menu', {
- 'title': ('search', 0, 0, 80,
- ' SEARCH FUNCTIONS +OTHER FUNCTIONS '),
- })
- vt.define_screen('search', {
- 'title': ('search', 0, 0, 80, ' Search '),
- })
- vt.define_screen('shortlist', {'title': ('search', 0, 0, 80,
- ' Short-list')})
- vt.define_screen('showrecord', {
- 'title': ('search', 0, 0, 80, ' Show record '),
- })
- vt.define_screen('timelimit', {
- 'limit': ('search', 12, 0, 80, ' TIME LIMIT '),
- })
- vt.define_screen('attention', {
- 'BASE': ('copy', 0, 0, 0, 'search'),
- 'title': ('search', 10, 0, 80, ' ATTENTION ')})
- vt.define_screen('syntaxerror', {
- 'BASE': ('copy', 0, 0, 0, 'attention'),
- 'message': ('search', 12, 0, 80, ' Syntax error'),
- })
- vt.define_screen('emptyerror', {
- 'BASE': ('copy', 0, 0, 0, 'attention'),
- 'message': ('search', 12, 0, 80,
- ' Check your input. Search at least one term'),
- })
- vt.define_screen('unsortedwarning', {
- 'BASE': ('copy', 0, 0, 0, 'attention'),
- 'message': ('search', 12, 0, 80,
- ' Number of records exceeds sort limit'),
- })
- vt.define_screen('thereismore', {
- 'BASE': ('copy', 0, 0, 0, 'showrecord'),
- 'message': ('search', 15, 0, 80,
- 'There is more within this record. Use the arrow keys'),
- })
- vt.define_screen('nofurther', {
- 'BASE': ('copy', 0, 0, 0, 'showrecord'),
- 'message': ('search', 17, 0, 80, 'You cannot go further\.'),
- })
- vt.define_screen('nofurtherback', {
- 'BASE': ('copy', 0, 0, 0, 'showrecord'),
- 'message': ('search', 17, 0, 80,
- 'You cannot go further back'),
- })
-
-
-# Class to implement our user interface.
-
-class UserInterface:
-
- def __init__(self):
- stdwin.setfont('7x14')
- self.queryform = QueryForm()
- self.listform = ListForm()
- self.recordform = RecordForm()
- self.forms = [self.queryform, self.listform, self.recordform]
- define_query_fields(self.queryform)
- self.windows = []
- for form in self.forms:
- if form.formheight > 0:
- form.open()
- self.windows.append(form.window)
-
- def __del__(self):
- self.close()
-
- def close(self):
- for form in self.forms:
- form.close()
-
- def dispatch(self, type, window, detail):
- for form in self.forms:
- if window == form.window:
- form.dispatch(type, detail)
-
-
-def define_query_fields(f):
- f.define_field('name', 'Name auth./ed.', 1, 60)
- f.define_field('title', 'Title', 4, 60)
- f.define_field('shelfmark', 'Shelf mark', 1, 60)
- f.define_field('class', 'Prim. classif.', 1, 60)
- f.define_field('series', 'Series', 1, 60)
- f.define_field('congress', 'Congr. pl./year', 1, 60)
- f.define_field('type', 'Type', 1, 60)
-
-
-class QueryForm(Form):
-
- def __init__(self):
- Form.__init__(self, 'Query form -- CWI Library')
-
- def dispatch(self, type, detail):
- if type == WE_COMMAND and detail == WC_RETURN:
- print '*** SUBMIT ***'
- else:
- Form.dispatch(self, type, detail)
-
-
-class ListForm(Form):
-
- def __init__(self):
- Form.__init__(self, 'Short list -- CWI Library')
-
-
-class RecordForm(Form):
-
- def __init__(self):
- Form.__init__(self, 'Record detail -- CWI Library')
-
-
-main()
diff --git a/Demo/cwilib/form.py b/Demo/cwilib/form.py
deleted file mode 100755
index 8dd6ef9..0000000
--- a/Demo/cwilib/form.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Fill-out form window
-
-import stdwin
-from stdwinevents import *
-
-
-class Form:
-
- def __init__(self, title):
- self.title = title
- self.window = None
- self.fields = {}
- self.fieldnames = []
- self.formwidth = self.formheight = 0
- self.focusname = None
- self.tefocus = None
-
- def define_field(self, name, label, lines, chars):
- self.fieldnames.append(name)
- lh = stdwin.lineheight()
- cw = stdwin.textwidth('m')
- left = 20*cw
- top = self.formheight + 4
- right = left + chars*cw
- bottom = top + lines*lh
- te = None
- self.fields[name] = (label, left, top, right, bottom, te)
- self.formheight = bottom + 2
- self.formwidth = max(self.formwidth, right + 4)
-
- def open(self):
- if self.window: return
- self.formwidth = max(100, self.formwidth)
- self.formheight = max(50, self.formheight)
- stdwin.setdefwinsize(self.formwidth, self.formheight)
- stdwin.setdefscrollbars(0, 0)
- self.window = stdwin.open(self.title)
- self.window.setdocsize(self.formwidth, self.formheight)
- for name in self.fieldnames:
- label, left, top, right, bottom, te = \
- self.fields[name]
- rect = (left, top), (right, bottom)
- te = self.window.textcreate(rect)
- te.setactive(0)
- te.setview(rect)
- self.fields[name] = \
- label, left, top, right, bottom, te
- if self.fieldnames:
- self.setfocus(self.fieldnames[0])
-
- def setfocus(self, name):
- if name <> self.focusname and self.tefocus:
- self.tefocus.setactive(0)
- self.focusname = name
- if self.focusname:
- self.tefocus = self.fields[self.focusname][-1]
- self.tefocus.setactive(1)
- else:
- self.tefocus = None
-
- def dispatch(self, type, detail):
- event = type, self.window, detail
- if type == WE_NULL:
- pass
- elif type == WE_DRAW:
- self.draw(detail)
- elif type == WE_MOUSE_DOWN:
- x, y = detail[0]
- for name in self.fieldnames:
- label, left, top, right, bottom, te = \
- self.fields[name]
- if left <= x < right and \
- top <= y < bottom:
- self.setfocus(name)
- break
- else:
- stdwin.fleep()
- return
- if self.tefocus:
- (left, top), (right, bottom) = \
- self.tefocus.getrect()
- if x < left: x = left
- if x >= right: x = right-1
- if y < top: y = top
- if y >= bottom:
- y = bottom-1
- x = right-1
- event = type, self.window, ((x,y),)+detail[1:]
- if not self.tefocus.event(event):
- stdwin.fleep()
- elif type in (WE_MOUSE_MOVE, WE_MOUSE_UP, WE_CHAR):
- if not self.tefocus or not self.tefocus.event(event):
- stdwin.fleep()
- elif type == WE_MOUSE_UP:
- button = detail[2]
- if button == 2:
- self.paste_selection()
- else:
- self.make_selection()
- elif type == WE_COMMAND:
- if detail in (WC_BACKSPACE, WC_UP, WC_DOWN,
- WC_LEFT, WC_RIGHT):
- if not self.tefocus or \
- not self.tefocus.event(event):
- stdwin.fleep()
- elif detail == WC_RETURN:
- print '*** Submit query'
- elif detail == WC_TAB:
- if not self.fields:
- stdwin.fleep()
- return
- if not self.focusname:
- i = 0
- else:
- i = self.fieldnames.index(
- self.focusname)
- i = (i+1) % len(self.fieldnames)
- self.setfocus(self.fieldnames[i])
- self.tefocus.setfocus(0, 0x7fff)
- self.make_selection()
- elif type in (WE_ACTIVATE, WE_DEACTIVATE):
- pass
- elif type == WE_LOST_SEL:
- if self.tefocus:
- a, b = self.tefocus.getfocus()
- self.tefocus.setfocus(a, a)
- else:
- print 'Form.dispatch(%d, %s)' % (type, `detail`)
-
- def draw(self, detail):
- d = self.window.begindrawing()
- d.cliprect(detail)
- d.erase(detail)
- self.drawform(d, detail)
- d.noclip()
- d.close()
- # Stupid textedit objects can't draw with open draw object...
- self.drawtextedit(detail)
-
- def drawform(self, d, detail):
- for name in self.fieldnames:
- label, left, top, right, bottom, te = self.fields[name]
- d.text((0, top), label)
- d.box((left-3, top-2), (right+4, bottom+2))
-
- def drawtextedit(self, detail):
- for name in self.fieldnames:
- label, left, top, right, bottom, te = self.fields[name]
- te.draw(detail)
-
- def make_selection(self):
- s = self.tefocus.getfocustext()
- if not s:
- return
- stdwin.rotatecutbuffers(1)
- stdwin.setcutbuffer(0, s)
- if not self.window.setselection(WS_PRIMARY, s):
- stdwin.fleep()
-
- def paste_selection(self):
- if not self.tefocus:
- stdwin.fleep()
- return
- s = stdwin.getselection(WS_PRIMARY)
- if not s:
- s = stdwin.getcutbuffer(0)
- if not s:
- stdwin.fleep()
- return
- self.tefocus.replace(s)
diff --git a/Demo/cwilib/vt100.py b/Demo/cwilib/vt100.py
deleted file mode 100755
index 9edd481..0000000
--- a/Demo/cwilib/vt100.py
+++ /dev/null
@@ -1,328 +0,0 @@
-# VT100 terminal emulator.
-# This is incomplete and slow, but will do for now...
-# It shouldn't be difficult to extend it to be a more-or-less complete
-# VT100 emulator. And little bit of profiling could go a long way...
-
-from array import array
-import regex
-import string
-
-# Tunable parameters
-DEBUGLEVEL = 1
-
-# Symbolic constants
-ESC = '\033'
-
-
-# VT100 emulation class
-
-class VT100:
-
- def __init__(self):
- self.debuglevel = DEBUGLEVEL
- # Unchangeable parameters (for now)
- self.width = 80
- self.height = 24
- self.blankline = array('c', ' '*self.width)
- self.blankattr = array('b', '\0'*self.width)
- # Set mutable display state
- self.reset()
- # Set parser state
- self.unfinished = ''
- # Set screen recognition state
- self.reset_recognizer()
-
- def msg(self, msg, *args):
- if self.debuglevel > 0:
- print 'VT100:', msg%args
-
- def set_debuglevel(self, debuglevel):
- self.debuglevel = debuglevel
-
- def reset(self):
- self.lines = []
- self.attrs = []
- self.fill_bottom()
- self.x = 0
- self.y = 0
- self.curattrs = []
-
- def show(self):
- lineno = 0
- for line in self.lines:
- lineno = lineno + 1
- i = len(line)
- while i > 0 and line[i-1] == ' ': i = i-1
- print line[:i]
- print 'CURSOR:', self.x, self.y
-
- def fill_bottom(self):
- while len(self.lines) < self.height:
- self.lines.append(self.blankline[:])
- self.attrs.append(self.blankattr[:])
-
- def fill_top(self):
- while len(self.lines) < self.height:
- self.lines.insert(0, self.blankline[:])
- self.attrs.insert(0, self.blankattr[:])
-
- def clear_all(self):
- self.lines = []
- self.attrs = []
- self.fill_bottom()
-
- def clear_below(self):
- del self.lines[self.y:]
- del self.attrs[self.y:]
- self.fill_bottom()
-
- def clear_above(self):
- del self.lines[:self.y]
- del self.attrs[:self.y]
- self.fill_top()
-
- def send(self, buffer):
- self.msg('send: unfinished=%s, buffer=%s',
- `self.unfinished`, `buffer`)
- self.unfinished = self.unfinished + buffer
- i = 0
- n = len(self.unfinished)
- while i < n:
- c = self.unfinished[i]
- i = i+1
- if c != ESC:
- self.add_char(c)
- continue
- if i >= n:
- i = i-1
- break
- c = self.unfinished[i]
- i = i+1
- if c == 'c':
- self.reset()
- continue
- if c <> '[':
- self.msg('unrecognized: ESC %s', `c`)
- continue
- argstr = ''
- while i < n:
- c = self.unfinished[i]
- i = i+1
- if c not in '0123456789;':
- break
- argstr = argstr + c
- else:
- i = i - len(argstr) - 2
- break
-## self.msg('found ESC [ %s %s' % (`argstr`, `c`))
- args = string.splitfields(argstr, ';')
- for j in range(len(args)):
- s = args[j]
- while s[:1] == '0': s = s[1:]
- if s: args[j] = eval(s)
- else: args[j] = 0
- p1 = p2 = 0
- if args: p1 = args[0]
- if args[1:]: p2 = args[1]
- if c in '@ABCDH':
- if not p1: p1 = 1
- if c in 'H':
- if not p2: p2 = 1
- if c == '@':
- for j in range(p1):
- self.add_char(' ')
- elif c == 'A':
- self.move_by(0, -p1)
- elif c == 'B':
- self.move_by(0, p1)
- elif c == 'C':
- self.move_by(p1, 0)
- elif c == 'D':
- self.move_by(-p1, 0)
- elif c == 'H':
- self.move_to(p2-1, p1-1)
- elif c == 'J':
- if p1 == 0: self.clear_above()
- elif p1 == 1: self.clear_below()
- elif p1 == 2: self.clear_all()
- else: self.msg('weird ESC [ %d J', p1)
- elif c == 'K':
- if p1 == 0: self.erase_right()
- elif p1 == 1: self.erase_left()
- elif p1 == 2: self.erase_line()
- else: self.msg('weird ESC [ %d K', p1)
- elif c == 'm':
- if p1 == 0:
- self.curattrs = []
- else:
- if p1 not in self.curattrs:
- self.curattrs.append(p1)
- self.curattrs.sort()
- else:
- self.msg('unrecognized: ESC [ %s', `argstr+c`)
- self.unfinished = self.unfinished[i:]
-
- def add_char(self, c):
- if c == '\r':
- self.move_to(0, self.y)
- return
- if c in '\n\f\v':
- self.move_to(self.x, self.y + 1)
- if self.y >= self.height:
- self.scroll_up(1)
- self.move_to(self.x, self.height - 1)
- return
- if c == '\b':
- self.move_by(-1, 0)
- return
- if c == '\a':
- self.msg('BELL')
- return
- if c == '\t':
- self.move_to((self.x+8)/8*8, self.y)
- return
- if c == '\0':
- return
- if c < ' ' or c > '~':
- self.msg('ignored control char: %s', `c`)
- return
- if self.x >= self.width:
- self.move_to(0, self.y + 1)
- if self.y >= self.height:
- self.scroll_up(1)
- self.move_to(self.x, self.height - 1)
- self.lines[self.y][self.x] = c
- if self.curattrs:
- self.attrs[self.y][self.x] = max(self.curattrs)
- else:
- self.attrs[self.y][self.x] = 0
- self.move_by(1, 0)
-
- def move_to(self, x, y):
- self.x = min(max(0, x), self.width)
- self.y = min(max(0, y), self.height)
-
- def move_by(self, dx, dy):
- self.move_to(self.x + dx, self.y + dy)
-
- def scroll_up(self, nlines):
- del self.lines[:max(0, nlines)]
- del self.attrs[:max(0, nlines)]
- self.fill_bottom()
-
- def scroll_down(self, nlines):
- del self.lines[-max(0, nlines):]
- del self.attrs[-max(0, nlines):]
- self.fill_top()
-
- def erase_left(self):
- x = min(self.width-1, x)
- y = min(self.height-1, y)
- self.lines[y][:x] = self.blankline[:x]
- self.attrs[y][:x] = self.blankattr[:x]
-
- def erase_right(self):
- x = min(self.width-1, x)
- y = min(self.height-1, y)
- self.lines[y][x:] = self.blankline[x:]
- self.attrs[y][x:] = self.blankattr[x:]
-
- def erase_line(self):
- self.lines[y][:] = self.blankline
- self.attrs[y][:] = self.blankattr
-
- # The following routines help automating the recognition of
- # standard screens. A standard screen is characterized by
- # a number of fields. A field is part of a line,
- # characterized by a (lineno, begin, end) tuple;
- # e.g. the first 10 characters of the second line are
- # specified by the tuple (1, 0, 10). Fields can be:
- # - regex: desired contents given by a regular expression,
- # - extract: can be extracted,
- # - cursor: screen is only valid if cursor in field,
- # - copy: identical to another screen (position is ignored).
- # A screen is defined as a dictionary full of fields. Screens
- # also have names and are placed in a dictionary.
-
- def reset_recognizer(self):
- self.screens = {}
-
- def define_screen(self, screenname, fields):
- fieldscopy = {}
- # Check if the fields make sense
- for fieldname in fields.keys():
- field = fields[fieldname]
- ftype, lineno, begin, end, extra = field
- if ftype in ('match', 'search'):
- extra = regex.compile(extra)
- elif ftype == 'extract':
- extra = None
- elif ftype == 'cursor':
- extra = None
- elif ftype == 'copy':
- if not self.screens.has_key(extra):
- raise ValueError, 'bad copy ref'
- else:
- raise ValueError, 'bad ftype: %s' % `ftype`
- fieldscopy[fieldname] = (
- ftype, lineno, begin, end, extra)
- self.screens[screenname] = fieldscopy
-
- def which_screens(self):
- self.busy = []
- self.okay = []
- self.fail = []
- for name in self.screens.keys():
- ok = self.match_screen(name)
- return self.okay[:]
-
- def match_screen(self, name):
- if name in self.busy: raise RuntimeError, 'recursive match'
- if name in self.okay: return 1
- if name in self.fail: return 0
- self.busy.append(name)
- fields = self.screens[name]
- ok = 0
- for key in fields.keys():
- field = fields[key]
- ftype, lineno, begin, end, extra = field
- if ftype == 'copy':
- if not self.match_screen(extra): break
- elif ftype == 'search':
- text = self.lines[lineno][begin:end].tostring()
- if extra.search(text) < 0:
- break
- elif ftype == 'match':
- text = self.lines[lineno][begin:end].tostring()
- if extra.match(text) < 0:
- break
- elif ftype == 'cursor':
- if self.x != lineno or not \
- begin <= self.y < end:
- break
- else:
- ok = 1
- if ok:
- self.okay.append(name)
- else:
- self.fail.append(name)
- self.busy.remove(name)
- return ok
-
- def extract_field(self, screenname, fieldname):
- ftype, lineno, begin, end, extra = \
- self.screens[screenname][fieldname]
- return stripright(self.lines[lineno][begin:end].tostring())
-
- def extract_rect(self, left, top, right, bottom):
- lines = []
- for i in range(top, bottom):
- lines.append(stripright(self.lines[i][left:right])
- .tostring())
- return lines
-
-
-def stripright(line):
- i = len(line)
- while i > 0 and line[i-1] in string.whitespace: i = i-1
- return line[:i]
diff --git a/Demo/cwilib/vt100win.py b/Demo/cwilib/vt100win.py
deleted file mode 100755
index 122e5f9..0000000
--- a/Demo/cwilib/vt100win.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# VT100 terminal emulator in a STDWIN window.
-
-import stdwin
-from stdwinevents import *
-from vt100 import VT100
-
-class VT100win(VT100):
-
- def __init__(self):
- VT100.__init__(self)
- self.window = None
- self.last_x = -1
- self.last_y = -1
-
- def __del__(self):
- self.close()
-
- def open(self, title):
- stdwin.setfont('7x14')
- self.charwidth = stdwin.textwidth('m')
- self.lineheight = stdwin.lineheight()
- self.docwidth = self.width * self.charwidth
- self.docheight = self.height * self.lineheight
- stdwin.setdefwinsize(self.docwidth + 2, self.docheight + 2)
- stdwin.setdefscrollbars(0, 0)
- self.window = stdwin.open(title)
- self.window.setdocsize(self.docwidth + 2, self.docheight + 2)
-
- def close(self):
- if self.window:
- self.window.close()
- self.window = None
-
- def show(self):
- if not self.window: return
- self.window.change(((-10, -10),
- (self.docwidth+10, self.docheight+10)))
-
- def draw(self, detail):
- d = self.window.begindrawing()
- fg = stdwin.getfgcolor()
- red = stdwin.fetchcolor('red')
- d.cliprect(detail)
- d.erase(detail)
- lh = self.lineheight
- cw = self.charwidth
- for y in range(self.height):
- d.text((0, y*lh), self.lines[y].tostring())
- if self.attrs[y] <> self.blankattr:
- for x in range(len(self.attrs[y])):
- if self.attrs[y][x] == 7:
- p1 = x*cw, y*lh
- p2 = (x+1)*cw, (y+1)*lh
- d.invert((p1, p2))
- x = self.x * cw
- y = self.y * lh
- d.setfgcolor(red)
- d.invert((x, y), (x+cw, y+lh))
- d.setfgcolor(fg)
- d.close()
-
- def move_to(self, x, y):
- VT100.move_to(self, x, y)
- if not self.window: return
- if self.y != self.last_y:
- self.window.change((0, self.last_y * self.lineheight),
- (self.width*self.charwidth,
- (self.last_y+1) * self.lineheight))
- self.last_x = self.x
- self.last_y = y
- self.window.change((0, self.y * self.lineheight),
- (self.width*self.charwidth,
- (self.y+1) * self.lineheight))
-
- def send(self, str):
- VT100.send(self, str)
-## self.show()
-