From patchwork Tue Oct 7 17:05:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 563 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=1759856826; bh=Kwbwq4FNGX582H6j8tqoBdnMglEZHW1VNV36heV/LYs=; 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=Dgt/oV2UaExXx7Zr3y/v7Njsa9I+65jSQJmGtZjCKXViGgu+McCm3A3E4AOZxFbAo U1q9oesy4upqR6Y4oLcYPrsUShKmXTzBJ5tdG9etQR1rtyYEcC6BmzEirUEve/mkfj xbfRX3lDIDWw92StjkAqVDPKQJsezou1FZkD65cQHhQrLpr00wbT3FeRzLGFTsUffR eSXIdHclXxwg0xO+BzXob90tm2lixTXDoxf+Z87Oa52SmEcUwKciZJl4qX1eUv6NVj eTAx8SP/l7Z6SCJGG/+nselqNmPrBEC+iwc4vQw4iNLAkwa//YPnthtv/geSY0QmA0 osR8rbuiiQPKw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 911B667FF9 for ; Tue, 7 Oct 2025 11:07:06 -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 Deuh6Hex2Eda for ; Tue, 7 Oct 2025 11:07:06 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759856824; bh=Kwbwq4FNGX582H6j8tqoBdnMglEZHW1VNV36heV/LYs=; 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=RfjlrsW5u7GLjE71yQO+4Dn07mKYO3CxhP8oTaQCexsib5W8FCrmouj7kXQenE8Jc auDuaYJfRBgbSYldORlJTaLuxs7MCVdPNsPuLznj4+PKQtoGb8SPWS0MqOYt0asLxK F4FM7goYc8ZnlZo4QVNvQv7bameQoZRAgYfCOSrnulf/RBigjlM18ACYrA06sAiV6D Q2DE8o5rgx/Ou5zEHM6BxzTWJNoQSlfsCcP7llCqTBgSc3M5ZHLpaxLko1kDhPzg+8 i/KCwxkQv6FqJsh8EIrWsfV7VgIEiDD4DZL9fa+oc0RP3AD1Y5WlpnE0U84VgPPzI9 wIiOCf45QouZg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A255468006 for ; Tue, 7 Oct 2025 11:07:04 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759856821; bh=c1+SYBp+oxXPJGxHP/SajHhr8HrAV3n2SLmGoiFliXE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mU7OVH0xz0AHJZhYXrWB6JuV4Q04vZl1jUoJ3W1vjqFC+m3lYx5hago0g3OutIDVi BTpoHoiqPUFc5FdlDtVemwdshGnfBrpw74nR4Ev8f8FwthenoLOtEB3ZZcCgWlK0Nz HGEGGOSaNhsseUDPXxV4If8z96+cJYD9k6h5smJpHINtG6QfEVUyV9Y4N+AXskuinB qw5VRNMpuG4+8gD5Nf4QCg8GrLtKLtiEEOw+YEo+Qo+B3QSoMRojHf7gTK1WU/2w1V vz+uwuG/Lxop56uboKtCOVBROrctl76v8zebcFqSnvi//A83QbApTRejpRvD2uA9W1 LmjNwB8/8ePLA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4BA9667F1E; Tue, 7 Oct 2025 11:07:01 -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 8lloGKK24Jjr; Tue, 7 Oct 2025 11:07:01 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759856820; bh=5HxFarTkzuelFw6PPWNmyam1yz6Od+3lKrYHaUnJOQc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BjTRa1rh559fdtxjjFg3/ueckgoFKc5tj/gMviKUiRaJrurfhfdLD3Og8Ki8dirmK NtjzBkb5Jq9IoQoecc5oN5rcKWMUzY3a0i+Ad1PJOWG37Sjj0M8Z5tlu7nMptKx9Yt eoZhbltXNQwh1Y+LSSqzZ/H+8FL+ZXa2BurfMar10yla05XYypWYGorvqLvfbP/nXq cQlxasEWn3CzkcL4htQu+pR1vIoX8M4EMjEOB+atKrOjLewQygZPel0UYLz3llCHAs RbVZZWb3mY5TX04XgWS5RaTRpBguAJPKyizWjQDIoF+oUmGMa340ObqzzmwOZz1op9 QBWl+czB4llvg== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 6DCFF67EE5; Tue, 7 Oct 2025 11:07:00 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 7 Oct 2025 11:05:31 -0600 Message-ID: <20251007170549.541981-18-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251007170549.541981-1-sjg@u-boot.org> References: <20251007170549.541981-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: HJW2UYCDTAC4SZZMICW3PBA3JRVWFA2E X-Message-ID-Hash: HJW2UYCDTAC4SZZMICW3PBA3JRVWFA2E 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 v2 17/20] 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 --- (no changes since v1) 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 5badbfab066..ced8672085c 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; } /**