Two ways to put something on the 128×64 OLED: the canvas for pixels you draw yourself, and the UI helpers for the stock modal widgets that match the rest of the device. Both are ungated — no capability, no prompt — except file_pick, which browses the whole card.

Canvas

The canvas is a 128×48 pixel area occupying OLED pages 2–7 (below the frame text). In fullscreen mode it expands to 128×64 pixels covering the entire display.

Each pixel row is 16 bytes (128 bits). In each byte, the most significant bit is the leftmost pixel: byte 0 bits [7..0] map to pixels x=0..7, byte 1 to x=8..15, and so on.

set_frame and every modal drop fullscreen mode.

canvas_fullscreen(true) is cleared by set_frame and by dialog / list / input / confirm. Re-enable it after any of those calls, or your next frame draws into the 48-row window.

canvas_write

Write a complete row of pixels to the canvas.

Capability: None

jpp_sdk_status_t jpp_sdk_canvas_write(jpp_sdk_context_t *ctx,
                                       uint8_t row,
                                       const uint8_t *pixels);
jppsdk.canvas_write(row: int, pixels: bytes) -> None

Parameters:

Name Description
row Pixel row. 0–47 in windowed mode; 0–63 in fullscreen mode.
pixels Exactly 16 bytes. MSB of byte 0 = leftmost pixel of the row.

Notes: Canvas writes are buffered and flushed to the display on the next render tick. You can write multiple rows before the display updates.


canvas_draw_pixel

Set or clear a single pixel.

Capability: None

jpp_sdk_status_t jpp_sdk_canvas_draw_pixel(jpp_sdk_context_t *ctx,
                                            uint8_t x, uint8_t y,
                                            bool on);
jppsdk.canvas_draw_pixel(x: int, y: int, on: bool) -> None

Parameters:

Name Description
x Horizontal position, 0–127 (left to right).
y Vertical position. 0–47 windowed; 0–63 fullscreen.
on true to light the pixel; false to clear it.

canvas_clear

Zero the entire canvas (turn all pixels off).

Capability: None

jpp_sdk_status_t jpp_sdk_canvas_clear(jpp_sdk_context_t *ctx);
jppsdk.canvas_clear() -> None

canvas_fullscreen

Toggle the fullscreen canvas mode.

Capability: None

jpp_sdk_status_t jpp_sdk_canvas_fullscreen(jpp_sdk_context_t *ctx, bool on);
jppsdk.canvas_fullscreen(on: bool) -> None

Parameters:

Name Description
on true to enable the 128×64 full-display canvas; false to return to the 128×48 windowed canvas.

Notes: - Enabling fullscreen clears the canvas and hides the frame text and signature rule. - set_frame and all modal UI helpers (dialog, list, input) switch back to windowed mode. Call canvas_fullscreen(true) again after any of those calls. - Games should call canvas_fullscreen(true) once at startup and re-enable it after any modal.


UI helpers

These are blocking modal calls. They take over the display and d-pad until the user resolves the prompt, then return. The control scheme is consistent across all helpers: d-pad moves focus, CENTER selects/confirms, CENTER long-press cancels.

All titled modals draw the signature rule under the title row, matching the system Settings and launcher style.

dialog

Show a message with an OK button. The user can confirm or press BACK to dismiss.

Capability: None

jpp_sdk_status_t jpp_sdk_dialog(jpp_sdk_context_t *ctx,
                                 const char *title,
                                 const char *text,
                                 jpp_sdk_ui_result_t *out_result);
jppsdk.dialog(text: str, title: str = None) -> bool

Parameters:

Name Description
title Optional title displayed in row 0 with a rule below it. Pass NULL/None for no title.
text The message body. Long text is automatically word-wrapped across available rows.
out_result C only: receives JPP_SDK_UI_OK (user pressed OK) or JPP_SDK_UI_BACK (dismissed).

Returns: - C: JPP_SDK_OK; check *out_result for the user's choice. - Python: True if the user pressed OK; False if they pressed BACK.


list

Show a scrollable list of items for the user to select.

Capability: None

jpp_sdk_status_t jpp_sdk_list(jpp_sdk_context_t *ctx,
                               const char *title,
                               const char *const *items,
                               size_t item_count,
                               bool multiselect,
                               size_t *out_indices,
                               size_t out_capacity,
                               size_t *out_count,
                               jpp_sdk_ui_result_t *out_result);
jppsdk.list(items: list[str],
            title: str = None,
            multiselect: bool = False) -> int | list[int] | None

Parameters:

