Skip to content

Commit

Permalink
tty implementation done
Browse files Browse the repository at this point in the history
  • Loading branch information
koehlma committed Dec 10, 2015
1 parent a2424bc commit 1e00c3c
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 10 deletions.
2 changes: 1 addition & 1 deletion uv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
from .handles.stream import Stream, ShutdownRequest, ConnectRequest
from .handles.tcp import TCP, TCPFlags
from .handles.timer import Timer
from .handles.tty import TTY
from .handles.tty import TTY, reset_mode, TTYMode, ConsoleSize
from .handles.udp import UDP, UDPFlags, UDPMembership, SendRequest

from .handles.fs_monitor import FSMonitor, FSEvent, FSEventFlags
Expand Down
87 changes: 78 additions & 9 deletions uv/handles/tty.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,117 @@

from __future__ import print_function, unicode_literals, division

from collections import namedtuple

from uv.library import ffi, lib
from ..library import ffi, lib

from ..common import Enumeration
from ..error import UVError
from ..error import UVError, HandleClosedError
from ..handle import HandleType

from .stream import Stream

WinSize = namedtuple('WinSize', ['width', 'height'])

class ConsoleSize(tuple):
def __new__(cls, width, height):
return tuple.__new__(cls, (width, height))

def __init__(self, width, height):
super(ConsoleSize, self).__init__((width, height))

@property
def width(self):
return self[0]

@property
def height(self):
return self[1]


def reset_mode():
"""
To be called when the program exits. Resets TTY settings to default
values for the next process to take over.
This function is async signal-safe on Unix platforms but can fail with
error code UV_EBUSY if you call it when execution is inside `set_mode()`.
:raises uv.UVError: error while resetting tty mode
"""
code = lib.uv_tty_reset_mode()
if code < 0: raise UVError(code)


class TTYMode(Enumeration):
"""
TTY modes enumeration.
"""

NORMAL = lib.UV_TTY_MODE_NORMAL
"""
initial normal terminal mode
"""
RAW = lib.UV_TTY_MODE_RAW
"""
raw input mode (on windows, `ENABLE_WINDOW_INPUT` is also enabled)
"""
IO = lib.UV_TTY_MODE_IO
"""
binary-safe IO mode for IPC (Unix only)
"""


@HandleType.TTY
class TTY(Stream):
"""
TTY handles represent a stream for the console.
:raises uv.UVError: error while initializing the handle
:param fd: file descriptor
:param readable: specifies whether the file descriptor is readable or not
:param loop: event loop the handle should run on
:param ipc: inter process communication support
:type fd: int
:type readable: bool
:type loop: uv.Loop
:type ipc: bool
"""

__slots__ = ['uv_tty']

def __init__(self, fd, readable=False, loop=None):
def __init__(self, fd, readable=False, loop=None, ipc=False):
self.uv_tty = ffi.new('uv_tty_t*')
super(TTY, self).__init__(self.uv_tty, loop)
super(TTY, self).__init__(self.uv_tty, ipc, loop)
code = lib.cross_uv_tty_init(self.loop.uv_loop, self.uv_tty, fd, int(readable))
if code < 0:
self.destroy()
raise UVError(code)

@property
def winsize(self):
def console_size(self):
"""
Current size of the console.
:raises uv.UVError: error while getting console size
:rtype: ConsoleSize
"""
if self.closing: return ConsoleSize(0, 0)
c_with, c_height = ffi.new('int*'), ffi.new('int*')
code = lib.uv_tty_get_winsize(self.uv_tty, c_with, c_height)
if code < 0: raise UVError(code)
return WinSize(c_with[0], c_height[0])
return ConsoleSize(c_with[0], c_height[0])

def set_mode(self, mode=TTYMode.NORMAL):
"""
Set the TTY using the specified terminal mode.
:raises uv.UVError: error while setting mode
:raises uv.HandleClosedError: handle has already been closed or is closing
:param mode: mode to set
:type mode: uv.TTYMode
"""
if self.closing: raise HandleClosedError()
code = lib.uv_tty_set_mode(self.uv_tty, mode)
if code < 0: raise UVError(code)

0 comments on commit 1e00c3c

Please sign in to comment.