diff --git a/extmod/moductypes.c b/extmod/moductypes.c index b3a20937e2053..ba84c63525a42 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -378,7 +378,12 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(uctypes_struct_sizeof_obj, 1, 2, ucty mp_obj_t uctypes_get_struct_desc(mp_obj_t arg) { if (is_struct_instance(arg)) { mp_obj_uctypes_struct_t *struct_ = MP_OBJ_TO_PTR(arg); - return struct_->desc; + arg = struct_->desc; + if (is_struct_type(arg)) { + mp_obj_ctypes_struct_type_t *struct_type = MP_OBJ_TO_PTR(arg); + return struct_type->desc; + } + return arg; } if (is_struct_type(arg)) { mp_obj_ctypes_struct_type_t *struct_type = MP_OBJ_TO_PTR(arg); diff --git a/extmod/multiverse_support.c b/extmod/multiverse_support.c index 826c04cd6fced..15695187ed977 100644 --- a/extmod/multiverse_support.c +++ b/extmod/multiverse_support.c @@ -85,6 +85,11 @@ void *to_struct_helper(mp_obj_t obj, const mp_obj_type_t *struct_type, bool is_c if (obj == mp_const_none) { return NULL; } + if (struct_type == (const mp_obj_type_t *)&char_obj) { // C type is 'Ptr', we don't know what it is + mp_buffer_info_t bufinfo = {0}; + mp_get_buffer_raise(obj, &bufinfo, is_const ? MP_BUFFER_READ : MP_BUFFER_READ | MP_BUFFER_WRITE); + return bufinfo.buf; + } if (struct_type && !mp_obj_is_type(obj, struct_type)) { mp_obj_t arg_descr = uctypes_get_struct_desc(obj); mp_obj_t type_descr = uctypes_get_struct_desc(MP_OBJ_FROM_PTR(struct_type)); @@ -95,10 +100,10 @@ void *to_struct_helper(mp_obj_t obj, const mp_obj_type_t *struct_type, bool is_c // w = WindowMgr.NewWindow(...) // qd.SetPort(w) // ``` - // which would otherwise say `TypeError: p must be of type GrafPort, not GrafPtr + // which would otherwise say `TypeError: p must be of type GrafPtr, not GrafPort // // (currently) mkapi treats the argument to SetPort - // as a GrafPort. But `GrafPtr` is a typedef to `GrafPort*`. It might be + // as a GrafPtr. But `GrafPtr` is a typedef to `GrafPort*`. It might be // better to fix this in mkapi, but instead cater here... mp_buffer_info_t bufinfo = {0}; diff --git a/ports/m68kmac/examples/textbox.py b/ports/m68kmac/examples/textbox.py new file mode 100644 index 0000000000000..3412e6a303a1b --- /dev/null +++ b/ports/m68kmac/examples/textbox.py @@ -0,0 +1,13 @@ +import mactypes +import textedit +import toolboxevent +import deskmgr + +teJustCenter = 1 +textRect = mactypes.Rect(135, 10, 270, 487) +text = bytearray(b"\r".join([b"Hello, World", b"This is MicroPython calling TETextBox", b"", b"Click to exit"])) +textedit.TETextBox(text, len(text), textRect, textedit.teJustCenter) + + +while not toolboxevent.Button(): + deskmgr.SystemTask() # scott added - slows it down on fast machines diff --git a/ports/m68kmac/main.c b/ports/m68kmac/main.c index 29fff92d6b5db..2ffd65dd18445 100644 --- a/ports/m68kmac/main.c +++ b/ports/m68kmac/main.c @@ -70,6 +70,9 @@ int main(int argc, char **argv) { size_t heap_size = growmax / 2; unsigned char *heap = (unsigned char *)NewPtr(growmax / 2); + // show the console window always + mp_hal_stdin_init(); + // Check if we were given a file ... short message, count; CountAppFiles(&message, &count); diff --git a/ports/m68kmac/modmachine.c b/ports/m68kmac/modmachine.c new file mode 100644 index 0000000000000..116c01b610f75 --- /dev/null +++ b/ports/m68kmac/modmachine.c @@ -0,0 +1,26 @@ +// This file is never compiled standalone, it's included directly from +// extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE. + +#include "uart_core.h" + +static void mp_machine_idle(void) { + mp_console_idle(true); +} + +static mp_obj_t machine_show_console_fn(void) { + mp_console_showhide(true); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(machine_show_console_obj, machine_show_console_fn); + +static mp_obj_t machine_hide_console_fn(void) { + mp_console_showhide(false); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(machine_hide_console_obj, machine_hide_console_fn); + +#define MICROPY_PY_MACHINE_EXTRA_GLOBALS \ + { MP_ROM_QSTR(MP_QSTR_ShowConsole), MP_ROM_PTR(&machine_show_console_obj) }, \ + { MP_ROM_QSTR(MP_QSTR_HideConsole), MP_ROM_PTR(&machine_hide_console_obj) }, \ + diff --git a/ports/m68kmac/mpconfigport.h b/ports/m68kmac/mpconfigport.h index 2a3424e601c3c..63ec2cd79143c 100644 --- a/ports/m68kmac/mpconfigport.h +++ b/ports/m68kmac/mpconfigport.h @@ -57,3 +57,6 @@ typedef long mp_off_t; typedef struct _mp_obj_type_t mp_obj_type_t; extern const mp_obj_type_t mp_type_vfs_mac; #define MICROPY_VFS_PORT { MP_ROM_QSTR(MP_QSTR_VfsMac), MP_ROM_PTR(&mp_type_vfs_mac) } + +#define MICROPY_PY_MACHINE (1) +#define MICROPY_PY_MACHINE_INCLUDEFILE "ports/m68kmac/modmachine.c" diff --git a/ports/m68kmac/retro/Console.h b/ports/m68kmac/retro/Console.h index ce85393ae3b4b..fbe31c1bbdbb6 100644 --- a/ports/m68kmac/retro/Console.h +++ b/ports/m68kmac/retro/Console.h @@ -104,6 +104,8 @@ namespace retro virtual void setWindowName(const char *newName) { }; + virtual void setVisibility(bool shown) { + } void Idle(); diff --git a/ports/m68kmac/retro/ConsoleWindow.cpp b/ports/m68kmac/retro/ConsoleWindow.cpp index e61c9554cb83c..0ade37920fe5c 100644 --- a/ports/m68kmac/retro/ConsoleWindow.cpp +++ b/ports/m68kmac/retro/ConsoleWindow.cpp @@ -271,3 +271,11 @@ static void setupEventFunction() } #endif } + +void ConsoleWindow::setVisibility(bool shown) { + if (shown) { + ShowWindow(win); + } else { + HideWindow(win); + } +} diff --git a/ports/m68kmac/retro/ConsoleWindow.h b/ports/m68kmac/retro/ConsoleWindow.h index d57cecde46adc..b06d49653f6a0 100644 --- a/ports/m68kmac/retro/ConsoleWindow.h +++ b/ports/m68kmac/retro/ConsoleWindow.h @@ -35,7 +35,7 @@ namespace retro ConsoleWindow(Rect r, ConstStr255Param title); ~ConsoleWindow(); void setWindowName(std::string newName); - + void setVisibility(bool shown) override; private: WindowPtr win; diff --git a/ports/m68kmac/uart_core.cpp b/ports/m68kmac/uart_core.cpp index 0015ccc9db6d3..8cfa400513f57 100644 --- a/ports/m68kmac/uart_core.cpp +++ b/ports/m68kmac/uart_core.cpp @@ -20,15 +20,17 @@ namespace retro #define USE_CONSOLE (1) -// Receive single character -extern "C" -int mp_hal_stdin_rx_chr(void); -int mp_hal_stdin_rx_chr(void) { +void mp_hal_stdin_init(void) { #if USE_CONSOLE if(!Console::currentInstance) InitConsole(); - if(Console::currentInstance == (Console*)-1) - return EOF; +#endif +} + +// Receive single character +int mp_hal_stdin_rx_chr(void) { +#if USE_CONSOLE + mp_console_showhide(true); int c = Console::currentInstance->WaitNextChar(); #else int c = *(char*)0xc0006a; @@ -36,6 +38,16 @@ int mp_hal_stdin_rx_chr(void) { return c; } +int show_state = -1; +void mp_console_showhide(bool shown) { + if (shown == show_state) return; + show_state = shown; + if(!Console::currentInstance) + InitConsole(); + if(Console::currentInstance == (Console*)-1) + return; + Console::currentInstance->setVisibility(shown); +} bool mp_hal_stdin_available(void) { if(!Console::currentInstance) InitConsole(); @@ -44,8 +56,6 @@ bool mp_hal_stdin_available(void) { return Console::currentInstance->Available(1); } -extern "C" -mp_uint_t debug_uart_tx_strn(const char *str, mp_uint_t len); mp_uint_t debug_uart_tx_strn(const char *str, mp_uint_t len) { mp_uint_t result = len; // debug hack, needs patched umac @@ -76,3 +86,11 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { return len; } +void mp_console_idle() { + if(!Console::currentInstance) + InitConsole(); + if(Console::currentInstance == (Console*)-1) + return; + + Console::currentInstance->Idle(); +} diff --git a/ports/m68kmac/uart_core.h b/ports/m68kmac/uart_core.h index 1ce2cebd87c71..528393d6eebd4 100644 --- a/ports/m68kmac/uart_core.h +++ b/ports/m68kmac/uart_core.h @@ -1,17 +1,12 @@ #pragma once -#if defined(__cplusplus) -extern "C" { -#endif - #include "py/mpprint.h" +void mp_console_showhide(bool shown); +void mp_console_idle(); +void mp_hal_stdin_init(void); bool mp_hal_stdin_available(void); int mp_hal_stdin_rx_chr(void); extern mp_print_t debug_print; mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len); #define DEBUG_PRINT(...) mp_printf(&debug_print, __VA_ARGS__) - -#if defined(__cplusplus) -} -#endif diff --git a/ports/unix/variants/coverage/mkapi_test.yaml b/ports/unix/variants/coverage/mkapi_test.yaml index 7bbffb75f6907..3dcc9478e74ab 100644 --- a/ports/unix/variants/coverage/mkapi_test.yaml +++ b/ports/unix/variants/coverage/mkapi_test.yaml @@ -2,6 +2,14 @@ name: Byte type: uint8_t +- typedef: + name: Ptr + type: char* + +- typedef: + name: LONGINT + type: int32_t + - typedef: name: INTEGER type: int16_t @@ -75,6 +83,8 @@ - pyverbatim: typedef_content: | + typedef void *Ptr; + typedef struct { INTEGER top, left, bottom, right; } Rect; @@ -117,14 +127,22 @@ return &result; } + static void ShowWindow(WindowPtr w) { + mp_printf(&mp_plat_print, "ShowWindow(w@%p)\n", w); + } + static void PtToAngle(const Rect *r, Point p, INTEGER *angle) { - mp_printf(&mp_plat_print, "PtToAngle(rect@%p, p={%d,%d}, angle@%p\n", r, p.h, p.v, angle); + mp_printf(&mp_plat_print, "PtToAngle(rect@%p, p={%d,%d}, angle@%p)\n", r, p.h, p.v, angle); *angle = 314; } static INTEGER GetWinDevice(WindowPtr w) { return w->device; } + + static void TETextBox(char *p, uint32_t ln, const Rect *r, int j) { + mp_printf(&mp_plat_print, "TETextBox(p[ln=%d]=%.*s, r@%p, j=%d\n", ln, ln, p, r, j); + } - function: name: NewRgn return: RgnHandle @@ -165,3 +183,26 @@ args: - name: w type: WindowPtr + +- function: + name: ShowWindow + args: + - name: w + type: WindowPtr + trap: 0xA915 + executor: C_ + +- function: + name: TETextBox + args: + - name: p + type: Ptr + - name: ln + type: LONGINT + - name: r + type: const Rect* + - name: j + type: INTEGER + trap: 0xA9CE + executor: C_ + diff --git a/tests/extmod/mkapi2.py b/tests/extmod/mkapi2.py new file mode 100644 index 0000000000000..1e62e70a533c9 --- /dev/null +++ b/tests/extmod/mkapi2.py @@ -0,0 +1,4 @@ +import mkapitest + +w = mkapitest.NewWindow() +mkapitest.ShowWindow(w) diff --git a/tests/extmod/mkapi2.py.exp b/tests/extmod/mkapi2.py.exp new file mode 100644 index 0000000000000..260a484630661 --- /dev/null +++ b/tests/extmod/mkapi2.py.exp @@ -0,0 +1 @@ +ShowWindow(w@\[0-9a-f\]\*) diff --git a/tests/extmod/mkapi3.py b/tests/extmod/mkapi3.py new file mode 100644 index 0000000000000..863f52cc7662c --- /dev/null +++ b/tests/extmod/mkapi3.py @@ -0,0 +1,7 @@ +import mkapitest as mactypes +import mkapitest as textedit + +teJustCenter = 1 +textRect = mactypes.Rect(135, 10, 270, 487) +text = bytearray(b"\n".join([b"Hello, World", b"This is another line"])) +textedit.TETextBox(text, len(text), textRect, teJustCenter) diff --git a/tests/extmod/mkapi3.py.exp b/tests/extmod/mkapi3.py.exp new file mode 100644 index 0000000000000..9a1fe73fab740 --- /dev/null +++ b/tests/extmod/mkapi3.py.exp @@ -0,0 +1,2 @@ +TETextBox(p[ln=33]=Hello, World +This is another line, r@\[0-9a-f\]\*, j=1 diff --git a/tests/run-tests.py b/tests/run-tests.py index b612c37883122..82b72aea2ef10 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -358,6 +358,8 @@ def run_script_on_remote_target(pyb, args, test_file, is_special): "thread/thread_exc2.py", "ports/esp32/partition_ota.py", "extmod/mkapi.py", + "extmod/mkapi2.py", + "extmod/mkapi3.py", ) ] diff --git a/tools/mkapi.py b/tools/mkapi.py index f3fdbf8d49ff1..bb0cc01e0a83b 100644 --- a/tools/mkapi.py +++ b/tools/mkapi.py @@ -555,8 +555,8 @@ def body_dedent(self, text): self.body.append(textwrap.dedent(text.rstrip())) def parse_type(self, typestr): - if scalar_type := self.types.get(typestr, None): - typestr = scalar_type + while typedef_type := self.types.get(typestr, None): + typestr = typedef_type is_const = self.is_const(typestr) base_type = self.remove_const(typestr) if self.is_array(base_type):