2002-04-16 13:37:50 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 by Daniel Stenberg
|
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* 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.
|
2002-04-16 13:37:50 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2004-12-01 00:33:18 +00:00
|
|
|
|
2002-04-16 13:37:50 +00:00
|
|
|
/*
|
2004-12-01 00:33:18 +00:00
|
|
|
* Rockbox button functions
|
2002-04-16 13:37:50 +00:00
|
|
|
*/
|
|
|
|
|
2002-05-23 09:26:20 +00:00
|
|
|
#include <stdlib.h>
|
2002-04-16 13:37:50 +00:00
|
|
|
#include "config.h"
|
2002-06-26 21:31:47 +00:00
|
|
|
#include "system.h"
|
2002-04-16 13:37:50 +00:00
|
|
|
#include "button.h"
|
2002-05-23 09:26:20 +00:00
|
|
|
#include "kernel.h"
|
2007-03-11 10:52:36 +00:00
|
|
|
#include "thread.h"
|
2002-06-24 13:50:39 +00:00
|
|
|
#include "backlight.h"
|
2002-09-30 08:55:22 +00:00
|
|
|
#include "serial.h"
|
2002-10-16 12:40:30 +00:00
|
|
|
#include "power.h"
|
2004-06-22 07:16:31 +00:00
|
|
|
#include "powermgmt.h"
|
2010-06-21 16:53:00 +00:00
|
|
|
#ifdef HAVE_SDL
|
2009-09-23 16:59:56 +00:00
|
|
|
#include "button-sdl.h"
|
|
|
|
#else
|
2006-11-27 02:16:32 +00:00
|
|
|
#include "button-target.h"
|
2009-09-23 16:59:56 +00:00
|
|
|
#endif
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
2006-02-20 20:08:27 +00:00
|
|
|
#include "lcd-remote.h"
|
|
|
|
#endif
|
2016-06-29 21:18:00 +00:00
|
|
|
#if defined(HAVE_TRANSFLECTIVE_LCD) && defined(HAVE_LCD_SLEEP)
|
|
|
|
#include "lcd.h" /* lcd_active() prototype */
|
|
|
|
#endif
|
2006-02-20 20:08:27 +00:00
|
|
|
|
2011-02-14 11:27:45 +00:00
|
|
|
struct event_queue button_queue SHAREDBSS_ATTR;
|
2002-05-23 09:26:20 +00:00
|
|
|
|
2005-01-27 11:49:29 +00:00
|
|
|
static long lastbtn; /* Last valid button status */
|
|
|
|
static long last_read; /* Last button status, for debouncing/filtering */
|
2007-07-22 21:02:24 +00:00
|
|
|
static intptr_t button_data; /* data value from last message dequeued */
|
2004-12-01 00:33:18 +00:00
|
|
|
static bool flipped; /* buttons can be flipped to match the LCD flip */
|
2022-12-31 00:40:47 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_BACKLIGHT /* Filter first keypress function pointer */
|
|
|
|
static bool (*keypress_filter_fn)(int, int);
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
2022-12-31 00:40:47 +00:00
|
|
|
static bool (*remote_keypress_filter_fn)(int, int);
|
2006-03-25 19:16:45 +00:00
|
|
|
#endif
|
2007-04-12 22:12:13 +00:00
|
|
|
#endif /* HAVE_BACKLIGHT */
|
2022-12-31 00:40:47 +00:00
|
|
|
|
2020-06-27 00:53:15 +00:00
|
|
|
#ifdef HAVE_SW_POWEROFF
|
|
|
|
static bool enable_sw_poweroff = true;
|
|
|
|
#endif
|
2002-09-23 11:33:04 +00:00
|
|
|
|
2010-09-15 07:43:55 +00:00
|
|
|
/* how long until repeat kicks in, in centiseconds */
|
|
|
|
#define REPEAT_START (30*HZ/100)
|
2002-09-05 22:41:22 +00:00
|
|
|
|
2021-11-20 02:38:00 +00:00
|
|
|
/* The next two make repeat "accelerate", which is nice for lists
|
2010-09-22 23:01:51 +00:00
|
|
|
* which begin to scroll a bit faster when holding until the
|
2022-12-31 00:40:47 +00:00
|
|
|
* real list acceleration kicks in (this smooths acceleration).
|
2021-11-20 02:38:00 +00:00
|
|
|
*
|
|
|
|
* Note that touchscreen pointing events are not subject to this
|
|
|
|
* acceleration and always use REPEAT_INTERVAL_TOUCH. (Do repeat
|
|
|
|
* events even do anything sane for touchscreens??)
|
2010-09-22 23:01:51 +00:00
|
|
|
*/
|
|
|
|
|
2010-09-15 07:43:55 +00:00
|
|
|
/* the speed repeat starts at, in centiseconds */
|
|
|
|
#define REPEAT_INTERVAL_START (16*HZ/100)
|
|
|
|
/* speed repeat finishes at, in centiseconds */
|
|
|
|
#define REPEAT_INTERVAL_FINISH (5*HZ/100)
|
2021-11-20 02:38:00 +00:00
|
|
|
/* repeat interval for touch events */
|
|
|
|
#define REPEAT_INTERVAL_TOUCH (5*HZ/100)
|
2002-05-23 09:26:20 +00:00
|
|
|
|
2014-03-14 15:21:34 +00:00
|
|
|
static int lastdata = 0;
|
2022-12-31 00:40:47 +00:00
|
|
|
static int button_read(int *data);
|
2005-11-23 22:34:11 +00:00
|
|
|
|
2009-04-20 01:41:56 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2021-08-30 00:23:39 +00:00
|
|
|
static long last_touchscreen_touch;
|
2019-01-04 01:46:54 +00:00
|
|
|
#endif
|
|
|
|
|
2022-12-31 00:40:47 +00:00
|
|
|
static void button_remote_post(void)
|
|
|
|
{
|
|
|
|
#if defined(HAS_SERIAL_REMOTE) && !defined(SIMULATOR)
|
|
|
|
/* Post events for the remote control */
|
|
|
|
int btn = remote_control_rx();
|
|
|
|
if(btn)
|
|
|
|
button_try_post(btn, 0);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(HAVE_HEADPHONE_DETECTION)
|
2019-01-04 01:46:54 +00:00
|
|
|
static int hp_detect_callback(struct timeout *tmo)
|
2008-01-27 21:13:04 +00:00
|
|
|
{
|
|
|
|
/* Try to post only transistions */
|
|
|
|
const long id = tmo->data ? SYS_PHONE_PLUGGED : SYS_PHONE_UNPLUGGED;
|
|
|
|
queue_remove_from_head(&button_queue, id);
|
|
|
|
queue_post(&button_queue, id, 0);
|
2009-01-21 02:44:20 +00:00
|
|
|
return 0;
|
2020-09-17 18:53:29 +00:00
|
|
|
/*misc.c:hp_unplug_change*/
|
2008-01-27 21:13:04 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-01-04 01:46:54 +00:00
|
|
|
#if defined(HAVE_LINEOUT_DETECTION)
|
|
|
|
static int lo_detect_callback(struct timeout *tmo)
|
|
|
|
{
|
|
|
|
/* Try to post only transistions */
|
|
|
|
const long id = tmo->data ? SYS_LINEOUT_PLUGGED : SYS_LINEOUT_UNPLUGGED;
|
|
|
|
queue_remove_from_head(&button_queue, id);
|
|
|
|
queue_post(&button_queue, id, 0);
|
|
|
|
return 0;
|
2020-09-17 18:53:29 +00:00
|
|
|
/*misc.c:lo_unplug_change*/
|
2019-01-04 01:46:54 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-12-31 00:40:47 +00:00
|
|
|
static void check_audio_peripheral_state(void)
|
|
|
|
{
|
|
|
|
#if defined(HAVE_HEADPHONE_DETECTION)
|
|
|
|
static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */
|
|
|
|
static bool phones_present = false;
|
|
|
|
|
|
|
|
if (headphones_inserted() != phones_present)
|
|
|
|
{
|
|
|
|
/* Use the autoresetting oneshot to debounce the detection signal */
|
|
|
|
phones_present = !phones_present;
|
|
|
|
timeout_register(&hp_detect_timeout, hp_detect_callback,
|
|
|
|
HZ/2, phones_present);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined(HAVE_LINEOUT_DETECTION)
|
|
|
|
static struct timeout lo_detect_timeout; /* Debouncer for lineout plug/unplug */
|
|
|
|
static bool lineout_present = false;
|
|
|
|
|
|
|
|
if (lineout_inserted() != lineout_present)
|
|
|
|
{
|
|
|
|
/* Use the autoresetting oneshot to debounce the detection signal */
|
|
|
|
lineout_present = !lineout_present;
|
|
|
|
timeout_register(&lo_detect_timeout, lo_detect_callback,
|
|
|
|
HZ/2, lineout_present);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-09-22 23:01:51 +00:00
|
|
|
static bool button_try_post(int button, int data)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
|
|
|
/* one can swipe over the scren very quickly,
|
|
|
|
* for this to work we want to forget about old presses and
|
|
|
|
* only respect the very latest ones */
|
2010-11-14 13:13:06 +00:00
|
|
|
const bool force_post = true;
|
2010-09-22 23:01:51 +00:00
|
|
|
#else
|
|
|
|
/* Only post events if the queue is empty,
|
|
|
|
* to avoid afterscroll effects.
|
|
|
|
* i.e. don't post new buttons if previous ones haven't been
|
2010-11-14 13:13:06 +00:00
|
|
|
* processed yet - but always post releases */
|
|
|
|
const bool force_post = button & BUTTON_REL;
|
2010-09-22 23:01:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
bool ret = queue_empty(&button_queue);
|
|
|
|
if (!ret && force_post)
|
|
|
|
{
|
|
|
|
queue_remove_from_head(&button_queue, button);
|
|
|
|
ret = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
queue_post(&button_queue, button, data);
|
|
|
|
|
|
|
|
/* on touchscreen we posted unconditionally */
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-12-31 00:40:47 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
|
|
|
/* disabled function is shared between Main & Remote LCDs */
|
|
|
|
static bool filter_first_keypress_disabled(int button, int data)
|
|
|
|
{
|
|
|
|
button_try_post(button, data);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool filter_first_keypress_enabled(int button, int data)
|
|
|
|
{
|
|
|
|
#if defined(HAVE_TRANSFLECTIVE_LCD) && defined(HAVE_LCD_SLEEP)
|
|
|
|
if (is_backlight_on(false) && lcd_active())
|
|
|
|
#else
|
|
|
|
if (is_backlight_on(false))
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
return filter_first_keypress_disabled(button, data);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_REMOTE_LCD
|
|
|
|
static bool filter_first_remote_keypress_enabled(int button, int data)
|
|
|
|
{
|
|
|
|
if (is_remote_backlight_on(false)
|
|
|
|
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
|
|
|
|
|| (remote_type()==REMOTETYPE_H300_NONLCD)
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return filter_first_keypress_disabled(button, data);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif /* def HAVE_REMOTE_LCD */
|
|
|
|
#endif /* def HAVE_BACKLIGHT */
|
|
|
|
|
2002-05-23 09:26:20 +00:00
|
|
|
static void button_tick(void)
|
|
|
|
{
|
2002-09-30 08:55:22 +00:00
|
|
|
static int count = 0;
|
|
|
|
static int repeat_speed = REPEAT_INTERVAL_START;
|
2003-02-25 03:03:55 +00:00
|
|
|
static int repeat_count = 0;
|
2002-09-30 08:55:22 +00:00
|
|
|
static bool repeat = false;
|
2006-02-19 13:34:12 +00:00
|
|
|
static bool post = false;
|
2007-04-12 22:12:13 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2006-03-25 19:16:45 +00:00
|
|
|
static bool skip_release = false;
|
|
|
|
#ifdef HAVE_REMOTE_LCD
|
|
|
|
static bool skip_remote_release = false;
|
|
|
|
#endif
|
|
|
|
#endif
|
2002-07-27 11:24:22 +00:00
|
|
|
int diff;
|
2002-09-30 08:55:22 +00:00
|
|
|
int btn;
|
2007-10-22 07:01:59 +00:00
|
|
|
int data = 0;
|
2002-05-23 09:26:20 +00:00
|
|
|
|
2022-12-31 00:40:47 +00:00
|
|
|
button_remote_post();
|
2004-12-01 00:33:18 +00:00
|
|
|
|
2007-10-22 07:01:59 +00:00
|
|
|
btn = button_read(&data);
|
2022-12-31 00:40:47 +00:00
|
|
|
|
|
|
|
check_audio_peripheral_state();
|
2008-01-27 21:13:04 +00:00
|
|
|
|
2006-04-06 18:58:42 +00:00
|
|
|
/* Find out if a key has been released */
|
|
|
|
diff = btn ^ lastbtn;
|
|
|
|
if(diff && (btn & diff) == 0)
|
|
|
|
{
|
2007-04-12 22:12:13 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
2006-04-06 18:58:42 +00:00
|
|
|
if(diff & BUTTON_REMOTE)
|
|
|
|
if(!skip_remote_release)
|
2010-09-22 23:01:51 +00:00
|
|
|
button_try_post(BUTTON_REL | diff, data);
|
2006-03-25 19:16:45 +00:00
|
|
|
else
|
2006-04-06 18:58:42 +00:00
|
|
|
skip_remote_release = false;
|
|
|
|
else
|
2006-03-25 19:16:45 +00:00
|
|
|
#endif
|
2006-04-06 18:58:42 +00:00
|
|
|
if(!skip_release)
|
2010-09-22 23:01:51 +00:00
|
|
|
button_try_post(BUTTON_REL | diff, data);
|
2006-04-06 18:58:42 +00:00
|
|
|
else
|
|
|
|
skip_release = false;
|
2006-03-25 19:16:45 +00:00
|
|
|
#else
|
2010-09-22 23:01:51 +00:00
|
|
|
button_try_post(BUTTON_REL | diff, data);
|
2006-03-25 19:16:45 +00:00
|
|
|
#endif
|
2006-04-06 18:58:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( btn )
|
2002-07-27 11:24:22 +00:00
|
|
|
{
|
2006-04-06 18:58:42 +00:00
|
|
|
/* normal keypress */
|
|
|
|
if ( btn != lastbtn )
|
2002-07-27 19:38:20 +00:00
|
|
|
{
|
2006-04-06 18:58:42 +00:00
|
|
|
post = true;
|
|
|
|
repeat = false;
|
|
|
|
repeat_speed = REPEAT_INTERVAL_START;
|
|
|
|
}
|
|
|
|
else /* repeat? */
|
|
|
|
{
|
iBasso DX50/DX90: Major code cleanup and reorganization.
Reorganization
- Separated iBasso devices from PLATFORM_ANDROID. These are now standlone
hosted targets. Most device specific code is in the
firmware/target/hosted/ibasso directory.
- No dependency on Android SDK, only the Android NDK is needed.
32 bit Android NDK and Android API Level 16.
- Separate implementation for each device where feasible.
Code cleanup
- Rewrite of existing code, from simple reformat to complete reimplementation.
- New backlight interface, seperating backlight from touchscreen.
- Rewrite of device button handler, removing unneeded code and fixing memory
leaks.
- New Debug messages interface logging to Android adb logcat (DEBUGF, panicf,
logf).
- Rewrite of lcd device handler, removing unneeded code and fixing memory leaks.
- Rewrite of audiohw device handler/pcm interface, removing unneeded code and
fixing memory leaks, enabling 44.1/48kHz pthreaded playback.
- Rewrite of power and powermng, proper shutdown, using batterylog results
(see http://gerrit.rockbox.org/r/#/c/1047/).
- Rewrite of configure (Android NDK) and device specific config.
- Rewrite of the Android NDK specific Makefile.
Misc
- All plugins/games/demos activated.
- Update tinyalsa to latest from https://github.com/tinyalsa/tinyalsa.
Includes
- http://gerrit.rockbox.org/r/#/c/993/
- http://gerrit.rockbox.org/r/#/c/1010/
- http://gerrit.rockbox.org/r/#/c/1035/
Does not include http://gerrit.rockbox.org/r/#/c/1007/ due to new backlight
interface and new option for hold switch, touchscreen, physical button
interaction.
Rockbox needs the iBasso DX50/DX90 loader for startup, see
http://gerrit.rockbox.org/r/#/c/1099/
The loader expects Rockbox to be installed in /mnt/sdcard/.rockbox/. If
/mnt/sdcard/ is accessed as USB mass storage device, Rockbox will exit
gracefully and the loader will restart Rockbox on USB disconnect.
Tested on iBasso DX50.
Compiled (not tested) for iBasso DX90.
Compiled (not tested) for PLATFORM_ANDROID.
Change-Id: I5f5e22e68f5b4cf29c28e2b40b2c265f2beb7ab7
2015-02-02 20:44:29 +00:00
|
|
|
|
|
|
|
#if defined(DX50) || defined(DX90)
|
|
|
|
/*
|
|
|
|
Power button on these devices reports two distinct key codes, which are
|
|
|
|
triggerd by a short or medium duration press. Additionlly a long duration press
|
|
|
|
will trigger a hard reset, which is hardwired.
|
|
|
|
|
|
|
|
The time delta between medium and long duration press is not large enough to
|
|
|
|
register here as power off repeat. A hard reset is triggered before Rockbox
|
|
|
|
can power off.
|
|
|
|
|
|
|
|
To cirumvent the hard reset, Rockbox will shutdown on the first POWEROFF_BUTTON
|
|
|
|
repeat. POWEROFF_BUTTON is associated with the a medium duration press of the
|
|
|
|
power button.
|
|
|
|
*/
|
|
|
|
if(btn & POWEROFF_BUTTON)
|
|
|
|
{
|
|
|
|
sys_poweroff();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-04-06 18:58:42 +00:00
|
|
|
if ( repeat )
|
2004-07-24 20:38:56 +00:00
|
|
|
{
|
2006-04-06 18:58:42 +00:00
|
|
|
if (!post)
|
|
|
|
count--;
|
|
|
|
if (count == 0) {
|
|
|
|
post = true;
|
|
|
|
/* yes we have repeat */
|
|
|
|
if (repeat_speed > REPEAT_INTERVAL_FINISH)
|
2004-07-24 20:38:56 +00:00
|
|
|
repeat_speed--;
|
2021-11-20 02:38:00 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
|
|
|
if(btn & BUTTON_TOUCHSCREEN)
|
|
|
|
repeat_speed = REPEAT_INTERVAL_TOUCH;
|
|
|
|
#endif
|
|
|
|
|
2006-04-06 18:58:42 +00:00
|
|
|
count = repeat_speed;
|
2005-01-10 21:47:55 +00:00
|
|
|
|
2006-04-06 18:58:42 +00:00
|
|
|
repeat_count++;
|
2005-01-10 21:47:55 +00:00
|
|
|
|
2006-04-06 18:58:42 +00:00
|
|
|
/* Send a SYS_POWEROFF event if we have a device
|
|
|
|
which doesn't shut down easily with the OFF
|
|
|
|
key */
|
2004-10-12 11:00:19 +00:00
|
|
|
#ifdef HAVE_SW_POWEROFF
|
2020-06-27 00:53:15 +00:00
|
|
|
if (enable_sw_poweroff &&
|
|
|
|
(btn & POWEROFF_BUTTON
|
2006-11-27 02:16:32 +00:00
|
|
|
#ifdef RC_POWEROFF_BUTTON
|
2006-09-12 15:56:31 +00:00
|
|
|
|| btn == RC_POWEROFF_BUTTON
|
2005-06-08 18:01:14 +00:00
|
|
|
#endif
|
2006-04-06 18:58:42 +00:00
|
|
|
) &&
|
2007-02-18 05:32:06 +00:00
|
|
|
#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
|
2006-04-06 18:58:42 +00:00
|
|
|
!charger_inserted() &&
|
2003-02-25 03:03:55 +00:00
|
|
|
#endif
|
2006-04-06 18:58:42 +00:00
|
|
|
repeat_count > POWEROFF_COUNT)
|
|
|
|
{
|
|
|
|
/* Tell the main thread that it's time to
|
|
|
|
power off */
|
|
|
|
sys_poweroff();
|
|
|
|
|
|
|
|
/* Safety net for players without hardware
|
|
|
|
poweroff */
|
2010-06-21 16:53:00 +00:00
|
|
|
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
2006-04-06 18:58:42 +00:00
|
|
|
if(repeat_count > POWEROFF_COUNT * 10)
|
|
|
|
power_off();
|
2009-09-23 16:59:56 +00:00
|
|
|
#endif
|
2004-07-24 20:38:56 +00:00
|
|
|
}
|
2006-04-06 18:58:42 +00:00
|
|
|
#endif
|
2002-05-23 11:59:30 +00:00
|
|
|
}
|
2006-04-06 18:58:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (count++ > REPEAT_START)
|
2002-07-24 15:21:08 +00:00
|
|
|
{
|
2006-04-06 18:58:42 +00:00
|
|
|
post = true;
|
|
|
|
repeat = true;
|
|
|
|
repeat_count = 0;
|
|
|
|
/* initial repeat */
|
|
|
|
count = REPEAT_INTERVAL_START;
|
2002-07-27 19:38:20 +00:00
|
|
|
}
|
2010-09-22 23:01:51 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
|
|
|
else if (lastdata != data && btn == lastbtn)
|
|
|
|
{ /* only coordinates changed, post anyway */
|
|
|
|
if (touchscreen_get_mode() == TOUCHSCREEN_POINT)
|
|
|
|
post = true;
|
|
|
|
}
|
|
|
|
#endif
|
2002-05-23 11:59:30 +00:00
|
|
|
}
|
2006-04-06 18:58:42 +00:00
|
|
|
}
|
|
|
|
if ( post )
|
|
|
|
{
|
|
|
|
if (repeat)
|
2004-07-24 20:38:56 +00:00
|
|
|
{
|
2006-04-06 18:58:42 +00:00
|
|
|
/* Only post repeat events if the queue is empty,
|
|
|
|
* to avoid afterscroll effects. */
|
2010-09-22 23:01:51 +00:00
|
|
|
if (button_try_post(BUTTON_REPEAT | btn, data))
|
2006-02-19 13:34:12 +00:00
|
|
|
{
|
2007-04-12 22:12:13 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
2006-04-06 18:58:42 +00:00
|
|
|
skip_remote_release = false;
|
2006-03-25 19:16:45 +00:00
|
|
|
#endif
|
2006-04-06 18:58:42 +00:00
|
|
|
skip_release = false;
|
|
|
|
#endif
|
|
|
|
post = false;
|
2006-02-19 13:34:12 +00:00
|
|
|
}
|
2006-04-06 18:58:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-04-12 22:12:13 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
2006-04-06 18:58:42 +00:00
|
|
|
if (btn & BUTTON_REMOTE) {
|
2022-12-31 00:40:47 +00:00
|
|
|
skip_remote_release = remote_keypress_filter_fn(btn, data);
|
|
|
|
remote_backlight_on();
|
2006-04-06 18:58:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2022-12-31 00:40:47 +00:00
|
|
|
{
|
|
|
|
skip_release = keypress_filter_fn(btn, data);
|
|
|
|
backlight_on();
|
|
|
|
buttonlight_on();
|
|
|
|
}
|
2006-03-25 19:16:45 +00:00
|
|
|
#else /* no backlight, nothing to skip */
|
2010-09-22 23:01:51 +00:00
|
|
|
button_try_post(btn, data);
|
2006-03-24 13:47:24 +00:00
|
|
|
#endif
|
2006-04-06 18:58:42 +00:00
|
|
|
post = false;
|
|
|
|
}
|
|
|
|
reset_poweroff_timer();
|
2002-06-24 13:50:39 +00:00
|
|
|
}
|
2002-05-23 11:59:30 +00:00
|
|
|
}
|
2006-04-06 18:58:42 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
repeat = false;
|
|
|
|
count = 0;
|
|
|
|
}
|
2002-05-23 09:26:20 +00:00
|
|
|
}
|
2006-04-06 18:58:42 +00:00
|
|
|
lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
|
2022-12-31 00:40:47 +00:00
|
|
|
|
2009-10-05 02:09:00 +00:00
|
|
|
lastdata = data;
|
2002-05-23 09:26:20 +00:00
|
|
|
}
|
|
|
|
|
2007-03-11 22:27:35 +00:00
|
|
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
2017-01-21 13:09:48 +00:00
|
|
|
static bool button_boosted = false;
|
|
|
|
static long button_unboost_tick;
|
|
|
|
#define BUTTON_UNBOOST_TMO HZ
|
|
|
|
|
2007-03-11 22:27:35 +00:00
|
|
|
static void button_boost(bool state)
|
2007-03-11 10:52:36 +00:00
|
|
|
{
|
2017-01-21 13:09:48 +00:00
|
|
|
if (state)
|
2007-03-11 10:52:36 +00:00
|
|
|
{
|
2017-01-21 13:09:48 +00:00
|
|
|
button_unboost_tick = current_tick + BUTTON_UNBOOST_TMO;
|
|
|
|
|
|
|
|
if (!button_boosted)
|
|
|
|
{
|
|
|
|
button_boosted = true;
|
|
|
|
cpu_boost(true);
|
|
|
|
}
|
2007-03-11 10:52:36 +00:00
|
|
|
}
|
2017-01-21 13:09:48 +00:00
|
|
|
else if (!state && button_boosted)
|
2007-03-11 10:52:36 +00:00
|
|
|
{
|
2017-01-21 13:09:48 +00:00
|
|
|
button_boosted = false;
|
2007-03-11 10:52:36 +00:00
|
|
|
cpu_boost(false);
|
|
|
|
}
|
|
|
|
}
|
2017-01-21 13:09:48 +00:00
|
|
|
|
|
|
|
static void button_queue_wait(struct queue_event *evp, int timeout)
|
|
|
|
{
|
|
|
|
/* Loop once after wait time if boosted in order to unboost and wait the
|
|
|
|
full remaining time */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
int ticks = timeout;
|
|
|
|
|
|
|
|
if (ticks == 0) /* TIMEOUT_NOBLOCK */
|
|
|
|
;
|
|
|
|
else if (ticks > 0)
|
|
|
|
{
|
|
|
|
if (button_boosted && ticks > BUTTON_UNBOOST_TMO)
|
|
|
|
ticks = BUTTON_UNBOOST_TMO;
|
|
|
|
|
|
|
|
timeout -= ticks;
|
|
|
|
}
|
|
|
|
else /* TIMEOUT_BLOCK (ticks < 0) */
|
|
|
|
{
|
|
|
|
if (button_boosted)
|
|
|
|
ticks = BUTTON_UNBOOST_TMO;
|
|
|
|
}
|
|
|
|
|
|
|
|
queue_wait_w_tmo(&button_queue, evp, ticks);
|
|
|
|
if (evp->id != SYS_TIMEOUT)
|
|
|
|
{
|
|
|
|
/* GUI boost build gets immediate kick, otherwise at least 3
|
|
|
|
messages had to be there */
|
|
|
|
#ifndef HAVE_GUI_BOOST
|
|
|
|
if (queue_count(&button_queue) >= 2)
|
|
|
|
#endif
|
|
|
|
button_boost(true);
|
|
|
|
|
2019-01-04 01:46:54 +00:00
|
|
|
break;
|
2017-01-21 13:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (button_boosted && TIME_AFTER(current_tick, button_unboost_tick))
|
|
|
|
button_boost(false);
|
|
|
|
}
|
|
|
|
while (timeout);
|
|
|
|
}
|
|
|
|
#else /* ndef HAVE_ADJUSTABLE_CPU_FREQ */
|
|
|
|
static inline void button_queue_wait(struct queue_event *evp, int timeout)
|
|
|
|
{
|
2017-01-21 17:16:27 +00:00
|
|
|
queue_wait_w_tmo(&button_queue, evp, timeout);
|
2017-01-21 13:09:48 +00:00
|
|
|
}
|
2007-03-11 22:27:35 +00:00
|
|
|
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */
|
2007-03-11 10:52:36 +00:00
|
|
|
|
2007-10-09 21:28:51 +00:00
|
|
|
int button_queue_count( void )
|
2007-10-09 20:42:20 +00:00
|
|
|
{
|
|
|
|
return queue_count(&button_queue);
|
|
|
|
}
|
|
|
|
|
2005-02-07 22:57:05 +00:00
|
|
|
long button_get(bool block)
|
2002-05-23 09:26:20 +00:00
|
|
|
{
|
2007-10-16 01:25:17 +00:00
|
|
|
struct queue_event ev;
|
2017-01-21 13:09:48 +00:00
|
|
|
button_queue_wait(&ev, block ? TIMEOUT_BLOCK : TIMEOUT_NOBLOCK);
|
2007-03-11 22:27:35 +00:00
|
|
|
|
2017-01-21 13:09:48 +00:00
|
|
|
if (ev.id == SYS_TIMEOUT)
|
|
|
|
ev.id = BUTTON_NONE;
|
|
|
|
else
|
2007-07-22 21:02:24 +00:00
|
|
|
button_data = ev.data;
|
2017-01-21 13:09:48 +00:00
|
|
|
|
|
|
|
return ev.id;
|
2002-05-23 09:26:20 +00:00
|
|
|
}
|
2002-04-16 13:37:50 +00:00
|
|
|
|
2005-02-07 22:57:05 +00:00
|
|
|
long button_get_w_tmo(int ticks)
|
2002-08-07 07:22:44 +00:00
|
|
|
{
|
2019-01-04 01:46:54 +00:00
|
|
|
struct queue_event ev;
|
2017-01-21 13:09:48 +00:00
|
|
|
button_queue_wait(&ev, ticks);
|
|
|
|
|
2007-07-22 21:02:24 +00:00
|
|
|
if (ev.id == SYS_TIMEOUT)
|
|
|
|
ev.id = BUTTON_NONE;
|
|
|
|
else
|
|
|
|
button_data = ev.data;
|
2017-01-21 13:09:48 +00:00
|
|
|
|
2007-07-22 21:02:24 +00:00
|
|
|
return ev.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
intptr_t button_get_data(void)
|
|
|
|
{
|
|
|
|
return button_data;
|
2002-08-07 07:22:44 +00:00
|
|
|
}
|
|
|
|
|
2004-12-01 00:33:18 +00:00
|
|
|
void button_init(void)
|
2004-11-18 23:22:45 +00:00
|
|
|
{
|
2022-12-31 00:40:47 +00:00
|
|
|
int temp;
|
2008-01-27 21:13:04 +00:00
|
|
|
/* Init used objects first */
|
|
|
|
queue_init(&button_queue, true);
|
|
|
|
|
2004-12-01 00:33:18 +00:00
|
|
|
/* hardware inits */
|
2006-07-27 13:27:31 +00:00
|
|
|
button_init_device();
|
2006-11-27 02:16:32 +00:00
|
|
|
|
2007-10-22 07:01:59 +00:00
|
|
|
button_read(&temp);
|
|
|
|
lastbtn = button_read(&temp);
|
2019-01-04 01:46:54 +00:00
|
|
|
|
2004-11-18 23:22:45 +00:00
|
|
|
reset_poweroff_timer();
|
2004-12-01 00:33:18 +00:00
|
|
|
|
2004-11-18 23:22:45 +00:00
|
|
|
flipped = false;
|
2007-04-12 22:12:13 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2022-12-31 00:40:47 +00:00
|
|
|
set_backlight_filter_keypress(false);
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
2022-12-31 00:40:47 +00:00
|
|
|
set_remote_backlight_filter_keypress(false);
|
2019-01-04 01:46:54 +00:00
|
|
|
#endif
|
2006-03-24 13:47:24 +00:00
|
|
|
#endif
|
2009-04-20 01:41:56 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2021-08-30 00:23:39 +00:00
|
|
|
last_touchscreen_touch = -1;
|
2019-01-04 01:46:54 +00:00
|
|
|
#endif
|
2008-01-27 21:13:04 +00:00
|
|
|
/* Start polling last */
|
|
|
|
tick_add_task(button_tick);
|
2004-11-18 23:22:45 +00:00
|
|
|
}
|
|
|
|
|
2008-05-10 18:00:11 +00:00
|
|
|
#ifdef BUTTON_DRIVER_CLOSE
|
|
|
|
void button_close(void)
|
|
|
|
{
|
|
|
|
tick_remove_task(button_tick);
|
|
|
|
}
|
|
|
|
#endif /* BUTTON_DRIVER_CLOSE */
|
|
|
|
|
2009-09-23 16:59:56 +00:00
|
|
|
#ifdef HAVE_LCD_FLIP
|
2004-11-18 23:22:45 +00:00
|
|
|
/*
|
2020-10-08 22:27:03 +00:00
|
|
|
* helper function to swap LEFT/RIGHT, UP/DOWN (if present)
|
2004-11-18 23:22:45 +00:00
|
|
|
*/
|
2009-10-05 17:53:45 +00:00
|
|
|
static int button_flip(int button)
|
2004-11-18 23:22:45 +00:00
|
|
|
{
|
2010-05-15 21:02:47 +00:00
|
|
|
int newbutton = button;
|
2004-11-18 23:22:45 +00:00
|
|
|
|
2010-06-21 16:53:00 +00:00
|
|
|
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
2020-10-08 22:27:03 +00:00
|
|
|
newbutton &= ~(
|
|
|
|
#if defined(BUTTON_LEFT) && defined(BUTTON_RIGHT)
|
|
|
|
BUTTON_LEFT | BUTTON_RIGHT
|
|
|
|
#else
|
|
|
|
#warning "LEFT/RIGHT not defined!"
|
|
|
|
0
|
|
|
|
#endif
|
2006-04-01 23:48:03 +00:00
|
|
|
#if defined(BUTTON_UP) && defined(BUTTON_DOWN)
|
|
|
|
| BUTTON_UP | BUTTON_DOWN
|
|
|
|
#endif
|
2008-01-10 08:08:31 +00:00
|
|
|
#if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD)
|
|
|
|
| BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD
|
2006-09-25 18:45:03 +00:00
|
|
|
#endif
|
2012-04-15 13:53:46 +00:00
|
|
|
#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\
|
|
|
|
(CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
2008-09-03 22:30:30 +00:00
|
|
|
| BUTTON_VOL_UP | BUTTON_VOL_DOWN
|
2009-07-07 03:26:57 +00:00
|
|
|
#endif
|
|
|
|
#if CONFIG_KEYPAD == PHILIPS_SA9200_PAD
|
|
|
|
| BUTTON_VOL_UP | BUTTON_VOL_DOWN
|
|
|
|
| BUTTON_NEXT | BUTTON_PREV
|
2004-12-01 00:33:18 +00:00
|
|
|
#endif
|
|
|
|
);
|
2004-11-18 23:22:45 +00:00
|
|
|
|
2020-10-08 22:27:03 +00:00
|
|
|
#if defined(BUTTON_LEFT) && defined(BUTTON_RIGHT)
|
2004-11-18 23:22:45 +00:00
|
|
|
if (button & BUTTON_LEFT)
|
|
|
|
newbutton |= BUTTON_RIGHT;
|
|
|
|
if (button & BUTTON_RIGHT)
|
|
|
|
newbutton |= BUTTON_LEFT;
|
2020-10-08 22:27:03 +00:00
|
|
|
#else
|
|
|
|
#warning "LEFT/RIGHT not defined!"
|
|
|
|
#endif
|
|
|
|
|
2006-04-01 23:48:03 +00:00
|
|
|
#if defined(BUTTON_UP) && defined(BUTTON_DOWN)
|
|
|
|
if (button & BUTTON_UP)
|
|
|
|
newbutton |= BUTTON_DOWN;
|
|
|
|
if (button & BUTTON_DOWN)
|
|
|
|
newbutton |= BUTTON_UP;
|
|
|
|
#endif
|
2008-01-10 08:08:31 +00:00
|
|
|
#if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD)
|
|
|
|
if (button & BUTTON_SCROLL_BACK)
|
|
|
|
newbutton |= BUTTON_SCROLL_FWD;
|
|
|
|
if (button & BUTTON_SCROLL_FWD)
|
|
|
|
newbutton |= BUTTON_SCROLL_BACK;
|
2006-09-25 18:45:03 +00:00
|
|
|
#endif
|
2012-04-15 13:53:46 +00:00
|
|
|
#if (CONFIG_KEYPAD == SANSA_C200_PAD) || (CONFIG_KEYPAD == SANSA_CLIP_PAD) ||\
|
|
|
|
(CONFIG_KEYPAD == GIGABEAT_PAD) || (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
2008-09-03 22:30:30 +00:00
|
|
|
if (button & BUTTON_VOL_UP)
|
|
|
|
newbutton |= BUTTON_VOL_DOWN;
|
|
|
|
if (button & BUTTON_VOL_DOWN)
|
|
|
|
newbutton |= BUTTON_VOL_UP;
|
|
|
|
#endif
|
2009-07-07 03:26:57 +00:00
|
|
|
#if CONFIG_KEYPAD == PHILIPS_SA9200_PAD
|
|
|
|
if (button & BUTTON_VOL_UP)
|
|
|
|
newbutton |= BUTTON_VOL_DOWN;
|
|
|
|
if (button & BUTTON_VOL_DOWN)
|
|
|
|
newbutton |= BUTTON_VOL_UP;
|
|
|
|
if (button & BUTTON_NEXT)
|
|
|
|
newbutton |= BUTTON_PREV;
|
|
|
|
if (button & BUTTON_PREV)
|
|
|
|
newbutton |= BUTTON_NEXT;
|
|
|
|
#endif
|
2010-05-15 21:02:47 +00:00
|
|
|
#endif /* !SIMULATOR */
|
2004-11-18 23:22:45 +00:00
|
|
|
return newbutton;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* set the flip attribute
|
|
|
|
* better only call this when the queue is empty
|
|
|
|
*/
|
2009-10-05 17:53:45 +00:00
|
|
|
void button_set_flip(bool flip)
|
2004-11-18 23:22:45 +00:00
|
|
|
{
|
|
|
|
if (flip != flipped) /* not the current setting */
|
|
|
|
{
|
|
|
|
/* avoid race condition with the button_tick() */
|
2008-03-26 01:50:41 +00:00
|
|
|
int oldlevel = disable_irq_save();
|
2009-10-05 17:53:45 +00:00
|
|
|
lastbtn = button_flip(lastbtn);
|
2004-11-18 23:22:45 +00:00
|
|
|
flipped = flip;
|
2008-03-26 01:50:41 +00:00
|
|
|
restore_irq(oldlevel);
|
2004-11-18 23:22:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-09-23 16:59:56 +00:00
|
|
|
#endif /* HAVE_LCD_FLIP */
|
2004-12-01 00:33:18 +00:00
|
|
|
|
2007-04-12 22:12:13 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2006-03-24 13:47:24 +00:00
|
|
|
void set_backlight_filter_keypress(bool value)
|
|
|
|
{
|
2022-12-31 00:40:47 +00:00
|
|
|
if (!value)
|
|
|
|
keypress_filter_fn = filter_first_keypress_disabled;
|
|
|
|
else
|
|
|
|
keypress_filter_fn = filter_first_keypress_enabled;
|
2006-03-24 13:47:24 +00:00
|
|
|
}
|
2006-03-25 19:16:45 +00:00
|
|
|
#ifdef HAVE_REMOTE_LCD
|
|
|
|
void set_remote_backlight_filter_keypress(bool value)
|
|
|
|
{
|
2022-12-31 00:40:47 +00:00
|
|
|
if (!value)
|
|
|
|
remote_keypress_filter_fn = filter_first_keypress_disabled;
|
|
|
|
else
|
|
|
|
remote_keypress_filter_fn = filter_first_remote_keypress_enabled;
|
2006-03-25 19:16:45 +00:00
|
|
|
}
|
|
|
|
#endif
|
2006-03-24 13:47:24 +00:00
|
|
|
#endif
|
|
|
|
|
2004-11-18 23:22:45 +00:00
|
|
|
/*
|
|
|
|
* Get button pressed from hardware
|
|
|
|
*/
|
2022-12-31 00:40:47 +00:00
|
|
|
|
2007-10-22 07:01:59 +00:00
|
|
|
static int button_read(int *data)
|
|
|
|
{
|
2022-12-31 00:40:47 +00:00
|
|
|
#ifdef HAVE_BUTTON_DATA
|
2007-10-22 07:01:59 +00:00
|
|
|
int btn = button_read_device(data);
|
|
|
|
#else
|
2022-12-31 00:40:47 +00:00
|
|
|
(void) data;
|
2006-11-27 02:16:32 +00:00
|
|
|
int btn = button_read_device();
|
2007-10-22 07:01:59 +00:00
|
|
|
#endif
|
2004-11-18 23:22:45 +00:00
|
|
|
int retval;
|
2004-12-01 00:33:18 +00:00
|
|
|
|
2009-09-23 16:59:56 +00:00
|
|
|
#ifdef HAVE_LCD_FLIP
|
2004-10-08 17:02:16 +00:00
|
|
|
if (btn && flipped)
|
2009-10-05 17:53:45 +00:00
|
|
|
btn = button_flip(btn); /* swap upside down */
|
2009-09-23 16:59:56 +00:00
|
|
|
#endif /* HAVE_LCD_FLIP */
|
|
|
|
|
2009-04-20 01:41:56 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
|
|
|
if (btn & BUTTON_TOUCHSCREEN)
|
|
|
|
last_touchscreen_touch = current_tick;
|
2019-01-04 01:46:54 +00:00
|
|
|
#endif
|
2004-09-23 22:36:15 +00:00
|
|
|
/* Filter the button status. It is only accepted if we get the same
|
|
|
|
status twice in a row. */
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifndef HAVE_TOUCHSCREEN
|
2004-12-01 00:33:18 +00:00
|
|
|
if (btn != last_read)
|
2021-04-09 23:21:02 +00:00
|
|
|
retval = lastbtn;
|
2004-09-23 22:36:15 +00:00
|
|
|
else
|
2007-10-22 07:01:59 +00:00
|
|
|
#endif
|
2004-09-23 22:36:15 +00:00
|
|
|
retval = btn;
|
|
|
|
last_read = btn;
|
|
|
|
|
|
|
|
return retval;
|
2004-09-10 10:51:54 +00:00
|
|
|
}
|
|
|
|
|
2004-07-21 08:02:23 +00:00
|
|
|
int button_status(void)
|
|
|
|
{
|
2005-01-27 11:53:13 +00:00
|
|
|
return lastbtn;
|
2004-07-21 08:02:23 +00:00
|
|
|
}
|
|
|
|
|
2009-10-05 02:09:00 +00:00
|
|
|
#ifdef HAVE_BUTTON_DATA
|
|
|
|
int button_status_wdata(int *pdata)
|
|
|
|
{
|
|
|
|
*pdata = lastdata;
|
|
|
|
return lastbtn;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-07-21 08:02:23 +00:00
|
|
|
void button_clear_queue(void)
|
|
|
|
{
|
2004-09-01 06:24:57 +00:00
|
|
|
queue_clear(&button_queue);
|
2004-07-21 08:02:23 +00:00
|
|
|
}
|
2007-07-22 21:02:24 +00:00
|
|
|
|
2009-04-20 01:41:56 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2021-08-30 00:23:39 +00:00
|
|
|
long touchscreen_last_touch(void)
|
2009-04-20 01:41:56 +00:00
|
|
|
{
|
|
|
|
return last_touchscreen_touch;
|
|
|
|
}
|
|
|
|
#endif
|
2007-08-12 19:49:03 +00:00
|
|
|
|
2009-03-02 19:25:50 +00:00
|
|
|
#ifdef HAVE_WHEEL_ACCELERATION
|
2007-11-19 11:05:54 +00:00
|
|
|
/* WHEEL_ACCEL_FACTOR = 2^16 / WHEEL_ACCEL_START */
|
|
|
|
#define WHEEL_ACCEL_FACTOR (1<<16)/WHEEL_ACCEL_START
|
2007-07-22 21:02:24 +00:00
|
|
|
/**
|
|
|
|
* data:
|
|
|
|
* [31] Use acceleration
|
|
|
|
* [30:24] Message post count (skipped + 1) (1-127)
|
2007-11-19 11:05:54 +00:00
|
|
|
* [23:0] Velocity - degree/sec
|
2007-07-22 21:02:24 +00:00
|
|
|
*
|
2007-11-19 11:05:54 +00:00
|
|
|
* WHEEL_ACCEL_FACTOR:
|
2019-01-04 01:46:54 +00:00
|
|
|
* Value in degree/sec -- configurable via settings -- above which
|
|
|
|
* the accelerated scrolling starts. Factor is internally scaled by
|
2007-11-19 11:05:54 +00:00
|
|
|
* 1<<16 in respect to the following 32bit integer operations.
|
2007-07-22 21:02:24 +00:00
|
|
|
*/
|
2007-11-19 11:05:54 +00:00
|
|
|
int button_apply_acceleration(const unsigned int data)
|
2007-07-22 21:02:24 +00:00
|
|
|
{
|
|
|
|
int delta = (data >> 24) & 0x7f;
|
|
|
|
|
|
|
|
if ((data & (1 << 31)) != 0)
|
|
|
|
{
|
2007-11-19 11:05:54 +00:00
|
|
|
/* read driver's velocity from data */
|
2007-07-22 21:02:24 +00:00
|
|
|
unsigned int v = data & 0xffffff;
|
|
|
|
|
2007-11-19 11:05:54 +00:00
|
|
|
/* v = 28.4 fixed point */
|
|
|
|
v = (WHEEL_ACCEL_FACTOR * v)>>(16-4);
|
|
|
|
|
|
|
|
/* Calculate real numbers item to scroll based upon acceleration
|
|
|
|
* setting, use correct roundoff */
|
|
|
|
#if (WHEEL_ACCELERATION == 1)
|
|
|
|
v = (v*v + (1<< 7))>> 8;
|
|
|
|
#elif (WHEEL_ACCELERATION == 2)
|
|
|
|
v = (v*v*v + (1<<11))>>12;
|
|
|
|
#elif (WHEEL_ACCELERATION == 3)
|
|
|
|
v = (v*v*v*v + (1<<15))>>16;
|
|
|
|
#endif
|
2007-07-22 21:02:24 +00:00
|
|
|
|
|
|
|
if (v > 1)
|
|
|
|
delta *= v;
|
|
|
|
}
|
|
|
|
|
|
|
|
return delta;
|
|
|
|
}
|
2009-03-02 19:25:50 +00:00
|
|
|
#endif /* HAVE_WHEEL_ACCELERATION */
|
2013-09-02 09:03:56 +00:00
|
|
|
|
|
|
|
#if (defined(HAVE_TOUCHPAD) || defined(HAVE_TOUCHSCREEN)) && !defined(HAS_BUTTON_HOLD)
|
|
|
|
void button_enable_touch(bool en)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_TOUCHPAD
|
|
|
|
touchpad_enable(en);
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
|
|
|
touchscreen_enable(en);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
2020-06-27 00:53:15 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SW_POWEROFF
|
|
|
|
void button_set_sw_poweroff_state(bool en) {
|
|
|
|
enable_sw_poweroff = en;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool button_get_sw_poweroff_state() {
|
|
|
|
return enable_sw_poweroff;
|
|
|
|
}
|
|
|
|
#endif
|