def _stop(self): """ Restore the screen. """ self.clear() signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) self.signal_restore() fd = self._term_input_file.fileno() if os.isatty(fd): termios.tcsetattr(fd, termios.TCSADRAIN, self._old_termios_settings) self._mouse_tracking(False) move_cursor = "" if self._alternate_buffer: move_cursor = escape.RESTORE_NORMAL_BUFFER elif self.maxrow is not None: move_cursor = escape.set_cursor_position( 0, self.maxrow) self.write( self._attrspec_to_escape(AttrSpec('','')) + escape.SI + move_cursor + escape.SHOW_CURSOR) if self._old_signal_keys: self.tty_signal_keys(*(self._old_signal_keys + (fd,))) super(Screen, self)._stop()
def _encode_gpm_event( self ): self.gpm_event_pending = False s = self.gpm_mev.stdout.readline().decode('ascii') l = s.split(",") if len(l) != 6: # unexpected output, stop tracking self._stop_gpm_tracking() signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) return [] ev, x, y, ign, b, m = s.split(",") ev = int( ev.split("x")[-1], 16) x = int( x.split(" ")[-1] ) y = int( y.lstrip().split(" ")[0] ) b = int( b.split(" ")[-1] ) m = int( m.split("x")[-1].rstrip(), 16 ) # convert to xterm-like escape sequence last = next = self.last_bstate l = [] mod = 0 if m & 1: mod |= 4 # shift if m & 10: mod |= 8 # alt if m & 4: mod |= 16 # ctrl def append_button( b ): b |= mod l.extend([ 27, ord('['), ord('M'), b+32, x+32, y+32 ]) if ev == 20: # press if b & 4 and last & 1 == 0: append_button( 0 ) next |= 1 if b & 2 and last & 2 == 0: append_button( 1 ) next |= 2 if b & 1 and last & 4 == 0: append_button( 2 ) next |= 4 elif ev == 146: # drag if b & 4: append_button( 0 + escape.MOUSE_DRAG_FLAG ) elif b & 2: append_button( 1 + escape.MOUSE_DRAG_FLAG ) elif b & 1: append_button( 2 + escape.MOUSE_DRAG_FLAG ) else: # release if b & 4 and last & 1: append_button( 0 + escape.MOUSE_RELEASE_FLAG ) next &= ~ 1 if b & 2 and last & 2: append_button( 1 + escape.MOUSE_RELEASE_FLAG ) next &= ~ 2 if b & 1 and last & 4: append_button( 2 + escape.MOUSE_RELEASE_FLAG ) next &= ~ 4 self.last_bstate = next return l
def start(self, alternate_buffer=True): """ Initialize the screen and input mode. alternate_buffer -- use alternate screen buffer """ assert not self._started if alternate_buffer: self._term_output_file.write(escape.SWITCH_TO_ALTERNATE_BUFFER) self._rows_used = None else: self._rows_used = 0 fd = self._term_input_file.fileno() if os.isatty(fd): self._old_termios_settings = termios.tcgetattr(fd) tty.setcbreak(fd) self.signal_init() self._alternate_buffer = alternate_buffer self._input_iter = self._run_input_iter() self._next_timeout = self.max_wait if not self._signal_keys_set: self._old_signal_keys = self.tty_signal_keys(fileno=fd) super(Screen, self).start() signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) # restore mouse tracking to previous state self._mouse_tracking(self._mouse_tracking_enabled)
def _encode_gpm_event(self): self.gpm_event_pending = False s = self.gpm_mev.stdout.readline() l = s.split(",") if len(l) != 6: # unexpected output, stop tracking self._stop_gpm_tracking() signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) return [] ev, x, y, ign, b, m = s.split(",") ev = int(ev.split("x")[-1], 16) x = int(x.split(" ")[-1]) y = int(y.lstrip().split(" ")[0]) b = int(b.split(" ")[-1]) m = int(m.split("x")[-1].rstrip(), 16) # convert to xterm-like escape sequence last = next = self.last_bstate l = [] mod = 0 if m & 1: mod |= 4 # shift if m & 10: mod |= 8 # alt if m & 4: mod |= 16 # ctrl def append_button(b): b |= mod l.extend([27, ord('['), ord('M'), b + 32, x + 32, y + 32]) if ev == 20: # press if b & 4 and last & 1 == 0: append_button(0) next |= 1 if b & 2 and last & 2 == 0: append_button(1) next |= 2 if b & 1 and last & 4 == 0: append_button(2) next |= 4 elif ev == 146: # drag if b & 4: append_button(0 + escape.MOUSE_DRAG_FLAG) elif b & 2: append_button(1 + escape.MOUSE_DRAG_FLAG) elif b & 1: append_button(2 + escape.MOUSE_DRAG_FLAG) else: # release if b & 4 and last & 1: append_button(0 + escape.MOUSE_RELEASE_FLAG) next &= ~1 if b & 2 and last & 2: append_button(1 + escape.MOUSE_RELEASE_FLAG) next &= ~2 if b & 1 and last & 4: append_button(2 + escape.MOUSE_RELEASE_FLAG) next &= ~4 self.last_bstate = next return l
def stop(self): """ Restore the screen. """ self.clear() if not self._started: return signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) self.signal_restore() fd = self._term_input_file.fileno() if os.isatty(fd): termios.tcsetattr(fd, termios.TCSADRAIN, self._old_termios_settings) self._mouse_tracking(False) move_cursor = "" if self._alternate_buffer: move_cursor = escape.RESTORE_NORMAL_BUFFER elif self.maxrow is not None: move_cursor = escape.set_cursor_position(0, self.maxrow) self._term_output_file.write( self._attrspec_to_escape(AttrSpec('', '')) + escape.SI + move_cursor + escape.SHOW_CURSOR) self._input_iter = self._fake_input_iter() if self._old_signal_keys: self.tty_signal_keys(*(self._old_signal_keys + (fd, ))) super(Screen, self).stop()
def set_position_collapsed(self, pos, is_collapsed): if self._initially_collapsed(pos) == is_collapsed: if pos in self._divergent_positions: self._divergent_positions.remove(pos) signals.emit_signal(self, "modified") else: if pos not in self._divergent_positions: self._divergent_positions.append(pos) signals.emit_signal(self, "modified")
def _start(self, alternate_buffer=True): """ Initialize the screen and input mode. alternate_buffer -- use alternate screen buffer """ if alternate_buffer: self.write(escape.SWITCH_TO_ALTERNATE_BUFFER) self._rows_used = None else: self._rows_used = 0 fd = self._input_fileno() if fd is not None and os.isatty(fd) and not IS_WINDOWS: self._old_termios_settings = termios.tcgetattr(fd) tty.setcbreak(fd) if IS_WINDOWS: hOut = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE) hIn = win32.GetStdHandle(win32.STD_INPUT_HANDLE) self._dwOriginalOutMode = win32.DWORD() self._dwOriginalInMode = win32.DWORD() win32.GetConsoleMode(hOut, byref(self._dwOriginalOutMode)) win32.GetConsoleMode(hIn, byref(self._dwOriginalInMode)) # TODO: Restore on exit dwOutMode = win32.DWORD(self._dwOriginalOutMode.value | win32.ENABLE_VIRTUAL_TERMINAL_PROCESSING | win32.DISABLE_NEWLINE_AUTO_RETURN) dwInMode = win32.DWORD(self._dwOriginalInMode.value | win32.ENABLE_WINDOW_INPUT | win32.ENABLE_VIRTUAL_TERMINAL_INPUT) ok = win32.SetConsoleMode(hOut, dwOutMode) if not ok: raise RuntimeError( "Error enabling virtual terminal processing, " "mitmproxy's console interface requires Windows 10 Build 10586 or above." ) ok = win32.SetConsoleMode(hIn, dwInMode) assert ok else: self.signal_init() self._alternate_buffer = alternate_buffer self._next_timeout = self.max_wait if not self._signal_keys_set and not IS_WINDOWS: self._old_signal_keys = self.tty_signal_keys(fileno=fd) signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) # restore mouse tracking to previous state self._mouse_tracking(self._mouse_tracking_enabled) return super(Screen, self)._start()
def _reset_palette(self, palette: Dict[str, Tuple]): # Reset the palette for activity. We use a bit of urwid implementation # details here, because of lack of public way to do this. self._mainloop.screen._palette = palette.copy() for name, entry in palette.items(): (basic, mono, high_88, high_true) = entry signals.emit_signal( self._mainloop.screen, urwid.UPDATE_PALETTE_ENTRY, name, basic, mono, high_88, high_true, ) self._mainloop.screen.clear()
def _stop(self): """ Restore the screen. """ self.clear() signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) if not IS_WINDOWS: self.signal_restore() fd = self._input_fileno() if fd is not None and os.isatty(fd) and not IS_WINDOWS: termios.tcsetattr(fd, termios.TCSADRAIN, self._old_termios_settings) self._mouse_tracking(False) move_cursor = "" if self._alternate_buffer: move_cursor = escape.RESTORE_NORMAL_BUFFER elif self.maxrow is not None: move_cursor = escape.set_cursor_position( 0, self.maxrow) self.write( self._attrspec_to_escape(AttrSpec('','')) + escape.SI + move_cursor + escape.SHOW_CURSOR) self.flush() if self._old_signal_keys: self.tty_signal_keys(*(self._old_signal_keys + (fd,))) if IS_WINDOWS: hOut = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE) hIn = win32.GetStdHandle(win32.STD_INPUT_HANDLE) ok = win32.SetConsoleMode(hOut, self._dwOriginalOutMode) assert ok ok = win32.SetConsoleMode(hIn, self._dwOriginalInMode) assert ok super(Screen, self)._stop()
def __init__(self, df, col_widths): self._size = None self._focused_col = None self._walker = DataFrameWalker(df=df, col_widths=col_widths) signals.connect_signal( self._walker, 'modified', lambda: signals.emit_signal(self, 'focused_row_changed', self. focus_position), ) super().__init__(self._walker)
def stop(self): """ Restore the screen. """ self.clear() if not self._started: return signals.emit_signal(self, INPUT_DESCRIPTORS_CHANGED) self.signal_restore() fd = self._term_input_file.fileno() if os.isatty(fd): termios.tcsetattr(fd, termios.TCSADRAIN, self._old_termios_settings) move_cursor = "" if self.gpm_mev: self._stop_gpm_tracking() if self._alternate_buffer: move_cursor = escape.RESTORE_NORMAL_BUFFER elif self.maxrow is not None: move_cursor = escape.set_cursor_position( 0, self.maxrow) self._term_output_file.write(self._attrspec_to_escape(AttrSpec('','')) + escape.SI + escape.MOUSE_TRACKING_OFF + escape.SHOW_CURSOR + move_cursor + "\n" + escape.SHOW_CURSOR ) self._input_iter = self._fake_input_iter() if self._old_signal_keys: self.tty_signal_keys(*(self._old_signal_keys + (fd,))) super(Screen, self).stop()
def set_collapsed_all(self, is_collapsed): self._initially_collapsed = lambda x: is_collapsed self._divergent_positions = [] newfocus = self._walker.first_ancestor(self._focus) self.set_focus(newfocus) signals.emit_signal(self, "modified")
def register_palette_entry(self, name, foreground, background, mono=None, foreground_high=None, background_high=None): """Register a single palette entry. name -- new entry/attribute name foreground -- a string containing a comma-separated foreground color and settings Color values: 'default' (use the terminal's default foreground), 'black', 'dark red', 'dark green', 'brown', 'dark blue', 'dark magenta', 'dark cyan', 'light gray', 'dark gray', 'light red', 'light green', 'yellow', 'light blue', 'light magenta', 'light cyan', 'white' Settings: 'bold', 'underline', 'blink', 'standout' Some terminals use 'bold' for bright colors. Most terminals ignore the 'blink' setting. If the color is not given then 'default' will be assumed. background -- a string containing the background color Background color values: 'default' (use the terminal's default background), 'black', 'dark red', 'dark green', 'brown', 'dark blue', 'dark magenta', 'dark cyan', 'light gray' mono -- a comma-separated string containing monochrome terminal settings (see "Settings" above.) None = no terminal settings (same as 'default') foreground_high -- a string containing a comma-separated foreground color and settings, standard foreground colors (see "Color values" above) or high-colors may be used High-color example values: '#009' (0% red, 0% green, 60% red, like HTML colors) '#fcc' (100% red, 80% green, 80% blue) 'g40' (40% gray, decimal), 'g#cc' (80% gray, hex), '#000', 'g0', 'g#00' (black), '#fff', 'g100', 'g#ff' (white) 'h8' (color number 8), 'h255' (color number 255) None = use foreground parameter value background_high -- a string containing the background color, standard background colors (see "Background colors" above) or high-colors (see "High-color example values" above) may be used None = use background parameter value """ basic = AttrSpec(foreground, background, 16) if type(mono) == tuple: # old style of specifying mono attributes was to put them # in a tuple. convert to comma-separated string mono = ",".join(mono) if mono is None: mono = DEFAULT mono = AttrSpec(mono, DEFAULT, 1) if foreground_high is None: foreground_high = foreground if background_high is None: background_high = background high_256 = AttrSpec(foreground_high, background_high, 256) # 'hX' where X > 15 are different in 88/256 color, use # basic colors for 88-color mode if high colors are specified # in this way (also avoids crash when X > 87) def large_h(desc): if not desc.startswith('h'): return False if ',' in desc: desc = desc.split(',',1)[0] num = int(desc[1:], 10) return num > 15 if large_h(foreground_high) or large_h(background_high): high_88 = basic else: high_88 = AttrSpec(foreground_high, background_high, 88) signals.emit_signal(self, UPDATE_PALETTE_ENTRY, name, basic, mono, high_88, high_256) self._palette[name] = (basic, mono, high_88, high_256)
def set_focused_col(self, focused_col): if focused_col != self._focused_col: self._focused_col = focused_col self.body.set_focused_col(focused_col=focused_col) signals.emit_signal(self, 'focused_col_changed', focused_col)
def _modified(self): signals.emit_signal(self, "modified")
def _emit(self, event, state): signals.emit_signal(self, event, Event(type=event, target=self, data={'state': state}))
def _emit(self, name, *args): """ Convenience function to emit signals with self as first argument. """ signals.emit_signal(self, name, self, *args)
def register_palette_entry(self, name, foreground, background, mono=None, foreground_high=None, background_high=None): """Register a single palette entry. name -- new entry/attribute name foreground -- a string containing a comma-separated foreground color and settings Color values: 'default' (use the terminal's default foreground), 'black', 'dark red', 'dark green', 'brown', 'dark blue', 'dark magenta', 'dark cyan', 'light gray', 'dark gray', 'light red', 'light green', 'yellow', 'light blue', 'light magenta', 'light cyan', 'white' Settings: 'bold', 'underline', 'blink', 'standout', 'strikethrough' Some terminals use 'bold' for bright colors. Most terminals ignore the 'blink' setting. If the color is not given then 'default' will be assumed. background -- a string containing the background color Background color values: 'default' (use the terminal's default background), 'black', 'dark red', 'dark green', 'brown', 'dark blue', 'dark magenta', 'dark cyan', 'light gray' mono -- a comma-separated string containing monochrome terminal settings (see "Settings" above.) None = no terminal settings (same as 'default') foreground_high -- a string containing a comma-separated foreground color and settings, standard foreground colors (see "Color values" above) or high-colors may be used High-color example values: '#009' (0% red, 0% green, 60% red, like HTML colors) '#fcc' (100% red, 80% green, 80% blue) 'g40' (40% gray, decimal), 'g#cc' (80% gray, hex), '#000', 'g0', 'g#00' (black), '#fff', 'g100', 'g#ff' (white) 'h8' (color number 8), 'h255' (color number 255) None = use foreground parameter value background_high -- a string containing the background color, standard background colors (see "Background colors" above) or high-colors (see "High-color example values" above) may be used None = use background parameter value """ basic = AttrSpec(foreground, background, 16) if type(mono) == tuple: # old style of specifying mono attributes was to put them # in a tuple. convert to comma-separated string mono = ",".join(mono) if mono is None: mono = DEFAULT mono = AttrSpec(mono, DEFAULT, 1) if foreground_high is None: foreground_high = foreground if background_high is None: background_high = background high_88 = AttrSpec(foreground_high, background_high, 88) high_256 = AttrSpec(foreground_high, background_high, 256) # 'hX' where X > 15 are different in 88/256 color, use # basic colors for 88-color mode if high colors are specified # in this way (also avoids crash when X > 87) def large_h(desc): if not desc.startswith('h'): return False if ',' in desc: desc = desc.split(',', 1)[0] num = int(desc[1:], 10) return num > 15 if large_h(foreground_high) or large_h(background_high): high_88 = basic else: high_88 = AttrSpec(foreground_high, background_high, 88) signals.emit_signal(self, UPDATE_PALETTE_ENTRY, name, basic, mono, high_88, high_256) self._palette[name] = (basic, mono, high_88, high_256)
def _emit(self, event, state): signals.emit_signal(self, event, Event(type=event, target=self, data={"state": state}))
def refresh(self): self._walker.clear_cache() signals.emit_signal(self._walker, "modified")