8 changed files with 884 additions and 1866 deletions
@ -0,0 +1,241 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
__all__ = [''] |
||||
|
||||
import os, pty, threading |
||||
import struct, fcntl, termios |
||||
|
||||
from dataclasses import dataclass |
||||
|
||||
import re |
||||
from select import select |
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
|
||||
|
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.log import TTkLog |
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.cfg import TTkCfg |
||||
from TermTk.TTkCore.string import TTkString |
||||
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot |
||||
from TermTk.TTkCore.helper import TTkHelper |
||||
from TermTk.TTkGui.clipboard import TTkClipboard |
||||
from TermTk.TTkGui.textwrap1 import TTkTextWrap |
||||
from TermTk.TTkGui.textcursor import TTkTextCursor |
||||
from TermTk.TTkGui.textdocument import TTkTextDocument |
||||
from TermTk.TTkLayouts.gridlayout import TTkGridLayout |
||||
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea |
||||
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView, TTkAbstractScrollViewGridLayout |
||||
from TermTk.TTkWidgets.widget import TTkWidget |
||||
|
||||
from TermTk.TTkWidgets.TTkTerminal.terminal_screen import _TTkTerminalScreen |
||||
from TermTk.TTkWidgets.TTkTerminal.mode import TTkTerminalModes |
||||
|
||||
from TermTk.TTkWidgets.TTkTerminal.vt102 import TTkVT102 |
||||
|
||||
from TermTk.TTkCore.TTkTerm.colors import TTkTermColor |
||||
from TermTk.TTkCore.TTkTerm.colors_ansi_map import ansiMap16, ansiMap256 |
||||
|
||||
|
||||
class _termLog(): |
||||
# debug = TTkLog.debug |
||||
# info = TTkLog.info |
||||
error = TTkLog.error |
||||
warn = TTkLog.warn |
||||
fatal = TTkLog.fatal |
||||
# mouse = TTkLog.error |
||||
|
||||
debug = lambda _:None |
||||
info = lambda _:None |
||||
# error = lambda _:None |
||||
# warn = lambda _:None |
||||
# fatal = lambda _:None |
||||
mouse = lambda _:None |
||||
|
||||
class _TTkTerminal_CSI_DEC(): |
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 ⇒ Application Cursor Keys (MODE_DECCKM), VT100. |
||||
# UP = \0330A |
||||
# DOWN = \0330B |
||||
# LEFT = \0330C |
||||
# RIGHT = \0330D |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 ⇒ Normal Cursor Keys (MODE_DECCKM), VT100. |
||||
# UP = \033[A |
||||
# DOWN = \033[B |
||||
# LEFT = \033[C |
||||
# RIGHT = \033[D |
||||
def _CSI_DEC_SR_1_MODE_DECCKM(self, s): |
||||
if s: |
||||
self._keyboard.flags |= TTkTerminalModes.MODE_DECCKM |
||||
else: |
||||
self._keyboard.flags &= ~TTkTerminalModes.MODE_DECCKM |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 2 5 ⇒ Show cursor (DECTCEM), VT220. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 2 5 ⇒ Hide cursor (DECTCEM), VT220. |
||||
def _CSI_DEC_SR_25_DECTCEM(self, s): |
||||
self.enableWidgetCursor(enable=s) |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 0 0 ⇒ Send Mouse X & Y on button press and |
||||
# release. See the section Mouse Tracking. This is the X11 |
||||
# xterm mouse protocol. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 0 0 ⇒ Don't send Mouse X & Y on button press and |
||||
# release. See the section Mouse Tracking. |
||||
def _CSI_DEC_SR_1000(self, s): |
||||
self._mouse.reportPress = s |
||||
self._mouse.reportDrag = False |
||||
self._mouse.reportMove = False |
||||
_termLog.info(f"1000 Mouse Tracking {s=}") |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 0 2 ⇒ Use Cell Motion Mouse Tracking, xterm. See |
||||
# the section Button-event tracking. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 0 2 ⇒ Don't use Cell Motion Mouse Tracking, |
||||
# xterm. See the section Button-event tracking. |
||||
def _CSI_DEC_SR_1002(self, s): |
||||
self._mouse.reportPress = s |
||||
self._mouse.reportDrag = s |
||||
self._mouse.reportMove = False |
||||
_termLog.info(f"1002 Mouse Tracking {s=}") |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 0 3 ⇒ Use All Motion Mouse Tracking, xterm. See |
||||
# the section Any-event tracking. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 0 3 ⇒ Don't use All Motion Mouse Tracking, xterm. |
||||
# See the section Any-event tracking. |
||||
def _CSI_DEC_SR_1003(self, s): |
||||
self._mouse.reportPress = s |
||||
self._mouse.reportDrag = s |
||||
self._mouse.reportMove = s |
||||
_termLog.info(f"1003 Mouse Tracking {s=}") |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 0 4 ⇒ Send FocusIn/FocusOut events, xterm. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 0 4 ⇒ Don't send FocusIn/FocusOut events, xterm. |
||||
def _CSI_DEC_SR_1004(self, s): |
||||
_termLog.warn(f"Unhandled 1004 Focus In/Out event {s=}") |
||||
|
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 0 6 ⇒ Enable SGR Mouse Mode, xterm. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 0 6 ⇒ Disable SGR Mouse Mode, xterm. |
||||
def _CSI_DEC_SR_1006(self, s): |
||||
self._mouse.sgrMode = s |
||||
_termLog.info(f"1006 SGR Mouse Mode {s=}") |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 1 5 ⇒ Enable urxvt Mouse Mode. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 1 5 ⇒ Disable urxvt Mouse Mode. |
||||
def _CSI_DEC_SR_1015(self, s): |
||||
_termLog.warn(f"1015 {s=} Unimplemented: _CSI_DEC_SR_1015 urxvt Mouse Mode.") |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 4 7 ⇒ Use Alternate Screen Buffer, xterm. This |
||||
# may be disabled by the titeInhibit resource. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 4 7 ⇒ Use Normal Screen Buffer, xterm. Clear the |
||||
# screen first if in the Alternate Screen Buffer. This may be |
||||
# disabled by the titeInhibit resource. |
||||
def _CSI_DEC_SR_1047(self, s): |
||||
if s: |
||||
self._screen_current = self._screen_alt |
||||
else: |
||||
self._screen_current = self._screen_normal |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 4 8 ⇒ Save cursor as in DECSC, xterm. This may |
||||
# be disabled by the titeInhibit resource. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 4 8 ⇒ Restore cursor as in DECRC, xterm. This |
||||
# may be disabled by the titeInhibit resource. |
||||
def _CSI_DEC_SR_1048(self, s): |
||||
pass |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 1 0 4 9 ⇒ Save cursor as in DECSC, xterm. After |
||||
# saving the cursor, switch to the Alternate Screen Buffer, |
||||
# clearing it first. This may be disabled by the titeInhibit |
||||
# resource. This control combines the effects of the 1 0 4 7 |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 1 0 4 9 ⇒ Use Normal Screen Buffer and restore cursor |
||||
# as in DECRC, xterm. This may be disabled by the titeInhibit |
||||
# resource. This combines the effects of the 1 0 4 7 and 1 0 4 |
||||
# 8 modes. Use this with terminfo-based applications rather |
||||
# than the 4 7 mode. |
||||
def _CSI_DEC_SR_1049(self, s): |
||||
self._CSI_DEC_SR_1047(s) |
||||
self._CSI_DEC_SR_1048(s) |
||||
|
||||
# CSI ? Pm h |
||||
# DEC Private Mode Set (DECSET). |
||||
# Ps = 2 0 0 4 ⇒ Set bracketed paste mode, xterm. |
||||
# CSI ? Pm l |
||||
# DEC Private Mode Reset (DECRST). |
||||
# Ps = 2 0 0 4 ⇒ Reset bracketed paste mode, xterm. |
||||
def _CSI_DEC_SR_2004(self, s): |
||||
self._terminal.bracketedMode = s |
||||
|
||||
_CSI_DEC_SET_RST_MAP = { |
||||
1 : _CSI_DEC_SR_1_MODE_DECCKM, |
||||
25 : _CSI_DEC_SR_25_DECTCEM, |
||||
1000: _CSI_DEC_SR_1000, |
||||
1002: _CSI_DEC_SR_1002, |
||||
1003: _CSI_DEC_SR_1003, |
||||
1004: _CSI_DEC_SR_1004, |
||||
1006: _CSI_DEC_SR_1006, |
||||
1015: _CSI_DEC_SR_1015, |
||||
1047: _CSI_DEC_SR_1047, |
||||
1049: _CSI_DEC_SR_1049, |
||||
2004: _CSI_DEC_SR_2004 |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,188 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
__all__ = [''] |
||||
|
||||
import collections |
||||
import unicodedata |
||||
|
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
|
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.log import TTkLog |
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.cfg import TTkCfg |
||||
from TermTk.TTkCore.string import TTkString |
||||
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot |
||||
from TermTk.TTkCore.helper import TTkHelper |
||||
from TermTk.TTkGui.clipboard import TTkClipboard |
||||
from TermTk.TTkGui.textwrap1 import TTkTextWrap |
||||
from TermTk.TTkGui.textcursor import TTkTextCursor |
||||
from TermTk.TTkGui.textdocument import TTkTextDocument |
||||
from TermTk.TTkLayouts.gridlayout import TTkGridLayout |
||||
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea |
||||
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView, TTkAbstractScrollViewGridLayout |
||||
from TermTk.TTkWidgets.widget import TTkWidget |
||||
|
||||
from .terminal_screen_CSI import _TTkTerminalScreen_CSI |
||||
from .terminal_screen_C1 import _TTkTerminalScreen_C1 |
||||
|
||||
class _TTkTerminalScreen(_TTkTerminalScreen_CSI, _TTkTerminalScreen_C1): |
||||
__slots__ = ('_lines', '_terminalCursor', |
||||
'_scrollingRegion', |
||||
'_bufferSize', '_bufferedLines', |
||||
'_w', '_h', '_color', '_canvas', |
||||
'_last', |
||||
# Signals |
||||
'bell' |
||||
) |
||||
def __init__(self, w=80, h=24, bufferSize=1000, color=TTkColor.RST) -> None: |
||||
self.bell = pyTTkSignal() |
||||
self._w = w |
||||
self._h = h |
||||
self._last = None |
||||
self._bufferSize = bufferSize |
||||
self._bufferedLines = collections.deque(maxlen=bufferSize) |
||||
self._terminalCursor = (0,0) |
||||
self._scrollingRegion = (0,h) |
||||
self._color = color |
||||
self._canvas = TTkCanvas(width=w, height=h) |
||||
|
||||
def color(self): |
||||
return self._color |
||||
|
||||
def setColor(self, color): |
||||
self._color = color |
||||
|
||||
def getCursor(self): |
||||
return self._terminalCursor |
||||
|
||||
def resize(self, w, h): |
||||
ow, oh = self._w, self._h |
||||
self._w, self._h = w, h |
||||
st,sb = self._scrollingRegion |
||||
# if oh <= h: # Terminal height decreasing |
||||
# sb = min(h,oh) |
||||
# else:# Terminal height increasing |
||||
# sb = h-oh+sb |
||||
# self._scrollingRegion = (st,sb) |
||||
self._scrollingRegion = (0,h) |
||||
newCanvas = TTkCanvas(width=w, height=h) |
||||
s = (0,0,w,h) |
||||
newCanvas.paintCanvas(self._canvas,s,s,s) |
||||
|
||||
self._canvas = newCanvas |
||||
x,y = self._terminalCursor |
||||
self._terminalCursor = (min(x,w-1),min(y,h-1)) |
||||
|
||||
def _pushTxt(self, txt:str, irm:bool=False): |
||||
x,y = self._terminalCursor |
||||
w,h = self._w, self._h |
||||
st,sb = self._scrollingRegion |
||||
self._last = txt[-1] if txt else None |
||||
|
||||
for bi, tout in enumerate(txt.split('\a')): # grab the bells |
||||
if bi: |
||||
self.bell.emit() |
||||
|
||||
# I check the size of each char in order to draw |
||||
# it in the correct position |
||||
for ch in tout: |
||||
if ord(ch) < 0x20: |
||||
# TTkLog.error(f"Unhandled ASCII: 0x{ord(ch):02x}") |
||||
continue |
||||
l = TTkString._getWidthText(ch) |
||||
# Scroll up if we are at the right border |
||||
if l+x > w: |
||||
x=0 |
||||
y+=1 |
||||
if y >= sb: |
||||
self._CSI_S_SU(y-sb+1, None) # scroll up |
||||
y=sb-1 |
||||
self._terminalCursor = (x,y) |
||||
if l==1: # push normal char |
||||
if irm: |
||||
self._canvas._data[y][x:x] = [ch] |
||||
self._canvas._colors[y][x:x] = [self._color] |
||||
# self._canvas._data[y].insert(x,ch) |
||||
# self._canvas._colors[y].insert(x,self._color) |
||||
self._canvas._data[y].pop() |
||||
self._canvas._colors[y].pop() |
||||
else: |
||||
self._canvas._data[y][x] = ch |
||||
self._canvas._colors[y][x] = self._color |
||||
elif l > 1: # push wide char |
||||
if irm: |
||||
self._canvas._data[y][x:x] = [ch,''] |
||||
self._canvas._colors[y][x:x] = [self._color,self._color] |
||||
# self._canvas._data[y].insert(x,ch) |
||||
# self._canvas._colors[y].insert(x,self._color) |
||||
self._canvas._data[y].pop() |
||||
self._canvas._data[y].pop() |
||||
self._canvas._colors[y].pop() |
||||
self._canvas._colors[y].pop() |
||||
else: |
||||
self._canvas._data[y][x] = ch |
||||
self._canvas._data[y][x+1] = '' |
||||
self._canvas._colors[y][x] = self._color |
||||
self._canvas._colors[y][x+1] = self._color |
||||
else: # l==0 # push zero sized char |
||||
if x>0 and self._canvas._data[y][x-1] != '': |
||||
self._canvas._data[y][x-1] += ch |
||||
elif x>1: |
||||
self._canvas._data[y][x-2] += ch |
||||
x+=l |
||||
self._terminalCursor = (x+l,y) |
||||
self._terminalCursor = (x,y) |
||||
|
||||
def pushLine(self, line:str, irm:bool=False): |
||||
if not line: return |
||||
w,h = self._w, self._h |
||||
st,sb = self._scrollingRegion |
||||
|
||||
lines = line.split('\n') |
||||
for i,l in enumerate(lines): |
||||
if i: |
||||
x,y = self._terminalCursor |
||||
y+=1 |
||||
if y >= sb: |
||||
self._CSI_S_SU(y-sb+1, None) # scroll up |
||||
y=sb-1 |
||||
self._terminalCursor = (x,y) |
||||
ls = l.split('\r') |
||||
for ii,ll in enumerate(ls): |
||||
if ii: |
||||
x,y = self._terminalCursor |
||||
self._terminalCursor = (0,y) |
||||
lls = ll.split('\b') # 0x08 = Backspace |
||||
for iii,lll in enumerate(lls): |
||||
if iii: |
||||
x,y = self._terminalCursor |
||||
x = max(0,x-1) |
||||
self._terminalCursor = (x,y) |
||||
self._pushTxt(lll,irm) |
||||
|
||||
def paintEvent(self, canvas: TTkCanvas, w:int, h:int, ox:int=0, oy:int=0) -> None: |
||||
w,h = self._w, self._h |
||||
s = (0,0,w,h) |
||||
canvas.paintCanvas(self._canvas,s,s,s) |
||||
# TTkLog.debug("Paint") |
||||
@ -0,0 +1,127 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
__all__ = [''] |
||||
|
||||
import collections |
||||
import unicodedata |
||||
|
||||
from TermTk.TTkCore.canvas import TTkCanvas |
||||
|
||||
from TermTk.TTkCore.color import TTkColor |
||||
from TermTk.TTkCore.log import TTkLog |
||||
from TermTk.TTkCore.constant import TTkK |
||||
from TermTk.TTkCore.cfg import TTkCfg |
||||
from TermTk.TTkCore.string import TTkString |
||||
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot |
||||
from TermTk.TTkCore.helper import TTkHelper |
||||
from TermTk.TTkGui.clipboard import TTkClipboard |
||||
from TermTk.TTkGui.textwrap1 import TTkTextWrap |
||||
from TermTk.TTkGui.textcursor import TTkTextCursor |
||||
from TermTk.TTkGui.textdocument import TTkTextDocument |
||||
from TermTk.TTkLayouts.gridlayout import TTkGridLayout |
||||
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea |
||||
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView, TTkAbstractScrollViewGridLayout |
||||
from TermTk.TTkWidgets.widget import TTkWidget |
||||
|
||||
class _TTkTerminalScreen_C1(): |
||||
# C1 (8-Bit) Control Characters |
||||
# |
||||
# The xterm program recognizes both 8-bit and 7-bit control characters. |
||||
# It generates 7-bit controls (by default) or 8-bit if S8C1T is enabled. |
||||
# The following pairs of 7-bit and 8-bit control characters are |
||||
# equivalent: |
||||
# |
||||
# ESC D |
||||
# Index (IND is 0x84). |
||||
# Move the cursor down and scroll at the edge |
||||
def _C1_D(self): |
||||
x,y = self._terminalCursor |
||||
t,b = self._scrollingRegion |
||||
h = self._h |
||||
if y < b-1: |
||||
self._terminalCursor = (x,y+1) |
||||
else: |
||||
self._CSI_S_SU(1) |
||||
|
||||
# ESC E |
||||
# Next Line (NEL is 0x85). |
||||
# |
||||
# ESC H |
||||
# Tab Set (HTS is 0x88). |
||||
# |
||||
# ESC M |
||||
# Reverse Index (RI is 0x8d). |
||||
# Move the cursor Up and scroll at the edge |
||||
def _C1_M(self): |
||||
x,y = self._terminalCursor |
||||
t,b = self._scrollingRegion |
||||
h = self._h |
||||
if y > t: |
||||
self._terminalCursor = (x,y-1) |
||||
else: |
||||
self._CSI_T_SD(1) |
||||
|
||||
# ESC N |
||||
# Single Shift Select of G2 Character Set (SS2 is 0x8e), VT220. |
||||
# This affects next character only. |
||||
# |
||||
# ESC O |
||||
# Single Shift Select of G3 Character Set (SS3 is 0x8f), VT220. |
||||
# This affects next character only. |
||||
# |
||||
# ESC P |
||||
# Device Control String (DCS is 0x90). |
||||
# |
||||
# ESC V |
||||
# Start of Guarded Area (SPA is 0x96). |
||||
# |
||||
# ESC W |
||||
# End of Guarded Area (EPA is 0x97). |
||||
# |
||||
# ESC X |
||||
# Start of String (SOS is 0x98). |
||||
# |
||||
# ESC Z |
||||
# Return Terminal ID (DECID is 0x9a). Obsolete form of CSI c (DA). |
||||
# |
||||
# ESC [ |
||||
# Control Sequence Introducer (CSI is 0x9b). |
||||
# |
||||
# ESC \ |
||||
# String Terminator (ST is 0x9c). |
||||
# |
||||
# ESC ] |
||||
# Operating System Command (OSC is 0x9d). |
||||
# |
||||
# ESC ^ |
||||
# Privacy Message (PM is 0x9e). |
||||
# |
||||
# ESC _ |
||||
# Application Program Command (APC is 0x9f). |
||||
# |
||||
# |
||||
# These control characters are used in the vtXXX emulation. |
||||
_C1_MAP = { |
||||
'D' : _C1_D, |
||||
'M' : _C1_M |
||||
} |
||||
@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
import sys, os |
||||
|
||||
import timeit |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../..')) |
||||
from TermTk import TTkTermColor |
||||
|
||||
testInput = "abcdefghil£££ABCDEFG<£££>!#$()0123459zZ£££" |
||||
|
||||
testDict1 = { |
||||
'!' : lambda x: x*2, |
||||
'#' : lambda x: x*2, |
||||
'$' : lambda x: x*2, |
||||
|
||||
'0' : lambda x: x*2, |
||||
'1' : lambda x: x*2, |
||||
'2' : lambda x: x*2, |
||||
'3' : lambda x: x*2, |
||||
'4' : lambda x: x*2, |
||||
'9' : lambda x: x*2, |
||||
|
||||
'A' : lambda x: x*2, |
||||
'B' : lambda x: x*2, |
||||
'C' : lambda x: x*2, |
||||
'D' : lambda x: x*2, |
||||
'E' : lambda x: x*2, |
||||
'F' : lambda x: x*2, |
||||
'G' : lambda x: x*2, |
||||
'H' : lambda x: x*2, |
||||
'I' : lambda x: x*2, |
||||
'Z' : lambda x: x*2, |
||||
|
||||
'a' : lambda x: x*2, |
||||
'b' : lambda x: x*2, |
||||
'c' : lambda x: x*2, |
||||
'd' : lambda x: x*2, |
||||
'e' : lambda x: x*2, |
||||
'f' : lambda x: x*2, |
||||
'g' : lambda x: x*2, |
||||
'h' : lambda x: x*2, |
||||
'i' : lambda x: x*2, |
||||
'z' : lambda x: x*2, |
||||
} |
||||
|
||||
testArray1 = [ # Oct Dec Kex Char |
||||
lambda x : x*2 , # 041 33 21 ! |
||||
None , # 042 34 22 " |
||||
lambda x : x*2 , # 043 35 23 # |
||||
lambda x : x*2 , # 044 36 24 $ |
||||
None , # 045 37 25 % |
||||
None , # 046 38 26 & |
||||
None , # 047 39 27 ' |
||||
None , # 050 40 28 ( |
||||
None , # 051 41 29 ) |
||||
None , # 052 42 2A * |
||||
None , # 053 43 2B + |
||||
None , # 054 44 2C , |
||||
None , # 055 45 2D - |
||||
None , # 056 46 2E . |
||||
None , # 057 47 2F / |
||||
lambda x : x*2 , # 060 48 30 0 |
||||
lambda x : x*2 , # 061 49 31 1 |
||||
lambda x : x*2 , # 062 50 32 2 |
||||
lambda x : x*2 , # 063 51 33 3 |
||||
lambda x : x*2 , # 064 52 34 4 |
||||
None , # 065 53 35 5 |
||||
None , # 066 54 36 6 |
||||
None , # 067 55 37 7 |
||||
None , # 070 56 38 8 |
||||
lambda x : x*2 , # 071 57 39 9 |
||||
None , # 072 58 3A : |
||||
None , # 073 59 3B ; |
||||
None , # 074 60 3C < |
||||
None , # 075 61 3D = |
||||
None , # 076 62 3E > |
||||
None , # 077 63 3F ? |
||||
None , # 100 64 40 @ |
||||
lambda x : x*2 , # 101 65 41 A |
||||
lambda x : x*2 , # 102 66 42 B |
||||
lambda x : x*2 , # 103 67 43 C |
||||
lambda x : x*2 , # 104 68 44 D |
||||
lambda x : x*2 , # 105 69 45 E |
||||
lambda x : x*2 , # 106 70 46 F |
||||
lambda x : x*2 , # 107 71 47 G |
||||
lambda x : x*2 , # 110 72 48 H |
||||
lambda x : x*2 , # 111 73 49 I |
||||
None , # 112 74 4A J |
||||
None , # 113 75 4B K |
||||
None , # 114 76 4C L |
||||
None , # 115 77 4D M |
||||
None , # 116 78 4E N |
||||
None , # 117 79 4F O |
||||
None , # 120 80 50 P |
||||
None , # 121 81 51 Q |
||||
None , # 122 82 52 R |
||||
None , # 123 83 53 S |
||||
None , # 124 84 54 T |
||||
None , # 125 85 55 U |
||||
None , # 126 86 56 V |
||||
None , # 127 87 57 W |
||||
None , # 130 88 58 X |
||||
None , # 131 89 59 Y |
||||
lambda x : x*2 , # 132 90 5A Z |
||||
None , # 133 91 5B [ |
||||
None , # 134 92 5C \ '\\' |
||||
None , # 135 93 5D ] |
||||
None , # 136 94 5E ^ |
||||
None , # 137 95 5F _ |
||||
None , # 140 96 60 ` |
||||
lambda x : x*2 , # 141 97 61 a |
||||
lambda x : x*2 , # 142 98 62 b |
||||
lambda x : x*2 , # 143 99 63 c |
||||
lambda x : x*2 , # 144 100 64 d |
||||
lambda x : x*2 , # 145 101 65 e |
||||
lambda x : x*2 , # 146 102 66 f |
||||
lambda x : x*2 , # 147 103 67 g |
||||
lambda x : x*2 , # 150 104 68 h |
||||
lambda x : x*2 , # 151 105 69 i |
||||
None , # 152 106 6A j |
||||
None , # 153 107 6B k |
||||
None , # 154 108 6C l |
||||
None , # 155 109 6D m |
||||
None , # 156 110 6E n |
||||
None , # 157 111 6F o |
||||
None , # 160 112 70 p |
||||
None , # 161 113 71 q |
||||
None , # 162 114 72 r |
||||
None , # 163 115 73 s |
||||
None , # 164 116 74 t |
||||
None , # 165 117 75 u |
||||
None , # 166 118 76 v |
||||
None , # 167 119 77 w |
||||
None , # 170 120 78 x |
||||
None , # 171 121 79 y |
||||
lambda x : x*2 , # 172 122 7A z |
||||
lambda x : x*2 , # 173 123 7B { |
||||
lambda x : x*2 , # 174 124 7C | |
||||
lambda x : x*2 , # 175 125 7D } |
||||
lambda x : x*2 , # 176 126 7E ~ |
||||
lambda x : x*2 , # 177 127 7F DEL |
||||
] |
||||
|
||||
|
||||
def test1(ttt=testInput): |
||||
ret = 0 |
||||
for ch in ttt: |
||||
op = testDict1.get(ch,None) |
||||
if op: |
||||
ret += op(10) |
||||
return ret |
||||
|
||||
def test2(ttt=testInput): |
||||
ret = 0 |
||||
for ch in ttt: |
||||
if 33 <= (o:=ord(ch)) <= 127: |
||||
op = testArray1[o-33] |
||||
if op: |
||||
ret += op(10) |
||||
return ret |
||||
|
||||
loop = 150000 |
||||
|
||||
a={} |
||||
|
||||
iii = 1 |
||||
while (testName := f'test{iii}') and (testName in globals()): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"test{iii:02}) | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
iii+=1 |
||||
|
||||
@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2023 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
import sys, os |
||||
|
||||
import timeit |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../..')) |
||||
|
||||
testString1 = "1234567890ABCDEFGHI" |
||||
|
||||
class T1: |
||||
def a(self): return 1 |
||||
def b(self): return 2 |
||||
def c(self): return 3 |
||||
def d(self): return 4 |
||||
|
||||
def process1(txt): |
||||
t = T1() |
||||
return t.a() + t.b() + t.c() + t.d() |
||||
|
||||
class T2a: |
||||
def a(self): return 1 |
||||
class T2b(T2a): |
||||
def b(self): return 2 |
||||
class T2c(T2b): |
||||
def c(self): return 3 |
||||
class T2d(T2c): |
||||
def d(self): return 4 |
||||
class T2(T2d): pass |
||||
|
||||
def process2(txt): |
||||
t = T2() |
||||
return t.a() + t.b() + t.c() + t.d() |
||||
|
||||
class T3a: |
||||
def a(self): return 1 |
||||
class T3b: |
||||
def b(self): return 2 |
||||
class T3c: |
||||
def c(self): return 3 |
||||
class T3d: |
||||
def d(self): return 4 |
||||
class T3(T3a, T3b, T3c, T3d): pass |
||||
|
||||
def process3(txt): |
||||
t = T3() |
||||
return t.a() + t.b() + t.c() + t.d() |
||||
|
||||
t1 = T1() |
||||
t2 = T2() |
||||
t3 = T3() |
||||
def process4(t): return ( t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() + |
||||
t.a() + t.b() + t.c() + t.d() ) |
||||
|
||||
|
||||
def test1(): return process1(None) |
||||
def test2(): return process2(None) |
||||
def test3(): return process3(None) |
||||
def test4(): return process4(t1) |
||||
def test5(): return process4(t2) |
||||
def test6(): return process4(t3) |
||||
|
||||
loop = 100000 |
||||
|
||||
a={} |
||||
|
||||
iii = 1 |
||||
while (testName := f'test{iii}') and (testName in globals()): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"test{iii:02}) | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
iii+=1 |
||||
|
||||
Loading…
Reference in new issue