@@ -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