apps/graphics: Add input generator library

We can use it to unify our monkey / input tools, and for other input
generation purposes easily.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2025-03-11 20:08:58 +08:00 committed by Xiang Xiao
parent 1820d7d2c7
commit 7a2d5bbc64
9 changed files with 1680 additions and 0 deletions

View file

@ -0,0 +1,27 @@
# ##############################################################################
# apps/graphics/input/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
if(CONFIG_GRAPHICS_INPUT_GENERATOR)
nuttx_add_library(input_generator)
file(GLOB CSRCS generator/*.c)
target_sources(input_generator PRIVATE ${CSRCS})
endif()

11
graphics/input/Kconfig Normal file
View file

@ -0,0 +1,11 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config GRAPHICS_INPUT_GENERATOR
bool "Input generator library"
default n
---help---
This is a simple input generator library that can be used to
generate input events for testing graphics applications.

25
graphics/input/Make.defs Normal file
View file

@ -0,0 +1,25 @@
############################################################################
# apps/graphics/input/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_GRAPHICS_INPUT_GENERATOR),)
CONFIGURED_APPS += $(APPDIR)/graphics/input
endif

29
graphics/input/Makefile Normal file
View file

@ -0,0 +1,29 @@
############################################################################
# apps/graphics/input/Makefile
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(APPDIR)/Make.defs
ifneq ($(CONFIG_GRAPHICS_INPUT_GENERATOR),)
CSRCS = $(wildcard generator/*.c)
endif
include $(APPDIR)/Application.mk

View file

@ -0,0 +1,304 @@
/****************************************************************************
* apps/graphics/input/generator/input_gen_ctx.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/types.h>
#include "input_gen_internal.h"
/****************************************************************************
* Private Types
****************************************************************************/
struct input_gen_ctx_s
{
struct input_gen_dev_s devs[INPUT_GEN_DEV_NUM];
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: input_gen_create
*
* Description:
* Create an input generator context.
*
* Input Parameters:
* ctx - A pointer to the input generator context, or NULL if the
* context failed to be created.
* devices - Device types to be opened.
*
* Returned Value:
* Success device count. On failure, a negated errno value is returned.
*
****************************************************************************/
int input_gen_create(FAR input_gen_ctx_t *ctx, uint32_t devices)
{
int success = 0;
int i;
if (ctx == NULL || devices & ~INPUT_GEN_DEV_ALL)
{
gerr("ERROR: Invalid parameter: ctx=%p, devices=0x%08" PRIX32 "\n",
ctx, devices);
return -EINVAL;
}
*ctx = (input_gen_ctx_t)zalloc(sizeof(struct input_gen_ctx_s));
if (*ctx == NULL)
{
return -ENOMEM;
}
/* Initialize the device context */
for (i = 0; i < INPUT_GEN_DEV_NUM; i++)
{
FAR struct input_gen_dev_s *dev = &(*ctx)->devs[i];
input_gen_dev_t current = (1 << i);
if (devices & current)
{
dev->fd = open(input_gen_dev2path(current),
O_WRONLY | O_NONBLOCK);
if (dev->fd < 0)
{
dev->device = INPUT_GEN_DEV_NONE;
gerr("ERROR: Open %s failed: %d\n",
input_gen_dev2path(current), errno);
continue;
}
ginfo("Opened %s, fd = %d\n",
input_gen_dev2path(current), dev->fd);
dev->device = current;
success++;
}
else
{
dev->fd = -1;
dev->device = INPUT_GEN_DEV_NONE;
}
}
ginfo("%d devices opened\n", success);
if (success == 0)
{
free(*ctx);
*ctx = NULL;
return -ENODEV;
}
return success;
}
/****************************************************************************
* Name: input_gen_destroy
*
* Description:
* Destroy an input generator context.
*
* Input Parameters:
* ctx - The input generator context to destroy.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_destroy(input_gen_ctx_t ctx)
{
int i;
if (ctx == NULL)
{
return -EINVAL;
}
for (i = 0; i < INPUT_GEN_DEV_NUM; i++)
{
if (ctx->devs[i].fd >= 0)
{
ginfo("Closing %s, fd = %d\n",
input_gen_dev2path(ctx->devs[i].device), ctx->devs[i].fd);
close(ctx->devs[i].fd);
}
}
free(ctx);
return OK;
}
/****************************************************************************
* Name: input_gen_search_dev
*
* Description:
* Get the input generator device by type.
*
* Input Parameters:
* ctx - The input generator context.
* device - The device type.
*
* Returned Value:
* A pointer to the input generator device structure, or NULL if not found.
*
****************************************************************************/
FAR struct input_gen_dev_s *input_gen_search_dev(input_gen_ctx_t ctx,
input_gen_dev_t device)
{
int i;
if (ctx == NULL || device > INPUT_GEN_DEV_ALL)
{
return NULL;
}
for (i = 0; i < INPUT_GEN_DEV_NUM; i++)
{
if (ctx->devs[i].device & device)
{
return &ctx->devs[i];
}
}
nwarn("WARNING: Device with type %d not found\n", device);
return NULL;
}
/****************************************************************************
* Name: input_gen_query_device
*
* Description:
* Query whether the device with the specified type is opened.
*
* Input Parameters:
* ctx - The input generator context.
* device - The device type.
*
* Returned Value:
* True if the device is opened, false otherwise.
*
****************************************************************************/
bool input_gen_query_device(input_gen_ctx_t ctx, input_gen_dev_t device)
{
return input_gen_search_dev(ctx, device) != NULL;
}
/****************************************************************************
* Name: input_gen_reset_devices
*
* Description:
* Reset the device state with the specified type.
*
* Input Parameters:
* ctx - The input generator context.
* devices - The device types to reset state.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_reset_devices(input_gen_ctx_t ctx, uint32_t devices)
{
int ret;
if (ctx == NULL)
{
return -EINVAL;
}
/* Use actions with duration 0 to reset the device state */
if (devices & INPUT_GEN_DEV_UTOUCH)
{
ret = input_gen_swipe(ctx, 0, 0, 0, 0, 0);
if (ret < 0 && ret != -ENODEV)
{
return ret;
}
}
if (devices & INPUT_GEN_DEV_UBUTTON)
{
ret = input_gen_button_longpress(ctx, 0, 0);
if (ret < 0 && ret != -ENODEV)
{
return ret;
}
}
/* TODO: Reset keyboard when we support it. */
return OK;
}
/****************************************************************************
* Name: input_gen_write_raw
*
* Description:
* Write raw data to the device.
*
* Input Parameters:
* ctx - The input generator context.
* device - The device type.
* buf - The buffer to write.
* nbytes - The number of bytes to write.
*
* Returned Value:
* The number of bytes written, or a negated errno value on failure.
*
****************************************************************************/
ssize_t input_gen_write_raw(input_gen_ctx_t ctx, input_gen_dev_t device,
FAR const void *buf, size_t nbytes)
{
FAR struct input_gen_dev_s *dev = input_gen_search_dev(ctx, device);
ssize_t ret;
if (dev == NULL)
{
gerr("ERROR: Device with type %d not found\n", device);
return -ENODEV;
}
ret = write(dev->fd, buf, nbytes);
return ret < 0 ? -errno : ret;
}

View file

@ -0,0 +1,228 @@
/****************************************************************************
* apps/graphics/input/generator/input_gen_dev.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <nuttx/input/mouse.h>
#include "input_gen_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define INPUT_GEN_DEV_PATH_UTOUCH "/dev/utouch"
#define INPUT_GEN_DEV_PATH_UBUTTON "/dev/ubutton"
#define INPUT_GEN_DEV_PATH_UMOUSE "/dev/umouse"
#define INPUT_GEN_DEV_PATH_UKEYBOARD "/dev/ukeyboard"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: input_gen_dev2path
*
* Description:
* Convert device type to device path.
*
* Input Parameters:
* device - Device type
*
* Returned Value:
* Device path string.
*
****************************************************************************/
FAR const char *input_gen_dev2path(input_gen_dev_t device)
{
switch (device)
{
case INPUT_GEN_DEV_UTOUCH:
return INPUT_GEN_DEV_PATH_UTOUCH;
case INPUT_GEN_DEV_UBUTTON:
return INPUT_GEN_DEV_PATH_UBUTTON;
case INPUT_GEN_DEV_UMOUSE:
return INPUT_GEN_DEV_PATH_UMOUSE;
case INPUT_GEN_DEV_UKEYBOARD:
return INPUT_GEN_DEV_PATH_UKEYBOARD;
default:
gerr("ERROR: Invalid device type: %d\n", device);
return "";
}
}
/****************************************************************************
* Name: input_gen_utouch_write
*
* Description:
* Write touch sample to the device.
*
* Input Parameters:
* fd - File descriptor of the device
* sample - Pointer to the touch sample structure
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_utouch_write(int fd, FAR const struct touch_sample_s *sample)
{
size_t nbytes = SIZEOF_TOUCH_SAMPLE_S(sample->npoints);
ssize_t ret = write(fd, sample, nbytes);
if (ret != nbytes)
{
gerr("ERROR: utouch_write failed: nbytes = %zu, ret = %zd, error = %d,"
" data = %d points, first at x = %d, y = %d, pressure = %u\n",
nbytes, ret, errno, sample->npoints, sample->point[0].x,
sample->point[0].y, sample->point[0].pressure);
return ret < 0 ? -errno : -EIO;
}
ginfo("utouch_write: %d points, first at x = %d, y = %d, pressure = %u\n",
sample->npoints, sample->point[0].x, sample->point[0].y,
sample->point[0].pressure);
return OK;
}
/****************************************************************************
* Name: input_gen_ubutton_write
*
* Description:
* Write button state to the device.
*
* Input Parameters:
* fd - File descriptor of the device
* mask - Button mask
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_ubutton_write(int fd, btn_buttonset_t mask)
{
ssize_t ret = write(fd, &mask, sizeof(mask));
if (ret != sizeof(mask))
{
gerr("ERROR: ubutton_write failed: %zd, error = %d\n", ret, errno);
return ret < 0 ? -errno : -EIO;
}
ginfo("ubutton_write: mask = 0x%08" PRIX32 "\n", mask);
return OK;
}
/****************************************************************************
* Name: input_gen_umouse_write
*
* Description:
* Write mouse wheel state to the device.
*
* Input Parameters:
* fd - File descriptor of the device
* wheel - Mouse wheel value
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
#ifdef CONFIG_INPUT_MOUSE_WHEEL
int input_gen_umouse_write(int fd, int16_t wheel)
{
struct mouse_report_s sample;
ssize_t ret;
memset(&sample, 0, sizeof(sample));
sample.wheel = wheel;
ret = write(fd, &sample, sizeof(sample));
if (ret != sizeof(sample))
{
gerr("ERROR: umouse_write failed: %zd, error = %d\n", ret, errno);
return ret < 0 ? -errno : -EIO;
}
ginfo("umouse_write: wheel = %d\n", wheel);
return OK;
}
#endif
/****************************************************************************
* Name: input_gen_grab / input_gen_ungrab
*
* Description:
* Grab or ungrab the input device.
*
* Input Parameters:
* dev - The input generator device.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_grab(FAR struct input_gen_dev_s *dev)
{
/* Note: We use flock instead of GRAB ioctl because GRAB will block user
* programs like LVGL from receiving events from the device.
*/
#if CONFIG_FS_LOCK_BUCKET_SIZE > 0
if (flock(dev->fd, LOCK_EX | LOCK_NB) < 0)
{
gerr("ERROR: input_gen_grab failed: %d\n", errno);
return -errno;
}
#endif
return OK;
}
int input_gen_ungrab(FAR struct input_gen_dev_s *dev)
{
#if CONFIG_FS_LOCK_BUCKET_SIZE > 0
if (flock(dev->fd, LOCK_UN) < 0)
{
gerr("ERROR: input_gen_ungrab failed: %d\n", errno);
return -errno;
}
#endif
return OK;
}

