From patchwork Mon Oct 6 23:21:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 544 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=1759793023; bh=QkH9JCqXHvcNMo++hYfXOD9ceK+OSRFxlDp9kaKDyzo=; 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=lcpUpOL7xDVnJfdafFUxk0qPGLY0z9TIr1GvqpXh7NdRv1Nll6uX8VeqUBLp2sgc7 Jxn0BxgL1DJ/aAu+i6W8UhBbfumVGSerA3nNvANK1Mat3wvyEx/ajTig1k0DtaZ98r 089Cc5/l57QIRfrdQi8o1a1hrej51gyYurzRpfVnU4mCSykLWF5roCGiH+zHIl7VZc OHOoR45hvkdH9PCKkskOI2Wy/u0zPyPpETAlpx6m46aP+yb1zlfp+ShwRIW43i8qtu YWEDvKKBljJ3XiT124uEN3oXmpGHeieFBM1RljcopN3HgqED1irUr1HAOlWGsxu4+d bo+fdqtCxG2Zw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 27D8867FE2 for ; Mon, 6 Oct 2025 17:23:43 -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 YvlBvGCaL7E2 for ; Mon, 6 Oct 2025 17:23:43 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759793022; bh=QkH9JCqXHvcNMo++hYfXOD9ceK+OSRFxlDp9kaKDyzo=; 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=GPPkfjSh9MO429u1R7G/PAKgJR1e4wOYWRKIKjnSBd2e0giN6CxDcxkPBkJYOWA3u DcvOIgVIYdAKrjZGElb+pBG7SbmRWI7k1HaayUeMeX3rCSiiX3HmszdFaGuTfi8YiU xKH68XK22XuhBXxmS+Qu5K3FuiCElFEk5MSnJ7pBHdIddg/LXuaDue7rC4rFlLUMI8 2PzaRnMY2CLYC5TZTP0YtwBmM4YSbJs/sqQSX0uTFEX8VxMDzLgtDIUg2UCNh9mPD4 friVHIY1YrVuniovkPbY50blHgoxgCAraNDdXavkZm8abAGLUtkFRMm4FKkNAoY3y7 Tlt4w42wcQIGQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 28B2B67DB4 for ; Mon, 6 Oct 2025 17:23:42 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759793020; bh=fKvY9IzEr90kgOn45mKUTppXdXFScn3ThgOPJu5RpP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dJvDaBRqytzV5S16Yhe9LWybu9LoZ6QV4ga1ffAUQf2J/WgoDw9LfUikvKG6Z1BWN KBlLn5LK50VwDFFG5+I3FwFRESJGadaBK64foNZWG0mpQXmIG3yj+l0aU+cFpID4fH HQRJQTwTMLe+dCSBJ1wLdV1ERP2g7YylZltiuEAYBLntHVIRholvy183mO5QkOCrqm qU+HjDKPZ/t00MkiZFlJqzpHq1OZjzAgj5KpGX5F0sxd0hyj9NiY0O/PG5I92WfTxg 020RcYqAvbxeyP3TEvolK9opRUrsIKC6+5/KagDzD+zXp7ntAraW8HX76kI5lj+hQr XRzUzJ8faPpPA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 64BB667DB4; Mon, 6 Oct 2025 17:23:40 -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 PwK7bP35xOVC; Mon, 6 Oct 2025 17:23:40 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759793018; bh=rh0RYEtV5lJp3GcjrV/wx93Rcz4gZbU0vqAfS9n0ZA4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QTSu3iUExv02WqF6qgIbGkBNJUIIWm1osvfyR+He5+ezQoz1lafVUyc8RBwb9rtmA KyxIqsjnNpT8VYMANRM+vO9A7m+oPePIK9QNZlLGWoij/FHEEpPL4KoN5aMhwhgG4c nrHeGk55I0AUpnusYoaoP93B7x5tqyxrX7sPw/p18JwwzYRG1BdeKlsKZsNzcTawcp AJVHQEWsaX4BNpVSvwAVU6Vyrz/OYSYMd/mCwY1bi3ibAviSoYjIOVLP7NJNYvnmQi 6yCyfTYiCxxg5mWpv+3KGTb4AXuFXMbv37p+3W4Cq95q63SVojPsrzwVs+22jTYC5x j3Tjuo1NYZBMg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 98E3E67AF3; Mon, 6 Oct 2025 17:23:38 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Mon, 6 Oct 2025 17:21:56 -0600 Message-ID: <20251006232236.2091941-15-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251006232236.2091941-1-sjg@u-boot.org> References: <20251006232236.2091941-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: R2DFTIELJIFH4UNYVELH3GHIDN46BWO5 X-Message-ID-Hash: R2DFTIELJIFH4UNYVELH3GHIDN46BWO5 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 14/17] efi: mouse: Split out event handling further 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 Create a function which handles getting the pointer position using the simple-pointer protocol. Call this from efi_mouse_get_event() Return immediately if there is a button event. Otherwise return a motion event if motion is detected. Signed-off-by: Simon Glass --- drivers/input/efi_mouse.c | 162 +++++++++++++++++++++++++------------- 1 file changed, 106 insertions(+), 56 deletions(-) diff --git a/drivers/input/efi_mouse.c b/drivers/input/efi_mouse.c index 3e9ec370a50..81c3fcb862e 100644 --- a/drivers/input/efi_mouse.c +++ b/drivers/input/efi_mouse.c @@ -39,6 +39,93 @@ struct efi_mouse_priv { struct efi_event *timer_event; }; +/** + * get_rel_pointer() - Handle relative pointer input + * + * @priv: Private data + * @rel_x: Returns relative X movement + * @rel_y: Returns relative Y movement + * @new_buttons: Returns button state + * Return: 0 if OK, -EAGAIN if no event, -ve on error + */ +static int get_rel_pointer(struct efi_mouse_priv *priv, int *rel_x, + int *rel_y, int *new_buttons) +{ + struct efi_simple_pointer_state state; + efi_status_t ret; + + /* Use timer-based polling approach like EFI keyboard */ + if (priv->timer_event) { + struct efi_boot_services *boot = efi_get_boot(); + efi_uintn_t index; + struct efi_event *events[2]; + efi_uintn_t num_events = 1; + + events[0] = priv->timer_event; + if (priv->simple->wait_for_input) { + events[1] = priv->simple->wait_for_input; + num_events = 2; + } + + ret = boot->wait_for_event(num_events, events, &index); + if (ret != EFI_SUCCESS) + return -EAGAIN; + } + + log_debug("rel: calling get_state\n"); + ret = priv->simple->get_state(priv->simple, &state); + log_debug("rel: get_state returned 0x%lx\n", ret); + if (ret == EFI_NOT_READY) + return -EAGAIN; + if (ret) { + log_debug("rel: get_state failed (ret=0x%lx)\n", ret); + return -EIO; + } + + log_debug("rel: RelX=%d RelY=%d LeftBtn=%d RightBtn=%d\n", + state.relative_movement_x, state.relative_movement_y, + state.left_button, state.right_button); + + /* + * Scale down large movement values that seem to be incorrectly + * reported + */ + *rel_x = state.relative_movement_x; + *rel_y = state.relative_movement_y; + + /* If movement values are very large, scale them down */ + if (abs(*rel_x) > 1000) { + *rel_x = *rel_x / 1000; + if (*rel_x == 0 && state.relative_movement_x != 0) + *rel_x = (state.relative_movement_x > 0) ? 1 : -1; + } + if (abs(*rel_y) > 1000) { + *rel_y = *rel_y / 1000; + if (*rel_y == 0 && state.relative_movement_y != 0) + *rel_y = (state.relative_movement_y > 0) ? 1 : -1; + } + + log_debug("rel: scaled RelX=%d RelY=%d\n", *rel_x, *rel_y); + + /* Update absolute position */ + priv->x += *rel_x; + priv->x = max(priv->x, 0); + priv->x = min(priv->x, MOUSE_MAX_COORD); + + priv->y += *rel_y; + priv->y = max(priv->y, 0); + priv->y = min(priv->y, MOUSE_MAX_COORD); + + /* Extract button state */ + *new_buttons = 0; + if (state.left_button) + *new_buttons |= 1 << 0; + if (state.right_button) + *new_buttons |= 1 << 1; + + return 0; +} + /** * get_button_event() - Check for button-change events * @@ -80,76 +167,39 @@ static int get_button_event(struct efi_mouse_priv *priv, int new_buttons, static int efi_mouse_get_event(struct udevice *dev, struct mouse_event *event) { struct efi_mouse_priv *priv = dev_get_priv(dev); - struct efi_simple_pointer_state state; - efi_status_t ret; + struct mouse_motion *motion; int new_buttons; - if (!priv->simple) - return -ENODEV; - - /* Use timer-based polling approach like EFI keyboard */ - if (priv->timer_event) { - struct efi_boot_services *boot = efi_get_boot(); - efi_uintn_t index; - struct efi_event *events[2]; - efi_uintn_t num_events = 1; - - events[0] = priv->timer_event; - if (priv->simple->wait_for_input) { - events[1] = priv->simple->wait_for_input; - num_events = 2; - } - - ret = boot->wait_for_event(num_events, events, &index); - if (ret != EFI_SUCCESS) - return -EAGAIN; - } + int rel_x, rel_y; + int ret; /* Get current pointer state */ - ret = priv->simple->get_state(priv->simple, &state); - if (ret != EFI_SUCCESS) { - if (ret == EFI_NOT_READY) - return -EAGAIN; - printf("EFI mouse: get_state failed (ret=0x%lx)\n", ret); - return -EIO; - } + ret = get_rel_pointer(priv, &rel_x, &rel_y, &new_buttons); + if (ret) + return ret; + + priv->has_last_state = true; /* Check for button changes */ - new_buttons = 0; - if (state.left_button) - new_buttons |= 1 << 0; - if (state.right_button) - new_buttons |= 1 << 1; ret = get_button_event(priv, new_buttons, event); if (!ret) return 0; - /* Check for movement */ - if (state.relative_movement_x || state.relative_movement_y) { - struct mouse_motion *motion = &event->motion; - - /* Update absolute position */ - priv->x += state.relative_movement_x; - priv->x = max(priv->x, 0); - priv->x = min(priv->x, 0xffff); - - priv->y += state.relative_movement_y; - priv->y = max(priv->y, 0); - priv->y = min(priv->y, 0xffff); - - event->type = MOUSE_EV_MOTION; - motion->state = new_buttons; - motion->x = priv->x; - motion->y = priv->y; - motion->xrel = state.relative_movement_x; - motion->yrel = state.relative_movement_y; - + /* If there's no movement, nothing to do */ + if (!rel_x && !rel_y) { priv->buttons = new_buttons; - return 0; + return -EAGAIN; } + motion = &event->motion; + event->type = MOUSE_EV_MOTION; + motion->state = new_buttons; + motion->x = priv->x; + motion->y = priv->y; + motion->xrel = rel_x; + motion->yrel = rel_y; priv->buttons = new_buttons; - return -EAGAIN; + return 0; } /**