a3766bf92e
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8047 a1c6a512-1295-4272-9138-f99709370657
312 lines
7.2 KiB
C
312 lines
7.2 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2002 by Björn Stenberg
|
|
*
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#include <stdlib.h>
|
|
#include "config.h"
|
|
#include "button.h"
|
|
#include "kernel.h"
|
|
#include "debug.h"
|
|
#include "backlight.h"
|
|
#include "misc.h"
|
|
|
|
#include "X11/keysym.h"
|
|
|
|
extern int screenhack_handle_events(bool *release);
|
|
|
|
struct event_queue button_queue;
|
|
|
|
static int button_state = 0; /* keeps track of pressed keys */
|
|
static long lastbtn; /* Last valid button status */
|
|
|
|
/* how often we check to see if a button is pressed */
|
|
#define POLL_FREQUENCY HZ/25
|
|
|
|
/* how long until repeat kicks in */
|
|
#define REPEAT_START 8
|
|
|
|
/* the speed repeat starts at */
|
|
#define REPEAT_INTERVAL_START 4
|
|
|
|
/* speed repeat finishes at */
|
|
#define REPEAT_INTERVAL_FINISH 2
|
|
|
|
/* mostly copied from real button.c */
|
|
void button_read (void);
|
|
|
|
static void button_tick(void)
|
|
{
|
|
static int tick = 0;
|
|
static int count = 0;
|
|
static int repeat_speed = REPEAT_INTERVAL_START;
|
|
static int repeat_count = 0;
|
|
static bool repeat = false;
|
|
int diff;
|
|
int btn;
|
|
|
|
/* only poll every X ticks */
|
|
if ( ++tick >= POLL_FREQUENCY )
|
|
{
|
|
bool post = false;
|
|
button_read();
|
|
btn = button_state;
|
|
|
|
/* Find out if a key has been released */
|
|
diff = btn ^ lastbtn;
|
|
if(diff && (btn & diff) == 0)
|
|
{
|
|
queue_post(&button_queue, BUTTON_REL | diff, NULL);
|
|
}
|
|
else
|
|
{
|
|
if ( btn )
|
|
{
|
|
/* normal keypress */
|
|
if ( btn != lastbtn )
|
|
{
|
|
post = true;
|
|
repeat = false;
|
|
repeat_speed = REPEAT_INTERVAL_START;
|
|
|
|
}
|
|
else /* repeat? */
|
|
{
|
|
if ( repeat )
|
|
{
|
|
count--;
|
|
if (count == 0) {
|
|
post = true;
|
|
/* yes we have repeat */
|
|
repeat_speed--;
|
|
if (repeat_speed < REPEAT_INTERVAL_FINISH)
|
|
repeat_speed = REPEAT_INTERVAL_FINISH;
|
|
count = repeat_speed;
|
|
|
|
repeat_count++;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (count++ > REPEAT_START)
|
|
{
|
|
post = true;
|
|
repeat = true;
|
|
repeat_count = 0;
|
|
/* initial repeat */
|
|
count = REPEAT_INTERVAL_START;
|
|
}
|
|
}
|
|
}
|
|
if ( post )
|
|
{
|
|
if (repeat)
|
|
queue_post(&button_queue, BUTTON_REPEAT | btn, NULL);
|
|
else
|
|
queue_post(&button_queue, btn, NULL);
|
|
#ifdef HAVE_REMOTE_LCD
|
|
if(btn & BUTTON_REMOTE)
|
|
remote_backlight_on();
|
|
else
|
|
#endif
|
|
backlight_on();
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
repeat = false;
|
|
count = 0;
|
|
}
|
|
}
|
|
lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
|
|
tick = 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Read X keys and translate to rockbox buttons
|
|
*/
|
|
|
|
void button_read (void)
|
|
{
|
|
int k;
|
|
bool release = false; /* is this a release event */
|
|
int ev = screenhack_handle_events(&release);
|
|
|
|
switch (ev)
|
|
{
|
|
case XK_KP_Left:
|
|
case XK_Left:
|
|
case XK_KP_4:
|
|
k = BUTTON_LEFT;
|
|
break;
|
|
|
|
case XK_KP_Right:
|
|
case XK_Right:
|
|
case XK_KP_6:
|
|
k = BUTTON_RIGHT;
|
|
break;
|
|
|
|
case XK_KP_Up:
|
|
case XK_Up:
|
|
case XK_KP_8:
|
|
#ifdef BUTTON_UP
|
|
k = BUTTON_UP;
|
|
#elif defined BUTTON_PLAY
|
|
k = BUTTON_PLAY;
|
|
#endif
|
|
break;
|
|
|
|
case XK_KP_Down:
|
|
case XK_Down:
|
|
case XK_KP_2:
|
|
#ifdef BUTTON_DOWN
|
|
k = BUTTON_DOWN;
|
|
#elif defined BUTTON_STOP
|
|
k = BUTTON_STOP;
|
|
#endif
|
|
break;
|
|
|
|
#ifdef BUTTON_ON
|
|
case XK_KP_Add:
|
|
case XK_Q:
|
|
case XK_q:
|
|
k = BUTTON_ON;
|
|
break;
|
|
#endif
|
|
|
|
#ifdef BUTTON_OFF
|
|
case XK_KP_Enter:
|
|
case XK_A:
|
|
case XK_a:
|
|
k = BUTTON_OFF;
|
|
break;
|
|
#endif
|
|
|
|
#ifdef BUTTON_F1
|
|
case XK_KP_Divide:
|
|
case XK_1:
|
|
k = BUTTON_F1;
|
|
break;
|
|
|
|
case XK_KP_Multiply:
|
|
case XK_2:
|
|
k = BUTTON_F2;
|
|
break;
|
|
|
|
case XK_KP_Subtract:
|
|
case XK_3:
|
|
k = BUTTON_F3;
|
|
break;
|
|
#elif defined(BUTTON_REC)
|
|
case XK_KP_Divide:
|
|
case XK_1:
|
|
k = BUTTON_REC;
|
|
break;
|
|
#endif
|
|
|
|
case XK_KP_Space:
|
|
case XK_KP_5:
|
|
case XK_KP_Begin:
|
|
case XK_space:
|
|
#ifdef BUTTON_PLAY
|
|
k = BUTTON_PLAY;
|
|
#elif defined(BUTTON_SELECT)
|
|
k = BUTTON_SELECT;
|
|
#endif
|
|
break;
|
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
case XK_5:
|
|
if(!release)
|
|
screen_dump();
|
|
break;
|
|
#endif
|
|
|
|
case XK_KP_Separator:
|
|
case XK_KP_Insert:
|
|
case XK_Insert:
|
|
#ifdef BUTTON_MENU
|
|
k = BUTTON_MENU;
|
|
#elif defined(BUTTON_MODE)
|
|
k = BUTTON_MODE;
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
k = 0;
|
|
if(ev)
|
|
DEBUGF("received ev %d\n", ev);
|
|
break;
|
|
}
|
|
|
|
if (release)
|
|
button_state &= ~k;
|
|
else
|
|
button_state |= k;
|
|
}
|
|
|
|
/* Again copied from real button.c... */
|
|
|
|
long button_get(bool block)
|
|
{
|
|
struct event ev;
|
|
|
|
if ( block || !queue_empty(&button_queue) )
|
|
{
|
|
queue_wait(&button_queue, &ev);
|
|
return ev.id;
|
|
}
|
|
return BUTTON_NONE;
|
|
}
|
|
|
|
long button_get_w_tmo(int ticks)
|
|
{
|
|
struct event ev;
|
|
queue_wait_w_tmo(&button_queue, &ev, ticks);
|
|
return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE;
|
|
}
|
|
|
|
void button_init(void)
|
|
{
|
|
tick_add_task(button_tick);
|
|
}
|
|
|
|
int button_status(void)
|
|
{
|
|
return lastbtn;
|
|
}
|
|
|
|
void button_clear_queue(void)
|
|
{
|
|
queue_clear(&button_queue);
|
|
}
|
|
|
|
#ifdef HAS_BUTTON_HOLD
|
|
bool button_hold(void) {
|
|
/* temp fix for hold button on irivers */
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAS_REMOTE_BUTTON_HOLD
|
|
bool remote_button_hold(void) {
|
|
/* temp fix for hold button on irivers */
|
|
return false;
|
|
}
|
|
#endif
|