View file

@ -0,0 +1,578 @@
/****************************************************************************
* apps/graphics/input/generator/input_gen_event.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <stdint.h>
#include <unistd.h>
#include "input_gen_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define INPUT_GEN_DEFAULT_PRESSURE 42
#define INPUT_GEN_DEFAULT_PRESS_DURATION 50 /* ms */
#define INPUT_GEN_DEFAULT_HOLD_DURATION 5 /* ms */
#define INPUT_GEN_DEFAULT_CLICK_DURATION 100 /* ms */
#define INPUT_GEN_MAX_FINGERS 2
/****************************************************************************
* Private Types
****************************************************************************/
/* Structure to hold parameters for single finger operations, we can support
* multiple fingers by using multiple instances of this structure.
*/
struct input_gen_single_finger_s
{
int16_t x1;
int16_t y1;
int16_t x2;
int16_t y2;
uint32_t press_duration;
uint32_t move_duration;
uint32_t hold_duration;
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: input_gen_tick_get
*
* Description:
* Get the current tick count in milliseconds.
*
* Returned Value:
* The current tick count in milliseconds.
*
****************************************************************************/
static uint32_t input_gen_tick_get(void)
{
struct timespec ts;
uint32_t ms;
clock_gettime(CLOCK_MONOTONIC, &ts);
ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
return ms;
}
/****************************************************************************
* Name: input_gen_tick_elapsed
*
* Description:
* Calculate the elapsed time in milliseconds since the last tick.
*
* Input Parameters:
* act_time - The current tick count.
* prev_tick - The previous tick count.
*
* Returned Value:
* The elapsed time in milliseconds.
*
****************************************************************************/
static uint32_t input_gen_tick_elapsed(uint32_t act_time, uint32_t prev_tick)
{
/* If there is no overflow in sys_time simple subtract */
if (act_time >= prev_tick)
{
prev_tick = act_time - prev_tick;
}
else
{
prev_tick = UINT32_MAX - prev_tick + 1;
prev_tick += act_time;
}
return prev_tick;
}
/****************************************************************************
* Name: input_gen_single_finger
*
* Description:
* Calculate the position of a single finger based on the elapsed time and
* the parameters.
*
* Input Parameters:
* point - The touch point structure to fill in.
* finger - The parameters for the single finger operation.
* elapsed - The elapsed time since the start of the operation.
*
* Returned Value:
* True if the operation is finished, false otherwise.
*
****************************************************************************/
static bool
input_gen_single_finger(FAR struct touch_point_s *point,
FAR const struct input_gen_single_finger_s *finger,
uint32_t elapsed)
{
if (elapsed < finger->press_duration)
{
/* Press */
input_gen_fill_point(point, finger->x1, finger->y1, TOUCH_DOWN);
return false;
}
elapsed -= finger->press_duration;
if (elapsed < finger->move_duration)
{
int16_t x = ((int64_t)(finger->x2 - finger->x1) * elapsed) /
finger->move_duration + finger->x1;
int16_t y = ((int64_t)(finger->y2 - finger->y1) * elapsed) /
finger->move_duration + finger->y1;
input_gen_fill_point(point, x, y, TOUCH_MOVE);
return false;
}
elapsed -= finger->move_duration;
if (elapsed < finger->hold_duration)
{
/* Hold */
input_gen_fill_point(point, finger->x2, finger->y2, TOUCH_DOWN);
return false;
}
/* Release */
input_gen_fill_point(point, finger->x2, finger->y2, TOUCH_UP);
return true;
}
/****************************************************************************
* Name: input_gen_write_motion
*
* Description:
* Write a motion event to the device.
*
* Input Parameters:
* fd - The file descriptor of the device.
* fingers - The parameters for the motion operation.
* nfingers - The number of fingers.
* elapsed - The elapsed time since the start of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
static int input_gen_write_motion(int fd,
FAR const struct input_gen_single_finger_s *fingers,
size_t nfingers, uint32_t elapsed)
{
size_t finished = 0;
size_t i;
int ret;
union /* A union with enough space to make compiler / checker happy. */
{
struct touch_sample_s sample;
struct
{
uint8_t placeholder[offsetof(struct touch_sample_s, point)];
struct touch_point_s point[INPUT_GEN_MAX_FINGERS];
} points;
} buffer;
/* Check the number of fingers */
if (nfingers < 1 || nfingers > INPUT_GEN_MAX_FINGERS)
{
return -EINVAL;
}
/* Fill the touch sample structure */
buffer.sample.npoints = nfingers;
for (i = 0; i < nfingers; i++)
{
FAR struct touch_point_s *point = &buffer.points.point[i];
point->id = i;
if (input_gen_single_finger(point, &fingers[i], elapsed))
{
finished++;
}
ginfo("Finger %zu: x = %d, y = %d, flags = %02X\n",
i, point->x, point->y, point->flags);
}
/* Write the sample to the device */
ret = input_gen_utouch_write(fd, &buffer.sample);
if (ret < 0)
{
return ret;
}
return finished == nfingers ? OK : -EAGAIN;
}
/****************************************************************************
* Name: input_gen_motion
*
* Description:
* Perform a motion operation.
*
* Input Parameters:
* ctx - The input generator context.
* fingers - The parameters for the motion operation.
* nfingers - The number of fingers.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
static int input_gen_motion(input_gen_ctx_t ctx,
FAR const struct input_gen_single_finger_s *fingers,
size_t nfingers)
{
FAR struct input_gen_dev_s *dev;
uint32_t start;
int ret;
dev = input_gen_search_dev(ctx, INPUT_GEN_DEV_UTOUCH);
if (dev == NULL)
{
return -ENODEV;
}
ret = input_gen_grab(dev);
if (ret < 0)
{
return ret;
}
start = input_gen_tick_get();
do
{
uint32_t elapsed = input_gen_tick_elapsed(input_gen_tick_get(), start);
ret = input_gen_write_motion(dev->fd, fingers, nfingers, elapsed);
if (ret == -EAGAIN && usleep(1000) < 0)
{
nwarn("WARNING: Maybe interrupted by signal\n");
input_gen_ungrab(dev);
return -errno;
}
}
while (ret == -EAGAIN);
input_gen_ungrab(dev);
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: input_gen_tap
*
* Description:
* Perform a tap operation.
*
* Input Parameters:
* ctx - The input generator context.
* x - The x coordinate.
* y - The y coordinate.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_tap(input_gen_ctx_t ctx, int16_t x, int16_t y)
{
struct input_gen_single_finger_s finger =
{
.x1 = x,
.y1 = y,
.x2 = x,
.y2 = y,
.press_duration = INPUT_GEN_DEFAULT_PRESS_DURATION,
.move_duration = 0,
.hold_duration = 0,
};
return input_gen_motion(ctx, &finger, 1);
}
/****************************************************************************
* Name: input_gen_drag / input_gen_swipe
*
* Description:
* Perform a drag or swipe operation.
*
* Input Parameters:
* ctx - The input generator context.
* x1 - The start x coordinate.
* y1 - The start y coordinate.
* x2 - The end x coordinate.
* y2 - The end y coordinate.
* duration - The duration of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_drag(input_gen_ctx_t ctx, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint32_t duration)
{
struct input_gen_single_finger_s finger =
{
.x1 = x1,
.y1 = y1,
.x2 = x2,
.y2 = y2,
.press_duration = INPUT_GEN_DEFAULT_PRESS_DURATION,
.move_duration = duration,
.hold_duration = INPUT_GEN_DEFAULT_HOLD_DURATION,
};
return input_gen_motion(ctx, &finger, 1);
}
int input_gen_swipe(input_gen_ctx_t ctx, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint32_t duration)
{
struct input_gen_single_finger_s finger =
{
.x1 = x1,
.y1 = y1,
.x2 = x2,
.y2 = y2,
.press_duration = 0,
.move_duration = duration,
.hold_duration = 0,
};
return input_gen_motion(ctx, &finger, 1);
}
/****************************************************************************
* Name: input_gen_pinch
*
* Description:
* Perform a pinch operation.
*
* Input Parameters:
* ctx - The input generator context.
* x1_start - The start x coordinate of the first finger.
* y1_start - The start y coordinate of the first finger.
* x2_start - The start x coordinate of the second finger.
* y2_start - The start y coordinate of the second finger.
* x1_end - The end x coordinate of the first finger.
* y1_end - The end y coordinate of the first finger.
* x2_end - The end x coordinate of the second finger.
* y2_end - The end y coordinate of the second finger.
* duration - The duration of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_pinch(input_gen_ctx_t ctx, int16_t x1_start, int16_t y1_start,
int16_t x2_start, int16_t y2_start, int16_t x1_end,
int16_t y1_end, int16_t x2_end, int16_t y2_end,
uint32_t duration)
{
struct input_gen_single_finger_s fingers[2] =
{
{
.x1 = x1_start,
.y1 = y1_start,
.x2 = x1_end,
.y2 = y1_end,
.press_duration = INPUT_GEN_DEFAULT_PRESS_DURATION,
.move_duration = duration,
.hold_duration = INPUT_GEN_DEFAULT_HOLD_DURATION,
},
{
.x1 = x2_start,
.y1 = y2_start,
.x2 = x2_end,
.y2 = y2_end,
.press_duration = INPUT_GEN_DEFAULT_PRESS_DURATION,
.move_duration = duration,
.hold_duration = INPUT_GEN_DEFAULT_HOLD_DURATION,
},
};
return input_gen_motion(ctx, fingers, 2);
}
/****************************************************************************
* Name: input_gen_button_click / input_gen_button_longpress
*
* Description:
* Perform a button click or long press operation.
*
* Input Parameters:
* ctx - The input generator context.
* mask - The button mask.
* duration - The duration of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_button_click(input_gen_ctx_t ctx, btn_buttonset_t mask)
{
return input_gen_button_longpress(ctx, mask,
INPUT_GEN_DEFAULT_CLICK_DURATION);
}
int input_gen_button_longpress(input_gen_ctx_t ctx, btn_buttonset_t mask,
uint32_t duration)
{
FAR struct input_gen_dev_s *dev;
int ret;
dev = input_gen_search_dev(ctx, INPUT_GEN_DEV_UBUTTON);
if (dev == NULL)
{
return -ENODEV;
}
ret = input_gen_grab(dev);
if (ret < 0)
{
return ret;
}
ret = input_gen_ubutton_write(dev->fd, mask);
if (ret < 0)
{
goto out;
}
usleep(duration * 1000);
ret = input_gen_ubutton_write(dev->fd, 0);
if (ret < 0)
{
goto out;
}
out:
input_gen_ungrab(dev);
return ret;
}
/****************************************************************************
* Name: input_gen_mouse_wheel
*
* Description:
* Perform a mouse wheel operation.
*
* Input Parameters:
* ctx - The input generator context.
* wheel - The wheel value.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
#ifdef CONFIG_INPUT_MOUSE_WHEEL
int input_gen_mouse_wheel(input_gen_ctx_t ctx, int16_t wheel)
{
FAR struct input_gen_dev_s *dev;
dev = input_gen_search_dev(ctx, INPUT_GEN_DEV_UMOUSE);
if (dev == NULL)
{
return -ENODEV;
}
return input_gen_umouse_write(dev->fd, wheel);
}
#endif
/****************************************************************************
* Name: input_gen_fill_point
*
* Description:
* Fill the touch point structure.
*
* Input Parameters:
* point - The touch point structure.
* x - The x coordinate.
* y - The y coordinate.
* flags - The TOUCH_DOWN, TOUCH_MOVE, TOUCH_UP flag.
*
****************************************************************************/
void input_gen_fill_point(FAR struct touch_point_s *point,
int16_t x, int16_t y, uint8_t flags)
{
point->x = x;
point->y = y;
point->h = 1;
point->w = 1;
if (flags & TOUCH_UP)
{
point->pressure = 0;
point->flags = flags | TOUCH_ID_VALID;
}
else
{
point->pressure = INPUT_GEN_DEFAULT_PRESSURE;
point->flags = flags | TOUCH_ID_VALID | TOUCH_POS_VALID |
TOUCH_PRESSURE_VALID;
}
}

