From af482d3da1d87b2638daf52ec3d7cc1afd862e88 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Thu, 5 May 2016 14:22:40 +0200 Subject: [PATCH] experiment with touch event multiplexing Now we can have 2 buttons! --- src/apps/playground/__init__.py | 69 +++++++++++++++++++++++++++++++-- src/trezor/loop.py | 20 +++++----- 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/apps/playground/__init__.py b/src/apps/playground/__init__.py index 2b5698022..95ab05b1c 100644 --- a/src/apps/playground/__init__.py +++ b/src/apps/playground/__init__.py @@ -3,6 +3,50 @@ from trezor import ui from trezor.utils import unimport_func +def multiplex_touch_events(gens): + while True: + e, (x, y) = yield loop.Wait([ + loop.EVT_TSTART, + loop.EVT_TMOVE, + loop.EVT_TEND, + ]) + for gen in gens: + gen.send((e, (x, y))) + + +def in_area(pos, area): + x, y = pos + ax, ay, aw, ah = area + return ax <= x <= ax + aw and ay <= y <= ay + ah + + +def click_in(area, enter, leave): + while True: + e, pos = yield + if e is not loop.EVT_TSTART or not in_area(pos, area): + continue + + inside = True + enter() + + while True: + e, pos = yield + if e is loop.EVT_TMOVE: + if in_area(pos, area): + if not inside: + enter() + inside = True + else: + if inside: + leave() + inside = False + elif e is loop.EVT_TEND: + if in_area(pos, area): + return + else: + break + + def layout_tap_to_confirm(address, amount, currency): ui.display.bar(0, 0, 240, 40, ui.GREEN) @@ -16,18 +60,35 @@ def layout_tap_to_confirm(address, amount, currency): f = open('apps/playground/tap_64.toig', 'rb') bg = ui.WHITE + style = ui.NORMAL + + def enter(): + nonlocal style + style = ui.BOLD + + def leave(): + nonlocal style + style = ui.NORMAL def func(fg): - ui.display.text(68, 212, 'TAP TO CONFIRM', ui.BOLD, fg, bg) + ui.display.text(68, 212, 'TAP TO CONFIRM', style, fg, bg) f.seek(0) ui.display.icon(3, 170, f.read(), bg, fg) animation = ui.animate_pulse(func, ui.BLACK, ui.GREY, speed=200000) + click_up = click_in((0, 0, 240, 40), enter, leave) + click_down = click_in((0, 200, 240, 40), enter, leave) + + next(click_down) + next(click_up) - yield loop.Wait([ + yield loop.Wait(( animation, - loop.EVT_TSTART, - ]) + multiplex_touch_events(( + click_down, + click_up, + )), + )) @unimport_func diff --git a/src/trezor/loop.py b/src/trezor/loop.py index 9ef6462c9..72d2d1b2b 100644 --- a/src/trezor/loop.py +++ b/src/trezor/loop.py @@ -26,14 +26,14 @@ if __debug__: log_delay_rb = array.array('i', [0] * log_delay_rb_len) -def __schedule(gen, time=None): +def __schedule(gen, args=(), time=None): if __debug__: log.debug(__name__, 'Scheduling %s %s', time, gen) if not time: time = utime.ticks_us() - heappush(time_queue, (time, gen)) + heappush(time_queue, (time, gen, args)) class Wait(): @@ -59,7 +59,7 @@ class Wait(): self.received += 1 if self.received == self.wait_for: - __schedule(self.callback) + __schedule(self.callback, (gen, result)) self.callback = None if self.exit_others: @@ -88,7 +88,7 @@ def run_forever(start_gens): while True: if time_queue: - t, _ = time_queue[0] + t, _, _ = time_queue[0] delay = t - utime.ticks_us() else: delay = delay_max @@ -109,18 +109,17 @@ def run_forever(start_gens): if not gen: log.info(__name__, 'No handler for event: %s', event) continue - if not args: - args = None else: if time_queue: # Run something from the time queue - _, gen = heappop(time_queue) - args = None + _, gen, args = heappop(time_queue) else: # Sleep again delay = delay_max continue + if not args: + args = None try: ret = gen.send(args) @@ -134,13 +133,12 @@ def run_forever(start_gens): if isinstance(ret, int) and ret >= 0: # Sleep until ret, call us later - __schedule(gen, ret) + __schedule(gen, (), ret) elif isinstance(ret, int) and ret in event_handlers: # Wait for event if event_handlers[ret]: - raise Exception('Already waiting for %s: %s' % - (ret, event_handlers[ret])) + event_handlers[ret].close() event_handlers[ret] = gen elif isinstance(ret, Wait):