Name Description
title Optional title.
items The list of options to display.
item_count Number of items (C only).
multiselect If true, the user can check multiple items before confirming with a trailing "Done" row. If false, selection is immediate on CENTER.
out_indices C only: array receiving the selected indices.
out_capacity C only: size of out_indices array.
out_count C only: number of indices written to out_indices.

Returns: - C: JPP_SDK_OK; check *out_result (JPP_SDK_UI_OK or JPP_SDK_UI_BACK) and *out_count. - Python, single-select: the chosen index as int, or None if cancelled. - Python, multiselect: a list[int] of checked indices, or None if cancelled.

Notes: Long item names scroll as marquees when focused.


input

Show a text input prompt. The input type selects the keyboard layout.

Capability: None

jpp_sdk_status_t jpp_sdk_input(jpp_sdk_context_t *ctx,
                                const char *title,
                                const char *placeholder,
                                jpp_sdk_input_type_t type,
                                char *out_value,
                                size_t value_buf_len,
                                jpp_sdk_ui_result_t *out_result);
jppsdk.input(title: str,
             placeholder: str = None,
             type: int = jppsdk.INPUT_TEXT) -> str | None

Parameters:

Name Description
title Prompt title shown at the top.
placeholder Pre-filled text, or NULL/None to start empty.
type Input mode — see below.
out_value C only: buffer for the returned string. Max value_buf_len - 1 characters.
value_buf_len C only: size of out_value including the null terminator.

Input types:

Type Keyboard Returns
INPUT_TEXT Full QWERTY with shift, space, backspace, done, cancel The typed string
INPUT_NUMBER Digit keys with - and . The typed string
INPUT_DATE Field spinner: year / month / day; LEFT/RIGHT to move fields, UP/DOWN to adjust; 123 for manual entry, now to fill from RTC "YYYY-MM-DD"
INPUT_TIME Field spinner: hour / minute / second; same controls as INPUT_DATE "HH:MM:SS"

Returns: - C: JPP_SDK_OK; check *out_result. - Python: the entered string, or None if the user cancelled.

Notes: Cancelling (BACK or cancel key) returns None/JPP_SDK_UI_BACK. The returned string is limited to 64 characters.


confirm (C only)

Show a customizable Deny/Allow prompt. This is the same consent surface used by capability and files.full path prompts.

Capability: None

Resolvable from SDK level 2 onwards.

jpp_sdk_confirm was declared in the v1.0-RTM header but was missing from the firmware's native symbol table, so a native app that called it failed to launch with UNRESOLVED_SYM. It became callable in firmware v1.1 — declare "sdk_min": 2 if you use it. See the SDK changelog.

jpp_sdk_status_t jpp_sdk_confirm(jpp_sdk_context_t *ctx,
                                  const char *title,
                                  const char *const *body_lines,
                                  size_t body_count,
                                  bool default_allow,
                                  bool *out_allow);

Parameters:

Name Description
title Prompt title.
body_lines Array of body text rows.
body_count Number of body rows.
default_allow Which button (Deny/Allow) is focused by default.
out_allow Receives the user's decision: true = Allow, false = Deny.

Notes: There is no Python binding for confirm — the MicroPython test app uses dialog for similar prompts. confirm is primarily useful in native apps that implement their own consent flows.


file_pick (C only)

Launch a full SD card file browser and return the path the user selects.

Capability: files.full.

Tier 2 — prompted on first use of every launch, never persisted. See Full file access.

jpp_sdk_status_t jpp_sdk_file_pick(jpp_sdk_context_t *ctx,
                                    char *out_path,
                                    size_t out_path_len,
                                    jpp_sdk_ui_result_t *out_result);

Notes: The browser starts at the SD root (/sd). Directories appear with a / suffix; .. navigates up. Long names scroll as marquees. out_path receives the absolute path of the selected file. Returns JPP_SDK_UI_BACK if the user cancels without selecting a file.

There is no direct Python equivalent; use file_open with a known path for MicroPython apps that need full access.


wrap_text (C only)

Word-wrap a string into fixed-width frame lines.

size_t jpp_sdk_wrap_text(const char *text,
                          char lines[][JPP_SDK_FRAME_TEXT_MAX],
                          size_t max_lines);

Returns: Number of lines produced. Use this to split a long message before passing it to set_frame or a modal helper.

Not callable from a loaded app binary.

jpp_sdk_wrap_text is compiled into the firmware but is absent from the native symbol table, so a native app that calls it is rejected at launch with UNRESOLVED_SYM. Until that is fixed, wrap text in your own code. (Firmware-side: add it to s_symtab in components/jpp_native_loader_core/src/jpp_native_symtab.c.)