import moo DEFAULT_SPEED = 9600 LOG_ENABLED = False BEL = '\007' SO = '\016' SI = '\017' ESC = '\033' CSI = '\233' SS3 = '\217' DCS = '\220' ST = '\234' GATM = 1 ## guarded area transfer (disabled) KAM = 2 ## keyboard action CRM = 3 ## control representation (setup) IRM = 4 ## insert/replace SRTM = 5 ## status reporting transfer (disabled) ERM = 6 ## erasure mode (non-DEC) VEM = 7 ## vertical editing (disabled) BDSM = 8 ## bi-directional support mode (non-DEC) DCSM = 9 ## device component select mode (non-DEC) HEM = 10 ## horizontal editing (disabled) PUM = 11 ## positioning unit (disabled) SRM = 12 ## send/receive FEAM = 13 ## format effector action (disabled) FETM = 14 ## format effector transfer (disabled) MATM = 15 ## multiple area transfer (disabled) TTM = 16 ## transfer termination (disabled) SATM = 17 ## selected area transfer (disabled) TSM = 18 ## tabulation stop (disabled) EBM = 19 ## editing boundary (disabled) LNM = 20 ## line feed/new line DECCKM = 1 ## cursor keys DECANM = 2 ## ANSI DECCOLM = 3 ## column DECSCLM = 4 ## scrolling DECSCNM = 5 ## screen DECOM = 6 ## origin DECAWM = 7 ## autowrap DECARM = 8 ## autorepeat DECEDM = 10 ## edit DECLTM = 11 ## line transmit DECSCFDM = 13 ## space compression field delimiter DECTEM = 14 ## transmission execution DECEKEM = 16 ## edit key execution DECPFF = 18 ## print form feed DECPEX = 19 ## printer extent DECTCEM = 25 ## text cursor enable DECRLM = 34 ## left-to-right DECTEK = 35 ## 4010/4014 emulation DECHEM = 36 ## Hebrew encoding DECNRCM = 42 ## national replacement character set DECGEPM = 43 ## graphics expanded print DECGPCM = 44 ## graphics print color DECGPCS = 45 ## graphics print color syntax DECGPBM = 46 ## graphics print background DECGRPM = 47 ## graphics rotated print DEC131TM = 53 ## VT131 transmit DECNAKB = 57 ## Greek/N-A Keyboard Mapping DECHCCM = 60 ## horizontal cursor coupling (disabled) DECVCCM = 61 ## vertical cursor coupling DECPCCM = 64 ## page cursor coupling DECNKM = 66 ## numeric keypad DECBKM = 67 ## backarrow key DECKBUM = 68 ## keyboard usage DECVSSM = 69 ## vertical split DECXRLM = 73 ## transmit rate linking DECKPM = 81 ## keyboard positioning DECNCSM = 95 ## no clearing screen on column change DECRLCM = 96 ## right-to-left copy DECCRTSM = 97 ## CRT save DECARSM = 98 ## auto resize DECMCM = 99 ## modem control DECAAM = 100 ## auto answerback DECCANSM = 101 ## conceal answerback DECNULM = 102 ## null DECHDPXM = 103 ## half duplex DECESKM = 104 ## enable secondary keyboard language DECOSCNM = 106 ## overscan DECFWM = 111 ## framed windows DECRPL = 112 ## review previous lines DECHWUM = 113 ## host wake-up mode (CRT and energy saver) DECATCUM = 114 ## alternate text color underline DECATCBM = 115 ## alternate text color blink DECBBSM = 116 ## bold and blink style DECECM = 117 ## erase color soft_scroll = 0 #/******************************************************************************/ csi_7 = ESC + '[' csi_8 = chr(0x9b) dcs_7 = ESC + 'P' dcs_8 = chr(0x90) osc_7 = ESC + ']' osc_8 = chr(0x9d) ss3_7 = ESC + 'O' ss3_8 = chr(0x8f) st_7 = ESC + '\\' st_8 = chr(0x9c) class VtTest(moo.term.Term): def __init__(self): moo.term.Term.__init__(self) self.brkrd = 0 self.input_8bits = False self.log_disabled = False self.max_cols = 132 self.max_lines = 24 self.min_cols = 80 self.output_8bits = False self.reading = 0 self.tty_speed = DEFAULT_SPEED self.use_padding = False def csi_input(self): if self.input_8bits: return csi_8 else: return csi_7 def csi_output(self): if self.output_8bits: return csi_8 else: return csi_7 def dcs_input(self): if self.input_8bits: return dcs_8 else: return dcs_7 def dcs_output(self): if self.output_8bits: return dcs_8 else: return dcs_7 def osc_input(self): if self.input_8bits: return osc_8 else: return osc_7 def osc_output(self): if self.output_8bits: return osc_8 else: return osc_7 def ss3_input(self): if self.input_8bits: return ss3_8 else: return ss3_7 def ss3_output(self): if self.output_8bits: return ss3_8 else: return ss3_7 def st_input(self): if self.input_8bits: return st_8 else: return st_7 def st_output(self): if self.output_8bits: return st_8 else: return st_7 def padding(self, msecs): if self.use_padding: count = (3 * msecs * tty_speed + DEFAULT_SPEED - 1) / DEFAULT_SPEED while count > 0: count -= 1 self.feed('\0') def extra_padding(self, msecs): if self.use_padding: if self.soft_scroll: self.padding(msecs * 4) else: self.padding(msecs) def println(self, s): self.feed(s + "\r\n") return 1 def do_csi(self, fmt, *args): self.feed(self.csi_output()) self.feed(fmt % args) def do_dcs(self, fmt, *args): self.feed(self.dcs_output()) self.feed(fmt % args) def do_osc(self, fmt, *args): self.feed(self.osc_output()) self.feed(fmt % args) def send_char(self, c): self.feed(chr(c)) def esc(self, s): self.feed(ESC + s) def brc(self, pn, c): self.do_csi("%d%s", pn, c) def brc2(self, pn1, pn2, c): self.do_csi("%d;%d%s", pn1, pn2, c) def brc3(self, pn1, pn2, pn3, c): self.do_csi("%d;%d;%d%s", pn1, pn2, pn3, c) def cbt(self, pn): self.brc(pn, 'Z') ## Cursor Character Absolute def cha(self, pn): self.brc(pn, 'G') ## Cursor Forward Tabulation def cht(self, pn): self.brc(pn, 'I') # Cursor Next Line def cnl(self, pn): self.brc(pn, 'E') # Cursor Previous Line def cpl(self, pn): brc(pn, 'F') # Cursor Backward def cub(self, pn): self.brc(pn, 'D') self.padding(2) # Cursor Down def cud(self, pn): self.brc(pn, 'B') self.extra_padding(2) # Cursor Forward def cuf(self, pn): self.brc(pn, 'C') self.padding(2) def cup(self, pn1, pn2): # Cursor Position self.brc2(pn1, pn2, 'H') self.padding(5) # 10 for vt220 return 1 # used for indenting def cuu(self, pn): # Cursor Up self.brc(pn, 'A') self.extra_padding(2) def da(self): # Device Attributes self.brc(0, 'c') def decaln(self): # Screen Alignment Display self.esc("#8") def decarm(self, flag): # DECARM autorepeat if flag: self.sm("?8") # autorepeat else: self.rm("?8") # no autorepeat def decawm(self, flag): # DECAWM autowrap if flag: self.sm("?7") # autowrap else: self.rm("?7") # no autowrap def decbi(self): # VT400: Back Index self.esc("6") self.padding(40) def decbkm(self, flag): # VT400: Backarrow key if flag: self.sm("?67") # backspace else: self.rm("?67") # delete def deccara(self, top, left, bottom, right, attr): self.do_csi("%d%d%d%d%d$r", top, left, bottom, right, attr) def decckm(self, flag): # DECCKM Cursor Keys if flag: self.sm("?1") # application else: self.rm("?1") # normal def deccolm(self, flag): # DECCOLM 80/132 Columns if flag: self.sm("?3") # 132 columns else: self.rm("?3") # 80 columns def deccra(self, Pts, Pl, Pbs, Prs, Pps, Ptd, Pld, Ppd): self.do_csi("%d%d%d%d%d%d%d%d$v", Pts, # top-line border Pl, # left-line border Pbs, # bottom-line border Prs, # right-line border Pps, # source page number Ptd, # destination top-line border Pld, # destination left-line border Ppd) # destination page number def decdc(self, pn): # VT400 Delete Column self.do_csi("%d'~", pn) self.padding(10 * pn) return 1 def decefr(self, top, left, bottom, right): # DECterm Enable filter rectangle self.do_csi("%d%d%d%d'w", top, left, bottom, right) def decelr(self, all_or_one, pixels_or_cells): # DECterm Enable Locator Reporting self.do_csi("%d%d'z", all_or_one, pixels_or_cells) def decera(self, top, left, bottom, right): # VT400 Erase Rectangular area self.do_csi("%d%d%d%d$z", top, left, bottom, right) def decdhl(self, lower): # Double Height Line (also double width) if lower: self.esc("#4") else: self.esc("#3") def decdwl(self): # Double Wide Line self.esc("#6") def decfi(self): # VT400: Forward Index self.esc("9") self.padding(40) def decfra(self, c, top, left, bottom, right): # VT400 Fill Rectangular area self.do_csi("%d%d%d%d%d$x", c, top, left, bottom, right) def decid(self): # required for VT52, not recommended above VT100 self.esc("Z") # Identify def decic(self, pn): # VT400 Insert Column self.do_csi("%d'}", pn) self.padding(10 * pn) return 1 def deckbum(self, flag): # VT400: Keyboard Usage if flag: self.sm("?68") # data processing else: self.rm("?68") # typewriter def deckpam(self): # Keypad Application Mode self.esc("=") def deckpm(self, flag): # VT400: Keyboard Position if flag: self.sm("?81") # position reports else: self.rm("?81") # character codes def deckpnm(self): # Keypad Numeric Mode self.esc(">") def decll(self, ps): # Load LEDs self.do_csi("%sq", ps) def decnkm(self, flag): # VT400: Numeric Keypad if flag: self.sm("?66") # application else: self.rm("?66") # numeric def decom(self, flag): # DECOM Origin if flag: self.sm("?6") # relative else: self.rm("?6") # absolute def decpex(self, flag): # VT220: printer extent mode if flag: self.sm("?19") # full screen (page) else: self.rm("?19") # scrolling region def decpff(self, flag): # VT220: print form feed mode if flag: self.sm("?18") # form feed else: self.rm("?18") # no form feed def decnrcm(self, flag): # VT220: National replacement character set if flag: self.sm("?42") # national else: self.rm("?42") # multinational def decrara(self, top, left, bottom, right, attr): self.do_csi("%d%d%d%d%d$t", top, left, bottom, right, attr) def decrc(self): # Restore Cursor self.esc("8") def decreqtparm(self, pn): # Request Terminal Parameters self.brc(pn, 'x') def decrqlp(self, mode): # DECterm Request Locator Position self.do_csi("%d'|", mode) def decrqss(self, pn): # VT200 Request Status-String self.do_dcs("$q%s", pn) def decsace(self, flag): # VT400 Select attribute change extent if flag: self.do_csi("%d*x", 2) else: self.do_csi("%d*x", 0) def decsasd(self, pn): # VT200 Select active status display self.do_csi("%d$}", pn) def decsc(self): # Save Cursor self.esc("7") def decsca(self, pn1): # VT200 select character attribute (protect) self.do_csi("%d\"q", pn1) def decsclm(self, flag): # Scrolling mode (smooth/jump) if flag: self.sm("?4") # smooth scrolling else: self.rm("?4") # jump-scrolling scrolling self.soft_scroll = flag def decscnm(self, flag): # Screen mode (inverse-video) if flag: self.sm("?5") # inverse video else: self.rm("?5") # normal video self.padding(200) def decsed(self, pn1): # VT200 selective erase in display self.do_csi("?%dJ", pn1) def decsel(self, pn1): # VT200 selective erase in line self.do_csi("?%dK", pn1) def decsera(self, top, left, bottom, right): # VT400 Selective erase rectangular area self.do_csi("%d%d%d%d${", top, left, bottom, right) def decsle(self, mode): # DECterm Select Locator Events self.do_csi("%d'{", mode) def decsnls(self, pn): # VT400 Select number of lines per screen self.do_csi("%d*|", pn) def decssdt(self, pn): # VT200 Select status line type self.do_csi("%d$~", pn) def decstbm(self, pn1, pn2): # Set Top and Bottom Margins if pn1 or pn2: self.brc2(pn1, pn2, 'r') else: self.esc("[r") # Good for >24-line terminals def decstr(self): # VT200 Soft terminal reset self.do_csi("!p") def decswl(self): # Single Width Line self.esc("#5") def dectst(self, pn): # Invoke Confidence Test self.brc2(2, pn, 'y') def dsr(self, pn): # Device Status Report self.brc(pn, 'n') def ed(self, pn): # Erase in Display self.brc(pn, 'J') self.padding(50) def el(self, pn): # Erase in Line self.brc(pn, 'K') self.padding(3) # 4 for vt400 def ech(self, pn): # Erase character(s) self.brc(pn, 'X') def hpa(self, pn): # Character Position Absolute self.brc(pn, '`') def hts(self): # Horizontal Tabulation Set self.esc("H") def hvp(self, pn1, pn2): # Horizontal and Vertical Position self.brc2(pn1, pn2, 'f') def ind(self): # Index self.esc("D") self.padding(20) # vt220 # The functions beginning "mc_" are variations of Media Copy (MC) def mc_autoprint(self, flag): # VT220: auto print mode if flag: self.do_csi("?%di", 5) else: self.do_csi("?%di", 4) def mc_printer_controller(self, flag): # VT220: printer controller mode if flag: self.do_csi("%di", 5) else: self.do_csi("%di", 4) def mc_print_page(self): # VT220: print page self.do_csi("i") def mc_print_composed(self): # VT300: print composed main display self.do_csi("?10i") def mc_print_all_pages(self): # VT300: print composed all pages self.do_csi("?11i") def mc_print_cursor_line(self): # VT220: print cursor line self.do_csi("?1i") def mc_printer_start(self, flag): # VT300: start/stop printer-to-host session if flag: self.do_csi("?%di", 9) else: self.do_csi("?%di", 8) def mc_printer_assign(self, flag): # VT300: assign/release printer to active session if flag: self.do_csi("?%di", 18) else: self.do_csi("?%di", 19) def nel(self): # Next Line self.esc("E") def rep(self, pn): # Repeat self.do_csi("%db", pn) def ri(self): # Reverse Index self.esc("M") self.extra_padding(5) # 14 on vt220 def ris(self): # Reset to Initial State self.esc("c") def rm(self, ps): # Reset Mode self.do_csi("%sl", ps) def s8c1t(self, flag): # Tell terminal to respond with 7-bit or 8-bit controls self.input_8bits = flag if flag: self.esc(" G") # select 8-bit controls else: self.esc(" F") # select 7-bit controls self.zleep(300) # /* # * If g is zero, # * designate G0 as character set c # * designate G1 as character set B (ASCII) # * shift-in (select G0 into GL). # * If g is nonzero # * designate G0 as character set B (ASCII) # * designate G1 as character set c # * shift-out (select G1 into GL). # * See also scs_normal() and scs_graphics(). # */ def scs(self, g, c): # Select character Set if g: self.esc("%c%c" % (')', c)) else: self.esc("%c%c" % ('(', c)) if g: self.esc("%c%c" % (')', 'B')) else: self.esc("%c%c" % ('(', 'B')) if g: self.feed(SO) else: self.feed(SI) self.padding(4) def sd(self, pn): # Scroll Down self.brc(pn, 'T') def sgr(self, ps): # Select Graphic Rendition self.do_csi("%sm", ps) self.padding(2) def sl(self, pn): # Scroll Left self.do_csi("%d @", pn) def sm(self, ps): # Set Mode self.do_csi("%sh", ps) def sr(self, pn): # Scroll Right self.do_csi("%d A", pn) def srm(self, flag): # VT400: Send/Receive mode if flag: self.sm("12") # local echo off else: self.rm("12") # local echo on def su(self, pn): # Scroll Up self.brc(pn, 'S') self.extra_padding(5) def tbc(self, pn): # Tabulation Clear self.brc(pn, 'g') def dch(self, pn): # Delete character self.brc(pn, 'P') def ich(self, pn): # Insert character -- not in VT102 self.brc(pn, '@') def dl(self, pn): # Delete line self.brc(pn, 'M') def il(self, pn): # Insert line self.brc(pn, 'L') def vpa(self, pn): # Line Position Absolute self.brc(pn, 'd') def vt52cub1(self): # cursor left self.esc("D") self.padding(5) def vt52cud1(self): # cursor down self.esc("B") self.padding(5) def vt52cuf1(self): # cursor right self.esc("C") self.padding(5) def vt52cup(self, l, c): # direct cursor address self.esc("Y%c%c" % (l + 31, c + 31)) self.padding(5) def vt52cuu1(self): # cursor up self.esc("A") self.padding(5) def vt52ed(self): # erase to end of screen self.esc("J") self.padding(5) def vt52el(self): # erase to end of line self.esc("K") self.padding(5) def vt52home(self): # cursor to home self.esc("H") self.padding(5) def vt52ri(self): # reverse line feed self.esc("I") self.padding(5) def tst_movements(self, N=26): ctext = "This is a correct sentence"; self.deccolm(False) width = 80 # Compute left/right columns for a 60-column box centered in 'width' inner_l = (width - 60) / 2; inner_r = 61 + inner_l; hlfxtra = (width - 80) / 2; self.decaln(); self.cup( 9,inner_l); self.ed(1); self.cup(18,60+hlfxtra); self.ed(0); self.el(1); self.cup( 9,inner_r); self.el(0); # 132: 36..97 */ # 80: 10..71 */ for row in range(10,17): self.cup(row, inner_l); self.el(1); self.cup(row, inner_r); self.el(0); self.cup(17,30); self.el(2); for col in range(1,width+1): self.hvp(self.max_lines, col); self.feed("*"); self.hvp( 1, col); self.feed("*"); self.cup(2,2); for row in range(2,self.max_lines): self.feed("+"); self.cub(1); self.ind(); self.cup(self.max_lines-1,width-1); l = range(2, self.max_lines) l.reverse for row in l: self.feed("+"); self.cub(1); self.ri(); self.cup(2,1); for row in range(2, self.max_lines): self.feed("*"); self.cup(row, width); self.feed("*"); self.cub(10); if (row < 10): self.nel(); else: self.feed("\n"); self.cup(2,10); self.cub(42+hlfxtra); self.cuf(2); for col in range(3, width-1): self.feed("+"); self.cuf(0); self.cub(2); self.cuf(1); self.cup(self.max_lines-1,inner_r-1); self.cuf(42+hlfxtra); self.cub(2); l = range(3, width-1) l.reverse() for col in l: self.feed("+"); self.cub(1); self.cuf(1); self.cub(0); self.feed("%c" % (8,)); self.cup( 1, 1); self.cuu(10); self.cuu(1); self.cuu(0); self.cup(self.max_lines,width); self.cud(10); self.cud(1); self.cud(0); self.cup(10,2+inner_l); for row in range(10, 16): for col in range(2+inner_l, inner_r-1): self.feed(" "); self.cud(1); self.cub(58); self.cuu(5); self.cuf(1); self.feed("The screen should be cleared, and have an unbroken bor-"); self.cup(12,inner_l+3); self.feed("der of *'s and +'s around the edge, and exactly in the"); self.cup(13,inner_l+3); self.feed("middle there should be a frame of E's around this text"); self.cup(14,inner_l+3); self.feed("with one (1) free position around it. "); for i in range(1): on_left = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; on_right = "abcdefghijklmnopqrstuvwxyz"; height = len(on_left) - 1; region = self.max_lines - 6; height = 10; self.deccolm(False); width = self.min_cols self.println("Test of autowrap, mixing control and print characters."); self.println("The left/right margins should have letters in order:"); self.decstbm(3, region + 3); self.decom(True) for i in range(N): if i % 4 == 0: self.cup(region + 1, 1) self.feed(on_left[i]); self.cup(region + 1, width) self.feed(on_right[i]); self.feed("\n"); elif i % 4 == 1: self.cup(region, width) self.feed(on_right[i - 1] + on_left[i]) self.cup(region + 1, width) self.feed(on_left[i] + "\010 " + on_right[i]); self.feed("\n"); elif i % 4 == 2: self.cup(region + 1, width) self.feed(on_left[i] + "\010\010\011\011" + on_right[i]); self.cup(region + 1, 2) self.feed("\010" + on_left[i] + "\n"); else: self.cup(region + 1, width) self.feed("\n"); self.cup(region, 1) self.feed(on_left[i]); self.cup(region, width) self.feed(on_right[i]); # self.decom(False); # self.decstbm(0, 0); # self.cup(self.max_lines - 2, 1); # self.deccolm(False) # vt_clear(2); # vt_move(1,1); # println("Test of cursor-control characters inside ESC sequences."); # println("Below should be four identical lines:"); # println(""); # println("A B C D E F G H I"); # for (i = 1; i < 10; i++) { # printf("%c", '@' + i); # do_csi("2\010C"); /* Two forward, one backspace */ # } # println(""); # /* Now put CR in CUF sequence. */ # printf("A "); # for (i = 2; i < 10; i++) # printf("%s\015%dC%c", csi_output(), 2 * i - 2, '@' + i); # println(""); # /* Now put VT in CUU sequence. */ # rm("20"); # for (i = 1; i < 10; i++) { # printf("%c ", '@' + i); # do_csi("1\013A"); # } # println(""); # println(""); # holdit(); # # if (LOG_ENABLED) # fprintf(log_fp, "tst_movements leading zeros in ESC sequences\n"); # # vt_clear(2); # vt_move(1,1); # println("Test of leading zeros in ESC sequences."); # printf("Two lines below you should see the sentence \"%s\".",ctext); # for (col = 1; *ctext; col++) # printf("%s00000000004;00000000%dH%c", csi_output(), col, *ctext++); # cup(20,1); # # restore_ttymodes(); # return MENU_HOLD; # }