From ca85c401f58e089b27a4d37ce76265985fa470d7 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Wed, 23 Sep 2009 16:59:56 +0000 Subject: Rework the simulators button reading to not implement it's own complete driver. Instead, implement it more as a target driver with button_read_device(), button_init_device() and button_hold(), then use the normal button driver from firmware/drivers/button.c. Fixes FS#10451 ("backlight off on hold doesn't function properly"). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22799 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/button.c | 27 +++-- uisimulator/sdl/button-sdl.h | 42 ++++++++ uisimulator/sdl/button.c | 227 ++++++------------------------------------- 3 files changed, 92 insertions(+), 204 deletions(-) create mode 100644 uisimulator/sdl/button-sdl.h diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 6f6eb8f222..7199d99e28 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c @@ -33,13 +33,16 @@ #include "serial.h" #include "power.h" #include "powermgmt.h" +#ifdef SIMULATOR +#include "button-sdl.h" +#else #include "button-target.h" +#endif #ifdef HAVE_REMOTE_LCD #include "lcd-remote.h" #endif -#ifndef SIMULATOR #if 0 /* Older than MAX_EVENT_AGE button events are going to be ignored. * Used to prevent for example volume going up uncontrollable when events @@ -82,9 +85,9 @@ static int button_read(void); #endif #ifdef HAVE_TOUCHSCREEN - int last_touchscreen_touch; +static int last_touchscreen_touch; #endif -#if defined(HAVE_HEADPHONE_DETECTION) +#if defined(HAVE_HEADPHONE_DETECTION) && !defined(SIMULATOR) static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */ /* This callback can be used for many different functions if needed - just check to which object tmo points */ @@ -211,8 +214,10 @@ static void button_tick(void) /* Safety net for players without hardware poweroff */ +#ifndef SIMULATOR if(repeat_count > POWEROFF_COUNT * 10) power_off(); +#endif } #endif } @@ -376,7 +381,11 @@ long button_get_w_tmo(int ticks) intptr_t button_get_data(void) { +#if defined(SIMULATOR) + return button_get_data_sdl(); +#else return button_data; +#endif } void button_init(void) @@ -416,6 +425,7 @@ void button_init(void) tick_add_task(button_tick); } +#ifndef SIMULATOR #ifdef BUTTON_DRIVER_CLOSE void button_close(void) { @@ -423,7 +433,7 @@ void button_close(void) } #endif /* BUTTON_DRIVER_CLOSE */ -#ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */ +#ifdef HAVE_LCD_FLIP /* * helper function to swap LEFT/RIGHT, UP/DOWN (if present), and F1/F3 (Recorder) */ @@ -508,7 +518,7 @@ void button_set_flip(bool flip) restore_irq(oldlevel); } } -#endif /* HAVE_LCD_BITMAP */ +#endif /* HAVE_LCD_FLIP */ #ifdef HAVE_BACKLIGHT void set_backlight_filter_keypress(bool value) @@ -523,6 +533,7 @@ void set_remote_backlight_filter_keypress(bool value) #endif #endif +#endif /* SIMULATOR */ /* * Get button pressed from hardware */ @@ -537,10 +548,11 @@ static int button_read(void) #endif int retval; -#ifdef HAVE_LCD_BITMAP +#ifdef HAVE_LCD_FLIP if (btn && flipped) btn = button_flip(btn); /* swap upside down */ -#endif +#endif /* HAVE_LCD_FLIP */ + #ifdef HAVE_TOUCHSCREEN if (btn & BUTTON_TOUCHSCREEN) last_touchscreen_touch = current_tick; @@ -574,7 +586,6 @@ int touchscreen_last_touch(void) return last_touchscreen_touch; } #endif -#endif /* SIMULATOR */ #ifdef HAVE_WHEEL_ACCELERATION /* WHEEL_ACCEL_FACTOR = 2^16 / WHEEL_ACCEL_START */ diff --git a/uisimulator/sdl/button-sdl.h b/uisimulator/sdl/button-sdl.h new file mode 100644 index 0000000000..0adb434e6a --- /dev/null +++ b/uisimulator/sdl/button-sdl.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Thomas Martitz + * + * 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. + * + ****************************************************************************/ + + +#ifndef _BUTTON_SDL_H_ +#define _BUTTON_SDL_H_ + +#include +#include "config.h" +#include "button-target.h" + +#define HAS_BUTTON_HOLD +#undef HAVE_LCD_FLIP + +#undef button_init_device +#define button_init_device() + +bool button_hold(void); +void button_init_sdl(void); +intptr_t button_get_data_sdl(void); +#undef button_init_device +#define button_init_device() button_init_sdl() + +#endif diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c index 45dfc3fe2c..c52cf12f9c 100644 --- a/uisimulator/sdl/button.c +++ b/uisimulator/sdl/button.c @@ -28,15 +28,13 @@ #include "backlight.h" #include "misc.h" #include "sim_tasks.h" +#include "button-sdl.h" #include "debug.h" -static intptr_t button_data; /* data value from last message dequeued */ - #ifdef HAVE_TOUCHSCREEN #include "touchscreen.h" static int mouse_coords = 0; -static int last_touchscreen_touch = 0xffff; #endif /* how long until repeat kicks in */ #define REPEAT_START 6 @@ -91,23 +89,9 @@ bool remote_button_hold(void) { } #endif -static int lastbtn; void button_event(int key, bool pressed) { int new_btn = 0; - int diff = 0; - int data = 0; - static int count = 0; - static int repeat_speed = REPEAT_INTERVAL_START; - static int repeat_count = 0; - static bool repeat = false; - static bool post = false; -#ifdef HAVE_BACKLIGHT - static bool skip_release = false; -#ifdef HAVE_REMOTE_LCD - static bool skip_remote_release = false; -#endif -#endif static bool usb_connected = false; if (usb_connected && key != SDLK_u) return; @@ -116,7 +100,6 @@ void button_event(int key, bool pressed) #ifdef HAVE_TOUCHSCREEN case BUTTON_TOUCHSCREEN: - data = mouse_coords; switch (touchscreen_get_mode()) { case TOUCHSCREEN_POINT: @@ -129,7 +112,8 @@ void button_event(int key, bool pressed) {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT}, {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT}, }; - int px_x = ((data&0xffff0000)>>16), px_y = ((data&0x0000ffff)); + int px_x = ((mouse_coords&0xffff0000)>>16); + int px_y = ((mouse_coords&0x0000ffff)); new_btn = touchscreen_buttons[px_y/(LCD_HEIGHT/3)][px_x/(LCD_WIDTH/3)]; break; } @@ -1223,177 +1207,30 @@ void button_event(int key, bool pressed) btn |= new_btn; else btn &= ~new_btn; - - /* Lots of stuff copied from real button.c. Not good, I think... */ - - /* Find out if a key has been released */ - diff = btn ^ lastbtn; - if(diff && (btn & diff) == 0) - { -#ifdef HAVE_BACKLIGHT -#ifdef HAVE_REMOTE_LCD - if(diff & BUTTON_REMOTE) - if(!skip_remote_release) - queue_post(&button_queue, BUTTON_REL | diff, data); - else - skip_remote_release = false; - else -#endif - if(!skip_release) - queue_post(&button_queue, BUTTON_REL | diff, data); - else - skip_release = false; -#else - queue_post(&button_queue, BUTTON_REL | diff, data); -#endif - } - - else - { - if ( btn ) - { - /* normal keypress */ - if ( btn != lastbtn ) - { - post = true; - repeat = false; - repeat_speed = REPEAT_INTERVAL_START; - - } - else /* repeat? */ - { - if ( repeat ) - { - if (!post) - 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) - { - if (queue_empty(&button_queue)) - { - queue_post(&button_queue, BUTTON_REPEAT | btn, data); -#ifdef HAVE_BACKLIGHT -#ifdef HAVE_REMOTE_LCD - if(btn & BUTTON_REMOTE) - { - if(skip_remote_release) - skip_remote_release = false; - } - else -#endif - if(skip_release) - skip_release = false; -#endif - post = false; - } - } - else - { -#ifdef HAVE_BACKLIGHT -#ifdef HAVE_REMOTE_LCD - if (btn & BUTTON_REMOTE) { - if (!remote_filter_first_keypress - || is_remote_backlight_on(false)) - queue_post(&button_queue, btn, data); - else - skip_remote_release = true; - } - else -#endif - if (!filter_first_keypress - || is_backlight_on(false)) - queue_post(&button_queue, btn, data); - else - skip_release = true; -#else /* no backlight, nothing to skip */ - queue_post(&button_queue, btn, data); -#endif - post = false; - } - -#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); } - -/* Again copied from real button.c... */ - -int button_queue_count( void ) +#ifdef HAVE_BUTTON_DATA +int button_read_device(int* data) { - return queue_count(&button_queue); -} - -long button_get(bool block) + (void)data; +#else +int button_read_device(void) { - struct queue_event ev; - - if ( block || !queue_empty(&button_queue) ) { - queue_wait(&button_queue, &ev); - button_data = ev.data; - return ev.id; +#endif + static int hold_button_old = false; + int hold_button = button_hold(); + /* light handling */ + if (hold_button != hold_button_old) + { + hold_button_old = hold_button; + backlight_hold_changed(hold_button); } - return BUTTON_NONE; -} -long button_get_w_tmo(int ticks) -{ - struct queue_event ev; - queue_wait_w_tmo(&button_queue, &ev, ticks); - if (ev.id == SYS_TIMEOUT) - ev.id = BUTTON_NONE; - else - button_data = ev.data; + if (hold_button) + return BUTTON_NONE; - return ev.id; + return btn; } -intptr_t button_get_data(void) -{ -#ifdef HAVE_TOUCHSCREEN - return button_data; -#else - /* Needed by the accelerating wheel driver for Sansa e200 */ - return 1 << 24; -#endif -} #ifdef HAVE_TOUCHSCREEN extern bool debug_wps; @@ -1416,31 +1253,29 @@ void mouse_tick_task(void) } mouse_coords = (x<<16)|y; - last_touchscreen_touch = current_tick; button_event(BUTTON_TOUCHSCREEN, true); if (debug_wps) printf("Mouse at: (%d, %d)\n", x, y); } } -int touchscreen_last_touch(void) -{ - return last_touchscreen_touch; -} + #endif -void button_init(void) + +intptr_t button_get_data_sdl(void) { #ifdef HAVE_TOUCHSCREEN - tick_add_task(mouse_tick_task); + /* pass the mouse coordinates to the button driver */ + return mouse_coords; +#else + /* pass scrollwheel acceleration to the button driver */ + return 1<<24; #endif } -int button_status(void) -{ - return btn; -} - -void button_clear_queue(void) +void button_init_sdl(void) { - queue_clear(&button_queue); +#ifdef HAVE_TOUCHSCREEN + tick_add_task(mouse_tick_task); +#endif } -- cgit v1.2.3