Skip to content

Commit 56903a4

Browse files
committed
Make waitKey() get input from REPL
Derived from https://github.com/orgs/micropython/discussions/11448
1 parent 7e30426 commit 56903a4

File tree

1 file changed

+51
-8
lines changed

1 file changed

+51
-8
lines changed

src/highgui.cpp

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,56 @@ mp_obj_t cv2_highgui_waitKey(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
5959
// Convert arguments to required types
6060
int delay = args[Arg_delay].u_int;
6161

62-
// Because we have no way to get user input in this environment, we'll just
63-
// delay for the specified time and return a dummy value. Normally, passing
64-
// a delay of 0 would wait infinitely until a keyPress, but since that will
65-
// never happen here, we will just return immediately after the delay.
66-
if(delay > 0)
67-
mp_hal_delay_ms(delay);
62+
// Derived from:
63+
// https://github.com/orgs/micropython/discussions/11448
6864

69-
// Return a dummy value to indicate no key was pressed
70-
return MP_OBJ_NEW_SMALL_INT(-1);
65+
// Import `sys` and `select` modules
66+
mp_obj_t sys_module = mp_import_name(MP_QSTR_sys, mp_const_none, MP_OBJ_NEW_SMALL_INT(0));
67+
mp_obj_t select_module = mp_import_name(MP_QSTR_select, mp_const_none, MP_OBJ_NEW_SMALL_INT(0));
68+
69+
// Get the `sys.stdin` object
70+
mp_obj_t stdin_obj = mp_load_attr(sys_module, MP_QSTR_stdin);
71+
72+
// Get the `select.POLLIN` constant
73+
mp_obj_t pollin_obj = mp_load_attr(select_module, MP_QSTR_POLLIN);
74+
75+
// Call `select.poll()` function to create a poll object
76+
mp_obj_t select_poll_method[2];
77+
mp_load_method(select_module, MP_QSTR_poll, select_poll_method);
78+
mp_obj_t poll_obj = mp_call_method_n_kw(0, 0, select_poll_method);
79+
80+
// Call `poll.register(sys.stdin, select.POLLIN)`
81+
mp_obj_t poll_register_method[4];
82+
mp_load_method(poll_obj, MP_QSTR_register, poll_register_method);
83+
poll_register_method[2] = stdin_obj;
84+
poll_register_method[3] = pollin_obj;
85+
mp_call_method_n_kw(2, 0, poll_register_method);
86+
87+
// Create timeout integer object for next method call. OpenCV uses a delay
88+
// of 0 to wait indefinitely, whereas `select.poll` uses -1
89+
mp_obj_t timeout = MP_OBJ_NEW_SMALL_INT(delay <= 0 ? -1 : delay);
90+
91+
// Call `poll.poll(timeout)`
92+
mp_obj_t poll_poll_method[3];
93+
mp_load_method(poll_obj, MP_QSTR_poll, poll_poll_method);
94+
poll_poll_method[2] = timeout;
95+
mp_obj_t result = mp_call_method_n_kw(1, 0, poll_poll_method);
96+
97+
// Extract the items from the result list
98+
mp_obj_t *items;
99+
size_t len;
100+
mp_obj_list_get(result, &len, &items);
101+
102+
// Check if any items were returned
103+
if(len == 0) {
104+
// If no items were returned, return -1 to indicate no key was pressed
105+
return MP_OBJ_NEW_SMALL_INT(-1);
106+
}
107+
108+
// Since something was returned, a key was pressed. We need to extract it
109+
// with `sys.stdin.read(1)`
110+
mp_obj_t read_method[3];
111+
mp_load_method(stdin_obj, MP_QSTR_read, read_method);
112+
read_method[2] = MP_OBJ_NEW_SMALL_INT(1);
113+
return mp_call_method_n_kw(1, 0, read_method);
71114
}

0 commit comments

Comments
 (0)