forked from len0rd/rockbox
Button queue handling is split from main button driver
First half of https://gerrit.rockbox.org/r/c/rockbox/+/570 Change-Id: Icc64dfd8194c18f69564ed5f8bf7dd70a4330eb9
This commit is contained in:
parent
5954a2fd48
commit
da9d67a0fe
30 changed files with 266 additions and 221 deletions
185
firmware/drivers/button_queue.c
Normal file
185
firmware/drivers/button_queue.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Daniel Stenberg
|
||||
*
|
||||
* 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 "config.h"
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "button.h"
|
||||
|
||||
static struct event_queue button_queue SHAREDBSS_ATTR;
|
||||
static intptr_t button_data; /* data value from last message dequeued */
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
static bool button_boosted = false;
|
||||
static long button_unboost_tick;
|
||||
#define BUTTON_UNBOOST_TMO HZ
|
||||
|
||||
static void button_boost(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
/* update the unboost time each button_boost(true) call */
|
||||
button_unboost_tick = current_tick + BUTTON_UNBOOST_TMO;
|
||||
|
||||
if (!button_boosted)
|
||||
{
|
||||
button_boosted = true;
|
||||
cpu_boost(true);
|
||||
}
|
||||
}
|
||||
else if (!button_boosted && TIME_AFTER(current_tick, button_unboost_tick))
|
||||
{
|
||||
button_boosted = false;
|
||||
cpu_boost(false);
|
||||
}
|
||||
}
|
||||
|
||||
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 == TIMEOUT_NOBLOCK)
|
||||
;
|
||||
else if (ticks > 0)
|
||||
{
|
||||
if (button_boosted && ticks > BUTTON_UNBOOST_TMO)
|
||||
ticks = BUTTON_UNBOOST_TMO;
|
||||
|
||||
timeout -= ticks;
|
||||
}
|
||||
else if (button_boosted) /* TIMEOUT_BLOCK (ticks < 0) */
|
||||
{
|
||||
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);
|
||||
|
||||
break;
|
||||
}
|
||||
button_boost(false);
|
||||
}
|
||||
while (timeout);
|
||||
}
|
||||
#else /* ndef HAVE_ADJUSTABLE_CPU_FREQ */
|
||||
static inline void button_queue_wait(struct queue_event *evp, int timeout)
|
||||
{
|
||||
queue_wait_w_tmo(&button_queue, evp, timeout);
|
||||
}
|
||||
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */
|
||||
|
||||
void button_queue_post(long id, intptr_t data)
|
||||
{
|
||||
queue_post(&button_queue, id, data);
|
||||
}
|
||||
|
||||
void button_queue_post_remove_head(long id, intptr_t data)
|
||||
{
|
||||
queue_remove_from_head(&button_queue, id);
|
||||
queue_post(&button_queue, id, data);
|
||||
}
|
||||
|
||||
bool button_queue_try_post(long 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 */
|
||||
const bool force_post = true;
|
||||
#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
|
||||
* processed yet - but always post releases */
|
||||
const bool force_post = button & BUTTON_REL;
|
||||
#endif
|
||||
|
||||
if (!queue_empty(&button_queue))
|
||||
{
|
||||
if (force_post)
|
||||
queue_remove_from_head(&button_queue, button);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
queue_post(&button_queue, button, data);
|
||||
|
||||
/* on touchscreen we posted unconditionally */
|
||||
return true;
|
||||
}
|
||||
|
||||
int button_queue_count(void)
|
||||
{
|
||||
return queue_count(&button_queue);
|
||||
}
|
||||
|
||||
bool button_queue_empty(void)
|
||||
{
|
||||
return queue_empty(&button_queue);
|
||||
}
|
||||
|
||||
bool button_queue_full(void)
|
||||
{
|
||||
return queue_full(&button_queue);
|
||||
}
|
||||
|
||||
void button_clear_queue(void)
|
||||
{
|
||||
queue_clear(&button_queue);
|
||||
}
|
||||
|
||||
long button_get_w_tmo(int ticks)
|
||||
{
|
||||
struct queue_event ev;
|
||||
button_queue_wait(&ev, ticks);
|
||||
|
||||
if (ev.id == SYS_TIMEOUT)
|
||||
ev.id = BUTTON_NONE;
|
||||
else
|
||||
button_data = ev.data;
|
||||
|
||||
return ev.id;
|
||||
}
|
||||
|
||||
long button_get(bool block)
|
||||
{
|
||||
return button_get_w_tmo(block ? TIMEOUT_BLOCK : TIMEOUT_NOBLOCK);
|
||||
}
|
||||
|
||||
intptr_t button_get_data(void)
|
||||
{
|
||||
return button_data;
|
||||
}
|
||||
|
||||
void INIT_ATTR button_queue_init(void)
|
||||
{
|
||||
queue_init(&button_queue, true);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue