rockbox/apps/plugins/test_touchscreen.c
Aidan MacDonald e2363b0e2c plugins: Add touch API to plugin API and revamp touchscreen test
Change-Id: Iefb658693b03e0cda43e2a9fc93086485e790b4e
2025-12-04 09:01:51 -05:00

333 lines
9.5 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2008 Rob Purchase
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "plugin.h"
#if (CONFIG_KEYPAD == COWON_D2_PAD)
#define TOUCHSCREEN_QUIT BUTTON_POWER
#define TOUCHSCREEN_TOGGLE BUTTON_MENU
#elif (CONFIG_KEYPAD == MROBE500_PAD)
#define TOUCHSCREEN_QUIT BUTTON_POWER
#define TOUCHSCREEN_TOGGLE BUTTON_RC_MODE
#elif (CONFIG_KEYPAD == ONDAVX747_PAD)
#define TOUCHSCREEN_QUIT BUTTON_POWER
#define TOUCHSCREEN_TOGGLE BUTTON_MENU
#elif (CONFIG_KEYPAD == ONDAVX777_PAD)
#define TOUCHSCREEN_QUIT BUTTON_POWER
#define TOUCHSCREEN_TOGGLE BUTTON_MENU
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
#define TOUCHSCREEN_QUIT BUTTON_POWER
#define TOUCHSCREEN_TOGGLE BUTTON_MENU
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#define TOUCHSCREEN_QUIT BUTTON_POWER
#define TOUCHSCREEN_TOGGLE BUTTON_PLAY
#elif (CONFIG_KEYPAD == ANDROID_PAD)
#define TOUCHSCREEN_QUIT BUTTON_BACK
#define TOUCHSCREEN_TOGGLE BUTTON_MENU
#elif (CONFIG_KEYPAD == SDL_PAD)
#define TOUCHSCREEN_QUIT BUTTON_MIDLEFT
#define TOUCHSCREEN_TOGGLE BUTTON_CENTER
#else
# error "No keymap defined!"
#endif
static bool usb_exit = false;
static const struct button_mapping tstest_context[] = {
{ACTION_STD_OK, TOUCHSCREEN_TOGGLE, BUTTON_NONE},
{ACTION_STD_CANCEL, TOUCHSCREEN_QUIT, BUTTON_NONE},
LAST_ITEM_IN_LIST,
};
static const struct button_mapping *get_context_map(int context)
{
(void)context;
return tstest_context;
}
static void draw_tsbutton_rect(int x, int y)
{
int x0 = x*LCD_WIDTH/3;
int y0 = y*LCD_HEIGHT/3;
int x1 = (x+1)*LCD_WIDTH/3;
int y1 = (y+1)*LCD_HEIGHT/3;
rb->lcd_set_foreground(LCD_RGBPACK(0xc0, 0, 0));
rb->lcd_fillrect(x0, y0, x1 - x0, y1 - y0);
}
static void draw_crosshair(int x, int y, unsigned fg)
{
rb->lcd_set_foreground(fg);
rb->lcd_hline(x-7, x+7, y);
rb->lcd_vline(x, y-7, y+7);
}
static void tstest_button_mode(void)
{
rb->splashf(HZ, "Button mode test");
rb->touchscreen_set_mode(TOUCHSCREEN_BUTTON);
int button = BUTTON_NONE;
while (true)
{
rb->lcd_clear_display();
if ((button & BUTTON_TOPLEFT) && !(button & BUTTON_REL))
draw_tsbutton_rect(0, 0);
if ((button & BUTTON_TOPMIDDLE) && !(button & BUTTON_REL))
draw_tsbutton_rect(1, 0);
if ((button & BUTTON_TOPRIGHT) && !(button & BUTTON_REL))
draw_tsbutton_rect(2, 0);
if ((button & BUTTON_MIDLEFT) && !(button & BUTTON_REL))
draw_tsbutton_rect(0, 1);
if ((button & BUTTON_CENTER) && !(button & BUTTON_REL))
draw_tsbutton_rect(1, 1);
if ((button & BUTTON_MIDRIGHT) && !(button & BUTTON_REL))
draw_tsbutton_rect(2, 1);
if ((button & BUTTON_BOTTOMLEFT) && !(button & BUTTON_REL))
draw_tsbutton_rect(0, 2);
if ((button & BUTTON_BOTTOMMIDDLE) && !(button & BUTTON_REL))
draw_tsbutton_rect(1, 2);
if ((button & BUTTON_BOTTOMRIGHT) && !(button & BUTTON_REL))
draw_tsbutton_rect(2, 2);
rb->lcd_update();
if (button & TOUCHSCREEN_QUIT)
break;
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
button = rb->button_get(true);
}
}
static void tstest_pointing_mode(void)
{
struct touchevent tevent;
rb->splashf(HZ, "Pointing mode test");
rb->touchscreen_set_mode(TOUCHSCREEN_POINT);
rb->lcd_clear_display();
rb->lcd_update();
while (true)
{
int action = rb->get_custom_action(CONTEXT_PLUGIN, TIMEOUT_BLOCK,
get_context_map);
if (action == ACTION_TOUCHSCREEN)
{
rb->lcd_clear_display();
rb->action_get_touch_event(&tevent);
draw_crosshair(tevent.x, tevent.y, LCD_RGBPACK(0, 0xc0, 0));
rb->lcd_update();
}
else if (action == ACTION_STD_CANCEL)
{
break;
}
else if (rb->default_event_handler(action) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
}
}
static void tstest_gesture(void)
{
static const char *const gesture_names[] = {
[GESTURE_NONE] = "none",
[GESTURE_TAP] = "tap",
[GESTURE_LONG_PRESS] = "long press",
[GESTURE_HOLD] = "hold",
[GESTURE_DRAGSTART] = "dragstart",
[GESTURE_DRAG] = "drag",
[GESTURE_RELEASE] = "release",
};
struct gesture_event gevt;
int gevent_array[10];
int gevent_count = 0;
rb->splashf(HZ, "Gesture test");
rb->touchscreen_set_mode(TOUCHSCREEN_POINT);
rb->lcd_clear_display();
rb->lcd_update();
while (true)
{
int action = rb->get_custom_action(CONTEXT_PLUGIN, TIMEOUT_BLOCK,
get_context_map);
if (action == ACTION_TOUCHSCREEN)
{
rb->lcd_clear_display();
if (rb->action_gesture_get_event_in_vp(&gevt, NULL))
{
if (gevt.id == GESTURE_NONE)
{
gevent_array[gevent_count] = GESTURE_NONE;
gevent_count = 1;
}
if (gevt.id != gevent_array[gevent_count-1])
{
if (gevent_count < (int)ARRAYLEN(gevent_array))
{
gevent_array[gevent_count] = gevt.id;
gevent_count++;
}
}
rb->lcd_set_foreground(LCD_RGBPACK(0xff, 0xff, 0xff));
for (int i = 0; i < gevent_count; ++i)
rb->lcd_puts(0, i, gesture_names[gevent_array[i]]);
draw_crosshair(gevt.x, gevt.y, LCD_RGBPACK(0, 0xc0, 0));
draw_crosshair(gevt.ox, gevt.oy, LCD_RGBPACK(0xc0, 0, 0));
}
rb->lcd_update();
}
else if (action == ACTION_STD_OK)
{
rb->splashf(HZ, "Gesture reset");
rb->action_gesture_reset();
rb->lcd_clear_display();
rb->lcd_update();
}
else if (action == ACTION_STD_CANCEL)
{
break;
}
else if (rb->default_event_handler(action) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
}
}
static void tstest_velocity(void)
{
struct touchevent tevent;
struct gesture_vel gv;
rb->splashf(HZ, "Velocity test");
rb->touchscreen_set_mode(TOUCHSCREEN_POINT);
rb->lcd_clear_display();
rb->lcd_update();
rb->gesture_vel_reset(&gv);
while (true)
{
int action = rb->get_custom_action(CONTEXT_PLUGIN, TIMEOUT_BLOCK,
get_context_map);
if (action == ACTION_TOUCHSCREEN)
{
rb->lcd_clear_display();
rb->action_get_touch_event(&tevent);
rb->gesture_vel_process(&gv, &tevent);
int xvel, yvel;
rb->gesture_vel_get(&gv, &xvel, &yvel);
rb->lcd_set_foreground(LCD_RGBPACK(0xff, 0xff, 0xff));
rb->lcd_putsf(0, 0, "xvel=%4d yvel=%4d", xvel, yvel);
draw_crosshair(tevent.x, tevent.y, LCD_RGBPACK(0, 0xc0, 0));
rb->lcd_update();
if (tevent.type == TOUCHEVENT_RELEASE)
rb->gesture_vel_reset(&gv);
}
else if (action == ACTION_STD_OK)
{
rb->splashf(HZ, "Velocity reset");
rb->gesture_vel_reset(&gv);
rb->lcd_clear_display();
rb->lcd_update();
}
else if (action == ACTION_STD_CANCEL)
{
break;
}
else if (rb->default_event_handler(action) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
}
}
/* plugin entry point */
enum plugin_status plugin_start(const void* parameter)
{
(void)parameter;
int sel;
MENUITEM_STRINGLIST(menu, "Touchscreen test",
NULL,
"Button mode test",
"Pointing mode test",
"Gesture test",
"Velocity test",
"Quit");
while (true)
{
rb->touchscreen_set_mode(rb->global_settings->touch_mode);
switch (rb->do_menu(&menu, &sel, NULL, false))
{
case 0:
tstest_button_mode();
break;
case 1:
tstest_pointing_mode();
break;
case 2:
tstest_gesture();
break;
case 3:
tstest_velocity();
break;
default:
return PLUGIN_OK;
}
if (usb_exit)
return PLUGIN_USB_CONNECTED;
}
}