From 837da6ade7aebe9541b5a13e40b75ab2b308ac77 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 6 Feb 2017 15:02:25 +0100 Subject: libpayload: Add mouse cursor driver Add a driver to handle multiple low level mouse drivers and provide basic cursor acceleration support. Tested on Lenovo T500. Change-Id: Ib7cec736631b8acf81a14d28daa29ff720777b10 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/18593 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- payloads/libpayload/Kconfig | 10 ++ payloads/libpayload/drivers/Makefile.inc | 2 + payloads/libpayload/drivers/mouse_cursor.c | 202 +++++++++++++++++++++++++++++ payloads/libpayload/include/libpayload.h | 37 ++++++ 4 files changed, 251 insertions(+) create mode 100644 payloads/libpayload/drivers/mouse_cursor.c diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index 5a5bce2a64..63cc1527b6 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -350,6 +350,16 @@ config NVRAM depends on ARCH_X86 # for now default y +config MOUSE_CURSOR + bool "Support for mouse cursor handling" + default n + help + Provides a common interface for various mouse cursor drivers. + * Supports up to 32 buttons. + * Supports 3 axis mice. + * Applies simple cursor acceleration. + * Allows to set cursor acceleration and cursor speed. + config RTC_PORT_EXTENDED_VIA bool "Extended RTC ports are 0x74/0x75" default n diff --git a/payloads/libpayload/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc index 1fa0ec3b18..c6f6575df6 100644 --- a/payloads/libpayload/drivers/Makefile.inc +++ b/payloads/libpayload/drivers/Makefile.inc @@ -42,6 +42,8 @@ libc-$(CONFIG_LP_PC_KEYBOARD) += keyboard.c libc-$(CONFIG_LP_CBMEM_CONSOLE) += cbmem_console.c +libc-$(CONFIG_LP_MOUSE_CURSOR) += mouse_cursor.c + libc-$(CONFIG_LP_NVRAM) += nvram.c libc-$(CONFIG_LP_NVRAM) += options.c diff --git a/payloads/libpayload/drivers/mouse_cursor.c b/payloads/libpayload/drivers/mouse_cursor.c new file mode 100644 index 0000000000..781845caaf --- /dev/null +++ b/payloads/libpayload/drivers/mouse_cursor.c @@ -0,0 +1,202 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2017 Patrick Rudolph + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +static struct mouse_cursor_input_driver *cursor_in; + +static int +mouse_cursor_driver_exists(const struct mouse_cursor_input_driver *const in) +{ + struct mouse_cursor_input_driver *head = cursor_in; + + while (head) { + if (head == in) + return 1; + head = head->next; + } + + return 0; +} + +/** Add new mouse cursor input driver */ +void mouse_cursor_add_input_driver(struct mouse_cursor_input_driver *const in) +{ + /* Check if this driver was already added to the console list */ + if (mouse_cursor_driver_exists(in)) + return; + in->next = cursor_in; + cursor_in = in; +} + +/** Init enabled mouse cursor drivers */ +void mouse_cursor_init(void) +{ +/* FIXME */ +} + +static u32 mouse_buttons; +static u8 mouse_acceleration = 0x10; +/* Fixed-point 1/256 units */ +static int mouse_rel_x; +static int mouse_rel_y; +static int mouse_rel_z; +static u32 mouse_speed = 0x299; + +/** Test for fast moving cursor */ +static u8 mouse_cusor_is_fast(int x, int y) +{ + return (x * x + y * y) > (mouse_acceleration * mouse_acceleration); +} + +/** + * Poll for mouse data. + * + * Polls all drivers for new mouse data. + * Applies accelerations to relative movement. + * Logical ORs all buttons states. + * Call often to prevent driver's queue overrun ! + */ +void mouse_cursor_poll(void) +{ + struct mouse_cursor_input_driver *in; + int rel_x, rel_y, rel_z; + u32 buttons; + + mouse_buttons = 0; + /* Iterate over all connected drivers */ + for (in = cursor_in; in != NULL; in = in->next) + if (in->get_state) { + in->get_state(&rel_x, &rel_y, &rel_z, &buttons); + + /* Accumulate relative movement */ + if (mouse_cusor_is_fast(rel_x, rel_y)) { + /* Apply simple cursor acceleration. Default: x2.6 */ + mouse_rel_x += rel_x * mouse_speed; + mouse_rel_y += rel_y * mouse_speed; + mouse_rel_z += rel_z * mouse_speed; + } else { + mouse_rel_x += rel_x * 256; + mouse_rel_y += rel_y * 256; + mouse_rel_z += rel_z * 256; + } + + /* Logic or all buttons */ + mouse_buttons |= buttons; + } +} + +/** + * Get relative mouse movement. + * + * Returns relative mouse movement with acceleration + * applied. The internal state will be cleared and stays + * clear until one of the drivers provide motion input again. + */ +void mouse_cursor_get_rel(int *x, int *y, int *z) +{ + mouse_cursor_poll(); + + if (x) { + *x = mouse_rel_x / 256; + mouse_rel_x = 0; + } + if (y) { + *y = mouse_rel_y / 256; + mouse_rel_y = 0; + } + if (z) { + *z = mouse_rel_z / 256; + mouse_rel_z = 0; + } +} + +/** + * Get mouse button state. + * + * Returns the current button states. + * There are up to 32 possible buttons, + * but most devices only implement three buttons. + */ +u32 mouse_cursor_get_buttons(void) +{ + mouse_cursor_poll(); + + return mouse_buttons; +} + +/** + * Set cursor speed. + * + * Sets the mouse cursor speed coefficient. + * It is used in case the cursor is moving faster + * than the mouse acceleration coefficient. + */ +void mouse_cursor_set_speed(u32 val) +{ + mouse_speed = val; +} + +/** + * Get cursor speed. + * + * Returns the internal mouse cursor speed in + * 1/256th units. + * Default: 0x299 ~ 2.6 + */ +u32 mouse_cursor_get_speed(void) +{ + return mouse_speed; +} + +/** + * Set cursor acceleration. + * + * Sets the mouse cursor acceleration coefficient. + * The acceleration is used to compare the raw relative + * cursor movement against. If greater the raw values are + * multiplied by mouse_speed to fasten the cursor. + */ +void mouse_cursor_set_acceleration(u8 val) +{ + mouse_acceleration = val; +} + +/** + * Get cursor acceleration. + * + * Returns the current cursor acceleration coefficient. + * Default: 0x10 + */ +u8 mouse_cursor_get_acceleration(void) +{ + return mouse_acceleration; +} diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 97d5944c63..54e01623a1 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -163,6 +163,20 @@ int keyboard_getchar(void); int keyboard_set_layout(char *country); /** @} */ +/** + * @defgroup mouse Mouse cursor functions + * @ingroup input + * @{ + */ +void mouse_cursor_poll(void); +void mouse_cursor_get_rel(int *x, int *y, int *z); +u32 mouse_cursor_get_buttons(void); +void mouse_cursor_set_speed(u32 val); +u32 mouse_cursor_get_speed(void); +void mouse_cursor_set_acceleration(u8 val); +u8 mouse_cursor_get_acceleration(void); +/** @} */ + /** * @defgroup serial Serial functions * @ingroup input @@ -304,6 +318,29 @@ int console_remove_output_driver(void *function); #define havechar havekey /** @} */ +/** + * @defgroup mouse_cursor Mouse cursor functions + * @{ + */ +typedef enum { + CURSOR_INPUT_TYPE_UNKNOWN = 0, + CURSOR_INPUT_TYPE_USB, + CURSOR_INPUT_TYPE_PS2, +} cursor_input_type; + +void mouse_cursor_init(void); + +struct mouse_cursor_input_driver; +struct mouse_cursor_input_driver { + struct mouse_cursor_input_driver *next; + /* X,Y,Z axis and buttons */ + void (*get_state)(int *, int *, int *, u32 *); + cursor_input_type input_type; +}; + +void mouse_cursor_add_input_driver(struct mouse_cursor_input_driver *in); + +/** @} */ /** * @defgroup exec Execution functions -- cgit v1.2.3