From patchwork Mon Sep 15 12:28:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 331 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1757939421; bh=JIhBzRi1KMdX4hh3fbkcMBiwExp1cNaHe8fXSBSq3Wk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=NvPpBW0QeUAhaenF5tddtrK9VFwU56wLyxS1GYIBHXnY43Ull9KIvepPI8JUk6Adw MIP36eQRH73Lt36n0mH/rGoVdXIMSt4ynIDpPHlrPSlO5plMhXeJw6CE/Vqmmc9oPX V+tUkvj6z+vygF0tVS9rJdd9Y+LfajpGTzjxYQgFEuj17cTkcCTrEcwrAlPCSRIBK4 mp7XoZszvh0rpTxqbEzoVi5Ewk9+6UXQYLQjaB5MgRRD7HwOrbuuzujse8E7fOjoRI ozhHsp23cxCDvN5olgYtn9ymCthcvAohgA0FjvCZACjFldO27v5c/FceqM+qviODTY L5oUP6YADr5TA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id EE96867BD4 for ; Mon, 15 Sep 2025 06:30:21 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id H3DcJr80G8Ai for ; Mon, 15 Sep 2025 06:30:21 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1757939421; bh=JIhBzRi1KMdX4hh3fbkcMBiwExp1cNaHe8fXSBSq3Wk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=NvPpBW0QeUAhaenF5tddtrK9VFwU56wLyxS1GYIBHXnY43Ull9KIvepPI8JUk6Adw MIP36eQRH73Lt36n0mH/rGoVdXIMSt4ynIDpPHlrPSlO5plMhXeJw6CE/Vqmmc9oPX V+tUkvj6z+vygF0tVS9rJdd9Y+LfajpGTzjxYQgFEuj17cTkcCTrEcwrAlPCSRIBK4 mp7XoZszvh0rpTxqbEzoVi5Ewk9+6UXQYLQjaB5MgRRD7HwOrbuuzujse8E7fOjoRI ozhHsp23cxCDvN5olgYtn9ymCthcvAohgA0FjvCZACjFldO27v5c/FceqM+qviODTY L5oUP6YADr5TA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D9A6267BC8 for ; Mon, 15 Sep 2025 06:30:21 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1757939419; bh=jyeBrgdy/eRLJQT+FiTY4Oq8448cP0re1/Dl4mmZ56A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QzNf/LRrzt9vdZ/s6ZZEnPmoh0v452ng9kPvatV27fRFLwlZokIZ2DyqCWhjDGx4d 0TvdgtighVKfBxHV51CTeStXibPFer74x8wPGapDDYQaQf7mlUT9tvKY0w11+hrRRR fn6Hr4Do6X13JzhLBdTqysX22HMuh9cGJz9W8EB3a5XTTS5iofN0F+YVqkWyI5ezZW 2pHZVyC40d2ckV/juOPCcXfijH5Pbcim16kJyyogwA2B2CewaPYfYwnM523IsMZ5JX H9mF2mjy8bXhP/pdY3pqmOMpYk2ArwRimGqzRL/eUJrl9uu6vcobuwXi9uz4caMcCx YQlFrD2q3HNgQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 6401467B3C; Mon, 15 Sep 2025 06:30:19 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id veRsNmHTYLLN; Mon, 15 Sep 2025 06:30:19 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1757939415; bh=1kxFAItZ44+MybuZnopEDa+Ei+1Qfgi+U34oJc8skDc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BnkI1SZ1HoMf/S9I7Uogg4GzuGTL/+t9cnf9PQd74hJ+dtegzgI7XDj8VvRBrSIup kAUVUBknsbGIM9WdQDbkgnrJpVsLBeNbcfXHJSc98oaR7Qp+VfA6jwG0hW/RPoNCWa qB5+1fkEdq9j1uIaFwpzSN+8On3SNl9uyXOMq0DmPy3orVs8WPK/nCPyDinB40IYod wZahrFbHt9E+e8gn9qMaLQrp633vwioa6YARBYUP6YaFMqbXaTm5oDdvYhEBPIvHCl ZU9CRKkigvzcM0TVSjYlwS0mFRHMbCh7yXzwr8ZApIp9RAh+1iFSGp1dFRFHh3SDeE IuMixyi8xHoHA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 4E28567B34; Mon, 15 Sep 2025 06:30:15 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Mon, 15 Sep 2025 06:28:49 -0600 Message-ID: <20250915122905.1217249-17-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250915122905.1217249-1-sjg@u-boot.org> References: <20250915122905.1217249-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: LIWPFANSG2ON4PJGJUIZSNJ5VY5Y7S5E X-Message-ID-Hash: LIWPFANSG2ON4PJGJUIZSNJ5VY5Y7S5E X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 16/23] expo: Support sending a click to a scene List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Implement clicking on an object in the scene. For now only menus and textlines respond to this. For menus the behaviour is different for popups than for normal menus. Signed-off-by: Simon Glass --- boot/scene.c | 173 ++++++++++++++++++++++++++++++++++++++++++ boot/scene_internal.h | 23 ++++++ 2 files changed, 196 insertions(+) diff --git a/boot/scene.c b/boot/scene.c index e25596366cc..d7e0d008b56 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -1078,6 +1078,179 @@ bool scene_obj_within(const struct scene *scn, struct scene_obj *obj, int x, return within; } +/** + * scene_find_obj_within() - Find an object that is within the coords + * + * @scn: Scene to check + * @x: X coordinates of the click + * @y: Y coordinate of the click + * Return: object that is being clicked on, NULL if none + */ +static struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, + int y) +{ + struct scene_obj *obj; + + log_debug("within: x %d y %d\n", x, y); + list_for_each_entry(obj, &scn->obj_head, sibling) { + log_debug(" - obj %d '%s' can_highlight %d within %d\n", + obj->id, obj->name, scene_obj_can_highlight(obj), + scene_obj_within(scn, obj, x, y)); + if (scene_obj_can_highlight(obj) && + scene_obj_within(scn, obj, x, y)) { + log_debug("- returning obj %d '%s'\n", obj->id, + obj->name); + return obj; + } + } + log_debug("- no object\n"); + + return NULL; +} + +/** + * send_click_obj() - Handle a click for moving between objects + * + * On entry, scn->highlight_id is set to a menu/textline, but the object is not + * open. + * + * @scn: Scene to receive the click + * @obj: Object to receive the click + * @x: X coordinate of the click + * @y: Y coordinate of the click + * @event: Returns resulting event from this keypress + * Returns: 0 if OK, -ve on error + */ +static void send_click_obj(struct scene *scn, struct scene_obj *obj, int x, + int y, struct expo_action *event) +{ + if (scene_obj_can_highlight(obj) && scene_obj_within(scn, obj, x, y)) { + event->type = EXPOACT_OPEN; + event->select.id = obj->id; + log_debug("open obj %d\n", event->select.id); + return; + } + + log_debug("no object; finding...\n"); + obj = scene_find_obj_within(scn, x, y); + if (obj) { + event->type = EXPOACT_POINT_OPEN; + event->select.id = obj->id; + } +} + +static int scene_click_popup(struct scene *scn, int x, int y, + struct expo_action *event) +{ + struct scene_obj *obj, *chk; + + obj = NULL; + if (scn->highlight_id) { + obj = scene_obj_find(scn, scn->highlight_id, + SCENEOBJT_NONE); + } + if (!obj) + return 0; + + if (!(obj->flags & SCENEOF_OPEN)) { + send_click_obj(scn, obj, x, y, event); + return 0; + } + + /* check that the click is within our object */ + chk = scene_find_obj_within(scn, x, y); + log_debug("chk %d '%s' (obj %d '%s')\n", chk ? chk->id : -1, + chk ? chk->name : "(none)", obj->id, obj->name); + if (!chk) { + /* click into space */ + event->type = EXPOACT_CLOSE; + event->select.id = obj->id; + return 0; + } else if (chk != obj) { + send_click_obj(scn, chk, x, y, event); + if (event->type == EXPOACT_OPEN) { + event->type = EXPOACT_REPOINT_OPEN; + event->select.prev_id = obj->id; + } + return 0; + } + + /* click within the open object */ + switch (obj->type) { + case SCENEOBJT_NONE: + case SCENEOBJT_IMAGE: + case SCENEOBJT_TEXT: + case SCENEOBJT_BOX: + break; + case SCENEOBJT_MENU: { + struct scene_obj_menu *menu; + + menu = (struct scene_obj_menu *)obj, + scene_menu_send_click(scn, menu, x, y, event); + break; + } + case SCENEOBJT_TEXTLINE: { + struct scene_obj_textline *tline; + + tline = (struct scene_obj_textline *)obj; + // ret = scene_textline_send_click(scn, tline, x, y, event); + // if (ret) + // return log_msg_ret("key", ret); + break; + } + case SCENEOBJT_TEXTEDIT: + /* TODO(sjg@chromium.org): Implement this */ + break; + } + + return 0; +} + +int scene_send_click(struct scene *scn, int x, int y, struct expo_action *event) +{ + struct scene_obj *obj; + + event->type = EXPOACT_NONE; + + if (scn->expo->popup) { + scene_click_popup(scn, x, y, event); + return 0; + } + + obj = scene_find_obj_within(scn, x, y); + log_debug("non-popup obj %d '%s'\n", obj ? obj->id : -1, + obj ? obj->name : "(none)"); + if (!obj) + return 0; + + switch (obj->type) { + case SCENEOBJT_NONE: + case SCENEOBJT_IMAGE: + case SCENEOBJT_TEXT: + case SCENEOBJT_BOX: + /* These objects don't handle clicks directly */ + break; + case SCENEOBJT_MENU: { + struct scene_obj_menu *menu; + + menu = (struct scene_obj_menu *)obj, + scene_menu_send_click(scn, menu, x, y, event); + break; + } + case SCENEOBJT_TEXTLINE: { + /* For now, just highlight the textline */ + scn->highlight_id = obj->id; + break; + } + case SCENEOBJT_TEXTEDIT: + /* For now, just highlight the textedit */ + scn->highlight_id = obj->id; + break; + } + + return 0; +} + int scene_obj_calc_bbox(struct scene_obj *obj, struct vidconsole_bbox bbox[]) { switch (obj->type) { diff --git a/boot/scene_internal.h b/boot/scene_internal.h index 91828538417..0bc6f45cdcb 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -265,6 +265,18 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event); */ bool scene_within(const struct scene *scn, uint id, int x, int y); +/** + * scene_obj_within() - check if a point is considered within an object + * + * @scn: Scene to check + * @menu: Menu to check + * @x: X coordinate of the point + * @y: Y coordinate of the point + * Return: true if the point is considered within the object, false if not + */ +bool scene_obj_within(const struct scene *scn, struct scene_obj *obj, + int x, int y); + /** * scene_menu_within() - check if a point is considered within a menu * @@ -290,6 +302,17 @@ struct scene_menitem *scene_menu_within(const struct scene *scn, bool scene_textline_within(const struct scene *scn, struct scene_obj_textline *tline, int x, int y); +/** + * scene_send_click() - process a mouse click in a scene + * + * @scn: Scene to receive the click + * @x: X coordinate of the click + * @y: Y coordinate of the click + * @event: Returns resulting event from this click + * Returns: 0 if OK, -ve on error + */ +int scene_send_click(struct scene *scn, int x, int y, struct expo_action *event); + /** * scene_render_deps() - Render an object and its dependencies *