View file

@ -0,0 +1,174 @@
/****************************************************************************
* apps/graphics/input/generator/input_gen_internal.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_GRAPHICS_INPUT_GENERATOR_INPUT_GEN_INTERNAL_H
#define __APPS_GRAPHICS_INPUT_GENERATOR_INPUT_GEN_INTERNAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/input/touchscreen.h>
#include <graphics/input_gen.h>
/****************************************************************************
* Public Types
****************************************************************************/
struct input_gen_dev_s
{
int fd;
input_gen_dev_t device;
};
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: input_gen_search_dev
*
* Description:
* Get the input generator device by type.
*
* Input Parameters:
* ctx - The input generator context.
* device - The device type.
*
* Returned Value:
* A pointer to the input generator device structure, or NULL if not found.
*
****************************************************************************/
FAR struct input_gen_dev_s *input_gen_search_dev(input_gen_ctx_t ctx,
input_gen_dev_t device);
/****************************************************************************
* Name: input_gen_dev2path
*
* Description:
* Convert device type to device path.
*
* Input Parameters:
* device - Device type
*
* Returned Value:
* Device path string.
*
****************************************************************************/
FAR const char *input_gen_dev2path(input_gen_dev_t device);
/****************************************************************************
* Name: input_gen_utouch_write
*
* Description:
* Write touch sample to the device.
*
* Input Parameters:
* fd - File descriptor of the device
* sample - Pointer to the touch sample structure
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_utouch_write(int fd, FAR const struct touch_sample_s *sample);
/****************************************************************************
* Name: input_gen_ubutton_write
*
* Description:
* Write button state to the device.
*
* Input Parameters:
* fd - File descriptor of the device
* mask - Button mask
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_ubutton_write(int fd, btn_buttonset_t mask);
/****************************************************************************
* Name: input_gen_umouse_write
*
* Description:
* Write mouse wheel state to the device.
*
* Input Parameters:
* fd - File descriptor of the device
* wheel - Mouse wheel value
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
#ifdef CONFIG_INPUT_MOUSE_WHEEL
int input_gen_umouse_write(int fd, int16_t wheel);
#endif
/****************************************************************************
* Name: input_gen_grab / input_gen_ungrab
*
* Description:
* Grab or ungrab the input device.
*
* Input Parameters:
* dev - The input generator device.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_grab(FAR struct input_gen_dev_s *dev);
int input_gen_ungrab(FAR struct input_gen_dev_s *dev);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __APPS_GRAPHICS_INPUT_GENERATOR_INPUT_GEN_INTERNAL_H */

