summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES21
-rw-r--r--firmware/drivers/audio/sdl.c186
-rw-r--r--firmware/drivers/button.c9
-rw-r--r--firmware/export/audiohw.h6
-rw-r--r--firmware/export/config/sim.h4
-rw-r--r--firmware/export/system.h1
-rw-r--r--firmware/kernel.c5
-rw-r--r--firmware/libc/include/stdlib.h3
-rw-r--r--firmware/sound.c85
-rw-r--r--firmware/target/hosted/sdl/button-sdl.c2018
-rw-r--r--firmware/target/hosted/sdl/button-sdl.h32
-rw-r--r--firmware/target/hosted/sdl/kernel-sdl.c162
-rw-r--r--firmware/target/hosted/sdl/lcd-bitmap.c416
-rw-r--r--firmware/target/hosted/sdl/lcd-bitmap.h35
-rw-r--r--firmware/target/hosted/sdl/lcd-charcells.c198
-rw-r--r--firmware/target/hosted/sdl/lcd-charcells.h34
-rw-r--r--firmware/target/hosted/sdl/lcd-remote-bitmap.c111
-rw-r--r--firmware/target/hosted/sdl/lcd-remote-bitmap.h32
-rw-r--r--firmware/target/hosted/sdl/lcd-sdl.c113
-rw-r--r--firmware/target/hosted/sdl/lcd-sdl.h43
-rw-r--r--firmware/target/hosted/sdl/pcm-sdl.c373
-rw-r--r--firmware/target/hosted/sdl/sim-ui-defines.h405
-rw-r--r--firmware/target/hosted/sdl/system-sdl.c236
-rw-r--r--firmware/target/hosted/sdl/system-sdl.h52
-rw-r--r--firmware/target/hosted/sdl/thread-sdl.c610
-rw-r--r--firmware/target/hosted/sdl/thread-sdl.h32
-rw-r--r--firmware/target/hosted/sdl/timer-sdl.c61
27 files changed, 5188 insertions, 95 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 68074dbbec..47249a2d6d 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -18,6 +18,22 @@ rolo.c
18thread.c 18thread.c
19timer.c 19timer.c
20#endif /* SIMULATOR */ 20#endif /* SIMULATOR */
21#ifdef HAVE_SDL
22target/hosted/sdl/button-sdl.c
23target/hosted/sdl/kernel-sdl.c
24#ifdef HAVE_LCD_BITMAP
25target/hosted/sdl/lcd-bitmap.c
26#elif defined(HAVE_LCD_CHARCELLS)
27target/hosted/sdl/lcd-charcells.c
28#endif
29#ifdef HAVE_REMOTE_LCD
30target/hosted/sdl/lcd-remote-bitmap.c
31#endif
32target/hosted/sdl/lcd-sdl.c
33target/hosted/sdl/system-sdl.c
34target/hosted/sdl/thread-sdl.c
35target/hosted/sdl/timer-sdl.c
36#endif
21panic.c 37panic.c
22debug.c 38debug.c
23 39
@@ -292,6 +308,11 @@ drivers/audio/ak4537.c
292#elif defined(HAVE_UDA1341) 308#elif defined(HAVE_UDA1341)
293drivers/audio/uda1341.c 309drivers/audio/uda1341.c
294#endif /* defined(HAVE_*) */ 310#endif /* defined(HAVE_*) */
311#elif defined(HAVE_SDL_AUDIO)
312drivers/audio/sdl.c
313#if CONFIG_CODEC == SWCODEC
314target/hosted/sdl/pcm-sdl.c
315#endif
295#endif /* !defined(SIMULATOR) && !defined(BOOTLOADER) */ 316#endif /* !defined(SIMULATOR) && !defined(BOOTLOADER) */
296 317
297/* USB Stack */ 318/* USB Stack */
diff --git a/firmware/drivers/audio/sdl.c b/firmware/drivers/audio/sdl.c
new file mode 100644
index 0000000000..c063192873
--- /dev/null
+++ b/firmware/drivers/audio/sdl.c
@@ -0,0 +1,186 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright © 2010 Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <SDL_audio.h>
23#include "config.h"
24#include "audiohw.h"
25
26/**
27 * Audio Hardware api. Make them do nothing as we cannot properly simulate with
28 * SDL. if we used DSP we would run code that doesn't actually run on the target
29 **/
30
31extern void pcm_set_mixer_volume(int);
32
33void audiohw_set_volume(int volume)
34{
35#if CONFIG_CODEC == SWCODEC
36 pcm_set_mixer_volume(
37 SDL_MIX_MAXVOLUME * ((volume - VOLUME_MIN) / 10) / (VOLUME_RANGE / 10));
38#else
39 (void)volume;
40#endif
41}
42
43const struct sound_settings_info audiohw_settings[] = {
44 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
45/* Bass and treble tone controls */
46#ifdef AUDIOHW_HAVE_BASS
47 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
48#endif
49#ifdef AUDIOHW_HAVE_TREBLE
50 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
51#endif
52 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
53 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
54 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
55#if defined(HAVE_RECORDING)
56 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
57 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
58 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
59#endif
60#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
61 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
62#endif
63#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
64 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
65#endif
66#if defined(AUDIOHW_HAVE_DEPTH_3D)
67 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
68#endif
69/* Hardware EQ tone controls */
70#if defined(AUDIOHW_HAVE_EQ_BAND1)
71 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
72#endif
73#if defined(AUDIOHW_HAVE_EQ_BAND2)
74 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
75#endif
76#if defined(AUDIOHW_HAVE_EQ_BAND3)
77 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
78#endif
79#if defined(AUDIOHW_HAVE_EQ_BAND4)
80 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
81#endif
82#if defined(AUDIOHW_HAVE_EQ_BAND5)
83 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
84#endif
85#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
86 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1},
87#endif
88#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
89 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1},
90#endif
91#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
92 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1},
93#endif
94#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
95 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1},
96#endif
97#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
98 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1},
99#endif
100#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
101 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
102#endif
103#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
104 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
105#endif
106#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
107 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
108#endif
109
110#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
111 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
112 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
113 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
114 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
115 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
116 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
117 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
118 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
119#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
120};
121
122/**
123 * stubs here, for the simulator
124 **/
125
126#if defined(AUDIOHW_HAVE_PRESCALER)
127void audiohw_set_prescaler(int value) { (void)value; }
128#endif
129#if defined(AUDIOHW_HAVE_BALANCE)
130void audiohw_set_balance(int value) { (void)value; }
131#endif
132#if defined(AUDIOHW_HAVE_BASS)
133void audiohw_set_bass(int value) { (void)value; }
134#endif
135#if defined(AUDIOHW_HAVE_TREBLE)
136void audiohw_set_treble(int value) { (void)value; }
137#endif
138#if CONFIG_CODEC != SWCODEC
139void audiohw_set_channel(int value) { (void)value; }
140void audiohw_set_stereo_width(int value){ (void)value; }
141#endif
142#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
143void audiohw_set_bass_cutoff(int value) { (void)value; }
144#endif
145#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
146void audiohw_set_treble_cutoff(int value){ (void)value; }
147#endif
148/* EQ-based tone controls */
149#if defined(AUDIOHW_HAVE_EQ)
150void audiohw_set_eq_band_gain(unsigned int band, int value)
151 { (void)band; (void)value; }
152#endif
153#if defined(AUDIOHW_HAVE_EQ_FREQUENCY)
154void audiohw_set_eq_band_frequency(unsigned int band, int value)
155 { (void)band; (void)value; }
156#endif
157#if defined(AUDIOHW_HAVE_EQ_WIDTH)
158void audiohw_set_eq_band_width(unsigned int band, int value)
159 { (void)band; (void)value; }
160#endif
161#if defined(AUDIOHW_HAVE_DEPTH_3D)
162void audiohw_set_depth_3d(int value)
163 { (void)value; }
164#endif
165#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
166int mas_codec_readreg(int reg)
167{
168 (void)reg;
169 return 0;
170}
171
172int mas_codec_writereg(int reg, unsigned int val)
173{
174 (void)reg;
175 (void)val;
176 return 0;
177}
178int mas_writemem(int bank, int addr, const unsigned long* src, int len)
179{
180 (void)bank;
181 (void)addr;
182 (void)src;
183 (void)len;
184 return 0;
185}
186#endif
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 100957b77a..f116ad646e 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -429,7 +429,6 @@ void button_init(void)
429 tick_add_task(button_tick); 429 tick_add_task(button_tick);
430} 430}
431 431
432#ifndef SIMULATOR
433#ifdef BUTTON_DRIVER_CLOSE 432#ifdef BUTTON_DRIVER_CLOSE
434void button_close(void) 433void button_close(void)
435{ 434{
@@ -443,9 +442,10 @@ void button_close(void)
443 */ 442 */
444static int button_flip(int button) 443static int button_flip(int button)
445{ 444{
446 int newbutton; 445 int newbutton = button;
447 446
448 newbutton = button & 447#ifndef SIMULATOR
448 newbutton &=
449 ~(BUTTON_LEFT | BUTTON_RIGHT 449 ~(BUTTON_LEFT | BUTTON_RIGHT
450#if defined(BUTTON_UP) && defined(BUTTON_DOWN) 450#if defined(BUTTON_UP) && defined(BUTTON_DOWN)
451 | BUTTON_UP | BUTTON_DOWN 451 | BUTTON_UP | BUTTON_DOWN
@@ -503,7 +503,7 @@ static int button_flip(int button)
503 if (button & BUTTON_PREV) 503 if (button & BUTTON_PREV)
504 newbutton |= BUTTON_NEXT; 504 newbutton |= BUTTON_NEXT;
505#endif 505#endif
506 506#endif /* !SIMULATOR */
507 return newbutton; 507 return newbutton;
508} 508}
509 509
@@ -523,7 +523,6 @@ void button_set_flip(bool flip)
523 } 523 }
524} 524}
525#endif /* HAVE_LCD_FLIP */ 525#endif /* HAVE_LCD_FLIP */
526#endif /* SIMULATOR */
527 526
528#ifdef HAVE_BACKLIGHT 527#ifdef HAVE_BACKLIGHT
529void set_backlight_filter_keypress(bool value) 528void set_backlight_filter_keypress(bool value)
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h
index d7ee551e40..b8214e67b9 100644
--- a/firmware/export/audiohw.h
+++ b/firmware/export/audiohw.h
@@ -66,6 +66,10 @@
66#elif defined(HAVE_AK4537) 66#elif defined(HAVE_AK4537)
67#include "ak4537.h" 67#include "ak4537.h"
68#endif 68#endif
69#if defined(HAVE_SDL_AUDIO)
70/* #include <SDL_audio.h> gives errors in other code areas,
71 * we don't really need it here, so don't. but it should maybe be fixed */
72#endif
69 73
70 74
71 75
@@ -369,7 +373,7 @@ void audiohw_postinit(void);
369 */ 373 */
370void audiohw_close(void); 374void audiohw_close(void);
371 375
372#ifdef AUDIOHW_HAVE_CLIPPING 376#if defined(AUDIOHW_HAVE_CLIPPING) || defined(HAVE_SDL_AUDIO)
373 /** 377 /**
374 * Set new volume value 378 * Set new volume value
375 * @param val to set. 379 * @param val to set.
diff --git a/firmware/export/config/sim.h b/firmware/export/config/sim.h
index 6d2e6d24ea..d65b0fbbf8 100644
--- a/firmware/export/config/sim.h
+++ b/firmware/export/config/sim.h
@@ -80,6 +80,8 @@
80 80
81#undef HAVE_SPEAKER 81#undef HAVE_SPEAKER
82 82
83#undef BUTTON_DRIVER_CLOSE
84
83#if CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG 85#if CONFIG_BACKLIGHT_FADING == BACKLIGHT_FADING_SW_HW_REG
84#undef CONFIG_BACKLIGHT_FADING 86#undef CONFIG_BACKLIGHT_FADING
85 /* simulate SW_SETTING, as we handle sdl very similary */ 87 /* simulate SW_SETTING, as we handle sdl very similary */
@@ -97,4 +99,6 @@
97#define DEFAULT_BRIGHTNESS_SETTING MAX_BRIGHTNESS_SETTING 99#define DEFAULT_BRIGHTNESS_SETTING MAX_BRIGHTNESS_SETTING
98#endif 100#endif
99 101
102#define HAVE_SDL
103#define HAVE_SDL_AUDIO
100#define _ISOC99_SOURCE 1 104#define _ISOC99_SOURCE 1
diff --git a/firmware/export/system.h b/firmware/export/system.h
index bd31c03028..fc582aac03 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -235,6 +235,7 @@ enum {
235#if !defined(SIMULATOR) && !defined(__PCTOOL__) 235#if !defined(SIMULATOR) && !defined(__PCTOOL__)
236#include "system-target.h" 236#include "system-target.h"
237#else /* SIMULATOR */ 237#else /* SIMULATOR */
238#include "system-sdl.h"
238static inline uint16_t swap16(uint16_t value) 239static inline uint16_t swap16(uint16_t value)
239 /* 240 /*
240 result[15..8] = value[ 7..0]; 241 result[15..8] = value[ 7..0];
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 64c8142540..d8c67e8485 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -22,14 +22,11 @@
22#include <string.h> 22#include <string.h>
23#include "config.h" 23#include "config.h"
24#include "kernel.h" 24#include "kernel.h"
25#ifdef SIMULATOR
26#include "system-sdl.h"
27#include "debug.h"
28#endif
29#include "thread.h" 25#include "thread.h"
30#include "cpu.h" 26#include "cpu.h"
31#include "system.h" 27#include "system.h"
32#include "panic.h" 28#include "panic.h"
29#include "debug.h"
33 30
34/* Make this nonzero to enable more elaborate checks on objects */ 31/* Make this nonzero to enable more elaborate checks on objects */
35#if defined(DEBUG) || defined(SIMULATOR) 32#if defined(DEBUG) || defined(SIMULATOR)
diff --git a/firmware/libc/include/stdlib.h b/firmware/libc/include/stdlib.h
index 5f6db6da8a..57553367c4 100644
--- a/firmware/libc/include/stdlib.h
+++ b/firmware/libc/include/stdlib.h
@@ -29,6 +29,7 @@ void *malloc(size_t);
29void *calloc (size_t nmemb, size_t size); 29void *calloc (size_t nmemb, size_t size);
30void free(void *); 30void free(void *);
31void *realloc(void *, size_t); 31void *realloc(void *, size_t);
32int atexit(void (*)(void));
32 33
33#define RAND_MAX INT_MAX 34#define RAND_MAX INT_MAX
34 35
@@ -51,7 +52,7 @@ void exit(int status);
51#endif 52#endif
52 53
53int atoi (const char *str); 54int atoi (const char *str);
54 55
55#ifdef __cplusplus 56#ifdef __cplusplus
56} 57}
57#endif 58#endif
diff --git a/firmware/sound.c b/firmware/sound.c
index fb2f353d71..dccca12264 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -43,89 +43,6 @@
43 43
44extern bool audio_is_initialized; 44extern bool audio_is_initialized;
45 45
46#ifdef SIMULATOR
47extern void audiohw_set_volume(int value);
48/* dummy for sim */
49const struct sound_settings_info audiohw_settings[] = {
50 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
51/* Bass and treble tone controls */
52#ifdef AUDIOHW_HAVE_BASS
53 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
54#endif
55#ifdef AUDIOHW_HAVE_TREBLE
56 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
57#endif
58 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
59 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
60 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
61#if defined(HAVE_RECORDING)
62 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
63 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
64 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
65#endif
66#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
67 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
68#endif
69#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
70 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
71#endif
72#if defined(AUDIOHW_HAVE_DEPTH_3D)
73 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
74#endif
75/* Hardware EQ tone controls */
76#if defined(AUDIOHW_HAVE_EQ_BAND1)
77 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
78#endif
79#if defined(AUDIOHW_HAVE_EQ_BAND2)
80 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
81#endif
82#if defined(AUDIOHW_HAVE_EQ_BAND3)
83 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
84#endif
85#if defined(AUDIOHW_HAVE_EQ_BAND4)
86 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
87#endif
88#if defined(AUDIOHW_HAVE_EQ_BAND5)
89 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
90#endif
91#if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
92 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1},
93#endif
94#if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
95 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1},
96#endif
97#if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
98 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1},
99#endif
100#if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
101 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1},
102#endif
103#if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
104 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1},
105#endif
106#if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
107 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
108#endif
109#if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
110 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
111#endif
112#if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
113 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
114#endif
115
116#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
117 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
118 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
119 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
120 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
121 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
122 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
123 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
124 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
125#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
126};
127#endif
128
129const char *sound_unit(int setting) 46const char *sound_unit(int setting)
130{ 47{
131 return audiohw_settings[setting].unit; 48 return audiohw_settings[setting].unit;
@@ -356,7 +273,7 @@ static void set_prescaled_volume(void)
356 273
357#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) 274#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985)
358 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); 275 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
359#elif defined(HAVE_JZ4740_CODEC) 276#elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO)
360 audiohw_set_volume(current_volume); 277 audiohw_set_volume(current_volume);
361#endif 278#endif
362#else /* SIMULATOR */ 279#else /* SIMULATOR */
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
new file mode 100644
index 0000000000..51ba8cff92
--- /dev/null
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -0,0 +1,2018 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Felix Arends
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <math.h>
23#include "sim-ui-defines.h"
24#include "lcd-charcells.h"
25#include "lcd-remote.h"
26#include "config.h"
27#include "button.h"
28#include "kernel.h"
29#include "backlight.h"
30#include "misc.h"
31#include "sim_tasks.h"
32#include "button-sdl.h"
33#include "backlight.h"
34
35#include "debug.h"
36
37#ifdef HAVE_TOUCHSCREEN
38#include "touchscreen.h"
39static int mouse_coords = 0;
40#endif
41/* how long until repeat kicks in */
42#define REPEAT_START 6
43
44/* the speed repeat starts at */
45#define REPEAT_INTERVAL_START 4
46
47/* speed repeat finishes at */
48#define REPEAT_INTERVAL_FINISH 2
49
50#ifdef HAVE_TOUCHSCREEN
51#define USB_KEY SDLK_c /* SDLK_u is taken by BUTTON_MIDLEFT */
52#else
53#define USB_KEY SDLK_u
54#endif
55
56#if defined(IRIVER_H100_SERIES) || defined (IRIVER_H300_SERIES)
57int _remote_type=REMOTETYPE_H100_LCD;
58
59int remote_type(void)
60{
61 return _remote_type;
62}
63#endif
64
65static int xy2button(int x, int y);
66
67struct event_queue button_queue;
68
69static int btn = 0; /* Hopefully keeps track of currently pressed keys... */
70
71#ifdef HAS_BUTTON_HOLD
72bool hold_button_state = false;
73bool button_hold(void) {
74 return hold_button_state;
75}
76#endif
77
78#ifdef HAS_REMOTE_BUTTON_HOLD
79bool remote_hold_button_state = false;
80bool remote_button_hold(void) {
81 return remote_hold_button_state;
82}
83#endif
84static void button_event(int key, bool pressed);
85extern bool debug_wps;
86extern bool mapping;
87static void gui_message_loop(void)
88{
89 SDL_Event event;
90 static int x,y,xybutton = 0;
91
92 if (SDL_PollEvent(&event))
93 {
94 switch(event.type)
95 {
96 case SDL_KEYDOWN:
97 button_event(event.key.keysym.sym, true);
98 break;
99 case SDL_KEYUP:
100 button_event(event.key.keysym.sym, false);
101 case SDL_MOUSEBUTTONDOWN:
102 switch ( event.button.button ) {
103#ifdef HAVE_SCROLLWHEEL
104 case SDL_BUTTON_WHEELUP:
105 button_event( SDLK_UP, true );
106 break;
107 case SDL_BUTTON_WHEELDOWN:
108 button_event( SDLK_DOWN, true );
109 break;
110#endif
111 case SDL_BUTTON_LEFT:
112 case SDL_BUTTON_MIDDLE:
113 if ( mapping && background ) {
114 x = event.button.x;
115 y = event.button.y;
116 }
117 if ( background ) {
118 xybutton = xy2button( event.button.x, event.button.y );
119 if( xybutton )
120 button_event( xybutton, true );
121 }
122 break;
123 default:
124 break;
125 }
126
127 if (debug_wps && event.button.button == 1)
128 {
129 if ( background )
130#ifdef HAVE_REMOTE
131 if ( event.button.y < UI_REMOTE_POSY ) /* Main Screen */
132 printf("Mouse at: (%d, %d)\n", event.button.x - UI_LCD_POSX -1 , event.button.y - UI_LCD_POSY - 1 );
133 else
134 printf("Mouse at: (%d, %d)\n", event.button.x - UI_REMOTE_POSX -1 , event.button.y - UI_REMOTE_POSY - 1 );
135#else
136 printf("Mouse at: (%d, %d)\n", event.button.x - UI_LCD_POSX -1 , event.button.y - UI_LCD_POSY - 1 );
137#endif
138 else
139 if ( event.button.y/display_zoom < LCD_HEIGHT ) /* Main Screen */
140 printf("Mouse at: (%d, %d)\n", event.button.x/display_zoom, event.button.y/display_zoom );
141#ifdef HAVE_REMOTE
142 else
143 printf("Mouse at: (%d, %d)\n", event.button.x/display_zoom, event.button.y/display_zoom - LCD_HEIGHT );
144#endif
145 }
146 break;
147 case SDL_MOUSEBUTTONUP:
148 switch ( event.button.button ) {
149 /* The scrollwheel button up events are ignored as they are queued immediately */
150 case SDL_BUTTON_LEFT:
151 case SDL_BUTTON_MIDDLE:
152 if ( mapping && background ) {
153 printf(" { SDLK_, %d, %d, %d, \"\" },\n", x,
154#define SQUARE(x) ((x)*(x))
155 y, (int)sqrt( SQUARE(x-(int)event.button.x)
156 + SQUARE(y-(int)event.button.y)) );
157 }
158 if ( background && xybutton ) {
159 button_event( xybutton, false );
160 xybutton = 0;
161 }
162#ifdef HAVE_TOUCHSCREEN
163 else {
164 button_event(BUTTON_TOUCHSCREEN, false);
165 }
166#endif
167 break;
168 default:
169 break;
170 }
171 break;
172
173
174 case SDL_QUIT:
175 {
176 exit(EXIT_SUCCESS);
177 break;
178 }
179 default:
180 /*printf("Unhandled event\n"); */
181 break;
182 }
183 }
184}
185
186static void button_event(int key, bool pressed)
187{
188 int new_btn = 0;
189 static bool usb_connected = false;
190 if (usb_connected && key != USB_KEY)
191 return;
192 switch (key)
193 {
194
195#ifdef HAVE_TOUCHSCREEN
196 case BUTTON_TOUCHSCREEN:
197 switch (touchscreen_get_mode())
198 {
199 case TOUCHSCREEN_POINT:
200 new_btn = BUTTON_TOUCHSCREEN;
201 break;
202 case TOUCHSCREEN_BUTTON:
203 {
204 static int touchscreen_buttons[3][3] = {
205 {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT},
206 {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT},
207 {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT},
208 };
209 int px_x = ((mouse_coords&0xffff0000)>>16);
210 int px_y = ((mouse_coords&0x0000ffff));
211 new_btn = touchscreen_buttons[px_y/(LCD_HEIGHT/3)][px_x/(LCD_WIDTH/3)];
212 break;
213 }
214 }
215 break;
216 case SDLK_KP7:
217 case SDLK_7:
218 new_btn = BUTTON_TOPLEFT;
219 break;
220 case SDLK_KP8:
221 case SDLK_8:
222 case SDLK_UP:
223 new_btn = BUTTON_TOPMIDDLE;
224 break;
225 case SDLK_KP9:
226 case SDLK_9:
227 new_btn = BUTTON_TOPRIGHT;
228 break;
229 case SDLK_KP4:
230 case SDLK_u:
231 case SDLK_LEFT:
232 new_btn = BUTTON_MIDLEFT;
233 break;
234 case SDLK_KP5:
235 case SDLK_i:
236 new_btn = BUTTON_CENTER;
237 break;
238 case SDLK_KP6:
239 case SDLK_o:
240 case SDLK_RIGHT:
241 new_btn = BUTTON_MIDRIGHT;
242 break;
243 case SDLK_KP1:
244 case SDLK_j:
245 new_btn = BUTTON_BOTTOMLEFT;
246 break;
247 case SDLK_KP2:
248 case SDLK_k:
249 case SDLK_DOWN:
250 new_btn = BUTTON_BOTTOMMIDDLE;
251 break;
252 case SDLK_KP3:
253 case SDLK_l:
254 new_btn = BUTTON_BOTTOMRIGHT;
255 break;
256 case SDLK_F4:
257 if(pressed)
258 {
259 touchscreen_set_mode(touchscreen_get_mode() == TOUCHSCREEN_POINT ? TOUCHSCREEN_BUTTON : TOUCHSCREEN_POINT);
260 printf("Touchscreen mode: %s\n", touchscreen_get_mode() == TOUCHSCREEN_POINT ? "TOUCHSCREEN_POINT" : "TOUCHSCREEN_BUTTON");
261 }
262 break;
263
264#endif
265 case USB_KEY:
266 if (!pressed)
267 {
268 usb_connected = !usb_connected;
269 if (usb_connected)
270 queue_post(&button_queue, SYS_USB_CONNECTED, 0);
271 else
272 queue_post(&button_queue, SYS_USB_DISCONNECTED, 0);
273 }
274 return;
275
276#ifdef HAS_BUTTON_HOLD
277 case SDLK_h:
278 if(pressed)
279 {
280 hold_button_state = !hold_button_state;
281 DEBUGF("Hold button is %s\n", hold_button_state?"ON":"OFF");
282 }
283 return;
284#endif
285
286#ifdef HAS_REMOTE_BUTTON_HOLD
287 case SDLK_j:
288 if(pressed)
289 {
290 remote_hold_button_state = !remote_hold_button_state;
291 DEBUGF("Remote hold button is %s\n",
292 remote_hold_button_state?"ON":"OFF");
293 }
294 return;
295#endif
296
297#if CONFIG_KEYPAD == GIGABEAT_PAD
298 case SDLK_KP4:
299 case SDLK_LEFT:
300 new_btn = BUTTON_LEFT;
301 break;
302 case SDLK_KP6:
303 case SDLK_RIGHT:
304 new_btn = BUTTON_RIGHT;
305 break;
306 case SDLK_KP8:
307 case SDLK_UP:
308 new_btn = BUTTON_UP;
309 break;
310 case SDLK_KP2:
311 case SDLK_DOWN:
312 new_btn = BUTTON_DOWN;
313 break;
314 case SDLK_KP_PLUS:
315 case SDLK_F8:
316 new_btn = BUTTON_POWER;
317 break;
318 case SDLK_ESCAPE:
319 new_btn = BUTTON_POWER;
320 break;
321 case SDLK_KP_ENTER:
322 case SDLK_RETURN:
323 case SDLK_a:
324 new_btn = BUTTON_A;
325 break;
326 case SDLK_KP5:
327 case SDLK_SPACE:
328 new_btn = BUTTON_SELECT;
329 break;
330 case SDLK_KP_PERIOD:
331 case SDLK_INSERT:
332 new_btn = BUTTON_MENU;
333 break;
334 case SDLK_KP9:
335 new_btn = BUTTON_VOL_UP;
336 break;
337 case SDLK_KP3:
338 new_btn = BUTTON_VOL_DOWN;
339 break;
340
341#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
342 case SDLK_KP4:
343 case SDLK_LEFT:
344 new_btn = BUTTON_LEFT;
345 break;
346 case SDLK_KP6:
347 case SDLK_RIGHT:
348 new_btn = BUTTON_RIGHT;
349 break;
350 case SDLK_KP8:
351 case SDLK_UP:
352 new_btn = BUTTON_UP;
353 break;
354 case SDLK_KP2:
355 case SDLK_DOWN:
356 new_btn = BUTTON_DOWN;
357 break;
358 case SDLK_F8:
359 case SDLK_ESCAPE:
360 new_btn = BUTTON_POWER;
361 break;
362 case SDLK_KP_PLUS:
363 case SDLK_KP_ENTER:
364 case SDLK_RETURN:
365 new_btn = BUTTON_PLAY;
366 break;
367 case SDLK_KP7:
368 new_btn = BUTTON_BACK;
369 break;
370 case SDLK_KP5:
371 case SDLK_SPACE:
372 new_btn = BUTTON_SELECT;
373 break;
374 case SDLK_KP9:
375 case SDLK_KP_PERIOD:
376 case SDLK_INSERT:
377 new_btn = BUTTON_MENU;
378 break;
379
380#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
381 case SDLK_KP4:
382 case SDLK_LEFT:
383 new_btn = BUTTON_LEFT;
384 break;
385 case SDLK_KP6:
386 case SDLK_RIGHT:
387 new_btn = BUTTON_RIGHT;
388 break;
389 case SDLK_KP8:
390 case SDLK_UP:
391 new_btn = BUTTON_UP;
392 break;
393 case SDLK_KP2:
394 case SDLK_DOWN:
395 new_btn = BUTTON_DOWN;
396 break;
397 case SDLK_KP_PLUS:
398 case SDLK_F8:
399 new_btn = BUTTON_PLAY;
400 break;
401 case SDLK_ESCAPE:
402 new_btn = BUTTON_POWER;
403 break;
404 case SDLK_KP_ENTER:
405 case SDLK_RETURN:
406 case SDLK_a:
407 new_btn = BUTTON_POWER;
408 break;
409 case SDLK_KP_DIVIDE:
410 case SDLK_F1:
411 new_btn = BUTTON_REC;
412 break;
413 case SDLK_KP5:
414 case SDLK_SPACE:
415 new_btn = BUTTON_SELECT;
416 break;
417
418#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
419 case SDLK_KP4:
420 new_btn = BUTTON_LEFT;
421 break;
422 case SDLK_LEFT:
423 new_btn = BUTTON_RC_REW;
424 break;
425 case SDLK_KP6:
426 new_btn = BUTTON_RIGHT;
427 break;
428 case SDLK_RIGHT:
429 new_btn = BUTTON_RC_FF;
430 break;
431 case SDLK_KP8:
432 new_btn = BUTTON_VOL_UP;
433 break;
434 case SDLK_UP:
435 new_btn = BUTTON_RC_VOL_UP;
436 break;
437 case SDLK_KP2:
438 new_btn = BUTTON_VOL_DOWN;
439 break;
440 case SDLK_DOWN:
441 new_btn = BUTTON_RC_VOL_DOWN;
442 break;
443 case SDLK_KP_PERIOD:
444 new_btn = BUTTON_MODE;
445 break;
446 case SDLK_INSERT:
447 new_btn = BUTTON_RC_MODE;
448 break;
449 case SDLK_KP_DIVIDE:
450 new_btn = BUTTON_REC;
451 break;
452 case SDLK_F1:
453 new_btn = BUTTON_RC_REC;
454 break;
455 case SDLK_KP5:
456 new_btn = BUTTON_PLAY;
457 break;
458 case SDLK_SPACE:
459 new_btn = BUTTON_RC_PLAY;
460 break;
461 case SDLK_KP_ENTER:
462 case SDLK_RETURN:
463 new_btn = BUTTON_RC_MENU;
464 break;
465
466#elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \
467 || (CONFIG_KEYPAD == IPOD_4G_PAD)
468 case SDLK_KP4:
469 case SDLK_LEFT:
470 new_btn = BUTTON_LEFT;
471 break;
472 case SDLK_KP6:
473 case SDLK_RIGHT:
474 new_btn = BUTTON_RIGHT;
475 break;
476 case SDLK_KP8:
477 case SDLK_UP:
478 new_btn = BUTTON_SCROLL_BACK;
479 break;
480 case SDLK_KP2:
481 case SDLK_DOWN:
482 new_btn = BUTTON_SCROLL_FWD;
483 break;
484 case SDLK_KP_PLUS:
485 case SDLK_F8:
486 new_btn = BUTTON_PLAY;
487 break;
488 case SDLK_KP5:
489 case SDLK_SPACE:
490 new_btn = BUTTON_SELECT;
491 break;
492 case SDLK_KP_PERIOD:
493 case SDLK_INSERT:
494 new_btn = BUTTON_MENU;
495 break;
496
497#elif CONFIG_KEYPAD == IRIVER_H10_PAD
498 case SDLK_KP4:
499 case SDLK_LEFT:
500 new_btn = BUTTON_LEFT;
501 break;
502 case SDLK_KP6:
503 case SDLK_RIGHT:
504 new_btn = BUTTON_RIGHT;
505 break;
506 case SDLK_KP8:
507 case SDLK_UP:
508 new_btn = BUTTON_SCROLL_UP;
509 break;
510 case SDLK_KP2:
511 case SDLK_DOWN:
512 new_btn = BUTTON_SCROLL_DOWN;
513 break;
514 case SDLK_KP_PLUS:
515 case SDLK_F8:
516 new_btn = BUTTON_POWER;
517 break;
518 case SDLK_ESCAPE:
519 new_btn = BUTTON_POWER;
520 break;
521 case SDLK_KP_DIVIDE:
522 case SDLK_F1:
523 new_btn = BUTTON_REW;
524 break;
525 case SDLK_KP_MULTIPLY:
526 case SDLK_F2:
527 new_btn = BUTTON_FF;
528 break;
529 case SDLK_KP5:
530 case SDLK_SPACE:
531 new_btn = BUTTON_PLAY;
532 break;
533
534#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
535 case SDLK_t:
536 if(pressed)
537 switch(_remote_type)
538 {
539 case REMOTETYPE_UNPLUGGED:
540 _remote_type=REMOTETYPE_H100_LCD;
541 DEBUGF("Changed remote type to H100\n");
542 break;
543 case REMOTETYPE_H100_LCD:
544 _remote_type=REMOTETYPE_H300_LCD;
545 DEBUGF("Changed remote type to H300\n");
546 break;
547 case REMOTETYPE_H300_LCD:
548 _remote_type=REMOTETYPE_H300_NONLCD;
549 DEBUGF("Changed remote type to H300 NON-LCD\n");
550 break;
551 case REMOTETYPE_H300_NONLCD:
552 _remote_type=REMOTETYPE_UNPLUGGED;
553 DEBUGF("Changed remote type to none\n");
554 break;
555 }
556 break;
557 case SDLK_KP4:
558 case SDLK_LEFT:
559 new_btn = BUTTON_LEFT;
560 break;
561 case SDLK_KP6:
562 case SDLK_RIGHT:
563 new_btn = BUTTON_RIGHT;
564 break;
565 case SDLK_KP8:
566 case SDLK_UP:
567 new_btn = BUTTON_UP;
568 break;
569 case SDLK_KP2:
570 case SDLK_DOWN:
571 new_btn = BUTTON_DOWN;
572 break;
573 case SDLK_KP_PLUS:
574 case SDLK_F8:
575 new_btn = BUTTON_ON;
576 break;
577 case SDLK_KP_ENTER:
578 case SDLK_RETURN:
579 case SDLK_a:
580 new_btn = BUTTON_OFF;
581 break;
582 case SDLK_KP_DIVIDE:
583 case SDLK_F1:
584 new_btn = BUTTON_REC;
585 break;
586 case SDLK_KP5:
587 case SDLK_SPACE:
588 new_btn = BUTTON_SELECT;
589 break;
590 case SDLK_KP_PERIOD:
591 case SDLK_INSERT:
592 new_btn = BUTTON_MODE;
593 break;
594
595#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
596 case SDLK_KP4:
597 case SDLK_LEFT:
598 new_btn = BUTTON_LEFT;
599 break;
600 case SDLK_KP6:
601 case SDLK_RIGHT:
602 new_btn = BUTTON_RIGHT;
603 break;
604 case SDLK_KP8:
605 case SDLK_UP:
606 new_btn = BUTTON_UP;
607 break;
608 case SDLK_KP2:
609 case SDLK_DOWN:
610 new_btn = BUTTON_DOWN;
611 break;
612 case SDLK_KP_PLUS:
613 case SDLK_F8:
614 new_btn = BUTTON_PLAY;
615 break;
616 case SDLK_KP_ENTER:
617 case SDLK_RETURN:
618 case SDLK_a:
619 new_btn = BUTTON_EQ;
620 break;
621 case SDLK_KP5:
622 case SDLK_SPACE:
623 new_btn = BUTTON_SELECT;
624 break;
625 case SDLK_KP_PERIOD:
626 case SDLK_INSERT:
627 new_btn = BUTTON_MODE;
628 break;
629
630#elif CONFIG_KEYPAD == ONDIO_PAD
631 case SDLK_KP4:
632 case SDLK_LEFT:
633 new_btn = BUTTON_LEFT;
634 break;
635 case SDLK_KP6:
636 case SDLK_RIGHT:
637 new_btn = BUTTON_RIGHT;
638 break;
639 case SDLK_KP8:
640 case SDLK_UP:
641 new_btn = BUTTON_UP;
642 break;
643 case SDLK_KP2:
644 case SDLK_DOWN:
645 new_btn = BUTTON_DOWN;
646 break;
647 case SDLK_KP_ENTER:
648 case SDLK_RETURN:
649 case SDLK_a:
650 new_btn = BUTTON_OFF;
651 break;
652 case SDLK_KP_PERIOD:
653 case SDLK_INSERT:
654 new_btn = BUTTON_MENU;
655 break;
656
657#elif CONFIG_KEYPAD == PLAYER_PAD
658 case SDLK_KP4:
659 case SDLK_LEFT:
660 new_btn = BUTTON_LEFT;
661 break;
662 case SDLK_KP6:
663 case SDLK_RIGHT:
664 new_btn = BUTTON_RIGHT;
665 break;
666 case SDLK_KP8:
667 case SDLK_UP:
668 new_btn = BUTTON_PLAY;
669 break;
670 case SDLK_KP2:
671 case SDLK_DOWN:
672 new_btn = BUTTON_STOP;
673 break;
674 case SDLK_KP_PLUS:
675 case SDLK_F8:
676 new_btn = BUTTON_ON;
677 break;
678 case SDLK_KP_PERIOD:
679 case SDLK_INSERT:
680 new_btn = BUTTON_MENU;
681 break;
682
683#elif CONFIG_KEYPAD == RECORDER_PAD
684 case SDLK_KP4:
685 case SDLK_LEFT:
686 new_btn = BUTTON_LEFT;
687 break;
688 case SDLK_KP6:
689 case SDLK_RIGHT:
690 new_btn = BUTTON_RIGHT;
691 break;
692 case SDLK_KP8:
693 case SDLK_UP:
694 new_btn = BUTTON_UP;
695 break;
696 case SDLK_KP2:
697 case SDLK_DOWN:
698 new_btn = BUTTON_DOWN;
699 break;
700 case SDLK_KP_PLUS:
701 case SDLK_F8:
702 new_btn = BUTTON_ON;
703 break;
704 case SDLK_KP_ENTER:
705 case SDLK_RETURN:
706 case SDLK_a:
707 new_btn = BUTTON_OFF;
708 break;
709 case SDLK_KP_DIVIDE:
710 case SDLK_F1:
711 new_btn = BUTTON_F1;
712 break;
713 case SDLK_KP_MULTIPLY:
714 case SDLK_F2:
715 new_btn = BUTTON_F2;
716 break;
717 case SDLK_KP_MINUS:
718 case SDLK_F3:
719 new_btn = BUTTON_F3;
720 break;
721 case SDLK_KP5:
722 case SDLK_SPACE:
723 new_btn = BUTTON_PLAY;
724 break;
725
726#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
727 case SDLK_KP4:
728 case SDLK_LEFT:
729 new_btn = BUTTON_LEFT;
730 break;
731 case SDLK_KP6:
732 case SDLK_RIGHT:
733 new_btn = BUTTON_RIGHT;
734 break;
735 case SDLK_KP8:
736 case SDLK_UP:
737 new_btn = BUTTON_UP;
738 break;
739 case SDLK_KP2:
740 case SDLK_DOWN:
741 new_btn = BUTTON_DOWN;
742 break;
743 case SDLK_KP_PLUS:
744 case SDLK_F8:
745 new_btn = BUTTON_ON;
746 break;
747 case SDLK_KP_ENTER:
748 case SDLK_RETURN:
749 case SDLK_a:
750 new_btn = BUTTON_OFF;
751 break;
752 case SDLK_KP_DIVIDE:
753 case SDLK_F1:
754 new_btn = BUTTON_F1;
755 break;
756 case SDLK_KP_MULTIPLY:
757 case SDLK_F2:
758 new_btn = BUTTON_F2;
759 break;
760 case SDLK_KP_MINUS:
761 case SDLK_F3:
762 new_btn = BUTTON_F3;
763 break;
764 case SDLK_KP5:
765 case SDLK_SPACE:
766 new_btn = BUTTON_SELECT;
767 break;
768
769#elif CONFIG_KEYPAD == SANSA_E200_PAD
770 case SDLK_KP4:
771 case SDLK_LEFT:
772 new_btn = BUTTON_LEFT;
773 break;
774 case SDLK_KP6:
775 case SDLK_RIGHT:
776 new_btn = BUTTON_RIGHT;
777 break;
778 case SDLK_KP8:
779 case SDLK_UP:
780 new_btn = BUTTON_SCROLL_BACK;
781 break;
782 case SDLK_KP2:
783 case SDLK_DOWN:
784 new_btn = BUTTON_SCROLL_FWD;
785 break;
786 case SDLK_KP9:
787 case SDLK_PAGEUP:
788 new_btn = BUTTON_UP;
789 break;
790 case SDLK_KP3:
791 case SDLK_PAGEDOWN:
792 new_btn = BUTTON_DOWN;
793 break;
794 case SDLK_KP1:
795 case SDLK_HOME:
796 new_btn = BUTTON_POWER;
797 break;
798 case SDLK_KP7:
799 case SDLK_END:
800 new_btn = BUTTON_REC;
801 break;
802 case SDLK_KP5:
803 case SDLK_SPACE:
804 new_btn = BUTTON_SELECT;
805 break;
806
807#elif CONFIG_KEYPAD == SANSA_C200_PAD
808 case SDLK_KP4:
809 case SDLK_LEFT:
810 new_btn = BUTTON_LEFT;
811 break;
812 case SDLK_KP6:
813 case SDLK_RIGHT:
814 new_btn = BUTTON_RIGHT;
815 break;
816 case SDLK_KP8:
817 case SDLK_UP:
818 new_btn = BUTTON_UP;
819 break;
820 case SDLK_KP2:
821 case SDLK_DOWN:
822 new_btn = BUTTON_DOWN;
823 break;
824 case SDLK_KP3:
825 new_btn = BUTTON_POWER;
826 break;
827 case SDLK_KP1:
828 new_btn = BUTTON_REC;
829 break;
830 case SDLK_KP5:
831 case SDLK_KP_ENTER:
832 case SDLK_RETURN:
833 new_btn = BUTTON_SELECT;
834 break;
835 case SDLK_KP7:
836 new_btn = BUTTON_VOL_DOWN;
837 break;
838 case SDLK_KP9:
839 new_btn = BUTTON_VOL_UP;
840 break;
841
842#elif CONFIG_KEYPAD == MROBE500_PAD
843 case SDLK_F9:
844 new_btn = BUTTON_RC_HEART;
845 break;
846 case SDLK_F10:
847 new_btn = BUTTON_RC_MODE;
848 break;
849 case SDLK_F11:
850 new_btn = BUTTON_RC_VOL_DOWN;
851 break;
852 case SDLK_F12:
853 new_btn = BUTTON_RC_VOL_UP;
854 break;
855 case SDLK_MINUS:
856 case SDLK_LESS:
857 case SDLK_LEFTBRACKET:
858 case SDLK_KP_DIVIDE:
859 new_btn = BUTTON_LEFT;
860 break;
861 case SDLK_PLUS:
862 case SDLK_GREATER:
863 case SDLK_RIGHTBRACKET:
864 case SDLK_KP_MULTIPLY:
865 new_btn = BUTTON_RIGHT;
866 break;
867 case SDLK_PAGEUP:
868 new_btn = BUTTON_RC_PLAY;
869 break;
870 case SDLK_PAGEDOWN:
871 new_btn = BUTTON_RC_DOWN;
872 break;
873 case SDLK_F8:
874 case SDLK_ESCAPE:
875 new_btn = BUTTON_POWER;
876 break;
877#elif CONFIG_KEYPAD == MROBE100_PAD
878 case SDLK_F9:
879 new_btn = BUTTON_RC_HEART;
880 break;
881 case SDLK_F10:
882 new_btn = BUTTON_RC_MODE;
883 break;
884 case SDLK_F11:
885 new_btn = BUTTON_RC_VOL_DOWN;
886 break;
887 case SDLK_F12:
888 new_btn = BUTTON_RC_VOL_UP;
889 break;
890 case SDLK_LEFT:
891 new_btn = BUTTON_RC_FF;
892 break;
893 case SDLK_RIGHT:
894 new_btn = BUTTON_RC_REW;
895 break;
896 case SDLK_UP:
897 new_btn = BUTTON_RC_PLAY;
898 break;
899 case SDLK_DOWN:
900 new_btn = BUTTON_RC_DOWN;
901 break;
902 case SDLK_KP1:
903 new_btn = BUTTON_DISPLAY;
904 break;
905 case SDLK_KP7:
906 new_btn = BUTTON_MENU;
907 break;
908 case SDLK_KP9:
909 new_btn = BUTTON_PLAY;
910 break;
911 case SDLK_KP4:
912 new_btn = BUTTON_LEFT;
913 break;
914 case SDLK_KP6:
915 new_btn = BUTTON_RIGHT;
916 break;
917 case SDLK_KP8:
918 new_btn = BUTTON_UP;
919 break;
920 case SDLK_KP2:
921 new_btn = BUTTON_DOWN;
922 break;
923 case SDLK_KP5:
924 case SDLK_SPACE:
925 new_btn = BUTTON_SELECT;
926 break;
927 case SDLK_KP_MULTIPLY:
928 case SDLK_F8:
929 case SDLK_ESCAPE:
930 new_btn = BUTTON_POWER;
931 break;
932
933#elif CONFIG_KEYPAD == COWON_D2_PAD
934 case SDLK_KP_MULTIPLY:
935 case SDLK_F8:
936 case SDLK_ESCAPE:
937 case SDLK_BACKSPACE:
938 case SDLK_DELETE:
939 new_btn = BUTTON_POWER;
940 break;
941 case SDLK_KP_PLUS:
942 case SDLK_EQUALS:
943 new_btn = BUTTON_PLUS;
944 break;
945 case SDLK_KP_MINUS:
946 case SDLK_MINUS:
947 new_btn = BUTTON_MINUS;
948 break;
949 case SDLK_KP_ENTER:
950 case SDLK_RETURN:
951 case SDLK_SPACE:
952 case SDLK_INSERT:
953 new_btn = BUTTON_MENU;
954 break;
955#elif CONFIG_KEYPAD == IAUDIO67_PAD
956 case SDLK_UP:
957 new_btn = BUTTON_RIGHT;
958 break;
959 case SDLK_DOWN:
960 new_btn = BUTTON_LEFT;
961 break;
962 case SDLK_LEFT:
963 new_btn = BUTTON_STOP;
964 break;
965 case SDLK_RETURN:
966 case SDLK_KP_ENTER:
967 case SDLK_RIGHT:
968 new_btn = BUTTON_PLAY;
969 break;
970 case SDLK_PLUS:
971 new_btn = BUTTON_VOLUP;
972 break;
973 case SDLK_MINUS:
974 new_btn = BUTTON_VOLDOWN;
975 break;
976 case SDLK_SPACE:
977 new_btn = BUTTON_MENU;
978 break;
979 case SDLK_BACKSPACE:
980 new_btn = BUTTON_POWER;
981 break;
982#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
983 case SDLK_KP1:
984 new_btn = BUTTON_BACK;
985 break;
986 case SDLK_KP3:
987 new_btn = BUTTON_MENU;
988 break;
989 case SDLK_KP7:
990 new_btn = BUTTON_CUSTOM;
991 break;
992 case SDLK_KP9:
993 new_btn = BUTTON_PLAY;
994 break;
995 case SDLK_KP4:
996 case SDLK_LEFT:
997 new_btn = BUTTON_LEFT;
998 break;
999 case SDLK_KP6:
1000 case SDLK_RIGHT:
1001 new_btn = BUTTON_RIGHT;
1002 break;
1003 case SDLK_KP8:
1004 case SDLK_UP:
1005 new_btn = BUTTON_UP;
1006 break;
1007 case SDLK_KP2:
1008 case SDLK_DOWN:
1009 new_btn = BUTTON_DOWN;
1010 break;
1011 case SDLK_KP5:
1012 case SDLK_SPACE:
1013 new_btn = BUTTON_SELECT;
1014 break;
1015 case SDLK_KP_MULTIPLY:
1016 case SDLK_F8:
1017 case SDLK_ESCAPE:
1018 new_btn = BUTTON_POWER;
1019 break;
1020#elif CONFIG_KEYPAD == CREATIVEZV_PAD
1021 case SDLK_KP1:
1022 new_btn = BUTTON_PREV;
1023 break;
1024 case SDLK_KP3:
1025 new_btn = BUTTON_NEXT;
1026 break;
1027 case SDLK_KP7:
1028 new_btn = BUTTON_BACK;
1029 break;
1030 case SDLK_p:
1031 new_btn = BUTTON_PLAY;
1032 break;
1033 case SDLK_KP9:
1034 new_btn = BUTTON_MENU;
1035 break;
1036 case SDLK_KP4:
1037 case SDLK_LEFT:
1038 new_btn = BUTTON_LEFT;
1039 break;
1040 case SDLK_KP6:
1041 case SDLK_RIGHT:
1042 new_btn = BUTTON_RIGHT;
1043 break;
1044 case SDLK_KP8:
1045 case SDLK_UP:
1046 new_btn = BUTTON_UP;
1047 break;
1048 case SDLK_KP2:
1049 case SDLK_DOWN:
1050 new_btn = BUTTON_DOWN;
1051 break;
1052 case SDLK_KP5:
1053 case SDLK_SPACE:
1054 new_btn = BUTTON_SELECT;
1055 break;
1056 case SDLK_KP_MULTIPLY:
1057 case SDLK_F8:
1058 case SDLK_ESCAPE:
1059 new_btn = BUTTON_POWER;
1060 break;
1061 case SDLK_z:
1062 new_btn = BUTTON_VOL_DOWN;
1063 break;
1064 case SDLK_s:
1065 new_btn = BUTTON_VOL_UP;
1066
1067#elif CONFIG_KEYPAD == MEIZU_M6SL_PAD
1068 case SDLK_KP1:
1069 new_btn = BUTTON_PREV;
1070 break;
1071 case SDLK_KP3:
1072 new_btn = BUTTON_NEXT;
1073 break;
1074 case SDLK_KP_ENTER:
1075 case SDLK_RETURN:
1076 case SDLK_a:
1077 new_btn = BUTTON_PLAY;
1078 break;
1079 case SDLK_KP_PERIOD:
1080 case SDLK_INSERT:
1081 new_btn = BUTTON_MENU;
1082 break;
1083 case SDLK_KP8:
1084 case SDLK_UP:
1085 new_btn = BUTTON_UP;
1086 break;
1087 case SDLK_KP2:
1088 case SDLK_DOWN:
1089 new_btn = BUTTON_DOWN;
1090 break;
1091 case SDLK_KP5:
1092 case SDLK_SPACE:
1093 new_btn = BUTTON_SELECT;
1094 break;
1095#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
1096 case SDLK_KP4:
1097 case SDLK_LEFT:
1098 new_btn = BUTTON_LEFT;
1099 break;
1100 case SDLK_KP6:
1101 case SDLK_RIGHT:
1102 new_btn = BUTTON_RIGHT;
1103 break;
1104 case SDLK_KP8:
1105 case SDLK_UP:
1106 new_btn = BUTTON_SCROLL_BACK;
1107 break;
1108 case SDLK_KP2:
1109 case SDLK_DOWN:
1110 new_btn = BUTTON_SCROLL_FWD;
1111 break;
1112 case SDLK_PAGEUP:
1113 case SDLK_KP9:
1114 new_btn = BUTTON_UP;
1115 break;
1116 case SDLK_PAGEDOWN:
1117 case SDLK_KP3:
1118 new_btn = BUTTON_DOWN;
1119 break;
1120 case SDLK_KP_MINUS:
1121 case SDLK_KP1:
1122 new_btn = BUTTON_POWER;
1123 break;
1124 case SDLK_KP_MULTIPLY:
1125 new_btn = BUTTON_HOME;
1126 break;
1127 case SDLK_KP5:
1128 case SDLK_SPACE:
1129 case SDLK_KP_ENTER:
1130 case SDLK_RETURN:
1131 new_btn = BUTTON_SELECT;
1132 break;
1133#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
1134 case SDLK_KP4:
1135 case SDLK_LEFT:
1136 new_btn = BUTTON_LEFT;
1137 break;
1138 case SDLK_KP6:
1139 case SDLK_RIGHT:
1140 new_btn = BUTTON_RIGHT;
1141 break;
1142 case SDLK_KP8:
1143 case SDLK_UP:
1144 new_btn = BUTTON_UP;
1145 break;
1146 case SDLK_KP2:
1147 case SDLK_DOWN:
1148 new_btn = BUTTON_DOWN;
1149 break;
1150
1151 case SDLK_INSERT:
1152 case SDLK_KP_MULTIPLY:
1153 new_btn = BUTTON_HOME;
1154 break;
1155 case SDLK_SPACE:
1156 case SDLK_KP5:
1157 new_btn = BUTTON_SELECT;
1158 break;
1159 case SDLK_PAGEDOWN:
1160 case SDLK_KP3:
1161 new_btn = BUTTON_VOL_DOWN;
1162 break;
1163 case SDLK_PAGEUP:
1164 case SDLK_KP9:
1165 new_btn = BUTTON_VOL_UP;
1166 break;
1167 case SDLK_ESCAPE:
1168 case SDLK_KP1:
1169 new_btn = BUTTON_POWER;
1170 break;
1171#elif CONFIG_KEYPAD == SANSA_M200_PAD
1172 case SDLK_KP4:
1173 case SDLK_LEFT:
1174 new_btn = BUTTON_LEFT;
1175 break;
1176 case SDLK_KP6:
1177 case SDLK_RIGHT:
1178 new_btn = BUTTON_RIGHT;
1179 break;
1180 case SDLK_KP8:
1181 case SDLK_UP:
1182 new_btn = BUTTON_UP;
1183 break;
1184 case SDLK_KP2:
1185 case SDLK_DOWN:
1186 new_btn = BUTTON_DOWN;
1187 break;
1188 case SDLK_PLUS:
1189 new_btn = BUTTON_POWER;
1190 break;
1191 case SDLK_KP5:
1192 new_btn = BUTTON_SELECT;
1193 break;
1194 case SDLK_KP7:
1195 new_btn = BUTTON_VOL_DOWN;
1196 break;
1197 case SDLK_KP9:
1198 new_btn = BUTTON_VOL_UP;
1199 break;
1200#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
1201 case SDLK_KP4:
1202 case SDLK_LEFT:
1203 new_btn = BUTTON_LEFT;
1204 break;
1205 case SDLK_KP6:
1206 case SDLK_RIGHT:
1207 new_btn = BUTTON_RIGHT;
1208 break;
1209 case SDLK_KP8:
1210 case SDLK_UP:
1211 new_btn = BUTTON_UP;
1212 break;
1213 case SDLK_KP2:
1214 case SDLK_DOWN:
1215 new_btn = BUTTON_DOWN;
1216 break;
1217 case SDLK_KP1:
1218 new_btn = BUTTON_MENU;
1219 break;
1220 case SDLK_KP5:
1221 case SDLK_SPACE:
1222 new_btn = BUTTON_PLAY;
1223 break;
1224 case SDLK_KP7:
1225 new_btn = BUTTON_PREV;
1226 break;
1227 case SDLK_KP9:
1228 new_btn = BUTTON_NEXT;
1229 break;
1230 case SDLK_KP_ENTER:
1231 case SDLK_RETURN:
1232 new_btn = BUTTON_POWER;
1233 break;
1234 case SDLK_PAGEUP:
1235 new_btn = BUTTON_VOL_UP;
1236 break;
1237 case SDLK_PAGEDOWN:
1238 new_btn = BUTTON_VOL_DOWN;
1239 break;
1240#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
1241 case SDLK_KP4:
1242 case SDLK_LEFT:
1243 new_btn = BUTTON_LEFT;
1244 break;
1245 case SDLK_KP6:
1246 case SDLK_RIGHT:
1247 new_btn = BUTTON_RIGHT;
1248 break;
1249 case SDLK_KP8:
1250 case SDLK_UP:
1251 new_btn = BUTTON_UP;
1252 break;
1253 case SDLK_KP2:
1254 case SDLK_DOWN:
1255 new_btn = BUTTON_DOWN;
1256 break;
1257 case SDLK_KP5:
1258 case SDLK_SPACE:
1259 new_btn = BUTTON_SELECT;
1260 break;
1261 case SDLK_KP7:
1262 case SDLK_ESCAPE:
1263 new_btn = BUTTON_POWER;
1264 break;
1265 case SDLK_KP1:
1266 new_btn = BUTTON_PLAYLIST;
1267 break;
1268 case SDLK_KP9:
1269 new_btn = BUTTON_VOL_UP;
1270 break;
1271 case SDLK_KP3:
1272 new_btn = BUTTON_VOL_DOWN;
1273 break;
1274 case SDLK_KP_MINUS:
1275 new_btn = BUTTON_MENU;
1276 break;
1277 case SDLK_KP_PLUS:
1278 new_btn = BUTTON_VIEW;
1279 break;
1280#elif CONFIG_KEYPAD == ONDAVX747_PAD
1281 case SDLK_ESCAPE:
1282 new_btn = BUTTON_POWER;
1283 break;
1284 case SDLK_KP_PLUS:
1285 case SDLK_PLUS:
1286 case SDLK_GREATER:
1287 case SDLK_RIGHTBRACKET:
1288 case SDLK_KP_MULTIPLY:
1289 new_btn = BUTTON_VOL_UP;
1290 break;
1291 case SDLK_KP_MINUS:
1292 case SDLK_MINUS:
1293 case SDLK_LESS:
1294 case SDLK_LEFTBRACKET:
1295 case SDLK_KP_DIVIDE:
1296 new_btn = BUTTON_VOL_DOWN;
1297 break;
1298 case SDLK_KP_ENTER:
1299 case SDLK_RETURN:
1300 new_btn = BUTTON_MENU;
1301 break;
1302#elif CONFIG_KEYPAD == ONDAVX777_PAD
1303 case SDLK_ESCAPE:
1304 new_btn = BUTTON_POWER;
1305 break;
1306#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
1307 case SDLK_KP4:
1308 case SDLK_LEFT:
1309 new_btn = BUTTON_LEFT;
1310 break;
1311 case SDLK_KP6:
1312 case SDLK_RIGHT:
1313 new_btn = BUTTON_RIGHT;
1314 break;
1315 case SDLK_KP8:
1316 case SDLK_UP:
1317 new_btn = BUTTON_UP;
1318 break;
1319 case SDLK_KP2:
1320 case SDLK_DOWN:
1321 new_btn = BUTTON_DOWN;
1322 break;
1323 case SDLK_KP5:
1324 case SDLK_KP_ENTER:
1325 new_btn = BUTTON_PLAY;
1326 break;
1327 case SDLK_KP9:
1328 case SDLK_PAGEUP:
1329 new_btn = BUTTON_FFWD;
1330 break;
1331#ifdef SAMSUNG_YH820
1332 case SDLK_KP7:
1333#else
1334 case SDLK_KP3:
1335#endif
1336 case SDLK_PAGEDOWN:
1337 new_btn = BUTTON_REW;
1338 break;
1339 case SDLK_KP_PLUS:
1340 new_btn = BUTTON_REC;
1341 break;
1342#elif CONFIG_KEYPAD == MINI2440_PAD
1343 case SDLK_LEFT:
1344 new_btn = BUTTON_LEFT;
1345 break;
1346 case SDLK_RIGHT:
1347 new_btn = BUTTON_RIGHT;
1348 break;
1349 case SDLK_UP:
1350 new_btn = BUTTON_UP;
1351 break;
1352 case SDLK_DOWN:
1353 new_btn = BUTTON_DOWN;
1354 break;
1355 case SDLK_F8:
1356 case SDLK_ESCAPE:
1357 new_btn = BUTTON_POWER;
1358 break;
1359 case SDLK_KP_ENTER:
1360 case SDLK_RETURN:
1361 case SDLK_a:
1362 new_btn = BUTTON_A;
1363 break;
1364 case SDLK_SPACE:
1365 new_btn = BUTTON_SELECT;
1366 break;
1367 case SDLK_KP_PERIOD:
1368 case SDLK_INSERT:
1369 new_btn = BUTTON_MENU;
1370 break;
1371 case SDLK_KP_PLUS:
1372 new_btn = BUTTON_VOL_UP;
1373 break;
1374 case SDLK_KP_MINUS:
1375 new_btn = BUTTON_VOL_DOWN;
1376 break;
1377#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
1378 case SDLK_KP4:
1379 case SDLK_LEFT:
1380 new_btn = BUTTON_PREV;
1381 break;
1382 case SDLK_KP6:
1383 case SDLK_RIGHT:
1384 new_btn = BUTTON_NEXT;
1385 break;
1386 case SDLK_KP8:
1387 case SDLK_UP:
1388 new_btn = BUTTON_UP;
1389 break;
1390 case SDLK_KP2:
1391 case SDLK_DOWN:
1392 new_btn = BUTTON_DOWN;
1393 break;
1394 case SDLK_KP7:
1395 new_btn = BUTTON_MENU;
1396 break;
1397 case SDLK_KP9:
1398 new_btn = BUTTON_PLAY;
1399 break;
1400 case SDLK_KP5:
1401 new_btn = BUTTON_OK;
1402 break;
1403 case SDLK_KP_DIVIDE:
1404 new_btn = BUTTON_CANCEL;
1405 break;
1406 case SDLK_KP_PLUS:
1407 new_btn = BUTTON_POWER;
1408 break;
1409 case SDLK_KP_MULTIPLY:
1410 new_btn = BUTTON_REC;
1411 break;
1412
1413#elif CONFIG_KEYPAD == MPIO_HD200_PAD
1414 case SDLK_UP:
1415 new_btn = BUTTON_PREV;
1416 break;
1417 case SDLK_DOWN:
1418 new_btn = BUTTON_NEXT;
1419 break;
1420 case SDLK_SPACE:
1421 new_btn = BUTTON_SELECT;
1422 break;
1423 case SDLK_RETURN:
1424 new_btn = BUTTON_PLAY;
1425 break;
1426 case SDLK_LEFT:
1427 new_btn = BUTTON_VOL_DOWN;
1428 break;
1429 case SDLK_RIGHT:
1430 new_btn = BUTTON_VOL_UP;
1431 break;
1432 case SDLK_ESCAPE:
1433 new_btn = BUTTON_REC;
1434 break;
1435
1436#else
1437#error No keymap defined!
1438#endif /* CONFIG_KEYPAD */
1439 case SDLK_KP0:
1440 case SDLK_F5:
1441 if(pressed)
1442 {
1443 sim_trigger_screendump();
1444 return;
1445 }
1446 break;
1447 }
1448
1449 /* Call to make up for scrollwheel target implementation. This is
1450 * not handled in the main button.c driver, but on the target
1451 * implementation (look at button-e200.c for example if you are trying to
1452 * figure out why using button_get_data needed a hack before).
1453 */
1454#if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK)
1455 if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) &&
1456 pressed)
1457 {
1458 /* Clear these buttons from the data - adding them to the queue is
1459 * handled in the scrollwheel drivers for the targets. They do not
1460 * store the scroll forward/back buttons in their button data for
1461 * the button_read call.
1462 */
1463#ifdef HAVE_BACKLIGHT
1464 backlight_on();
1465#endif
1466#ifdef HAVE_BUTTON_LIGHT
1467 buttonlight_on();
1468#endif
1469 queue_post(&button_queue, new_btn, 1<<24);
1470 new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK);
1471 }
1472#endif
1473
1474 if (pressed)
1475 btn |= new_btn;
1476 else
1477 btn &= ~new_btn;
1478}
1479#if defined(HAVE_BUTTON_DATA) && defined(HAVE_TOUCHSCREEN)
1480int button_read_device(int* data)
1481{
1482 *data = mouse_coords;
1483#else
1484int button_read_device(void)
1485{
1486#endif
1487#ifdef HAS_BUTTON_HOLD
1488 int hold_button = button_hold();
1489
1490#ifdef HAVE_BACKLIGHT
1491 /* light handling */
1492 static int hold_button_old = false;
1493 if (hold_button != hold_button_old)
1494 {
1495 hold_button_old = hold_button;
1496 backlight_hold_changed(hold_button);
1497 }
1498#endif
1499
1500 if (hold_button)
1501 return BUTTON_NONE;
1502 else
1503#endif
1504 gui_message_loop();
1505
1506 return btn;
1507}
1508
1509
1510#ifdef HAVE_TOUCHSCREEN
1511extern bool debug_wps;
1512void mouse_tick_task(void)
1513{
1514 static int last_check = 0;
1515 int x,y;
1516 if (TIME_BEFORE(current_tick, last_check+(HZ/10)))
1517 return;
1518 last_check = current_tick;
1519 if (SDL_GetMouseState(&x, &y) & SDL_BUTTON(SDL_BUTTON_LEFT))
1520 {
1521 if(background)
1522 {
1523 x -= UI_LCD_POSX;
1524 y -= UI_LCD_POSY;
1525
1526 if(x<0 || y<0 || x>SIM_LCD_WIDTH || y>SIM_LCD_HEIGHT)
1527 return;
1528 }
1529
1530 mouse_coords = (x<<16)|y;
1531 button_event(BUTTON_TOUCHSCREEN, true);
1532 if (debug_wps)
1533 printf("Mouse at: (%d, %d)\n", x, y);
1534 }
1535}
1536#endif
1537
1538void button_init_device(void)
1539{
1540 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
1541#ifdef HAVE_TOUCHSCREEN
1542 tick_add_task(mouse_tick_task);
1543#endif
1544}
1545
1546/* Button maps: simulated key, x, y, radius, name */
1547/* Run sim with --mapping to get coordinates */
1548/* or --debugbuttons to check */
1549/* The First matching button is returned */
1550struct button_map {
1551 int button, x, y, radius;
1552 char *description;
1553};
1554
1555#ifdef SANSA_FUZE
1556struct button_map bm[] = {
1557 { SDLK_KP8, 70, 265, 35, "Scroll Back" },
1558 { SDLK_KP9, 141, 255, 31, "Play" },
1559 { SDLK_KP_MULTIPLY, 228, 267, 18, "Home" },
1560 { SDLK_LEFT, 69, 329, 31, "Left" },
1561 { SDLK_SPACE, 141, 330, 20, "Select" },
1562 { SDLK_RIGHT, 214, 331, 23, "Right" },
1563 { SDLK_KP3, 142, 406, 30, "Menu" },
1564 { SDLK_DOWN, 221, 384, 24, "Scroll Fwd" },
1565 { SDLK_KP_MINUS, 270, 299, 25, "Power" },
1566 { SDLK_h, 269, 358, 26, "Hold" },
1567 { 0, 0, 0, 0, "None" }
1568};
1569#elif defined (SANSA_CLIP)
1570struct button_map bm[] = {
1571 { SDLK_KP_MULTIPLY, 165, 158, 17, "Home" },
1572 { SDLK_KP5, 102, 230, 29, "Select" },
1573 { SDLK_KP8, 100, 179, 25, "Play" },
1574 { SDLK_KP4, 53, 231, 21, "Left" },
1575 { SDLK_KP6, 147, 232, 19, "Right" },
1576 { SDLK_KP2, 105, 275, 22, "Menu" },
1577 { 0, 0, 0, 0, "None" }
1578};
1579#elif defined (SANSA_C200) || defined(SANSA_C200V2)
1580struct button_map bm[] = {
1581
1582 { SDLK_KP7, 84, 7, 21, "Vol Down" },
1583 { SDLK_KP9, 158, 7, 20, "Vol Up" },
1584 { SDLK_KP1, 173, 130, 27, "Record" },
1585 { SDLK_KP5, 277, 75, 21, "Select" },
1586 { SDLK_KP4, 233, 75, 24, "Left" },
1587 { SDLK_KP6, 313, 74, 18, "Right" },
1588 { SDLK_KP8, 276, 34, 15, "Play" },
1589 { SDLK_KP2, 277, 119, 17, "Down" },
1590 { SDLK_KP3, 314, 113, 19, "Menu" },
1591 { 0, 0, 0, 0, "None" }
1592};
1593#elif defined (SANSA_E200V2) || defined(SANSA_E200)
1594struct button_map bm[] = {
1595 { SDLK_KP7, 5, 92, 18, "Record" },
1596 { SDLK_KP9, 128, 295, 43, "Play" },
1597 { SDLK_KP4, 42, 380, 33, "Left" },
1598 { SDLK_KP5, 129, 378, 36, "Select" },
1599 { SDLK_KP6, 218, 383, 30, "Right" },
1600 { SDLK_KP3, 129, 461, 29, "Down" },
1601 { SDLK_KP1, 55, 464, 20, "Menu" },
1602 { SDLK_KP8, 92, 338, 17, "Scroll Back" },
1603 { SDLK_KP2, 167, 342, 17, "Scroll Fwd" },
1604 { 0, 0, 0, 0, "None" }
1605};
1606#elif defined (SANSA_M200V4)
1607struct button_map bm[] = {
1608 { SDLK_KP_PLUS, 54, 14, 16, "Power" },
1609 { SDLK_KP7, 96, 13, 12, "Vol Down" },
1610 { SDLK_KP9, 139, 14, 14, "Vol Up" },
1611 { SDLK_KP5, 260, 82, 20, "Select" },
1612 { SDLK_KP8, 258, 35, 30, "Play" },
1613 { SDLK_KP4, 214, 84, 25, "Left" },
1614 { SDLK_KP6, 300, 83, 24, "Right" },
1615 { SDLK_KP2, 262, 125, 28, "Repeat" },
1616 { SDLK_h, 113, 151, 21, "Hold" },
1617 { 0, 0, 0, 0, "None" }
1618};
1619#elif defined (IPOD_VIDEO)
1620struct button_map bm[] = {
1621 { SDLK_KP_PERIOD, 174, 350, 35, "Menu" },
1622 { SDLK_KP8, 110, 380, 33, "Scroll Back" },
1623 { SDLK_KP2, 234, 377, 34, "Scroll Fwd" },
1624 { SDLK_KP4, 78, 438, 47, "Left" },
1625 { SDLK_KP5, 172, 435, 43, "Select" },
1626 { SDLK_KP6, 262, 438, 52, "Right" },
1627 { SDLK_KP_PLUS, 172, 519, 43, "Play" },
1628 { 0, 0, 0 , 0, "None" }
1629};
1630#elif defined (IPOD_MINI) || defined(IPOD_MINI2G)
1631struct button_map bm[] = {
1632 { SDLK_KP5, 92, 267, 29, "Select" },
1633 { SDLK_KP4, 31, 263, 37, "Left" },
1634 { SDLK_KP6, 150, 268, 33, "Right" },
1635 { SDLK_KP_PERIOD, 93, 209, 30, "Menu" },
1636 { SDLK_KP_PLUS, 93, 324, 25, "Play" },
1637 { SDLK_KP8, 53, 220, 29, "Scroll Back" },
1638 { SDLK_KP2, 134, 219, 31, "Scroll Fwd" },
1639 { 0, 0, 0 , 0, "None" }
1640};
1641#elif defined (IPOD_3G)
1642struct button_map bm[] = {
1643 { SDLK_KP5, 108, 296, 26, "Select" },
1644 { SDLK_KP8, 70, 255, 26, "Scroll Back" },
1645 { SDLK_KP2, 149, 256, 28, "Scroll Fwd" },
1646 { SDLK_KP4, 27, 186, 22, "Left" },
1647 { SDLK_KP_PERIOD, 82, 185, 22, "Menu" },
1648 { SDLK_KP_PERIOD, 133, 185, 21, "Play" },
1649 { SDLK_KP6, 189, 188, 21, "Right" },
1650 { 0, 0, 0 , 0, "None" }
1651};
1652#elif defined (IPOD_4G)
1653struct button_map bm[] = {
1654 { SDLK_KP5, 96, 269, 27, "Select" },
1655 { SDLK_KP4, 39, 267, 30, "Left" },
1656 { SDLK_KP6, 153, 270, 27, "Right" },
1657 { SDLK_KP_PERIOD, 96, 219, 30, "Menu" },
1658 { SDLK_KP_PLUS, 95, 326, 27, "Play" },
1659 { SDLK_KP8, 57, 233, 29, "Scroll Back" },
1660 { SDLK_KP2, 132, 226, 29, "Scroll Fwd" },
1661 { 0, 0, 0 , 0, "None" }
1662};
1663#elif defined (IPOD_COLOR)
1664struct button_map bm[] = {
1665 { SDLK_KP5, 128, 362, 35, "Select" },
1666 { SDLK_KP4, 55, 358, 38, "Left" },
1667 { SDLK_KP6, 203, 359, 39, "Right" },
1668 { SDLK_KP_PERIOD, 128, 282, 34, "Menu" },
1669 { SDLK_KP_PLUS, 129, 439, 41, "Play" },
1670 { SDLK_KP8, 76, 309, 34, "Scroll Back" },
1671 { SDLK_KP2, 182, 311, 45, "Scroll Fwd" },
1672 { 0, 0, 0 , 0, "None" }
1673};
1674#elif defined (IPOD_1G2G)
1675struct button_map bm[] = {
1676 { SDLK_KP5, 112, 265, 31, "Select" },
1677 { SDLK_KP8, 74, 224, 28, "Scroll Back" },
1678 { SDLK_KP2, 146, 228, 28, "Scroll Fwd" },
1679 /* Dummy button to make crescent shape */
1680 { SDLK_y, 112, 265, 76, "None" },
1681 { SDLK_KP8, 74, 224, 28, "Scroll Back" },
1682 { SDLK_KP2, 146, 228, 28, "Scroll Fwd" },
1683 { SDLK_KP6, 159, 268, 64, "Right" },
1684 { SDLK_KP4, 62, 266, 62, "Left" },
1685 { SDLK_KP_PERIOD, 111, 216, 64, "Menu" },
1686 { SDLK_KP_PLUS, 111, 326, 55, "Down" },
1687 { 0, 0, 0 , 0, "None" }
1688};
1689#elif defined (IPOD_NANO)
1690struct button_map bm[] = {
1691 { SDLK_KP5, 98, 316, 37, "Select" },
1692 { SDLK_KP4, 37, 312, 28, "Left" },
1693 { SDLK_KP6, 160, 313, 25, "Right" },
1694 { SDLK_KP_PERIOD,102, 256, 23, "Menu" },
1695 { SDLK_KP_PLUS, 99, 378, 28, "Play" },
1696 { SDLK_KP8, 58, 272, 24, "Scroll Back" },
1697 { SDLK_KP2, 141, 274, 22, "Scroll Fwd" },
1698 { 0, 0, 0 , 0, "None" }
1699};
1700#elif defined (IPOD_NANO2G)
1701struct button_map bm[] = {
1702 { SDLK_KP5, 118, 346, 37, "Select" },
1703 { SDLK_KP4, 51, 345, 28, "Left" },
1704 { SDLK_KP6, 180, 346, 26, "Right" },
1705 { SDLK_KP_PERIOD, 114, 286, 23, "Menu" },
1706 { SDLK_KP_PLUS, 115, 412, 27, "Down" },
1707 { SDLK_KP8, 67, 303, 28, "Scroll Back" },
1708 { SDLK_KP2, 163, 303, 27, "Scroll Fwd" },
1709 { 0, 0, 0 , 0, "None" }
1710};
1711#elif defined (COWON_D2)
1712struct button_map bm[] = {
1713 { SDLK_DELETE, 51, 14, 17, "Power" },
1714 { SDLK_h, 138, 14, 16, "Hold" },
1715 { SDLK_MINUS, 320, 14, 10, "Minus" },
1716 { SDLK_INSERT, 347, 13, 13, "Menu" },
1717 { SDLK_KP_PLUS, 374, 14, 12, "Plus" },
1718 { 0, 0, 0, 0, "None" }
1719};
1720#elif defined (IAUDIO_M3)
1721struct button_map bm[] = {
1722 { SDLK_KP5, 256, 72, 29, "Play" },
1723 { SDLK_KP6, 255, 137, 28, "Right" },
1724 { SDLK_KP4, 257, 201, 26, "Left" },
1725 { SDLK_KP8, 338, 31, 27, "Up" },
1726 { SDLK_KP2, 339, 92, 23, "Down" },
1727 { SDLK_KP_PERIOD, 336, 50, 23, "Mode" },
1728 { SDLK_KP_DIVIDE, 336, 147, 23, "Rec" },
1729 { SDLK_h, 336, 212, 30, "Hold" },
1730 /* remote */
1731 { SDLK_SPACE, 115, 308, 20, "RC Play" },
1732 { SDLK_RIGHT, 85, 308, 20, "RC Rew" },
1733 { SDLK_LEFT, 143, 308, 20, "RC FF" },
1734 { SDLK_UP, 143, 498, 20, "RC Up" },
1735 { SDLK_DOWN, 85, 498, 20, "RC Down" },
1736 { SDLK_INSERT, 212, 308, 30, "RC Mode" },
1737 { SDLK_F1, 275, 308, 25, "RC Rec" },
1738 { SDLK_KP_ENTER, 115, 498, 20, "RC Menu" },
1739 { 0, 0, 0, 0, "None" }
1740};
1741#elif defined (IAUDIO_M5)
1742struct button_map bm[] = {
1743 { SDLK_KP_ENTER, 333, 41, 17, "Enter" },
1744 { SDLK_h, 334, 74, 21, "Hold" },
1745 { SDLK_KP_DIVIDE, 333, 142, 24, "Record" },
1746 { SDLK_KP_PLUS, 332, 213, 20, "Play" },
1747 { SDLK_KP5, 250, 291, 19, "Select" },
1748 { SDLK_KP8, 249, 236, 32, "Up" },
1749 { SDLK_KP4, 194, 292, 29, "Left" },
1750 { SDLK_KP6, 297, 290, 27, "Right" },
1751 { SDLK_KP2, 252, 335, 28, "Down" },
1752 { 0, 0, 0, 0, "None" }
1753};
1754#elif defined (IAUDIO_7)
1755struct button_map bm[] = {
1756 { 0, 0, 0, 0, "None" }
1757};
1758#elif defined (IAUDIO_X5)
1759struct button_map bm[] = {
1760 { SDLK_KP_ENTER, 275, 38, 17, "Power" },
1761 { SDLK_h, 274, 83, 16, "Hold" },
1762 { SDLK_KP_DIVIDE, 276, 128, 22, "Record" },
1763 { SDLK_KP_PLUS, 274, 186, 22, "Play" },
1764 { SDLK_KP5, 200, 247, 16, "Select" },
1765 { SDLK_KP8, 200, 206, 16, "Up" },
1766 { SDLK_KP4, 163, 248, 19, "Left" },
1767 { SDLK_KP6, 225, 247, 24, "Right" },
1768 { SDLK_KP2, 199, 279, 20, "Down" },
1769 { 0, 0, 0, 0, "None" }
1770};
1771#elif defined (ARCHOS_PLAYER)
1772struct button_map bm[] = {
1773 { SDLK_KP_PLUS, 79, 252, 23, "On" },
1774 { SDLK_KP_PERIOD, 81, 310, 20, "Menu" },
1775 { SDLK_KP8, 154, 237, 28, "Play" },
1776 { SDLK_KP4, 121, 282, 23, "Left" },
1777 { SDLK_KP6, 187, 282, 22, "Right" },
1778 { SDLK_KP2, 157, 312, 20, "Down" },
1779 { 0, 0, 0, 0, "None" }
1780};
1781#elif defined (ARCHOS_RECORDER)
1782struct button_map bm[] = {
1783 { SDLK_F1, 94, 205, 22, "F1" },
1784 { SDLK_F2, 136, 204, 21, "F2" },
1785 { SDLK_F3, 174, 204, 24, "F3" },
1786 { SDLK_KP_PLUS, 75, 258, 19, "On" },
1787 { SDLK_KP_ENTER, 76, 307, 15, "Off" },
1788 { SDLK_KP5, 151, 290, 20, "Select" },
1789 { SDLK_KP8, 152, 251, 23, "Up" },
1790 { SDLK_KP4, 113, 288, 26, "Left" },
1791 { SDLK_KP6, 189, 291, 23, "Right" },
1792 { SDLK_KP2, 150, 327, 27, "Down" },
1793 { 0, 0, 0, 0, "None" }
1794};
1795#elif defined (ARCHOS_FMRECORDER) || defined (ARCHOS_RECORDERV2)
1796struct button_map bm[] = {
1797 { SDLK_F1, 88, 210, 28, "F1" },
1798 { SDLK_F2, 144, 212, 28, "F2" },
1799 { SDLK_F3, 197, 212, 28, "F3" },
1800 { SDLK_KP5, 144, 287, 21, "Select" },
1801 { SDLK_KP_PLUS, 86, 320, 13, "Menu" },
1802 { SDLK_KP_ENTER, 114, 347, 13, "Stop" },
1803 { SDLK_y, 144, 288, 31, "None" },
1804 { SDLK_KP8, 144, 259, 25, "Up" },
1805 { SDLK_KP2, 144, 316, 31, "Down" },
1806 { SDLK_KP6, 171, 287, 32, "Right" },
1807 { SDLK_KP4, 117, 287, 31, "Left" },
1808 { 0, 0, 0, 0, "None" }
1809};
1810#elif defined (ARCHOS_ONDIOSP) || defined (ARCHOS_ONDIOFM)
1811struct button_map bm[] = {
1812 { SDLK_KP_ENTER, 75, 23, 30, "Enter" },
1813 { SDLK_KP8, 75, 174, 33, "KP8" },
1814 { SDLK_KP4, 26, 186, 48, "KP4" },
1815 { SDLK_KP6, 118, 196, 32, "KP6" },
1816 { SDLK_KP2, 75, 234, 16, "KP2" },
1817 { SDLK_KP_PERIOD, 54, 250, 24, "Period" },
1818 { 0, 0, 0, 0, "None" }
1819};
1820#elif defined (IRIVER_H10)
1821struct button_map bm[] = {
1822 { SDLK_KP_PLUS, 38, 70, 37, "Power" },
1823 { SDLK_KP4, 123, 194, 26, "Cancel" },
1824 { SDLK_KP6, 257, 195, 34, "Select" },
1825 { SDLK_KP8, 190, 221, 28, "Up" },
1826 { SDLK_KP2, 192, 320, 27, "Down" },
1827 { SDLK_KP_DIVIDE, 349, 49, 20, "Rew" },
1828 { SDLK_KP5, 349, 96, 20, "Play" },
1829 { SDLK_KP_MULTIPLY, 350, 141, 23, "FF" },
1830 { 0, 0, 0, 0, "None" }
1831};
1832#elif defined (IRIVER_H10_5GB)
1833struct button_map bm[] = {
1834 { SDLK_KP_PLUS, 34, 76, 23, "Power" },
1835 { SDLK_KP4, 106, 222, 28, "Cancel" },
1836 { SDLK_KP6, 243, 220, 31, "Select" },
1837 { SDLK_KP8, 176, 254, 34, "Up" },
1838 { SDLK_KP2, 175, 371, 35, "Down" },
1839 { SDLK_KP_DIVIDE, 319, 63, 26, "Rew" },
1840 { SDLK_KP5, 320, 124, 26, "Play" },
1841 { SDLK_KP_MULTIPLY, 320, 181, 32, "FF" },
1842 { 0, 0, 0, 0, "None" }
1843};
1844#elif defined (IRIVER_H120) || defined (IRIVER_H100)
1845struct button_map bm[] = {
1846 { SDLK_KP_DIVIDE, 46, 162, 13, "Record" },
1847 { SDLK_KP_PLUS, 327, 36, 16, "Play" },
1848 { SDLK_KP_ENTER, 330, 99, 18, "Stop" },
1849 { SDLK_KP_PERIOD, 330, 163, 18, "AB" },
1850 { SDLK_KP5, 186, 227, 27, "5" },
1851 { SDLK_KP8, 187, 185, 19, "8" },
1852 { SDLK_KP4, 142, 229, 23, "4" },
1853 { SDLK_KP6, 231, 229, 22, "6" },
1854 { SDLK_KP2, 189, 272, 28, "2" },
1855/* Remote Buttons */
1856 { SDLK_KP_ENTER, 250, 404, 20, "Stop" },
1857 { SDLK_SPACE, 285, 439, 29, "Space" },
1858 { SDLK_h, 336, 291, 24, "Hold" },
1859 { 0, 0, 0, 0, "None" }
1860};
1861#elif defined (IRIVER_H300)
1862struct button_map bm[] = {
1863 { SDLK_KP_PLUS, 56, 335, 20, "Play" },
1864 { SDLK_KP8, 140, 304, 29, "Up" },
1865 { SDLK_KP_DIVIDE, 233, 331, 23, "Record" },
1866 { SDLK_KP_ENTER, 54, 381, 24, "Stop" },
1867 { SDLK_KP4, 100, 353, 17, "Left" },
1868 { SDLK_KP5, 140, 351, 19, "Navi" },
1869 { SDLK_KP6, 185, 356, 19, "Right" },
1870 { SDLK_KP_PERIOD, 230, 380, 20, "AB" },
1871 { SDLK_KP2, 142, 402, 24, "Down" },
1872 { SDLK_KP_ENTER, 211, 479, 21, "Stop" },
1873 { SDLK_KP_PLUS, 248, 513, 29, "Play" },
1874 { 0, 0, 0, 0, "None" }
1875};
1876#elif defined (MROBE_500)
1877struct button_map bm[] = {
1878 { SDLK_KP9, 171, 609, 9, "Play" },
1879 { SDLK_KP4, 158, 623, 9, "Left" },
1880 { SDLK_KP6, 184, 622, 9, "Right" },
1881 { SDLK_KP7, 171, 638, 11, "Menu" },
1882 { 0, 0, 0, 0, "None" }
1883};
1884#elif defined (MROBE_100)
1885struct button_map bm[] = {
1886 { SDLK_KP7, 80, 233, 30, "Menu" },
1887 { SDLK_KP8, 138, 250, 19, "Up" },
1888 { SDLK_KP9, 201, 230, 27, "Play" },
1889 { SDLK_KP4, 63, 305, 25, "Left" },
1890 { SDLK_KP5, 125, 309, 28, "Select" },
1891 { SDLK_KP6, 200, 307, 35, "Right" },
1892 { SDLK_KP1, 52, 380, 32, "Display" },
1893 { SDLK_KP2, 125, 363, 30, "Down" },
1894 { SDLK_KP9, 168, 425, 10, "Play" },
1895 { SDLK_KP4, 156, 440, 11, "Left" },
1896 { SDLK_KP6, 180, 440, 13, "Right" },
1897 { SDLK_KP7, 169, 452, 10, "Menu" },
1898 { SDLK_KP_MULTIPLY, 222, 15, 16, "Power" },
1899 { 0, 0, 0, 0, "None" }
1900};
1901#elif defined (GIGABEAT_F)
1902struct button_map bm[] = {
1903 { SDLK_KP_PLUS, 361, 187, 22, "Power" },
1904 { SDLK_KP_PERIOD, 361, 270, 17, "Menu" },
1905 { SDLK_KP9, 365, 345, 26, "Vol Up" },
1906 { SDLK_KP3, 363, 433, 25, "Vol Down" },
1907 { SDLK_KP_ENTER, 365, 520, 19, "A" },
1908 { SDLK_KP8, 167, 458, 35, "Up" },
1909 { SDLK_KP4, 86, 537, 29, "Left" },
1910 { SDLK_KP5, 166, 536, 30, "Select" },
1911 { SDLK_KP6, 248, 536, 30, "Right" },
1912 { SDLK_KP2, 169, 617, 28, "Down" },
1913 { 0, 0, 0, 0, "None" }
1914};
1915#elif defined (GIGABEAT_S)
1916struct button_map bm[] = {
1917 { SDLK_KP_PLUS, 416, 383, 23, "Play" },
1918 { SDLK_KP7, 135, 442, 46, "Back" },
1919 { SDLK_KP9, 288, 447, 35, "Menu" },
1920 { SDLK_KP8, 214, 480, 32, "Up" },
1921 { SDLK_KP4, 128, 558, 33, "Left" },
1922 { SDLK_KP5, 214, 556, 34, "Select" },
1923 { SDLK_KP6, 293, 558, 35, "Right" },
1924 { SDLK_KP2, 214, 637, 38, "Down" },
1925 { 0, 0, 0, 0, "None" }
1926};
1927#elif defined (SAMSUNG_YH820)
1928struct button_map bm[] = {
1929 { SDLK_KP_PLUS, 330, 53, 23, "Record" },
1930 { SDLK_KP7, 132, 208, 21, "Left" },
1931 { SDLK_KP5, 182, 210, 18, "Play" },
1932 { SDLK_KP9, 234, 211, 22, "Right" },
1933 { SDLK_KP8, 182, 260, 15, "Up" },
1934 { SDLK_KP4, 122, 277, 29, "Menu" },
1935 { SDLK_KP6, 238, 276, 25, "Select" },
1936 { SDLK_KP2, 183, 321, 24, "Down" },
1937 { 0, 0, 0, 0, "None" }
1938};
1939#elif defined (SAMSUNG_YH920) || defined (SAMSUNG_YH925)
1940struct button_map bm[] = {
1941 { SDLK_KP9, 370, 32, 15, "FF" },
1942 { SDLK_KP5, 369, 84, 25, "Play" },
1943 { SDLK_KP5, 367, 125, 27, "Play" },
1944 { SDLK_KP3, 369, 188, 17, "Rew" },
1945 { SDLK_KP_PLUS, 370, 330, 30, "Record" },
1946 { SDLK_KP4, 146, 252, 32, "Menu" },
1947 { SDLK_KP8, 204, 226, 27, "Up" },
1948 { SDLK_KP6, 257, 250, 34, "Select" },
1949 { SDLK_KP2, 205, 294, 35, "Down" },
1950 { 0, 0, 0, 0, "None" }
1951};
1952#elif defined (ONDA_VX747) || defined (ONDA_VX747P)
1953struct button_map bm[] = {
1954 { SDLK_MINUS, 113, 583, 28, "Minus" },
1955 { SDLK_PLUS, 227, 580, 28, "Plus" },
1956 { SDLK_RETURN, 171, 583, 34, "Menu" },
1957 { 0, 0, 0, 0, "None" }
1958};
1959#elif defined (PHILIPS_SA9200)
1960struct button_map bm[] = {
1961 { SDLK_KP_ENTER, 25, 155, 33, "Power" },
1962 { SDLK_PAGEUP, 210, 98, 31, "Vol Up" },
1963 { SDLK_PAGEDOWN, 210, 168, 34, "Vol Down" },
1964 { SDLK_KP7, 40, 249, 26, "Prev" },
1965 { SDLK_KP8, 110, 247, 22, "Up" },
1966 { SDLK_KP9, 183, 249, 31, "Next" },
1967 { SDLK_KP4, 45, 305, 25, "Left" },
1968 { SDLK_KP5, 111, 304, 24, "Play" },
1969 { SDLK_KP6, 183, 304, 21, "Right" },
1970 { SDLK_KP1, 43, 377, 21, "Menu" },
1971 { SDLK_KP2, 112, 371, 24, "Down" },
1972 { 0, 0, 0, 0, "None" }
1973};
1974#elif defined (CREATIVE_ZVM) || defined (CREATIVE_ZVM60GB) || \
1975 defined (CREATIVE_ZV)
1976struct button_map bm[] = {
1977 { SDLK_KP7, 52, 414, 35, "Custom" },
1978 { SDLK_KP8, 185, 406, 55, "Up" },
1979 { SDLK_KP9, 315, 421, 46, "Play" },
1980 { SDLK_KP4, 122, 500, 41, "Left" },
1981 { SDLK_KP6, 247, 493, 49, "Right" },
1982 { SDLK_KP1, 58, 577, 49, "Back" },
1983 { SDLK_KP2, 186, 585, 46, "Down" },
1984 { SDLK_KP3, 311, 569, 47, "Menu" },
1985 { 0, 0, 0, 0, "None" }
1986};
1987#elif defined (MPIO_HD200)
1988struct button_map bm[] = {
1989 { SDLK_ESCAPE, 369, 257, 20, "Rec" },
1990 { SDLK_RETURN, 369, 305, 20, "Play/Stop" },
1991 { SDLK_UP, 353, 168, 10, "Rew" },
1992 { SDLK_DOWN, 353, 198, 10, "FF" },
1993 { SDLK_SPACE, 353, 186, 10, "Select" },
1994 { SDLK_LEFT, 123, 67, 20, "Vol Down" },
1995 { SDLK_RIGHT, 206, 67, 20, "Vol Up" },
1996 { SDLK_h, 369, 402, 30, "Hold" },
1997 { 0, 0, 0, 0, "None" }
1998};
1999#else
2000struct button_map bm[] = {
2001 { 0, 0, 0, 0, ""}
2002};
2003#endif
2004
2005static int xy2button( int x, int y)
2006{
2007 int i;
2008 extern bool debug_buttons;
2009
2010 for ( i = 0; bm[i].button; i++ )
2011 /* check distance from center of button < radius */
2012 if ( ( (x-bm[i].x)*(x-bm[i].x) ) + ( ( y-bm[i].y)*(y-bm[i].y) ) < bm[i].radius*bm[i].radius ) {
2013 if (debug_buttons)
2014 printf("Button: %s\n", bm[i].description );
2015 return bm[i].button;
2016 }
2017 return 0;
2018}
diff --git a/firmware/target/hosted/sdl/button-sdl.h b/firmware/target/hosted/sdl/button-sdl.h
new file mode 100644
index 0000000000..75a68c49bc
--- /dev/null
+++ b/firmware/target/hosted/sdl/button-sdl.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#ifndef __BUTTON_SDL_H__
24#define __BUTTON_SDL_H__
25
26#include <stdbool.h>
27#include "config.h"
28
29bool button_hold(void);
30void button_init_device(void);
31
32#endif /* __BUTTON_SDL_H__ */
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c
new file mode 100644
index 0000000000..d796921e35
--- /dev/null
+++ b/firmware/target/hosted/sdl/kernel-sdl.c
@@ -0,0 +1,162 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Felix Arends
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <SDL.h>
25#include <SDL_thread.h>
26#include "memory.h"
27#include "system-sdl.h"
28#include "thread-sdl.h"
29#include "kernel.h"
30#include "thread.h"
31#include "panic.h"
32#include "debug.h"
33
34static SDL_TimerID tick_timer_id;
35long start_tick;
36
37/* Condition to signal that "interrupts" may proceed */
38static SDL_cond *sim_thread_cond;
39/* Mutex to serialize changing levels and exclude other threads while
40 * inside a handler */
41static SDL_mutex *sim_irq_mtx;
42static int interrupt_level = HIGHEST_IRQ_LEVEL;
43static int handlers_pending = 0;
44static int status_reg = 0;
45
46/* Nescessary logic:
47 * 1) All threads must pass unblocked
48 * 2) Current handler must always pass unblocked
49 * 3) Threads must be excluded when irq routine is running
50 * 4) No more than one handler routine should execute at a time
51 */
52int set_irq_level(int level)
53{
54 SDL_LockMutex(sim_irq_mtx);
55
56 int oldlevel = interrupt_level;
57
58 if (status_reg == 0 && level == 0 && oldlevel != 0)
59 {
60 /* Not in a handler and "interrupts" are being reenabled */
61 if (handlers_pending > 0)
62 SDL_CondSignal(sim_thread_cond);
63 }
64
65 interrupt_level = level; /* save new level */
66
67 SDL_UnlockMutex(sim_irq_mtx);
68 return oldlevel;
69}
70
71void sim_enter_irq_handler(void)
72{
73 SDL_LockMutex(sim_irq_mtx);
74 handlers_pending++;
75
76 if(interrupt_level != 0)
77 {
78 /* "Interrupts" are disabled. Wait for reenable */
79 SDL_CondWait(sim_thread_cond, sim_irq_mtx);
80 }
81
82 status_reg = 1;
83}
84
85void sim_exit_irq_handler(void)
86{
87 if (--handlers_pending > 0)
88 SDL_CondSignal(sim_thread_cond);
89
90 status_reg = 0;
91 SDL_UnlockMutex(sim_irq_mtx);
92}
93
94static bool sim_kernel_init(void)
95{
96 sim_irq_mtx = SDL_CreateMutex();
97 if (sim_irq_mtx == NULL)
98 {
99 panicf("Cannot create sim_handler_mtx\n");
100 return false;
101 }
102
103 sim_thread_cond = SDL_CreateCond();
104 if (sim_thread_cond == NULL)
105 {
106 panicf("Cannot create sim_thread_cond\n");
107 return false;
108 }
109
110 return true;
111}
112
113void sim_kernel_shutdown(void)
114{
115 SDL_RemoveTimer(tick_timer_id);
116 SDL_DestroyMutex(sim_irq_mtx);
117 SDL_DestroyCond(sim_thread_cond);
118}
119
120Uint32 tick_timer(Uint32 interval, void *param)
121{
122 long new_tick;
123
124 (void) interval;
125 (void) param;
126
127 new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);
128
129 while(new_tick != current_tick)
130 {
131 sim_enter_irq_handler();
132
133 /* Run through the list of tick tasks - increments tick
134 * on each iteration. */
135 call_tick_tasks();
136
137 sim_exit_irq_handler();
138 }
139
140 return 1;
141}
142
143void tick_start(unsigned int interval_in_ms)
144{
145 if (!sim_kernel_init())
146 {
147 panicf("Could not initialize kernel!");
148 exit(-1);
149 }
150
151 if (tick_timer_id != NULL)
152 {
153 SDL_RemoveTimer(tick_timer_id);
154 tick_timer_id = NULL;
155 }
156 else
157 {
158 start_tick = SDL_GetTicks();
159 }
160
161 tick_timer_id = SDL_AddTimer(interval_in_ms, tick_timer, NULL);
162}
diff --git a/firmware/target/hosted/sdl/lcd-bitmap.c b/firmware/target/hosted/sdl/lcd-bitmap.c
new file mode 100644
index 0000000000..6dfbffff37
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-bitmap.c
@@ -0,0 +1,416 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "debug.h"
23#include "sim-ui-defines.h"
24#include "system.h"
25#include "lcd-sdl.h"
26#include "screendump.h"
27
28SDL_Surface* lcd_surface;
29
30#if LCD_DEPTH <= 8
31#ifdef HAVE_BACKLIGHT
32SDL_Color lcd_bl_color_dark = {RED_CMP(LCD_BL_DARKCOLOR),
33 GREEN_CMP(LCD_BL_DARKCOLOR),
34 BLUE_CMP(LCD_BL_DARKCOLOR), 0};
35SDL_Color lcd_bl_color_bright = {RED_CMP(LCD_BL_BRIGHTCOLOR),
36 GREEN_CMP(LCD_BL_BRIGHTCOLOR),
37 BLUE_CMP(LCD_BL_BRIGHTCOLOR), 0};
38#ifdef HAVE_LCD_SPLIT
39SDL_Color lcd_bl_color2_dark = {RED_CMP(LCD_BL_DARKCOLOR_2),
40 GREEN_CMP(LCD_BL_DARKCOLOR_2),
41 BLUE_CMP(LCD_BL_DARKCOLOR_2), 0};
42SDL_Color lcd_bl_color2_bright = {RED_CMP(LCD_BL_BRIGHTCOLOR_2),
43 GREEN_CMP(LCD_BL_BRIGHTCOLOR_2),
44 BLUE_CMP(LCD_BL_BRIGHTCOLOR_2), 0};
45#endif
46#endif /* HAVE_BACKLIGHT */
47SDL_Color lcd_color_dark = {RED_CMP(LCD_DARKCOLOR),
48 GREEN_CMP(LCD_DARKCOLOR),
49 BLUE_CMP(LCD_DARKCOLOR), 0};
50SDL_Color lcd_color_bright = {RED_CMP(LCD_BRIGHTCOLOR),
51 GREEN_CMP(LCD_BRIGHTCOLOR),
52 BLUE_CMP(LCD_BRIGHTCOLOR), 0};
53#ifdef HAVE_LCD_SPLIT
54SDL_Color lcd_color2_dark = {RED_CMP(LCD_DARKCOLOR_2),
55 GREEN_CMP(LCD_DARKCOLOR_2),
56 BLUE_CMP(LCD_DARKCOLOR_2), 0};
57SDL_Color lcd_color2_bright = {RED_CMP(LCD_BRIGHTCOLOR_2),
58 GREEN_CMP(LCD_BRIGHTCOLOR_2),
59 BLUE_CMP(LCD_BRIGHTCOLOR_2), 0};
60#endif
61
62#ifdef HAVE_LCD_SPLIT
63#define NUM_SHADES 128
64#else
65#define NUM_SHADES 129
66#endif
67
68#else /* LCD_DEPTH > 8 */
69
70#ifdef HAVE_TRANSFLECTIVE_LCD
71#define BACKLIGHT_OFF_ALPHA 85 /* 1/3 brightness */
72#else
73#define BACKLIGHT_OFF_ALPHA 0 /* pitch black */
74#endif
75
76#endif /* LCD_DEPTH */
77
78#if LCD_DEPTH < 8
79unsigned long (*lcd_ex_getpixel)(int, int) = NULL;
80#endif /* LCD_DEPTH < 8 */
81
82#if LCD_DEPTH == 2
83/* Only defined for positive, non-split LCD for now */
84static const unsigned char colorindex[4] = {128, 85, 43, 0};
85#endif
86
87static unsigned long get_lcd_pixel(int x, int y)
88{
89#if LCD_DEPTH == 1
90#ifdef HAVE_NEGATIVE_LCD
91 return (lcd_framebuffer[y/8][x] & (1 << (y & 7))) ? (NUM_SHADES-1) : 0;
92#else
93 return (lcd_framebuffer[y/8][x] & (1 << (y & 7))) ? 0 : (NUM_SHADES-1);
94#endif
95#elif LCD_DEPTH == 2
96#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
97 return colorindex[(lcd_framebuffer[y][x/4] >> (2 * (~x & 3))) & 3];
98#elif LCD_PIXELFORMAT == VERTICAL_PACKING
99 return colorindex[(lcd_framebuffer[y/4][x] >> (2 * (y & 3))) & 3];
100#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED
101 unsigned bits = (lcd_framebuffer[y/8][x] >> (y & 7)) & 0x0101;
102 return colorindex[(bits | (bits >> 7)) & 3];
103#endif
104#elif LCD_DEPTH == 16
105#if LCD_PIXELFORMAT == RGB565SWAPPED
106 unsigned bits = lcd_framebuffer[y][x];
107 return (bits >> 8) | (bits << 8);
108#else
109#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
110 return *(&lcd_framebuffer[0][0]+LCD_HEIGHT*x+y);
111#else
112 return lcd_framebuffer[y][x];
113#endif
114#endif
115#endif
116}
117
118void lcd_update(void)
119{
120 /* update a full screen rect */
121 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
122}
123
124void lcd_update_rect(int x_start, int y_start, int width, int height)
125{
126 sdl_update_rect(lcd_surface, x_start, y_start, width, height,
127 LCD_WIDTH, LCD_HEIGHT, get_lcd_pixel);
128 sdl_gui_update(lcd_surface, x_start, y_start, width,
129 height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
130 background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
131}
132
133#ifdef HAVE_BACKLIGHT
134void sim_backlight(int value)
135{
136#if LCD_DEPTH <= 8
137 if (value > 0) {
138 sdl_set_gradient(lcd_surface, &lcd_bl_color_dark,
139 &lcd_bl_color_bright, 0, NUM_SHADES);
140#ifdef HAVE_LCD_SPLIT
141 sdl_set_gradient(lcd_surface, &lcd_bl_color2_dark,
142 &lcd_bl_color2_bright, NUM_SHADES, NUM_SHADES);
143#endif
144 } else {
145 sdl_set_gradient(lcd_surface, &lcd_color_dark,
146 &lcd_color_bright, 0, NUM_SHADES);
147#ifdef HAVE_LCD_SPLIT
148 sdl_set_gradient(lcd_surface, &lcd_color2_dark,
149 &lcd_color2_bright, NUM_SHADES, NUM_SHADES);
150#endif
151 }
152#else /* LCD_DEPTH > 8 */
153 SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, (value * 255) / 100);
154#endif /* LCD_DEPTH */
155
156 sdl_gui_update(lcd_surface, 0, 0, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
157 SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
158 background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0);
159}
160#endif /* HAVE_BACKLIGHT */
161
162/* initialise simulator lcd driver */
163void sim_lcd_init(void)
164{
165#if LCD_DEPTH == 16
166 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
167 SIM_LCD_WIDTH * display_zoom,
168 SIM_LCD_HEIGHT * display_zoom,
169 LCD_DEPTH, 0, 0, 0, 0);
170#elif LCD_DEPTH <= 8
171 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
172 SIM_LCD_WIDTH * display_zoom,
173 SIM_LCD_HEIGHT * display_zoom,
174 8, 0, 0, 0, 0);
175
176#ifdef HAVE_BACKLIGHT
177 sdl_set_gradient(lcd_surface, &lcd_bl_color_dark,
178 &lcd_bl_color_bright, 0, NUM_SHADES);
179#ifdef HAVE_LCD_SPLIT
180 sdl_set_gradient(lcd_surface, &lcd_bl_color2_dark,
181 &lcd_bl_color2_bright, NUM_SHADES, NUM_SHADES);
182#endif
183#else /* !HAVE_BACKLIGHT */
184 sdl_set_gradient(lcd_surface, &lcd_color_dark,
185 &lcd_color_bright, 0, NUM_SHADES);
186#ifdef HAVE_LCD_SPLIT
187 sdl_set_gradient(lcd_surface, &lcd_color2_dark,
188 &lcd_color2_bright, NUM_SHADES, NUM_SHADES);
189#endif
190#endif /* !HAVE_BACKLIGHT */
191#endif /* LCD_DEPTH */
192}
193
194#if LCD_DEPTH < 8
195void sim_lcd_ex_init(unsigned long (*getpixel)(int, int))
196{
197 lcd_ex_getpixel = getpixel;
198}
199
200void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height)
201{
202 if (lcd_ex_getpixel) {
203 sdl_update_rect(lcd_surface, x_start, y_start, width, height,
204 LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel);
205 sdl_gui_update(lcd_surface, x_start, y_start, width,
206 height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
207 background ? UI_LCD_POSX : 0,
208 background ? UI_LCD_POSY : 0);
209 }
210}
211#endif
212
213#ifdef HAVE_LCD_COLOR
214/**
215 * |R| |1.000000 -0.000001 1.402000| |Y'|
216 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
217 * |B| |1.000000 1.772000 0.000000| |Pr|
218 * Scaled, normalized, rounded and tweaked to yield RGB 565:
219 * |R| |74 0 101| |Y' - 16| >> 9
220 * |G| = |74 -24 -51| |Cb - 128| >> 8
221 * |B| |74 128 0| |Cr - 128| >> 9
222 */
223#define YFAC (74)
224#define RVFAC (101)
225#define GUFAC (-24)
226#define GVFAC (-51)
227#define BUFAC (128)
228
229static inline int clamp(int val, int min, int max)
230{
231 if (val < min)
232 val = min;
233 else if (val > max)
234 val = max;
235 return val;
236}
237
238void lcd_yuv_set_options(unsigned options)
239{
240 (void)options;
241}
242
243/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
244 in the core */
245void lcd_blit_yuv(unsigned char * const src[3],
246 int src_x, int src_y, int stride,
247 int x, int y, int width, int height)
248{
249 const unsigned char *ysrc, *usrc, *vsrc;
250 int linecounter;
251 fb_data *dst, *row_end;
252 long z;
253
254 /* width and height must be >= 2 and an even number */
255 width &= ~1;
256 linecounter = height >> 1;
257
258#if LCD_WIDTH >= LCD_HEIGHT
259 dst = &lcd_framebuffer[y][x];
260 row_end = dst + width;
261#else
262 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
263 row_end = dst + LCD_WIDTH * width;
264#endif
265
266 z = stride * src_y;
267 ysrc = src[0] + z + src_x;
268 usrc = src[1] + (z >> 2) + (src_x >> 1);
269 vsrc = src[2] + (usrc - src[1]);
270
271 /* stride => amount to jump from end of last row to start of next */
272 stride -= width;
273
274 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
275
276 do
277 {
278 do
279 {
280 int y, cb, cr, rv, guv, bu, r, g, b;
281
282 y = YFAC*(*ysrc++ - 16);
283 cb = *usrc++ - 128;
284 cr = *vsrc++ - 128;
285
286 rv = RVFAC*cr;
287 guv = GUFAC*cb + GVFAC*cr;
288 bu = BUFAC*cb;
289
290 r = y + rv;
291 g = y + guv;
292 b = y + bu;
293
294 if ((unsigned)(r | g | b) > 64*256-1)
295 {
296 r = clamp(r, 0, 64*256-1);
297 g = clamp(g, 0, 64*256-1);
298 b = clamp(b, 0, 64*256-1);
299 }
300
301 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
302
303#if LCD_WIDTH >= LCD_HEIGHT
304 dst++;
305#else
306 dst += LCD_WIDTH;
307#endif
308
309 y = YFAC*(*ysrc++ - 16);
310 r = y + rv;
311 g = y + guv;
312 b = y + bu;
313
314 if ((unsigned)(r | g | b) > 64*256-1)
315 {
316 r = clamp(r, 0, 64*256-1);
317 g = clamp(g, 0, 64*256-1);
318 b = clamp(b, 0, 64*256-1);
319 }
320
321 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
322
323#if LCD_WIDTH >= LCD_HEIGHT
324 dst++;
325#else
326 dst += LCD_WIDTH;
327#endif
328 }
329 while (dst < row_end);
330
331 ysrc += stride;
332 usrc -= width >> 1;
333 vsrc -= width >> 1;
334
335#if LCD_WIDTH >= LCD_HEIGHT
336 row_end += LCD_WIDTH;
337 dst += LCD_WIDTH - width;
338#else
339 row_end -= 1;
340 dst -= LCD_WIDTH*width + 1;
341#endif
342
343 do
344 {
345 int y, cb, cr, rv, guv, bu, r, g, b;
346
347 y = YFAC*(*ysrc++ - 16);
348 cb = *usrc++ - 128;
349 cr = *vsrc++ - 128;
350
351 rv = RVFAC*cr;
352 guv = GUFAC*cb + GVFAC*cr;
353 bu = BUFAC*cb;
354
355 r = y + rv;
356 g = y + guv;
357 b = y + bu;
358
359 if ((unsigned)(r | g | b) > 64*256-1)
360 {
361 r = clamp(r, 0, 64*256-1);
362 g = clamp(g, 0, 64*256-1);
363 b = clamp(b, 0, 64*256-1);
364 }
365
366 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
367
368#if LCD_WIDTH >= LCD_HEIGHT
369 dst++;
370#else
371 dst += LCD_WIDTH;
372#endif
373
374 y = YFAC*(*ysrc++ - 16);
375 r = y + rv;
376 g = y + guv;
377 b = y + bu;
378
379 if ((unsigned)(r | g | b) > 64*256-1)
380 {
381 r = clamp(r, 0, 64*256-1);
382 g = clamp(g, 0, 64*256-1);
383 b = clamp(b, 0, 64*256-1);
384 }
385
386 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
387
388#if LCD_WIDTH >= LCD_HEIGHT
389 dst++;
390#else
391 dst += LCD_WIDTH;
392#endif
393 }
394 while (dst < row_end);
395
396 ysrc += stride;
397 usrc += stride >> 1;
398 vsrc += stride >> 1;
399
400#if LCD_WIDTH >= LCD_HEIGHT
401 row_end += LCD_WIDTH;
402 dst += LCD_WIDTH - width;
403#else
404 row_end -= 1;
405 dst -= LCD_WIDTH*width + 1;
406#endif
407 }
408 while (--linecounter > 0);
409
410#if LCD_WIDTH >= LCD_HEIGHT
411 lcd_update_rect(x, y, width, height);
412#else
413 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
414#endif
415}
416#endif /* HAVE_LCD_COLOR */
diff --git a/firmware/target/hosted/sdl/lcd-bitmap.h b/firmware/target/hosted/sdl/lcd-bitmap.h
new file mode 100644
index 0000000000..a898744b41
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-bitmap.h
@@ -0,0 +1,35 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __LCDBITMAP_H__
23#define __LCDBITMAP_H__
24
25#include "lcd.h"
26#include "SDL.h"
27
28void sim_lcd_init(void);
29#if LCD_DEPTH < 8
30void sim_lcd_ex_init(unsigned long (*getpixel)(int, int));
31void sim_lcd_ex_update_rect(int x, int y, int width, int height);
32#endif
33
34#endif /* #ifndef __LCDBITMAP_H__ */
35
diff --git a/firmware/target/hosted/sdl/lcd-charcells.c b/firmware/target/hosted/sdl/lcd-charcells.c
new file mode 100644
index 0000000000..900cbb04dd
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-charcells.c
@@ -0,0 +1,198 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <string.h>
23#include <unistd.h>
24#include <fcntl.h>
25#include "system.h"
26#include "debug.h"
27#include "lcd.h"
28#include "lcd-charcell.h"
29#include "screendump.h"
30#include "general.h"
31
32#include "lcd-playersim.h"
33#include "sim-ui-defines.h"
34#include "lcd-sdl.h"
35
36/* can't include file.h here */
37#ifndef MAX_PATH
38#define MAX_PATH 260
39#endif
40
41/* extern functions, needed for screendump() */
42extern int sim_creat(const char *name, mode_t mode);
43
44SDL_Surface* lcd_surface;
45
46SDL_Color lcd_bl_color_dark = {RED_CMP(LCD_BL_DARKCOLOR),
47 GREEN_CMP(LCD_BL_DARKCOLOR),
48 BLUE_CMP(LCD_BL_DARKCOLOR), 0};
49SDL_Color lcd_bl_color_bright = {RED_CMP(LCD_BL_BRIGHTCOLOR),
50 GREEN_CMP(LCD_BL_BRIGHTCOLOR),
51 BLUE_CMP(LCD_BL_BRIGHTCOLOR), 0};
52SDL_Color lcd_color_dark = {RED_CMP(LCD_DARKCOLOR),
53 GREEN_CMP(LCD_DARKCOLOR),
54 BLUE_CMP(LCD_DARKCOLOR), 0};
55SDL_Color lcd_color_bright = {RED_CMP(LCD_BRIGHTCOLOR),
56 GREEN_CMP(LCD_BRIGHTCOLOR),
57 BLUE_CMP(LCD_BRIGHTCOLOR), 0};
58
59
60static unsigned long get_lcd_pixel(int x, int y)
61{
62 return sim_lcd_framebuffer[y][x];
63}
64
65void sim_lcd_update_rect(int x_start, int y_start, int width, int height)
66{
67 sdl_update_rect(lcd_surface, x_start, y_start, width, height,
68 SIM_LCD_WIDTH, SIM_LCD_HEIGHT, get_lcd_pixel);
69 sdl_gui_update(lcd_surface, x_start, y_start, width, height,
70 SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
71 background ? UI_LCD_POSX : 0, background ? UI_LCD_POSY : 0);
72}
73
74void lcd_update(void)
75{
76 int x, y;
77
78 for (y = 0; y < lcd_pattern_count; y++)
79 if (lcd_patterns[y].count > 0)
80 sim_lcd_define_pattern(y, lcd_patterns[y].pattern);
81
82 for (y = 0; y < LCD_HEIGHT; y++)
83 for (x = 0; x < LCD_WIDTH; x++)
84 lcd_print_char(x, y, lcd_charbuffer[y][x]);
85
86 if (lcd_cursor.visible)
87 lcd_print_char(lcd_cursor.x, lcd_cursor.y, lcd_cursor.hw_char);
88
89 sim_lcd_update_rect(0, ICON_HEIGHT, SIM_LCD_WIDTH,
90 LCD_HEIGHT*CHAR_HEIGHT*CHAR_PIXEL);
91}
92
93#ifdef HAVE_BACKLIGHT
94void sim_backlight(int value)
95{
96 if (value > 0) {
97 sdl_set_gradient(lcd_surface, &lcd_bl_color_bright,
98 &lcd_bl_color_dark, 0, (1<<LCD_DEPTH));
99 } else {
100 sdl_set_gradient(lcd_surface, &lcd_color_bright,
101 &lcd_color_dark, 0, (1<<LCD_DEPTH));
102 }
103
104 sim_lcd_update_rect(0, 0, SIM_LCD_WIDTH, SIM_LCD_HEIGHT);
105}
106#endif
107
108/* initialise simulator lcd driver */
109void sim_lcd_init(void)
110{
111 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
112 SIM_LCD_WIDTH * display_zoom,
113 SIM_LCD_HEIGHT * display_zoom,
114 8, 0, 0, 0, 0);
115
116 sdl_set_gradient(lcd_surface, &lcd_bl_color_bright,
117 &lcd_bl_color_dark, 0, (1<<LCD_DEPTH));
118}
119
120#define BMP_COMPRESSION 0 /* BI_RGB */
121#define BMP_NUMCOLORS (1 << LCD_DEPTH)
122#define BMP_BPP 1
123#define BMP_LINESIZE (((SIM_LCD_WIDTH + 31) / 32) * 4)
124
125#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
126#define BMP_DATASIZE (BMP_LINESIZE * SIM_LCD_HEIGHT)
127#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE)
128
129#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff
130#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff
131
132static const unsigned char bmpheader[] =
133{
134 0x42, 0x4d, /* 'BM' */
135 LE32_CONST(BMP_TOTALSIZE), /* Total file size */
136 0x00, 0x00, 0x00, 0x00, /* Reserved */
137 LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */
138
139 0x28, 0x00, 0x00, 0x00, /* Size of (2nd) header */
140 LE32_CONST(SIM_LCD_WIDTH), /* Width in pixels */
141 LE32_CONST(SIM_LCD_HEIGHT), /* Height in pixels */
142 0x01, 0x00, /* Number of planes (always 1) */
143 LE16_CONST(BMP_BPP), /* Bits per pixel 1/4/8/16/24 */
144 LE32_CONST(BMP_COMPRESSION),/* Compression mode */
145 LE32_CONST(BMP_DATASIZE), /* Size of bitmap data */
146 0xc4, 0x0e, 0x00, 0x00, /* Horizontal resolution (pixels/meter) */
147 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */
148 LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */
149 LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */
150
151 BMP_COLOR(LCD_BL_BRIGHTCOLOR),
152 BMP_COLOR(LCD_BL_DARKCOLOR)
153};
154
155void screen_dump(void)
156{
157 int fd;
158 char filename[MAX_PATH];
159 int x, y;
160 static unsigned char line[BMP_LINESIZE];
161
162 create_numbered_filename(filename, "", "dump_", ".bmp", 4
163 IF_CNFN_NUM_(, NULL));
164 DEBUGF("screen_dump\n");
165
166 fd = sim_creat(filename, 0666);
167 if (fd < 0)
168 return;
169
170 write(fd, bmpheader, sizeof(bmpheader));
171 SDL_LockSurface(lcd_surface);
172
173 /* BMP image goes bottom up */
174 for (y = SIM_LCD_HEIGHT - 1; y >= 0; y--)
175 {
176 Uint8 *src = (Uint8 *)lcd_surface->pixels
177 + y * SIM_LCD_WIDTH * display_zoom * display_zoom;
178 unsigned char *dst = line;
179 unsigned dst_mask = 0x80;
180
181 memset(line, 0, sizeof(line));
182 for (x = SIM_LCD_WIDTH; x > 0; x--)
183 {
184 if (*src)
185 *dst |= dst_mask;
186 src += display_zoom;
187 dst_mask >>= 1;
188 if (dst_mask == 0)
189 {
190 dst++;
191 dst_mask = 0x80;
192 }
193 }
194 write(fd, line, sizeof(line));
195 }
196 SDL_UnlockSurface(lcd_surface);
197 close(fd);
198}
diff --git a/firmware/target/hosted/sdl/lcd-charcells.h b/firmware/target/hosted/sdl/lcd-charcells.h
new file mode 100644
index 0000000000..890594f766
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-charcells.h
@@ -0,0 +1,34 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __LCDCHARCELL_H__
23#define __LCDCHARCELL_H__
24
25#include "lcd.h"
26#include "SDL.h"
27
28#ifdef HAVE_LCD_CHARCELLS
29void sim_lcd_init(void);
30void screen_dump(void);
31#endif
32
33#endif /* #ifndef __LCDCHARCELL_H__ */
34
diff --git a/firmware/target/hosted/sdl/lcd-remote-bitmap.c b/firmware/target/hosted/sdl/lcd-remote-bitmap.c
new file mode 100644
index 0000000000..9972f3e423
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-remote-bitmap.c
@@ -0,0 +1,111 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "sim-ui-defines.h"
23#include "lcd-sdl.h"
24#include "lcd-remote-bitmap.h"
25#include "screendump.h"
26#include "system.h" /* background */
27
28SDL_Surface *remote_surface = 0;
29
30SDL_Color remote_bl_color_dark = {RED_CMP(LCD_REMOTE_BL_DARKCOLOR),
31 GREEN_CMP(LCD_REMOTE_BL_DARKCOLOR),
32 BLUE_CMP(LCD_REMOTE_BL_DARKCOLOR), 0};
33SDL_Color remote_bl_color_bright = {RED_CMP(LCD_REMOTE_BL_BRIGHTCOLOR),
34 GREEN_CMP(LCD_REMOTE_BL_BRIGHTCOLOR),
35 BLUE_CMP(LCD_REMOTE_BL_BRIGHTCOLOR), 0};
36SDL_Color remote_color_dark = {RED_CMP(LCD_REMOTE_DARKCOLOR),
37 GREEN_CMP(LCD_REMOTE_DARKCOLOR),
38 BLUE_CMP(LCD_REMOTE_DARKCOLOR), 0};
39SDL_Color remote_color_bright = {RED_CMP(LCD_REMOTE_BRIGHTCOLOR),
40 GREEN_CMP(LCD_REMOTE_BRIGHTCOLOR),
41 BLUE_CMP(LCD_REMOTE_BRIGHTCOLOR), 0};
42
43#define NUM_SHADES 129
44
45#if LCD_REMOTE_DEPTH == 2
46/* Only defined for positive, non-split LCD for now */
47static const unsigned char colorindex[4] = {128, 85, 43, 0};
48#endif
49
50static unsigned long get_lcd_remote_pixel(int x, int y)
51{
52#if LCD_REMOTE_DEPTH == 1
53 return lcd_remote_framebuffer[y/8][x] & (1 << (y & 7)) ? 0 : (NUM_SHADES-1);
54#elif LCD_REMOTE_DEPTH == 2
55#if LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED
56 unsigned bits = (lcd_remote_framebuffer[y/8][x] >> (y & 7)) & 0x0101;
57 return colorindex[(bits | (bits >> 7)) & 3];
58#endif
59#endif
60}
61
62void lcd_remote_update (void)
63{
64 lcd_remote_update_rect(0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT);
65}
66
67void lcd_remote_update_rect(int x_start, int y_start, int width, int height)
68{
69 if (remote_surface)
70 {
71 sdl_update_rect(remote_surface, x_start, y_start, width, height,
72 LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, get_lcd_remote_pixel);
73 sdl_gui_update(remote_surface, x_start, y_start, width, height,
74 LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, background ? UI_REMOTE_POSX : 0,
75 background ? UI_REMOTE_POSY : LCD_HEIGHT);
76 }
77}
78
79void sim_remote_backlight(int value)
80{
81 if (remote_surface)
82 {
83 if (value > 0)
84 {
85 sdl_set_gradient(remote_surface, &remote_bl_color_dark,
86 &remote_bl_color_bright, 0, NUM_SHADES);
87 }
88 else
89 {
90 sdl_set_gradient(remote_surface, &remote_color_dark,
91 &remote_color_bright, 0, NUM_SHADES);
92 }
93 sdl_gui_update(remote_surface, 0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT,
94 LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT,
95 background ? UI_REMOTE_POSX : 0,
96 background? UI_REMOTE_POSY : LCD_HEIGHT);
97 }
98}
99
100/* initialise simulator lcd remote driver */
101void sim_lcd_remote_init(void)
102{
103 remote_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
104 LCD_REMOTE_WIDTH * display_zoom,
105 LCD_REMOTE_HEIGHT * display_zoom,
106 8, 0, 0, 0, 0);
107
108 sdl_set_gradient(remote_surface, &remote_bl_color_dark,
109 &remote_bl_color_bright, 0, NUM_SHADES);
110}
111
diff --git a/firmware/target/hosted/sdl/lcd-remote-bitmap.h b/firmware/target/hosted/sdl/lcd-remote-bitmap.h
new file mode 100644
index 0000000000..0a92ee6b79
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-remote-bitmap.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __LCDREMOTE_H__
23#define __LCDREMOTE_H__
24
25#include "lcd.h"
26#include "lcd-remote.h"
27#include "SDL.h"
28
29void sim_lcd_remote_init(void);
30
31#endif /* #ifndef __LCDREMOTE_H__ */
32
diff --git a/firmware/target/hosted/sdl/lcd-sdl.c b/firmware/target/hosted/sdl/lcd-sdl.c
new file mode 100644
index 0000000000..15e4ba95c3
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-sdl.c
@@ -0,0 +1,113 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <SDL.h>
23#include "lcd-sdl.h"
24#include "sim-ui-defines.h"
25#include "system.h" /* for MIN() and MAX() */
26
27int display_zoom = 1;
28
29void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width,
30 int height, int max_x, int max_y,
31 unsigned long (*getpixel)(int, int))
32{
33 int x, y;
34 int xmax, ymax;
35 SDL_Rect dest;
36
37 ymax = y_start + height;
38 xmax = x_start + width;
39
40 if(xmax > max_x)
41 xmax = max_x;
42 if(ymax >= max_y)
43 ymax = max_y;
44
45 SDL_LockSurface(surface);
46
47 dest.w = display_zoom;
48 dest.h = display_zoom;
49
50 for (x = x_start; x < xmax; x++) {
51 dest.x = x * display_zoom;
52
53#ifdef HAVE_LCD_SPLIT
54 for (y = y_start; y < MIN(ymax, LCD_SPLIT_POS); y++) {
55 dest.y = y * display_zoom;
56
57 SDL_FillRect(surface, &dest, (Uint32)(getpixel(x, y) | 0x80));
58 }
59 for (y = MAX(y_start, LCD_SPLIT_POS); y < ymax; y++) {
60 dest.y = (y + LCD_SPLIT_LINES) * display_zoom ;
61
62 SDL_FillRect(surface, &dest, (Uint32)getpixel(x, y));
63 }
64#else
65 for (y = y_start; y < ymax; y++) {
66 dest.y = y * display_zoom;
67
68 SDL_FillRect(surface, &dest, (Uint32)getpixel(x, y));
69 }
70#endif
71 }
72
73 SDL_UnlockSurface(surface);
74}
75
76void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
77 int height, int max_x, int max_y, int ui_x, int ui_y)
78{
79 if (x_start + width > max_x)
80 width = max_x - x_start;
81 if (y_start + height > max_y)
82 height = max_y - y_start;
83
84 SDL_Rect src = {x_start * display_zoom, y_start * display_zoom,
85 width * display_zoom, height * display_zoom};
86 SDL_Rect dest= {(ui_x + x_start) * display_zoom,
87 (ui_y + y_start) * display_zoom,
88 width * display_zoom, height * display_zoom};
89
90 if (surface->flags & SDL_SRCALPHA) /* alpha needs a black background */
91 SDL_FillRect(gui_surface, &dest, 0);
92
93 SDL_BlitSurface(surface, &src, gui_surface, &dest);
94
95 SDL_Flip(gui_surface);
96}
97
98/* set a range of bitmap indices to a gradient from startcolour to endcolour */
99void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end,
100 int first, int steps)
101{
102 int i;
103 SDL_Color palette[steps];
104
105 for (i = 0; i < steps; i++) {
106 palette[i].r = start->r + (end->r - start->r) * i / (steps - 1);
107 palette[i].g = start->g + (end->g - start->g) * i / (steps - 1);
108 palette[i].b = start->b + (end->b - start->b) * i / (steps - 1);
109 }
110
111 SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, first, steps);
112}
113
diff --git a/firmware/target/hosted/sdl/lcd-sdl.h b/firmware/target/hosted/sdl/lcd-sdl.h
new file mode 100644
index 0000000000..1f57b06b95
--- /dev/null
+++ b/firmware/target/hosted/sdl/lcd-sdl.h
@@ -0,0 +1,43 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __LCDSDL_H__
23#define __LCDSDL_H__
24
25#include "lcd.h"
26#include "SDL.h"
27
28/* Default display zoom level */
29extern int display_zoom;
30extern SDL_Surface *gui_surface;
31
32void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width,
33 int height, int max_x, int max_y,
34 unsigned long (*getpixel)(int, int));
35
36void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
37 int height, int max_x, int max_y, int ui_x, int ui_y);
38
39void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end,
40 int first, int steps);
41
42#endif /* #ifndef __LCDSDL_H__ */
43
diff --git a/firmware/target/hosted/sdl/pcm-sdl.c b/firmware/target/hosted/sdl/pcm-sdl.c
new file mode 100644
index 0000000000..1772db94f4
--- /dev/null
+++ b/firmware/target/hosted/sdl/pcm-sdl.c
@@ -0,0 +1,373 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Nick Lanham
11 * Copyright (C) 2010 by Thomas Martitz
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "autoconf.h"
24
25#include <stdlib.h>
26#include <stdbool.h>
27#include <SDL.h>
28#include "config.h"
29#include "debug.h"
30#include "sound.h"
31#include "audiohw.h"
32#include "system.h"
33
34#include "pcm.h"
35#include "pcm_sampr.h"
36
37#ifdef DEBUG
38#include <stdio.h>
39extern bool debug_audio;
40#endif
41
42static int sim_volume = 0;
43
44#if CONFIG_CODEC == SWCODEC
45static int cvt_status = -1;
46
47static Uint8* pcm_data;
48static size_t pcm_data_size;
49static size_t pcm_sample_bytes;
50static size_t pcm_channel_bytes;
51
52struct pcm_udata
53{
54 Uint8 *stream;
55 Uint32 num_in;
56 Uint32 num_out;
57#ifdef DEBUG
58 FILE *debug;
59#endif
60} udata;
61
62static SDL_AudioSpec obtained;
63static SDL_AudioCVT cvt;
64
65void pcm_play_lock(void)
66{
67 SDL_LockAudio();
68}
69
70void pcm_play_unlock(void)
71{
72 SDL_UnlockAudio();
73}
74
75static void pcm_dma_apply_settings_nolock(void)
76{
77 cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr,
78 obtained.format, obtained.channels, obtained.freq);
79
80 if (cvt_status < 0) {
81 cvt.len_ratio = (double)obtained.freq / (double)pcm_sampr;
82 }
83}
84
85void pcm_dma_apply_settings(void)
86{
87 pcm_play_lock();
88 pcm_dma_apply_settings_nolock();
89 pcm_play_unlock();
90}
91
92void pcm_play_dma_start(const void *addr, size_t size)
93{
94 pcm_dma_apply_settings_nolock();
95
96 pcm_data = (Uint8 *) addr;
97 pcm_data_size = size;
98
99 SDL_PauseAudio(0);
100}
101
102void pcm_play_dma_stop(void)
103{
104 SDL_PauseAudio(1);
105#ifdef DEBUG
106 if (udata.debug != NULL) {
107 fclose(udata.debug);
108 udata.debug = NULL;
109 DEBUGF("Audio debug file closed\n");
110 }
111#endif
112}
113
114void pcm_play_dma_pause(bool pause)
115{
116 if (pause)
117 SDL_PauseAudio(1);
118 else
119 SDL_PauseAudio(0);
120}
121
122size_t pcm_get_bytes_waiting(void)
123{
124 return pcm_data_size;
125}
126
127void write_to_soundcard(struct pcm_udata *udata)
128{
129#ifdef DEBUG
130 if (debug_audio && (udata->debug == NULL)) {
131 udata->debug = fopen("audiodebug.raw", "ab");
132 DEBUGF("Audio debug file open\n");
133 }
134#endif
135 if (cvt.needed) {
136 Uint32 rd = udata->num_in;
137 Uint32 wr = (double)rd * cvt.len_ratio;
138
139 if (wr > udata->num_out) {
140 wr = udata->num_out;
141 rd = (double)wr / cvt.len_ratio;
142
143 if (rd > udata->num_in)
144 {
145 rd = udata->num_in;
146 wr = (double)rd * cvt.len_ratio;
147 }
148 }
149
150 if (wr == 0 || rd == 0)
151 {
152 udata->num_out = udata->num_in = 0;
153 return;
154 }
155
156 if (cvt_status > 0) {
157 cvt.len = rd * pcm_sample_bytes;
158 cvt.buf = (Uint8 *) malloc(cvt.len * cvt.len_mult);
159
160 memcpy(cvt.buf, pcm_data, cvt.len);
161
162 SDL_ConvertAudio(&cvt);
163 SDL_MixAudio(udata->stream, cvt.buf, cvt.len_cvt, sim_volume);
164
165 udata->num_in = cvt.len / pcm_sample_bytes;
166 udata->num_out = cvt.len_cvt / pcm_sample_bytes;
167
168#ifdef DEBUG
169 if (udata->debug != NULL) {
170 fwrite(cvt.buf, sizeof(Uint8), cvt.len_cvt, udata->debug);
171 }
172#endif
173 free(cvt.buf);
174 }
175 else {
176 /* Convert is bad, so do silence */
177 Uint32 num = wr*obtained.channels;
178 udata->num_in = rd;
179 udata->num_out = wr;
180
181 switch (pcm_channel_bytes)
182 {
183 case 1:
184 {
185 Uint8 *stream = udata->stream;
186 while (num-- > 0)
187 *stream++ = obtained.silence;
188 break;
189 }
190 case 2:
191 {
192 Uint16 *stream = (Uint16 *)udata->stream;
193 while (num-- > 0)
194 *stream++ = obtained.silence;
195 break;
196 }
197 }
198#ifdef DEBUG
199 if (udata->debug != NULL) {
200 fwrite(udata->stream, sizeof(Uint8), wr, udata->debug);
201 }
202#endif
203 }
204 } else {
205 udata->num_in = udata->num_out = MIN(udata->num_in, udata->num_out);
206 SDL_MixAudio(udata->stream, pcm_data,
207 udata->num_out * pcm_sample_bytes, sim_volume);
208#ifdef DEBUG
209 if (udata->debug != NULL) {
210 fwrite(pcm_data, sizeof(Uint8), udata->num_out * pcm_sample_bytes,
211 udata->debug);
212 }
213#endif
214 }
215}
216
217void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
218{
219 udata->stream = stream;
220
221 /* Write what we have in the PCM buffer */
222 if (pcm_data_size > 0)
223 goto start;
224
225 /* Audio card wants more? Get some more then. */
226 while (len > 0) {
227 if ((ssize_t)pcm_data_size <= 0) {
228 pcm_data_size = 0;
229
230 if (pcm_callback_for_more)
231 pcm_callback_for_more(&pcm_data, &pcm_data_size);
232 }
233
234 if (pcm_data_size > 0) {
235 start:
236 udata->num_in = pcm_data_size / pcm_sample_bytes;
237 udata->num_out = len / pcm_sample_bytes;
238
239 write_to_soundcard(udata);
240
241 udata->num_in *= pcm_sample_bytes;
242 udata->num_out *= pcm_sample_bytes;
243
244 pcm_data += udata->num_in;
245 pcm_data_size -= udata->num_in;
246 udata->stream += udata->num_out;
247 len -= udata->num_out;
248 } else {
249 DEBUGF("sdl_audio_callback: No Data.\n");
250 pcm_play_dma_stop();
251 pcm_play_dma_stopped_callback();
252 break;
253 }
254 }
255}
256
257const void * pcm_play_dma_get_peak_buffer(int *count)
258{
259 uintptr_t addr = (uintptr_t)pcm_data;
260 *count = pcm_data_size / 4;
261 return (void *)((addr + 2) & ~3);
262}
263
264#ifdef HAVE_RECORDING
265void pcm_rec_lock(void)
266{
267}
268
269void pcm_rec_unlock(void)
270{
271}
272
273void pcm_rec_dma_init(void)
274{
275}
276
277void pcm_rec_dma_close(void)
278{
279}
280
281void pcm_rec_dma_start(void *start, size_t size)
282{
283 (void)start;
284 (void)size;
285}
286
287void pcm_rec_dma_stop(void)
288{
289}
290
291void pcm_rec_dma_record_more(void *start, size_t size)
292{
293 (void)start;
294 (void)size;
295}
296
297unsigned long pcm_rec_status(void)
298{
299 return 0;
300}
301
302const void * pcm_rec_dma_get_peak_buffer(void)
303{
304 return NULL;
305}
306
307#endif /* HAVE_RECORDING */
308
309void pcm_play_dma_init(void)
310{
311 if (SDL_InitSubSystem(SDL_INIT_AUDIO))
312 {
313 DEBUGF("Could not initialize SDL audio subsystem!\n");
314 return;
315 }
316
317 SDL_AudioSpec wanted_spec;
318#ifdef DEBUG
319 udata.debug = NULL;
320 if (debug_audio) {
321 udata.debug = fopen("audiodebug.raw", "wb");
322 DEBUGF("Audio debug file open\n");
323 }
324#endif
325 /* Set 16-bit stereo audio at 44Khz */
326 wanted_spec.freq = 44100;
327 wanted_spec.format = AUDIO_S16SYS;
328 wanted_spec.channels = 2;
329 wanted_spec.samples = 2048;
330 wanted_spec.callback =
331 (void (SDLCALL *)(void *userdata,
332 Uint8 *stream, int len))sdl_audio_callback;
333 wanted_spec.userdata = &udata;
334
335 /* Open the audio device and start playing sound! */
336 if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) {
337 DEBUGF("Unable to open audio: %s\n", SDL_GetError());
338 return;
339 }
340
341 switch (obtained.format)
342 {
343 case AUDIO_U8:
344 case AUDIO_S8:
345 pcm_channel_bytes = 1;
346 break;
347 case AUDIO_U16LSB:
348 case AUDIO_S16LSB:
349 case AUDIO_U16MSB:
350 case AUDIO_S16MSB:
351 pcm_channel_bytes = 2;
352 break;
353 default:
354 DEBUGF("Unknown sample format obtained: %u\n",
355 (unsigned)obtained.format);
356 return;
357 }
358
359 pcm_sample_bytes = obtained.channels * pcm_channel_bytes;
360
361 pcm_dma_apply_settings_nolock();
362}
363
364void pcm_postinit(void)
365{
366}
367
368void pcm_set_mixer_volume(int volume)
369{
370 sim_volume = volume;
371}
372
373#endif /* CONFIG_CODEC == SWCODEC */
diff --git a/firmware/target/hosted/sdl/sim-ui-defines.h b/firmware/target/hosted/sdl/sim-ui-defines.h
new file mode 100644
index 0000000000..567a618fc3
--- /dev/null
+++ b/firmware/target/hosted/sdl/sim-ui-defines.h
@@ -0,0 +1,405 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __UISDL_H__
23#define __UISDL_H__
24
25#include <stdbool.h>
26#include "SDL.h"
27#include "config.h"
28
29/* colour definitions are R, G, B */
30
31#if defined(ARCHOS_RECORDER)
32#define UI_TITLE "Jukebox Recorder"
33#define UI_WIDTH 270 /* width of GUI window */
34#define UI_HEIGHT 406 /* height of GUI window */
35#define UI_LCD_POSX 80 /* x position of lcd */
36#define UI_LCD_POSY 104 /* y position of lcd */
37
38#elif defined(ARCHOS_PLAYER)
39#define UI_TITLE "Jukebox Player"
40#define UI_WIDTH 284 /* width of GUI window */
41#define UI_HEIGHT 420 /* height of GUI window */
42#define UI_LCD_POSX 75 /* x position of lcd */
43#define UI_LCD_POSY 116 /* y position of lcd */
44
45#elif defined(ARCHOS_FMRECORDER) || defined(ARCHOS_RECORDERV2)
46#define UI_TITLE "Jukebox FM Recorder"
47#define UI_WIDTH 285 /* width of GUI window */
48#define UI_HEIGHT 414 /* height of GUI window */
49#define UI_LCD_POSX 87 /* x position of lcd */
50#define UI_LCD_POSY 77 /* y position of lcd */
51
52#elif defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM)
53#define UI_TITLE "Ondio"
54#define UI_WIDTH 155 /* width of GUI window */
55#define UI_HEIGHT 334 /* height of GUI window */
56#define UI_LCD_POSX 21 /* x position of lcd */
57#define UI_LCD_POSY 82 /* y position of lcd */
58
59#elif defined(IRIVER_H120) || defined(IRIVER_H100)
60#define UI_TITLE "iriver H1x0"
61#define UI_WIDTH 379 /* width of GUI window */
62#define UI_HEIGHT 508 /* height of GUI window */
63#define UI_LCD_POSX 109 /* x position of lcd */
64#define UI_LCD_POSY 23 /* y position of lcd */
65#define UI_REMOTE_POSX 50 /* x position of remote lcd */
66#define UI_REMOTE_POSY 403 /* y position of remote lcd */
67
68#elif defined(IRIVER_H300)
69#define UI_TITLE "iriver H300"
70#define UI_WIDTH 288 /* width of GUI window */
71#define UI_HEIGHT 581 /* height of GUI window */
72#define UI_LCD_POSX 26 /* x position of lcd */
73#define UI_LCD_POSY 36 /* y position of lcd */
74#define UI_REMOTE_POSX 12 /* x position of remote lcd */
75#define UI_REMOTE_POSY 478 /* y position of remote lcd */
76
77#elif defined(IPOD_1G2G)
78#define UI_TITLE "iPod 1G/2G"
79#define UI_WIDTH 224 /* width of GUI window */
80#define UI_HEIGHT 382 /* height of GUI window */
81#define UI_LCD_POSX 32 /* x position of lcd */
82#define UI_LCD_POSY 12 /* y position of lcd */
83
84#elif defined(IPOD_3G)
85#define UI_TITLE "iPod 3G"
86#define UI_WIDTH 218 /* width of GUI window */
87#define UI_HEIGHT 389 /* height of GUI window */
88#define UI_LCD_POSX 29 /* x position of lcd */
89#define UI_LCD_POSY 16 /* y position of lcd */
90
91#elif defined(IPOD_4G)
92#define UI_TITLE "iPod 4G"
93#define UI_WIDTH 196 /* width of GUI window */
94#define UI_HEIGHT 370 /* height of GUI window */
95#define UI_LCD_POSX 19 /* x position of lcd */
96#define UI_LCD_POSY 14 /* y position of lcd */
97
98#elif defined(IPOD_MINI) || defined(IPOD_MINI2G)
99#define UI_TITLE "iPod mini"
100#define UI_WIDTH 191 /* width of GUI window */
101#define UI_HEIGHT 365 /* height of GUI window */
102#define UI_LCD_POSX 24 /* x position of lcd */
103#define UI_LCD_POSY 17 /* y position of lcd */
104
105#elif defined(IPOD_COLOR)
106#define UI_TITLE "iPod Color"
107#define UI_WIDTH 261 /* width of GUI window */
108#define UI_HEIGHT 493 /* height of GUI window */
109#define UI_LCD_POSX 21 /* x position of lcd */
110#define UI_LCD_POSY 16 /* y position of lcd */
111
112#elif defined(IPOD_NANO)
113#define UI_TITLE "iPod Nano"
114#define UI_WIDTH 199 /* width of GUI window */
115#define UI_HEIGHT 421 /* height of GUI window */
116#define UI_LCD_POSX 13 /* x position of lcd */
117#define UI_LCD_POSY 14 /* y position of lcd */
118
119#elif defined(IPOD_NANO2G)
120#define UI_TITLE "iPod Nano 2G"
121#define UI_WIDTH 235 /* width of GUI window */
122#define UI_HEIGHT 537 /* height of GUI window */
123#define UI_LCD_POSX 29 /* x position of lcd */
124#define UI_LCD_POSY 33 /* y position of lcd */
125
126#elif defined(IPOD_VIDEO)
127#define UI_TITLE "iPod Video"
128#define UI_WIDTH 350 /* width of GUI window */
129#define UI_HEIGHT 591 /* height of GUI window */
130#define UI_LCD_POSX 14 /* x position of lcd */
131#define UI_LCD_POSY 12 /* y position of lcd */
132
133#elif defined(IAUDIO_X5)
134#define UI_TITLE "iAudio X5"
135#define UI_WIDTH 300 /* width of GUI window */
136#define UI_HEIGHT 558 /* height of GUI window */
137#define UI_LCD_POSX 55 /* x position of lcd */
138#define UI_LCD_POSY 61 /* y position of lcd */
139#define UI_REMOTE_POSX 12 /* x position of remote lcd */
140#define UI_REMOTE_POSY 462 /* y position of remote lcd */
141
142#elif defined(IAUDIO_M5)
143#define UI_TITLE "iAudio M5"
144#define UI_WIDTH 374 /* width of GUI window */
145#define UI_HEIGHT 650 /* height of GUI window */
146#define UI_LCD_POSX 82 /* x position of lcd */
147#define UI_LCD_POSY 74 /* y position of lcd */
148#define UI_REMOTE_POSX 59 /* x position of remote lcd */
149#define UI_REMOTE_POSY 509 /* y position of remote lcd */
150
151#elif defined(IAUDIO_M3)
152#define UI_TITLE "iAudio M3"
153#define UI_WIDTH 397 /* width of GUI window */
154#define UI_HEIGHT 501 /* height of GUI window */
155#define UI_LCD_POSX 92 /* x position of lcd */
156#define UI_LCD_POSY 348 /* y position of lcd */
157
158#elif defined(GIGABEAT_F)
159#define UI_TITLE "Toshiba Gigabeat"
160#define UI_WIDTH 401 /* width of GUI window */
161#define UI_HEIGHT 655 /* height of GUI window */
162#define UI_LCD_POSX 48 /* x position of lcd */
163#define UI_LCD_POSY 60 /* y position of lcd */
164
165#elif defined(GIGABEAT_S)
166#define UI_TITLE "Toshiba Gigabeat"
167#define UI_WIDTH 450 /* width of GUI window */
168#define UI_HEIGHT 688 /* height of GUI window */
169#define UI_LCD_POSX 96 /* x position of lcd */
170#define UI_LCD_POSY 90 /* y position of lcd */
171
172#elif defined(MROBE_500)
173#if LCD_WIDTH==320
174#define UI_TITLE "Olympus M:Robe 500"
175#define UI_WIDTH 450 /* width of GUI window */
176#define UI_HEIGHT 350 /* height of GUI window */
177#define UI_LCD_POSX 65 /* x position of lcd */
178#define UI_LCD_POSY 30 /* y position of lcd */
179#define UI_REMOTE_POSX 36 /* x position of remote lcd */
180#define UI_REMOTE_POSY 318 /* y position of remote lcd */
181#else
182#define UI_TITLE "Olympus M:Robe 500"
183#define UI_WIDTH 895 /* width of GUI window */
184#define UI_HEIGHT 646 /* height of GUI window */
185#define UI_LCD_POSX 129 /* x position of lcd */
186#define UI_LCD_POSY 60 /* y position of lcd */
187#define UI_REMOTE_POSX 37 /* x position of remote lcd */
188#define UI_REMOTE_POSY 615 /* y position of remote lcd */
189#endif
190
191#elif defined(IRIVER_H10)
192#define UI_TITLE "iriver H10 20Gb"
193#define UI_WIDTH 392 /* width of GUI window */
194#define UI_HEIGHT 391 /* height of GUI window */
195#define UI_LCD_POSX 111 /* x position of lcd */
196#define UI_LCD_POSY 30 /* y position of lcd */
197
198#elif defined(IRIVER_H10_5GB)
199#define UI_TITLE "iriver H10 5/6Gb"
200#define UI_WIDTH 353 /* width of GUI window */
201#define UI_HEIGHT 460 /* height of GUI window */
202#define UI_LCD_POSX 112 /* x position of lcd */
203#define UI_LCD_POSY 45 /* y position of lcd */
204
205#elif defined(SANSA_E200) || defined(SANSA_E200V2)
206#ifdef SANSA_E200
207#define UI_TITLE "Sansa e200"
208#else
209#define UI_TITLE "Sansa e200v2"
210#endif
211#define UI_WIDTH 260 /* width of GUI window */
212#define UI_HEIGHT 502 /* height of GUI window */
213#define UI_LCD_POSX 42 /* x position of lcd */
214#define UI_LCD_POSY 37 /* y position of lcd */
215
216#elif defined(SANSA_C200) || defined(SANSA_C200V2)
217#ifdef SANSA_C200
218#define UI_TITLE "Sansa c200"
219#else
220#define UI_TITLE "Sansa c200v2"
221#endif
222#define UI_WIDTH 350 /* width of GUI window */
223#define UI_HEIGHT 152 /* height of GUI window */
224#define UI_LCD_POSX 42 /* x position of lcd */
225#define UI_LCD_POSY 35 /* y position of lcd */
226
227#elif defined(IRIVER_IFP7XX)
228#define UI_TITLE "iriver iFP7xx"
229#define UI_WIDTH 425 /* width of GUI window */
230#define UI_HEIGHT 183 /* height of GUI window */
231#define UI_LCD_POSX 115 /* x position of lcd */
232#define UI_LCD_POSY 54 /* y position of lcd */
233
234#elif defined(ARCHOS_AV300)
235#define UI_TITLE "Archos AV300"
236/* We are temporarily using a 2bpp LCD driver and dummy bitmap */
237#define UI_WIDTH 420 /* width of GUI window */
238#define UI_HEIGHT 340 /* height of GUI window */
239#define UI_LCD_POSX 50 /* x position of lcd */
240#define UI_LCD_POSY 50 /* y position of lcd */
241
242#elif defined(MROBE_100)
243#define UI_TITLE "Olympus M:Robe 100"
244#define UI_WIDTH 247 /* width of GUI window */
245#define UI_HEIGHT 462 /* height of GUI window */
246#define UI_LCD_POSX 43 /* x position of lcd */
247#define UI_LCD_POSY 25 /* y position of lcd */
248#define UI_REMOTE_POSX 34 /* x position of remote lcd */
249#define UI_REMOTE_POSY 432 /* y position of remote lcd */
250
251#elif defined(COWON_D2)
252#define UI_TITLE "Cowon D2"
253#define UI_WIDTH 472 /* width of GUI window */
254#define UI_HEIGHT 368 /* height of GUI window */
255#define UI_LCD_POSX 58 /* x position of lcd */
256#define UI_LCD_POSY 67 /* y position of lcd */
257
258#elif defined(IAUDIO_7)
259#define UI_TITLE "iAudio7"
260#define UI_WIDTH 494 /* width of GUI window */
261#define UI_HEIGHT 214 /* height of GUI window */
262#define UI_LCD_POSX 131 /* x position of lcd */
263#define UI_LCD_POSY 38 /* y position of lcd */
264
265#elif defined(CREATIVE_ZVM) || defined(CREATIVE_ZVM60GB)
266#ifdef CREATIVE_ZVM
267 #define UI_TITLE "Creative Zen Vision:M 30GB"
268#else
269 #define UI_TITLE "Creative Zen Vision:M 60GB"
270#endif
271#define UI_WIDTH 383 /* width of GUI window */
272#define UI_HEIGHT 643 /* height of GUI window */
273#define UI_LCD_POSX 31 /* x position of lcd */
274#define UI_LCD_POSY 62 /* y position of lcd */
275
276#elif defined(CREATIVE_ZV)
277#define UI_TITLE "Creative Zen Vision"
278#define UI_WIDTH 1054 /* width of GUI window */
279#define UI_HEIGHT 643 /* height of GUI window */
280#define UI_LCD_POSX 129 /* x position of lcd */
281#define UI_LCD_POSY 85 /* y position of lcd */
282
283#elif defined(MEIZU_M6SL)
284#define UI_TITLE "Meizu M6"
285#define UI_WIDTH 512 /* width of GUI window */
286#define UI_HEIGHT 322 /* height of GUI window */
287#define UI_LCD_POSX 39 /* x position of lcd */
288#define UI_LCD_POSY 38 /* y position of lcd */
289
290#elif defined(SANSA_FUZE) || defined(SANSA_FUZEV2)
291#ifdef SANSA_FUZE
292#define UI_TITLE "Sansa Fuze"
293#else
294#define UI_TITLE "Sansa Fuzev2"
295#endif
296#define UI_WIDTH 279 /* width of GUI window */
297#define UI_HEIGHT 449 /* height of GUI window */
298#define UI_LCD_POSX 30 /* x position of lcd */
299#define UI_LCD_POSY 31 /* y position of lcd */
300
301#elif defined(SANSA_CLIP) || defined(SANSA_CLIPV2)
302#if defined(SANSA_CLIP)
303#define CLIP_VERSION ""
304#elif defined(SANSA_CLIPV2)
305#define CLIP_VERSION "v2"
306#endif
307#define UI_TITLE "Sansa Clip"CLIP_VERSION
308#define UI_WIDTH 205 /* width of GUI window */
309#define UI_HEIGHT 325 /* height of GUI window */
310#define UI_LCD_POSX 38 /* x position of lcd */
311#define UI_LCD_POSY 38 /* y position of lcd */
312
313#elif defined(SANSA_CLIPPLUS)
314#define UI_TITLE "Sansa Clip+"
315#define UI_WIDTH 205 /* width of GUI window */
316#define UI_HEIGHT 325 /* height of GUI window */
317#define UI_LCD_POSX 42 /* x position of lcd */
318#define UI_LCD_POSY 42 /* y position of lcd */
319
320
321
322#elif defined(PHILIPS_SA9200)
323#define UI_TITLE "Philips GoGear SA9200"
324#define UI_WIDTH 233 /* width of GUI window */
325#define UI_HEIGHT 435 /* height of GUI window */
326#define UI_LCD_POSX 50 /* x position of lcd */
327#define UI_LCD_POSY 50 /* y position of lcd */
328
329#elif defined(PHILIPS_HDD1630)
330#define UI_TITLE "Philips GoGear HDD1630"
331#define UI_WIDTH 407 /* width of GUI window */
332#define UI_HEIGHT 391 /* height of GUI window */
333#define UI_LCD_POSX 143 /* x position of lcd */
334#define UI_LCD_POSY 27 /* y position of lcd */
335
336#elif defined(SANSA_M200V4)
337#define UI_TITLE "sansa m200v4"
338#define UI_WIDTH 350 /* width of GUI window */
339#define UI_HEIGHT 168 /* height of GUI window */
340#define UI_LCD_POSX 42 /* x position of lcd */
341#define UI_LCD_POSY 55 /* y position of lcd */
342
343#elif defined(ONDA_VX747) || defined(ONDA_VX747P)
344#ifdef ONDA_VX747
345#define UI_TITLE "Onda VX747"
346#else
347#define UI_TITLE "Onda VX747+"
348#endif
349#define UI_WIDTH 340 /* width of GUI window */
350#define UI_HEIGHT 601 /* height of GUI window */
351#define UI_LCD_POSX 45 /* x position of lcd */
352#define UI_LCD_POSY 90 /* y position of lcd */
353
354#elif defined(ONDA_VX777)
355#define UI_TITLE "Onda VX777"
356#define UI_WIDTH 306 /* width of GUI window */
357#define UI_HEIGHT 558 /* height of GUI window */
358#define UI_LCD_POSX 32 /* x position of lcd */
359#define UI_LCD_POSY 81 /* y position of lcd */
360
361#elif defined(SAMSUNG_YH820)
362#define UI_TITLE "Samsung YH-820"
363#define UI_WIDTH 368 /* width of GUI window */
364#define UI_HEIGHT 428 /* height of GUI window */
365#define UI_LCD_POSX 120 /* x position of lcd */
366#define UI_LCD_POSY 75 /* y position of lcd */
367
368#elif defined(SAMSUNG_YH920) || defined(SAMSUNG_YH925)
369#ifdef SAMSUNG_YH920
370#define UI_TITLE "Samsung YH-920"
371#else
372#define UI_TITLE "Samsung YH-925"
373#endif
374#define UI_WIDTH 408 /* width of GUI window */
375#define UI_HEIGHT 454 /* height of GUI window */
376#define UI_LCD_POSX 124 /* x position of lcd */
377#define UI_LCD_POSY 42 /* y position of lcd */
378
379#elif defined(MINI2440)
380#define UI_TITLE "Mini2440"
381#define UI_WIDTH 441 /* width of GUI window */
382#define UI_HEIGHT 436 /* height of GUI window */
383#define UI_LCD_POSX 148 /* x position of lcd */
384#define UI_LCD_POSY 50 /* y position of lcd */
385
386#elif defined(PBELL_VIBE500)
387#define UI_TITLE "Packard Bell Vibe 500"
388#define UI_WIDTH 287 /* width of GUI window */
389#define UI_HEIGHT 488 /* height of GUI window */
390#define UI_LCD_POSX 64 /* x position of lcd */
391#define UI_LCD_POSY 61 /* y position of lcd */
392
393#elif defined(MPIO_HD200)
394#define UI_TITLE "MPIO HD200"
395#define UI_WIDTH 430 /* width of GUI window */
396#define UI_HEIGHT 479 /* height of GUI window */
397#define UI_LCD_POSX 101
398#define UI_LCD_POSY 195
399
400#elif defined(SIMULATOR)
401#error no UI defines
402#endif
403
404#endif /* #ifndef __UISDL_H__ */
405
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
new file mode 100644
index 0000000000..693e8d1b57
--- /dev/null
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -0,0 +1,236 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Daniel Everton <dan@iocaine.org>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <SDL.h>
23#include <stdlib.h>
24#include <string.h>
25#include <setjmp.h>
26#include "system-sdl.h"
27#include "thread-sdl.h"
28#include "sim-ui-defines.h"
29#include "lcd-sdl.h"
30#ifdef HAVE_LCD_BITMAP
31#include "lcd-bitmap.h"
32#elif defined(HAVE_LCD_CHARCELLS)
33#include "lcd-charcells.h"
34#endif
35#ifdef HAVE_REMOTE_LCD
36#include "lcd-remote-bitmap.h"
37#endif
38#include "panic.h"
39#include "debug.h"
40
41SDL_Surface *gui_surface;
42
43bool background = true; /* use backgrounds by default */
44#ifdef HAVE_REMOTE_LCD
45bool showremote = true; /* include remote by default */
46#endif
47bool mapping = false;
48bool debug_buttons = false;
49
50bool lcd_display_redraw = true; /* Used for player simulator */
51char having_new_lcd = true; /* Used for player simulator */
52bool sim_alarm_wakeup = false;
53const char *sim_root_dir = NULL;
54extern int display_zoom;
55
56#ifdef DEBUG
57bool debug_audio = false;
58#endif
59
60bool debug_wps = false;
61int wps_verbose_level = 3;
62
63
64void sys_poweroff(void)
65{
66 /* Order here is relevent to prevent deadlocks and use of destroyed
67 sync primitives by kernel threads */
68 sim_thread_shutdown();
69 sim_kernel_shutdown();
70 SDL_Quit();
71}
72
73void system_init(void)
74{
75 SDL_Surface *picture_surface;
76 int width, height;
77
78 if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER))
79 panicf("%s", SDL_GetError());
80
81 /* Try and load the background image. If it fails go without */
82 if (background) {
83 picture_surface = SDL_LoadBMP("UI256.bmp");
84 if (picture_surface == NULL) {
85 background = false;
86 DEBUGF("warn: %s\n", SDL_GetError());
87 }
88 }
89
90 /* Set things up */
91 if (background)
92 {
93 width = UI_WIDTH;
94 height = UI_HEIGHT;
95 }
96 else
97 {
98#ifdef HAVE_REMOTE_LCD
99 if (showremote)
100 {
101 width = SIM_LCD_WIDTH > SIM_REMOTE_WIDTH ? SIM_LCD_WIDTH : SIM_REMOTE_WIDTH;
102 height = SIM_LCD_HEIGHT + SIM_REMOTE_HEIGHT;
103 }
104 else
105#endif
106 {
107 width = SIM_LCD_WIDTH;
108 height = SIM_LCD_HEIGHT;
109 }
110 }
111
112
113 if ((gui_surface = SDL_SetVideoMode(width * display_zoom, height * display_zoom, 24, SDL_HWSURFACE|SDL_DOUBLEBUF)) == NULL) {
114 panicf("%s", SDL_GetError());
115 }
116
117 SDL_WM_SetCaption(UI_TITLE, NULL);
118
119 sim_lcd_init();
120#ifdef HAVE_REMOTE_LCD
121 if (showremote)
122 sim_lcd_remote_init();
123#endif
124
125 if (background && picture_surface != NULL) {
126 SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);
127 SDL_UpdateRect(gui_surface, 0, 0, 0, 0);
128 }
129}
130
131void system_exception_wait(void)
132{
133 sim_thread_exception_wait();
134}
135
136void system_reboot(void)
137{
138 sim_thread_exception_wait();
139}
140
141void sys_handle_argv(int argc, char *argv[])
142{
143 if (argc >= 1)
144 {
145 int x;
146 for (x = 1; x < argc; x++)
147 {
148#ifdef DEBUG
149 if (!strcmp("--debugaudio", argv[x]))
150 {
151 debug_audio = true;
152 printf("Writing debug audio file.\n");
153 }
154 else
155#endif
156 if (!strcmp("--debugwps", argv[x]))
157 {
158 debug_wps = true;
159 printf("WPS debug mode enabled.\n");
160 }
161 else if (!strcmp("--nobackground", argv[x]))
162 {
163 background = false;
164 printf("Disabling background image.\n");
165 }
166#ifdef HAVE_REMOTE_LCD
167 else if (!strcmp("--noremote", argv[x]))
168 {
169 showremote = false;
170 background = false;
171 printf("Disabling remote image.\n");
172 }
173#endif
174 else if (!strcmp("--old_lcd", argv[x]))
175 {
176 having_new_lcd = false;
177 printf("Using old LCD layout.\n");
178 }
179 else if (!strcmp("--zoom", argv[x]))
180 {
181 x++;
182 if(x < argc)
183 display_zoom=atoi(argv[x]);
184 else
185 display_zoom = 2;
186 printf("Window zoom is %d\n", display_zoom);
187 }
188 else if (!strcmp("--alarm", argv[x]))
189 {
190 sim_alarm_wakeup = true;
191 printf("Simulating alarm wakeup.\n");
192 }
193 else if (!strcmp("--root", argv[x]))
194 {
195 x++;
196 if (x < argc)
197 {
198 sim_root_dir = argv[x];
199 printf("Root directory: %s\n", sim_root_dir);
200 }
201 }
202 else if (!strcmp("--mapping", argv[x]))
203 {
204 mapping = true;
205 printf("Printing click coords with drag radii.\n");
206 }
207 else if (!strcmp("--debugbuttons", argv[x]))
208 {
209 debug_buttons = true;
210 printf("Printing background button clicks.\n");
211 }
212 else
213 {
214 printf("rockboxui\n");
215 printf("Arguments:\n");
216#ifdef DEBUG
217 printf(" --debugaudio \t Write raw PCM data to audiodebug.raw\n");
218#endif
219 printf(" --debugwps \t Print advanced WPS debug info\n");
220 printf(" --nobackground \t Disable the background image\n");
221#ifdef HAVE_REMOTE_LCD
222 printf(" --noremote \t Disable the remote image (will disable backgrounds)\n");
223#endif
224 printf(" --old_lcd \t [Player] simulate old playermodel (ROM version<4.51)\n");
225 printf(" --zoom [VAL]\t Window zoom (will disable backgrounds)\n");
226 printf(" --alarm \t Simulate a wake-up on alarm\n");
227 printf(" --root [DIR]\t Set root directory\n");
228 printf(" --mapping \t Output coordinates and radius for mapping backgrounds\n");
229 exit(0);
230 }
231 }
232 }
233 if (display_zoom > 1) {
234 background = false;
235 }
236}
diff --git a/firmware/target/hosted/sdl/system-sdl.h b/firmware/target/hosted/sdl/system-sdl.h
new file mode 100644
index 0000000000..917e6e89da
--- /dev/null
+++ b/firmware/target/hosted/sdl/system-sdl.h
@@ -0,0 +1,52 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _SYSTEM_SDL_H_
22#define _SYSTEM_SDL_H_
23
24#include <stdbool.h>
25
26#define HIGHEST_IRQ_LEVEL 1
27
28int set_irq_level(int level);
29
30#define disable_irq() \
31 ((void)set_irq_level(HIGHEST_IRQ_LEVEL))
32
33#define enable_irq() \
34 ((void)set_irq_level(0))
35
36#define disable_irq_save() \
37 set_irq_level(HIGHEST_IRQ_LEVEL)
38
39#define restore_irq(level) \
40 ((void)set_irq_level(level))
41
42void sim_enter_irq_handler(void);
43void sim_exit_irq_handler(void);
44void sim_kernel_shutdown(void);
45void sys_poweroff(void);
46void sys_handle_argv(int argc, char *argv[]);
47
48extern bool background; /* True if the background image is enabled */
49extern int display_zoom;
50extern long start_tick;
51
52#endif /* _SYSTEM_SDL_H_ */
diff --git a/firmware/target/hosted/sdl/thread-sdl.c b/firmware/target/hosted/sdl/thread-sdl.c
new file mode 100644
index 0000000000..fbe2621d40
--- /dev/null
+++ b/firmware/target/hosted/sdl/thread-sdl.c
@@ -0,0 +1,610 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdbool.h>
23#include <time.h>
24#include <SDL.h>
25#include <SDL_thread.h>
26#include <stdlib.h>
27#include <memory.h>
28#include <setjmp.h>
29#include "system-sdl.h"
30#include "thread-sdl.h"
31#include "system.h"
32#include "kernel.h"
33#include "thread.h"
34#include "debug.h"
35
36/* Define this as 1 to show informational messages that are not errors. */
37#define THREAD_SDL_DEBUGF_ENABLED 0
38
39#if THREAD_SDL_DEBUGF_ENABLED
40#define THREAD_SDL_DEBUGF(...) DEBUGF(__VA_ARGS__)
41static char __name[32];
42#define THREAD_SDL_GET_NAME(thread) \
43 ({ thread_get_name(__name, ARRAYLEN(__name), thread); __name; })
44#else
45#define THREAD_SDL_DEBUGF(...)
46#define THREAD_SDL_GET_NAME(thread)
47#endif
48
49#define THREAD_PANICF(str...) \
50 ({ fprintf(stderr, str); exit(-1); })
51
52/* Thread/core entries as in rockbox core */
53static struct core_entry cores[NUM_CORES];
54struct thread_entry threads[MAXTHREADS];
55/* Jump buffers for graceful exit - kernel threads don't stay neatly
56 * in their start routines responding to messages so this is the only
57 * way to get them back in there so they may exit */
58static jmp_buf thread_jmpbufs[MAXTHREADS];
59/* this mutex locks out other Rockbox threads while one runs,
60 * that enables us to simulate a cooperative environment even if
61 * the host is preemptive */
62static SDL_mutex *m;
63static volatile bool threads_exit = false;
64
65extern long start_tick;
66
67void sim_thread_shutdown(void)
68{
69 int i;
70
71 /* Tell all threads jump back to their start routines, unlock and exit
72 gracefully - we'll check each one in turn for it's status. Threads
73 _could_ terminate via remove_thread or multiple threads could exit
74 on each unlock but that is safe. */
75
76 /* Do this before trying to acquire lock */
77 threads_exit = true;
78
79 /* Take control */
80 SDL_LockMutex(m);
81
82 for (i = 0; i < MAXTHREADS; i++)
83 {
84 struct thread_entry *thread = &threads[i];
85 /* exit all current threads, except the main one */
86 if (thread->context.t != NULL)
87 {
88 /* Signal thread on delay or block */
89 SDL_Thread *t = thread->context.t;
90 SDL_SemPost(thread->context.s);
91 SDL_UnlockMutex(m);
92 /* Wait for it to finish */
93 SDL_WaitThread(t, NULL);
94 /* Relock for next thread signal */
95 SDL_LockMutex(m);
96 }
97 }
98
99 SDL_UnlockMutex(m);
100 SDL_DestroyMutex(m);
101}
102
103static void new_thread_id(unsigned int slot_num,
104 struct thread_entry *thread)
105{
106 unsigned int version =
107 (thread->id + (1u << THREAD_ID_VERSION_SHIFT))
108 & THREAD_ID_VERSION_MASK;
109
110 if (version == 0)
111 version = 1u << THREAD_ID_VERSION_SHIFT;
112
113 thread->id = version | (slot_num & THREAD_ID_SLOT_MASK);
114}
115
116static struct thread_entry * find_empty_thread_slot(void)
117{
118 struct thread_entry *thread = NULL;
119 int n;
120
121 for (n = 0; n < MAXTHREADS; n++)
122 {
123 int state = threads[n].state;
124
125 if (state == STATE_KILLED)
126 {
127 thread = &threads[n];
128 break;
129 }
130 }
131
132 return thread;
133}
134
135
136/* Initialize SDL threading */
137void init_threads(void)
138{
139 struct thread_entry *thread;
140 int n;
141
142 memset(cores, 0, sizeof(cores));
143 memset(threads, 0, sizeof(threads));
144
145 m = SDL_CreateMutex();
146
147 if (SDL_LockMutex(m) == -1)
148 {
149 fprintf(stderr, "Couldn't lock mutex\n");
150 return;
151 }
152
153 /* Initialize all IDs */
154 for (n = 0; n < MAXTHREADS; n++)
155 threads[n].id = THREAD_ID_INIT(n);
156
157 /* Slot 0 is reserved for the main thread - initialize it here and
158 then create the SDL thread - it is possible to have a quick, early
159 shutdown try to access the structure. */
160 thread = &threads[0];
161 thread->stack = (uintptr_t *)" ";
162 thread->stack_size = 8;
163 thread->name = "main";
164 thread->state = STATE_RUNNING;
165 thread->context.s = SDL_CreateSemaphore(0);
166 thread->context.t = NULL; /* NULL for the implicit main thread */
167 cores[CURRENT_CORE].running = thread;
168
169 if (thread->context.s == NULL)
170 {
171 fprintf(stderr, "Failed to create main semaphore\n");
172 return;
173 }
174
175 THREAD_SDL_DEBUGF("Main thread: %p\n", thread);
176
177 return;
178}
179
180void sim_thread_exception_wait(void)
181{
182 while (1)
183 {
184 SDL_Delay(HZ/10);
185 if (threads_exit)
186 thread_exit();
187 }
188}
189
190/* A way to yield and leave the threading system for extended periods */
191void sim_thread_lock(void *me)
192{
193 SDL_LockMutex(m);
194 cores[CURRENT_CORE].running = (struct thread_entry *)me;
195
196 if (threads_exit)
197 thread_exit();
198}
199
200void * sim_thread_unlock(void)
201{
202 struct thread_entry *current = cores[CURRENT_CORE].running;
203 SDL_UnlockMutex(m);
204 return current;
205}
206
207struct thread_entry * thread_id_entry(unsigned int thread_id)
208{
209 return (thread_id == THREAD_ID_CURRENT) ?
210 cores[CURRENT_CORE].running :
211 &threads[thread_id & THREAD_ID_SLOT_MASK];
212}
213
214static void add_to_list_l(struct thread_entry **list,
215 struct thread_entry *thread)
216{
217 if (*list == NULL)
218 {
219 /* Insert into unoccupied list */
220 thread->l.next = thread;
221 thread->l.prev = thread;
222 *list = thread;
223 }
224 else
225 {
226 /* Insert last */
227 thread->l.next = *list;
228 thread->l.prev = (*list)->l.prev;
229 thread->l.prev->l.next = thread;
230 (*list)->l.prev = thread;
231 }
232}
233
234static void remove_from_list_l(struct thread_entry **list,
235 struct thread_entry *thread)
236{
237 if (thread == thread->l.next)
238 {
239 /* The only item */
240 *list = NULL;
241 return;
242 }
243
244 if (thread == *list)
245 {
246 /* List becomes next item */
247 *list = thread->l.next;
248 }
249
250 /* Fix links to jump over the removed entry. */
251 thread->l.prev->l.next = thread->l.next;
252 thread->l.next->l.prev = thread->l.prev;
253}
254
255unsigned int thread_get_current(void)
256{
257 return cores[CURRENT_CORE].running->id;
258}
259
260void switch_thread(void)
261{
262 struct thread_entry *current = cores[CURRENT_CORE].running;
263
264 enable_irq();
265
266 switch (current->state)
267 {
268 case STATE_RUNNING:
269 {
270 SDL_UnlockMutex(m);
271 /* Any other thread waiting already will get it first */
272 SDL_LockMutex(m);
273 break;
274 } /* STATE_RUNNING: */
275
276 case STATE_BLOCKED:
277 {
278 int oldlevel;
279
280 SDL_UnlockMutex(m);
281 SDL_SemWait(current->context.s);
282 SDL_LockMutex(m);
283
284 oldlevel = disable_irq_save();
285 current->state = STATE_RUNNING;
286 restore_irq(oldlevel);
287 break;
288 } /* STATE_BLOCKED: */
289
290 case STATE_BLOCKED_W_TMO:
291 {
292 int result, oldlevel;
293
294 SDL_UnlockMutex(m);
295 result = SDL_SemWaitTimeout(current->context.s, current->tmo_tick);
296 SDL_LockMutex(m);
297
298 oldlevel = disable_irq_save();
299
300 if (current->state == STATE_BLOCKED_W_TMO)
301 {
302 /* Timed out */
303 remove_from_list_l(current->bqp, current);
304
305#ifdef HAVE_WAKEUP_EXT_CB
306 if (current->wakeup_ext_cb != NULL)
307 current->wakeup_ext_cb(current);
308#endif
309 current->state = STATE_RUNNING;
310 }
311
312 if (result == SDL_MUTEX_TIMEDOUT)
313 {
314 /* Other signals from an explicit wake could have been made before
315 * arriving here if we timed out waiting for the semaphore. Make
316 * sure the count is reset. */
317 while (SDL_SemValue(current->context.s) > 0)
318 SDL_SemTryWait(current->context.s);
319 }
320
321 restore_irq(oldlevel);
322 break;
323 } /* STATE_BLOCKED_W_TMO: */
324
325 case STATE_SLEEPING:
326 {
327 SDL_UnlockMutex(m);
328 SDL_SemWaitTimeout(current->context.s, current->tmo_tick);
329 SDL_LockMutex(m);
330 current->state = STATE_RUNNING;
331 break;
332 } /* STATE_SLEEPING: */
333 }
334
335 cores[CURRENT_CORE].running = current;
336
337 if (threads_exit)
338 thread_exit();
339}
340
341void sleep_thread(int ticks)
342{
343 struct thread_entry *current = cores[CURRENT_CORE].running;
344 int rem;
345
346 current->state = STATE_SLEEPING;
347
348 rem = (SDL_GetTicks() - start_tick) % (1000/HZ);
349 if (rem < 0)
350 rem = 0;
351
352 current->tmo_tick = (1000/HZ) * ticks + ((1000/HZ)-1) - rem;
353}
354
355void block_thread(struct thread_entry *current)
356{
357 current->state = STATE_BLOCKED;
358 add_to_list_l(current->bqp, current);
359}
360
361void block_thread_w_tmo(struct thread_entry *current, int ticks)
362{
363 current->state = STATE_BLOCKED_W_TMO;
364 current->tmo_tick = (1000/HZ)*ticks;
365 add_to_list_l(current->bqp, current);
366}
367
368unsigned int wakeup_thread(struct thread_entry **list)
369{
370 struct thread_entry *thread = *list;
371
372 if (thread != NULL)
373 {
374 switch (thread->state)
375 {
376 case STATE_BLOCKED:
377 case STATE_BLOCKED_W_TMO:
378 remove_from_list_l(list, thread);
379 thread->state = STATE_RUNNING;
380 SDL_SemPost(thread->context.s);
381 return THREAD_OK;
382 }
383 }
384
385 return THREAD_NONE;
386}
387
388unsigned int thread_queue_wake(struct thread_entry **list)
389{
390 unsigned int result = THREAD_NONE;
391
392 for (;;)
393 {
394 unsigned int rc = wakeup_thread(list);
395
396 if (rc == THREAD_NONE)
397 break;
398
399 result |= rc;
400 }
401
402 return result;
403}
404
405void thread_thaw(unsigned int thread_id)
406{
407 struct thread_entry *thread = thread_id_entry(thread_id);
408
409 if (thread->id == thread_id && thread->state == STATE_FROZEN)
410 {
411 thread->state = STATE_RUNNING;
412 SDL_SemPost(thread->context.s);
413 }
414}
415
416int runthread(void *data)
417{
418 struct thread_entry *current;
419 jmp_buf *current_jmpbuf;
420
421 /* Cannot access thread variables before locking the mutex as the
422 data structures may not be filled-in yet. */
423 SDL_LockMutex(m);
424 cores[CURRENT_CORE].running = (struct thread_entry *)data;
425 current = cores[CURRENT_CORE].running;
426 current_jmpbuf = &thread_jmpbufs[current - threads];
427
428 /* Setup jump for exit */
429 if (setjmp(*current_jmpbuf) == 0)
430 {
431 /* Run the thread routine */
432 if (current->state == STATE_FROZEN)
433 {
434 SDL_UnlockMutex(m);
435 SDL_SemWait(current->context.s);
436 SDL_LockMutex(m);
437 cores[CURRENT_CORE].running = current;
438 }
439
440 if (!threads_exit)
441 {
442 current->context.start();
443 THREAD_SDL_DEBUGF("Thread Done: %d (%s)\n",
444 current - threads, THREAD_SDL_GET_NAME(current));
445 /* Thread routine returned - suicide */
446 }
447
448 thread_exit();
449 }
450 else
451 {
452 /* Unlock and exit */
453 SDL_UnlockMutex(m);
454 }
455
456 return 0;
457}
458
459unsigned int create_thread(void (*function)(void),
460 void* stack, size_t stack_size,
461 unsigned flags, const char *name)
462{
463 struct thread_entry *thread;
464 SDL_Thread* t;
465 SDL_sem *s;
466
467 THREAD_SDL_DEBUGF("Creating thread: (%s)\n", name ? name : "");
468
469 thread = find_empty_thread_slot();
470 if (thread == NULL)
471 {
472 DEBUGF("Failed to find thread slot\n");
473 return 0;
474 }
475
476 s = SDL_CreateSemaphore(0);
477 if (s == NULL)
478 {
479 DEBUGF("Failed to create semaphore\n");
480 return 0;
481 }
482
483 t = SDL_CreateThread(runthread, thread);
484 if (t == NULL)
485 {
486 DEBUGF("Failed to create SDL thread\n");
487 SDL_DestroySemaphore(s);
488 return 0;
489 }
490
491 thread->stack = stack;
492 thread->stack_size = stack_size;
493 thread->name = name;
494 thread->state = (flags & CREATE_THREAD_FROZEN) ?
495 STATE_FROZEN : STATE_RUNNING;
496 thread->context.start = function;
497 thread->context.t = t;
498 thread->context.s = s;
499
500 THREAD_SDL_DEBUGF("New Thread: %d (%s)\n",
501 thread - threads, THREAD_SDL_GET_NAME(thread));
502
503 return thread->id;
504}
505
506#ifndef ALLOW_REMOVE_THREAD
507static void remove_thread(unsigned int thread_id)
508#else
509void remove_thread(unsigned int thread_id)
510#endif
511{
512 struct thread_entry *current = cores[CURRENT_CORE].running;
513 struct thread_entry *thread = thread_id_entry(thread_id);
514
515 SDL_Thread *t;
516 SDL_sem *s;
517
518 if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
519 return;
520
521 int oldlevel = disable_irq_save();
522
523 t = thread->context.t;
524 s = thread->context.s;
525 thread->context.t = NULL;
526
527 if (thread != current)
528 {
529 switch (thread->state)
530 {
531 case STATE_BLOCKED:
532 case STATE_BLOCKED_W_TMO:
533 /* Remove thread from object it's waiting on */
534 remove_from_list_l(thread->bqp, thread);
535
536#ifdef HAVE_WAKEUP_EXT_CB
537 if (thread->wakeup_ext_cb != NULL)
538 thread->wakeup_ext_cb(thread);
539#endif
540 break;
541 }
542
543 SDL_SemPost(s);
544 }
545
546 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
547 thread - threads, THREAD_SDL_GET_NAME(thread));
548
549 new_thread_id(thread->id, thread);
550 thread->state = STATE_KILLED;
551 thread_queue_wake(&thread->queue);
552
553 SDL_DestroySemaphore(s);
554
555 if (thread == current)
556 {
557 /* Do a graceful exit - perform the longjmp back into the thread
558 function to return */
559 restore_irq(oldlevel);
560 longjmp(thread_jmpbufs[current - threads], 1);
561 }
562
563 SDL_KillThread(t);
564 restore_irq(oldlevel);
565}
566
567void thread_exit(void)
568{
569 remove_thread(THREAD_ID_CURRENT);
570}
571
572void thread_wait(unsigned int thread_id)
573{
574 struct thread_entry *current = cores[CURRENT_CORE].running;
575 struct thread_entry *thread = thread_id_entry(thread_id);
576
577 if (thread_id == THREAD_ID_CURRENT ||
578 (thread->id == thread_id && thread->state != STATE_KILLED))
579 {
580 current->bqp = &thread->queue;
581 block_thread(current);
582 switch_thread();
583 }
584}
585
586int thread_stack_usage(const struct thread_entry *thread)
587{
588 return 50;
589 (void)thread;
590}
591
592/* Return name if one or ID if none */
593void thread_get_name(char *buffer, int size,
594 struct thread_entry *thread)
595{
596 if (size <= 0)
597 return;
598
599 *buffer = '\0';
600
601 if (thread)
602 {
603 /* Display thread name if one or ID if none */
604 bool named = thread->name && *thread->name;
605 const char *fmt = named ? "%s" : "%08lX";
606 intptr_t name = named ?
607 (intptr_t)thread->name : (intptr_t)thread;
608 snprintf(buffer, size, fmt, name);
609 }
610}
diff --git a/firmware/target/hosted/sdl/thread-sdl.h b/firmware/target/hosted/sdl/thread-sdl.h
new file mode 100644
index 0000000000..9384e6060d
--- /dev/null
+++ b/firmware/target/hosted/sdl/thread-sdl.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Dan Everton
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __THREADSDL_H__
23#define __THREADSDL_H__
24
25/* extra thread functions that only apply when running on hosting platforms */
26void sim_thread_lock(void *me);
27void * sim_thread_unlock(void);
28void sim_thread_exception_wait(void);
29void sim_thread_shutdown(void); /* Shut down all kernel threads gracefully */
30
31#endif /* #ifndef __THREADSDL_H__ */
32
diff --git a/firmware/target/hosted/sdl/timer-sdl.c b/firmware/target/hosted/sdl/timer-sdl.c
new file mode 100644
index 0000000000..369aeab929
--- /dev/null
+++ b/firmware/target/hosted/sdl/timer-sdl.c
@@ -0,0 +1,61 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id: timer.h 13806 2007-07-06 21:36:32Z jethead71 $
9*
10* Copyright (C) 2005 Kévin Ferrare
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version 2
15* of the License, or (at your option) any later version.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21
22#include "timer.h"
23#include <SDL_timer.h>
24
25static int timer_prio = -1;
26void (*global_timer_callback)(void);
27SDL_TimerID timerId;
28
29Uint32 SDL_timer_callback(Uint32 interval, void *param){
30 (void)param;
31 global_timer_callback();
32 return(interval);
33}
34
35#define cycles_to_miliseconds(cycles) \
36 ((int)((1000*cycles)/TIMER_FREQ))
37
38bool timer_register(int reg_prio, void (*unregister_callback)(void),
39 long cycles, void (*timer_callback)(void))
40{
41 (void)unregister_callback;
42 if (reg_prio <= timer_prio || cycles == 0)
43 return false;
44 timer_prio=reg_prio;
45 global_timer_callback=timer_callback;
46 timerId=SDL_AddTimer(cycles_to_miliseconds(cycles), SDL_timer_callback, 0);
47 return true;
48}
49
50bool timer_set_period(long cycles)
51{
52 SDL_RemoveTimer (timerId);
53 timerId=SDL_AddTimer(cycles_to_miliseconds(cycles), SDL_timer_callback, 0);
54 return true;
55}
56
57void timer_unregister(void)
58{
59 SDL_RemoveTimer (timerId);
60 timer_prio = -1;
61}