def init_audio_plugin(interface_name): """ Find and initialise audio plugin for given interface. """ names = audio_backends[interface_name] for audio_name in names: if audio.init(audio_name): return interface_name logging.debug('Could not initialise %s plugin.', audio_name) logging.error( 'Null sound plugin malfunction. Could not initialise interface.') raise error.Exit()
def check_input(): """ Handle input events. """ while True: try: signal = input_queue.get(False) except Queue.Empty: if not state.console_state.keyb.pause: break else: time.sleep(tick_s) continue # we're on it input_queue.task_done() if signal.event_type == KEYB_QUIT: raise error.Exit() elif signal.event_type == KEYB_CHAR: # params is a unicode sequence state.console_state.keyb.insert_chars(*signal.params) elif signal.event_type == KEYB_DOWN: # params is e-ASCII/unicode character sequence, scancode, modifier state.console_state.keyb.key_down(*signal.params) elif signal.event_type == KEYB_UP: state.console_state.keyb.key_up(*signal.params) elif signal.event_type == PEN_DOWN: state.console_state.pen.down(*signal.params) elif signal.event_type == PEN_UP: state.console_state.pen.up() elif signal.event_type == PEN_MOVED: state.console_state.pen.moved(*signal.params) elif signal.event_type == STICK_DOWN: state.console_state.stick.down(*signal.params) elif signal.event_type == STICK_UP: state.console_state.stick.up(*signal.params) elif signal.event_type == STICK_MOVED: state.console_state.stick.moved(*signal.params) elif signal.event_type == CLIP_PASTE: text = clipboard_handler.paste(*signal.params) state.console_state.keyb.insert_chars(text, check_full=False) elif signal.event_type == CLIP_COPY: text = state.console_state.screen.get_text(*(signal.params[:4])) clipboard_handler.copy(text, signal.params[-1])
def prepare_console(): """ Initialise backend and console. """ import state import backend import sound # load backend modules # this can't be done in backend.py as it would create circular dependency import console import error import fp # we need this prepared for input to work, # even if we don't use any function from it import redirect # hack: mark modules for inclusion by pyinstaller # see https://groups.google.com/forum/#!topic/pyinstaller/S8QgHXiGJ_A if False: import video_none import video_curses import video_ansi import video_cli import video_pygame import audio_none import audio_beep import audio_pygame backends = { 'none': ('video_none', 'audio_none'), 'cli': ('video_cli', 'audio_beep'), 'text': ('video_curses', 'audio_beep'), 'ansi': ('video_ansi', 'audio_beep'), 'graphical': ('video_pygame', 'audio_pygame'), } if not config.get('interface'): config.options['interface'] = 'graphical' # select interface video_name, audio_name = backends[config.get('interface')] # initialise video backend before console while True: try: # __name__ global is needed when calling from setuptools package video = __import__(video_name, globals={"__name__": __name__}) except ImportError as e: video = None if not video: if not video_name or video_name == 'video_none': logging.error('Failed to initialise interface.') raise error.Exit() logging.error('Could not load module %s.', video_name) video_name = 'video_none' continue if backend.init_video(video): break else: video_name = video.fallback if video: video.close() if video_name: logging.info('Falling back to %s interface.', video_name) if config.get('nosound'): sound.audio = __import__('audio_none', globals={"__name__": __name__}) else: sound.audio = __import__(audio_name, globals={"__name__": __name__}) if not sound.init(): sound.audio = __import__('audio_none', globals={"__name__": __name__}) sound.init() logging.warning( 'Failed to initialise sound. Sound will be disabled.\r') if not state.loaded: console.init_mode() # set the output for maths error messages fp.init(error_stream=console) return backend, console
def wait_interactive(prompt_width): """ Manage the interactive mode. """ # force cursor visibility in all cases state.console_state.screen.cursor.show(True) try: # this is where we started start_row = state.console_state.row furthest_left = 1 + prompt_width # this is where we arrow-keyed on the start line furthest_right = state.console_state.col while True: row, col = state.console_state.row, state.console_state.col if row == start_row: furthest_left = min(col, furthest_left) furthest_right = max(col, furthest_right) if col == state.console_state.screen.mode.width and state.console_state.overflow: furthest_right += 1 # wait_char returns one e-ASCII code d = state.console_state.keyb.get_char_block() # insert dbcs chars from keyboard buffer two bytes at a time if (d in state.console_state.codepage.lead and state.console_state.keyb.buf.peek() in state.console_state.codepage.trail): d += state.console_state.keyb.buf.getc() if not d: # input stream closed raise error.Exit() if d in ('\0\x48', '\x1e', '\0\x50', '\x1f', '\0\x4d', '\x1c', '\0\x4B', '\x1d', '\0\x47', '\x0b', '\0\x4f', '\x0e'): # arrow keys drop us out of insert mode set_overwrite_mode(True) if d == '\x03': # CTRL-C -- only caught here, not in wait_char like <CTRL+BREAK> raise error.Break() elif d == '\r': # ENTER, CTRL+M break elif d == '\a': # BEL, CTRL+G state.console_state.sound.beep() elif d == '\b': # BACKSPACE, CTRL+H backspace(start_row, furthest_left) elif d == '\t': # TAB, CTRL+I tab() elif d == '\n': # CTRL+ENTER, CTRL+J line_feed() elif d == '\x1b': # ESC, CTRL+[ clear_line(row, furthest_left) elif d in ('\0\x75', '\x05'): # CTRL+END, CTRL+E clear_rest_of_line(row, col) elif d in ('\0\x48', '\x1e'): # UP, CTRL+6 set_pos(row - 1, col, scroll_ok=False) elif d in ('\0\x50', '\x1f'): # DOWN, CTRL+- set_pos(row + 1, col, scroll_ok=False) elif d in ('\0\x4D', '\x1c'): # RIGHT, CTRL+\ # skip dbcs trail byte if state.console_state.screen.apage.row[row - 1].double[col - 1] == 1: set_pos(row, col + 2, scroll_ok=False) else: set_pos(row, col + 1, scroll_ok=False) elif d in ('\0\x4b', '\x1d'): # LEFT, CTRL+] set_pos(row, col - 1, scroll_ok=False) elif d in ('\0\x74', '\x06'): # CTRL+RIGHT, CTRL+F skip_word_right() elif d in ('\0\x73', '\x02'): # CTRL+LEFT, CTRL+B skip_word_left() elif d in ('\0\x52', '\x12'): # INS, CTRL+R set_overwrite_mode(not state.console_state.overwrite_mode) elif d in ('\0\x53', '\x7f'): # DEL, CTRL+BACKSPACE delete_char(row, col) elif d in ('\0\x47', '\x0b'): # HOME, CTRL+K set_pos(1, 1) elif d in ('\0\x4f', '\x0e'): # END, CTRL+N end() elif d in ('\0\x77', '\x0c'): # CTRL+HOME, CTRL+L clear() else: try: # these are done on a less deep level than the fn key macros letters = list(alt_key_replace[d]) + [' '] except KeyError: letters = [d] for d in letters: # ignore eascii by this point, but not dbcs if d[0] not in ('\0', '\r'): if not state.console_state.overwrite_mode: for c in d: insert(row, col, c, state.console_state.screen.attr) # row and col have changed state.console_state.screen.redraw_row( col - 1, row) col += 1 set_pos(state.console_state.row, state.console_state.col + len(d)) else: # put all dbcs in before messing with cursor position for c in d: put_char(c, do_scroll_down=True) # move left if we end up on dbcs trail byte row, col = state.console_state.row, state.console_state.col if state.console_state.screen.apage.row[row - 1].double[col - 1] == 2: set_pos(row, col - 1, scroll_ok=False) # adjust cursor width row, col = state.console_state.row, state.console_state.col if state.console_state.screen.apage.row[row - 1].double[col - 1] == 1: state.console_state.screen.cursor.set_width(2) else: state.console_state.screen.cursor.set_width(1) finally: set_overwrite_mode(True) # reset cursor visibility state.console_state.screen.cursor.reset_visibility() return start_row, furthest_left, furthest_right