View file

@ -0,0 +1,304 @@
/****************************************************************************
* apps/include/graphics/input_gen.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_INCLUDE_GRAPHICS_INPUT_GEN_H
#define __APPS_INCLUDE_GRAPHICS_INPUT_GEN_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/input/buttons.h>
#include <nuttx/input/touchscreen.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define INPUT_GEN_DEV_NUM 4
/****************************************************************************
* Public Types
****************************************************************************/
/* Device types */
typedef enum
{
INPUT_GEN_DEV_NONE = 0x00,
INPUT_GEN_DEV_UTOUCH = 0x01, /* Touchscreen */
INPUT_GEN_DEV_UBUTTON = 0x02, /* Button */
INPUT_GEN_DEV_UMOUSE = 0x04, /* Mouse */
INPUT_GEN_DEV_UKEYBOARD = 0x08, /* Keyboard */
INPUT_GEN_DEV_ALL = INPUT_GEN_DEV_UTOUCH | INPUT_GEN_DEV_UBUTTON |
INPUT_GEN_DEV_UMOUSE | INPUT_GEN_DEV_UKEYBOARD
} input_gen_dev_t;
/* Input generator context */
typedef FAR struct input_gen_ctx_s *input_gen_ctx_t;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: input_gen_create
*
* Description:
* Create an input generator context.
*
* Input Parameters:
* ctx - A pointer to the input generator context, or NULL if the
* context failed to be created.
* devices - Device types to be opened.
*
* Returned Value:
* Success device count. On failure, a negated errno value is returned.
*
****************************************************************************/
int input_gen_create(FAR input_gen_ctx_t *ctx, uint32_t devices);
/****************************************************************************
* Name: input_gen_destroy
*
* Description:
* Destroy an input generator context.
*
* Input Parameters:
* ctx - The input generator context to destroy.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_destroy(input_gen_ctx_t ctx);
/****************************************************************************
* Name: input_gen_query_device
*
* Description:
* Query whether the device with the specified type is opened.
*
* Input Parameters:
* ctx - The input generator context.
* device - The device type.
*
* Returned Value:
* True if the device is opened, false otherwise.
*
****************************************************************************/
bool input_gen_query_device(input_gen_ctx_t ctx, input_gen_dev_t device);
/****************************************************************************
* Name: input_gen_reset_devices
*
* Description:
* Reset the device state with the specified type.
*
* Input Parameters:
* ctx - The input generator context.
* devices - The device types to reset state.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_reset_devices(input_gen_ctx_t ctx, uint32_t devices);
/****************************************************************************
* Name: input_gen_tap
*
* Description:
* Perform a tap operation.
*
* Input Parameters:
* ctx - The input generator context.
* x - The x coordinate.
* y - The y coordinate.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_tap(input_gen_ctx_t ctx, int16_t x, int16_t y);
/****************************************************************************
* Name: input_gen_drag / input_gen_swipe
*
* Description:
* Perform a drag or swipe operation.
*
* Input Parameters:
* ctx - The input generator context.
* x1 - The start x coordinate.
* y1 - The start y coordinate.
* x2 - The end x coordinate.
* y2 - The end y coordinate.
* duration - The duration of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_drag(input_gen_ctx_t ctx, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint32_t duration);
int input_gen_swipe(input_gen_ctx_t ctx, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint32_t duration);
/****************************************************************************
* Name: input_gen_pinch
*
* Description:
* Perform a pinch operation.
*
* Input Parameters:
* ctx - The input generator context.
* x1_start - The start x coordinate of the first finger.
* y1_start - The start y coordinate of the first finger.
* x2_start - The start x coordinate of the second finger.
* y2_start - The start y coordinate of the second finger.
* x1_end - The end x coordinate of the first finger.
* y1_end - The end y coordinate of the first finger.
* x2_end - The end x coordinate of the second finger.
* y2_end - The end y coordinate of the second finger.
* duration - The duration of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_pinch(input_gen_ctx_t ctx, int16_t x1_start, int16_t y1_start,
int16_t x2_start, int16_t y2_start, int16_t x1_end,
int16_t y1_end, int16_t x2_end, int16_t y2_end,
uint32_t duration);
/****************************************************************************
* Name: input_gen_button_click / input_gen_button_longpress
*
* Description:
* Perform a button click or long press operation.
*
* Input Parameters:
* ctx - The input generator context.
* mask - The button mask.
* duration - The duration of the operation.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
int input_gen_button_click(input_gen_ctx_t ctx, btn_buttonset_t mask);
int input_gen_button_longpress(input_gen_ctx_t ctx, btn_buttonset_t mask,
uint32_t duration);
/****************************************************************************
* Name: input_gen_mouse_wheel
*
* Description:
* Perform a mouse wheel operation.
*
* Input Parameters:
* ctx - The input generator context.
* wheel - The wheel value.
*
* Returned Value:
* Zero (OK) is returned on success. On failure, a negated errno value is
* returned.
*
****************************************************************************/
#ifdef CONFIG_INPUT_MOUSE_WHEEL
int input_gen_mouse_wheel(input_gen_ctx_t ctx, int16_t wheel);
#else
#define input_gen_mouse_wheel(ctx, wheel) (-ENODEV)
#endif
/****************************************************************************
* Name: input_gen_fill_point
*
* Description:
* Fill the touch point structure.
*
* Input Parameters:
* point - The touch point structure.
* x - The x coordinate.
* y - The y coordinate.
* flags - The TOUCH_DOWN, TOUCH_MOVE, TOUCH_UP flag.
*
****************************************************************************/
void input_gen_fill_point(FAR struct touch_point_s *point,
int16_t x, int16_t y, uint8_t flags);
/****************************************************************************
* Name: input_gen_write_raw
*
* Description:
* Write raw data to the device.
*
* Input Parameters:
* ctx - The input generator context.
* device - The device type.
* buf - The buffer to write.
* nbytes - The number of bytes to write.
*
* Returned Value:
* The number of bytes written, or a negated errno value on failure.
*
****************************************************************************/
ssize_t input_gen_write_raw(input_gen_ctx_t ctx, input_gen_dev_t device,
FAR const void *buf, size_t nbytes);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __APPS_INCLUDE_GRAPHICS_INPUT_GEN_H */