tuikit/driver/curses.py
author Radek Brich <radek.brich@devl.cz>
Sat, 15 Mar 2014 14:43:47 +0100
changeset 84 04dfb5ddf031
parent 83 ebe732b9ef19
child 86 0978fb755d31
permissions -rw-r--r--
Refactor Driver, CursesDriver: draw, setattr, input.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     2
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     3
import curses.ascii
57
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
     4
import math
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     5
import logging
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     6
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
     7
from tuikit.driver.driver import Driver
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     8
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     9
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    10
class CursesDriver(Driver):
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    11
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    12
    key_codes = (
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    13
        (0x09,                      'tab'           ),
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    14
        (0x0a,                      'enter'         ),
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    15
        (0x7f,                      'backspace'     ),
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
    16
        (0x1b,                      'escape'        ),
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    17
        (0x1b, 0x4f, 0x50,          'f1'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    18
        (0x1b, 0x4f, 0x51,          'f2'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    19
        (0x1b, 0x4f, 0x52,          'f3'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    20
        (0x1b, 0x4f, 0x53,          'f4'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    21
        (0x1b, 0x5b,                'CSI'           ),  # see csi_codes
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    22
        (0x1b, 0x5b, 0x4d,          'mouse'         ),
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    23
    )
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    24
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    25
    # http://en.wikipedia.org/wiki/ANSI_escape_code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    26
    csi_codes = (
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    27
        # code            param     key name
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    28
        (0x7e,              1,      'home'          ),  # linux
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    29
        (0x7e,              2,      'insert'        ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    30
        (0x7e,              3,      'delete'        ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    31
        (0x7e,              4,      'end'           ),  # linux
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    32
        (0x7e,              5,      'pageup'        ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    33
        (0x7e,              6,      'pagedown'      ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    34
        (0x7e,              15,     'f5'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    35
        (0x7e,              17,     'f6'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    36
        (0x7e,              18,     'f7'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    37
        (0x7e,              19,     'f8'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    38
        (0x7e,              20,     'f9'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    39
        (0x7e,              21,     'f10'           ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    40
        (0x7e,              23,     'f11'           ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    41
        (0x7e,              24,     'f12'           ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    42
        (0x41,              1,      'up'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    43
        (0x42,              1,      'down'          ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    44
        (0x43,              1,      'right'         ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    45
        (0x44,              1,      'left'          ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    46
        (0x46,              1,      'end'           ),  # xterm
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    47
        (0x48,              1,      'home'          ),  # xterm
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    48
        (0x5b, 0x41,        1,      'f1'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    49
        (0x5b, 0x42,        1,      'f2'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    50
        (0x5b, 0x43,        1,      'f3'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    51
        (0x5b, 0x44,        1,      'f4'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    52
        (0x5b, 0x45,        1,      'f5'            ),  # linux
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    53
    )
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    54
27
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    55
    color_map = {
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    56
        'default':      (-1,                    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    57
        'black':        (curses.COLOR_BLACK,    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    58
        'blue':         (curses.COLOR_BLUE,     0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    59
        'green':        (curses.COLOR_GREEN,    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    60
        'cyan':         (curses.COLOR_CYAN,     0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    61
        'red':          (curses.COLOR_RED,      0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    62
        'magenta':      (curses.COLOR_MAGENTA,  0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    63
        'brown':        (curses.COLOR_YELLOW,   0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    64
        'lightgray':    (curses.COLOR_WHITE,    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    65
        'gray':         (curses.COLOR_BLACK,    curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    66
        'lightblue':    (curses.COLOR_BLUE,     curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    67
        'lightgreen':   (curses.COLOR_GREEN,    curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    68
        'lightcyan':    (curses.COLOR_CYAN,     curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    69
        'lightred':     (curses.COLOR_RED,      curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    70
        'lightmagenta': (curses.COLOR_MAGENTA,  curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    71
        'yellow':       (curses.COLOR_YELLOW,   curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    72
        'white':        (curses.COLOR_WHITE,    curses.A_BOLD),
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    73
    }
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    74
27
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    75
    attr_map = {
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    76
        'bold':         curses.A_BOLD,
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    77
        'underline':    curses.A_UNDERLINE,
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    78
        'standout':     curses.A_STANDOUT,  # inverse bg/fg
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    79
        'blink':        curses.A_BLINK,
27
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    80
    }
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    81
23
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    82
    def __init__(self):
24
b248ef500557 Add DriverPygame (incomplete). Move unicode graphics constants to UnicodeGraphics class. Move shared parts of drivers to Driver base class.
Radek Brich <radek.brich@devl.cz>
parents: 23
diff changeset
    83
        Driver.__init__(self)
b248ef500557 Add DriverPygame (incomplete). Move unicode graphics constants to UnicodeGraphics class. Move shared parts of drivers to Driver base class.
Radek Brich <radek.brich@devl.cz>
parents: 23
diff changeset
    84
        self.log = logging.getLogger('tuikit')
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    85
        self.stdscr = None
5
ae128c885d0f New GridLayout. Change cursor behavior (hide on unfocus event). Change resize event to propagate through containers. Change container clipping - allowlayout=false children are clipped without borders. More Widget doc.
Radek Brich <radek.brich@devl.cz>
parents: 4
diff changeset
    86
        self.cursor = None
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    87
        self.colors = {}     # maps names to curses attributes
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    88
        self.colorpairs = {} # maps tuple (fg,bg) to curses color_pair
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    89
        self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    90
        self.inputqueue = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    91
        self.mbtnstack = []
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
    92
        self._mouse_last_pos = (None, None)
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
    93
        self._mouse_last_bstate = None
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    94
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    95
    ## initialization, finalization ##
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    96
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    97
    def init(self):
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    98
        """Initialize curses"""
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    99
        self.stdscr = curses.initscr()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   100
        curses.start_color()
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   101
        curses.use_default_colors()
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   102
        curses.noecho()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   103
        curses.cbreak()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   104
        self.stdscr.keypad(0)
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   105
        self.stdscr.immedok(0)
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   106
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   107
        self.size.h, self.size.w = self.stdscr.getmaxyx()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   108
23
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   109
        curses.curs_set(False)  # hide cursor
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   110
        curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   111
        curses.mouseinterval(0)  # do not wait to detect clicks, we use only press/release
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   112
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   113
    def close(self):
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   114
        self.stdscr.keypad(0)
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   115
        curses.echo()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   116
        curses.nocbreak()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   117
        curses.endwin()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   118
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   119
    ## drawing ##
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   120
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   121
    def erase(self):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   122
        self.stdscr.erase()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   123
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   124
    def putch(self, x, y, c):
23
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   125
        if not self.clipstack.test(x, y):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   126
            return
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   127
        try:
10
ec1d47e6fe09 Use isinstance instead of type.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   128
            if isinstance(c, str) and len(c) == 1:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   129
                self.stdscr.addstr(y, x, c)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   130
            else:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   131
                self.stdscr.addch(y, x, c)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   132
        except curses.error:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   133
            pass
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   134
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   135
    def draw(self, buffer, x=0, y=0):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   136
        for bufy in range(buffer.size.h):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   137
            for bufx in range(buffer.size.w):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   138
                char, attr_desc = buffer.get(bufx, bufy)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   139
                self.setattr(attr_desc)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   140
                self.putch(x + bufx, y + bufy, char)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   141
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   142
    def flush(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   143
        if self.cursor:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   144
            self.stdscr.move(*self.cursor)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   145
            curses.curs_set(True)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   146
        else:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   147
            curses.curs_set(False)
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   148
        self.stdscr.refresh()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   149
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   150
    ## colors, attributes ##
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   151
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   152
    def setattr(self, attr_desc):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   153
        """Set attribute to be used for subsequent draw operations."""
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   154
        attr = self.colors.get(attr_desc, None)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   155
        if attr is None:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   156
            # first encountered `attr_desc`, initialize
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   157
            fg, bg, attrs = self._parse_attr_desc(attr_desc)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   158
            fgcol, fgattr = self.color_map[fg]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   159
            bgcol, _bgattr = self.color_map[bg]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   160
            colpair = self._getcolorpair(fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   161
            attr = curses.color_pair(colpair) | self._parseattrs(attrs) | fgattr
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   162
            self.colors[attr_desc] = attr
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   163
        self.stdscr.attrset(attr)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   164
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   165
    def _getcolorpair(self, fgcol, bgcol):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   166
        pair = (fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   167
        if pair in self.colorpairs:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   168
            return self.colorpairs[pair]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   169
        num = len(self.colorpairs) + 1
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   170
        curses.init_pair(num, fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   171
        self.colorpairs[pair] = num
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   172
        return num
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   173
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   174
    def _parseattrs(self, attrs):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   175
        res = 0
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   176
        for a in attrs:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   177
            res = res | self.attr_map[a]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   178
        return res
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   179
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   180
    ## cursor ##
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   181
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   182
    def showcursor(self, x, y):
77
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   183
        if self.clipstack.test(x, y):
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   184
            self.cursor = (y, x)
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   185
        else:
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   186
            self.cursor = None
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
   187
5
ae128c885d0f New GridLayout. Change cursor behavior (hide on unfocus event). Change resize event to propagate through containers. Change container clipping - allowlayout=false children are clipped without borders. More Widget doc.
Radek Brich <radek.brich@devl.cz>
parents: 4
diff changeset
   188
    def hidecursor(self):
ae128c885d0f New GridLayout. Change cursor behavior (hide on unfocus event). Change resize event to propagate through containers. Change container clipping - allowlayout=false children are clipped without borders. More Widget doc.
Radek Brich <radek.brich@devl.cz>
parents: 4
diff changeset
   189
        curses.curs_set(False)
ae128c885d0f New GridLayout. Change cursor behavior (hide on unfocus event). Change resize event to propagate through containers. Change container clipping - allowlayout=false children are clipped without borders. More Widget doc.
Radek Brich <radek.brich@devl.cz>
parents: 4
diff changeset
   190
        self.cursor = None
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   191
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   192
    ## input, events ##
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   193
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   194
    def getevents(self, timeout=None):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   195
        """Process input, return list of events.
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   196
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   197
        timeout -- float, in seconds (None=infinite)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   198
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   199
        Returns:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   200
            [('event', param1, ...), ...]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   201
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   202
        """
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   203
        # empty queue -> fill
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   204
        if len(self.inputqueue) == 0:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   205
            if timeout is not None:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   206
                timeout = math.ceil(timeout * 10)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   207
            self._inputqueue_fill(timeout)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   208
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   209
        res = []
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   210
        while len(self.inputqueue):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   211
            c = self._inputqueue_get()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   212
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   213
            if c == curses.KEY_MOUSE:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   214
                res += self._process_mouse()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   215
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   216
            elif c == curses.KEY_RESIZE:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   217
                self.size.h, self.size.w = self.stdscr.getmaxyx()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   218
                res.append(('resize',))
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   219
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   220
            elif curses.ascii.isctrl(c):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   221
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   222
                res += self._process_control_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   223
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   224
            elif 192 <= c <= 255:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   225
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   226
                res += self._process_utf8_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   227
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   228
            elif curses.ascii.isprint(c):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   229
                res += [('keypress', None, str(chr(c)))]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   230
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   231
            else:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   232
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   233
                res += self._process_control_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   234
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   235
        return res
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   236
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   237
    def _inputqueue_fill(self, timeout=None):
57
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   238
        """Wait for curses input, add it to inputqueue.
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   239
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   240
        timeout -- int, tenths of second (None=infinite)
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   241
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   242
        """
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   243
        if timeout is None:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   244
            # wait indefinitely
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   245
            c = self.stdscr.getch()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   246
            self.inputqueue.insert(0, c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   247
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   248
        elif timeout > 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   249
            # wait
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   250
            curses.halfdelay(timeout)
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   251
            c = self.stdscr.getch()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   252
            curses.cbreak()
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   253
            if c == -1:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   254
                return
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   255
            self.inputqueue.insert(0, c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   256
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   257
        # timeout = 0 -> no wait
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   258
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   259
        self.stdscr.nodelay(1)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   260
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   261
        while True:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   262
            c = self.stdscr.getch()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   263
            if c == -1:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   264
                break
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   265
            self.inputqueue.insert(0, c)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   266
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   267
        self.stdscr.nodelay(0)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   268
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   269
    def _inputqueue_get(self):
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   270
        c = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   271
        try:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   272
            c = self.inputqueue.pop()
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   273
        except IndexError:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   274
            pass
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   275
        return c
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   276
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   277
    def _inputqueue_get_wait(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   278
        c = None
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   279
        while c is None:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   280
            try:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   281
                c = self.inputqueue.pop()
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   282
            except IndexError:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   283
                curses.napms(25)
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   284
                self._inputqueue_fill(0)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   285
        return c
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   286
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   287
    def _inputqueue_unget(self, c):
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   288
        self.inputqueue.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   289
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   290
    def _process_mouse(self):
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   291
        try:
25
f69a1f0382ce Partial DriverPygame.putch() implementation. Add patch for PyGame implementing font.render_glyph(). Add test for PyGame font module. Add special key definitions to DriverPygame.
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
   292
            _id, x, y, _z, bstate = curses.getmouse()
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   293
        except curses.error:
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   294
            return []
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   295
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   296
        out = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   297
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   298
        if bstate & curses.REPORT_MOUSE_POSITION:
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   299
            if self._mouse_last_pos != (x, y):
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   300
                if self._mouse_last_pos[0] is not None:
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   301
                    relx = x - (self._mouse_last_pos[0] or 0)
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   302
                    rely = y - (self._mouse_last_pos[1] or 0)
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   303
                    out += [('mousemove', 0, x, y, relx, rely)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   304
                self._mouse_last_pos = (x, y)
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   305
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   306
        # we are interested only in changes, not buttons already pressed before event
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   307
        if self._mouse_last_bstate is not None:
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   308
            old = self._mouse_last_bstate
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   309
            new = bstate
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   310
            bstate = ~old & new
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   311
            self._mouse_last_bstate = new
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   312
        else:
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   313
            self._mouse_last_bstate = bstate
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   314
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   315
        if bstate & curses.BUTTON1_PRESSED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   316
            out += [('mousedown', 1, x, y)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   317
        if bstate & curses.BUTTON2_PRESSED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   318
            out += [('mousedown', 2, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   319
        if bstate & curses.BUTTON3_PRESSED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   320
            out += [('mousedown', 3, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   321
        if bstate & curses.BUTTON1_RELEASED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   322
            out += [('mouseup', 1, x, y)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   323
        if bstate & curses.BUTTON2_RELEASED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   324
            out += [('mouseup', 2, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   325
        if bstate & curses.BUTTON3_RELEASED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   326
            out += [('mouseup', 3, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   327
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   328
        # reset last pos when pressed/released
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   329
        if len(out) > 0 and out[-1][0] in ('mousedown', 'mouseup'):
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   330
            self._mouse_last_pos = (None, None)
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   331
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   332
        return out
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   333
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   334
    def _process_utf8_chars(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   335
        #FIXME read exact number of chars as defined by utf-8
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   336
        utf = []
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   337
        while len(utf) <= 6:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   338
            c = self._inputqueue_get_wait()
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   339
            utf.append(c)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   340
            try:
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   341
                uni = str(bytes(utf), 'utf-8')
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   342
                return [('keypress', None, uni)]
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   343
            except UnicodeDecodeError:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   344
                continue
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   345
        raise Exception('Invalid UTF-8 sequence: %r' % utf)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   346
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   347
    def _process_control_chars(self):
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   348
        codes = self.key_codes
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   349
        matchingcodes = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   350
        match = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   351
        consumed = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   352
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   353
        # consume next char, filter out matching codes
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   354
        c = self._inputqueue_get_wait()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   355
        consumed.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   356
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   357
        while True:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   358
            #self.log.debug('c=%s len=%s', c, len(codes))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   359
            for code in codes:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   360
                if c == code[len(consumed)-1]:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   361
                    if len(code) - 1 == len(consumed):
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   362
                        match = code
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   363
                    else:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   364
                        matchingcodes += [code]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   365
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   366
            #self.log.debug('matching=%s', len(matchingcodes))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   367
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   368
            # match found, or no matching code found -> stop
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   369
            if len(matchingcodes) == 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   370
                break
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   371
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   372
            # match found and some sequencies still match -> continue
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   373
            if len(matchingcodes) > 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   374
                if len(self.inputqueue) == 0:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   375
                    self._inputqueue_fill(1)
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   376
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   377
            c = self._inputqueue_get()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   378
            if c:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   379
                consumed.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   380
                codes = matchingcodes
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   381
                matchingcodes = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   382
            else:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   383
                break
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   384
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   385
        keyname = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   386
        if match:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   387
            # compare match to consumed, return unused chars
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   388
            l = len(match) - 1
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   389
            while len(consumed) > l:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   390
                self._inputqueue_unget(consumed[-1])
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   391
                del consumed[-1]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   392
            keyname = match[-1]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   393
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   394
        if match is None:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   395
            self.log.debug('Unknown control sequence: %s',
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   396
                           ','.join(['0x%x' % x for x in consumed]))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   397
            return [('keypress', 'Unknown', None)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   398
66
Radek Brich <radek.brich@devl.cz>
parents: 65
diff changeset
   399
        if keyname == 'mouse':
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   400
            return self._process_xterm_mouse()
66
Radek Brich <radek.brich@devl.cz>
parents: 65
diff changeset
   401
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   402
        if keyname == 'CSI':
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   403
            return self._process_control_sequence()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   404
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   405
        return [('keypress', keyname, None)]
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   406
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   407
    def _process_xterm_mouse(self):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   408
        t = self._inputqueue_get_wait()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   409
        x = self._inputqueue_get_wait() - 0x21
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   410
        y = self._inputqueue_get_wait() - 0x21
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   411
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   412
        out = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   413
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   414
        if t in (0x20, 0x21, 0x22):
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   415
            # button press
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   416
            btn = t - 0x1f
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   417
            if not btn in self.mbtnstack:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   418
                self.mbtnstack.append(btn)
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   419
                self._mouse_last_pos = (None, None)
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   420
                out += [('mousedown', btn, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   421
            else:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   422
                # mouse move
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   423
                if self._mouse_last_pos != (x, y):
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   424
                    if self._mouse_last_pos[0] is not None:
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   425
                        relx = x - self._mouse_last_pos[0]
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   426
                        rely = y - self._mouse_last_pos[1]
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   427
                        out += [('mousemove', btn, x, y, relx, rely)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   428
                    self._mouse_last_pos = (x, y)
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   429
        elif t == 0x23:
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   430
            # button release
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   431
            btn = self.mbtnstack.pop()
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   432
            self._mouse_last_pos = (None, None)
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   433
            out += [('mouseup', btn, x, y)]
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   434
        elif t in (0x60, 0x61):
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   435
            # wheel up, down
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   436
            btn = 4 + t - 0x60
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   437
            out += [('mousewheel', btn, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   438
        else:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   439
            raise Exception('Unknown mouse event: %x' % t)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   440
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   441
        return out
29
c0cdef06fd16 Import only one driver from application.
Radek Brich <radek.brich@devl.cz>
parents: 27
diff changeset
   442
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   443
    def _process_control_sequence(self):
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   444
        codes = self.csi_codes
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   445
        debug_seq = [0x1b, 0x5b]
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   446
        c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   447
        debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   448
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   449
        # numeric parameters?
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   450
        params = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   451
        if chr(c).isdigit():
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   452
            params.append(chr(c))
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   453
            while True:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   454
                c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   455
                debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   456
                if chr(c).isdigit():
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   457
                    params[-1] += chr(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   458
                elif chr(c) == ';':
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   459
                    params.append('')
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   460
                else:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   461
                    break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   462
        params = [int(x) for x in params]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   463
        if len(params) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   464
            params = [1]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   465
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   466
        # filter codes using byte sequence
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   467
        while True:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   468
            matching_codes = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   469
            for code in codes:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   470
                if len(code) > 2 and code[0] == c:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   471
                    matching_codes.append(code[1:])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   472
            codes = matching_codes
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   473
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   474
            if len(codes) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   475
                # no match -> unknown code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   476
                seq = ','.join(['0x%x' % x for x in debug_seq])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   477
                self.log.debug('Unknown control sequence: %s', seq)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   478
                return [('keypress', 'Unknown:' + seq, None)]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   479
            elif len(codes) == 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   480
                # one match -> we got the winner
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   481
                break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   482
            elif len(codes[0]) == 2:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   483
                # more than one matching, but no more chars to check
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   484
                # will be sorted out using parameters
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   485
                break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   486
            else:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   487
                # more than one matching -> continue loop
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   488
                c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   489
                debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   490
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   491
        # filter codes using first parameter
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   492
        matching_codes = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   493
        for code in codes:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   494
            if params[0] == code[0] or params[0] is None:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   495
                matching_codes.append(code)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   496
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   497
        if len(matching_codes) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   498
            # no match -> unknown code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   499
            seq = ','.join(['0x%x' % x for x in debug_seq])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   500
            self.log.debug('Unknown control sequence: %s', seq)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   501
            return [('keypress', 'Unknown:' + seq, None)]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   502
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   503
        if len(matching_codes) > 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   504
            raise Exception('Internal error: invalid csi_codes, more than one matching')
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   505
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   506
        keyname = matching_codes[0][1]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   507
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   508
        # modifiers
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   509
        mod = 0
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   510
        if len(params) > 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   511
            mod = params[1] - 1
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   512
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   513
        return [('keypress', keyname, None, mod)]