summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Rothen <rothen@gmx.net>2014-08-30 13:15:53 +0200
committerMichael Giacomelli <giac2000@hotmail.com>2014-09-18 18:19:01 +0200
commit0b5ad60c26f30dc5363c21e436b73292c09ac567 (patch)
tree2d7cee2b2133218d59e0f462c9dbdbec8e88b2e2
parent1f0fa0546647a191c52784a4a225982ffbd1af11 (diff)
downloadrockbox-0b5ad60c26f30dc5363c21e436b73292c09ac567.tar.gz
rockbox-0b5ad60c26f30dc5363c21e436b73292c09ac567.zip
Introducing Targets iBasso DX50 & iBasso DX90
The port to for this two targets has been entirely developped by Ilia Sergachev (alias Il or xzcc). His source can be found at https://bitbucket.org/isergachev/rockbox . The few necesary modifications for the DX90 port was done by headwhacker form head-fi.org. Unfortunately i could not try out the final state of the DX90 port. The port is hosted on android (without java) as standalone app. The official Firmware is required to run this port. Ilia did modify the source files for the "android" target in the rockbox source to make the DX port work. The work I did was to separate the code for DX50 (&DX90) from the android target. On this Target Ilia used source from tinyalsa from AOSP. I did not touch that part of the code because I do not understand it. What else I changed from Ilias sources besides the separation from the target "android": * removed a dirty hack to keep backlight off * changed value battery meter to voltage battery meter * made all plugins compile (named target as "standalone") and added keymaps * i added the graphics for the manual but did not do anything else for the manual yet * minor optimizations known bugs: * timers are slowed donw when playback is active (tinyalsa related?) * some minor bugs Things to do: * The main prolem will be how to install the app correctly. A guy called DOC2008 added a CWM (by androtab.info) to the official firmware and Ilia made a CWM installation script and a dualboot selector (rbutils/ibassoboot, build with ndk-build). We will have to find a way to install rockbox in a proper way without breaking any copyrights. Maybe ADB is an option but it is not enable with OF by default. Patching the OF is probably the way to go. * All the wiki and manual to build: needed: android ndk installed, android sdk installed with additional build-tools 19.1.0 installed ./tools/configure select iBasso DX50 or iBasso DX90 make -j apk the content of rockbox.zip/.rockbox needs to be copied to /system/rockbox/app_rockbox/rockbox/ (rockbox app not needed) the content of libs/armeabi to /system/rockbox/lib/ (rockbox app needed) The boot selector is needed as /system/bin/MangoPlayer and the iBasso app as /system/bin/MangoPlayer_original. There is also the "vold" file. The one from OF does not work with DX50 rockbox (DX90 works!?), the one from Ilia is necessary. Until we have found a proper way to install it, it can only be installed following the instructions of Ilia on his bitbucket page, using the CWM-OF and his installation script package. Change-Id: Ic4faaf84824c162aabcc08e492cee6e0068719d0 Reviewed-on: http://gerrit.rockbox.org/941 Tested: Chiwen Chang <rock1104.tw@yahoo.com.tw> Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
-rw-r--r--apps/SOURCES6
-rw-r--r--apps/keymaps/keymap-dx50.c219
-rw-r--r--apps/main.c2
-rw-r--r--apps/plugins/battery_bench.c6
-rw-r--r--apps/plugins/blackjack.c14
-rw-r--r--apps/plugins/brickmania.c7
-rw-r--r--apps/plugins/calculator.c3
-rw-r--r--apps/plugins/calendar.c10
-rw-r--r--apps/plugins/chessbox/chessbox_pgn.h13
-rw-r--r--apps/plugins/chessclock.c9
-rw-r--r--apps/plugins/chip8.c3
-rw-r--r--apps/plugins/clix.c3
-rw-r--r--apps/plugins/cube.c8
-rw-r--r--apps/plugins/doom/i_video.c6
-rw-r--r--apps/plugins/fft/fft.c5
-rw-r--r--apps/plugins/flipit.c12
-rw-r--r--apps/plugins/fractals/fractal.h3
-rw-r--r--apps/plugins/goban/goban.h3
-rw-r--r--apps/plugins/imageviewer/imageviewer_button.h8
-rw-r--r--apps/plugins/invadrox.c7
-rw-r--r--apps/plugins/jewels.c4
-rw-r--r--apps/plugins/lib/pluginlib_actions.c7
-rw-r--r--apps/plugins/midi/midiplay.c7
-rw-r--r--apps/plugins/minesweeper.c3
-rw-r--r--apps/plugins/mp3_encoder.c5
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c8
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c9
-rw-r--r--apps/plugins/oscilloscope.c5
-rw-r--r--apps/plugins/pacbox/pacbox.h3
-rw-r--r--apps/plugins/pegbox.c5
-rw-r--r--apps/plugins/plugins.make4
-rw-r--r--apps/plugins/pong.c3
-rw-r--r--apps/plugins/reversi/reversi-gui.h4
-rw-r--r--apps/plugins/rockblox.c8
-rw-r--r--apps/plugins/rockboy/rockboy.c9
-rw-r--r--apps/plugins/rockpaint.c3
-rw-r--r--apps/plugins/sliding_puzzle.c6
-rw-r--r--apps/plugins/snake.c8
-rw-r--r--apps/plugins/snake2.c9
-rw-r--r--apps/plugins/sokoban.c8
-rw-r--r--apps/plugins/solitaire.c3
-rw-r--r--apps/plugins/spacerocks.c8
-rw-r--r--apps/plugins/star.c4
-rw-r--r--apps/plugins/sudoku/sudoku.h3
-rw-r--r--apps/plugins/text_viewer/tv_button.h10
-rw-r--r--apps/plugins/vu_meter.c8
-rw-r--r--apps/plugins/wormlet.c9
-rw-r--r--apps/plugins/xobox.c8
-rw-r--r--apps/plugins/zxbox/keymaps.h8
-rw-r--r--apps/root_menu.c4
-rw-r--r--firmware/SOURCES18
-rw-r--r--firmware/asm/SOURCES2
-rw-r--r--firmware/asm/arm/thread.h4
-rw-r--r--firmware/drivers/audio/android.c24
-rw-r--r--firmware/drivers/touchscreen.c2
-rw-r--r--firmware/export/config.h5
-rw-r--r--firmware/export/config/ibassodx50.h136
-rw-r--r--firmware/export/config/ibassodx90.h136
-rw-r--r--firmware/export/hosted_codec.h4
-rw-r--r--firmware/powermgmt.c2
-rw-r--r--firmware/target/hosted/android/dx50/adc-target.h0
-rw-r--r--firmware/target/hosted/android/dx50/backlight-dx50.c76
-rw-r--r--firmware/target/hosted/android/dx50/backlight-target.h31
-rw-r--r--firmware/target/hosted/android/dx50/button-dx50.c314
-rw-r--r--firmware/target/hosted/android/dx50/button-target.h72
-rw-r--r--firmware/target/hosted/android/dx50/lcd-dx50.c120
-rw-r--r--firmware/target/hosted/android/dx50/lcd-target.h29
-rw-r--r--firmware/target/hosted/android/dx50/pcm-dx50.c364
-rw-r--r--firmware/target/hosted/android/dx50/powermgmt-dx50.c72
-rw-r--r--firmware/target/hosted/android/dx50/tinyalsa/asound.h821
-rw-r--r--firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h257
-rw-r--r--firmware/target/hosted/android/dx50/tinyalsa/mixer.c497
-rw-r--r--firmware/target/hosted/android/dx50/tinyalsa/pcm.c973
-rw-r--r--firmware/target/hosted/android/system-android.c54
-rw-r--r--firmware/target/hosted/filesystem-app.c1
-rw-r--r--manual/rockbox_interface/images/ibassodx50-front.pdfbin0 -> 41904 bytes
-rw-r--r--manual/rockbox_interface/images/ibassodx50-front.pngbin0 -> 32802 bytes
-rw-r--r--manual/rockbox_interface/images/ibassodx50-front.svg1966
-rw-r--r--rbutil/ibassoboot/jni/Android.mk6
-rw-r--r--rbutil/ibassoboot/jni/chooser.bmpbin0 -> 230454 bytes
-rw-r--r--rbutil/ibassoboot/jni/ibassodualboot.c439
-rw-r--r--rbutil/ibassoboot/jni/qdbmp.c798
-rw-r--r--rbutil/ibassoboot/jni/qdbmp.h133
-rwxr-xr-xtools/configure80
84 files changed, 7939 insertions, 27 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 1aa4955205..6118438b40 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -100,7 +100,7 @@ gui/statusbar.c
100#ifdef HAVE_LCD_BITMAP 100#ifdef HAVE_LCD_BITMAP
101gui/statusbar-skinned.c 101gui/statusbar-skinned.c
102#endif 102#endif
103#if (CONFIG_PLATFORM&PLATFORM_ANDROID) 103#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined (DX50) && !defined(DX90)
104hosted/android/yesno.c 104hosted/android/yesno.c
105hosted/android/notification.c 105hosted/android/notification.c
106#else 106#else
@@ -129,7 +129,7 @@ player/keyboard.c
129#ifdef HAVE_LCD_BITMAP 129#ifdef HAVE_LCD_BITMAP
130recorder/bmp.c 130recorder/bmp.c
131recorder/icons.c 131recorder/icons.c
132#if (CONFIG_PLATFORM&PLATFORM_ANDROID) 132#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined (DX50) && !defined(DX90)
133hosted/android/keyboard.c 133hosted/android/keyboard.c
134#else 134#else
135recorder/keyboard.c 135recorder/keyboard.c
@@ -305,4 +305,6 @@ keymaps/keymap-ypz5.c
305keymaps/keymap-ihifi.c 305keymaps/keymap-ihifi.c
306#elif CONFIG_KEYPAD == SAMSUNG_YPR1_PAD 306#elif CONFIG_KEYPAD == SAMSUNG_YPR1_PAD
307keymaps/keymap-ypr1.c 307keymaps/keymap-ypr1.c
308#elif CONFIG_KEYPAD == DX50_PAD
309keymaps/keymap-dx50.c
308#endif 310#endif
diff --git a/apps/keymaps/keymap-dx50.c b/apps/keymaps/keymap-dx50.c
new file mode 100644
index 0000000000..ee3b32005a
--- /dev/null
+++ b/apps/keymaps/keymap-dx50.c
@@ -0,0 +1,219 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Maurus Cuelenaere
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/* Button Code Definitions for iBasso DX50 & DX90 */
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27
28#include "config.h"
29#include "action.h"
30#include "button.h"
31#include "settings.h"
32
33/*
34 * The format of the list is as follows
35 * { Action Code, Button code, Prereq button code }
36 * if there's no need to check the previous button's value, use BUTTON_NONE
37 * Insert LAST_ITEM_IN_LIST at the end of each mapping
38 */
39
40static const struct button_mapping button_context_standard[] = {
41 { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
42 { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
43 { ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
44 { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
45 { ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
46 { ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
47 { ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
48
49 LAST_ITEM_IN_LIST
50}; /* button_context_standard */
51
52static const struct button_mapping button_context_wps[] = {
53 { ACTION_WPS_MENU, BUTTON_POWER, BUTTON_NONE },
54 { ACTION_WPS_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
55 { ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE },
56 { ACTION_WPS_SKIPNEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
57 { ACTION_WPS_SKIPPREV, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE },
58 { ACTION_WPS_SEEKBACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
59 { ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
60 { ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT },
61 { ACTION_WPS_STOPSEEK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT },
62 { ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
63 { ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
64 { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
65 { ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
66 LAST_ITEM_IN_LIST
67}; /* button_context_wps */
68
69static const struct button_mapping button_context_list[] = {
70#ifdef HAVE_VOLUME_IN_LIST
71 { ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
72 { ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
73 { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
74 { ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
75#endif
76 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
77}; /* button_context_list */
78
79static const struct button_mapping button_context_tree[] = {
80
81 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
82}; /* button_context_tree */
83
84static const struct button_mapping button_context_listtree_scroll_with_combo[] = {
85 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
86};
87
88static const struct button_mapping button_context_listtree_scroll_without_combo[] = {
89 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE),
90};
91
92static const struct button_mapping button_context_settings[] = {
93 { ACTION_SETTINGS_INC, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
94 { ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
95 { ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
96 { ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
97 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
98}; /* button_context_settings */
99
100static const struct button_mapping button_context_settings_right_is_inc[] = {
101
102 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
103}; /* button_context_settingsgraphical */
104
105static const struct button_mapping button_context_mainmenu[] = {
106
107 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_TREE),
108}; /* button_context_mainmenu */
109
110static const struct button_mapping button_context_yesno[] = {
111 { ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
112
113 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
114}; /* button_context_settings_yesno */
115
116static const struct button_mapping button_context_colorchooser[] = {
117 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
118}; /* button_context_colorchooser */
119
120static const struct button_mapping button_context_eq[] = {
121 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
122}; /* button_context_eq */
123
124static const struct button_mapping button_context_keyboard[] = {
125 { ACTION_KBD_LEFT, BUTTON_LEFT, BUTTON_NONE },
126 { ACTION_KBD_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
127 { ACTION_KBD_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
128 { ACTION_KBD_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
129
130 { ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY|BUTTON_LEFT, BUTTON_NONE },
131 { ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY|BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
132 { ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY|BUTTON_RIGHT, BUTTON_NONE },
133 { ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
134 { ACTION_KBD_SELECT, BUTTON_PLAY, BUTTON_NONE },
135
136 { ACTION_KBD_UP, BUTTON_VOL_UP, BUTTON_NONE },
137 { ACTION_KBD_UP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
138 { ACTION_KBD_DOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
139 { ACTION_KBD_DOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
140
141 LAST_ITEM_IN_LIST
142}; /* button_context_keyboard */
143
144/** Bookmark Screen **/
145static const struct button_mapping button_context_bmark[] = {
146 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
147}; /* button_context_bmark */
148
149static const struct button_mapping button_context_time[] = {
150 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
151}; /* button_context_time */
152
153static const struct button_mapping button_context_quickscreen[] = {
154 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
155}; /* button_context_quickscreen */
156
157static const struct button_mapping button_context_pitchscreen[] = {
158
159 { ACTION_PS_INC_SMALL, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
160 { ACTION_PS_DEC_SMALL, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
161 { ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE },
162
163 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
164}; /* button_context_pitchcreen */
165
166
167static const struct button_mapping button_context_radio[] = {
168 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
169}; /* button_context_radio */
170
171const struct button_mapping* target_get_context_mapping(int context)
172{
173 switch (context)
174 {
175 case CONTEXT_STD:
176 return button_context_standard;
177 case CONTEXT_WPS:
178 return button_context_wps;
179
180 case CONTEXT_LIST:
181 return button_context_list;
182 case CONTEXT_MAINMENU:
183 return button_context_mainmenu;
184 case CONTEXT_TREE:
185 if (global_settings.hold_lr_for_scroll_in_list)
186 return button_context_listtree_scroll_without_combo;
187 else
188 return button_context_listtree_scroll_with_combo;
189 case CONTEXT_CUSTOM|CONTEXT_TREE:
190 return button_context_tree;
191
192 case CONTEXT_SETTINGS:
193 return button_context_settings;
194 case CONTEXT_CUSTOM|CONTEXT_SETTINGS:
195 case CONTEXT_SETTINGS_RECTRIGGER:
196 return button_context_settings_right_is_inc;
197
198 case CONTEXT_SETTINGS_COLOURCHOOSER:
199 return button_context_colorchooser;
200 case CONTEXT_SETTINGS_EQ:
201 return button_context_eq;
202
203 case CONTEXT_SETTINGS_TIME:
204 return button_context_time;
205
206 case CONTEXT_KEYBOARD:
207 return button_context_keyboard;
208
209 case CONTEXT_FM:
210 return button_context_radio;
211 case CONTEXT_BOOKMARKSCREEN:
212 return button_context_bmark;
213 case CONTEXT_QUICKSCREEN:
214 return button_context_quickscreen;
215 case CONTEXT_PITCHSCREEN:
216 return button_context_pitchscreen;
217 }
218 return button_context_standard;
219}
diff --git a/apps/main.c b/apps/main.c
index 9098180fb8..60164515fa 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -340,7 +340,7 @@ static void init(void)
340#ifdef SIMULATOR 340#ifdef SIMULATOR
341 sim_tasks_init(); 341 sim_tasks_init();
342#endif 342#endif
343#if (CONFIG_PLATFORM & PLATFORM_ANDROID) 343#if (CONFIG_PLATFORM & PLATFORM_ANDROID) && !defined(DX50) && !defined(DX90)
344 notification_init(); 344 notification_init();
345#endif 345#endif
346 lang_init(core_language_builtin, language_strings, 346 lang_init(core_language_builtin, language_strings,
diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c
index 930d56f29a..b0976d5e10 100644
--- a/apps/plugins/battery_bench.c
+++ b/apps/plugins/battery_bench.c
@@ -261,6 +261,12 @@
261#define BATTERY_ON_TXT "PLAY - start" 261#define BATTERY_ON_TXT "PLAY - start"
262#define BATTERY_OFF_TXT "Power" 262#define BATTERY_OFF_TXT "Power"
263 263
264#elif CONFIG_KEYPAD == DX50_PAD
265#define BATTERY_ON BUTTON_PLAY
266#define BATTERY_OFF BUTTON_POWER
267#define BATTERY_OFF_TXT "POWER"
268#define BATTERY_ON_TXT "PLAY - start"
269
264#else 270#else
265#error No keymap defined! 271#error No keymap defined!
266#endif 272#endif
diff --git a/apps/plugins/blackjack.c b/apps/plugins/blackjack.c
index 2211f88620..4022696a1f 100644
--- a/apps/plugins/blackjack.c
+++ b/apps/plugins/blackjack.c
@@ -541,6 +541,20 @@ enum {
541#define BJACK_QUIT_NAME "Back" 541#define BJACK_QUIT_NAME "Back"
542#define BJACK_DOUBLE_NAME "Shortcut" 542#define BJACK_DOUBLE_NAME "Shortcut"
543 543
544#elif CONFIG_KEYPAD == DX50_PAD
545#define BJACK_QUIT BUTTON_POWER
546#define BJACK_DOUBLEDOWN BUTTON_RIGHT
547#define BJACK_SELECT BUTTON_PLAY
548#define BJACK_QUIT BUTTON_POWER
549#define BJACK_STAY BUTTON_LEFT
550#define BJACK_UP BUTTON_VOL_UP
551#define BJACK_DOWN BUTTON_VOL_DOWN
552#define BJACK_LEFT BUTTON_LEFT
553#define BJACK_SELECT_NAME "Play"
554#define BJACK_STAY_NAME "Left"
555#define BJACK_QUIT_NAME "Power"
556#define BJACK_DOUBLE_NAME "Right"
557
544#else 558#else
545#error No keymap defined! 559#error No keymap defined!
546#endif 560#endif
diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c
index ee72e0bf37..0c9223d398 100644
--- a/apps/plugins/brickmania.c
+++ b/apps/plugins/brickmania.c
@@ -311,6 +311,13 @@ CONFIG_KEYPAD == SANSA_CONNECT_PAD
311#define UP BUTTON_UP 311#define UP BUTTON_UP
312#define DOWN BUTTON_DOWN 312#define DOWN BUTTON_DOWN
313 313
314#elif CONFIG_KEYPAD == DX50_PAD
315#define QUIT BUTTON_POWER
316#define LEFT BUTTON_LEFT
317#define RIGHT BUTTON_RIGHT
318#define SELECT BUTTON_PLAY
319#define UP BUTTON_VOL_UP
320#define DOWN BUTTON_VOL_DOWN
314 321
315#else 322#else
316#error No keymap defined! 323#error No keymap defined!
diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c
index 6c75595f9e..c378ecbb81 100644
--- a/apps/plugins/calculator.c
+++ b/apps/plugins/calculator.c
@@ -497,6 +497,9 @@ F3: equal to "="
497#define CALCULATOR_CALC BUTTON_PLAYPAUSE 497#define CALCULATOR_CALC BUTTON_PLAYPAUSE
498#define CALCULATOR_CLEAR BUTTON_SHORTCUT 498#define CALCULATOR_CLEAR BUTTON_SHORTCUT
499 499
500#elif CONFIG_KEYPAD == DX50_PAD
501#define CALCULATOR_QUIT BUTTON_POWER
502
500#else 503#else
501#error No keymap defined! 504#error No keymap defined!
502#endif 505#endif
diff --git a/apps/plugins/calendar.c b/apps/plugins/calendar.c
index 2e0577fc73..91613fcf88 100644
--- a/apps/plugins/calendar.c
+++ b/apps/plugins/calendar.c
@@ -369,6 +369,16 @@
369#define CALENDAR_NEXT_MONTH BUTTON_SHORTCUT 369#define CALENDAR_NEXT_MONTH BUTTON_SHORTCUT
370#define CALENDAR_PREV_MONTH BUTTON_MENU 370#define CALENDAR_PREV_MONTH BUTTON_MENU
371 371
372#elif CONFIG_KEYPAD == DX50_PAD
373#define CALENDAR_QUIT (BUTTON_POWER|BUTTON_REL)
374#define CALENDAR_SELECT BUTTON_PLAY
375#define CALENDAR_NEXT_WEEK BUTTON_VOL_DOWN
376#define CALENDAR_PREV_WEEK BUTTON_VOL_UP
377#define CALENDAR_NEXT_DAY BUTTON_RIGHT
378#define CALENDAR_PREV_DAY BUTTON_LEFT
379#define CALENDAR_NEXT_MONTH BUTTON_BOTTOMRIGHT
380#define CALENDAR_PREV_MONTH BUTTON_BOTTOMLEFT
381
372#else 382#else
373#error "No keypad setting." 383#error "No keypad setting."
374#endif 384#endif
diff --git a/apps/plugins/chessbox/chessbox_pgn.h b/apps/plugins/chessbox/chessbox_pgn.h
index c7aca0f939..df6a01c891 100644
--- a/apps/plugins/chessbox/chessbox_pgn.h
+++ b/apps/plugins/chessbox/chessbox_pgn.h
@@ -485,6 +485,19 @@
485#define CB_MENU BUTTON_MENU 485#define CB_MENU BUTTON_MENU
486#define CB_LEVEL BUTTON_BACK 486#define CB_LEVEL BUTTON_BACK
487 487
488#elif CONFIG_KEYPAD == DX50_PAD
489#define CB_SELECT BUTTON_PLAY
490#define CB_UP BUTTON_VOL_UP
491#define CB_DOWN BUTTON_VOL_DOWN
492#define CB_LEFT BUTTON_LEFT
493#define CB_RIGHT BUTTON_RIGHT
494#define CB_PLAY (BUTTON_PLAY|BUTTON_REPEAT)
495#define CB_MENU BUTTON_POWER
496#define CB_SCROLL_UP (BUTTON_VOL_UP|BUTTON_REPEAT)
497#define CB_SCROLL_DOWN (BUTTON_VOL_DOWN|BUTTON_REPEAT)
498#define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT)
499#define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT)
500
488#else 501#else
489#error No keymap defined! 502#error No keymap defined!
490#endif 503#endif
diff --git a/apps/plugins/chessclock.c b/apps/plugins/chessclock.c
index cacfbbe939..01895d20f8 100644
--- a/apps/plugins/chessclock.c
+++ b/apps/plugins/chessclock.c
@@ -387,6 +387,15 @@
387#define CHC_SETTINGS_OK BUTTON_SELECT 387#define CHC_SETTINGS_OK BUTTON_SELECT
388#define CHC_SETTINGS_CANCEL BUTTON_BACK 388#define CHC_SETTINGS_CANCEL BUTTON_BACK
389 389
390#elif CONFIG_KEYPAD == DX50_PAD
391#define CHC_QUIT (BUTTON_POWER|BUTTON_REPEAT)
392#define CHC_RESET (BUTTON_PLAY|BUTTON_REPEAT)
393#define CHC_MENU BUTTON_RIGHT
394#define CHC_STARTSTOP BUTTON_PLAY
395#define CHC_SETTINGS_INC BUTTON_VOL_UP
396#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN
397#define CHC_SETTINGS_CANCEL BUTTON_RIGHT
398
390#else 399#else
391#error No keymap defined! 400#error No keymap defined!
392#endif 401#endif
diff --git a/apps/plugins/chip8.c b/apps/plugins/chip8.c
index d1a8285ace..efb62eb27e 100644
--- a/apps/plugins/chip8.c
+++ b/apps/plugins/chip8.c
@@ -1259,6 +1259,9 @@ CONFIG_KEYPAD == MROBE500_PAD
1259#define CHIP8_KEY8 BUTTON_PLAY 1259#define CHIP8_KEY8 BUTTON_PLAY
1260#define CHIP8_KEY9 BUTTON_POWER 1260#define CHIP8_KEY9 BUTTON_POWER
1261 1261
1262#elif (CONFIG_KEYPAD == DX50_PAD)
1263#define CHIP8_OFF BUTTON_POWER
1264
1262#else 1265#else
1263#error No keymap defined! 1266#error No keymap defined!
1264#endif 1267#endif
diff --git a/apps/plugins/clix.c b/apps/plugins/clix.c
index c204663cf5..ffbb01abb8 100644
--- a/apps/plugins/clix.c
+++ b/apps/plugins/clix.c
@@ -253,6 +253,9 @@
253#elif (CONFIG_KEYPAD == SAMSUNG_YPR1_PAD) 253#elif (CONFIG_KEYPAD == SAMSUNG_YPR1_PAD)
254#define CLIX_BUTTON_QUIT BUTTON_POWER 254#define CLIX_BUTTON_QUIT BUTTON_POWER
255 255
256#elif (CONFIG_KEYPAD == DX50_PAD)
257#define CLIX_BUTTON_QUIT BUTTON_POWER
258
256#else 259#else
257#error "no keymap" 260#error "no keymap"
258#endif 261#endif
diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c
index 5331d531db..09993204cd 100644
--- a/apps/plugins/cube.c
+++ b/apps/plugins/cube.c
@@ -390,6 +390,14 @@
390#define CUBE_PAUSE BUTTON_PLAYPAUSE 390#define CUBE_PAUSE BUTTON_PLAYPAUSE
391#define CUBE_HIGHSPEED BUTTON_SHORTCUT 391#define CUBE_HIGHSPEED BUTTON_SHORTCUT
392 392
393#elif (CONFIG_KEYPAD == DX50_PAD)
394#define CUBE_QUIT (BUTTON_POWER|BUTTON_REL)
395#define CUBE_NEXT BUTTON_RIGHT
396#define CUBE_PREV BUTTON_LEFT
397#define CUBE_INC BUTTON_VOL_UP
398#define CUBE_DEC BUTTON_VOL_DOWN
399#define CUBE_MODE BUTTON_PLAY
400
393#else 401#else
394#error No keymap defined! 402#error No keymap defined!
395#endif 403#endif
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index c285215e50..11aa712d33 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -523,6 +523,12 @@ void I_ShutdownGraphics(void)
523#define DOOMBUTTON_WEAPON BUTTON_SHORTCUT 523#define DOOMBUTTON_WEAPON BUTTON_SHORTCUT
524#define DOOMBUTTON_MAP BUTTON_MENU 524#define DOOMBUTTON_MAP BUTTON_MENU
525 525
526#elif CONFIG_KEYPAD == DX50_PAD
527#define DOOMBUTTON_ESC BUTTON_POWER
528#define DOOMBUTTON_SHOOT BUTTON_VOL_UP
529#define DOOMBUTTON_WEAPON BUTTON_VOL_DOWN
530#define DOOMBUTTON_MAP BUTTON_PLAY
531
526#else 532#else
527#error Keymap not defined! 533#error Keymap not defined!
528#endif 534#endif
diff --git a/apps/plugins/fft/fft.c b/apps/plugins/fft/fft.c
index d4b79b2ea7..9871c31eb9 100644
--- a/apps/plugins/fft/fft.c
+++ b/apps/plugins/fft/fft.c
@@ -320,6 +320,11 @@ GREY_INFO_STRUCT
320# define FFT_ORIENTATION BUTTON_SELECT 320# define FFT_ORIENTATION BUTTON_SELECT
321# define FFT_WINDOW BUTTON_MENU 321# define FFT_WINDOW BUTTON_MENU
322 322
323#elif (CONFIG_KEYPAD == DX50_PAD)
324# define FFT_QUIT (BUTTON_POWER|BUTTON_REL)
325# define FFT_PREV_GRAPH BUTTON_VOL_UP
326# define FFT_NEXT_GRAPH BUTTON_VOL_DOWN
327
323#elif !defined(HAVE_TOUCHSCREEN) 328#elif !defined(HAVE_TOUCHSCREEN)
324#error No keymap defined! 329#error No keymap defined!
325#endif 330#endif
diff --git a/apps/plugins/flipit.c b/apps/plugins/flipit.c
index 6274af4f1d..d3dc98aa54 100644
--- a/apps/plugins/flipit.c
+++ b/apps/plugins/flipit.c
@@ -453,6 +453,18 @@
453#define FLIPIT_STEP_BY_STEP BUTTON_PLAY 453#define FLIPIT_STEP_BY_STEP BUTTON_PLAY
454#define FLIPIT_TOGGLE BUTTON_SELECT 454#define FLIPIT_TOGGLE BUTTON_SELECT
455 455
456#elif CONFIG_KEYPAD == DX50_PAD
457
458#define FLIPIT_LEFT BUTTON_LEFT
459#define FLIPIT_RIGHT BUTTON_RIGHT
460#define FLIPIT_UP BUTTON_VOL_UP
461#define FLIPIT_DOWN BUTTON_VOL_DOWN
462#define FLIPIT_QUIT (BUTTON_POWER|BUTTON_REL)
463#define FLIPIT_SHUFFLE (BUTTON_VOL_UP|BUTTON_POWER)
464#define FLIPIT_SOLVE (BUTTON_VOL_DOWN|BUTTON_POWER)
465#define FLIPIT_STEP_BY_STEP (BUTTON_LEFT|BUTTON_POWER)
466#define FLIPIT_TOGGLE BUTTON_PLAY
467
456#else 468#else
457#error No keymap defined! 469#error No keymap defined!
458#endif 470#endif
diff --git a/apps/plugins/fractals/fractal.h b/apps/plugins/fractals/fractal.h
index b5ab0d31c9..7e13657595 100644
--- a/apps/plugins/fractals/fractal.h
+++ b/apps/plugins/fractals/fractal.h
@@ -451,6 +451,9 @@
451#define FRACTAL_PRECISION_DEC (BUTTON_POWER|BUTTON_MENU) 451#define FRACTAL_PRECISION_DEC (BUTTON_POWER|BUTTON_MENU)
452#define FRACTAL_RESET BUTTON_SHORTCUT 452#define FRACTAL_RESET BUTTON_SHORTCUT
453 453
454#elif CONFIG_KEYPAD == DX50_PAD
455#define FRACTAL_QUIT (BUTTON_POWER|BUTTON_REL)
456
454#else 457#else
455#error No keymap defined! 458#error No keymap defined!
456#endif 459#endif
diff --git a/apps/plugins/goban/goban.h b/apps/plugins/goban/goban.h
index c709df3281..531b137556 100644
--- a/apps/plugins/goban/goban.h
+++ b/apps/plugins/goban/goban.h
@@ -432,6 +432,9 @@
432#define GBN_BUTTON_CONTEXT BUTTON_PLAY 432#define GBN_BUTTON_CONTEXT BUTTON_PLAY
433#define GBN_BUTTON_NEXT_VAR BUTTON_NEXT 433#define GBN_BUTTON_NEXT_VAR BUTTON_NEXT
434 434
435#elif (CONFIG_KEYPAD == DX50_PAD)
436#define GBN_BUTTON_MENU (BUTTON_POWER|BUTTON_REL)
437
435#else 438#else
436#error Unsupported keypad 439#error Unsupported keypad
437#endif 440#endif
diff --git a/apps/plugins/imageviewer/imageviewer_button.h b/apps/plugins/imageviewer/imageviewer_button.h
index dd3b35041f..c5fb9730c1 100644
--- a/apps/plugins/imageviewer/imageviewer_button.h
+++ b/apps/plugins/imageviewer/imageviewer_button.h
@@ -452,6 +452,14 @@
452#define IMGVIEW_PREVIOUS BUTTON_BACK 452#define IMGVIEW_PREVIOUS BUTTON_BACK
453#define IMGVIEW_MENU BUTTON_MENU 453#define IMGVIEW_MENU BUTTON_MENU
454 454
455#elif CONFIG_KEYPAD == DX50_PAD
456#define IMGVIEW_ZOOM_IN BUTTON_VOL_UP
457#define IMGVIEW_ZOOM_OUT BUTTON_VOL_DOWN
458#define IMGVIEW_NEXT BUTTON_RIGHT
459#define IMGVIEW_PREVIOUS BUTTON_LEFT
460#define IMGVIEW_QUIT (BUTTON_POWER|BUTTON_REL)
461#define IMGVIEW_MENU (BUTTON_PLAY|BUTTON_REL)
462
455#else 463#else
456#error No keymap defined! 464#error No keymap defined!
457#endif 465#endif
diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c
index e77fe1e4a6..c1da3a6338 100644
--- a/apps/plugins/invadrox.c
+++ b/apps/plugins/invadrox.c
@@ -259,6 +259,13 @@ CONFIG_KEYPAD == MROBE500_PAD
259#define RIGHT BUTTON_RIGHT 259#define RIGHT BUTTON_RIGHT
260#define FIRE BUTTON_SELECT 260#define FIRE BUTTON_SELECT
261 261
262#elif CONFIG_KEYPAD == DX50_PAD
263
264#define QUIT (BUTTON_POWER|BUTTON_REL)
265#define LEFT BUTTON_LEFT
266#define RIGHT BUTTON_PLAY
267#define FIRE BUTTON_RIGHT
268
262#else 269#else
263 #error INVADROX: Unsupported keypad 270 #error INVADROX: Unsupported keypad
264#endif 271#endif
diff --git a/apps/plugins/jewels.c b/apps/plugins/jewels.c
index b4c53a96c4..d8a3cc39b5 100644
--- a/apps/plugins/jewels.c
+++ b/apps/plugins/jewels.c
@@ -359,6 +359,10 @@ CONFIG_KEYPAD == MROBE500_PAD
359#define HK_SELECT "SELECT" 359#define HK_SELECT "SELECT"
360#define HK_CANCEL "POWER" 360#define HK_CANCEL "POWER"
361 361
362#elif CONFIG_KEYPAD == DX50_PAD
363#define JEWELS_CANCEL BUTTON_POWER
364#define HK_CANCEL "Power"
365
362#else 366#else
363#error No keymap defined! 367#error No keymap defined!
364#endif 368#endif
diff --git a/apps/plugins/lib/pluginlib_actions.c b/apps/plugins/lib/pluginlib_actions.c
index 97dde57fbe..3113f64667 100644
--- a/apps/plugins/lib/pluginlib_actions.c
+++ b/apps/plugins/lib/pluginlib_actions.c
@@ -434,6 +434,13 @@ const struct button_mapping pla_main_ctx[] =
434 {PLA_SELECT, BUTTON_PLAY, BUTTON_NONE}, 434 {PLA_SELECT, BUTTON_PLAY, BUTTON_NONE},
435 {PLA_SELECT_REL, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY}, 435 {PLA_SELECT_REL, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY},
436 {PLA_SELECT_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, 436 {PLA_SELECT_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE},
437#elif (CONFIG_KEYPAD == DX50_PAD)
438 {PLA_CANCEL, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE},
439 {PLA_EXIT, BUTTON_POWER|BUTTON_REL, BUTTON_NONE},
440 {PLA_SELECT, BUTTON_PLAY, BUTTON_NONE},
441 {PLA_SELECT_REL, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE},
442 {PLA_SELECT_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE},
443
437#else 444#else
438# ifndef HAVE_TOUCHSCREEN 445# ifndef HAVE_TOUCHSCREEN
439# error pluginlib_actions: No actions defined 446# error pluginlib_actions: No actions defined
diff --git a/apps/plugins/midi/midiplay.c b/apps/plugins/midi/midiplay.c
index f5edc83f9a..2f4a698fad 100644
--- a/apps/plugins/midi/midiplay.c
+++ b/apps/plugins/midi/midiplay.c
@@ -275,6 +275,13 @@
275#define BTN_DOWN BUTTON_DOWN 275#define BTN_DOWN BUTTON_DOWN
276#define BTN_PLAY BUTTON_PLAYPAUSE 276#define BTN_PLAY BUTTON_PLAYPAUSE
277 277
278#elif CONFIG_KEYPAD == DX50_PAD
279#define BTN_QUIT BUTTON_POWER
280#define BTN_RIGHT BUTTON_RIGHT
281#define BTN_LEFT BUTTON_LEFT
282#define BTN_UP BUTTON_VOL_UP
283#define BTN_DOWN BUTTON_VOL_DOWN
284
278#else 285#else
279#error No keymap defined! 286#error No keymap defined!
280#endif 287#endif
diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c
index 4758a1f911..982bb8b67c 100644
--- a/apps/plugins/minesweeper.c
+++ b/apps/plugins/minesweeper.c
@@ -377,6 +377,9 @@ CONFIG_KEYPAD == MROBE500_PAD
377#define MINESWP_DISCOVER BUTTON_SELECT 377#define MINESWP_DISCOVER BUTTON_SELECT
378#define MINESWP_INFO BUTTON_MENU 378#define MINESWP_INFO BUTTON_MENU
379 379
380#elif (CONFIG_KEYPAD == DX50_PAD)
381# define MINESWP_QUIT (BUTTON_POWER|BUTTON_REL)
382
380#else 383#else
381#error No keymap defined! 384#error No keymap defined!
382#endif 385#endif
diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c
index 7b3c18bea2..7da00ad23b 100644
--- a/apps/plugins/mp3_encoder.c
+++ b/apps/plugins/mp3_encoder.c
@@ -2540,6 +2540,11 @@ CONFIG_KEYPAD == MROBE500_PAD
2540#define MP3ENC_DONE BUTTON_PLAYPAUSE 2540#define MP3ENC_DONE BUTTON_PLAYPAUSE
2541#define MP3ENC_SELECT BUTTON_SELECT 2541#define MP3ENC_SELECT BUTTON_SELECT
2542 2542
2543#elif (CONFIG_KEYPAD == DX50_PAD)
2544#define MP3ENC_PREV BUTTON_LEFT
2545#define MP3ENC_NEXT BUTTON_RIGHT
2546#define MP3ENC_DONE BUTTON_POWER
2547#define MP3ENC_SELECT BUTTON_PLAY
2543 2548
2544#else 2549#else
2545#error No keymap defined! 2550#error No keymap defined!
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 7b259395b9..1a9636e8d8 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -289,6 +289,14 @@ struct mpeg_settings settings;
289#define MPEG_START_TIME_DOWN BUTTON_DOWN 289#define MPEG_START_TIME_DOWN BUTTON_DOWN
290#define MPEG_START_TIME_EXIT BUTTON_BACK 290#define MPEG_START_TIME_EXIT BUTTON_BACK
291 291
292#elif CONFIG_KEYPAD == DX50_PAD
293#define MPEG_START_TIME_EXIT BUTTON_POWER
294#define MPEG_START_TIME_SELECT BUTTON_PLAY
295#define MPEG_START_TIME_LEFT BUTTON_LEFT
296#define MPEG_START_TIME_RIGHT BUTTON_RIGHT
297#define MPEG_START_TIME_UP BUTTON_VOL_UP
298#define MPEG_START_TIME_DOWN BUTTON_VOL_DOWN
299
292#else 300#else
293#error No keymap defined! 301#error No keymap defined!
294#endif 302#endif
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index b041094e25..945d906d8b 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -417,6 +417,15 @@ CONFIG_KEYPAD == SANSA_M200_PAD
417#define MPEG_RW BUTTON_LEFT 417#define MPEG_RW BUTTON_LEFT
418#define MPEG_FF BUTTON_RIGHT 418#define MPEG_FF BUTTON_RIGHT
419 419
420#elif CONFIG_KEYPAD == DX50_PAD
421#define MPEG_MENU BUTTON_POWER
422#define MPEG_VOLDOWN BUTTON_VOL_DOWN
423#define MPEG_VOLUP BUTTON_VOL_UP
424#define MPEG_RW BUTTON_LEFT
425#define MPEG_FF BUTTON_RIGHT
426#define MPEG_PAUSE BUTTON_PLAY
427#define MPEG_STOP (BUTTON_PLAY|BUTTON_REPEAT)
428
420#else 429#else
421#error No keymap defined! 430#error No keymap defined!
422#endif 431#endif
diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c
index 559d52ea06..a0b976f466 100644
--- a/apps/plugins/oscilloscope.c
+++ b/apps/plugins/oscilloscope.c
@@ -486,6 +486,11 @@
486#define OSCILLOSCOPE_VOL_UP BUTTON_UP 486#define OSCILLOSCOPE_VOL_UP BUTTON_UP
487#define OSCILLOSCOPE_VOL_DOWN BUTTON_DOWN 487#define OSCILLOSCOPE_VOL_DOWN BUTTON_DOWN
488 488
489#elif CONFIG_KEYPAD == DX50_PAD
490#define OSCILLOSCOPE_QUIT (BUTTON_POWER|BUTTON_REL)
491#define OSCILLOSCOPE_VOL_UP BUTTON_VOL_UP
492#define OSCILLOSCOPE_VOL_DOWN BUTTON_VOL_DOWN
493
489#else 494#else
490#error No keymap defined! 495#error No keymap defined!
491#endif 496#endif
diff --git a/apps/plugins/pacbox/pacbox.h b/apps/plugins/pacbox/pacbox.h
index 1854006a91..5da7a8b099 100644
--- a/apps/plugins/pacbox/pacbox.h
+++ b/apps/plugins/pacbox/pacbox.h
@@ -328,6 +328,9 @@
328#define PACMAN_1UP BUTTON_SELECT 328#define PACMAN_1UP BUTTON_SELECT
329#define PACMAN_COIN BUTTON_PLAYPAUSE 329#define PACMAN_COIN BUTTON_PLAYPAUSE
330 330
331#elif CONFIG_KEYPAD == DX50_PAD
332#define PACMAN_MENU BUTTON_POWER
333
331#else 334#else
332 335
333#error Keymap not defined! 336#error Keymap not defined!
diff --git a/apps/plugins/pegbox.c b/apps/plugins/pegbox.c
index fc0019fc26..1048138136 100644
--- a/apps/plugins/pegbox.c
+++ b/apps/plugins/pegbox.c
@@ -616,6 +616,11 @@ CONFIG_KEYPAD == MROBE500_PAD
616#define LVL_DOWN_TEXT "PLAY/PAUSE" 616#define LVL_DOWN_TEXT "PLAY/PAUSE"
617#define SELECT_TEXT "SELECT" 617#define SELECT_TEXT "SELECT"
618 618
619#elif CONFIG_KEYPAD == DX50_PAD
620#define PEGBOX_QUIT BUTTON_POWER
621
622#define QUIT_TEXT "Power"
623
619#else 624#else
620#error Unsupported keymap! 625#error Unsupported keymap!
621#endif 626#endif
diff --git a/apps/plugins/plugins.make b/apps/plugins/plugins.make
index 92769d770a..1edbd37306 100644
--- a/apps/plugins/plugins.make
+++ b/apps/plugins/plugins.make
@@ -11,7 +11,9 @@
11is_app_build = 11is_app_build =
12ifdef APP_TYPE 12ifdef APP_TYPE
13ifneq ($(APP_TYPE),sdl-sim) 13ifneq ($(APP_TYPE),sdl-sim)
14 is_app_build = yes 14ifeq (,$(findstring standalone, $(APP_TYPE)))
15 is_app_build = yes
16endif
15endif 17endif
16endif 18endif
17 19
diff --git a/apps/plugins/pong.c b/apps/plugins/pong.c
index eb5adb3351..4ec62e01be 100644
--- a/apps/plugins/pong.c
+++ b/apps/plugins/pong.c
@@ -287,6 +287,9 @@ CONFIG_KEYPAD == MROBE500_PAD
287#define PONG_RIGHT_UP BUTTON_RIGHT 287#define PONG_RIGHT_UP BUTTON_RIGHT
288#define PONG_RIGHT_DOWN BUTTON_LEFT 288#define PONG_RIGHT_DOWN BUTTON_LEFT
289 289
290#elif (CONFIG_KEYPAD == DX50_PAD)
291#define PONG_QUIT (BUTTON_POWER|BUTTON_REL)
292
290#else 293#else
291#error No keymap defined! 294#error No keymap defined!
292#endif 295#endif
diff --git a/apps/plugins/reversi/reversi-gui.h b/apps/plugins/reversi/reversi-gui.h
index 5c43ce2373..3932b688ef 100644
--- a/apps/plugins/reversi/reversi-gui.h
+++ b/apps/plugins/reversi/reversi-gui.h
@@ -312,6 +312,10 @@
312#define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT 312#define REVERSI_BUTTON_MAKE_MOVE BUTTON_SELECT
313#define REVERSI_BUTTON_MENU BUTTON_MENU 313#define REVERSI_BUTTON_MENU BUTTON_MENU
314 314
315#elif CONFIG_KEYPAD == DX50_PAD
316#define REVERSI_BUTTON_QUIT BUTTON_POWER
317#define REVERSI_BUTTON_MENU BUTTON_PLAY
318
315#else 319#else
316#error No keymap defined! 320#error No keymap defined!
317#endif 321#endif
diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c
index 5647b0a719..cde542a1c0 100644
--- a/apps/plugins/rockblox.c
+++ b/apps/plugins/rockblox.c
@@ -449,6 +449,14 @@
449#define ROCKBLOX_DROP BUTTON_SELECT 449#define ROCKBLOX_DROP BUTTON_SELECT
450#define ROCKBLOX_RESTART BUTTON_SHORTCUT 450#define ROCKBLOX_RESTART BUTTON_SHORTCUT
451 451
452#elif CONFIG_KEYPAD == DX50_PAD
453#define ROCKBLOX_OFF BUTTON_POWER
454#define ROCKBLOX_ROTATE BUTTON_RIGHT
455#define ROCKBLOX_LEFT BUTTON_LEFT
456#define ROCKBLOX_RIGHT BUTTON_PLAY
457#define ROCKBLOX_DROP BUTTON_VOL_DOWN
458#define ROCKBLOX_RESTART BUTTON_VOL_UP
459
452#else 460#else
453#error No keymap defined! 461#error No keymap defined!
454#endif 462#endif
diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c
index c12df07140..12feabb8e1 100644
--- a/apps/plugins/rockboy/rockboy.c
+++ b/apps/plugins/rockboy/rockboy.c
@@ -402,6 +402,13 @@ static void setoptions (void)
402 options.A = BUTTON_SHORTCUT; 402 options.A = BUTTON_SHORTCUT;
403 options.B = BUTTON_PLAYPAUSE; 403 options.B = BUTTON_PLAYPAUSE;
404 404
405#elif CONFIG_KEYPAD == DX50_PAD
406 options.A = BUTTON_VOL_UP;
407 options.B = BUTTON_VOL_DOWN;
408 options.MENU = BUTTON_POWER;
409 options.START = BUTTON_LEFT;
410 options.SELECT = BUTTON_RIGHT;
411
405#else 412#else
406#error No Keymap Defined! 413#error No Keymap Defined!
407#endif 414#endif
@@ -414,7 +421,7 @@ static void setoptions (void)
414#if CONFIG_KEYPAD == MROBE500_PAD 421#if CONFIG_KEYPAD == MROBE500_PAD
415 options.A = BUTTON_BOTTOMLEFT; 422 options.A = BUTTON_BOTTOMLEFT;
416 options.B = BUTTON_BOTTOMRIGHT; 423 options.B = BUTTON_BOTTOMRIGHT;
417#elif CONFIG_KEYPAD != COWON_D2_PAD 424#elif (CONFIG_KEYPAD != COWON_D2_PAD ) || (CONFIG_KEYPAD != DX50_PAD )
418 options.A = BUTTON_BOTTOMLEFT; 425 options.A = BUTTON_BOTTOMLEFT;
419 options.B = BUTTON_BOTTOMRIGHT; 426 options.B = BUTTON_BOTTOMRIGHT;
420 options.MENU = BUTTON_TOPLEFT; 427 options.MENU = BUTTON_TOPLEFT;
diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c
index af6ce20eec..f3647c6024 100644
--- a/apps/plugins/rockpaint.c
+++ b/apps/plugins/rockpaint.c
@@ -310,6 +310,9 @@
310#define ROCKPAINT_TOOLBAR BUTTON_SHORTCUT 310#define ROCKPAINT_TOOLBAR BUTTON_SHORTCUT
311#define ROCKPAINT_TOOLBAR2 BUTTON_PLAYPAUSE 311#define ROCKPAINT_TOOLBAR2 BUTTON_PLAYPAUSE
312 312
313#elif ( CONFIG_KEYPAD == DX50_PAD )
314#define ROCKPAINT_QUIT (BUTTON_POWER|BUTTON_REL)
315
313#else 316#else
314#error "Please define keys for this keypad" 317#error "Please define keys for this keypad"
315#endif 318#endif
diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c
index 39c60628c7..d4dd01f948 100644
--- a/apps/plugins/sliding_puzzle.c
+++ b/apps/plugins/sliding_puzzle.c
@@ -310,6 +310,12 @@ CONFIG_KEYPAD == MROBE500_PAD
310#define PUZZLE_SHUFFLE BUTTON_SHORTCUT 310#define PUZZLE_SHUFFLE BUTTON_SHORTCUT
311#define PUZZLE_PICTURE BUTTON_PLAYPAUSE 311#define PUZZLE_PICTURE BUTTON_PLAYPAUSE
312 312
313#elif (CONFIG_KEYPAD == DX50_PAD)
314#define PUZZLE_QUIT (BUTTON_POWER|BUTTON_REL)
315#define PUZZLE_SHUFFLE BUTTON_PLAY
316#define PUZZLE_PICTURE BUTTON_RIGHT
317#define PUZZLE_QUIT_TEXT "[Power]"
318
313#else 319#else
314#error No keymap defined! 320#error No keymap defined!
315#endif 321#endif
diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c
index 55d91cb5f9..a22ecf4c70 100644
--- a/apps/plugins/snake.c
+++ b/apps/plugins/snake.c
@@ -269,6 +269,14 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left;
269#define SNAKE_DOWN BUTTON_DOWN 269#define SNAKE_DOWN BUTTON_DOWN
270#define SNAKE_PLAYPAUSE BUTTON_PLAYPAUSE 270#define SNAKE_PLAYPAUSE BUTTON_PLAYPAUSE
271 271
272#elif CONFIG_KEYPAD == DX50_PAD
273#define SNAKE_QUIT BUTTON_POWER
274#define SNAKE_LEFT BUTTON_LEFT
275#define SNAKE_RIGHT BUTTON_PLAY
276#define SNAKE_UP BUTTON_VOL_UP
277#define SNAKE_DOWN BUTTON_VOL_DOWN
278#define SNAKE_PLAYPAUSE BUTTON_RIGHT
279
272#else 280#else
273#error No keymap defined! 281#error No keymap defined!
274#endif 282#endif
diff --git a/apps/plugins/snake2.c b/apps/plugins/snake2.c
index 2fb5521a79..b695dc9abd 100644
--- a/apps/plugins/snake2.c
+++ b/apps/plugins/snake2.c
@@ -383,6 +383,15 @@ CONFIG_KEYPAD == MROBE500_PAD
383#define SNAKE2_PLAYPAUSE BUTTON_PLAYPAUSE 383#define SNAKE2_PLAYPAUSE BUTTON_PLAYPAUSE
384#define SNAKE2_PLAYPAUSE_TEXT "Play/Pause" 384#define SNAKE2_PLAYPAUSE_TEXT "Play/Pause"
385 385
386#elif (CONFIG_KEYPAD == DX50_PAD)
387#define SNAKE2_QUIT (BUTTON_POWER|BUTTON_REL)
388#define SNAKE2_LEFT BUTTON_LEFT
389#define SNAKE2_RIGHT BUTTON_PLAY
390#define SNAKE2_UP BUTTON_VOL_UP
391#define SNAKE2_DOWN BUTTON_VOL_DOWN
392#define SNAKE2_PLAYPAUSE BUTTON_RIGHT
393#define SNAKE2_PLAYPAUSE_TEXT "Right"
394
386#else 395#else
387#error No keymap defined! 396#error No keymap defined!
388#endif 397#endif
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c
index 07b5856240..f3c4f9c8f6 100644
--- a/apps/plugins/sokoban.c
+++ b/apps/plugins/sokoban.c
@@ -611,6 +611,14 @@
611#define BUTTON_SAVE (BUTTON_POWER | BUTTON_PLAY) 611#define BUTTON_SAVE (BUTTON_POWER | BUTTON_PLAY)
612#define BUTTON_SAVE_NAME "POWER + PLAY" 612#define BUTTON_SAVE_NAME "POWER + PLAY"
613 613
614#elif CONFIG_KEYPAD == DX50_PAD
615#define SOKOBAN_MENU (BUTTON_POWER|BUTTON_REL)
616#define SOKOBAN_PAUSE BUTTON_PLAY
617#define SOKOBAN_LEVEL_DOWN BUTTON_LEFT
618#define SOKOBAN_LEVEL_UP BUTTON_RIGHT
619#define SOKOBAN_MENU_NAME "Power"
620#define SOKOBAN_PAUSE_NAME "Play"
621
614#else 622#else
615#error No keymap defined! 623#error No keymap defined!
616#endif 624#endif
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c
index 04e3c15d56..541b42de42 100644
--- a/apps/plugins/solitaire.c
+++ b/apps/plugins/solitaire.c
@@ -651,6 +651,9 @@ CONFIG_KEYPAD == MROBE500_PAD
651#define HK_CUR2STACK "Menu" 651#define HK_CUR2STACK "Menu"
652#define HK_REM2STACK "Shortcut" 652#define HK_REM2STACK "Shortcut"
653 653
654#elif (CONFIG_KEYPAD == DX50_PAD)
655# define SOL_QUIT (BUTTON_POWER | BUTTON_REL)
656
654#else 657#else
655#error No keymap defined! 658#error No keymap defined!
656#endif 659#endif
diff --git a/apps/plugins/spacerocks.c b/apps/plugins/spacerocks.c
index 68f47caa4a..a7e9912cf4 100644
--- a/apps/plugins/spacerocks.c
+++ b/apps/plugins/spacerocks.c
@@ -333,6 +333,14 @@
333#define AST_RIGHT BUTTON_RIGHT 333#define AST_RIGHT BUTTON_RIGHT
334#define AST_FIRE BUTTON_SELECT 334#define AST_FIRE BUTTON_SELECT
335 335
336#elif (CONFIG_KEYPAD == DX50_PAD)
337#define AST_QUIT BUTTON_POWER
338#define AST_THRUST BUTTON_VOL_UP
339#define AST_HYPERSPACE BUTTON_VOL_DOWN
340#define AST_LEFT BUTTON_LEFT
341#define AST_RIGHT BUTTON_PLAY
342#define AST_FIRE BUTTON_RIGHT
343
336#else 344#else
337#error No keymap defined! 345#error No keymap defined!
338#endif 346#endif
diff --git a/apps/plugins/star.c b/apps/plugins/star.c
index b43c05ebf5..a1367e9044 100644
--- a/apps/plugins/star.c
+++ b/apps/plugins/star.c
@@ -581,6 +581,10 @@
581#define STAR_TOGGLE_CONTROL_NAME "Select" 581#define STAR_TOGGLE_CONTROL_NAME "Select"
582#define STAR_QUIT_NAME "Back" 582#define STAR_QUIT_NAME "Back"
583 583
584#elif (CONFIG_KEYPAD == DX50_PAD)
585#define STAR_QUIT BUTTON_POWER
586#define STAR_QUIT_NAME "Power"
587
584#else 588#else
585#error No keymap defined! 589#error No keymap defined!
586#endif 590#endif
diff --git a/apps/plugins/sudoku/sudoku.h b/apps/plugins/sudoku/sudoku.h
index 2bc65eeaa7..2caa75fbbe 100644
--- a/apps/plugins/sudoku/sudoku.h
+++ b/apps/plugins/sudoku/sudoku.h
@@ -398,6 +398,9 @@
398#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT 398#define SUDOKU_BUTTON_TOGGLE BUTTON_SELECT
399#define SUDOKU_BUTTON_POSSIBLE BUTTON_SHORTCUT 399#define SUDOKU_BUTTON_POSSIBLE BUTTON_SHORTCUT
400 400
401#elif CONFIG_KEYPAD == DX50_PAD
402#define SUDOKU_BUTTON_QUIT (BUTTON_POWER|BUTTON_REL)
403
401#else 404#else
402#error No keymap defined! 405#error No keymap defined!
403#endif 406#endif
diff --git a/apps/plugins/text_viewer/tv_button.h b/apps/plugins/text_viewer/tv_button.h
index bcaa593cea..7c0cfab519 100644
--- a/apps/plugins/text_viewer/tv_button.h
+++ b/apps/plugins/text_viewer/tv_button.h
@@ -506,6 +506,16 @@
506#define TV_AUTOSCROLL BUTTON_PLAYPAUSE 506#define TV_AUTOSCROLL BUTTON_PLAYPAUSE
507#define TV_BOOKMARK BUTTON_SHORTCUT 507#define TV_BOOKMARK BUTTON_SHORTCUT
508 508
509#elif CONFIG_KEYPAD == DX50_PAD
510#define TV_QUIT (BUTTON_POWER | BUTTON_REL)
511#define TV_SCROLL_UP BUTTON_VOL_UP
512#define TV_SCROLL_DOWN BUTTON_VOL_DOWN
513#define TV_SCREEN_LEFT BUTTON_LEFT
514#define TV_SCREEN_RIGHT BUTTON_RIGHT
515#define TV_MENU (BUTTON_PLAY | BUTTON_REL)
516#define TV_AUTOSCROLL (BUTTON_POWER | BUTTON_PLAY)
517#define TV_BOOKMARK (BUTTON_POWER | BUTTON_VOL_UP)
518
509#else 519#else
510#error No keymap defined! 520#error No keymap defined!
511#endif 521#endif
diff --git a/apps/plugins/vu_meter.c b/apps/plugins/vu_meter.c
index 6d8922cd4b..43a7b917a9 100644
--- a/apps/plugins/vu_meter.c
+++ b/apps/plugins/vu_meter.c
@@ -395,6 +395,14 @@
395#define LABEL_MENU "Menu" 395#define LABEL_MENU "Menu"
396#define LABEL_VOLUME "Up/Down" 396#define LABEL_VOLUME "Up/Down"
397 397
398#elif CONFIG_KEYPAD == DX50_PAD
399#define VUMETER_QUIT (BUTTON_POWER|BUTTON_REL)
400#define VUMETER_MENU BUTTON_PLAY
401#define VUMETER_UP BUTTON_RIGHT
402#define VUMETER_DOWN BUTTON_LEFT
403#define LABEL_QUIT "Power"
404#define LABEL_MENU "Play"
405
398#else 406#else
399#error No keymap defined! 407#error No keymap defined!
400#endif 408#endif
diff --git a/apps/plugins/wormlet.c b/apps/plugins/wormlet.c
index 51021dfac4..26b97c7748 100644
--- a/apps/plugins/wormlet.c
+++ b/apps/plugins/wormlet.c
@@ -370,6 +370,15 @@ CONFIG_KEYPAD == MROBE500_PAD
370#define BTN_QUIT BUTTON_BACK 370#define BTN_QUIT BUTTON_BACK
371#define BTN_STOPRESET BUTTON_SHORTCUT 371#define BTN_STOPRESET BUTTON_SHORTCUT
372 372
373#elif CONFIG_KEYPAD == DX50_PAD
374#define BTN_DIR_UP BUTTON_VOL_UP
375#define BTN_DIR_DOWN BUTTON_VOL_DOWN
376#define BTN_DIR_LEFT BUTTON_LEFT
377#define BTN_DIR_RIGHT BUTTON_RIGHT
378#define BTN_STARTPAUSE BUTTON_PLAY
379#define BTN_QUIT BUTTON_POWER
380#define BTN_STOPRESET (BUTTON_PLAY|BUTTON_REPEAT)
381
373#else 382#else
374#error No keymap defined! 383#error No keymap defined!
375#endif 384#endif
diff --git a/apps/plugins/xobox.c b/apps/plugins/xobox.c
index 3cf3b2a434..f3ed96f282 100644
--- a/apps/plugins/xobox.c
+++ b/apps/plugins/xobox.c
@@ -322,6 +322,14 @@ CONFIG_KEYPAD == MROBE500_PAD
322#define DOWN BUTTON_DOWN 322#define DOWN BUTTON_DOWN
323#define PAUSE BUTTON_PLAYPAUSE 323#define PAUSE BUTTON_PLAYPAUSE
324 324
325#elif CONFIG_KEYPAD == DX50_PAD
326#define QUIT BUTTON_POWER
327#define LEFT BUTTON_LEFT
328#define RIGHT BUTTON_RIGHT
329#define UP BUTTON_VOL_UP
330#define DOWN BUTTON_VOL_DOWN
331#define PAUSE BUTTON_PLAY
332
325#else 333#else
326#error No keymap defined! 334#error No keymap defined!
327#endif 335#endif
diff --git a/apps/plugins/zxbox/keymaps.h b/apps/plugins/zxbox/keymaps.h
index d8be7f832b..bdbe4f93ad 100644
--- a/apps/plugins/zxbox/keymaps.h
+++ b/apps/plugins/zxbox/keymaps.h
@@ -262,6 +262,14 @@
262#define ZX_RIGHT BUTTON_RIGHT 262#define ZX_RIGHT BUTTON_RIGHT
263#define ZX_SELECT BUTTON_SELECT 263#define ZX_SELECT BUTTON_SELECT
264 264
265#elif CONFIG_KEYPAD == DX50_PAD
266#define ZX_MENU BUTTON_POWER
267#define ZX_UP BUTTON_VOL_UP
268#define ZX_DOWN BUTTON_VOL_DOWN
269#define ZX_SELECT BUTTON_PLAY
270#define ZX_LEFT BUTTON_LEFT
271#define ZX_RIGHT BUTTON_RIGHT
272
265#else 273#else
266#error Keymap not defined! 274#error Keymap not defined!
267 275
diff --git a/apps/root_menu.c b/apps/root_menu.c
index 7ec803f585..f1b5017751 100644
--- a/apps/root_menu.c
+++ b/apps/root_menu.c
@@ -792,13 +792,13 @@ void root_menu(void)
792 case GO_TO_ROOT: 792 case GO_TO_ROOT:
793 if (last_screen != GO_TO_ROOT) 793 if (last_screen != GO_TO_ROOT)
794 selected = get_selection(last_screen); 794 selected = get_selection(last_screen);
795#if (CONFIG_PLATFORM&PLATFORM_ANDROID) 795#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(DX50) && !defined(DX90)
796 /* When we are in the main menu we want the hardware BACK 796 /* When we are in the main menu we want the hardware BACK
797 * button to be handled by Android instead of rockbox */ 797 * button to be handled by Android instead of rockbox */
798 android_ignore_back_button(true); 798 android_ignore_back_button(true);
799#endif 799#endif
800 next_screen = do_menu(&root_menu_, &selected, NULL, false); 800 next_screen = do_menu(&root_menu_, &selected, NULL, false);
801#if (CONFIG_PLATFORM&PLATFORM_ANDROID) 801#if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(DX50) && !defined(DX90)
802 android_ignore_back_button(false); 802 android_ignore_back_button(false);
803#endif 803#endif
804 if (next_screen != GO_TO_PREVIOUS) 804 if (next_screen != GO_TO_PREVIOUS)
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 070f0d4a62..950e4f2bcf 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1811,18 +1811,28 @@ target/arm/rk27xx/ihifi/powermgmt-ihifi960.c
1811target/hosted/kernel-unix.c 1811target/hosted/kernel-unix.c
1812target/hosted/filesystem-unix.c 1812target/hosted/filesystem-unix.c
1813target/hosted/lc-unix.c 1813target/hosted/lc-unix.c
1814#if !defined(DX50) && !defined(DX90)
1814target/hosted/android/lcd-android.c 1815target/hosted/android/lcd-android.c
1815target/hosted/android/button-android.c 1816target/hosted/android/button-android.c
1816#ifdef DEBUG
1817target/hosted/android/debug-android.c
1818#endif
1819target/hosted/android/pcm-android.c 1817target/hosted/android/pcm-android.c
1820target/hosted/android/powermgmt-android.c 1818target/hosted/android/powermgmt-android.c
1821target/hosted/android/system-android.c
1822target/hosted/android/telephony-android.c 1819target/hosted/android/telephony-android.c
1823#ifdef APPLICATION 1820#ifdef APPLICATION
1824target/hosted/android/app/button-application.c 1821target/hosted/android/app/button-application.c
1825#endif 1822#endif
1823#else
1824drivers/lcd-memframe.c
1825target/hosted/android/dx50/pcm-dx50.c
1826target/hosted/android/dx50/tinyalsa/pcm.c
1827target/hosted/android/dx50/powermgmt-dx50.c
1828target/hosted/android/dx50/backlight-dx50.c
1829target/hosted/android/dx50/button-dx50.c
1830target/hosted/android/dx50/lcd-dx50.c
1831#endif
1832#ifdef DEBUG
1833target/hosted/android/debug-android.c
1834#endif
1835target/hosted/android/system-android.c
1826drivers/audio/android.c 1836drivers/audio/android.c
1827#endif 1837#endif
1828 1838
diff --git a/firmware/asm/SOURCES b/firmware/asm/SOURCES
index ebb6951071..f16285e623 100644
--- a/firmware/asm/SOURCES
+++ b/firmware/asm/SOURCES
@@ -14,7 +14,7 @@ mempcpy.c
14#if (defined(SANSA_E200) || defined(GIGABEAT_F) || defined(GIGABEAT_S) || \ 14#if (defined(SANSA_E200) || defined(GIGABEAT_F) || defined(GIGABEAT_S) || \
15 defined(CREATIVE_ZVx) || defined(SANSA_CONNECT) || defined(SANSA_FUZEPLUS) || \ 15 defined(CREATIVE_ZVx) || defined(SANSA_CONNECT) || defined(SANSA_FUZEPLUS) || \
16 defined(COWON_D2) || defined(MINI2440) || defined(SAMSUNG_YPR0) || \ 16 defined(COWON_D2) || defined(MINI2440) || defined(SAMSUNG_YPR0) || \
17 defined(SAMSUNG_YPR1) || (defined(MROBE_500) && !defined(LCD_USE_DMA)) || \ 17 defined(SAMSUNG_YPR1) || defined(DX50) || defined(DX90) || (defined(MROBE_500) && !defined(LCD_USE_DMA)) || \
18 defined(CREATIVE_ZEN) || defined(CREATIVE_ZENXFI)) && \ 18 defined(CREATIVE_ZEN) || defined(CREATIVE_ZENXFI)) && \
19 !defined(SIMULATOR) 19 !defined(SIMULATOR)
20#if LCD_DEPTH == 24 20#if LCD_DEPTH == 24
diff --git a/firmware/asm/arm/thread.h b/firmware/asm/arm/thread.h
index 7b8ebc2041..533a088979 100644
--- a/firmware/asm/arm/thread.h
+++ b/firmware/asm/arm/thread.h
@@ -31,7 +31,11 @@ struct regs
31 31
32#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 32#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
33 #include <errno.h> 33 #include <errno.h>
34#if defined(DX50) || defined (DX90)
35 #define DEFAULT_STACK_SIZE 0x2000 /* Bytes */
36#else
34 #define DEFAULT_STACK_SIZE 0x1000 /* Bytes */ 37 #define DEFAULT_STACK_SIZE 0x1000 /* Bytes */
38#endif
35#else 39#else
36 #define DEFAULT_STACK_SIZE 0x400 /* Bytes */ 40 #define DEFAULT_STACK_SIZE 0x400 /* Bytes */
37#endif 41#endif
diff --git a/firmware/drivers/audio/android.c b/firmware/drivers/audio/android.c
index 7a5f34ea48..f26087470b 100644
--- a/firmware/drivers/audio/android.c
+++ b/firmware/drivers/audio/android.c
@@ -22,12 +22,34 @@
22 22
23#include "config.h" 23#include "config.h"
24#include "audiohw.h" 24#include "audiohw.h"
25#if defined(DX50) || defined(DX90)
26#include "system.h"
27#include "pcm_sw_volume.h"
28#endif
25 29
30#if defined(DX50) || defined(DX90)
31void audiohw_set_volume(int vol_l, int vol_r)
32{
33 int hw_volume;
34 hw_volume = MAX(vol_l, vol_r);
35
36#ifdef HAVE_SW_VOLUME_CONTROL
37 vol_l-=hw_volume;
38 vol_r-=hw_volume;
39 pcm_set_master_volume(vol_l, vol_r);
40#endif
41
42 extern void pcm_set_mixer_volume(int);
43 pcm_set_mixer_volume(hw_volume);
44
45}
46#else
26void audiohw_set_volume(int volume) 47void audiohw_set_volume(int volume)
27{ 48{
28 extern void pcm_set_mixer_volume(int); 49 extern void pcm_set_mixer_volume(int);
29 pcm_set_mixer_volume(volume); 50 pcm_set_mixer_volume(volume);
30} 51}
52#endif
31 53
32void audiohw_set_balance(int balance) 54void audiohw_set_balance(int balance)
33{ 55{
@@ -36,6 +58,8 @@ void audiohw_set_balance(int balance)
36 58
37void audiohw_close(void) 59void audiohw_close(void)
38{ 60{
61#if !defined(DX50) && !defined(DX90)
39 extern void pcm_shutdown(void); 62 extern void pcm_shutdown(void);
40 pcm_shutdown(); 63 pcm_shutdown();
64#endif
41} 65}
diff --git a/firmware/drivers/touchscreen.c b/firmware/drivers/touchscreen.c
index 42ddf7ec47..572f05ab7f 100644
--- a/firmware/drivers/touchscreen.c
+++ b/firmware/drivers/touchscreen.c
@@ -188,7 +188,7 @@ bool touchscreen_is_enabled(void)
188} 188}
189#endif 189#endif
190 190
191#if ((CONFIG_PLATFORM & PLATFORM_ANDROID) == 0) 191#if ((CONFIG_PLATFORM & PLATFORM_ANDROID) == 0) || defined(DX50) || defined(DX90)
192/* android has an API for this */ 192/* android has an API for this */
193 193
194#define TOUCH_SLOP 16u 194#define TOUCH_SLOP 16u
diff --git a/firmware/export/config.h b/firmware/export/config.h
index a56dd32303..bf95dc4c09 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -164,6 +164,7 @@
164#define IHIFI_PAD 60 164#define IHIFI_PAD 60
165#define SAMSUNG_YPR1_PAD 61 165#define SAMSUNG_YPR1_PAD 61
166#define SAMSUNG_YH920_PAD 62 166#define SAMSUNG_YH920_PAD 62
167#define DX50_PAD 63
167 168
168/* CONFIG_REMOTE_KEYPAD */ 169/* CONFIG_REMOTE_KEYPAD */
169#define H100_REMOTE 1 170#define H100_REMOTE 1
@@ -575,6 +576,10 @@ Lyre prototype 1 */
575#include "config/creativezenxfistyle.h" 576#include "config/creativezenxfistyle.h"
576#elif defined(SAMSUNG_YPR1) 577#elif defined(SAMSUNG_YPR1)
577#include "config/samsungypr1.h" 578#include "config/samsungypr1.h"
579#elif defined(DX50)
580#include "config/ibassodx50.h"
581#elif defined(DX90)
582#include "config/ibassodx90.h"
578#else 583#else
579/* no known platform */ 584/* no known platform */
580#endif 585#endif
diff --git a/firmware/export/config/ibassodx50.h b/firmware/export/config/ibassodx50.h
new file mode 100644
index 0000000000..652377cc6c
--- /dev/null
+++ b/firmware/export/config/ibassodx50.h
@@ -0,0 +1,136 @@
1/*
2 * This config file is for Rockbox as an application on Android
3 */
4
5/* We don't run on hardware directly */
6#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_ANDROID)
7
8/* For Rolo and boot loader */
9#define MODEL_NUMBER 94
10
11#define MODEL_NAME "iBasso DX50"
12
13#define USB_NONE
14
15/* define this if you have a bitmap LCD display */
16#define HAVE_LCD_BITMAP
17
18/* define this if you have a colour LCD */
19#define HAVE_LCD_COLOR
20
21/* define this if you want album art for this target */
22#define HAVE_ALBUMART
23
24/* define this to enable bitmap scaling */
25#define HAVE_BMP_SCALING
26
27/* define this to enable JPEG decoding */
28#define HAVE_JPEG
29
30/* define this if you have access to the quickscreen */
31#define HAVE_QUICKSCREEN
32
33/* define this if you would like tagcache to build on this target */
34#define HAVE_TAGCACHE
35
36/* LCD dimensions */
37#define LCD_WIDTH 320
38#define LCD_HEIGHT 240
39#define LCD_DPI 166
40#define LCD_DEPTH 16
41#define LCD_PIXELFORMAT RGB565
42
43#define HAVE_LCD_ENABLE
44
45/* define this to indicate your device's keypad */
46#define HAVE_TOUCHSCREEN
47#define HAVE_BUTTON_DATA
48
49/* define this if you have RTC RAM available for settings */
50//#define HAVE_RTC_RAM
51
52/* define this if you have a real-time clock */
53//#define CONFIG_RTC APPLICATION
54
55/* Define this if you have a software controlled poweroff */
56#define HAVE_SW_POWEROFF
57
58/* The number of bytes reserved for loadable codecs */
59#define CODEC_SIZE 0x100000
60
61/* The number of bytes reserved for loadable plugins */
62#define PLUGIN_BUFFER_SIZE 0x160000
63
64#define AB_REPEAT_ENABLE
65
66/* Define this for LCD backlight available */
67#define HAVE_BACKLIGHT
68#define HAVE_BACKLIGHT_BRIGHTNESS
69
70/* Main LCD backlight brightness range and defaults */
71#define MIN_BRIGHTNESS_SETTING 4
72#define MAX_BRIGHTNESS_SETTING 255
73#define DEFAULT_BRIGHTNESS_SETTING 255
74
75/* Which backlight fading type? */
76#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING
77
78/* Define this if you do software codec */
79#define CONFIG_CODEC SWCODEC
80
81//#define HAVE_MULTIMEDIA_KEYS
82#define CONFIG_KEYPAD DX50_PAD
83
84/* define this if the target has volume keys which can be used in the lists */
85#define HAVE_VOLUME_IN_LIST
86
87/* define this if the host platform can change volume outside of rockbox */
88//#define PLATFORM_HAS_VOLUME_CHANGE
89
90#define HAVE_SW_TONE_CONTROLS
91
92#define HAVE_SW_VOLUME_CONTROL
93
94#define BATTERY_CAPACITY_DEFAULT 2100 /* default battery capacity */
95#define BATTERY_CAPACITY_MIN 1700 /* min. capacity selectable */
96#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
97#define BATTERY_CAPACITY_INC 50 /* capacity increment */
98#define BATTERY_TYPES_COUNT 1 /* only one type */
99
100#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
101
102#define CONFIG_CHARGING CHARGING_SIMPLE
103
104#define NO_LOW_BATTERY_SHUTDOWN
105
106/* Define current usage levels. */
107#define CURRENT_NORMAL 210 /* 10 hours from a 2100 mAh battery */
108#define CURRENT_BACKLIGHT 30 /* TBD */
109#define CURRENT_RECORD 0 /* no recording */
110
111/* Define this to the CPU frequency */
112/*
113#define CPU_FREQ 48000000
114*/
115
116/* define this if the hardware can be powered off while charging */
117#define HAVE_POWEROFF_WHILE_CHARGING
118
119
120/* Offset ( in the firmware file's header ) to the file CRC */
121#define FIRMWARE_OFFSET_FILE_CRC 0
122
123/* Offset ( in the firmware file's header ) to the real data */
124#define FIRMWARE_OFFSET_FILE_DATA 8
125
126#define CONFIG_LCD LCD_COWOND2
127
128/* Define this if a programmable hotkey is mapped */
129#define HAVE_HOTKEY
130
131#define BOOTDIR "/.rockbox"
132
133/* No special storage */
134#define CONFIG_STORAGE STORAGE_HOSTFS
135#define HAVE_STORAGE_FLUSH
136
diff --git a/firmware/export/config/ibassodx90.h b/firmware/export/config/ibassodx90.h
new file mode 100644
index 0000000000..d560f3e10b
--- /dev/null
+++ b/firmware/export/config/ibassodx90.h
@@ -0,0 +1,136 @@
1/*
2 * This config file is for Rockbox as an application on Android
3 */
4
5/* We don't run on hardware directly */
6#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_ANDROID)
7
8/* For Rolo and boot loader */
9#define MODEL_NUMBER 95
10
11#define MODEL_NAME "iBasso DX90"
12
13#define USB_NONE
14
15/* define this if you have a bitmap LCD display */
16#define HAVE_LCD_BITMAP
17
18/* define this if you have a colour LCD */
19#define HAVE_LCD_COLOR
20
21/* define this if you want album art for this target */
22#define HAVE_ALBUMART
23
24/* define this to enable bitmap scaling */
25#define HAVE_BMP_SCALING
26
27/* define this to enable JPEG decoding */
28#define HAVE_JPEG
29
30/* define this if you have access to the quickscreen */
31#define HAVE_QUICKSCREEN
32
33/* define this if you would like tagcache to build on this target */
34#define HAVE_TAGCACHE
35
36/* LCD dimensions */
37#define LCD_WIDTH 320
38#define LCD_HEIGHT 240
39#define LCD_DPI 166
40#define LCD_DEPTH 16
41#define LCD_PIXELFORMAT RGB565
42
43#define HAVE_LCD_ENABLE
44
45/* define this to indicate your device's keypad */
46#define HAVE_TOUCHSCREEN
47#define HAVE_BUTTON_DATA
48
49/* define this if you have RTC RAM available for settings */
50//#define HAVE_RTC_RAM
51
52/* define this if you have a real-time clock */
53//#define CONFIG_RTC APPLICATION
54
55/* Define this if you have a software controlled poweroff */
56#define HAVE_SW_POWEROFF
57
58/* The number of bytes reserved for loadable codecs */
59#define CODEC_SIZE 0x100000
60
61/* The number of bytes reserved for loadable plugins */
62#define PLUGIN_BUFFER_SIZE 0x160000
63
64#define AB_REPEAT_ENABLE
65
66/* Define this for LCD backlight available */
67#define HAVE_BACKLIGHT
68#define HAVE_BACKLIGHT_BRIGHTNESS
69
70/* Main LCD backlight brightness range and defaults */
71#define MIN_BRIGHTNESS_SETTING 4
72#define MAX_BRIGHTNESS_SETTING 255
73#define DEFAULT_BRIGHTNESS_SETTING 255
74
75/* Which backlight fading type? */
76#define CONFIG_BACKLIGHT_FADING BACKLIGHT_FADING_SW_SETTING
77
78/* Define this if you do software codec */
79#define CONFIG_CODEC SWCODEC
80
81//#define HAVE_MULTIMEDIA_KEYS
82#define CONFIG_KEYPAD DX50_PAD
83
84/* define this if the target has volume keys which can be used in the lists */
85#define HAVE_VOLUME_IN_LIST
86
87/* define this if the host platform can change volume outside of rockbox */
88//#define PLATFORM_HAS_VOLUME_CHANGE
89
90#define HAVE_SW_TONE_CONTROLS
91
92#define HAVE_SW_VOLUME_CONTROL
93
94#define BATTERY_CAPACITY_DEFAULT 2100 /* default battery capacity */
95#define BATTERY_CAPACITY_MIN 1700 /* min. capacity selectable */
96#define BATTERY_CAPACITY_MAX 3200 /* max. capacity selectable */
97#define BATTERY_CAPACITY_INC 50 /* capacity increment */
98#define BATTERY_TYPES_COUNT 1 /* only one type */
99
100#define CONFIG_BATTERY_MEASURE VOLTAGE_MEASURE
101
102#define CONFIG_CHARGING CHARGING_SIMPLE
103
104#define NO_LOW_BATTERY_SHUTDOWN
105
106/* Define current usage levels. */
107#define CURRENT_NORMAL 210 /* 10 hours from a 2100 mAh battery */
108#define CURRENT_BACKLIGHT 30 /* TBD */
109#define CURRENT_RECORD 0 /* no recording */
110
111/* Define this to the CPU frequency */
112/*
113#define CPU_FREQ 48000000
114*/
115
116/* define this if the hardware can be powered off while charging */
117#define HAVE_POWEROFF_WHILE_CHARGING
118
119
120/* Offset ( in the firmware file's header ) to the file CRC */
121#define FIRMWARE_OFFSET_FILE_CRC 0
122
123/* Offset ( in the firmware file's header ) to the real data */
124#define FIRMWARE_OFFSET_FILE_DATA 8
125
126#define CONFIG_LCD LCD_COWOND2
127
128/* Define this if a programmable hotkey is mapped */
129#define HAVE_HOTKEY
130
131#define BOOTDIR "/.rockbox"
132
133/* No special storage */
134#define CONFIG_STORAGE STORAGE_HOSTFS
135#define HAVE_STORAGE_FLUSH
136
diff --git a/firmware/export/hosted_codec.h b/firmware/export/hosted_codec.h
index f5e92ed297..00ab099772 100644
--- a/firmware/export/hosted_codec.h
+++ b/firmware/export/hosted_codec.h
@@ -25,7 +25,9 @@
25 && !(CONFIG_PLATFORM & PLATFORM_MAEMO5) 25 && !(CONFIG_PLATFORM & PLATFORM_MAEMO5)
26AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -80, 0, 0) 26AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -80, 0, 0)
27#else 27#else
28#if !defined(DX50) && !defined(DX90)
28#define AUDIOHW_CAPS (MONO_VOL_CAP) 29#define AUDIOHW_CAPS (MONO_VOL_CAP)
30#endif
29AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -99, 0, 0) 31AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -99, 0, 0)
30#endif /* CONFIG_PLATFORM & PLATFORM_SDL */ 32#endif /* CONFIG_PLATFORM & PLATFORM_SDL */
31 33
@@ -50,4 +52,4 @@ AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1)
50#endif 52#endif
51#endif /* CONFIG_PLATFORM & PLATFORM_ANDROID */ 53#endif /* CONFIG_PLATFORM & PLATFORM_ANDROID */
52 54
53#endif /* HOSTED_CODEC_H */ \ No newline at end of file 55#endif /* HOSTED_CODEC_H */
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index b6d4b9f66e..a4b260b315 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -679,6 +679,8 @@ static void power_thread(void)
679 /* Delay reading the first battery level */ 679 /* Delay reading the first battery level */
680#ifdef MROBE_100 680#ifdef MROBE_100
681 while (_battery_voltage() > 4200) /* gives false readings initially */ 681 while (_battery_voltage() > 4200) /* gives false readings initially */
682#elif defined(DX50) || defined(DX90)
683 while (_battery_voltage() < 1) /* can give false readings initially */
682#endif 684#endif
683 { 685 {
684 sleep(HZ/100); 686 sleep(HZ/100);
diff --git a/firmware/target/hosted/android/dx50/adc-target.h b/firmware/target/hosted/android/dx50/adc-target.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/adc-target.h
diff --git a/firmware/target/hosted/android/dx50/backlight-dx50.c b/firmware/target/hosted/android/dx50/backlight-dx50.c
new file mode 100644
index 0000000000..98dbcb8abe
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/backlight-dx50.c
@@ -0,0 +1,76 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2011 by Lorenzo Miori
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#include "config.h"
21#include "system.h"
22#include "backlight.h"
23#include "backlight-target.h"
24#include "lcd.h"
25#include "lcd-target.h"
26#include <fcntl.h>
27#include <stdio.h>
28#include "unistd.h"
29
30bool _backlight_init(void)
31{
32 /* We have nothing to do */
33 return true;
34}
35
36void _backlight_on(void)
37{
38 FILE *f = fopen("/sys/power/state", "w");
39 fputs("on", f);
40 fclose(f);
41 lcd_enable(true);
42}
43
44void _backlight_off(void)
45{
46 FILE * f;
47
48 /* deny the player to sleep deep */
49 f = fopen("/sys/power/wake_lock", "w");
50 fputs("player", f);
51 fclose(f);
52
53 /* deny the player to mute */
54 f = fopen("/sys/class/codec/wm8740_mute", "w");
55 fputc(0, f);
56 fclose(f);
57
58 /* turn off backlight */
59 f = fopen("/sys/power/state", "w");
60 fputs("mem", f);
61 fclose(f);
62
63}
64
65void _backlight_set_brightness(int brightness)
66{
67 /* Just another check... */
68 if (brightness > MAX_BRIGHTNESS_SETTING)
69 brightness = MAX_BRIGHTNESS_SETTING;
70 if (brightness < MIN_BRIGHTNESS_SETTING)
71 brightness = MIN_BRIGHTNESS_SETTING;
72
73 FILE *f = fopen("/sys/devices/platform/rk29_backlight/backlight/rk28_bl/brightness", "w");
74 fprintf(f, "%d", brightness);
75 fclose(f);
76}
diff --git a/firmware/target/hosted/android/dx50/backlight-target.h b/firmware/target/hosted/android/dx50/backlight-target.h
new file mode 100644
index 0000000000..67836aa790
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/backlight-target.h
@@ -0,0 +1,31 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
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 BACKLIGHT_TARGET_H
22#define BACKLIGHT_TARGET_H
23
24#include <stdbool.h>
25
26bool _backlight_init(void);
27void _backlight_on(void);
28void _backlight_off(void);
29void _backlight_set_brightness(int brightness);
30
31#endif /* BACKLIGHT_TARGET_H */
diff --git a/firmware/target/hosted/android/dx50/button-dx50.c b/firmware/target/hosted/android/dx50/button-dx50.c
new file mode 100644
index 0000000000..5ab58ce420
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/button-dx50.c
@@ -0,0 +1,314 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 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
23#include <stdbool.h>
24#include "button.h"
25#include "buttonmap.h"
26#include "config.h"
27#include "kernel.h"
28#include "system.h"
29#include "touchscreen.h"
30#include "powermgmt.h"
31#include "backlight.h"
32
33#include <linux/input.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <stdint.h>
38#include <dirent.h>
39#include <fcntl.h>
40#include <sys/ioctl.h>
41#include <sys/inotify.h>
42#include <sys/limits.h>
43#include <sys/poll.h>
44#include <errno.h>
45
46
47static struct pollfd *ufds;
48static char **device_names;
49static int nfds;
50
51enum {
52 PRINT_DEVICE_ERRORS = 1U << 0,
53 PRINT_DEVICE = 1U << 1,
54 PRINT_DEVICE_NAME = 1U << 2,
55 PRINT_DEVICE_INFO = 1U << 3,
56 PRINT_VERSION = 1U << 4,
57 PRINT_POSSIBLE_EVENTS = 1U << 5,
58 PRINT_INPUT_PROPS = 1U << 6,
59 PRINT_HID_DESCRIPTOR = 1U << 7,
60
61 PRINT_ALL_INFO = (1U << 8) - 1,
62
63 PRINT_LABELS = 1U << 16,
64};
65
66static int last_y, last_x;
67static int last_btns;
68
69static enum {
70 STATE_UNKNOWN,
71 STATE_UP,
72 STATE_DOWN
73} last_touch_state = STATE_UNKNOWN;
74
75
76static int open_device(const char *device, int print_flags)
77{
78 int fd;
79 struct pollfd *new_ufds;
80 char **new_device_names;
81
82 fd = open(device, O_RDWR);
83 if(fd < 0) {
84 if(print_flags & PRINT_DEVICE_ERRORS)
85 fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));
86 return -1;
87 }
88
89 new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
90 if(new_ufds == NULL) {
91 fprintf(stderr, "out of memory\n");
92 return -1;
93 }
94 ufds = new_ufds;
95 new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
96 if(new_device_names == NULL) {
97 fprintf(stderr, "out of memory\n");
98 return -1;
99 }
100 device_names = new_device_names;
101
102 ufds[nfds].fd = fd;
103 ufds[nfds].events = POLLIN;
104 device_names[nfds] = strdup(device);
105 nfds++;
106
107 return 0;
108}
109
110
111
112static int scan_dir(const char *dirname, int print_flags)
113{
114 char devname[PATH_MAX];
115 char *filename;
116 DIR *dir;
117 struct dirent *de;
118 dir = opendir(dirname);
119 if(dir == NULL)
120 return -1;
121 strcpy(devname, dirname);
122 filename = devname + strlen(devname);
123 *filename++ = '/';
124 while((de = readdir(dir))) {
125 if(de->d_name[0] == '.' &&
126 (de->d_name[1] == '\0' ||
127 (de->d_name[1] == '.' && de->d_name[2] == '\0')))
128 continue;
129 strcpy(filename, de->d_name);
130 open_device(devname, print_flags);
131 }
132 closedir(dir);
133 return 0;
134}
135
136bool _hold;
137
138bool button_hold()
139{
140 FILE *f = fopen("/sys/class/axppower/holdkey", "r");
141 char x;
142 fscanf(f, "%c", &x);
143 fclose(f);
144 _hold = !(x&STATE_UNLOCKED);
145 return _hold;
146}
147
148
149void button_init_device(void)
150{
151 int res;
152 int print_flags = 0;
153 const char *device = NULL;
154 const char *device_path = "/dev/input";
155
156 nfds = 1;
157 ufds = calloc(1, sizeof(ufds[0]));
158 ufds[0].fd = inotify_init();
159 ufds[0].events = POLLIN;
160 if(device) {
161 res = open_device(device, print_flags);
162 if(res < 0) {
163 // return 1;
164 }
165 } else {
166 res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
167 if(res < 0) {
168 fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));
169 // return 1;
170 }
171 res = scan_dir(device_path, print_flags);
172 if(res < 0) {
173 fprintf(stderr, "scan dir failed for %s\n", device_path);
174 // return 1;
175 }
176 }
177
178 button_hold(); //store state
179
180 set_rockbox_ready();
181}
182
183void touchscreen_enable_device(bool en)
184{
185 (void)en; /* FIXME: do something smart */
186}
187
188
189int keycode_to_button(int keyboard_key)
190{
191 switch(keyboard_key){
192 case KEYCODE_PWR:
193 return BUTTON_POWER;
194
195 case KEYCODE_PWR_LONG:
196 return BUTTON_POWER_LONG;
197
198 case KEYCODE_VOLPLUS:
199 return BUTTON_VOL_UP;
200
201 case KEYCODE_VOLMINUS:
202 return BUTTON_VOL_DOWN;
203
204 case KEYCODE_PREV:
205 return BUTTON_LEFT;
206
207 case KEYCODE_NEXT:
208 return BUTTON_RIGHT;
209
210 case KEYCODE_PLAY:
211 return BUTTON_PLAY;
212
213 case KEYCODE_HOLD:
214 button_hold(); /* store state */
215 backlight_hold_changed(_hold);
216 return BUTTON_NONE;
217
218 default:
219 return BUTTON_NONE;
220 }
221}
222
223
224int button_read_device(int *data)
225{
226 int i;
227 int res;
228 struct input_event event;
229 int read_more;
230 unsigned button = 0;
231
232 if(last_btns & BUTTON_POWER_LONG)
233 {
234 return last_btns; /* simulate repeat */
235 }
236
237 do {
238 read_more = 0;
239 poll(ufds, nfds, 10);
240 for(i = 1; i < nfds; i++) {
241 if(ufds[i].revents & POLLIN) {
242 res = read(ufds[i].fd, &event, sizeof(event));
243 if(res < (int)sizeof(event)) {
244 fprintf(stderr, "could not get event\n");
245 }
246
247 switch(event.type)
248 {
249 case 1: /* HW-Button */
250 button = keycode_to_button(event.code);
251 if (_hold) /* we have to wait for keycode_to_button() first to maybe clear hold state */
252 break;
253 if (button == BUTTON_NONE)
254 {
255 last_btns = button;
256 break;
257 }
258/* workaround for a wrong feedback, only present with DX90 */
259#if defined(DX90)
260 if (button == BUTTON_RIGHT && (last_btns & BUTTON_LEFT == BUTTON_LEFT) && !event.value)
261 {
262 button = BUTTON_LEFT;
263 }
264#endif
265 if (event.value)
266 last_btns |= button;
267 else
268 last_btns &= (~button);
269
270 break;
271
272 case 3: /* Touchscreen */
273 if(_hold)
274 break;
275
276 switch(event.code)
277 {
278 case 53: /* x -> next will be y */
279 last_x = event.value;
280 read_more = 1;
281 break;
282 case 54: /* y */
283 last_y = event.value;
284 break;
285 case 57: /* press -> next will be x */
286 if(event.value==1)
287 {
288 last_touch_state = STATE_DOWN;
289 read_more = 1;
290 }
291 else
292 last_touch_state = STATE_UP;
293 break;
294 }
295 break;
296 }
297 }
298 }
299 } while(read_more);
300
301
302 /* Get grid button/coordinates based on the current touchscreen mode
303 *
304 * Caveat: the caller seemingly depends on *data always being filled with
305 * the last known touchscreen position, so always call
306 * touchscreen_to_pixels() */
307 int touch = touchscreen_to_pixels(last_x, last_y, data);
308
309 if (last_touch_state == STATE_DOWN)
310 return last_btns | touch;
311
312 return last_btns;
313}
314
diff --git a/firmware/target/hosted/android/dx50/button-target.h b/firmware/target/hosted/android/dx50/button-target.h
new file mode 100644
index 0000000000..adc9cf6bfd
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/button-target.h
@@ -0,0 +1,72 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Rob Purchase
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.r
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 _BUTTON_TARGET_H_
23#define _BUTTON_TARGET_H_
24
25#include <stdbool.h>
26
27#define HAS_BUTTON_HOLD
28
29/* Main unit's buttons */
30#define BUTTON_LEFT 0x00000001
31#define BUTTON_RIGHT 0x00000002
32#define BUTTON_PLAY 0x00000004
33#define BUTTON_POWER 0x00000008
34#define BUTTON_VOL_UP 0x00000010
35#define BUTTON_VOL_DOWN 0x00000020
36#define BUTTON_POWER_LONG 0x00000040
37
38#define BUTTON_MAIN (BUTTON_LEFT|BUTTON_VOL_UP|BUTTON_VOL_DOWN\
39 |BUTTON_RIGHT|BUTTON_PLAY|BUTTON_POWER|BUTTON_POWER_LONG)
40
41#define KEYCODE_LINEOUT 113
42#define KEYCODE_SPDIF 114
43#define KEYCODE_HOLD 115
44#define KEYCODE_PWR 116
45#define KEYCODE_PWR_LONG 117
46#define KEYCODE_SD 143
47#define KEYCODE_VOLPLUS 158
48#define KEYCODE_VOLMINUS 159
49#define KEYCODE_PREV 160
50#define KEYCODE_NEXT 162
51#define KEYCODE_PLAY 161
52#define STATE_UNLOCKED 16
53#define STATE_SPDIF_UNPLUGGED 32
54#define STATE_LINEOUT_UNPLUGGED 64
55
56/* Touch Screen Area Buttons */
57#define BUTTON_TOPLEFT 0x00001000
58#define BUTTON_TOPMIDDLE 0x00002000
59#define BUTTON_TOPRIGHT 0x00004000
60#define BUTTON_MIDLEFT 0x00008000
61#define BUTTON_CENTER 0x00010000
62#define BUTTON_MIDRIGHT 0x00020000
63#define BUTTON_BOTTOMLEFT 0x00040000
64#define BUTTON_BOTTOMMIDDLE 0x00080000
65#define BUTTON_BOTTOMRIGHT 0x00100000
66
67
68/* Software power-off */
69#define POWEROFF_BUTTON BUTTON_POWER_LONG
70#define POWEROFF_COUNT 0
71
72#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/hosted/android/dx50/lcd-dx50.c b/firmware/target/hosted/android/dx50/lcd-dx50.c
new file mode 100644
index 0000000000..4d78baaf00
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/lcd-dx50.c
@@ -0,0 +1,120 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: lcd-bitmap.c 29248 2011-02-08 20:05:25Z thomasjfox $
9 *
10 * Copyright (C) 2011 Lorenzo Miori, Thomas Martitz
11 * Copyright (C) 2013 Lorenzo Miori
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 <stdlib.h>
24#include <unistd.h>
25#include <stdio.h>
26#include <linux/fb.h>
27#include <sys/mman.h>
28#include <sys/ioctl.h>
29#include "config.h"
30#include "file.h"
31#include "debug.h"
32#include "system.h"
33#include "screendump.h"
34#include "lcd.h"
35#include "lcd-target.h"
36
37static int dev_fd = 0;
38fb_data *dev_fb = 0;
39
40#ifdef HAVE_LCD_SHUTDOWN
41void lcd_shutdown(void)
42{
43 printf("FB closed.");
44 munmap(dev_fb, FRAMEBUFFER_SIZE);
45 close(dev_fd);
46}
47#endif
48
49void lcd_init_device(void)
50{
51 size_t screensize;
52 struct fb_var_screeninfo vinfo;
53 struct fb_fix_screeninfo finfo;
54
55 /* Open the framebuffer device */
56 dev_fd = open("/dev/graphics/fb0", O_RDWR);
57 if (dev_fd == -1) {
58 perror("Error: cannot open framebuffer device");
59 exit(1);
60 }
61
62 /* Get the fixed properties */
63 if (ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
64 perror("Error reading fixed information");
65 exit(2);
66 }
67
68
69 /* Now we get the settable settings, and we set 16 bit bpp */
70 if (ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
71 perror("Error reading variable information");
72 exit(3);
73 }
74 /* framebuffer does not fit the screen, a bug of iBassos Firmware, not rockbox.
75 cannot be solved with parameters */
76 vinfo.bits_per_pixel = LCD_DEPTH;
77 vinfo.xres = vinfo.xres_virtual = vinfo.width = LCD_WIDTH;
78 vinfo.yres = vinfo.yres_virtual = vinfo.height = LCD_HEIGHT;
79
80 if (ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo)) {
81 perror("fbset(ioctl)");
82 exit(4);
83 }
84
85 /* Figure out the size of the screen in bytes */
86 screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
87 if (screensize != FRAMEBUFFER_SIZE) {
88 exit(4);
89 perror("Display and framebuffer mismatch!\n");
90 }
91
92 /* Map the device to memory */
93 dev_fb = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
94 if ((int)dev_fb == -1) {
95 perror("Error: failed to map framebuffer device to memory");
96 exit(4);
97 }
98
99 /* Be sure to turn on display at startup */
100 ioctl(dev_fd, FBIOBLANK, VESA_NO_BLANKING);
101#ifdef HAVE_LCD_ENABLE
102 lcd_set_active(true);
103#endif
104}
105
106#ifdef HAVE_LCD_ENABLE
107void lcd_enable(bool enable)
108 {
109 if (lcd_active() == enable)
110 return;
111
112 lcd_set_active(enable);
113
114 /* Turn on or off the display using Linux interface */
115 ioctl(dev_fd, FBIOBLANK, enable ? VESA_NO_BLANKING : VESA_POWERDOWN);
116
117 if (enable)
118 send_event(LCD_EVENT_ACTIVATION, NULL);
119}
120#endif
diff --git a/firmware/target/hosted/android/dx50/lcd-target.h b/firmware/target/hosted/android/dx50/lcd-target.h
new file mode 100644
index 0000000000..900350eca2
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/lcd-target.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef __LCD_TARGET_H__
21#define __LCD_TARGET_H__
22
23extern fb_data *dev_fb;
24#define LCD_FRAMEBUF_ADDR(col, row) (dev_fb + row*LCD_WIDTH + col)
25#ifdef HAVE_LCD_ENABLE
26extern void lcd_set_active(bool active);
27extern void lcd_enable(bool enable);
28#endif
29#endif
diff --git a/firmware/target/hosted/android/dx50/pcm-dx50.c b/firmware/target/hosted/android/dx50/pcm-dx50.c
new file mode 100644
index 0000000000..e7695873a0
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/pcm-dx50.c
@@ -0,0 +1,364 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 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
23/*
24 * Based, but heavily modified, on the example given at
25 * http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html
26 *
27 * This driver uses the so-called unsafe async callback method and hardcoded device
28 * names. It fails when the audio device is busy by other apps.
29 *
30 * To make the async callback safer, an alternative stack is installed, since
31 * it's run from a signal hanlder (which otherwise uses the user stack). If
32 * tick tasks are run from a signal handler too, please install
33 * an alternative stack for it too.
34 *
35 * TODO: Rewrite this to do it properly with multithreading
36 *
37 * Alternatively, a version using polling in a tick task is provided. While
38 * supposedly safer, it appears to use more CPU (however I didn't measure it
39 * accurately, only looked at htop). At least, in this mode the "default"
40 * device works which doesnt break with other apps running.
41 */
42
43
44#include "autoconf.h"
45
46#include <stdlib.h>
47#include <stdbool.h>
48#include <stdio.h>
49#include <errno.h>
50#include "tinyalsa/asoundlib.h"
51#include "tinyalsa/asound.h"
52#include "system.h"
53#include "debug.h"
54#include "kernel.h"
55
56#include "pcm.h"
57#include "pcm-internal.h"
58#include "pcm_mixer.h"
59#include "pcm_sampr.h"
60#include "audiohw.h"
61
62#include <pthread.h>
63#include <signal.h>
64
65static const snd_pcm_format_t format = PCM_FORMAT_S16_LE; /* sample format */
66static const int channels = 2; /* count of channels */
67static unsigned int rate = 44100; /* stream rate */
68
69typedef struct pcm snd_pcm_t;
70static snd_pcm_t *handle;
71struct pcm_config config;
72
73static snd_pcm_sframes_t period_size = 512; /* if set to >= 1024, all timers become even slower */
74static char *frames;
75
76static const void *pcm_data = 0;
77static size_t pcm_size = 0;
78
79static int recursion;
80
81static int set_hwparams(snd_pcm_t *handle)
82{
83 int err;
84 if (!frames)
85 frames = malloc(pcm_frames_to_bytes(handle, pcm_get_buffer_size(handle)));
86 err = 0; /* success */
87 return err;
88}
89
90
91/* copy pcm samples to a spare buffer, suitable for snd_pcm_writei() */
92static bool fill_frames(void)
93{
94 size_t copy_n, frames_left = period_size;
95 bool new_buffer = false;
96
97 while (frames_left > 0)
98 {
99 if (!pcm_size)
100 {
101 new_buffer = true;
102 if (!pcm_play_dma_complete_callback(PCM_DMAST_OK, &pcm_data,
103 &pcm_size))
104 {
105 return false;
106 }
107 }
108 copy_n = MIN((size_t)pcm_size, pcm_frames_to_bytes(handle, frames_left));
109 memcpy(&frames[pcm_frames_to_bytes(handle, period_size-frames_left)], pcm_data, copy_n);
110
111 pcm_data += copy_n;
112 pcm_size -= copy_n;
113 frames_left -= pcm_bytes_to_frames(handle, copy_n);
114
115 if (new_buffer)
116 {
117 new_buffer = false;
118 pcm_play_dma_status_callback(PCM_DMAST_STARTED);
119 }
120 }
121 return true;
122}
123
124
125static void pcm_tick(void)
126{
127 if (fill_frames())
128 {
129 if (pcm_write(handle, frames, pcm_frames_to_bytes(handle, period_size))) {
130 printf("Error playing sample\n");
131 return;//break;
132 }
133
134 }
135 else
136 {
137 DEBUGF("%s: No Data.\n", __func__);
138 return;//break;
139 }
140}
141
142static int async_rw(snd_pcm_t *handle)
143{
144 int err;
145 snd_pcm_sframes_t sample_size;
146 char *samples;
147
148 /* fill buffer with silence to initiate playback without noisy click */
149 sample_size = pcm_frames_to_bytes(handle, pcm_get_buffer_size(handle));
150 samples = malloc(sample_size);
151
152 memset(samples, 0, sample_size);
153
154 err = pcm_write(handle, samples, sample_size);
155 free(samples);
156
157 if (err != 0)
158 {
159 DEBUGF("Initial write error: %d\n", err);
160 return err;
161 }
162 if (pcm_state(handle) == PCM_STATE_PREPARED)
163 {
164 err = pcm_start(handle);
165 if (err < 0)
166 {
167 DEBUGF("Start error: %d\n", err);
168 return err;
169 }
170 }
171 return 0;
172}
173
174void cleanup(void)
175{
176 free(frames);
177 frames = NULL;
178 pcm_close(handle);
179}
180
181void pcm_play_dma_init(void)
182{
183 config.channels = channels;
184 config.rate = rate;
185 config.period_size = period_size;
186 config.period_count = 4;
187 config.format = format;
188 config.start_threshold = 0;
189 config.stop_threshold = 0;
190 config.silence_threshold = 0;
191
192
193 handle = pcm_open(0, 0, PCM_OUT, &config);
194 if (!handle || !pcm_is_ready(handle)) {
195 printf("Unable to open PCM device: %s\n", pcm_get_error(handle));
196 return;
197 }
198
199 pcm_dma_apply_settings();
200
201 tick_add_task(pcm_tick);
202
203 atexit(cleanup);
204 return;
205}
206
207
208void pcm_play_lock(void)
209{
210 if (recursion++ == 0)
211 tick_remove_task(pcm_tick);
212}
213
214void pcm_play_unlock(void)
215{
216 if (--recursion == 0)
217 tick_add_task(pcm_tick);
218}
219
220static void pcm_dma_apply_settings_nolock(void)
221{
222 set_hwparams(handle);
223}
224
225void pcm_dma_apply_settings(void)
226{
227 pcm_play_lock();
228 pcm_dma_apply_settings_nolock();
229 pcm_play_unlock();
230}
231
232
233void pcm_play_dma_pause(bool pause)
234{
235 (void)pause;
236}
237
238
239void pcm_play_dma_stop(void)
240{
241 pcm_stop(handle);
242}
243
244void pcm_play_dma_start(const void *addr, size_t size)
245{
246#if defined(DX50) || defined(DX90)
247 /* headphone output relay: if this is done at startup already, a loud click is audible on headphones. Here, some time later,
248 the output caps are charged a bit and the click is much softer */
249 system("/system/bin/muteopen");
250#endif
251 pcm_dma_apply_settings_nolock();
252
253 pcm_data = addr;
254 pcm_size = size;
255
256 while (1)
257 {
258 snd_pcm_state_t state = pcm_state(handle);
259 switch (state)
260 {
261 case PCM_STATE_RUNNING:
262 return;
263 case PCM_STATE_XRUN:
264 {
265 printf("No handler for STATE_XRUN!\n");
266 continue;
267 }
268 case PCM_STATE_PREPARED:
269 { /* prepared state, we need to fill the buffer with silence before
270 * starting */
271 int err = async_rw(handle);
272 if (err < 0)
273 printf("Start error: %d\n", err);
274 return;
275 }
276 case PCM_STATE_PAUSED:
277 { /* paused, simply resume */
278 pcm_play_dma_pause(0);
279 return;
280 }
281 case PCM_STATE_DRAINING:
282 /* run until drained */
283 continue;
284 default:
285 DEBUGF("Unhandled state: %d\n", state);
286 return;
287 }
288 }
289}
290
291size_t pcm_get_bytes_waiting(void)
292{
293 return pcm_size;
294}
295
296const void * pcm_play_dma_get_peak_buffer(int *count)
297{
298 uintptr_t addr = (uintptr_t)pcm_data;
299 *count = pcm_size / 4;
300 return (void *)((addr + 3) & ~3);
301}
302
303void pcm_play_dma_postinit(void)
304{
305 return;
306}
307
308void pcm_set_mixer_volume(int volume)
309{
310#if defined(DX50) || defined(DX90)
311 /* -990 to 0 -> 0 to 255 */
312 int val = (volume+990)*255/990;
313#if defined(DX50)
314 FILE *f = fopen("/dev/codec_volume", "w");
315#else /* DX90 */
316 FILE *f = fopen("/sys/class/codec/es9018_volume", "w");
317#endif /* DX50 */
318 fprintf(f, "%d", val);
319 fclose(f);
320#else
321 (void)volume;
322#endif /* DX50 || DX90 */
323}
324
325#ifdef HAVE_RECORDING
326void pcm_rec_lock(void)
327{
328}
329
330void pcm_rec_unlock(void)
331{
332}
333
334void pcm_rec_dma_init(void)
335{
336}
337
338void pcm_rec_dma_close(void)
339{
340}
341
342void pcm_rec_dma_start(void *start, size_t size)
343{
344 (void)start;
345 (void)size;
346}
347
348void pcm_rec_dma_stop(void)
349{
350}
351
352const void * pcm_rec_dma_get_peak_buffer(void)
353{
354 return NULL;
355}
356
357void audiohw_set_recvol(int left, int right, int type)
358{
359 (void)left;
360 (void)right;
361 (void)type;
362}
363
364#endif /* HAVE_RECORDING */
diff --git a/firmware/target/hosted/android/dx50/powermgmt-dx50.c b/firmware/target/hosted/android/dx50/powermgmt-dx50.c
new file mode 100644
index 0000000000..45756cb8e8
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/powermgmt-dx50.c
@@ -0,0 +1,72 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 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#include <stdbool.h>
23#include <stdio.h>
24#include "config.h"
25#include "power.h"
26#include "powermgmt.h"
27
28unsigned int power_input_status(void)
29{
30 int val;
31 FILE *f = fopen("/sys/class/power_supply/ac/present", "r");
32 fscanf(f, "%d", &val);
33 fclose(f);
34 return val?POWER_INPUT_MAIN_CHARGER:POWER_INPUT_NONE;
35}
36
37/* Values for stock PISEN battery. TODO: Needs optimization */
38
39const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
40{
41 3380
42};
43
44const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
45{
46 3100
47};
48
49/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
50const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
51{
52 { 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4090, 4190 }
53};
54
55/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
56const unsigned short percent_to_volt_charge[11] =
57{
58 3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4220 /* LiPo */
59};
60
61
62/* Returns battery voltage from android measurement [millivolts] */
63int _battery_voltage(void)
64{
65 int val;
66 FILE *f = fopen("/sys/class/power_supply/battery/voltage_now", "r");
67 fscanf(f, "%d", &val);
68 fclose(f);
69 return (val/1000);
70}
71
72
diff --git a/firmware/target/hosted/android/dx50/tinyalsa/asound.h b/firmware/target/hosted/android/dx50/tinyalsa/asound.h
new file mode 100644
index 0000000000..fc1e4f6d67
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/tinyalsa/asound.h
@@ -0,0 +1,821 @@
1/****************************************************************************
2 ****************************************************************************
3 ***
4 *** This header was automatically generated from a Linux kernel header
5 *** of the same name, to make information necessary for userspace to
6 *** call into the kernel available to libc. It contains only constants,
7 *** structures, and macros generated from the original header, and thus,
8 *** contains no copyrightable information.
9 ***
10 ****************************************************************************
11 ****************************************************************************/
12#ifndef __SOUND_ASOUND_H
13#define __SOUND_ASOUND_H
14
15#include <linux/types.h>
16
17#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor))
18#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff)
19#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff)
20#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff)
21#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
22
23struct snd_aes_iec958 {
24 unsigned char status[24];
25 unsigned char subcode[147];
26 unsigned char pad;
27 unsigned char dig_subframe[4];
28};
29
30#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
31
32enum {
33 SNDRV_HWDEP_IFACE_OPL2 = 0,
34 SNDRV_HWDEP_IFACE_OPL3,
35 SNDRV_HWDEP_IFACE_OPL4,
36 SNDRV_HWDEP_IFACE_SB16CSP,
37 SNDRV_HWDEP_IFACE_EMU10K1,
38 SNDRV_HWDEP_IFACE_YSS225,
39 SNDRV_HWDEP_IFACE_ICS2115,
40 SNDRV_HWDEP_IFACE_SSCAPE,
41 SNDRV_HWDEP_IFACE_VX,
42 SNDRV_HWDEP_IFACE_MIXART,
43 SNDRV_HWDEP_IFACE_USX2Y,
44 SNDRV_HWDEP_IFACE_EMUX_WAVETABLE,
45 SNDRV_HWDEP_IFACE_BLUETOOTH,
46 SNDRV_HWDEP_IFACE_USX2Y_PCM,
47 SNDRV_HWDEP_IFACE_PCXHR,
48 SNDRV_HWDEP_IFACE_SB_RC,
49 SNDRV_HWDEP_IFACE_HDA,
50 SNDRV_HWDEP_IFACE_USB_STREAM,
51
52 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
53};
54
55struct snd_hwdep_info {
56 unsigned int device;
57 int card;
58 unsigned char id[64];
59 unsigned char name[80];
60 int iface;
61 unsigned char reserved[64];
62};
63
64struct snd_hwdep_dsp_status {
65 unsigned int version;
66 unsigned char id[32];
67 unsigned int num_dsps;
68 unsigned int dsp_loaded;
69 unsigned int chip_ready;
70 unsigned char reserved[16];
71};
72
73struct snd_hwdep_dsp_image {
74 unsigned int index;
75 unsigned char name[64];
76 unsigned char __user *image;
77 size_t length;
78 unsigned long driver_data;
79};
80
81#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int)
82#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct snd_hwdep_info)
83#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
84#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
85
86#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10)
87
88typedef unsigned long snd_pcm_uframes_t;
89typedef signed long snd_pcm_sframes_t;
90
91enum {
92 SNDRV_PCM_CLASS_GENERIC = 0,
93 SNDRV_PCM_CLASS_MULTI,
94 SNDRV_PCM_CLASS_MODEM,
95 SNDRV_PCM_CLASS_DIGITIZER,
96
97 SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER,
98};
99
100enum {
101 SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0,
102 SNDRV_PCM_SUBCLASS_MULTI_MIX,
103
104 SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX,
105};
106
107enum {
108 SNDRV_PCM_STREAM_PLAYBACK = 0,
109 SNDRV_PCM_STREAM_CAPTURE,
110 SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
111};
112
113typedef int __bitwise snd_pcm_access_t;
114#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0)
115#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1)
116#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2)
117#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3)
118#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4)
119#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
120
121typedef int __bitwise snd_pcm_format_t;
122#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0)
123#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1)
124#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2)
125#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3)
126#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4)
127#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5)
128#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6)
129#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7)
130#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8)
131#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9)
132#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10)
133#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11)
134#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12)
135#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13)
136#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14)
137#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15)
138#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16)
139#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17)
140#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18)
141#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19)
142#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20)
143#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21)
144#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22)
145#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23)
146#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24)
147#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31)
148#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32)
149#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33)
150#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34)
151#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35)
152#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36)
153#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37)
154#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38)
155#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39)
156#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40)
157#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41)
158#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42)
159#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43)
160#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44)
161#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45)
162#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46)
163#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47)
164#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_G723_40_1B
165
166#ifdef SNDRV_LITTLE_ENDIAN
167#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_LE
168#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_LE
169#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_LE
170#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_LE
171#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_LE
172#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_LE
173#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE
174#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE
175#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
176#endif
177#ifdef SNDRV_BIG_ENDIAN
178#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE
179#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_BE
180#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_BE
181#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_BE
182#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_BE
183#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_BE
184#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE
185#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE
186#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
187#endif
188
189typedef int __bitwise snd_pcm_subformat_t;
190#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
191#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
192
193#define SNDRV_PCM_INFO_MMAP 0x00000001
194#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
195#define SNDRV_PCM_INFO_DOUBLE 0x00000004
196#define SNDRV_PCM_INFO_BATCH 0x00000010
197#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100
198#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200
199#define SNDRV_PCM_INFO_COMPLEX 0x00000400
200#define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000
201#define SNDRV_PCM_INFO_OVERRANGE 0x00020000
202#define SNDRV_PCM_INFO_RESUME 0x00040000
203#define SNDRV_PCM_INFO_PAUSE 0x00080000
204#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000
205#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000
206#define SNDRV_PCM_INFO_SYNC_START 0x00400000
207#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000
208#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000
209
210typedef int __bitwise snd_pcm_state_t;
211#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0)
212#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1)
213#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2)
214#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3)
215#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4)
216#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5)
217#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6)
218#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7)
219#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8)
220#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
221
222enum {
223 SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
224 SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
225 SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
226};
227
228union snd_pcm_sync_id {
229 unsigned char id[16];
230 unsigned short id16[8];
231 unsigned int id32[4];
232};
233
234struct snd_pcm_info {
235 unsigned int device;
236 unsigned int subdevice;
237 int stream;
238 int card;
239 unsigned char id[64];
240 unsigned char name[80];
241 unsigned char subname[32];
242 int dev_class;
243 int dev_subclass;
244 unsigned int subdevices_count;
245 unsigned int subdevices_avail;
246 union snd_pcm_sync_id sync;
247 unsigned char reserved[64];
248};
249
250typedef int snd_pcm_hw_param_t;
251#define SNDRV_PCM_HW_PARAM_ACCESS 0
252#define SNDRV_PCM_HW_PARAM_FORMAT 1
253#define SNDRV_PCM_HW_PARAM_SUBFORMAT 2
254#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS
255#define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT
256
257#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8
258#define SNDRV_PCM_HW_PARAM_FRAME_BITS 9
259#define SNDRV_PCM_HW_PARAM_CHANNELS 10
260#define SNDRV_PCM_HW_PARAM_RATE 11
261#define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12
262#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13
263#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14
264#define SNDRV_PCM_HW_PARAM_PERIODS 15
265#define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16
266#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17
267#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18
268#define SNDRV_PCM_HW_PARAM_TICK_TIME 19
269#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS
270#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME
271
272#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0)
273#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1)
274#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2)
275
276struct snd_interval {
277 unsigned int min, max;
278 unsigned int openmin:1,
279 openmax:1,
280 integer:1,
281 empty:1;
282};
283
284#define SNDRV_MASK_MAX 256
285
286struct snd_mask {
287 __u32 bits[(SNDRV_MASK_MAX+31)/32];
288};
289
290struct snd_pcm_hw_params {
291 unsigned int flags;
292 struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
293 SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
294 struct snd_mask mres[5];
295 struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
296 SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
297 struct snd_interval ires[9];
298 unsigned int rmask;
299 unsigned int cmask;
300 unsigned int info;
301 unsigned int msbits;
302 unsigned int rate_num;
303 unsigned int rate_den;
304 snd_pcm_uframes_t fifo_size;
305 unsigned char reserved[64];
306};
307
308enum {
309 SNDRV_PCM_TSTAMP_NONE = 0,
310 SNDRV_PCM_TSTAMP_ENABLE,
311 SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE,
312};
313
314struct snd_pcm_sw_params {
315 int tstamp_mode;
316 unsigned int period_step;
317 unsigned int sleep_min;
318 snd_pcm_uframes_t avail_min;
319 snd_pcm_uframes_t xfer_align;
320 snd_pcm_uframes_t start_threshold;
321 snd_pcm_uframes_t stop_threshold;
322 snd_pcm_uframes_t silence_threshold;
323 snd_pcm_uframes_t silence_size;
324 snd_pcm_uframes_t boundary;
325 unsigned char reserved[64];
326};
327
328struct snd_pcm_channel_info {
329 unsigned int channel;
330 __kernel_off_t offset;
331 unsigned int first;
332 unsigned int step;
333};
334
335struct snd_pcm_status {
336 snd_pcm_state_t state;
337 struct timespec trigger_tstamp;
338 struct timespec tstamp;
339 snd_pcm_uframes_t appl_ptr;
340 snd_pcm_uframes_t hw_ptr;
341 snd_pcm_sframes_t delay;
342 snd_pcm_uframes_t avail;
343 snd_pcm_uframes_t avail_max;
344 snd_pcm_uframes_t overrange;
345 snd_pcm_state_t suspended_state;
346 unsigned char reserved[60];
347};
348
349struct snd_pcm_mmap_status {
350 snd_pcm_state_t state;
351 int pad1;
352 snd_pcm_uframes_t hw_ptr;
353 struct timespec tstamp;
354 snd_pcm_state_t suspended_state;
355};
356
357struct snd_pcm_mmap_control {
358 snd_pcm_uframes_t appl_ptr;
359 snd_pcm_uframes_t avail_min;
360};
361
362#define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0)
363#define SNDRV_PCM_SYNC_PTR_APPL (1<<1)
364#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2)
365
366struct snd_pcm_sync_ptr {
367 unsigned int flags;
368 union {
369 struct snd_pcm_mmap_status status;
370 unsigned char reserved[64];
371 } s;
372 union {
373 struct snd_pcm_mmap_control control;
374 unsigned char reserved[64];
375 } c;
376};
377
378struct snd_xferi {
379 snd_pcm_sframes_t result;
380 void __user *buf;
381 snd_pcm_uframes_t frames;
382};
383
384struct snd_xfern {
385 snd_pcm_sframes_t result;
386 void __user * __user *bufs;
387 snd_pcm_uframes_t frames;
388};
389
390enum {
391 SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,
392 SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
393 SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
394};
395
396#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int)
397#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info)
398#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
399#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int)
400#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params)
401#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params)
402#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
403#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct snd_pcm_sw_params)
404#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status)
405#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t)
406#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
407#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr)
408#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info)
409#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40)
410#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41)
411#define SNDRV_PCM_IOCTL_START _IO('A', 0x42)
412#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
413#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44)
414#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int)
415#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t)
416#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
417#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48)
418#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t)
419#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi)
420#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi)
421#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern)
422#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern)
423#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
424#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
425
426#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0)
427
428enum {
429 SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
430 SNDRV_RAWMIDI_STREAM_INPUT,
431 SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
432};
433
434#define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001
435#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
436#define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004
437
438struct snd_rawmidi_info {
439 unsigned int device;
440 unsigned int subdevice;
441 int stream;
442 int card;
443 unsigned int flags;
444 unsigned char id[64];
445 unsigned char name[80];
446 unsigned char subname[32];
447 unsigned int subdevices_count;
448 unsigned int subdevices_avail;
449 unsigned char reserved[64];
450};
451
452struct snd_rawmidi_params {
453 int stream;
454 size_t buffer_size;
455 size_t avail_min;
456 unsigned int no_active_sensing: 1;
457 unsigned char reserved[16];
458};
459
460struct snd_rawmidi_status {
461 int stream;
462 struct timespec tstamp;
463 size_t avail;
464 size_t xruns;
465 unsigned char reserved[16];
466};
467
468#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
469#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info)
470#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params)
471#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
472#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
473#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
474
475#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
476
477enum {
478 SNDRV_TIMER_CLASS_NONE = -1,
479 SNDRV_TIMER_CLASS_SLAVE = 0,
480 SNDRV_TIMER_CLASS_GLOBAL,
481 SNDRV_TIMER_CLASS_CARD,
482 SNDRV_TIMER_CLASS_PCM,
483 SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM,
484};
485
486enum {
487 SNDRV_TIMER_SCLASS_NONE = 0,
488 SNDRV_TIMER_SCLASS_APPLICATION,
489 SNDRV_TIMER_SCLASS_SEQUENCER,
490 SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
491 SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
492};
493
494#define SNDRV_TIMER_GLOBAL_SYSTEM 0
495#define SNDRV_TIMER_GLOBAL_RTC 1
496#define SNDRV_TIMER_GLOBAL_HPET 2
497#define SNDRV_TIMER_GLOBAL_HRTIMER 3
498
499#define SNDRV_TIMER_FLG_SLAVE (1<<0)
500
501struct snd_timer_id {
502 int dev_class;
503 int dev_sclass;
504 int card;
505 int device;
506 int subdevice;
507};
508
509struct snd_timer_ginfo {
510 struct snd_timer_id tid;
511 unsigned int flags;
512 int card;
513 unsigned char id[64];
514 unsigned char name[80];
515 unsigned long reserved0;
516 unsigned long resolution;
517 unsigned long resolution_min;
518 unsigned long resolution_max;
519 unsigned int clients;
520 unsigned char reserved[32];
521};
522
523struct snd_timer_gparams {
524 struct snd_timer_id tid;
525 unsigned long period_num;
526 unsigned long period_den;
527 unsigned char reserved[32];
528};
529
530struct snd_timer_gstatus {
531 struct snd_timer_id tid;
532 unsigned long resolution;
533 unsigned long resolution_num;
534 unsigned long resolution_den;
535 unsigned char reserved[32];
536};
537
538struct snd_timer_select {
539 struct snd_timer_id id;
540 unsigned char reserved[32];
541};
542
543struct snd_timer_info {
544 unsigned int flags;
545 int card;
546 unsigned char id[64];
547 unsigned char name[80];
548 unsigned long reserved0;
549 unsigned long resolution;
550 unsigned char reserved[64];
551};
552
553#define SNDRV_TIMER_PSFLG_AUTO (1<<0)
554#define SNDRV_TIMER_PSFLG_EXCLUSIVE (1<<1)
555#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2)
556
557struct snd_timer_params {
558 unsigned int flags;
559 unsigned int ticks;
560 unsigned int queue_size;
561 unsigned int reserved0;
562 unsigned int filter;
563 unsigned char reserved[60];
564};
565
566struct snd_timer_status {
567 struct timespec tstamp;
568 unsigned int resolution;
569 unsigned int lost;
570 unsigned int overrun;
571 unsigned int queue;
572 unsigned char reserved[64];
573};
574
575#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
576#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id)
577#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
578#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo)
579#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams)
580#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus)
581#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select)
582#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info)
583#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params)
584#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status)
585
586#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0)
587#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
588#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
589#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
590
591struct snd_timer_read {
592 unsigned int resolution;
593 unsigned int ticks;
594};
595
596enum {
597 SNDRV_TIMER_EVENT_RESOLUTION = 0,
598 SNDRV_TIMER_EVENT_TICK,
599 SNDRV_TIMER_EVENT_START,
600 SNDRV_TIMER_EVENT_STOP,
601 SNDRV_TIMER_EVENT_CONTINUE,
602 SNDRV_TIMER_EVENT_PAUSE,
603 SNDRV_TIMER_EVENT_EARLY,
604 SNDRV_TIMER_EVENT_SUSPEND,
605 SNDRV_TIMER_EVENT_RESUME,
606
607 SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
608 SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
609 SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
610 SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
611 SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10,
612 SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10,
613};
614
615struct snd_timer_tread {
616 int event;
617 struct timespec tstamp;
618 unsigned int val;
619};
620
621#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
622
623struct snd_ctl_card_info {
624 int card;
625 int pad;
626 unsigned char id[16];
627 unsigned char driver[16];
628 unsigned char name[32];
629 unsigned char longname[80];
630 unsigned char reserved_[16];
631 unsigned char mixername[80];
632 unsigned char components[128];
633};
634
635typedef int __bitwise snd_ctl_elem_type_t;
636#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0)
637#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1)
638#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2)
639#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3)
640#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4)
641#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5)
642#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6)
643#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64
644
645typedef int __bitwise snd_ctl_elem_iface_t;
646#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0)
647#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1)
648#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2)
649#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3)
650#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4)
651#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5)
652#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6)
653#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER
654
655#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0)
656#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1)
657#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
658#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2)
659#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3)
660#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4)
661#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5)
662#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
663#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1<<6)
664#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8)
665#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9)
666#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10)
667#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28)
668#define SNDRV_CTL_ELEM_ACCESS_USER (1<<29)
669
670#define SNDRV_CTL_POWER_D0 0x0000
671#define SNDRV_CTL_POWER_D1 0x0100
672#define SNDRV_CTL_POWER_D2 0x0200
673#define SNDRV_CTL_POWER_D3 0x0300
674#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000)
675#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001)
676
677struct snd_ctl_elem_id {
678 unsigned int numid;
679 snd_ctl_elem_iface_t iface;
680 unsigned int device;
681 unsigned int subdevice;
682 unsigned char name[44];
683 unsigned int index;
684};
685
686struct snd_ctl_elem_list {
687 unsigned int offset;
688 unsigned int space;
689 unsigned int used;
690 unsigned int count;
691 struct snd_ctl_elem_id __user *pids;
692 unsigned char reserved[50];
693};
694
695struct snd_ctl_elem_info {
696 struct snd_ctl_elem_id id;
697 snd_ctl_elem_type_t type;
698 unsigned int access;
699 unsigned int count;
700 __kernel_pid_t owner;
701 union {
702 struct {
703 long min;
704 long max;
705 long step;
706 } integer;
707 struct {
708 long long min;
709 long long max;
710 long long step;
711 } integer64;
712 struct {
713 unsigned int items;
714 unsigned int item;
715 char name[64];
716 } enumerated;
717 unsigned char reserved[128];
718 } value;
719 union {
720 unsigned short d[4];
721 unsigned short *d_ptr;
722 } dimen;
723 unsigned char reserved[64-4*sizeof(unsigned short)];
724};
725
726struct snd_ctl_elem_value {
727 struct snd_ctl_elem_id id;
728 unsigned int indirect: 1;
729 union {
730 union {
731 long value[128];
732 long *value_ptr;
733 } integer;
734 union {
735 long long value[64];
736 long long *value_ptr;
737 } integer64;
738 union {
739 unsigned int item[128];
740 unsigned int *item_ptr;
741 } enumerated;
742 union {
743 unsigned char data[512];
744 unsigned char *data_ptr;
745 } bytes;
746 struct snd_aes_iec958 iec958;
747 } value;
748 struct timespec tstamp;
749 unsigned char reserved[128-sizeof(struct timespec)];
750};
751
752struct snd_ctl_tlv {
753 unsigned int numid;
754 unsigned int length;
755 unsigned int tlv[0];
756};
757
758#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
759#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info)
760#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list)
761#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info)
762#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value)
763#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value)
764#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id)
765#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id)
766#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
767#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info)
768#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info)
769#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id)
770#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv)
771#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv)
772#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv)
773#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
774#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info)
775#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int)
776#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info)
777#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
778#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
779#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info)
780#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
781#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
782#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
783
784enum sndrv_ctl_event_type {
785 SNDRV_CTL_EVENT_ELEM = 0,
786 SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM,
787};
788
789#define SNDRV_CTL_EVENT_MASK_VALUE (1<<0)
790#define SNDRV_CTL_EVENT_MASK_INFO (1<<1)
791#define SNDRV_CTL_EVENT_MASK_ADD (1<<2)
792#define SNDRV_CTL_EVENT_MASK_TLV (1<<3)
793#define SNDRV_CTL_EVENT_MASK_REMOVE (~0U)
794
795struct snd_ctl_event {
796 int type;
797 union {
798 struct {
799 unsigned int mask;
800 struct snd_ctl_elem_id id;
801 } elem;
802 unsigned char data8[60];
803 } data;
804};
805
806#define SNDRV_CTL_NAME_NONE ""
807#define SNDRV_CTL_NAME_PLAYBACK "Playback "
808#define SNDRV_CTL_NAME_CAPTURE "Capture "
809
810#define SNDRV_CTL_NAME_IEC958_NONE ""
811#define SNDRV_CTL_NAME_IEC958_SWITCH "Switch"
812#define SNDRV_CTL_NAME_IEC958_VOLUME "Volume"
813#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default"
814#define SNDRV_CTL_NAME_IEC958_MASK "Mask"
815#define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask"
816#define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask"
817#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream"
818#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what
819
820#endif
821
diff --git a/firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h b/firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h
new file mode 100644
index 0000000000..6aacae46d6
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h
@@ -0,0 +1,257 @@
1/* asoundlib.h
2**
3** Copyright 2011, The Android Open Source Project
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions are met:
7** * Redistributions of source code must retain the above copyright
8** notice, this list of conditions and the following disclaimer.
9** * Redistributions in binary form must reproduce the above copyright
10** notice, this list of conditions and the following disclaimer in the
11** documentation and/or other materials provided with the distribution.
12** * Neither the name of The Android Open Source Project nor the names of
13** its contributors may be used to endorse or promote products derived
14** from this software without specific prior written permission.
15**
16** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26** DAMAGE.
27*/
28
29#ifndef ASOUNDLIB_H
30#define ASOUNDLIB_H
31
32#include <sys/time.h>
33#include <stddef.h>
34
35#if defined(__cplusplus)
36extern "C" {
37#endif
38
39/*
40 * PCM API
41 */
42
43struct pcm;
44
45#define PCM_OUT 0x00000000
46#define PCM_IN 0x10000000
47#define PCM_MMAP 0x00000001
48#define PCM_NOIRQ 0x00000002
49#define PCM_NORESTART 0x00000004 /* PCM_NORESTART - when set, calls to
50 * pcm_write for a playback stream will not
51 * attempt to restart the stream in the case
52 * of an underflow, but will return -EPIPE
53 * instead. After the first -EPIPE error, the
54 * stream is considered to be stopped, and a
55 * second call to pcm_write will attempt to
56 * restart the stream.
57 */
58
59/* PCM runtime states */
60#define PCM_STATE_OPEN 0
61#define PCM_STATE_SETUP 1
62#define PCM_STATE_PREPARED 2
63#define PCM_STATE_RUNNING 3
64#define PCM_STATE_XRUN 4
65#define PCM_STATE_DRAINING 5
66#define PCM_STATE_PAUSED 6
67#define PCM_STATE_SUSPENDED 7
68#define PCM_STATE_DISCONNECTED 8
69
70/* Bit formats */
71enum pcm_format {
72 PCM_FORMAT_S16_LE = 0,
73 PCM_FORMAT_S32_LE,
74 PCM_FORMAT_S8,
75 PCM_FORMAT_S24_LE,
76
77 PCM_FORMAT_MAX,
78};
79
80/* Configuration for a stream */
81struct pcm_config {
82 unsigned int channels;
83 unsigned int rate;
84 unsigned int period_size;
85 unsigned int period_count;
86 enum pcm_format format;
87
88 /* Values to use for the ALSA start, stop and silence thresholds. Setting
89 * any one of these values to 0 will cause the default tinyalsa values to be
90 * used instead. Tinyalsa defaults are as follows.
91 *
92 * start_threshold : period_count * period_size
93 * stop_threshold : period_count * period_size
94 * silence_threshold : 0
95 */
96 unsigned int start_threshold;
97 unsigned int stop_threshold;
98 unsigned int silence_threshold;
99};
100
101/* PCM parameters */
102enum pcm_param
103{
104 PCM_PARAM_SAMPLE_BITS,
105 PCM_PARAM_FRAME_BITS,
106 PCM_PARAM_CHANNELS,
107 PCM_PARAM_RATE,
108 PCM_PARAM_PERIOD_TIME,
109 PCM_PARAM_PERIOD_SIZE,
110 PCM_PARAM_PERIOD_BYTES,
111 PCM_PARAM_PERIODS,
112 PCM_PARAM_BUFFER_TIME,
113 PCM_PARAM_BUFFER_SIZE,
114 PCM_PARAM_BUFFER_BYTES,
115 PCM_PARAM_TICK_TIME,
116};
117
118/* Mixer control types */
119enum mixer_ctl_type {
120 MIXER_CTL_TYPE_BOOL,
121 MIXER_CTL_TYPE_INT,
122 MIXER_CTL_TYPE_ENUM,
123 MIXER_CTL_TYPE_BYTE,
124 MIXER_CTL_TYPE_IEC958,
125 MIXER_CTL_TYPE_INT64,
126 MIXER_CTL_TYPE_UNKNOWN,
127
128 MIXER_CTL_TYPE_MAX,
129};
130
131/* Open and close a stream */
132struct pcm *pcm_open(unsigned int card, unsigned int device,
133 unsigned int flags, struct pcm_config *config);
134int pcm_close(struct pcm *pcm);
135int pcm_is_ready(struct pcm *pcm);
136
137/* Obtain the parameters for a PCM */
138struct pcm_params *pcm_params_get(unsigned int card, unsigned int device,
139 unsigned int flags);
140void pcm_params_free(struct pcm_params *pcm_params);
141unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
142 enum pcm_param param);
143unsigned int pcm_params_get_max(struct pcm_params *pcm_params,
144 enum pcm_param param);
145
146/* Set and get config */
147int pcm_get_config(struct pcm *pcm, struct pcm_config *config);
148int pcm_set_config(struct pcm *pcm, struct pcm_config *config);
149
150/* Returns a human readable reason for the last error */
151const char *pcm_get_error(struct pcm *pcm);
152
153/* Returns the sample size in bits for a PCM format.
154 * As with ALSA formats, this is the storage size for the format, whereas the
155 * format represents the number of significant bits. For example,
156 * PCM_FORMAT_S24_LE uses 32 bits of storage.
157 */
158unsigned int pcm_format_to_bits(enum pcm_format format);
159
160/* Returns the buffer size (int frames) that should be used for pcm_write. */
161unsigned int pcm_get_buffer_size(struct pcm *pcm);
162unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames);
163unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes);
164
165/* Returns the pcm latency in ms */
166unsigned int pcm_get_latency(struct pcm *pcm);
167
168/* Returns available frames in pcm buffer and corresponding time stamp.
169 * For an input stream, frames available are frames ready for the
170 * application to read.
171 * For an output stream, frames available are the number of empty frames available
172 * for the application to write.
173 */
174int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
175 struct timespec *tstamp);
176
177/* Write data to the fifo.
178 * Will start playback on the first write or on a write that
179 * occurs after a fifo underrun.
180 */
181int pcm_write(struct pcm *pcm, const void *data, unsigned int count);
182int pcm_read(struct pcm *pcm, void *data, unsigned int count);
183
184/*
185 * mmap() support.
186 */
187int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);
188int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
189 unsigned int *frames);
190int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
191
192
193/* Start and stop a PCM channel that doesn't transfer data */
194int pcm_start(struct pcm *pcm);
195int pcm_stop(struct pcm *pcm);
196
197/* Interrupt driven API */
198int pcm_wait(struct pcm *pcm, int timeout);
199
200int pcm_avail_update(struct pcm *pcm);
201
202int pcm_state(struct pcm *pcm);
203
204
205/*
206 * MIXER API
207 */
208
209struct mixer;
210struct mixer_ctl;
211
212/* Open and close a mixer */
213struct mixer *mixer_open(unsigned int card);
214void mixer_close(struct mixer *mixer);
215
216/* Get info about a mixer */
217const char *mixer_get_name(struct mixer *mixer);
218
219/* Obtain mixer controls */
220unsigned int mixer_get_num_ctls(struct mixer *mixer);
221struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id);
222struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name);
223
224/* Get info about mixer controls */
225const char *mixer_ctl_get_name(struct mixer_ctl *ctl);
226enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl);
227const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl);
228unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl);
229unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl);
230const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
231 unsigned int enum_id);
232
233/* Some sound cards update their controls due to external events,
234 * such as HDMI EDID byte data changing when an HDMI cable is
235 * connected. This API allows the count of elements to be updated.
236 */
237void mixer_ctl_update(struct mixer_ctl *ctl);
238
239/* Set and get mixer controls */
240int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id);
241int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent);
242
243int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id);
244int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count);
245int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value);
246int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count);
247int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string);
248
249/* Determe range of integer mixer controls */
250int mixer_ctl_get_range_min(struct mixer_ctl *ctl);
251int mixer_ctl_get_range_max(struct mixer_ctl *ctl);
252
253#if defined(__cplusplus)
254} /* extern "C" */
255#endif
256
257#endif
diff --git a/firmware/target/hosted/android/dx50/tinyalsa/mixer.c b/firmware/target/hosted/android/dx50/tinyalsa/mixer.c
new file mode 100644
index 0000000000..f75dec488a
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/tinyalsa/mixer.c
@@ -0,0 +1,497 @@
1/* mixer.c
2**
3** Copyright 2011, The Android Open Source Project
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions are met:
7** * Redistributions of source code must retain the above copyright
8** notice, this list of conditions and the following disclaimer.
9** * Redistributions in binary form must reproduce the above copyright
10** notice, this list of conditions and the following disclaimer in the
11** documentation and/or other materials provided with the distribution.
12** * Neither the name of The Android Open Source Project nor the names of
13** its contributors may be used to endorse or promote products derived
14** from this software without specific prior written permission.
15**
16** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26** DAMAGE.
27*/
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33#include <fcntl.h>
34#include <errno.h>
35#include <ctype.h>
36
37#include <sys/ioctl.h>
38
39#include <linux/ioctl.h>
40#define __force
41#define __bitwise
42#define __user
43#include <tinyalsa/asound.h>
44
45#include <tinyalsa/asoundlib.h>
46
47struct mixer_ctl {
48 struct mixer *mixer;
49 struct snd_ctl_elem_info *info;
50 char **ename;
51};
52
53struct mixer {
54 int fd;
55 struct snd_ctl_card_info card_info;
56 struct snd_ctl_elem_info *elem_info;
57 struct mixer_ctl *ctl;
58 unsigned int count;
59};
60
61void mixer_close(struct mixer *mixer)
62{
63 unsigned int n,m;
64
65 if (!mixer)
66 return;
67
68 if (mixer->fd >= 0)
69 close(mixer->fd);
70
71 if (mixer->ctl) {
72 for (n = 0; n < mixer->count; n++) {
73 if (mixer->ctl[n].ename) {
74 unsigned int max = mixer->ctl[n].info->value.enumerated.items;
75 for (m = 0; m < max; m++)
76 free(mixer->ctl[n].ename[m]);
77 free(mixer->ctl[n].ename);
78 }
79 }
80 free(mixer->ctl);
81 }
82
83 if (mixer->elem_info)
84 free(mixer->elem_info);
85
86 free(mixer);
87
88 /* TODO: verify frees */
89}
90
91struct mixer *mixer_open(unsigned int card)
92{
93 struct snd_ctl_elem_list elist;
94 struct snd_ctl_elem_info tmp;
95 struct snd_ctl_elem_id *eid = NULL;
96 struct mixer *mixer = NULL;
97 unsigned int n, m;
98 int fd;
99 char fn[256];
100
101 snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card);
102 fd = open(fn, O_RDWR);
103 if (fd < 0)
104 return 0;
105
106 memset(&elist, 0, sizeof(elist));
107 if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
108 goto fail;
109
110 mixer = calloc(1, sizeof(*mixer));
111 if (!mixer)
112 goto fail;
113
114 mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
115 mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
116 if (!mixer->ctl || !mixer->elem_info)
117 goto fail;
118
119 if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0)
120 goto fail;
121
122 eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
123 if (!eid)
124 goto fail;
125
126 mixer->count = elist.count;
127 mixer->fd = fd;
128 elist.space = mixer->count;
129 elist.pids = eid;
130 if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
131 goto fail;
132
133 for (n = 0; n < mixer->count; n++) {
134 struct snd_ctl_elem_info *ei = mixer->elem_info + n;
135 ei->id.numid = eid[n].numid;
136 if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
137 goto fail;
138 mixer->ctl[n].info = ei;
139 mixer->ctl[n].mixer = mixer;
140 if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
141 char **enames = calloc(ei->value.enumerated.items, sizeof(char*));
142 if (!enames)
143 goto fail;
144 mixer->ctl[n].ename = enames;
145 for (m = 0; m < ei->value.enumerated.items; m++) {
146 memset(&tmp, 0, sizeof(tmp));
147 tmp.id.numid = ei->id.numid;
148 tmp.value.enumerated.item = m;
149 if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
150 goto fail;
151 enames[m] = strdup(tmp.value.enumerated.name);
152 if (!enames[m])
153 goto fail;
154 }
155 }
156 }
157
158 free(eid);
159 return mixer;
160
161fail:
162 /* TODO: verify frees in failure case */
163 if (eid)
164 free(eid);
165 if (mixer)
166 mixer_close(mixer);
167 else if (fd >= 0)
168 close(fd);
169 return 0;
170}
171
172const char *mixer_get_name(struct mixer *mixer)
173{
174 return (const char *)mixer->card_info.name;
175}
176
177unsigned int mixer_get_num_ctls(struct mixer *mixer)
178{
179 if (!mixer)
180 return 0;
181
182 return mixer->count;
183}
184
185struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id)
186{
187 if (mixer && (id < mixer->count))
188 return mixer->ctl + id;
189
190 return NULL;
191}
192
193struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name)
194{
195 unsigned int n;
196
197 if (!mixer)
198 return NULL;
199
200 for (n = 0; n < mixer->count; n++)
201 if (!strcmp(name, (char*) mixer->elem_info[n].id.name))
202 return mixer->ctl + n;
203
204 return NULL;
205}
206
207void mixer_ctl_update(struct mixer_ctl *ctl)
208{
209 ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info);
210}
211
212const char *mixer_ctl_get_name(struct mixer_ctl *ctl)
213{
214 if (!ctl)
215 return NULL;
216
217 return (const char *)ctl->info->id.name;
218}
219
220enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl)
221{
222 if (!ctl)
223 return MIXER_CTL_TYPE_UNKNOWN;
224
225 switch (ctl->info->type) {
226 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return MIXER_CTL_TYPE_BOOL;
227 case SNDRV_CTL_ELEM_TYPE_INTEGER: return MIXER_CTL_TYPE_INT;
228 case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return MIXER_CTL_TYPE_ENUM;
229 case SNDRV_CTL_ELEM_TYPE_BYTES: return MIXER_CTL_TYPE_BYTE;
230 case SNDRV_CTL_ELEM_TYPE_IEC958: return MIXER_CTL_TYPE_IEC958;
231 case SNDRV_CTL_ELEM_TYPE_INTEGER64: return MIXER_CTL_TYPE_INT64;
232 default: return MIXER_CTL_TYPE_UNKNOWN;
233 };
234}
235
236const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl)
237{
238 if (!ctl)
239 return "";
240
241 switch (ctl->info->type) {
242 case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return "BOOL";
243 case SNDRV_CTL_ELEM_TYPE_INTEGER: return "INT";
244 case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return "ENUM";
245 case SNDRV_CTL_ELEM_TYPE_BYTES: return "BYTE";
246 case SNDRV_CTL_ELEM_TYPE_IEC958: return "IEC958";
247 case SNDRV_CTL_ELEM_TYPE_INTEGER64: return "INT64";
248 default: return "Unknown";
249 };
250}
251
252unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl)
253{
254 if (!ctl)
255 return 0;
256
257 return ctl->info->count;
258}
259
260static int percent_to_int(struct snd_ctl_elem_info *ei, int percent)
261{
262 int range;
263
264 if (percent > 100)
265 percent = 100;
266 else if (percent < 0)
267 percent = 0;
268
269 range = (ei->value.integer.max - ei->value.integer.min);
270
271 return ei->value.integer.min + (range * percent) / 100;
272}
273
274static int int_to_percent(struct snd_ctl_elem_info *ei, int value)
275{
276 int range = (ei->value.integer.max - ei->value.integer.min);
277
278 if (range == 0)
279 return 0;
280
281 return ((value - ei->value.integer.min) / range) * 100;
282}
283
284int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id)
285{
286 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
287 return -EINVAL;
288
289 return int_to_percent(ctl->info, mixer_ctl_get_value(ctl, id));
290}
291
292int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent)
293{
294 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
295 return -EINVAL;
296
297 return mixer_ctl_set_value(ctl, id, percent_to_int(ctl->info, percent));
298}
299
300int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id)
301{
302 struct snd_ctl_elem_value ev;
303 int ret;
304
305 if (!ctl || (id >= ctl->info->count))
306 return -EINVAL;
307
308 memset(&ev, 0, sizeof(ev));
309 ev.id.numid = ctl->info->id.numid;
310 ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
311 if (ret < 0)
312 return ret;
313
314 switch (ctl->info->type) {
315 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
316 return !!ev.value.integer.value[id];
317
318 case SNDRV_CTL_ELEM_TYPE_INTEGER:
319 return ev.value.integer.value[id];
320
321 case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
322 return ev.value.enumerated.item[id];
323
324 case SNDRV_CTL_ELEM_TYPE_BYTES:
325 return ev.value.bytes.data[id];
326
327 default:
328 return -EINVAL;
329 }
330
331 return 0;
332}
333
334int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count)
335{
336 struct snd_ctl_elem_value ev;
337 int ret;
338 size_t size;
339 void *source;
340
341 if (!ctl || (count > ctl->info->count) || !count || !array)
342 return -EINVAL;
343
344 memset(&ev, 0, sizeof(ev));
345 ev.id.numid = ctl->info->id.numid;
346
347 ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
348 if (ret < 0)
349 return ret;
350
351 switch (ctl->info->type) {
352 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
353 case SNDRV_CTL_ELEM_TYPE_INTEGER:
354 size = sizeof(ev.value.integer.value[0]);
355 source = ev.value.integer.value;
356 break;
357
358 case SNDRV_CTL_ELEM_TYPE_BYTES:
359 size = sizeof(ev.value.bytes.data[0]);
360 source = ev.value.bytes.data;
361 break;
362
363 default:
364 return -EINVAL;
365 }
366
367 memcpy(array, source, size * count);
368
369 return 0;
370}
371
372int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
373{
374 struct snd_ctl_elem_value ev;
375 int ret;
376
377 if (!ctl || (id >= ctl->info->count))
378 return -EINVAL;
379
380 memset(&ev, 0, sizeof(ev));
381 ev.id.numid = ctl->info->id.numid;
382 ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
383 if (ret < 0)
384 return ret;
385
386 switch (ctl->info->type) {
387 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
388 ev.value.integer.value[id] = !!value;
389 break;
390
391 case SNDRV_CTL_ELEM_TYPE_INTEGER:
392 ev.value.integer.value[id] = value;
393 break;
394
395 case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
396 ev.value.enumerated.item[id] = value;
397 break;
398
399 default:
400 return -EINVAL;
401 }
402
403 return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
404}
405
406int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
407{
408 struct snd_ctl_elem_value ev;
409 size_t size;
410 void *dest;
411
412 if (!ctl || (count > ctl->info->count) || !count || !array)
413 return -EINVAL;
414
415 memset(&ev, 0, sizeof(ev));
416 ev.id.numid = ctl->info->id.numid;
417
418 switch (ctl->info->type) {
419 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
420 case SNDRV_CTL_ELEM_TYPE_INTEGER:
421 size = sizeof(ev.value.integer.value[0]);
422 dest = ev.value.integer.value;
423 break;
424
425 case SNDRV_CTL_ELEM_TYPE_BYTES:
426 size = sizeof(ev.value.bytes.data[0]);
427 dest = ev.value.bytes.data;
428 break;
429
430 default:
431 return -EINVAL;
432 }
433
434 memcpy(dest, array, size * count);
435
436 return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
437}
438
439int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
440{
441 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
442 return -EINVAL;
443
444 return ctl->info->value.integer.min;
445}
446
447int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
448{
449 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
450 return -EINVAL;
451
452 return ctl->info->value.integer.max;
453}
454
455unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl)
456{
457 if (!ctl)
458 return 0;
459
460 return ctl->info->value.enumerated.items;
461}
462
463const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
464 unsigned int enum_id)
465{
466 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
467 (enum_id >= ctl->info->value.enumerated.items))
468 return NULL;
469
470 return (const char *)ctl->ename[enum_id];
471}
472
473int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string)
474{
475 unsigned int i, num_enums;
476 struct snd_ctl_elem_value ev;
477 int ret;
478
479 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED))
480 return -EINVAL;
481
482 num_enums = ctl->info->value.enumerated.items;
483 for (i = 0; i < num_enums; i++) {
484 if (!strcmp(string, ctl->ename[i])) {
485 memset(&ev, 0, sizeof(ev));
486 ev.value.enumerated.item[0] = i;
487 ev.id.numid = ctl->info->id.numid;
488 ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
489 if (ret < 0)
490 return ret;
491 return 0;
492 }
493 }
494
495 return -EINVAL;
496}
497
diff --git a/firmware/target/hosted/android/dx50/tinyalsa/pcm.c b/firmware/target/hosted/android/dx50/tinyalsa/pcm.c
new file mode 100644
index 0000000000..bd44dce52f
--- /dev/null
+++ b/firmware/target/hosted/android/dx50/tinyalsa/pcm.c
@@ -0,0 +1,973 @@
1/* pcm.c
2**
3** Copyright 2011, The Android Open Source Project
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions are met:
7** * Redistributions of source code must retain the above copyright
8** notice, this list of conditions and the following disclaimer.
9** * Redistributions in binary form must reproduce the above copyright
10** notice, this list of conditions and the following disclaimer in the
11** documentation and/or other materials provided with the distribution.
12** * Neither the name of The Android Open Source Project nor the names of
13** its contributors may be used to endorse or promote products derived
14** from this software without specific prior written permission.
15**
16** THIS SOFTWARE IS PROVIDED BY The Android Open Source Project ``AS IS'' AND
17** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19** ARE DISCLAIMED. IN NO EVENT SHALL The Android Open Source Project BE LIABLE
20** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26** DAMAGE.
27*/
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <fcntl.h>
32#include <stdarg.h>
33#include <string.h>
34#include <errno.h>
35#include <unistd.h>
36#include <poll.h>
37
38#include <sys/ioctl.h>
39#include <sys/mman.h>
40#include <sys/time.h>
41#include <limits.h>
42
43#include <linux/ioctl.h>
44#define __force
45#define __bitwise
46#define __user
47#include <tinyalsa/asound.h>
48
49#include <tinyalsa/asoundlib.h>
50
51#define PARAM_MAX SNDRV_PCM_HW_PARAM_LAST_INTERVAL
52#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2)
53
54static inline int param_is_mask(int p)
55{
56 return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
57 (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
58}
59
60static inline int param_is_interval(int p)
61{
62 return (p >= SNDRV_PCM_HW_PARAM_FIRST_INTERVAL) &&
63 (p <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL);
64}
65
66static inline struct snd_interval *param_to_interval(struct snd_pcm_hw_params *p, int n)
67{
68 return &(p->intervals[n - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]);
69}
70
71static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
72{
73 return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
74}
75
76static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit)
77{
78 if (bit >= SNDRV_MASK_MAX)
79 return;
80 if (param_is_mask(n)) {
81 struct snd_mask *m = param_to_mask(p, n);
82 m->bits[0] = 0;
83 m->bits[1] = 0;
84 m->bits[bit >> 5] |= (1 << (bit & 31));
85 }
86}
87
88static void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned int val)
89{
90 if (param_is_interval(n)) {
91 struct snd_interval *i = param_to_interval(p, n);
92 i->min = val;
93 }
94}
95
96static unsigned int param_get_min(struct snd_pcm_hw_params *p, int n)
97{
98 if (param_is_interval(n)) {
99 struct snd_interval *i = param_to_interval(p, n);
100 return i->min;
101 }
102 return 0;
103}
104
105static unsigned int param_get_max(struct snd_pcm_hw_params *p, int n)
106{
107 if (param_is_interval(n)) {
108 struct snd_interval *i = param_to_interval(p, n);
109 return i->max;
110 }
111 return 0;
112}
113
114static void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned int val)
115{
116 if (param_is_interval(n)) {
117 struct snd_interval *i = param_to_interval(p, n);
118 i->min = val;
119 i->max = val;
120 i->integer = 1;
121 }
122}
123
124static unsigned int param_get_int(struct snd_pcm_hw_params *p, int n)
125{
126 if (param_is_interval(n)) {
127 struct snd_interval *i = param_to_interval(p, n);
128 if (i->integer)
129 return i->max;
130 }
131 return 0;
132}
133
134static void param_init(struct snd_pcm_hw_params *p)
135{
136 int n;
137
138 memset(p, 0, sizeof(*p));
139 for (n = SNDRV_PCM_HW_PARAM_FIRST_MASK;
140 n <= SNDRV_PCM_HW_PARAM_LAST_MASK; n++) {
141 struct snd_mask *m = param_to_mask(p, n);
142 m->bits[0] = ~0;
143 m->bits[1] = ~0;
144 }
145 for (n = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL;
146 n <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; n++) {
147 struct snd_interval *i = param_to_interval(p, n);
148 i->min = 0;
149 i->max = ~0;
150 }
151 p->rmask = ~0U;
152 p->cmask = 0;
153 p->info = ~0U;
154}
155
156#define PCM_ERROR_MAX 128
157
158struct pcm {
159 int fd;
160 unsigned int flags;
161 int running:1;
162 int underruns;
163 unsigned int buffer_size;
164 unsigned int boundary;
165 char error[PCM_ERROR_MAX];
166 struct pcm_config config;
167 struct snd_pcm_mmap_status *mmap_status;
168 struct snd_pcm_mmap_control *mmap_control;
169 struct snd_pcm_sync_ptr *sync_ptr;
170 void *mmap_buffer;
171 unsigned int noirq_frames_per_msec;
172};
173
174unsigned int pcm_get_buffer_size(struct pcm *pcm)
175{
176 return pcm->buffer_size;
177}
178
179const char* pcm_get_error(struct pcm *pcm)
180{
181 return pcm->error;
182}
183
184static int oops(struct pcm *pcm, int e, const char *fmt, ...)
185{
186 va_list ap;
187 int sz;
188
189 va_start(ap, fmt);
190 vsnprintf(pcm->error, PCM_ERROR_MAX, fmt, ap);
191 va_end(ap);
192 sz = strlen(pcm->error);
193
194 if (errno)
195 snprintf(pcm->error + sz, PCM_ERROR_MAX - sz,
196 ": %s", strerror(e));
197 return -1;
198}
199
200static unsigned int pcm_format_to_alsa(enum pcm_format format)
201{
202 switch (format) {
203 case PCM_FORMAT_S32_LE:
204 return SNDRV_PCM_FORMAT_S32_LE;
205 case PCM_FORMAT_S8:
206 return SNDRV_PCM_FORMAT_S8;
207 case PCM_FORMAT_S24_LE:
208 return SNDRV_PCM_FORMAT_S24_LE;
209 default:
210 case PCM_FORMAT_S16_LE:
211 return SNDRV_PCM_FORMAT_S16_LE;
212 };
213}
214
215unsigned int pcm_format_to_bits(enum pcm_format format)
216{
217 switch (format) {
218 case PCM_FORMAT_S32_LE:
219 case PCM_FORMAT_S24_LE:
220 return 32;
221 default:
222 case PCM_FORMAT_S16_LE:
223 return 16;
224 };
225}
226
227unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes)
228{
229 return bytes / (pcm->config.channels *
230 (pcm_format_to_bits(pcm->config.format) >> 3));
231}
232
233unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames)
234{
235 return frames * pcm->config.channels *
236 (pcm_format_to_bits(pcm->config.format) >> 3);
237}
238
239static int pcm_sync_ptr(struct pcm *pcm, int flags) {
240 if (pcm->sync_ptr) {
241 pcm->sync_ptr->flags = flags;
242 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SYNC_PTR, pcm->sync_ptr) < 0)
243 return -1;
244 }
245 return 0;
246}
247
248static int pcm_hw_mmap_status(struct pcm *pcm) {
249
250 if (pcm->sync_ptr)
251 return 0;
252
253 int page_size = sysconf(_SC_PAGE_SIZE);
254 pcm->mmap_status = mmap(NULL, page_size, PROT_READ, MAP_FILE | MAP_SHARED,
255 pcm->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
256 if (pcm->mmap_status == MAP_FAILED)
257 pcm->mmap_status = NULL;
258 if (!pcm->mmap_status)
259 goto mmap_error;
260
261 pcm->mmap_control = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
262 MAP_FILE | MAP_SHARED, pcm->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
263 if (pcm->mmap_control == MAP_FAILED)
264 pcm->mmap_control = NULL;
265 if (!pcm->mmap_control) {
266 munmap(pcm->mmap_status, page_size);
267 pcm->mmap_status = NULL;
268 goto mmap_error;
269 }
270 pcm->mmap_control->avail_min = 1;
271
272 return 0;
273
274mmap_error:
275
276 pcm->sync_ptr = calloc(1, sizeof(*pcm->sync_ptr));
277 if (!pcm->sync_ptr)
278 return -ENOMEM;
279 pcm->mmap_status = &pcm->sync_ptr->s.status;
280 pcm->mmap_control = &pcm->sync_ptr->c.control;
281 pcm->mmap_control->avail_min = 1;
282 pcm_sync_ptr(pcm, 0);
283
284 return 0;
285}
286
287static void pcm_hw_munmap_status(struct pcm *pcm) {
288 if (pcm->sync_ptr) {
289 free(pcm->sync_ptr);
290 pcm->sync_ptr = NULL;
291 } else {
292 int page_size = sysconf(_SC_PAGE_SIZE);
293 if (pcm->mmap_status)
294 munmap(pcm->mmap_status, page_size);
295 if (pcm->mmap_control)
296 munmap(pcm->mmap_control, page_size);
297 }
298 pcm->mmap_status = NULL;
299 pcm->mmap_control = NULL;
300}
301
302static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset,
303 const char *src, unsigned int src_offset,
304 unsigned int frames)
305{
306 int size_bytes = pcm_frames_to_bytes(pcm, frames);
307 int pcm_offset_bytes = pcm_frames_to_bytes(pcm, pcm_offset);
308 int src_offset_bytes = pcm_frames_to_bytes(pcm, src_offset);
309
310 /* interleaved only atm */
311 memcpy((char*)pcm->mmap_buffer + pcm_offset_bytes,
312 src + src_offset_bytes, size_bytes);
313 return 0;
314}
315
316static int pcm_mmap_write_areas(struct pcm *pcm, const char *src,
317 unsigned int offset, unsigned int size)
318{
319 void *pcm_areas;
320 int commit;
321 unsigned int pcm_offset, frames, count = 0;
322
323 while (size > 0) {
324 frames = size;
325 pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames);
326 pcm_areas_copy(pcm, pcm_offset, src, offset, frames);
327 commit = pcm_mmap_commit(pcm, pcm_offset, frames);
328 if (commit < 0) {
329 oops(pcm, commit, "failed to commit %d frames\n", frames);
330 return commit;
331 }
332
333 offset += commit;
334 count += commit;
335 size -= commit;
336 }
337 return count;
338}
339
340int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
341 struct timespec *tstamp)
342{
343 int frames;
344 int rc;
345 snd_pcm_uframes_t hw_ptr;
346
347 if (!pcm_is_ready(pcm))
348 return -1;
349
350 rc = pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_APPL|SNDRV_PCM_SYNC_PTR_HWSYNC);
351 if (rc < 0)
352 return -1;
353
354 if ((pcm->mmap_status->state != PCM_STATE_RUNNING) &&
355 (pcm->mmap_status->state != PCM_STATE_DRAINING))
356 return -1;
357
358 *tstamp = pcm->mmap_status->tstamp;
359 if (tstamp->tv_sec == 0 && tstamp->tv_nsec == 0)
360 return -1;
361
362 hw_ptr = pcm->mmap_status->hw_ptr;
363 if (pcm->flags & PCM_IN)
364 frames = hw_ptr - pcm->mmap_control->appl_ptr;
365 else
366 frames = hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr;
367
368 if (frames < 0)
369 return -1;
370
371 *avail = (unsigned int)frames;
372
373 return 0;
374}
375
376int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
377{
378 struct snd_xferi x;
379
380 if (pcm->flags & PCM_IN)
381 return -EINVAL;
382
383 x.buf = (void*)data;
384 x.frames = count / (pcm->config.channels *
385 pcm_format_to_bits(pcm->config.format) / 8);
386
387 for (;;) {
388 if (!pcm->running) {
389 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE))
390 return oops(pcm, errno, "cannot prepare channel");
391 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x))
392 return oops(pcm, errno, "cannot write initial data");
393 pcm->running = 1;
394 return 0;
395 }
396 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
397 pcm->running = 0;
398 if (errno == EPIPE) {
399 /* we failed to make our window -- try to restart if we are
400 * allowed to do so. Otherwise, simply allow the EPIPE error to
401 * propagate up to the app level */
402 pcm->underruns++;
403 if (pcm->flags & PCM_NORESTART)
404 return -EPIPE;
405 continue;
406 }
407 return oops(pcm, errno, "cannot write stream data");
408 }
409 return 0;
410 }
411}
412
413int pcm_read(struct pcm *pcm, void *data, unsigned int count)
414{
415 struct snd_xferi x;
416
417 if (!(pcm->flags & PCM_IN))
418 return -EINVAL;
419
420 x.buf = data;
421 x.frames = count / (pcm->config.channels *
422 pcm_format_to_bits(pcm->config.format) / 8);
423
424 for (;;) {
425 if (!pcm->running) {
426 if (pcm_start(pcm) < 0) {
427 fprintf(stderr, "start error");
428 return -errno;
429 }
430 }
431 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
432 pcm->running = 0;
433 if (errno == EPIPE) {
434 /* we failed to make our window -- try to restart */
435 pcm->underruns++;
436 continue;
437 }
438 return oops(pcm, errno, "cannot read stream data");
439 }
440 return 0;
441 }
442}
443
444static struct pcm bad_pcm = {
445 .fd = -1,
446};
447
448struct pcm_params *pcm_params_get(unsigned int card, unsigned int device,
449 unsigned int flags)
450{
451 struct snd_pcm_hw_params *params;
452 char fn[256];
453 int fd;
454
455 snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
456 flags & PCM_IN ? 'c' : 'p');
457
458 fd = open(fn, O_RDWR);
459 if (fd < 0) {
460 fprintf(stderr, "cannot open device '%s'\n", fn);
461 goto err_open;
462 }
463
464 params = calloc(1, sizeof(struct snd_pcm_hw_params));
465 if (!params)
466 goto err_calloc;
467
468 param_init(params);
469 if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, params)) {
470 fprintf(stderr, "SNDRV_PCM_IOCTL_HW_REFINE error (%d)\n", errno);
471 goto err_hw_refine;
472 }
473
474 close(fd);
475
476 return (struct pcm_params *)params;
477
478err_hw_refine:
479 free(params);
480err_calloc:
481 close(fd);
482err_open:
483 return NULL;
484}
485
486void pcm_params_free(struct pcm_params *pcm_params)
487{
488 struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
489
490 if (params)
491 free(params);
492}
493
494static int pcm_param_to_alsa(enum pcm_param param)
495{
496 switch (param) {
497 case PCM_PARAM_SAMPLE_BITS:
498 return SNDRV_PCM_HW_PARAM_SAMPLE_BITS;
499 break;
500 case PCM_PARAM_FRAME_BITS:
501 return SNDRV_PCM_HW_PARAM_FRAME_BITS;
502 break;
503 case PCM_PARAM_CHANNELS:
504 return SNDRV_PCM_HW_PARAM_CHANNELS;
505 break;
506 case PCM_PARAM_RATE:
507 return SNDRV_PCM_HW_PARAM_RATE;
508 break;
509 case PCM_PARAM_PERIOD_TIME:
510 return SNDRV_PCM_HW_PARAM_PERIOD_TIME;
511 break;
512 case PCM_PARAM_PERIOD_SIZE:
513 return SNDRV_PCM_HW_PARAM_PERIOD_SIZE;
514 break;
515 case PCM_PARAM_PERIOD_BYTES:
516 return SNDRV_PCM_HW_PARAM_PERIOD_BYTES;
517 break;
518 case PCM_PARAM_PERIODS:
519 return SNDRV_PCM_HW_PARAM_PERIODS;
520 break;
521 case PCM_PARAM_BUFFER_TIME:
522 return SNDRV_PCM_HW_PARAM_BUFFER_TIME;
523 break;
524 case PCM_PARAM_BUFFER_SIZE:
525 return SNDRV_PCM_HW_PARAM_BUFFER_SIZE;
526 break;
527 case PCM_PARAM_BUFFER_BYTES:
528 return SNDRV_PCM_HW_PARAM_BUFFER_BYTES;
529 break;
530 case PCM_PARAM_TICK_TIME:
531 return SNDRV_PCM_HW_PARAM_TICK_TIME;
532 break;
533
534 default:
535 return -1;
536 }
537}
538
539unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
540 enum pcm_param param)
541{
542 struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
543 int p;
544
545 if (!params)
546 return 0;
547
548 p = pcm_param_to_alsa(param);
549 if (p < 0)
550 return 0;
551
552 return param_get_min(params, p);
553}
554
555unsigned int pcm_params_get_max(struct pcm_params *pcm_params,
556 enum pcm_param param)
557{
558 struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
559 int p;
560
561 if (!params)
562 return 0;
563
564 p = pcm_param_to_alsa(param);
565 if (p < 0)
566 return 0;
567
568 return param_get_max(params, p);
569}
570
571int pcm_close(struct pcm *pcm)
572{
573 if (pcm == &bad_pcm)
574 return 0;
575
576 pcm_hw_munmap_status(pcm);
577
578 if (pcm->flags & PCM_MMAP) {
579 pcm_stop(pcm);
580 munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
581 }
582
583 if (pcm->fd >= 0)
584 close(pcm->fd);
585 pcm->running = 0;
586 pcm->buffer_size = 0;
587 pcm->fd = -1;
588 free(pcm);
589 return 0;
590}
591
592struct pcm *pcm_open(unsigned int card, unsigned int device,
593 unsigned int flags, struct pcm_config *config)
594{
595 struct pcm *pcm;
596 struct snd_pcm_info info;
597 struct snd_pcm_hw_params params;
598 struct snd_pcm_sw_params sparams;
599 char fn[256];
600 int rc;
601
602 pcm = calloc(1, sizeof(struct pcm));
603 if (!pcm || !config)
604 return &bad_pcm; /* TODO: could support default config here */
605
606 pcm->config = *config;
607
608 snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device,
609 flags & PCM_IN ? 'c' : 'p');
610
611 pcm->flags = flags;
612 pcm->fd = open(fn, O_RDWR);
613 if (pcm->fd < 0) {
614 oops(pcm, errno, "cannot open device '%s'", fn);
615 return pcm;
616 }
617
618 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_INFO, &info)) {
619 oops(pcm, errno, "cannot get info");
620 goto fail_close;
621 }
622
623 param_init(&params);
624 param_set_mask(&params, SNDRV_PCM_HW_PARAM_FORMAT,
625 pcm_format_to_alsa(config->format));
626 param_set_mask(&params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
627 SNDRV_PCM_SUBFORMAT_STD);
628 param_set_min(&params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, config->period_size);
629 param_set_int(&params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
630 pcm_format_to_bits(config->format));
631 param_set_int(&params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
632 pcm_format_to_bits(config->format) * config->channels);
633 param_set_int(&params, SNDRV_PCM_HW_PARAM_CHANNELS,
634 config->channels);
635 param_set_int(&params, SNDRV_PCM_HW_PARAM_PERIODS, config->period_count);
636 param_set_int(&params, SNDRV_PCM_HW_PARAM_RATE, config->rate);
637
638 if (flags & PCM_NOIRQ) {
639
640 if (!(flags & PCM_MMAP)) {
641 oops(pcm, -EINVAL, "noirq only currently supported with mmap().");
642 goto fail;
643 }
644
645 params.flags |= SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP;
646 pcm->noirq_frames_per_msec = config->rate / 1000;
647 }
648
649 if (flags & PCM_MMAP)
650 param_set_mask(&params, SNDRV_PCM_HW_PARAM_ACCESS,
651 SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
652 else
653 param_set_mask(&params, SNDRV_PCM_HW_PARAM_ACCESS,
654 SNDRV_PCM_ACCESS_RW_INTERLEAVED);
655
656 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS, &params)) {
657 oops(pcm, errno, "cannot set hw params");
658 goto fail_close;
659 }
660
661 /* get our refined hw_params */
662 config->period_size = param_get_int(&params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
663 config->period_count = param_get_int(&params, SNDRV_PCM_HW_PARAM_PERIODS);
664 pcm->buffer_size = config->period_count * config->period_size;
665
666 if (flags & PCM_MMAP) {
667 pcm->mmap_buffer = mmap(NULL, pcm_frames_to_bytes(pcm, pcm->buffer_size),
668 PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, pcm->fd, 0);
669 if (pcm->mmap_buffer == MAP_FAILED) {
670 oops(pcm, -errno, "failed to mmap buffer %d bytes\n",
671 pcm_frames_to_bytes(pcm, pcm->buffer_size));
672 goto fail_close;
673 }
674 }
675
676
677 memset(&sparams, 0, sizeof(sparams));
678 sparams.tstamp_mode = SNDRV_PCM_TSTAMP_ENABLE;
679 sparams.period_step = 1;
680 sparams.avail_min = 1;
681
682 if (!config->start_threshold) {
683 if (pcm->flags & PCM_IN)
684 pcm->config.start_threshold = sparams.start_threshold = 1;
685 else
686 pcm->config.start_threshold = sparams.start_threshold =
687 config->period_count * config->period_size / 2;
688 } else
689 sparams.start_threshold = config->start_threshold;
690
691 /* pick a high stop threshold - todo: does this need further tuning */
692 if (!config->stop_threshold) {
693 if (pcm->flags & PCM_IN)
694 pcm->config.stop_threshold = sparams.stop_threshold =
695 config->period_count * config->period_size * 10;
696 else
697 pcm->config.stop_threshold = sparams.stop_threshold =
698 config->period_count * config->period_size;
699 }
700 else
701 sparams.stop_threshold = config->stop_threshold;
702
703 sparams.xfer_align = config->period_size / 2; /* needed for old kernels */
704 sparams.silence_size = 0;
705 sparams.silence_threshold = config->silence_threshold;
706 pcm->boundary = sparams.boundary = pcm->buffer_size;
707
708 while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size)
709 pcm->boundary *= 2;
710
711 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
712 oops(pcm, errno, "cannot set sw params");
713 goto fail;
714 }
715
716 rc = pcm_hw_mmap_status(pcm);
717 if (rc < 0) {
718 oops(pcm, rc, "mmap status failed");
719 goto fail;
720 }
721
722 pcm->underruns = 0;
723 return pcm;
724
725fail:
726 if (flags & PCM_MMAP)
727 munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
728fail_close:
729 close(pcm->fd);
730 pcm->fd = -1;
731 return pcm;
732}
733
734int pcm_is_ready(struct pcm *pcm)
735{
736 return pcm->fd >= 0;
737}
738
739int pcm_start(struct pcm *pcm)
740{
741 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE) < 0)
742 return oops(pcm, errno, "cannot prepare channel");
743
744 if (pcm->flags & PCM_MMAP)
745 pcm_sync_ptr(pcm, 0);
746
747 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START) < 0)
748 return oops(pcm, errno, "cannot start channel");
749
750 pcm->running = 1;
751 return 0;
752}
753
754int pcm_stop(struct pcm *pcm)
755{
756 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0)
757 return oops(pcm, errno, "cannot stop channel");
758
759 pcm->running = 0;
760 return 0;
761}
762
763static inline int pcm_mmap_playback_avail(struct pcm *pcm)
764{
765 int avail;
766
767 avail = pcm->mmap_status->hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr;
768
769 if (avail < 0)
770 avail += pcm->boundary;
771 else if (avail > (int)pcm->boundary)
772 avail -= pcm->boundary;
773
774 return avail;
775}
776
777static inline int pcm_mmap_capture_avail(struct pcm *pcm)
778{
779 int avail = pcm->mmap_status->hw_ptr - pcm->mmap_control->appl_ptr;
780 if (avail < 0)
781 avail += pcm->boundary;
782 return avail;
783}
784
785static inline int pcm_mmap_avail(struct pcm *pcm)
786{
787 pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC);
788 if (pcm->flags & PCM_IN)
789 return pcm_mmap_capture_avail(pcm);
790 else
791 return pcm_mmap_playback_avail(pcm);
792}
793
794static void pcm_mmap_appl_forward(struct pcm *pcm, int frames)
795{
796 unsigned int appl_ptr = pcm->mmap_control->appl_ptr;
797 appl_ptr += frames;
798
799 /* check for boundary wrap */
800 if (appl_ptr > pcm->boundary)
801 appl_ptr -= pcm->boundary;
802 pcm->mmap_control->appl_ptr = appl_ptr;
803}
804
805int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
806 unsigned int *frames)
807{
808 unsigned int continuous, copy_frames, avail;
809
810 /* return the mmap buffer */
811 *areas = pcm->mmap_buffer;
812
813 /* and the application offset in frames */
814 *offset = pcm->mmap_control->appl_ptr % pcm->buffer_size;
815
816 avail = pcm_mmap_avail(pcm);
817 if (avail > pcm->buffer_size)
818 avail = pcm->buffer_size;
819 continuous = pcm->buffer_size - *offset;
820
821 /* we can only copy frames if the are availabale and continuos */
822 copy_frames = *frames;
823 if (copy_frames > avail)
824 copy_frames = avail;
825 if (copy_frames > continuous)
826 copy_frames = continuous;
827 *frames = copy_frames;
828
829 return 0;
830}
831
832int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames)
833{
834 (void)offset;
835 /* update the application pointer in userspace and kernel */
836 pcm_mmap_appl_forward(pcm, frames);
837 pcm_sync_ptr(pcm, 0);
838
839 return frames;
840}
841
842int pcm_avail_update(struct pcm *pcm)
843{
844 pcm_sync_ptr(pcm, 0);
845 return pcm_mmap_avail(pcm);
846}
847
848int pcm_state(struct pcm *pcm)
849{
850 int err = pcm_sync_ptr(pcm, 0);
851 if (err < 0)
852 return err;
853
854 return pcm->mmap_status->state;
855}
856
857int pcm_wait(struct pcm *pcm, int timeout)
858{
859 struct pollfd pfd;
860 int err;
861
862 pfd.fd = pcm->fd;
863 pfd.events = POLLOUT | POLLERR | POLLNVAL;
864
865 do {
866 /* let's wait for avail or timeout */
867 err = poll(&pfd, 1, timeout);
868 if (err < 0)
869 return -errno;
870
871 /* timeout ? */
872 if (err == 0)
873 return 0;
874
875 /* have we been interrupted ? */
876 if (errno == -EINTR)
877 continue;
878
879 /* check for any errors */
880 if (pfd.revents & (POLLERR | POLLNVAL)) {
881 switch (pcm_state(pcm)) {
882 case PCM_STATE_XRUN:
883 return -EPIPE;
884 case PCM_STATE_SUSPENDED:
885 return -ESTRPIPE;
886 case PCM_STATE_DISCONNECTED:
887 return -ENODEV;
888 default:
889 return -EIO;
890 }
891 }
892 /* poll again if fd not ready for IO */
893 } while (!(pfd.revents & (POLLIN | POLLOUT)));
894
895 return 1;
896}
897
898int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
899{
900 int err = 0, frames, avail;
901 unsigned int offset = 0, count;
902
903 if (bytes == 0)
904 return 0;
905
906 count = pcm_bytes_to_frames(pcm, bytes);
907
908 while (count > 0) {
909
910 /* get the available space for writing new frames */
911 avail = pcm_avail_update(pcm);
912 if (avail < 0) {
913 fprintf(stderr, "cannot determine available mmap frames");
914 return err;
915 }
916
917 /* start the audio if we reach the threshold */
918 if (!pcm->running &&
919 (pcm->buffer_size - avail) >= pcm->config.start_threshold) {
920 if (pcm_start(pcm) < 0) {
921 fprintf(stderr, "start error: hw 0x%x app 0x%x avail 0x%x\n",
922 (unsigned int)pcm->mmap_status->hw_ptr,
923 (unsigned int)pcm->mmap_control->appl_ptr,
924 avail);
925 return -errno;
926 }
927 }
928
929 /* sleep until we have space to write new frames */
930 if (pcm->running &&
931 (unsigned int)avail < pcm->mmap_control->avail_min) {
932 int time = -1;
933
934 if (pcm->flags & PCM_NOIRQ)
935 time = (pcm->buffer_size - avail - pcm->mmap_control->avail_min)
936 / pcm->noirq_frames_per_msec;
937
938 err = pcm_wait(pcm, time);
939 if (err < 0) {
940 pcm->running = 0;
941 fprintf(stderr, "wait error: hw 0x%x app 0x%x avail 0x%x\n",
942 (unsigned int)pcm->mmap_status->hw_ptr,
943 (unsigned int)pcm->mmap_control->appl_ptr,
944 avail);
945 pcm->mmap_control->appl_ptr = 0;
946 return err;
947 }
948 continue;
949 }
950
951 frames = count;
952 if (frames > avail)
953 frames = avail;
954
955 if (!frames)
956 break;
957
958 /* copy frames from buffer */
959 frames = pcm_mmap_write_areas(pcm, buffer, offset, frames);
960 if (frames < 0) {
961 fprintf(stderr, "write error: hw 0x%x app 0x%x avail 0x%x\n",
962 (unsigned int)pcm->mmap_status->hw_ptr,
963 (unsigned int)pcm->mmap_control->appl_ptr,
964 avail);
965 return frames;
966 }
967
968 offset += frames;
969 count -= frames;
970 }
971
972 return 0;
973}
diff --git a/firmware/target/hosted/android/system-android.c b/firmware/target/hosted/android/system-android.c
index d13b8d6462..6279504e48 100644
--- a/firmware/target/hosted/android/system-android.c
+++ b/firmware/target/hosted/android/system-android.c
@@ -23,6 +23,12 @@
23#include <setjmp.h> 23#include <setjmp.h>
24#include <jni.h> 24#include <jni.h>
25#include <pthread.h> 25#include <pthread.h>
26#if defined(DX50) || defined(DX90)
27#include <stdlib.h>
28#include <sys/reboot.h>
29#include <sys/stat.h>
30#include <stdio.h>
31#endif /* DX50 || DX90 */
26#include <unistd.h> 32#include <unistd.h>
27#include "config.h" 33#include "config.h"
28#include "system.h" 34#include "system.h"
@@ -31,40 +37,83 @@
31 37
32 38
33 39
40#if !defined(DX50) && !defined(DX90)
34/* global fields for use with various JNI calls */ 41/* global fields for use with various JNI calls */
35static JavaVM *vm_ptr; 42static JavaVM *vm_ptr;
36JNIEnv *env_ptr; 43JNIEnv *env_ptr;
37jobject RockboxService_instance; 44jobject RockboxService_instance;
38jclass RockboxService_class; 45jclass RockboxService_class;
46#endif /* !DX50 && !DX90 */
39 47
40uintptr_t *stackbegin; 48uintptr_t *stackbegin;
41uintptr_t *stackend; 49uintptr_t *stackend;
42 50
43extern int main(void); 51extern int main(void);
52#if !defined(DX50) && !defined(DX90)
44extern void telephony_init_device(void); 53extern void telephony_init_device(void);
45 54#endif
46void system_exception_wait(void) 55void system_exception_wait(void)
47{ 56{
57#if defined(DX50) || defined(DX90)
58 while(1);
59#else
48 intptr_t dummy = 0; 60 intptr_t dummy = 0;
49 while(button_read_device(&dummy) != BUTTON_BACK); 61 while(button_read_device(&dummy) != BUTTON_BACK);
62#endif /* DX50 || DX90 */
50} 63}
51 64
52void system_reboot(void) 65void system_reboot(void)
53{ 66{
67#if defined(DX50) || defined(DX90)
68 reboot(RB_AUTOBOOT);
69#else
54 power_off(); 70 power_off();
71#endif /* DX50 || DX90 */
55} 72}
56 73
74#if !defined(DX50) && !defined(DX90)
57/* this is used to return from the entry point of the native library. */ 75/* this is used to return from the entry point of the native library. */
58static jmp_buf poweroff_buf; 76static jmp_buf poweroff_buf;
77#endif
78
59void power_off(void) 79void power_off(void)
60{ 80{
81#if defined(DX50) || defined(DX90)
82 reboot(RB_POWER_OFF);
83#else
61 longjmp(poweroff_buf, 1); 84 longjmp(poweroff_buf, 1);
85#endif /* DX50 || DX90 */
62} 86}
63 87
64void system_init(void) 88void system_init(void)
65{ 89{
90#if defined(DX50) || defined(DX90)
91 volatile uintptr_t stack = 0;
92 stackbegin = stackend = (uintptr_t*) &stack;
93
94 struct stat m1, m2;
95 stat("/mnt/", &m1);
96 do
97 {
98 /* waiting for storage to get mounted */
99 stat("/sdcard/", &m2);
100 usleep(100000);
101 }
102 while(m1.st_dev == m2.st_dev);
103/* here would be the correct place for 'system("/system/bin/muteopen");' (headphone-out relay) but in pcm-dx50.c, pcm_play_dma_start()
104 the output capacitors are charged already a bit and the click of the headphone-connection-relay is softer */
105
106#if defined(DX90)
107 /* DAC needs to be unmuted on DX90 */
108 FILE * f = fopen("/sys/class/codec/wm8740_mute", "w");
109 fputc(0, f);
110 fclose(f);
111#endif /* DX90 */
112
113#else
66 /* no better place yet */ 114 /* no better place yet */
67 telephony_init_device(); 115 telephony_init_device();
116#endif /* DX50 || DX90 */
68} 117}
69 118
70int hostfs_init(void) 119int hostfs_init(void)
@@ -79,6 +128,7 @@ int hostfs_flush(void)
79 return 0; 128 return 0;
80} 129}
81 130
131#if !defined(DX50) && !defined(DX90)
82JNIEXPORT jint JNICALL 132JNIEXPORT jint JNICALL
83JNI_OnLoad(JavaVM *vm, void* reserved) 133JNI_OnLoad(JavaVM *vm, void* reserved)
84{ 134{
@@ -119,7 +169,7 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this)
119 /* simply return here. this will allow the VM to clean up objects and do 169 /* simply return here. this will allow the VM to clean up objects and do
120 * garbage collection */ 170 * garbage collection */
121} 171}
122 172#endif /* !DX50 && !DX90 */
123 173
124/* below is the facility for external (from other java threads) to safely call 174/* below is the facility for external (from other java threads) to safely call
125 * into our snative code. When extracting rockbox.zip the main function is 175 * into our snative code. When extracting rockbox.zip the main function is
diff --git a/firmware/target/hosted/filesystem-app.c b/firmware/target/hosted/filesystem-app.c
index a4730a07d9..93fadc6d6e 100644
--- a/firmware/target/hosted/filesystem-app.c
+++ b/firmware/target/hosted/filesystem-app.c
@@ -104,6 +104,7 @@ void paths_init(void)
104#if (CONFIG_PLATFORM & PLATFORM_ANDROID) 104#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
105 os_mkdir("/sdcard/rockbox" __MKDIR_MODE_ARG); 105 os_mkdir("/sdcard/rockbox" __MKDIR_MODE_ARG);
106 os_mkdir("/sdcard/rockbox/rocks.data" __MKDIR_MODE_ARG); 106 os_mkdir("/sdcard/rockbox/rocks.data" __MKDIR_MODE_ARG);
107 os_mkdir("/sdcard/rockbox/eqs" __MKDIR_MODE_ARG);
107#else 108#else
108 char config_dir[MAX_PATH]; 109 char config_dir[MAX_PATH];
109 110
diff --git a/manual/rockbox_interface/images/ibassodx50-front.pdf b/manual/rockbox_interface/images/ibassodx50-front.pdf
new file mode 100644
index 0000000000..ab35104b47
--- /dev/null
+++ b/manual/rockbox_interface/images/ibassodx50-front.pdf
Binary files differ
diff --git a/manual/rockbox_interface/images/ibassodx50-front.png b/manual/rockbox_interface/images/ibassodx50-front.png
new file mode 100644
index 0000000000..cb81b0dab1
--- /dev/null
+++ b/manual/rockbox_interface/images/ibassodx50-front.png
Binary files differ
diff --git a/manual/rockbox_interface/images/ibassodx50-front.svg b/manual/rockbox_interface/images/ibassodx50-front.svg
new file mode 100644
index 0000000000..81f9c8ee8c
--- /dev/null
+++ b/manual/rockbox_interface/images/ibassodx50-front.svg
@@ -0,0 +1,1966 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
6 xmlns:dc="http://purl.org/dc/elements/1.1/"
7 xmlns:cc="http://creativecommons.org/ns#"
8 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
9 xmlns:svg="http://www.w3.org/2000/svg"
10 xmlns="http://www.w3.org/2000/svg"
11 xmlns:xlink="http://www.w3.org/1999/xlink"
12 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
13 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
14 width="444.54602"
15 height="378.26721"
16 id="svg2"
17 version="1.1"
18 inkscape:version="0.48.4 r9939"
19 sodipodi:docname="manual-rockbox_interface-images-ibassodx50-front.svg"
20 style="display:inline"
21 inkscape:export-filename="/home/simon/Desktop/DX50 graph/manual-rockbox_interface-images-ibassodx50-front.png"
22 inkscape:export-xdpi="96"
23 inkscape:export-ydpi="96">
24 <title
25 id="title6374">iBasso DX50</title>
26 <defs
27 id="defs4">
28 <linearGradient
29 id="linearGradient8592">
30 <stop
31 id="stop8594"
32 offset="0"
33 style="stop-color:#141414;stop-opacity:1;" />
34 <stop
35 id="stop8596"
36 offset="0.14162582"
37 style="stop-color:#070707;stop-opacity:1;" />
38 <stop
39 id="stop8598"
40 offset="0.87554538"
41 style="stop-color:#070707;stop-opacity:1;" />
42 <stop
43 style="stop-color:#020202;stop-opacity:1;"
44 offset="1"
45 id="stop8600" />
46 </linearGradient>
47 <linearGradient
48 id="linearGradient7455"
49 osb:paint="solid">
50 <stop
51 style="stop-color:#4f4f4f;stop-opacity:1;"
52 offset="0"
53 id="stop7457" />
54 </linearGradient>
55 <linearGradient
56 id="linearGradient5151">
57 <stop
58 style="stop-color:#040404;stop-opacity:1;"
59 offset="0"
60 id="stop5153" />
61 <stop
62 id="stop5155"
63 offset="0.62867177"
64 style="stop-color:#191919;stop-opacity:1;" />
65 <stop
66 style="stop-color:#383838;stop-opacity:1;"
67 offset="0.88642782"
68 id="stop5157" />
69 <stop
70 id="stop5159"
71 offset="1"
72 style="stop-color:#434343;stop-opacity:1;" />
73 </linearGradient>
74 <linearGradient
75 id="linearGradient7633">
76 <stop
77 style="stop-color:#1b1b1b;stop-opacity:1;"
78 offset="0"
79 id="stop7635" />
80 <stop
81 style="stop-color:#1e1e1e;stop-opacity:1;"
82 offset="0.14162582"
83 id="stop7637" />
84 <stop
85 style="stop-color:#191919;stop-opacity:1;"
86 offset="0.87554538"
87 id="stop7641" />
88 <stop
89 id="stop7643"
90 offset="1"
91 style="stop-color:#2a2a2a;stop-opacity:1;" />
92 </linearGradient>
93 <linearGradient
94 id="linearGradient6376">
95 <stop
96 style="stop-color:#000000;stop-opacity:1"
97 offset="0"
98 id="stop6378" />
99 <stop
100 id="stop6380"
101 offset="0.54196042"
102 style="stop-color:#1a1a1a;stop-opacity:1" />
103 <stop
104 id="stop6382"
105 offset="0.60085368"
106 style="stop-color:#1a1a1a;stop-opacity:1" />
107 <stop
108 id="stop6384"
109 offset="0.65499872"
110 style="stop-color:#1a1a1a;stop-opacity:1" />
111 <stop
112 style="stop-color:#1a1a1a;stop-opacity:1"
113 offset="0.65499872"
114 id="stop6386" />
115 <stop
116 style="stop-color:#4d4d4d;stop-opacity:1"
117 offset="0.75479239"
118 id="stop6388" />
119 <stop
120 style="stop-color:#333333;stop-opacity:1"
121 offset="0.80990416"
122 id="stop6390" />
123 <stop
124 id="stop6392"
125 offset="1"
126 style="stop-color:#000000;stop-opacity:1" />
127 </linearGradient>
128 <linearGradient
129 id="linearGradient6425-4">
130 <stop
131 style="stop-color:#3c3c3c;stop-opacity:1;"
132 offset="0"
133 id="stop6427-1" />
134 <stop
135 style="stop-color:#272727;stop-opacity:1;"
136 offset="1"
137 id="stop6429-8" />
138 </linearGradient>
139 <linearGradient
140 y2="3934.3799"
141 x2="4910.75"
142 y1="3743.74"
143 x1="4877.3301"
144 gradientUnits="userSpaceOnUse"
145 id="id2-33-6-4">
146 <stop
147 id="stop2999-7-3-7"
148 style="stop-color:#EFB000"
149 offset="0" />
150 <stop
151 id="stop3001-98-0-8"
152 style="stop-color:#A5732B"
153 offset="0.6" />
154 <stop
155 id="stop3003-6-2-7"
156 style="stop-color:#492A28"
157 offset="1" />
158 <stop
159 id="stop3005-7-0-4"
160 style="stop-color:#492A28"
161 offset="1" />
162 </linearGradient>
163 <linearGradient
164 id="linearGradient4997">
165 <stop
166 id="stop4999"
167 offset="0"
168 style="stop-color:#cccccc;stop-opacity:1" />
169 <stop
170 style="stop-color:#ffffff;stop-opacity:1"
171 offset="0.64489639"
172 id="stop5005" />
173 <stop
174 id="stop5001"
175 offset="1"
176 style="stop-color:#808080;stop-opacity:1" />
177 </linearGradient>
178 <linearGradient
179 id="linearGradient6077-8">
180 <stop
181 style="stop-color:#222222;stop-opacity:1;"
182 offset="0"
183 id="stop6079-3" />
184 <stop
185 id="stop6085-1"
186 offset="0.5"
187 style="stop-color:#353535;stop-opacity:1;" />
188 <stop
189 style="stop-color:#141414;stop-opacity:1;"
190 offset="1"
191 id="stop6081-6" />
192 </linearGradient>
193 <linearGradient
194 id="linearGradient6425-4-3-4">
195 <stop
196 style="stop-color:#757575;stop-opacity:1"
197 offset="0"
198 id="stop6427-1-6-9" />
199 <stop
200 id="stop5246"
201 offset="0.07079889"
202 style="stop-color:#6d6d6d;stop-opacity:1;" />
203 <stop
204 style="stop-color:#2e2e2e;stop-opacity:1;"
205 offset="0.21239667"
206 id="stop5248" />
207 <stop
208 style="stop-color:#1b1b1b;stop-opacity:1"
209 offset="1"
210 id="stop6429-8-1-9" />
211 </linearGradient>
212 <linearGradient
213 y2="6768.9199"
214 x2="-64.68"
215 y1="9531.0195"
216 x1="10064.7"
217 gradientUnits="userSpaceOnUse"
218 id="id11-5-1-5"
219 gradientTransform="translate(-15385.399,557.13145)">
220 <stop
221 id="stop129-5-8-9"
222 stop-color="#484A4C"
223 offset="0"
224 style="stop-color:#1e1e20;stop-opacity:1;" />
225 <stop
226 id="stop131-1-3-78"
227 stop-color="#252425"
228 offset="0.50980401"
229 style="stop-color:#312f31;stop-opacity:1;" />
230 <stop
231 id="stop133-0-3-1"
232 stop-color="#494747"
233 offset="1"
234 style="stop-color:#4d4b4b;stop-opacity:1;" />
235 <stop
236 id="stop135-8-4-9"
237 stop-color="#494747"
238 offset="1"
239 style="stop-color:#2c2c2c;stop-opacity:1;" />
240 </linearGradient>
241 <linearGradient
242 id="linearGradient15570-9-9-5-1-8">
243 <stop
244 id="stop15572-8-1-4-9-6"
245 offset="0"
246 style="stop-color:#333333;stop-opacity:1" />
247 <stop
248 style="stop-color:#484848;stop-opacity:1"
249 offset="0.17310488"
250 id="stop15584-3-9-1-4-5" />
251 <stop
252 style="stop-color:#3b3b3b;stop-opacity:1"
253 offset="0.28851423"
254 id="stop15582-8-0-9-2-7" />
255 <stop
256 style="stop-color:#2f2f2f;stop-opacity:1"
257 offset="0.47606128"
258 id="stop15574-2-4-7-9-5" />
259 <stop
260 id="stop15576-8-6-0-6-5"
261 offset="0.7130661"
262 style="stop-color:#161616;stop-opacity:1" />
263 <stop
264 style="stop-color:#161616;stop-opacity:1"
265 offset="0.91021168"
266 id="stop15578-1-1-0-0-7" />
267 <stop
268 id="stop15580-4-6-1-6-2"
269 offset="1"
270 style="stop-color:#1d1d1d;stop-opacity:1" />
271 </linearGradient>
272 <filter
273 inkscape:collect="always"
274 id="filter5226"
275 color-interpolation-filters="sRGB">
276 <feGaussianBlur
277 inkscape:collect="always"
278 stdDeviation="1.2194559"
279 id="feGaussianBlur5228" />
280 </filter>
281 <linearGradient
282 id="linearGradient6425-4-3-4-9">
283 <stop
284 style="stop-color:#757575;stop-opacity:1"
285 offset="0"
286 id="stop6427-1-6-9-3" />
287 <stop
288 id="stop5246-5"
289 offset="0.07079889"
290 style="stop-color:#6d6d6d;stop-opacity:1;" />
291 <stop
292 style="stop-color:#2e2e2e;stop-opacity:1;"
293 offset="0.21239667"
294 id="stop5248-37" />
295 <stop
296 style="stop-color:#1b1b1b;stop-opacity:1"
297 offset="1"
298 id="stop6429-8-1-9-05" />
299 </linearGradient>
300 <linearGradient
301 id="linearGradient6425-4-3-4-1">
302 <stop
303 style="stop-color:#757575;stop-opacity:1"
304 offset="0"
305 id="stop6427-1-6-9-8" />
306 <stop
307 id="stop5246-24"
308 offset="0.07079889"
309 style="stop-color:#6d6d6d;stop-opacity:1;" />
310 <stop
311 style="stop-color:#2e2e2e;stop-opacity:1;"
312 offset="0.21239667"
313 id="stop5248-370" />
314 <stop
315 style="stop-color:#1b1b1b;stop-opacity:1"
316 offset="1"
317 id="stop6429-8-1-9-6" />
318 </linearGradient>
319 <linearGradient
320 id="linearGradient6425-4-3-4-1-0">
321 <stop
322 style="stop-color:#757575;stop-opacity:1"
323 offset="0"
324 id="stop6427-1-6-9-8-5" />
325 <stop
326 id="stop5246-24-8"
327 offset="0.07079889"
328 style="stop-color:#6d6d6d;stop-opacity:1;" />
329 <stop
330 style="stop-color:#2e2e2e;stop-opacity:1;"
331 offset="0.21239667"
332 id="stop5248-370-9" />
333 <stop
334 style="stop-color:#1b1b1b;stop-opacity:1"
335 offset="1"
336 id="stop6429-8-1-9-6-6" />
337 </linearGradient>
338 <linearGradient
339 id="linearGradient6425-4-3-4-9-5">
340 <stop
341 style="stop-color:#757575;stop-opacity:1"
342 offset="0"
343 id="stop6427-1-6-9-3-9" />
344 <stop
345 id="stop5246-5-3"
346 offset="0.07079889"
347 style="stop-color:#6d6d6d;stop-opacity:1;" />
348 <stop
349 style="stop-color:#2e2e2e;stop-opacity:1;"
350 offset="0.21239667"
351 id="stop5248-37-1" />
352 <stop
353 style="stop-color:#1b1b1b;stop-opacity:1"
354 offset="1"
355 id="stop6429-8-1-9-05-8" />
356 </linearGradient>
357 <filter
358 inkscape:collect="always"
359 id="filter6851"
360 x="-0.30888385"
361 width="1.6177677"
362 y="-0.27776667"
363 height="1.5555333"
364 color-interpolation-filters="sRGB">
365 <feGaussianBlur
366 inkscape:collect="always"
367 stdDeviation="1.1547718"
368 id="feGaussianBlur6853" />
369 </filter>
370 <linearGradient
371 id="linearGradient5151-0">
372 <stop
373 style="stop-color:#040404;stop-opacity:1;"
374 offset="0"
375 id="stop5153-4" />
376 <stop
377 id="stop5155-8"
378 offset="0.62867177"
379 style="stop-color:#191919;stop-opacity:1;" />
380 <stop
381 style="stop-color:#383838;stop-opacity:1;"
382 offset="0.88642782"
383 id="stop5157-7" />
384 <stop
385 id="stop5159-5"
386 offset="1"
387 style="stop-color:#434343;stop-opacity:1;" />
388 </linearGradient>
389 <linearGradient
390 id="linearGradient6425-4-3-4-09">
391 <stop
392 style="stop-color:#757575;stop-opacity:1"
393 offset="0"
394 id="stop6427-1-6-9-0" />
395 <stop
396 id="stop5246-7"
397 offset="0.07079889"
398 style="stop-color:#6d6d6d;stop-opacity:1;" />
399 <stop
400 style="stop-color:#2e2e2e;stop-opacity:1;"
401 offset="0.21239667"
402 id="stop5248-8" />
403 <stop
404 style="stop-color:#1b1b1b;stop-opacity:1"
405 offset="1"
406 id="stop6429-8-1-9-7" />
407 </linearGradient>
408 <filter
409 color-interpolation-filters="sRGB"
410 inkscape:collect="always"
411 id="filter5226-7">
412 <feGaussianBlur
413 inkscape:collect="always"
414 stdDeviation="1.2194559"
415 id="feGaussianBlur5228-7" />
416 </filter>
417 <linearGradient
418 y2="6768.9199"
419 x2="-64.68"
420 y1="9531.0195"
421 x1="10064.7"
422 gradientUnits="userSpaceOnUse"
423 id="id11-5-1-5-1"
424 gradientTransform="translate(-15385.399,557.13145)">
425 <stop
426 id="stop129-5-8-9-6"
427 stop-color="#484A4C"
428 offset="0"
429 style="stop-color:#1e1e20;stop-opacity:1;" />
430 <stop
431 id="stop131-1-3-78-5"
432 stop-color="#252425"
433 offset="0.50980401"
434 style="stop-color:#312f31;stop-opacity:1;" />
435 <stop
436 id="stop133-0-3-1-7"
437 stop-color="#494747"
438 offset="1"
439 style="stop-color:#4d4b4b;stop-opacity:1;" />
440 <stop
441 id="stop135-8-4-9-9"
442 stop-color="#494747"
443 offset="1"
444 style="stop-color:#2c2c2c;stop-opacity:1;" />
445 </linearGradient>
446 <linearGradient
447 id="linearGradient15570-9-9-5-1-8-8">
448 <stop
449 id="stop15572-8-1-4-9-6-1"
450 offset="0"
451 style="stop-color:#333333;stop-opacity:1" />
452 <stop
453 style="stop-color:#484848;stop-opacity:1"
454 offset="0.17310488"
455 id="stop15584-3-9-1-4-5-8" />
456 <stop
457 style="stop-color:#3b3b3b;stop-opacity:1"
458 offset="0.28851423"
459 id="stop15582-8-0-9-2-7-9" />
460 <stop
461 style="stop-color:#2f2f2f;stop-opacity:1"
462 offset="0.47606128"
463 id="stop15574-2-4-7-9-5-85" />
464 <stop
465 id="stop15576-8-6-0-6-5-66"
466 offset="0.7130661"
467 style="stop-color:#161616;stop-opacity:1" />
468 <stop
469 style="stop-color:#161616;stop-opacity:1"
470 offset="0.91021168"
471 id="stop15578-1-1-0-0-7-1" />
472 <stop
473 id="stop15580-4-6-1-6-2-6"
474 offset="1"
475 style="stop-color:#1d1d1d;stop-opacity:1" />
476 </linearGradient>
477 <linearGradient
478 id="linearGradient5151-3">
479 <stop
480 style="stop-color:#040404;stop-opacity:1;"
481 offset="0"
482 id="stop5153-8" />
483 <stop
484 id="stop5155-1"
485 offset="0.62867177"
486 style="stop-color:#191919;stop-opacity:1;" />
487 <stop
488 style="stop-color:#383838;stop-opacity:1;"
489 offset="0.88642782"
490 id="stop5157-6" />
491 <stop
492 id="stop5159-51"
493 offset="1"
494 style="stop-color:#434343;stop-opacity:1;" />
495 </linearGradient>
496 <linearGradient
497 id="linearGradient6425-4-3-4-5">
498 <stop
499 style="stop-color:#757575;stop-opacity:1"
500 offset="0"
501 id="stop6427-1-6-9-1" />
502 <stop
503 id="stop5246-28"
504 offset="0.07079889"
505 style="stop-color:#6d6d6d;stop-opacity:1;" />
506 <stop
507 style="stop-color:#2e2e2e;stop-opacity:1;"
508 offset="0.21239667"
509 id="stop5248-79" />
510 <stop
511 style="stop-color:#1b1b1b;stop-opacity:1"
512 offset="1"
513 id="stop6429-8-1-9-58" />
514 </linearGradient>
515 <filter
516 color-interpolation-filters="sRGB"
517 inkscape:collect="always"
518 id="filter5226-8">
519 <feGaussianBlur
520 inkscape:collect="always"
521 stdDeviation="1.2194559"
522 id="feGaussianBlur5228-51" />
523 </filter>
524 <linearGradient
525 y2="6768.9199"
526 x2="-64.68"
527 y1="9531.0195"
528 x1="10064.7"
529 gradientUnits="userSpaceOnUse"
530 id="id11-5-1-5-41"
531 gradientTransform="translate(-15385.399,557.13145)">
532 <stop
533 id="stop129-5-8-9-4"
534 stop-color="#484A4C"
535 offset="0"
536 style="stop-color:#1e1e20;stop-opacity:1;" />
537 <stop
538 id="stop131-1-3-78-18"
539 stop-color="#252425"
540 offset="0.50980401"
541 style="stop-color:#312f31;stop-opacity:1;" />
542 <stop
543 id="stop133-0-3-1-79"
544 stop-color="#494747"
545 offset="1"
546 style="stop-color:#4d4b4b;stop-opacity:1;" />
547 <stop
548 id="stop135-8-4-9-6"
549 stop-color="#494747"
550 offset="1"
551 style="stop-color:#2c2c2c;stop-opacity:1;" />
552 </linearGradient>
553 <linearGradient
554 id="linearGradient15570-9-9-5-1-8-5">
555 <stop
556 id="stop15572-8-1-4-9-6-4"
557 offset="0"
558 style="stop-color:#333333;stop-opacity:1" />
559 <stop
560 style="stop-color:#484848;stop-opacity:1"
561 offset="0.17310488"
562 id="stop15584-3-9-1-4-5-80" />
563 <stop
564 style="stop-color:#3b3b3b;stop-opacity:1"
565 offset="0.28851423"
566 id="stop15582-8-0-9-2-7-3" />
567 <stop
568 style="stop-color:#2f2f2f;stop-opacity:1"
569 offset="0.47606128"
570 id="stop15574-2-4-7-9-5-9" />
571 <stop
572 id="stop15576-8-6-0-6-5-60"
573 offset="0.7130661"
574 style="stop-color:#161616;stop-opacity:1" />
575 <stop
576 style="stop-color:#161616;stop-opacity:1"
577 offset="0.91021168"
578 id="stop15578-1-1-0-0-7-3" />
579 <stop
580 id="stop15580-4-6-1-6-2-9"
581 offset="1"
582 style="stop-color:#1d1d1d;stop-opacity:1" />
583 </linearGradient>
584 <linearGradient
585 inkscape:collect="always"
586 xlink:href="#linearGradient7633"
587 id="linearGradient3472"
588 gradientUnits="userSpaceOnUse"
589 x1="55.85672"
590 y1="335.20624"
591 x2="66.763878"
592 y2="335.20624" />
593 <linearGradient
594 inkscape:collect="always"
595 xlink:href="#linearGradient4997"
596 id="linearGradient3474"
597 gradientUnits="userSpaceOnUse"
598 spreadMethod="pad"
599 x1="55.90625"
600 y1="316.375"
601 x2="66.71875"
602 y2="316.375" />
603 <linearGradient
604 inkscape:collect="always"
605 xlink:href="#linearGradient5151"
606 id="linearGradient3478"
607 gradientUnits="userSpaceOnUse"
608 gradientTransform="translate(345.54877,627.16011)"
609 x1="-174.27351"
610 y1="-332.50967"
611 x2="-117.25081"
612 y2="-275.30774" />
613 <linearGradient
614 inkscape:collect="always"
615 xlink:href="#linearGradient6425-4-3-4"
616 id="linearGradient3480"
617 gradientUnits="userSpaceOnUse"
618 x1="228.29796"
619 y1="351.85236"
620 x2="171.27525"
621 y2="294.65045" />
622 <linearGradient
623 inkscape:collect="always"
624 xlink:href="#id11-5-1-5"
625 id="linearGradient3482"
626 gradientUnits="userSpaceOnUse"
627 gradientTransform="translate(345.54875,627.16011)"
628 x1="-169.15022"
629 y1="-321.3381"
630 x2="-120.44732"
631 y2="-285.0881" />
632 <linearGradient
633 inkscape:collect="always"
634 xlink:href="#linearGradient15570-9-9-5-1-8"
635 id="linearGradient3484"
636 gradientUnits="userSpaceOnUse"
637 gradientTransform="translate(345.54875,627.16011)"
638 x1="-169.15022"
639 y1="-321.3381"
640 x2="-120.44732"
641 y2="-285.0881" />
642 <linearGradient
643 inkscape:collect="always"
644 xlink:href="#linearGradient5151-3"
645 id="linearGradient3486"
646 gradientUnits="userSpaceOnUse"
647 gradientTransform="translate(345.54877,627.16011)"
648 x1="-174.27351"
649 y1="-332.50967"
650 x2="-117.25081"
651 y2="-275.30774" />
652 <linearGradient
653 inkscape:collect="always"
654 xlink:href="#linearGradient6425-4-3-4-5"
655 id="linearGradient3488"
656 gradientUnits="userSpaceOnUse"
657 x1="228.29796"
658 y1="351.85236"
659 x2="171.27525"
660 y2="294.65045" />
661 <linearGradient
662 inkscape:collect="always"
663 xlink:href="#id11-5-1-5-41"
664 id="linearGradient3490"
665 gradientUnits="userSpaceOnUse"
666 gradientTransform="translate(345.54875,627.16011)"
667 x1="-169.15022"
668 y1="-321.3381"
669 x2="-120.44732"
670 y2="-285.0881" />
671 <linearGradient
672 inkscape:collect="always"
673 xlink:href="#linearGradient15570-9-9-5-1-8-5"
674 id="linearGradient3492"
675 gradientUnits="userSpaceOnUse"
676 gradientTransform="translate(345.54875,627.16011)"
677 x1="-169.15022"
678 y1="-321.3381"
679 x2="-120.44732"
680 y2="-285.0881" />
681 <linearGradient
682 inkscape:collect="always"
683 xlink:href="#id2-33-6-4"
684 id="linearGradient3498"
685 gradientUnits="userSpaceOnUse"
686 x1="4877.3301"
687 y1="3743.74"
688 x2="4910.75"
689 y2="3934.3799" />
690 <linearGradient
691 inkscape:collect="always"
692 xlink:href="#linearGradient5151-0"
693 id="linearGradient3500"
694 gradientUnits="userSpaceOnUse"
695 gradientTransform="translate(345.54877,627.16011)"
696 x1="-174.27351"
697 y1="-332.50967"
698 x2="-117.25081"
699 y2="-275.30774" />
700 <linearGradient
701 inkscape:collect="always"
702 xlink:href="#linearGradient6425-4-3-4-09"
703 id="linearGradient3502"
704 gradientUnits="userSpaceOnUse"
705 x1="228.29796"
706 y1="351.85236"
707 x2="171.27525"
708 y2="294.65045" />
709 <linearGradient
710 inkscape:collect="always"
711 xlink:href="#id11-5-1-5-1"
712 id="linearGradient3504"
713 gradientUnits="userSpaceOnUse"
714 gradientTransform="translate(345.54875,627.16011)"
715 x1="-169.15022"
716 y1="-321.3381"
717 x2="-120.44732"
718 y2="-285.0881" />
719 <linearGradient
720 inkscape:collect="always"
721 xlink:href="#linearGradient15570-9-9-5-1-8-8"
722 id="linearGradient3506"
723 gradientUnits="userSpaceOnUse"
724 gradientTransform="translate(345.54875,627.16011)"
725 x1="-169.15022"
726 y1="-321.3381"
727 x2="-120.44732"
728 y2="-285.0881" />
729 <linearGradient
730 inkscape:collect="always"
731 xlink:href="#linearGradient6425-4-3-4-1-0"
732 id="linearGradient3446"
733 gradientUnits="userSpaceOnUse"
734 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,117.00472)"
735 x1="50.204582"
736 y1="24.731405"
737 x2="50.204582"
738 y2="21.0718" />
739 <linearGradient
740 inkscape:collect="always"
741 xlink:href="#linearGradient6425-4-3-4-9"
742 id="linearGradient3449"
743 gradientUnits="userSpaceOnUse"
744 gradientTransform="matrix(0,-0.36298039,1.1528432,0,49.539774,111.72068)"
745 x1="50.204582"
746 y1="24.731405"
747 x2="50.204582"
748 y2="21.0718" />
749 <linearGradient
750 inkscape:collect="always"
751 xlink:href="#linearGradient6425-4-3-4"
752 id="linearGradient3452"
753 gradientUnits="userSpaceOnUse"
754 gradientTransform="matrix(0,-0.38527708,0.78727403,0,58.433234,56.29863)"
755 x1="50.204582"
756 y1="24.731405"
757 x2="50.204582"
758 y2="21.0718" />
759 <linearGradient
760 inkscape:collect="always"
761 xlink:href="#linearGradient6376"
762 id="linearGradient3483"
763 gradientUnits="userSpaceOnUse"
764 gradientTransform="translate(21.566734,-139.2058)"
765 x1="48.236862"
766 y1="215.45312"
767 x2="279.76315"
768 y2="304.45312" />
769 <linearGradient
770 inkscape:collect="always"
771 xlink:href="#linearGradient6425-4"
772 id="linearGradient3495"
773 gradientUnits="userSpaceOnUse"
774 gradientTransform="matrix(1,0,0,1.0132067,-8.433266,-96.898305)"
775 x1="100.82813"
776 y1="319.75"
777 x2="298.17188"
778 y2="319.75" />
779 <linearGradient
780 inkscape:collect="always"
781 xlink:href="#linearGradient8592"
782 id="linearGradient3501"
783 gradientUnits="userSpaceOnUse"
784 gradientTransform="translate(21.566734,-139.2058)"
785 x1="271.37906"
786 y1="316.37115"
787 x2="283.19156"
788 y2="316.37115" />
789 <linearGradient
790 inkscape:collect="always"
791 xlink:href="#linearGradient6077-8"
792 id="linearGradient3505"
793 gradientUnits="userSpaceOnUse"
794 gradientTransform="translate(21.566734,-139.2058)"
795 x1="55.419907"
796 y1="316.37115"
797 x2="283.19156"
798 y2="316.37115" />
799 <linearGradient
800 inkscape:collect="always"
801 xlink:href="#linearGradient6425-4-3-4-1"
802 id="linearGradient3509"
803 gradientUnits="userSpaceOnUse"
804 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,66.045134)"
805 x1="50.204582"
806 y1="24.731405"
807 x2="50.204582"
808 y2="21.0718" />
809 <linearGradient
810 inkscape:collect="always"
811 xlink:href="#linearGradient6425-4-3-4-9-5"
812 id="linearGradient3513"
813 gradientUnits="userSpaceOnUse"
814 gradientTransform="matrix(-0.36298039,0,0,-1.1528432,249.0045,382.24845)"
815 x1="50.204582"
816 y1="24.731405"
817 x2="50.204582"
818 y2="21.0718" />
819 <linearGradient
820 inkscape:collect="always"
821 xlink:href="#linearGradient6425-4-3-4-9-5"
822 id="linearGradient4338"
823 gradientUnits="userSpaceOnUse"
824 gradientTransform="matrix(-0.36298039,0,0,-1.1528432,249.0045,382.24845)"
825 x1="50.204582"
826 y1="24.731405"
827 x2="50.204582"
828 y2="21.0718" />
829 <linearGradient
830 inkscape:collect="always"
831 xlink:href="#linearGradient6425-4-3-4-1"
832 id="linearGradient4340"
833 gradientUnits="userSpaceOnUse"
834 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,66.045134)"
835 x1="50.204582"
836 y1="24.731405"
837 x2="50.204582"
838 y2="21.0718" />
839 <linearGradient
840 inkscape:collect="always"
841 xlink:href="#linearGradient6077-8"
842 id="linearGradient4342"
843 gradientUnits="userSpaceOnUse"
844 gradientTransform="translate(21.566734,-139.2058)"
845 x1="55.419907"
846 y1="316.37115"
847 x2="283.19156"
848 y2="316.37115" />
849 <linearGradient
850 inkscape:collect="always"
851 xlink:href="#linearGradient8592"
852 id="linearGradient4344"
853 gradientUnits="userSpaceOnUse"
854 gradientTransform="translate(21.566734,-139.2058)"
855 x1="271.37906"
856 y1="316.37115"
857 x2="283.19156"
858 y2="316.37115" />
859 <linearGradient
860 inkscape:collect="always"
861 xlink:href="#linearGradient7633"
862 id="linearGradient4346"
863 gradientUnits="userSpaceOnUse"
864 x1="55.85672"
865 y1="335.20624"
866 x2="66.763878"
867 y2="335.20624" />
868 <linearGradient
869 inkscape:collect="always"
870 xlink:href="#linearGradient4997"
871 id="linearGradient4348"
872 gradientUnits="userSpaceOnUse"
873 spreadMethod="pad"
874 x1="55.90625"
875 y1="316.375"
876 x2="66.71875"
877 y2="316.375" />
878 <linearGradient
879 inkscape:collect="always"
880 xlink:href="#linearGradient6425-4"
881 id="linearGradient4350"
882 gradientUnits="userSpaceOnUse"
883 gradientTransform="matrix(1,0,0,1.0132067,-8.433266,-96.898305)"
884 x1="100.82813"
885 y1="319.75"
886 x2="298.17188"
887 y2="319.75" />
888 <linearGradient
889 inkscape:collect="always"
890 xlink:href="#linearGradient5151"
891 id="linearGradient4352"
892 gradientUnits="userSpaceOnUse"
893 gradientTransform="translate(345.54877,627.16011)"
894 x1="-174.27351"
895 y1="-332.50967"
896 x2="-117.25081"
897 y2="-275.30774" />
898 <linearGradient
899 inkscape:collect="always"
900 xlink:href="#linearGradient6425-4-3-4"
901 id="linearGradient4354"
902 gradientUnits="userSpaceOnUse"
903 x1="228.29796"
904 y1="351.85236"
905 x2="171.27525"
906 y2="294.65045" />
907 <linearGradient
908 inkscape:collect="always"
909 xlink:href="#id11-5-1-5"
910 id="linearGradient4356"
911 gradientUnits="userSpaceOnUse"
912 gradientTransform="translate(345.54875,627.16011)"
913 x1="-169.15022"
914 y1="-321.3381"
915 x2="-120.44732"
916 y2="-285.0881" />
917 <linearGradient
918 inkscape:collect="always"
919 xlink:href="#linearGradient15570-9-9-5-1-8"
920 id="linearGradient4358"
921 gradientUnits="userSpaceOnUse"
922 gradientTransform="translate(345.54875,627.16011)"
923 x1="-169.15022"
924 y1="-321.3381"
925 x2="-120.44732"
926 y2="-285.0881" />
927 <linearGradient
928 inkscape:collect="always"
929 xlink:href="#linearGradient5151-3"
930 id="linearGradient4360"
931 gradientUnits="userSpaceOnUse"
932 gradientTransform="translate(345.54877,627.16011)"
933 x1="-174.27351"
934 y1="-332.50967"
935 x2="-117.25081"
936 y2="-275.30774" />
937 <linearGradient
938 inkscape:collect="always"
939 xlink:href="#linearGradient6425-4-3-4-5"
940 id="linearGradient4362"
941 gradientUnits="userSpaceOnUse"
942 x1="228.29796"
943 y1="351.85236"
944 x2="171.27525"
945 y2="294.65045" />
946 <linearGradient
947 inkscape:collect="always"
948 xlink:href="#id11-5-1-5-41"
949 id="linearGradient4364"
950 gradientUnits="userSpaceOnUse"
951 gradientTransform="translate(345.54875,627.16011)"
952 x1="-169.15022"
953 y1="-321.3381"
954 x2="-120.44732"
955 y2="-285.0881" />
956 <linearGradient
957 inkscape:collect="always"
958 xlink:href="#linearGradient15570-9-9-5-1-8-5"
959 id="linearGradient4366"
960 gradientUnits="userSpaceOnUse"
961 gradientTransform="translate(345.54875,627.16011)"
962 x1="-169.15022"
963 y1="-321.3381"
964 x2="-120.44732"
965 y2="-285.0881" />
966 <linearGradient
967 inkscape:collect="always"
968 xlink:href="#linearGradient6376"
969 id="linearGradient4368"
970 gradientUnits="userSpaceOnUse"
971 gradientTransform="translate(21.566734,-139.2058)"
972 x1="48.236862"
973 y1="215.45312"
974 x2="279.76315"
975 y2="304.45312" />
976 <linearGradient
977 inkscape:collect="always"
978 xlink:href="#id2-33-6-4"
979 id="linearGradient4370"
980 gradientUnits="userSpaceOnUse"
981 x1="4877.3301"
982 y1="3743.74"
983 x2="4910.75"
984 y2="3934.3799" />
985 <linearGradient
986 inkscape:collect="always"
987 xlink:href="#linearGradient5151-0"
988 id="linearGradient4372"
989 gradientUnits="userSpaceOnUse"
990 gradientTransform="translate(345.54877,627.16011)"
991 x1="-174.27351"
992 y1="-332.50967"
993 x2="-117.25081"
994 y2="-275.30774" />
995 <linearGradient
996 inkscape:collect="always"
997 xlink:href="#linearGradient6425-4-3-4-09"
998 id="linearGradient4374"
999 gradientUnits="userSpaceOnUse"
1000 x1="228.29796"
1001 y1="351.85236"
1002 x2="171.27525"
1003 y2="294.65045" />
1004 <linearGradient
1005 inkscape:collect="always"
1006 xlink:href="#id11-5-1-5-1"
1007 id="linearGradient4376"
1008 gradientUnits="userSpaceOnUse"
1009 gradientTransform="translate(345.54875,627.16011)"
1010 x1="-169.15022"
1011 y1="-321.3381"
1012 x2="-120.44732"
1013 y2="-285.0881" />
1014 <linearGradient
1015 inkscape:collect="always"
1016 xlink:href="#linearGradient15570-9-9-5-1-8-8"
1017 id="linearGradient4378"
1018 gradientUnits="userSpaceOnUse"
1019 gradientTransform="translate(345.54875,627.16011)"
1020 x1="-169.15022"
1021 y1="-321.3381"
1022 x2="-120.44732"
1023 y2="-285.0881" />
1024 <linearGradient
1025 inkscape:collect="always"
1026 xlink:href="#linearGradient6425-4-3-4"
1027 id="linearGradient4380"
1028 gradientUnits="userSpaceOnUse"
1029 gradientTransform="matrix(0,-0.38527708,0.78727403,0,58.433234,56.29863)"
1030 x1="50.204582"
1031 y1="24.731405"
1032 x2="50.204582"
1033 y2="21.0718" />
1034 <linearGradient
1035 inkscape:collect="always"
1036 xlink:href="#linearGradient6425-4-3-4-9"
1037 id="linearGradient4382"
1038 gradientUnits="userSpaceOnUse"
1039 gradientTransform="matrix(0,-0.36298039,1.1528432,0,49.539774,111.72068)"
1040 x1="50.204582"
1041 y1="24.731405"
1042 x2="50.204582"
1043 y2="21.0718" />
1044 <linearGradient
1045 inkscape:collect="always"
1046 xlink:href="#linearGradient6425-4-3-4-1-0"
1047 id="linearGradient4384"
1048 gradientUnits="userSpaceOnUse"
1049 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,117.00472)"
1050 x1="50.204582"
1051 y1="24.731405"
1052 x2="50.204582"
1053 y2="21.0718" />
1054 <linearGradient
1055 inkscape:collect="always"
1056 xlink:href="#linearGradient6425-4-3-4-1-0"
1057 id="linearGradient4397"
1058 gradientUnits="userSpaceOnUse"
1059 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,117.00472)"
1060 x1="50.204582"
1061 y1="24.731405"
1062 x2="50.204582"
1063 y2="21.0718" />
1064 <linearGradient
1065 inkscape:collect="always"
1066 xlink:href="#linearGradient6425-4-3-4-9"
1067 id="linearGradient4400"
1068 gradientUnits="userSpaceOnUse"
1069 gradientTransform="matrix(0,-0.36298039,1.1528432,0,49.539772,111.72068)"
1070 x1="50.204582"
1071 y1="24.731405"
1072 x2="50.204582"
1073 y2="21.0718" />
1074 <linearGradient
1075 inkscape:collect="always"
1076 xlink:href="#linearGradient6425-4-3-4"
1077 id="linearGradient4403"
1078 gradientUnits="userSpaceOnUse"
1079 gradientTransform="matrix(0,-0.38527708,0.78727403,0,58.433232,56.29863)"
1080 x1="50.204582"
1081 y1="24.731405"
1082 x2="50.204582"
1083 y2="21.0718" />
1084 <linearGradient
1085 inkscape:collect="always"
1086 xlink:href="#linearGradient6376"
1087 id="linearGradient4430"
1088 gradientUnits="userSpaceOnUse"
1089 gradientTransform="translate(21.566732,-139.2058)"
1090 x1="48.236862"
1091 y1="215.45312"
1092 x2="279.76315"
1093 y2="304.45312" />
1094 <linearGradient
1095 inkscape:collect="always"
1096 xlink:href="#linearGradient6425-4"
1097 id="linearGradient4441"
1098 gradientUnits="userSpaceOnUse"
1099 gradientTransform="matrix(1,0,0,1.0132067,-8.4332679,-96.898305)"
1100 x1="100.82813"
1101 y1="319.75"
1102 x2="298.17188"
1103 y2="319.75" />
1104 <linearGradient
1105 inkscape:collect="always"
1106 xlink:href="#linearGradient8592"
1107 id="linearGradient4446"
1108 gradientUnits="userSpaceOnUse"
1109 gradientTransform="translate(21.566732,-139.2058)"
1110 x1="271.37906"
1111 y1="316.37115"
1112 x2="283.19156"
1113 y2="316.37115" />
1114 <linearGradient
1115 inkscape:collect="always"
1116 xlink:href="#linearGradient6077-8"
1117 id="linearGradient4449"
1118 gradientUnits="userSpaceOnUse"
1119 gradientTransform="translate(21.566732,-139.2058)"
1120 x1="55.419907"
1121 y1="316.37115"
1122 x2="283.19156"
1123 y2="316.37115" />
1124 <linearGradient
1125 inkscape:collect="always"
1126 xlink:href="#linearGradient6425-4-3-4-1"
1127 id="linearGradient4452"
1128 gradientUnits="userSpaceOnUse"
1129 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,66.045134)"
1130 x1="50.204582"
1131 y1="24.731405"
1132 x2="50.204582"
1133 y2="21.0718" />
1134 <linearGradient
1135 inkscape:collect="always"
1136 xlink:href="#linearGradient6425-4-3-4-9-5"
1137 id="linearGradient4455"
1138 gradientUnits="userSpaceOnUse"
1139 gradientTransform="matrix(-0.36298039,0,0,-1.1528432,249.0045,382.24845)"
1140 x1="50.204582"
1141 y1="24.731405"
1142 x2="50.204582"
1143 y2="21.0718" />
1144 <linearGradient
1145 inkscape:collect="always"
1146 xlink:href="#linearGradient6425-4-3-4-9-5"
1147 id="linearGradient4530"
1148 gradientUnits="userSpaceOnUse"
1149 gradientTransform="matrix(-0.36298039,0,0,-1.1528432,249.0045,382.24845)"
1150 x1="50.204582"
1151 y1="24.731405"
1152 x2="50.204582"
1153 y2="21.0718" />
1154 <linearGradient
1155 inkscape:collect="always"
1156 xlink:href="#linearGradient6425-4-3-4-1"
1157 id="linearGradient4532"
1158 gradientUnits="userSpaceOnUse"
1159 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,66.045134)"
1160 x1="50.204582"
1161 y1="24.731405"
1162 x2="50.204582"
1163 y2="21.0718" />
1164 <linearGradient
1165 inkscape:collect="always"
1166 xlink:href="#linearGradient6077-8"
1167 id="linearGradient4534"
1168 gradientUnits="userSpaceOnUse"
1169 gradientTransform="translate(21.566732,-139.2058)"
1170 x1="55.419907"
1171 y1="316.37115"
1172 x2="283.19156"
1173 y2="316.37115" />
1174 <linearGradient
1175 inkscape:collect="always"
1176 xlink:href="#linearGradient8592"
1177 id="linearGradient4536"
1178 gradientUnits="userSpaceOnUse"
1179 gradientTransform="translate(21.566732,-139.2058)"
1180 x1="271.37906"
1181 y1="316.37115"
1182 x2="283.19156"
1183 y2="316.37115" />
1184 <linearGradient
1185 inkscape:collect="always"
1186 xlink:href="#linearGradient7633"
1187 id="linearGradient4538"
1188 gradientUnits="userSpaceOnUse"
1189 x1="55.85672"
1190 y1="335.20624"
1191 x2="66.763878"
1192 y2="335.20624" />
1193 <linearGradient
1194 inkscape:collect="always"
1195 xlink:href="#linearGradient4997"
1196 id="linearGradient4540"
1197 gradientUnits="userSpaceOnUse"
1198 spreadMethod="pad"
1199 x1="55.90625"
1200 y1="316.375"
1201 x2="66.71875"
1202 y2="316.375" />
1203 <linearGradient
1204 inkscape:collect="always"
1205 xlink:href="#linearGradient6425-4"
1206 id="linearGradient4542"
1207 gradientUnits="userSpaceOnUse"
1208 gradientTransform="matrix(1,0,0,1.0132067,-8.4332679,-96.898305)"
1209 x1="100.82813"
1210 y1="319.75"
1211 x2="298.17188"
1212 y2="319.75" />
1213 <linearGradient
1214 inkscape:collect="always"
1215 xlink:href="#linearGradient5151"
1216 id="linearGradient4544"
1217 gradientUnits="userSpaceOnUse"
1218 gradientTransform="translate(345.54877,627.16011)"
1219 x1="-174.27351"
1220 y1="-332.50967"
1221 x2="-117.25081"
1222 y2="-275.30774" />
1223 <linearGradient
1224 inkscape:collect="always"
1225 xlink:href="#linearGradient6425-4-3-4"
1226 id="linearGradient4546"
1227 gradientUnits="userSpaceOnUse"
1228 x1="228.29796"
1229 y1="351.85236"
1230 x2="171.27525"
1231 y2="294.65045" />
1232 <linearGradient
1233 inkscape:collect="always"
1234 xlink:href="#id11-5-1-5"
1235 id="linearGradient4548"
1236 gradientUnits="userSpaceOnUse"
1237 gradientTransform="translate(345.54875,627.16011)"
1238 x1="-169.15022"
1239 y1="-321.3381"
1240 x2="-120.44732"
1241 y2="-285.0881" />
1242 <linearGradient
1243 inkscape:collect="always"
1244 xlink:href="#linearGradient15570-9-9-5-1-8"
1245 id="linearGradient4550"
1246 gradientUnits="userSpaceOnUse"
1247 gradientTransform="translate(345.54875,627.16011)"
1248 x1="-169.15022"
1249 y1="-321.3381"
1250 x2="-120.44732"
1251 y2="-285.0881" />
1252 <linearGradient
1253 inkscape:collect="always"
1254 xlink:href="#linearGradient5151-3"
1255 id="linearGradient4552"
1256 gradientUnits="userSpaceOnUse"
1257 gradientTransform="translate(345.54877,627.16011)"
1258 x1="-174.27351"
1259 y1="-332.50967"
1260 x2="-117.25081"
1261 y2="-275.30774" />
1262 <linearGradient
1263 inkscape:collect="always"
1264 xlink:href="#linearGradient6425-4-3-4-5"
1265 id="linearGradient4554"
1266 gradientUnits="userSpaceOnUse"
1267 x1="228.29796"
1268 y1="351.85236"
1269 x2="171.27525"
1270 y2="294.65045" />
1271 <linearGradient
1272 inkscape:collect="always"
1273 xlink:href="#id11-5-1-5-41"
1274 id="linearGradient4556"
1275 gradientUnits="userSpaceOnUse"
1276 gradientTransform="translate(345.54875,627.16011)"
1277 x1="-169.15022"
1278 y1="-321.3381"
1279 x2="-120.44732"
1280 y2="-285.0881" />
1281 <linearGradient
1282 inkscape:collect="always"
1283 xlink:href="#linearGradient15570-9-9-5-1-8-5"
1284 id="linearGradient4558"
1285 gradientUnits="userSpaceOnUse"
1286 gradientTransform="translate(345.54875,627.16011)"
1287 x1="-169.15022"
1288 y1="-321.3381"
1289 x2="-120.44732"
1290 y2="-285.0881" />
1291 <linearGradient
1292 inkscape:collect="always"
1293 xlink:href="#linearGradient6376"
1294 id="linearGradient4560"
1295 gradientUnits="userSpaceOnUse"
1296 gradientTransform="translate(21.566732,-139.2058)"
1297 x1="48.236862"
1298 y1="215.45312"
1299 x2="279.76315"
1300 y2="304.45312" />
1301 <linearGradient
1302 inkscape:collect="always"
1303 xlink:href="#id2-33-6-4"
1304 id="linearGradient4562"
1305 gradientUnits="userSpaceOnUse"
1306 x1="4877.3301"
1307 y1="3743.74"
1308 x2="4910.75"
1309 y2="3934.3799" />
1310 <linearGradient
1311 inkscape:collect="always"
1312 xlink:href="#linearGradient5151-0"
1313 id="linearGradient4564"
1314 gradientUnits="userSpaceOnUse"
1315 gradientTransform="translate(345.54877,627.16011)"
1316 x1="-174.27351"
1317 y1="-332.50967"
1318 x2="-117.25081"
1319 y2="-275.30774" />
1320 <linearGradient
1321 inkscape:collect="always"
1322 xlink:href="#linearGradient6425-4-3-4-09"
1323 id="linearGradient4566"
1324 gradientUnits="userSpaceOnUse"
1325 x1="228.29796"
1326 y1="351.85236"
1327 x2="171.27525"
1328 y2="294.65045" />
1329 <linearGradient
1330 inkscape:collect="always"
1331 xlink:href="#id11-5-1-5-1"
1332 id="linearGradient4568"
1333 gradientUnits="userSpaceOnUse"
1334 gradientTransform="translate(345.54875,627.16011)"
1335 x1="-169.15022"
1336 y1="-321.3381"
1337 x2="-120.44732"
1338 y2="-285.0881" />
1339 <linearGradient
1340 inkscape:collect="always"
1341 xlink:href="#linearGradient15570-9-9-5-1-8-8"
1342 id="linearGradient4570"
1343 gradientUnits="userSpaceOnUse"
1344 gradientTransform="translate(345.54875,627.16011)"
1345 x1="-169.15022"
1346 y1="-321.3381"
1347 x2="-120.44732"
1348 y2="-285.0881" />
1349 <linearGradient
1350 inkscape:collect="always"
1351 xlink:href="#linearGradient6425-4-3-4"
1352 id="linearGradient4572"
1353 gradientUnits="userSpaceOnUse"
1354 gradientTransform="matrix(0,-0.38527708,0.78727403,0,58.433232,56.29863)"
1355 x1="50.204582"
1356 y1="24.731405"
1357 x2="50.204582"
1358 y2="21.0718" />
1359 <linearGradient
1360 inkscape:collect="always"
1361 xlink:href="#linearGradient6425-4-3-4-9"
1362 id="linearGradient4574"
1363 gradientUnits="userSpaceOnUse"
1364 gradientTransform="matrix(0,-0.36298039,1.1528432,0,49.539772,111.72068)"
1365 x1="50.204582"
1366 y1="24.731405"
1367 x2="50.204582"
1368 y2="21.0718" />
1369 <linearGradient
1370 inkscape:collect="always"
1371 xlink:href="#linearGradient6425-4-3-4-1-0"
1372 id="linearGradient4576"
1373 gradientUnits="userSpaceOnUse"
1374 gradientTransform="matrix(0,-0.59788346,-0.78727403,0,323.3037,117.00472)"
1375 x1="50.204582"
1376 y1="24.731405"
1377 x2="50.204582"
1378 y2="21.0718" />
1379 </defs>
1380 <sodipodi:namedview
1381 id="base"
1382 pagecolor="#ffffff"
1383 bordercolor="#666666"
1384 borderopacity="1.0"
1385 inkscape:pageopacity="0.0"
1386 inkscape:pageshadow="2"
1387 inkscape:zoom="1"
1388 inkscape:cx="277.79436"
1389 inkscape:cy="98.864744"
1390 inkscape:document-units="mm"
1391 inkscape:current-layer="svg2"
1392 showgrid="false"
1393 inkscape:snap-bbox="false"
1394 inkscape:object-nodes="false"
1395 inkscape:snap-smooth-nodes="false"
1396 inkscape:snap-bbox-midpoints="false"
1397 inkscape:snap-bbox-edge-midpoints="true"
1398 inkscape:bbox-nodes="true"
1399 inkscape:bbox-paths="true"
1400 inkscape:snap-object-midpoints="true"
1401 inkscape:snap-center="false"
1402 showguides="true"
1403 inkscape:guide-bbox="true"
1404 inkscape:window-width="1351"
1405 inkscape:window-height="925"
1406 inkscape:window-x="116"
1407 inkscape:window-y="239"
1408 inkscape:window-maximized="0"
1409 inkscape:snap-nodes="true"
1410 inkscape:snap-to-guides="true"
1411 inkscape:snap-global="false"
1412 units="mm"
1413 fit-margin-top="0"
1414 fit-margin-left="0.8"
1415 fit-margin-right="0"
1416 fit-margin-bottom="0" />
1417 <metadata
1418 id="metadata7">
1419 <rdf:RDF>
1420 <cc:Work
1421 rdf:about="">
1422 <dc:format>image/svg+xml</dc:format>
1423 <dc:type
1424 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
1425 <dc:title>iBasso DX50</dc:title>
1426 <cc:license
1427 rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
1428 <dc:date>2014-05-01</dc:date>
1429 <dc:creator>
1430 <cc:Agent>
1431 <dc:title>Simon Rothen</dc:title>
1432 </cc:Agent>
1433 </dc:creator>
1434 </cc:Work>
1435 <cc:License
1436 rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
1437 <cc:permits
1438 rdf:resource="http://creativecommons.org/ns#Reproduction" />
1439 <cc:permits
1440 rdf:resource="http://creativecommons.org/ns#Distribution" />
1441 <cc:requires
1442 rdf:resource="http://creativecommons.org/ns#Notice" />
1443 <cc:requires
1444 rdf:resource="http://creativecommons.org/ns#Attribution" />
1445 <cc:permits
1446 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
1447 <cc:requires
1448 rdf:resource="http://creativecommons.org/ns#ShareAlike" />
1449 </cc:License>
1450 </rdf:RDF>
1451 </metadata>
1452 <g
1453 inkscape:groupmode="layer"
1454 id="layer5"
1455 inkscape:label="Text"
1456 transform="translate(-10.784083,-93.2058)">
1457 <text
1458 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000012px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Palatino Linotype;-inkscape-font-specification:Palatino Linotype"
1459 xml:space="preserve"
1460 id="text2869"
1461 y="187.98181"
1462 x="322.31253"
1463 sodipodi:linespacing="100%"
1464 inkscape:export-filename="/home/marko/Dropbox/Public/clipplus.png"
1465 inkscape:export-xdpi="96.824623"
1466 inkscape:export-ydpi="96.824623"><tspan
1467 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000012px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Palatino Linotype;-inkscape-font-specification:Palatino Linotype"
1468 id="tspan2871"
1469 y="187.98181"
1470 x="322.31253">Volume down</tspan></text>
1471 <text
1472 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000012px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Palatino Linotype;-inkscape-font-specification:Palatino Linotype"
1473 xml:space="preserve"
1474 id="text2875"
1475 y="137.01501"
1476 x="322.31253"
1477 sodipodi:linespacing="100%"
1478 inkscape:export-filename="/home/marko/Dropbox/Public/clipplus.png"
1479 inkscape:export-xdpi="96.824623"
1480 inkscape:export-ydpi="96.824623"><tspan
1481 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000012px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Palatino Linotype;-inkscape-font-specification:Palatino Linotype"
1482 id="tspan2877"
1483 y="137.01501"
1484 x="322.31253">Volume up</tspan></text>
1485 </g>
1486 <text
1487 inkscape:export-ydpi="72"
1488 inkscape:export-xdpi="72"
1489 inkscape:export-filename="C:\cygwin\home\Marianne\rockbox-patched\trunk\manual\rockbox_interface\images\mrobe100-front.png"
1490 sodipodi:linespacing="125%"
1491 id="text2289"
1492 y="44.155655"
1493 x="2.5209403"
1494 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Palatino Linotype"
1495 xml:space="preserve"><tspan
1496 y="44.155655"
1497 x="2.5209403"
1498 id="tspan2291"
1499 sodipodi:role="line"
1500 style="font-size:20px">Power</tspan></text>
1501 <text
1502 inkscape:export-ydpi="72"
1503 inkscape:export-xdpi="72"
1504 inkscape:export-filename="C:\cygwin\home\Marianne\rockbox-patched\trunk\manual\rockbox_interface\images\mrobe100-front.png"
1505 xml:space="preserve"
1506 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Palatino Linotype"
1507 x="14.358284"
1508 y="99.973114"
1509 id="text3263"
1510 sodipodi:linespacing="125%"><tspan
1511 sodipodi:role="line"
1512 id="tspan3265"
1513 x="14.358284"
1514 y="99.973114"
1515 style="font-size:20px">Hold</tspan></text>
1516 <text
1517 inkscape:export-ydpi="72"
1518 inkscape:export-xdpi="72"
1519 inkscape:export-filename="C:\cygwin\home\Marianne\rockbox-patched\trunk\manual\rockbox_interface\images\mrobe100-front.png"
1520 xml:space="preserve"
1521 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Palatino Linotype"
1522 x="0.87175506"
1523 y="226.6767"
1524 id="text3271"
1525 sodipodi:linespacing="125%"><tspan
1526 sodipodi:role="line"
1527 id="tspan3273"
1528 x="0.87175506"
1529 y="226.6767"
1530 style="font-size:20px">Prev</tspan></text>
1531 <text
1532 inkscape:export-ydpi="72"
1533 inkscape:export-xdpi="72"
1534 inkscape:export-filename="C:\cygwin\home\Marianne\rockbox-patched\trunk\manual\rockbox_interface\images\mrobe100-front.png"
1535 sodipodi:linespacing="125%"
1536 id="text3283"
1537 y="315.7233"
1538 x="318.98553"
1539 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Palatino Linotype"
1540 xml:space="preserve"><tspan
1541 y="315.7233"
1542 x="318.98553"
1543 id="tspan3285"
1544 sodipodi:role="line"
1545 style="font-size:20px">Play</tspan></text>
1546 <text
1547 inkscape:export-ydpi="72"
1548 inkscape:export-xdpi="72"
1549 inkscape:export-filename="C:\cygwin\home\Marianne\rockbox-patched\trunk\manual\rockbox_interface\images\mrobe100-front.png"
1550 xml:space="preserve"
1551 style="font-size:30px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Palatino Linotype"
1552 x="321.58533"
1553 y="240.20337"
1554 id="text3287"
1555 sodipodi:linespacing="125%"><tspan
1556 sodipodi:role="line"
1557 id="tspan3289"
1558 x="321.58533"
1559 y="240.20337"
1560 style="font-size:20px">Next</tspan></text>
1561 <text
1562 inkscape:export-ydpi="72"
1563 inkscape:export-xdpi="72"
1564 inkscape:export-filename="C:\cygwin\home\Marianne\rockbox-patched\trunk\manual\rockbox_interface\images\mrobe100-front.png"
1565 sodipodi:linespacing="125%"
1566 id="text3291-4"
1567 y="377.98401"
1568 x="204.79172"
1569 style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Palatino Linotype"
1570 xml:space="preserve"><tspan
1571 id="tspan3489"
1572 y="377.98401"
1573 x="204.79172"
1574 sodipodi:role="line"
1575 style="font-size:20px">Gain</tspan></text>
1576 <g
1577 id="g4475"
1578 transform="translate(-2.3508149,0)">
1579 <path
1580 inkscape:connector-curvature="0"
1581 inkscape:export-ydpi="96"
1582 inkscape:export-xdpi="96"
1583 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1584 sodipodi:nodetypes="ccccc"
1585 id="path6390-4-7-2"
1586 d="m 236.75674,354.31344 c 0,0 0.0286,3.10604 -0.56816,3.05693 l -10.63689,0.0625 c -0.8278,-0.0129 -0.74597,-3.11944 -0.74597,-3.11944 z"
1587 style="fill:url(#linearGradient4530);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
1588 <path
1589 inkscape:connector-curvature="0"
1590 inkscape:export-ydpi="96"
1591 inkscape:export-xdpi="96"
1592 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1593 sodipodi:nodetypes="ccccc"
1594 id="path6390-4-2"
1595 d="m 304.22694,45.87121 c 0,0 2.22674,-0.92481 2.08757,-1.98171 l 0,-15.21964 c -0.0696,-1.4797 -2.08758,-2.48378 -2.08758,-2.48378 l 1e-5,19.68513 z"
1596 style="fill:url(#linearGradient4532);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
1597 <path
1598 inkscape:export-ydpi="96"
1599 inkscape:export-xdpi="96"
1600 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1601 id="rect4585-1"
1602 d="M 87.652992,0 294.09195,0 c 5.63216,0 10.16635,4.53419 10.16635,10.16634 l 0,333.99803 c 0,5.63215 -4.53419,10.16634 -10.16635,10.16634 l -206.438958,0 c -5.63216,0 -10.16635,-4.53419 -10.16635,-10.16634 l 0,-333.99803 C 77.486642,4.53419 82.020832,0 87.652992,0 z"
1603 style="fill:url(#linearGradient4534);fill-opacity:1;stroke:none;display:inline"
1604 inkscape:connector-curvature="0" />
1605 <path
1606 inkscape:export-ydpi="96"
1607 inkscape:export-xdpi="96"
1608 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1609 id="rect4585-6"
1610 d="m 294.0708,0.00911 c 5.63216,0 10.1875,4.5241 10.1875,10.15625 l 0,334 c 0,5.63215 -4.55534,10.15625 -10.1875,10.15625 l -0.625,0 0,-354.3125 0.625,0 z"
1611 style="fill:url(#linearGradient4536);fill-opacity:1;stroke:none;display:inline"
1612 inkscape:connector-curvature="0" />
1613 <g
1614 inkscape:export-ydpi="96"
1615 inkscape:export-xdpi="96"
1616 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1617 transform="translate(21.566732,-139.2058)"
1618 style="fill:url(#linearGradient4540);fill-opacity:1;stroke:none"
1619 id="g7480">
1620 <path
1621 inkscape:connector-curvature="0"
1622 style="fill:url(#linearGradient4538);fill-opacity:1;stroke:none"
1623 d="m 66.09375,139.21875 c -5.632157,0 -10.1875,4.5241 -10.1875,10.15625 l 0,334 c 0,5.63215 4.555343,10.15625 10.1875,10.15625 l 0.625,0 0,-354.3125 -0.625,0 z"
1624 id="rect4585" />
1625 </g>
1626 <path
1627 inkscape:export-ydpi="96"
1628 inkscape:export-xdpi="96"
1629 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1630 inkscape:connector-curvature="0"
1631 id="rect3520"
1632 d="m 92.394952,186.38795 0,59.49423 0.0937,0 0,16.5596 c 0,2.94489 2.34349,5.31933 5.25,5.31933 l 186.656258,0 c 2.90652,0 5.25,-2.37444 5.25,-5.31933 l 0,-16.5596 0.0937,0 0,-59.49423 -197.343748,0 z"
1633 style="fill:url(#linearGradient4542);fill-opacity:1;stroke:#101010;stroke-width:0.70866144;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
1634 <g
1635 transform="translate(-8.4332679,-93.2058)"
1636 id="g6938">
1637 <rect
1638 style="fill:url(#linearGradient4544);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4546);stroke-width:0.99212599;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1639 id="rect4922-1-1-7"
1640 width="56.692913"
1641 height="56.692913"
1642 x="171.15355"
1643 y="294.72559"
1644 ry="13.143503"
1645 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1646 inkscape:export-xdpi="96"
1647 inkscape:export-ydpi="96" />
1648 <path
1649 inkscape:connector-curvature="0"
1650 style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;filter:url(#filter5226)"
1651 d="m 186.09375,300.59375 c -5.02091,0 -9.09375,4.03754 -9.09375,9.0625 l 0,26.8125 c 0,5.02496 4.06879,9.09375 9.09375,9.09375 l 26.8125,0 c 5.02496,0 9.09375,-4.06879 9.09375,-9.09375 l 0,-26.8125 c 0,-5.02496 -4.07284,-9.0625 -9.09375,-9.0625 l -26.8125,0 z"
1652 id="path4397" />
1653 <rect
1654 style="fill:url(#linearGradient4548);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4550);stroke-width:0.99921262;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1655 id="rect4922-5-6-6-7"
1656 width="40.202908"
1657 height="40.202908"
1658 x="179.39854"
1659 y="302.97058"
1660 ry="6.6378174"
1661 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1662 inkscape:export-xdpi="96"
1663 inkscape:export-ydpi="96" />
1664 </g>
1665 <g
1666 id="g6938-4"
1667 style="display:inline"
1668 transform="translate(-71.417325,-93.2058)">
1669 <rect
1670 style="fill:url(#linearGradient4552);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4554);stroke-width:0.99212599;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1671 id="rect4922-1-1-7-3"
1672 width="56.692913"
1673 height="56.692913"
1674 x="171.15355"
1675 y="294.72559"
1676 ry="13.143503"
1677 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1678 inkscape:export-xdpi="96"
1679 inkscape:export-ydpi="96" />
1680 <path
1681 inkscape:connector-curvature="0"
1682 style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;filter:url(#filter5226-8)"
1683 d="m 186.09375,300.59375 c -5.02091,0 -9.09375,4.03754 -9.09375,9.0625 l 0,26.8125 c 0,5.02496 4.06879,9.09375 9.09375,9.09375 l 26.8125,0 c 5.02496,0 9.09375,-4.06879 9.09375,-9.09375 l 0,-26.8125 c 0,-5.02496 -4.07284,-9.0625 -9.09375,-9.0625 l -26.8125,0 z"
1684 id="path4397-3" />
1685 <rect
1686 style="fill:url(#linearGradient4556);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4558);stroke-width:0.99921262;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1687 id="rect4922-5-6-6-7-31"
1688 width="40.202908"
1689 height="40.202908"
1690 x="179.39854"
1691 y="302.97058"
1692 ry="6.6378174"
1693 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1694 inkscape:export-xdpi="96"
1695 inkscape:export-ydpi="96" />
1696 </g>
1697 <path
1698 inkscape:export-ydpi="96"
1699 inkscape:export-xdpi="96"
1700 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1701 inkscape:connector-curvature="0"
1702 id="rect4587"
1703 d="m 96.910482,10.1067 c -2.52849,0 -4.5625,2.06526 -4.5625,4.59375 l 0,33.21875 -0.0625,0 0,138.46875 197.562508,0 0,-138.46875 -0.0312,0 0,-33.21875 c 0,-2.52849 -2.03402,-4.59375 -4.5625,-4.59375 l -188.343758,0 z"
1704 style="fill:url(#linearGradient4560);fill-opacity:1;stroke:#101010;stroke-width:0.70866144;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
1705 <path
1706 inkscape:export-ydpi="96"
1707 inkscape:export-xdpi="96"
1708 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1709 inkscape:connector-curvature="0"
1710 id="rect4587-8"
1711 d="m 96.910482,10.106696 c -2.52849,0 -4.5625,2.065259 -4.5625,4.593749 l 0,33.218751 -0.0625,0 0,138.468754 197.562508,0 0,-138.468754 -0.0312,0 0,-33.218751 c 0,-2.52849 -2.03402,-4.593749 -4.5625,-4.593749 l -188.343758,0 z"
1712 style="fill:#111111;fill-opacity:1;stroke:#101010;stroke-width:0.70866144;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
1713 <rect
1714 inkscape:export-ydpi="96"
1715 inkscape:export-xdpi="96"
1716 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1717 ry="0"
1718 y="25.918993"
1719 x="104.78932"
1720 height="130.0571"
1721 width="172.57677"
1722 id="rect4589"
1723 style="fill:#212121;fill-opacity:1;stroke:none" />
1724 <g
1725 inkscape:export-ydpi="96"
1726 inkscape:export-xdpi="96"
1727 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1728 id="g3054"
1729 style="fill-rule:evenodd;display:inline;enable-background:new"
1730 transform="matrix(0.08694953,0,0,0.08694953,-168.36562,-265.39841)">
1731 <path
1732 style="fill:#131516"
1733 id="path3056"
1734 d="m 3141.69,4007.74 1984.33,0 0,-614.37 -1984.33,0 0,614.37 0,0 z"
1735 class="fil6"
1736 inkscape:connector-curvature="0" />
1737 <path
1738 style="fill:#ffffff"
1739 id="path3058"
1740 d="m 3267.19,3972.16 c 0,-8.6299 -7,-15.626 -15.6299,-15.626 -8.6299,0 -15.626,6.9961 -15.626,15.626 0,8.6339 6.9961,15.6299 15.626,15.6299 8.6299,0 15.6299,-6.9961 15.6299,-15.6299 z m 49.0866,-13.0787 c 6.2795,-4.2756 14.626,-3.063 19.5472,2.8307 4.9252,5.8977 4.9252,14.6811 0,20.5787 -4.9213,5.8977 -13.2677,7.1063 -19.5472,2.8347 l 0,12.9488 -8.2795,0 0,-40.9803 8.2795,0 0,1.7874 0,0 z m 94.5079,13.0787 c 0,-8.6299 -7,-15.6299 -15.6299,-15.6299 -8.6299,0 -15.626,7 -15.626,15.6299 0,8.6339 6.9961,15.6299 15.626,15.6299 4.4449,0 8.4646,-1.8583 11.311,-4.8425 l -5.9803,-5.7047 5.9803,5.7047 -5.9803,-5.7047 c -1.5315,1.6063 -3.7126,2.437 -5.9331,2.2559 -2.2126,-0.1851 -4.2244,-1.3622 -5.4764,-3.2008 l 21.1535,0 c 0.3622,-1.3189 0.5552,-2.7047 0.5552,-4.1378 l 0,0 z m 519.035,0 c 0,-8.6299 -6.9961,-15.6299 -15.626,-15.6299 -8.6299,0 -15.626,7 -15.626,15.6299 0,8.6339 6.9961,15.6299 15.626,15.6299 4.4488,0 8.4646,-1.8583 11.311,-4.8425 l -5.9803,-5.7047 5.9803,5.7047 -5.9803,-5.7047 c -1.5354,1.6063 -3.7126,2.437 -5.9291,2.2559 -2.2166,-0.1851 -4.2284,-1.3622 -5.4803,-3.2008 l 21.1574,0 c 0.3583,-1.3189 0.5473,-2.7047 0.5473,-4.1378 l 0,0 z m 308.854,0 c 0,-8.6299 -6.9961,-15.6299 -15.6299,-15.6299 -8.626,0 -15.626,7 -15.626,15.6299 0,8.6339 7,15.6299 15.626,15.6299 4.4488,0 8.4646,-1.8583 11.311,-4.8425 l -5.9764,-5.7047 5.9764,5.7047 -5.9764,-5.7047 c -1.5354,1.6063 -3.7126,2.437 -5.9331,2.2559 -2.2126,-0.1851 -4.2283,-1.3622 -5.4803,-3.2008 l 21.1575,0 c 0.3622,-1.3189 0.5512,-2.7047 0.5512,-4.1378 l 0,0 z m 789.339,0 c 0,-8.6299 -6.9961,-15.6299 -15.6299,-15.6299 -8.626,0 -15.622,7 -15.622,15.6299 0,8.6339 6.9961,15.6299 15.622,15.6299 4.4528,0 8.4685,-1.8583 11.315,-4.8425 l -5.9803,-5.7047 5.9803,5.7047 -5.9803,-5.7047 c -1.5354,1.6063 -3.7166,2.437 -5.9291,2.2559 -2.2166,-0.1851 -4.2284,-1.3622 -5.4804,-3.2008 l 21.1535,0 c 0.3623,-1.3189 0.5512,-2.7047 0.5512,-4.1378 l 0,0 z m -1549.48,-2.3189 c 0,-5.0079 -2.4331,-9.5906 -6.3071,-11.8583 -3.874,-2.2717 -8.5197,-1.8465 -12.0354,1.0984 l 0,-1.7874 -8.2795,0 0,29.8189 8.2795,0 0,-17.2717 c 0,-2.7834 2.252,-5.0393 5.0315,-5.0393 2.7835,0 5.0354,2.2559 5.0354,5.0393 l 0,17.2717 8.2756,0 0,-17.2717 0,1e-4 z m 119.693,-3.8622 c 0,-3.9606 -2.9882,-7.5 -7.4764,-8.8622 -4.4882,-1.3661 -9.5315,-0.2756 -12.6299,2.7402 -3.1023,3.0196 -3.5984,7.3149 -1.248,10.7598 1.185,1.6614 2.8779,2.8897 4.8228,3.496 2.2008,0.7362 4.4528,1.3386 6.7284,1.7992 1.8661,0.3622 2.8464,1.2914 2.3031,2.1772 -0.5433,0.8819 -2.4527,1.4488 -4.4646,1.3228 -2.0118,-0.122 -3.5157,-0.9015 -3.5157,-1.8189 l 0,-0.8819 -8.2677,0 0,0.8819 c 0,4.3898 3.3464,8.2953 8.3307,9.7205 4.9803,1.4252 10.5039,0.055 13.7362,-3.4095 3.2362,-3.4566 3.4764,-8.2559 0.5905,-11.9331 -1.6653,-1.9448 -3.9606,-3.248 -6.4842,-3.6732 -2,-0.374 -3.9764,-0.8582 -5.9252,-1.4409 -1.0787,-0.3583 -1.3701,-0.9449 -0.6969,-1.4252 0.6772,-0.4764 2.1339,-0.7205 3.5355,-0.5945 1.4015,0.1299 2.3897,0.6024 2.3897,1.1417 l 0,0.4095 8.2717,0 0,-0.4095 0,1e-4 z m 71.9921,6.1811 c 0,-8.6299 -6.9961,-15.626 -15.626,-15.626 -8.6339,0 -15.626,6.9961 -15.626,15.626 0,8.6339 6.9921,15.6299 15.626,15.6299 8.6299,0 15.626,-6.9961 15.626,-15.6299 z m 40.9843,2.4055 0,-17.2717 8.2795,0 0,17.2717 c 0,2.7835 2.2559,5.0354 5.0315,5.0354 2.7835,0 5.0355,-2.2519 5.0355,-5.0354 l 0,-17.2717 8.2755,0 0,29.8189 -8.2755,0 0,-1.7874 c -3.5119,2.9449 -8.1615,3.3701 -12.0354,1.0984 -3.8701,-2.2716 -6.3111,-6.8504 -6.3111,-11.8583 l 0,1e-4 z m 76.5787,-15.4843 0,-1.7874 -8.2756,0 0,29.8189 8.2756,0 0,-14.9528 c 0,-1.9488 0.7756,-3.8228 2.1535,-5.2008 1.378,-1.3819 3.252,-2.1575 5.2048,-2.1575 l 0,-8.2441 c -2.6221,0.1575 -5.1575,1.0237 -7.3583,2.5237 l 0,0 z m 72.8228,2.2913 c -2.8465,-2.9803 -6.8622,-4.8425 -11.311,-4.8425 -8.626,0 -15.622,6.9961 -15.626,15.626 0,0 0,0 0,0 0,8.6299 7,15.626 15.626,15.626 4.4488,0 8.4646,-1.8583 11.311,-4.8426 l -5.9803,-5.7047 c -1.3386,1.4016 -3.2284,2.2756 -5.3189,2.2756 -4.063,0 -7.3583,-3.2913 -7.3583,-7.3543 0,0 0,0 0,0 0,-4.059 3.2953,-7.3543 7.3583,-7.3543 2.0905,0 3.9803,0.878 5.3189,2.2795 l 5.9803,-5.7086 0,-1e-4 z m 958.004,10.7677 -4.2677,-14.8465 -7.3859,0 -4.2677,14.8465 -4.2638,-14.8465 -8.6063,0 8.567,29.8189 8.6063,0 3.6575,-12.7323 3.6574,12.7323 8.6063,0 8.5709,-29.8189 -8.6063,0 -4.2677,14.8465 m -210.098,-24.5551 -8.2756,0 0,8.2717 8.2756,0 0,-8.2717 m 0,9.7087 -8.2756,0 0,29.8189 8.2756,0 0,-29.8189 m -171.508,14.9213 9.2126,14.8976 -9.748,0 -4.3386,-7.0197 -4.3425,7.0197 -9.7441,0 9.2126,-14.8976 -9.2284,-14.9213 9.7441,0 4.3583,7.0472 4.3582,-7.0472 9.7441,0 -9.2283,14.9213 m -277.26,-14.9213 -7.5866,12.2717 0,-21.9803 -8.2756,0 0,39.5276 8.2756,0 0,-12.437 9.3228,12.437 10.3386,0 -11.3819,-15.1811 9.0551,-14.6378 -9.748,0 m -126.098,-9.7087 -8.2795,0 0,8.2717 8.2795,0 0,-8.2717 m 0,40.9803 0,-31.2717 -8.2795,0 0,31.2795 c 0,0.7875 -0.6418,1.4292 -1.4292,1.4292 l -2.3425,0 0,8.2716 2.3425,0 c 5.3662,0 9.7087,-4.3464 9.7087,-9.7086 m 348.524,-16.4055 c 0,-8.6299 -6.9961,-15.626 -15.626,-15.626 -8.6299,0 -15.626,6.996 -15.626,15.626 0,8.6338 6.9961,15.6299 15.626,15.6299 8.6299,0 15.626,-6.9961 15.626,-15.6299 z m -288.228,13.1654 0,1.7874 8.2756,0 0,-29.8189 -8.2756,0 0,17.2717 c 0,2.7834 -2.2559,5.0354 -5.0354,5.0354 -2.7796,0 -5.0355,-2.252 -5.0355,-5.0354 l 0,-17.2717 -8.2756,0 0,17.2717 c 0,5.0078 2.4371,9.5866 6.3071,11.8583 3.8741,2.2716 8.5237,1.8464 12.0394,-1.0985 l 0,0 z m 193.657,-26.2441 0,-11.4961 -8.2795,0 0,39.5276 8.2795,0 0,-1.7874 c 6.2795,4.2716 14.626,3.063 19.5472,-2.8347 4.9252,-5.8976 4.9252,-14.6811 0,-20.5787 -4.9213,-5.8937 -13.2677,-7.1063 -19.5472,-2.8307 l 0,0 z m 271.61,-3.2244 -6.874,0 c -0.1851,-0.02 -0.3662,0.047 -0.4961,0.1811 -0.1299,0.1299 -0.1968,0.311 -0.1771,0.496 l 0,0.7599 0,0 3.7716,0 0,8.2716 -3.7716,0 0,21.5472 -8.2796,0 0,-21.5472 -3.7756,0 0,-8.2716 3.7756,0 c 0,-5.3622 4.3425,-9.7087 9.7047,-9.7087 l 6.1221,0 0,8.2717 0,0 z m 106.752,0.7007 0,8.2441 c -1.9488,0 -3.8189,0.7756 -5.2008,2.1575 -1.3819,1.378 -2.1535,3.252 -2.1535,5.2008 l 0,14.9528 -8.2796,0 0,-29.8189 8.2796,0 0,1.7874 c 2.2008,-1.5 4.7362,-2.3661 7.3543,-2.5236 l 0,-10e-5 z m 48.5236,2.5237 0,-1.7874 -8.2756,0 0,29.8189 8.2756,0 0,-17.2717 c 0,-2.7835 2.252,-5.0394 5.0354,-5.0394 2.7796,0 5.0315,2.2559 5.0315,5.0394 l 0,17.2717 8.2796,0 0,-17.2717 c 0,-2.7835 2.2559,-5.0394 5.0354,-5.0394 2.7795,0 5.0315,2.2559 5.0315,5.0394 l 0,17.2717 8.2756,0 0,-17.2717 c 0,-5.252 -3.0866,-10.0118 -7.8819,-12.1575 -4.7953,-2.1378 -10.3976,-1.2599 -14.3071,2.2401 -4.0591,-4.1811 -10.0984,-4.5315 -14.5,-0.8425 l 0,10e-5 z m 177.079,0 0,-1.7874 8.2795,0 0,29.8189 -8.2795,0 0,-1.7874 c -6.2795,4.2716 -14.626,3.063 -19.5472,-2.8347 -4.9252,-5.8976 -4.9252,-14.6811 0,-20.5787 4.9213,-5.8937 13.2677,-7.1063 19.5472,-2.8307 l 0,0 z m 66.7402,-2.5237 0,8.2441 c -1.9528,0 -3.8268,0.7756 -5.2047,2.1575 -1.3819,1.378 -2.1575,3.252 -2.1575,5.2008 l 0,14.9528 -8.2756,0 0,-29.8189 8.2756,0 0,1.7874 c 2.2008,-1.5 4.7362,-2.3661 7.3622,-2.5236 l 0,-10e-5 z"
1741 class="fil8"
1742 inkscape:connector-curvature="0" />
1743 <path
1744 style="fill:#131516"
1745 id="path3060"
1746 d="m 3258.91,3972.16 c 0,-4.0591 -3.2953,-7.3583 -7.3583,-7.3583 -4.063,0 -7.3543,3.2992 -7.3543,7.3583 0,4.063 3.2913,7.3622 7.3543,7.3622 4.063,0 7.3583,-3.2992 7.3583,-7.3622 z m 958.043,-4.1339 12.1732,0 c -1.3701,-2.0157 -3.6457,-3.2244 -6.0866,-3.2244 -2.437,0 -4.7166,1.2087 -6.0866,3.2244 m -308.846,0 12.1693,0 c -1.3662,-2.0157 -3.6457,-3.2244 -6.0827,-3.2244 -2.437,0 -4.7165,1.2087 -6.0866,3.2244 m -246.161,4.1339 c 0,-4.0591 -3.2953,-7.3583 -7.3583,-7.3583 -4.063,0 -7.3543,3.2992 -7.3543,7.3583 0,4.063 3.2913,7.3622 7.3543,7.3622 4.063,0 7.3583,-3.2992 7.3583,-7.3622 z m 711.949,0 c 0,-4.0591 -3.2953,-7.3583 -7.3583,-7.3583 -4.063,0 -7.3583,3.2992 -7.3583,7.3583 0,4.063 3.2953,7.3622 7.3583,7.3622 4.063,0 7.3583,-3.2992 7.3583,-7.3622 z m -71.5866,0 c 0,-4.0591 -3.2953,-7.3583 -7.3622,-7.3583 -4.0591,0 -7.3543,3.2992 -7.3543,7.3583 0,4.063 3.2952,7.3622 7.3543,7.3622 4.0669,0 7.3622,-3.2992 7.3622,-7.3622 z m -971.327,0.083 c 0,-4.063 -3.2914,-7.3583 -7.3583,-7.3583 -4.059,0 -7.3543,3.2953 -7.3543,7.3583 0,4.063 3.2953,7.3582 7.3543,7.3582 4.0669,0 7.3583,-3.2952 7.3583,-7.3582 z m 58.0866,-4.2166 12.1732,0 c -1.3701,-2.0157 -3.6496,-3.2244 -6.0866,-3.2244 -2.437,0 -4.7166,1.2087 -6.0866,3.2244 m 1617.23,0 12.1732,0 c -1.3741,-2.0157 -3.6496,-3.2244 -6.0906,-3.2244 -2.437,0 -4.7126,1.2087 -6.0827,3.2244 m -114.74,4.1339 c 0,-4.0591 -3.2913,-7.3583 -7.3543,-7.3583 -4.0669,0 -7.3622,3.2992 -7.3622,7.3583 0,4.063 3.2953,7.3622 7.3622,7.3622 4.063,0 7.3543,-3.2992 7.3543,-7.3622 z"
1747 class="fil6"
1748 inkscape:connector-curvature="0" />
1749 <path
1750 style="fill:#efaf04"
1751 id="path3062"
1752 d="m 3153.44,3407.72 1958.88,0 0,521.831 -1958.88,0 0,-521.831 0,0 z"
1753 class="fil9"
1754 inkscape:connector-curvature="0" />
1755 <path
1756 style="fill:url(#linearGradient4562)"
1757 id="path3064"
1758 d="m 4692.99,3898.2 0,0 m 414.071,-85.7402 5.2598,0 0,2.9921 -2.2716,0 0,11.9488 -2.9882,0 0,-14.9409 m -14.937,0 8.9646,0 0,2.9922 -8.9646,0 0,-2.9922 m 0,11.9528 8.9646,0 0,2.9882 -8.9646,0 0,-2.9882 m -20.9094,-11.9528 0,0 0,0 0,0 0,0 m 5.9724,2.9922 2.9882,0 0,11.9488 -2.9882,0 0,-11.9488 m 2.9882,-2.9922 2.9882,0 0,2.9922 -2.9882,0 0,-2.9922 m 2.9882,2.9922 2.9882,0 0,11.9488 -2.9882,0 0,-11.9488 m -11.9488,-2.9922 5.9725,0 0,2.9922 -2.9882,0 0,11.9488 -2.9843,0 0,-14.9409 m -5.9764,-2.9882 2.9882,0 0,5.9803 -2.9882,0 0,-5.9803 m 0,8.9645 2.9882,0 0,5.9764 -2.9882,0 0,-5.9764 m -23.8976,-5.9763 2.9882,0 0,5.9763 -2.9882,0 0,-5.9763 m -21.3898,0 2.9882,0 0,2.9921 -2.9882,0 0,-2.9921 m -8.9606,5.9763 2.9843,0 0,5.9764 -2.9843,0 0,-5.9764 m -11.4961,5.9764 11.4961,0 0,2.9882 -11.4961,0 0,-2.9882 m -11.9488,-8.9606 2.9843,0 0,2.9842 -2.9843,0 0,-2.9842 m -2.9921,-8.9646 8.9645,0 0,2.9843 -8.9645,0 0,-2.9843 m 0,17.9252 8.9645,0 0,2.9882 -8.9645,0 0,-2.9882 m -14.9331,-17.9252 5.9724,0 0,2.9843 -5.9724,0 0,-2.9843 m -2.9882,2.9843 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m 8.9606,8.9645 2.9921,0 0,5.9764 -2.9921,0 0,-5.9764 m 80.685,-38.5118 11.9488,0 0,2.9843 -11.9488,0 0,-2.9843 m -2.9882,2.9843 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m 2.9882,2.9882 8.9606,0 0,2.9882 -8.9606,0 0,-2.9882 m 8.9606,2.9882 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m -11.9488,2.9882 11.9488,0 0,2.9881 -11.9488,0 0,-2.9881 m 17.9252,-11.9488 2.9843,0 0,11.9488 -2.9843,0 0,-11.9488 m 2.9843,17.9252 8.9646,0 0,2.9842 -8.9646,0 0,-2.9842 m 14.9409,-5.9764 11.9488,0 0,2.9882 -11.9488,0 0,-2.9882 m 11.9488,-2.9882 2.9842,0 0,2.9882 -2.9842,0 0,-2.9882 m -8.9646,-2.9882 8.9646,0 0,2.9882 -8.9646,0 0,-2.9882 m -2.9842,-2.9882 2.9842,0 0,2.9882 -2.9842,0 0,-2.9882 m 2.9842,-2.9842 11.9488,0 0,2.9842 -11.9488,0 0,-2.9842 m -35.8465,65.0748 11.9488,0 0,2.9881 -11.9488,0 0,-2.9881 m -2.9882,2.9881 2.9882,0 0,2.9843 -2.9882,0 0,-2.9843 m 2.9882,2.9843 8.9607,0 0,2.9921 -8.9607,0 0,-2.9921 m 8.9607,2.9921 2.9881,0 0,2.9882 -2.9881,0 0,-2.9882 m -11.9488,2.9882 11.9488,0 0,2.9843 -11.9488,0 0,-2.9843 m -71.8071,0 11.9528,0 0,2.9843 -11.9528,0 0,-2.9843 m 11.9528,-2.9882 2.9842,0 0,2.9882 -2.9842,0 0,-2.9882 m -8.9646,-2.9921 8.9646,0 0,2.9921 -8.9646,0 0,-2.9921 m -2.9882,-2.9843 2.9882,0 0,2.9843 -2.9882,0 0,-2.9843 m 2.9882,-2.9881 11.9488,0 0,2.9881 -11.9488,0 0,-2.9881 m -89.7913,32.5394 11.9488,0 0,2.9842 -11.9488,0 0,-2.9842 m -2.9882,2.9842 2.9882,0 0,2.9921 -2.9882,0 0,-2.9921 m 2.9882,2.9921 8.9606,0 0,2.9843 -8.9606,0 0,-2.9843 m 8.9606,2.9843 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m -11.9488,2.9882 11.9488,0 0,2.9882 -11.9488,0 0,-2.9882 m -198.457,0 11.9488,0 0,2.9882 -11.9488,0 0,-2.9882 m 11.9488,-2.9882 2.9921,0 0,2.9882 -2.9921,0 0,-2.9882 m -8.9606,-2.9843 8.9606,0 0,2.9843 -8.9606,0 0,-2.9843 m -2.9882,-2.9921 2.9882,0 0,2.9921 -2.9882,0 0,-2.9921 m 2.9882,-2.9842 11.9528,0 0,2.9842 -11.9528,0 0,-2.9842 m 321.22,0 5.9724,0 0,2.9842 -2.9882,0 0,11.9528 -2.9842,0 0,-14.937 m 11.9488,2.9843 2.9842,0 0,11.9528 -2.9842,0 0,-11.9528 m -2.9882,-2.9843 2.9882,0 0,2.9843 -2.9882,0 0,-2.9843 m -2.9882,2.9843 2.9882,0 0,11.9528 -2.9882,0 0,-11.9528 m -5.9724,-2.9843 0,0 0,0 0,0 0,0 m -287.87,0 0,0 0,0 0,0 0,0 m 5.9763,2.9843 2.9882,0 0,11.9528 -2.9882,0 0,-11.9528 m 2.9882,-2.9843 2.9843,0 0,2.9843 -2.9843,0 0,-2.9843 m 2.9843,2.9843 2.9882,0 0,11.9528 -2.9882,0 0,-11.9528 m -11.9488,-2.9843 5.9764,0 0,2.9843 -2.9882,0 0,11.9528 -2.9882,0 0,-14.937 m 353.591,-85.6654 0,-11.9488 2.9882,0 0,17.9252 -2.9882,0 0,-2.9882 -8.9646,0 0,-2.9882 8.9646,0 m -233.701,97.1654 0,-11.9528 2.9882,0 0,17.9252 -2.9882,0 0,-2.9882 -8.9646,0 0,-2.9843 8.9646,0 m -8.9646,5.9725 8.9646,0 0,2.9882 -8.9646,0 0,-2.9882 m -2.9842,-17.9252 2.9842,0 0,11.9528 -2.9842,0 0,-11.9528 m 251.626,-61.6339 2.9842,0 0,2.9842 8.9646,0 0,-2.9842 2.9842,0 0,5.9724 -11.9488,0 0,2.9882 -2.9842,0 0,-8.9606 m -53.7756,32.5354 2.9882,0 0,2.9842 8.9645,0 0,-2.9842 2.9843,0 0,5.9764 -11.9488,0 0,2.9882 -2.9882,0 0,-8.9646 m 2.9882,8.9646 8.9646,0 0,2.9842 -8.9646,0 0,-2.9842 m 0,-11.9528 8.9646,0 0,2.9881 -8.9646,0 0,-2.9881 m -71.8071,0 8.9646,0 0,2.9881 -8.9646,0 0,-2.9881 m 0,11.9528 8.9646,0 0,2.9842 -8.9646,0 0,-2.9842 m -2.9882,-8.9646 2.9882,0 0,2.9842 8.9646,0 0,-2.9842 2.9842,0 0,5.9764 -11.9488,0 0,2.9882 -2.9882,0 0,-8.9646 m 107.657,32.5354 2.9843,0 0,2.9921 8.9645,0 0,-2.9921 2.9882,0 0,5.9764 -11.9528,0 0,2.9882 -2.9842,0 0,-8.9646 m 2.9842,8.9646 8.9646,0 0,2.9881 -8.9646,0 0,-2.9881 m 0,-11.9488 8.9646,0 0,2.9842 -8.9646,0 0,-2.9842 m 35.8504,0 2.2717,0 0,2.9842 -2.2717,0 0,-2.9842 m 0,11.9488 2.2717,0 0,2.9881 -2.2717,0 0,-2.9881 m -2.9881,-8.9646 2.9881,0 0,2.9921 2.2717,0 0,0 0,0 0,2.9843 -2.2717,0 0,2.9882 -2.9881,0 0,-8.9646 m -428.307,-2.9843 8.9606,0 0,2.9843 -8.9606,0 0,-2.9843 m 0,11.9488 8.9606,0 0,2.9882 -8.9606,0 0,-2.9882 m -2.9922,-8.9645 2.9922,0 0,2.9921 8.9606,0 0,-2.9921 2.9842,0 0,5.9763 -11.9449,0 0,2.9882 -2.9921,0 0,-8.9645 m 38.3819,5.9763 5.9764,0 0,5.5237 -5.9764,0 0,-5.5237 m 360.055,-41.5 8.9646,0 0,2.9882 -8.9646,0 0,-2.9882 m -2.9842,2.9882 2.9842,0 0,8.9646 -2.9842,0 0,-8.9646 m 2.9842,8.9646 8.9646,0 0,2.9843 -8.9646,0 0,-2.9843 m 8.9646,-2.9882 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m 8.9606,-8.9646 8.9646,0 0,2.9882 -8.9646,0 0,-2.9882 m -2.9842,8.9646 2.9842,0 0,2.9882 -2.9842,0 0,-2.9882 m -239.933,0 2.9881,0 0,2.9882 -2.9881,0 0,-2.9882 m -8.9607,2.9882 8.9607,0 0,2.9843 -8.9607,0 0,-2.9843 m -2.9882,-8.9646 2.9882,0 0,8.9646 -2.9882,0 0,-8.9646 m 2.9882,-2.9882 8.9607,0 0,2.9882 -8.9607,0 0,-2.9882 m 165.248,-5.9724 2.9882,0 0,2.9843 -2.9882,0 0,-2.9843 m 17.9213,11.9449 2.9882,0 0,2.9921 -2.9882,0 0,-2.9921 m -89.7323,-5.9724 5.9803,0 0,2.9882 -5.9803,0 0,-2.9882 m 5.9803,2.9882 2.9843,0 0,11.9488 -2.9843,0 0,-11.9488 m -81.4961,-2.9882 8.5118,0 0,2.9882 -8.5118,0 0,-2.9882 m -2.9842,2.9882 2.9842,0 0,8.9645 -2.9842,0 0,-8.9645 m 2.9842,8.9645 8.5118,0 0,2.9843 -8.5118,0 0,-2.9843 m 8.5118,-8.9645 2.9882,0 0,8.9645 -2.9882,0 0,-8.9645 m 144.055,32.5354 2.9843,0 0,8.9645 -2.9843,0 0,-8.9645 m -8.5118,8.9645 8.5118,0 0,2.9882 -8.5118,0 0,-2.9882 m -2.9842,-8.9645 2.9842,0 0,8.9645 -2.9842,0 0,-8.9645 m 2.9842,-2.9843 8.5118,0 0,2.9843 -8.5118,0 0,-2.9843 m -74.5157,-32.5394 2.9922,0 0,2.9882 2.9842,0 0,2.9842 -2.9842,0 0,8.9646 -2.9922,0 0,-14.937 m 179.354,0 2.9882,0 0,2.9882 2.2717,0 0,2.9843 -2.2717,0 0,8.9645 -2.9882,0 0,-14.937 m -146.492,14.937 -2.9842,0 0,-2.9842 -2.9882,0 0,-2.9882 2.9882,0 0,-8.9646 2.9842,0 0,14.937 m -11.9449,-2.9842 -2.9921,0 0,-11.9528 2.9921,0 0,11.9528 m 5.9725,2.9842 -5.9725,0 0,-2.9842 5.9725,0 0,2.9842 m -80.6575,-14.937 2.9882,0 0,2.9882 2.9842,0 0,2.9843 -2.9842,0 0,8.9645 -2.9882,0 0,-14.937 m 11.9488,2.9882 2.9842,0 0,11.9488 -2.9842,0 0,-11.9488 m -5.9764,-2.9882 5.9764,0 0,2.9882 -5.9764,0 0,-2.9882 m 89.4528,32.5394 5.9724,0 0,2.9843 -5.9724,0 0,-2.9843 m 5.9724,2.9843 2.9882,0 0,11.9528 -2.9882,0 0,-11.9528 m -11.9488,-2.9843 2.9843,0 0,2.9843 2.9921,0 0,2.9921 -2.9921,0 0,8.9606 -2.9843,0 0,-14.937 m 98.8661,14.937 -5.9764,0 0,-2.9882 5.9764,0 0,2.9882 m -5.9764,-2.9882 -2.9881,0 0,-11.9488 2.9881,0 0,11.9488 m 11.9488,2.9882 -2.9881,0 0,-2.9882 -2.9843,0 0,-2.9881 2.9843,0 0,-8.9607 2.9881,0 0,14.937 m 35.8465,0 -2.9842,0 0,-2.9882 -2.9882,0 0,-2.9882 2.9882,0 0,-8.9606 2.9842,0 0,14.937 m -11.9488,-2.9882 -2.9842,0 0,-11.9488 2.9842,0 0,11.9488 m 5.9764,2.9882 -5.9764,0 0,-2.9882 5.9764,0 0,2.9882 m 2.9882,-44.4882 2.9843,0 0,11.9488 -11.9488,0 0,-2.9842 8.9645,0 0,-2.9882 -8.9645,0 0,-2.9922 8.9645,0 0,-2.9842 m -143.677,32.5354 2.9922,0 0,11.9528 -11.9567,0 0,-2.9882 8.9645,0 0,-2.9882 -8.9645,0 0,-2.9842 8.9645,0 0,-2.9922 m -11.9488,5.9764 2.9843,0 0,2.9882 -2.9843,0 0,-2.9882 m 2.9843,-8.9606 8.9646,0 0,2.9842 -8.9646,0 0,-2.9842 m -125.87,0 8.9606,0 0,2.9842 -8.9606,0 0,-2.9842 m -2.9882,8.9606 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m 11.9488,-5.9764 2.9882,0 0,11.9528 -11.9488,0 0,-2.9882 8.9606,0 0,-2.9881 -8.9606,0 0,-2.9843 8.9606,0 0,-2.9921 m 233.701,-74.0354 -11.9488,0 0,20.9134 11.9488,0 0,-2.9882 -8.9606,0 0,-5.9764 8.9606,0 0,-2.9842 -8.9606,0 0,-5.9804 8.9606,0 0,-2.9842 m -29.874,0 0,20.9134 2.9882,0 0,-14.9409 2.9882,0 0,-2.9882 -2.9882,0 0,-2.9842 -2.9882,0 m 14.937,0 0,20.9134 -2.9842,0 0,-14.9409 -2.9882,0 0,-2.9882 2.9882,0 0,-2.9843 2.9842,0 m -24.374,0 2.9882,0 0,11.9488 2.9843,0 0,2.9882 -2.9843,0 0,5.9764 -2.9882,0 0,-5.9764 -8.9646,0 0,-5.9724 2.9882,0 0,2.9842 5.9764,0 0,-5.9764 -2.9882,0 0,-2.9882 2.9882,0 0,-2.9842 m -26.4331,0 0,2.9842 8.5079,0 0,2.9882 2.9882,0 0,-2.9882 2.9842,0 0,-2.9842 -14.4803,0 m 8.5079,5.9724 -2.9882,0 0,2.9922 -2.9842,0 0,2.9842 8.9606,0 0,-2.9842 -2.9882,0 0,-2.9922 m -26.4331,-2.9882 0,14.9409 2.9842,0 0,-2.9881 2.9922,0 0,-2.9882 -2.9922,0 0,-8.9646 -2.9842,0 m 11.9488,0 0,2.9882 -2.9882,0 0,2.9921 2.9882,0 0,8.9606 2.9882,0 0,-14.9409 -2.9882,0 m -29.874,2.9882 0,11.9528 2.9882,0 0,-5.9763 8.9606,0 0,-2.9843 -8.9606,0 0,-2.9921 -2.9882,0 m 2.9882,11.9528 8.9606,0 0,2.9882 -8.9606,0 0,-2.9882 m -192.248,53.126 -2.9882,0 0,2.9842 -2.9882,0 0,2.9922 8.9646,0 0,-2.9922 -2.9882,0 0,-2.9842 m -8.5118,-5.9764 0,2.9882 8.5118,0 0,2.9882 2.9882,0 0,-2.9882 2.9842,0 0,-2.9882 -14.4843,0 m 0,17.9252 11.5,0 0,2.9882 -11.5,0 0,-2.9882 m 11.5,-5.9724 2.9843,0 0,5.9724 -2.9843,0 0,-5.9724 m 240.071,-38.5157 0,2.9881 8.9607,0 0,2.9843 2.9882,0 0,-2.9843 2.9842,0 0,-2.9881 -14.9331,0 m 2.9843,8.9645 2.9881,0 0,2.9882 8.9607,0 0,2.9843 -14.9331,0 0,-2.9843 2.9842,0 0,-2.9882 m -17.9213,-8.9645 5.9764,0 0,11.9528 2.9843,0 0,2.9842 -8.9607,0 0,-2.9842 2.9882,0 0,-8.9646 -2.9882,0 0,-2.9882 m -89.7323,0 5.9725,0 0,11.9528 2.9921,0 0,2.9842 -8.9646,0 0,-2.9842 2.9882,0 0,-8.9646 -2.9882,0 0,-2.9882 m 2.9882,-5.9724 2.9843,0 0,2.9842 -2.9843,0 0,-2.9842 m -36.0197,32.5354 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m -2.9882,5.9764 5.9764,0 0,11.9488 2.9882,0 0,2.9882 -8.9646,0 0,-2.9882 2.9882,0 0,-8.9646 -2.9882,0 0,-2.9842 m 27.0591,-23.5748 2.9843,0 0,2.9881 -2.9843,0 0,-2.9881 m -2.9882,2.9881 2.9882,0 0,2.9843 -2.9882,0 0,-2.9843 m -2.9882,-17.9252 2.9882,0 0,5.9725 2.9882,0 0,2.9882 -2.9882,0 0,8.9645 -2.9882,0 0,-8.9645 -2.9881,0 0,-2.9882 2.9881,0 0,-5.9725 m 17.7559,32.5354 2.9843,0 0,5.9764 2.9882,0 0,2.9843 -2.9882,0 0,8.9645 -2.9843,0 0,-8.9645 -2.9921,0 0,-2.9843 2.9921,0 0,-5.9764 m 2.9843,17.9252 2.9882,0 0,2.9882 -2.9882,0 0,-2.9882 m 2.9882,-2.9881 2.9882,0 0,2.9881 -2.9882,0 0,-2.9881 m 5.9764,-8.9607 2.9842,0 0,2.9843 2.9882,0 0,2.9921 -2.9882,0 0,8.9606 -2.9842,0 0,-14.937 m 11.9449,2.9843 2.9921,0 0,3.4449 -2.9921,0 0,-3.4449 m -5.9725,-2.9843 5.9725,0 0,2.9843 -5.9725,0 0,-2.9843 m -75.0906,-5.9763 5.5236,0 0,17.9252 2.9882,0 0,2.5354 -8.5118,0 0,-2.5354 2.9882,0 0,-14.937 -2.9882,0 0,-2.9882 m -53.3189,0 5.5236,0 0,17.9252 2.9882,0 0,2.5354 -8.5118,0 0,-2.5354 2.9843,0 0,-14.937 -2.9843,0 0,-2.9882 m 179.193,5.9764 5.9764,0 0,2.9842 -5.9764,0 0,-2.9842 m -2.9842,2.9842 2.9842,0 0,8.9646 -2.9842,0 0,-8.9646 m 8.9606,0 2.9843,0 0,-8.9606 2.9921,0 0,20.4606 -11.9528,0 0,-2.5355 8.9606,0 0,-5.9724 -2.9842,0 0,-2.9921 m 45.0906,0 2.9882,0 0,8.9645 -2.9882,0 0,-8.9645 m 2.9882,-2.9843 5.9763,0 0,2.9843 -5.9763,0 0,-2.9843 m 5.9763,2.9843 2.9882,0 0,-2.9843 2.9843,0 0,20.4606 -2.9843,0 0,-5.9764 -8.9645,0 0,-2.5354 8.9645,0 0,-5.9724 -2.9882,0 0,-2.9922 m -248.638,-2.9842 -5.9724,0 0,2.9842 5.9724,0 0,-2.9842 m -5.9724,2.9842 -2.9882,0 0,-2.9842 -2.9921,0 0,20.4606 2.9921,0 0,-5.9764 8.9606,0 0,-2.5354 -8.9606,0 0,-5.9725 2.9882,0 0,-2.9921 m 8.9606,0 -2.9882,0 0,8.9646 2.9882,0 0,-8.9646 m -36.248,0 -2.9842,0 0,8.9646 2.9842,0 0,-8.9646 m -8.9606,0 -2.9882,0 0,-2.9842 -2.9842,0 0,20.4606 2.9842,0 0,-5.9764 8.9646,0 0,-2.5354 -8.9646,0 0,-5.9725 2.9882,0 0,-2.9921 m 5.9764,-2.9843 -5.9764,0 0,2.9843 5.9764,0 0,-2.9843 m -66.4567,20.6614 0,0 z"
1759 class="fil10"
1760 inkscape:connector-curvature="0" />
1761 <path
1762 style="fill:#131516"
1763 id="path3066"
1764 d="m 3661.04,3557.69 c -26.9764,-117.386 -96.8268,-122.492 -113.248,-122.492 l 0,-6.8622 c 36.4213,0 95.2874,25.9921 116.681,115.201 27.4016,-89.0236 74.2008,-112.917 107.047,-113.37 31.2992,-0.4331 50.6063,6.8661 80.2717,22.3228 l 0,-13.9291 85.6496,0 0,-11.748 6.8622,0 0,11.748 14.5236,0 0,6.8622 -14.5236,0 0,167.843 61.5945,-155.705 59.0157,0 5.1378,-12.1378 -73.5315,0 0,-6.8622 76.4409,0 8.0827,-19.0787 6.3189,2.6811 -6.9488,16.3976 16.2677,0 0,6.8622 -19.1732,0 -48,113.291 63.5709,0 0,84.9094 c 59.4961,-29.2835 130.681,-7.7953 166.559,49.5315 35.5866,-54.8622 105.11,-76.7205 165.685,-52.1024 l -2.4095,-3.8937 102.382,0 20.4528,33.063 19.9764,-32.2953 c 0.2992,-0.4803 0.8189,-0.7677 1.378,-0.7677 l 0,0 c 0.5905,0 1.1299,0.3149 1.4173,0.8307 0.2874,0.5118 0.2716,1.1417 -0.039,1.6417 l -20.8228,33.6772 2.6693,4.315 24.5512,-39.6969 c 0.2913,-0.4803 0.815,-0.7677 1.3779,-0.7677 l 0,0 c 0.5867,0 1.13,0.3149 1.4174,0.8307 0.2834,0.5118 0.2677,1.1417 -0.039,1.6417 l -25.4055,41.0709 2.6732,4.3189 29.6024,-47.8622 102.378,0 -80.7913,130.63 2.6654,4.311 85.2559,-137.835 -106.358,0 c -0.5906,0 -1.1299,-0.3189 -1.4173,-0.8307 -0.2874,-0.5157 -0.2717,-1.1417 0.039,-1.6457 l 0,0 c 0.2914,-0.4724 0.815,-0.7677 1.378,-0.7677 l 112.173,0 -84.5866,136.768 79.1299,127.941 c 0.311,0.4961 0.3228,1.1299 0.035,1.6418 -0.2835,0.5118 -0.8228,0.8307 -1.4134,0.8307 -0.563,0 -1.0827,-0.2874 -1.3779,-0.7678 l -78.2795,-126.567 -2.6693,4.3189 76.0827,123.016 -102.378,0 -19.5591,-31.6181 -19.0827,30.8504 c -0.2914,0.4804 -0.815,0.7678 -1.378,0.7678 l 0,0 c -0.2677,0 -0.5236,-0.063 -0.7598,-0.189 -0.2362,0.126 -0.5,0.189 -0.7638,0.189 -0.5905,0 -1.126,-0.3189 -1.4173,-0.8307 -0.2874,-0.5119 -0.2717,-1.1457 0.035,-1.6418 l 20.6969,-33.4606 -2.6693,-4.3149 -24.4173,39.4803 c -0.2952,0.4803 -0.8149,0.7677 -1.3779,0.7677 -0.5866,0 -1.1299,-0.3189 -1.4173,-0.8307 -0.2874,-0.5118 -0.2717,-1.1457 0.039,-1.6418 l 25.2677,-40.8583 -2.6653,-4.3149 -29.4724,47.6457 -102.382,0 2.996,-4.8465 c -60.626,25.0472 -130.488,3.3622 -166.283,-51.6102 -35.8307,57.4685 -107.106,78.4961 -166.681,49.1732 l 0,7.2835 -86.9921,0 0,-0.6496 -14.3622,0 6.2717,17.7008 -6.4646,2.2953 -7.0827,-19.9961 -27.5787,0 0,-6.8662 25.1457,0 -51.2362,-144.638 -3.0315,7.378 0,144.776 -56.7402,0 0,-440.642 56.7402,0 0,197.547 9.693,-24.4961 0,-185.189 -78.7874,0 0,20.0591 c -34.1772,-22.9843 -57.0787,-28.4488 -87.1339,-28.4488 -23.7953,0 -76.0157,17.3425 -103.618,120.657 l -6.8622,0 -7e-4,3e-4 z m 122.902,349.776 -108.181,0 0,-6.8661 73.878,0 c -56.2992,-24.9961 -80.8307,-115.469 -80.8307,-222.724 0,-126.453 34.0866,-229.587 114.154,-229.587 36.7953,0 57.7008,18.9016 75.6929,36.1299 l 0,11.2362 c 0.01,0.01 0.012,0.02 0.02,0.028 l 0,95.2244 -6.1102,0 c -13.2677,-24.1772 -37.6575,-58.122 -62.8465,-58.122 -41.9764,0 -62.7441,65.0236 -62.2165,145.091 -0.5276,80.0748 20.2402,145.094 62.2165,145.094 25.189,0 49.5787,-33.9488 62.8465,-58.122 l 6.1102,0 0,95.2244 c -0.01,0.012 -0.012,0.016 -0.02,0.032 l 0,11.2323 c -17.8307,17.0748 -38.5276,35.7913 -74.7126,36.126 l -6e-4,-10e-5 z m -236.98,-459.173 c 79.3819,0 113.173,108.268 113.173,229.587 0,121.323 -33.7913,229.591 -113.173,229.591 -79.3819,0 -113.173,-103.134 -113.173,-229.591 0,-126.453 33.7913,-229.587 113.173,-229.587 l 0,0 z m -197.626,9.2677 -103.358,0 0,255.894 c 0.6693,1.7874 1.3307,3.5827 1.9921,5.374 4.6378,-1.2716 9.4528,-1.7874 14.2598,-1.5315 9.3977,0.5079 17.8661,5.8347 22.378,14.0984 4.0827,7.4646 6.0236,15.9134 5.6142,24.4094 -0.1693,3.5473 -1.1063,7.0197 -2.7402,10.1772 -4.0157,7.7559 -10.2126,14.1693 -17.8268,18.4409 2.5788,8.7481 5.0394,17.5236 7.3859,26.3307 4.4921,16.8504 6.6023,34.248 6.2638,51.689 -0.087,4.4961 -1.0591,8.9331 -2.8701,13.0512 -1.8544,4.2205 -5.1024,7.6733 -9.2008,9.7874 -2.9764,1.5315 -6.4449,1.7835 -9.6103,0.7008 -3.1614,-1.0827 -5.748,-3.4094 -7.1614,-6.4449 -1.6417,-3.5315 -2.4488,-7.3937 -2.3464,-11.2874 0.051,-2.1929 1.1102,-4.2401 2.87,-5.5472 2.2166,-1.6535 4.941,-2.4842 7.7008,-2.3543 1.8111,0.091 3.437,1.1496 4.2481,2.7716 0.811,1.626 0.6811,3.5591 -0.3347,5.063 -1.252,1.8504 -3.0905,3.2284 -5.2205,3.9173 l 0.7284,1.5906 c 0.3425,0.8976 1.1063,1.5748 2.0433,1.8071 0.937,0.2323 1.9291,-0.012 2.6535,-0.6457 3.567,-3.0394 5.7874,-7.3622 6.1772,-12.0315 0.5158,-8.0472 0.3465,-16.122 -0.5079,-24.1378 -2.5118,-17.122 -6.2401,-34.0433 -11.1654,-50.6299 -1.2637,0.4016 -2.5472,0.7441 -3.8425,1.0315 -3.7953,0.8465 -7.626,1.5039 -11.4882,1.9685 l 0,107.15 69.1772,0 0,14.3307 6.8622,0 0,-14.3307 14.7362,0 0,-6.8622 -14.7362,0 0,-154.508 6.626,0 60.3661,161.37 66.2992,0 5.9921,15.2913 6.3859,-2.5039 -5.9567,-15.2008 20.685,0 0,-6.8622 -23.374,0 -71.3898,-182.217 c 26.2795,-27.1063 41.3543,-67.9055 41.3543,-119.717 0,-69.4449 -18.7992,-129.433 -79.6693,-129.433 l -1e-4,4e-4 z m -91.0472,320.823 c -3.9409,1.626 -8.0787,2.7126 -12.311,3.2362 l 0,-39.0512 c 4.2598,11.8346 8.3504,23.7323 12.2677,35.685 0.016,0.043 0.032,0.087 0.043,0.13 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 0,0 m -6.4803,-48.9213 c 1.3504,-0.3701 2.7165,-0.6851 4.0905,-0.941 4.3071,-0.8031 8.7638,0.2441 12.2677,2.874 3.193,2.3937 5.4882,5.7914 6.5315,9.6457 2.315,8.5945 1.8111,17.7047 -1.4409,25.9843 -0.6811,1.7441 -1.811,3.2717 -3.2638,4.4409 -1.1141,0.8977 -2.2716,1.7441 -3.4645,2.5355 -4.5788,-14.9528 -9.4843,-29.8031 -14.7205,-44.5394 m -5.8308,52.1575 c -1.0826,0.1299 -2.1692,0.2283 -3.2598,0.2874 -11.8858,0.6456 -22.9409,-6.1024 -27.8031,-16.9685 -8.626,-19.2874 -9.8779,-41.063 -3.5236,-61.2165 2.2362,-7.0709 4.5394,-14.1181 6.9212,-21.1417 0.6536,-1.9449 1.3229,-3.8859 1.9961,-5.8268 6.378,15.1575 12.4764,30.4252 18.2913,45.811 -8.2835,4.4331 -14.9685,11.3583 -19.1142,19.7953 -0.685,1.3898 -0.4173,3.0669 0.6693,4.1772 1.0866,1.1063 2.7559,1.4094 4.1614,0.7559 1.2244,-0.8819 2.3583,-1.878 3.3937,-2.9764 4.1851,-4.6457 9.2047,-8.4764 14.7992,-11.2835 1.1654,3.1732 2.3228,6.3543 3.4685,9.5354 l 0,-29.1142 c -5.5,-14.7283 -11.3307,-29.3268 -17.4882,-43.7953 -1.0197,-2.3976 -2.059,-4.7834 -3.122,-7.1614 1.2795,-3.5157 2.5826,-7.0275 3.9055,-10.5276 1.8858,-4.996 3.3307,-10.1496 4.3071,-15.3976 1.1063,-5.9409 0.6102,-12.0669 -1.4331,-17.752 -4.6654,-12.9528 -13.6535,-23.9016 -25.4528,-31 -5.189,-3.122 -11.1772,-4.6653 -17.2283,-4.4409 -5.0709,0.1929 -9.1693,4.2008 -9.4606,9.2716 -0.2717,4.5945 0.7992,9.1733 3.0669,13.1811 2.1024,3.7087 4.3661,7.3229 6.7835,10.8346 7.4685,10.8228 13.9252,22.315 19.2835,34.3268 1.0551,2.3622 2.1023,4.7284 3.1417,7.0945 -1.6378,4.5 -3.2362,9.0079 -4.8032,13.5276 -7.2716,20.9764 -11.9606,42.7598 -13.9685,64.8701 -0.9448,10.437 -0.016,20.9567 2.7441,31.063 3.7835,13.8701 16.1142,23.689 30.4764,24.2795 6.4252,0.2638 12.8661,0 19.248,-0.7756 l 0,-9.433 m 93.9921,-342.409 -106.854,0 0,-16.6496 -6.8622,0 0,16.6496 -15.9843,0 0,6.8622 15.9843,0 0,76.4528 6.8622,0 0,-76.4528 106.854,0 0,-6.8622 z"
1765 class="fil6"
1766 inkscape:connector-curvature="0" />
1767 <path
1768 style="fill:#a9becd"
1769 id="path3068"
1770 d="m 4668.85,3647.2 -78.748,0 -35.2008,56.9173 -35.2047,-56.9173 -78.748,0 14.7677,23.874 c -30.0551,-25.5157 -70.3071,-35.5276 -108.815,-27.0669 -38.5039,8.4567 -70.8504,34.4213 -87.4449,70.185 -14.8701,-33.2717 -42.8622,-58.1772 -76.7087,-68.2559 -33.8543,-10.0827 -70.2362,-4.3504 -99.7244,15.7126 l 0,-94.4646 -66.8819,0 0,319.39 66.8819,0 0,-12.8819 c 29.5394,20.0984 65.9921,25.815 99.8898,15.6614 33.8976,-10.1496 61.8898,-35.1654 76.6929,-68.5394 16.7795,35.9016 49.4409,61.8465 88.2087,70.0669 38.7677,8.2165 79.1457,-2.248 109.047,-28.2559 l -15.7795,25.5157 78.748,0 35.0709,-56.7047 35.0669,56.7047 78.748,0 -74.4449,-120.362 74.5787,-120.579 3e-4,0 z"
1771 class="fil11"
1772 inkscape:connector-curvature="0" />
1773 <path
1774 style="fill:#131516"
1775 id="path3070"
1776 d="m 4201.93,3767.35 c 0,-32.8386 -26.622,-59.4567 -59.4528,-59.4567 -32.8307,0 -59.4488,26.6181 -59.4488,59.4567 0,32.8346 26.6181,59.4528 59.4488,59.4528 32.8307,0 59.4528,-26.6181 59.4528,-59.4528 z m 294.693,-30.1339 c 4.9843,20.2913 4.8583,41.5 -0.3701,61.7283 l 19.2756,-31.1614 -18.9055,-30.5669 m -63.1772,30.1339 c 0,-32.8386 -26.6142,-59.4567 -59.4449,-59.4567 -32.8346,0 -59.4528,26.6181 -59.4528,59.4567 0,32.8346 26.6181,59.4528 59.4528,59.4528 32.8307,0 59.4449,-26.6181 59.4449,-59.4528 z"
1777 class="fil6"
1778 inkscape:connector-curvature="0" />
1779 <path
1780 style="fill:#efaf04"
1781 id="path3072"
1782 d="m 3302.71,3891.33 12.437,0 0,-154.508 -12.437,0 0,154.508 m 25.6732,-251.902 c 20.9685,0 24.252,-26.5827 24.2323,-44.8268 -0.024,-18.2441 -2.6732,-38.0433 -20.9685,-38.0433 l -28.937,0 0,100.823 12.437,0 0,-17.9528 13.2362,0 0,-1e-4 z m 0,6.8661 -6.374,0 0,11.0866 0.437,0 c 46.7283,0 46.7283,-41.8465 46.7283,-56.3858 l 0,-9.3858 c 0,-14.0945 -0.095,-52.9961 -39.4409,-52.9961 l -27.0236,0 0,11.0827 25.6732,0 c 13.3543,0 31.2638,1.8977 31.2638,46.6811 0,44.7756 -18,49.5433 -31.2638,49.9173 l 0,0 z m -111.276,-1.2244 c -5.3779,-10.7362 -11.1929,-21.2441 -17.4409,-31.5 -1.9882,-3.2598 -3.7835,-6.6299 -5.3779,-10.0984 -1.0434,-2.2598 -1.6615,-4.6929 -1.8308,-7.1771 -0.032,-0.5355 0.1615,-1.063 0.5315,-1.4489 0.3741,-0.3858 0.8937,-0.5905 1.4292,-0.5748 2.5787,0.087 5.0945,0.8307 7.3071,2.1536 9.5236,5.6968 16.3071,15.0315 18.7953,25.8425 0.7244,3.1535 0.748,6.433 0.067,9.5945 -0.9606,4.4527 -2.1221,8.8582 -3.4803,13.2087 l 0,0 m 1155.26,171.65 3.2401,0 c 26.9528,-0.8898 48.2165,-23.2244 47.7717,-50.189 -0.4409,-26.9606 -22.4252,-48.5866 -49.3898,-48.5866 -26.9685,0 -48.9488,21.626 -49.3937,48.5866 -0.4409,26.9646 20.8189,49.2992 47.7717,50.189 l 0,0 z m -231.52,0 3.2401,0 c 26.9528,-0.8898 48.2126,-23.2244 47.7717,-50.189 -0.4409,-26.9606 -22.4291,-48.5866 -49.3937,-48.5866 -26.9646,0 -48.9488,21.626 -49.3898,48.5866 -0.4409,26.9646 20.8189,49.2992 47.7717,50.189 l 0,0 z m -154.866,-155.323 20.0945,51.9843 0,-99.4134 -20.0945,47.4291 m 3.3031,229.28 -54.6102,-154.161 6.4055,-15.5945 63.1024,169.756 -14.8976,0 m -442.339,-359.386 c 38.2244,0 54.4882,69.1181 54.4882,146.579 0,77.4646 -16.2638,146.583 -54.4882,146.583 -38.2205,0 -54.4843,-65.8504 -54.4843,-146.583 0,-80.7283 16.2638,-146.579 54.4843,-146.579 z"
1783 class="fil9"
1784 inkscape:connector-curvature="0" />
1785 <path
1786 style="fill:#131516"
1787 id="path3074"
1788 d="m 4372.37,3816.72 c 1.0787,0.079 2.1575,0.071 3.2402,0 l 0,-4.5433 c 24.4488,-0.8819 43.6811,-21.1969 43.2323,-45.6575 -0.4489,-24.4646 -20.4173,-44.0551 -44.8858,-44.0394 -0.5867,-0.01 -1.0709,0.2992 -1.3622,0.8031 -0.2993,0.5079 -0.2993,1.1339 0,1.6418 0.2953,0.5039 0.7835,0.8071 1.3701,0.8031 15.063,-0.016 28.9606,8.1181 36.3307,21.2598 7.3661,13.1378 7.0591,29.2402 -0.8071,42.0866 -7.8622,12.8465 -22.0591,20.4449 -37.1142,19.8583 l 0,7.7874 0,10e-5 z m -229.902,-12.2953 c -0.8937,0 -1.6181,-0.7283 -1.6181,-1.6221 0,-0.8976 0.7244,-1.622 1.6181,-1.622 18.689,0 33.8346,-15.1496 33.8346,-33.8346 0,-18.6929 -15.1457,-33.8386 -33.8346,-33.8386 -0.8937,0 -1.6181,-0.7283 -1.6181,-1.6221 0,-0.8976 0.7244,-1.6181 1.6181,-1.6181 20.4803,0 37.0748,16.5945 37.0748,37.0787 0,20.4764 -16.5945,37.0787 -37.0748,37.0787 l 0,1e-4 z m 231.524,0 c -0.8976,0 -1.622,-0.7283 -1.622,-1.6221 0,-0.8976 0.7244,-1.622 1.622,-1.622 18.685,0 33.8346,-15.1496 33.8346,-33.8346 0,-18.6929 -15.1496,-33.8386 -33.8346,-33.8386 -0.8976,0 -1.622,-0.7283 -1.622,-1.6221 0,-0.8976 0.7244,-1.6181 1.622,-1.6181 20.4764,0 37.0748,16.5945 37.0748,37.0787 0,20.4764 -16.5984,37.0787 -37.0748,37.0787 l 0,1e-4 z M 4140.85,3816.72 c 1.0787,0.051 2.1575,0.035 3.2402,0 l 0,-4.5433 c 24.4488,-0.8819 43.6772,-21.1969 43.2323,-45.6575 -0.4528,-24.4646 -20.4213,-44.0551 -44.8858,-44.0394 -0.5827,-0.01 -1.067,0.2992 -1.3662,0.8031 -0.2953,0.5079 -0.2953,1.1339 0,1.6418 0.2953,0.5039 0.7835,0.8071 1.3701,0.8031 15.063,-0.016 28.9606,8.1181 36.3268,21.2598 7.3701,13.1378 7.0591,29.2402 -0.8071,42.0866 -7.8622,12.8465 -22.0591,20.4449 -37.1102,19.8583 l 0,7.7874 -10e-5,10e-5 z m -593.898,-12.8976 0,-16.9528 -6.8661,0 0,18.0551 0,6.8622 c 37.1024,0 47.9921,-63.0039 48.248,-130.484 l 156.142,0 c 0.37,47.5039 10.7874,120.209 41.7992,125.224 l 0,17.9252 6.8622,0 0,-143.15 27.3228,0 0,-6.8661 -27.3228,0 0,-24.7598 -6.8622,0 0,24.7598 -34.9094,0 c 0.7401,-47.0787 13.8937,-115.913 38.3386,-117.031 l 0,-6.8662 c -32.0669,1.2441 -44.5276,74.7126 -45.2087,123.898 l -156.173,0 c -0.4449,-67.1575 -11.2874,-129.65 -48.2362,-129.65 l 0,6.5866 0,123.063 -20.9724,0 0,6.8662 20.9724,0 0,23.9685 6.8661,0 0,-23.9685 34.5079,0 c -0.3425,43.1929 -5.7874,112.988 -34.5079,122.52 l -5e-4,-2e-4 z"
1789 class="fil6"
1790 inkscape:connector-curvature="0" />
1791 <path
1792 style="fill:#efaf04"
1793 id="path3076"
1794 d="m 3751.34,3681.31 c 0.4449,44.9685 11.8307,112.11 34.937,118.209 l 0,-118.209 -34.937,0 z m -169.866,-6.8661 -34.5197,0 0,-121.953 c 28.5748,9.496 34.315,78.689 34.5197,121.953 z"
1795 class="fil9"
1796 inkscape:connector-curvature="0" />
1797 </g>
1798 <g
1799 id="g6938-8"
1800 style="display:inline"
1801 transform="translate(54.936222,-93.2058)">
1802 <rect
1803 style="fill:url(#linearGradient4564);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4566);stroke-width:0.99212599;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1804 id="rect4922-1-1-7-5"
1805 width="56.692913"
1806 height="56.692913"
1807 x="171.15355"
1808 y="294.72559"
1809 ry="13.143503"
1810 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1811 inkscape:export-xdpi="96"
1812 inkscape:export-ydpi="96" />
1813 <path
1814 inkscape:connector-curvature="0"
1815 style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;filter:url(#filter5226-7)"
1816 d="m 186.09375,300.59375 c -5.02091,0 -9.09375,4.03754 -9.09375,9.0625 l 0,26.8125 c 0,5.02496 4.06879,9.09375 9.09375,9.09375 l 26.8125,0 c 5.02496,0 9.09375,-4.06879 9.09375,-9.09375 l 0,-26.8125 c 0,-5.02496 -4.07284,-9.0625 -9.09375,-9.0625 l -26.8125,0 z"
1817 id="path4397-6" />
1818 <rect
1819 style="fill:url(#linearGradient4568);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4570);stroke-width:0.99921262;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1820 id="rect4922-5-6-6-7-6"
1821 width="40.202908"
1822 height="40.202908"
1823 x="179.39854"
1824 y="302.97058"
1825 ry="6.6378174"
1826 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1827 inkscape:export-xdpi="96"
1828 inkscape:export-ydpi="96" />
1829 </g>
1830 <g
1831 transform="translate(-204.10139,-35.936746)"
1832 id="g8585">
1833 <path
1834 style="fill:#323232;fill-opacity:1;stroke:none"
1835 d="m 399.7843,265.81185 c -2.28956,-1.32188 -4.57912,-2.64375 -6.86868,-3.96563 0,2.63785 0,5.27569 0,7.91354 2.28956,-1.31597 4.57912,-2.63194 6.86868,-3.94791 z"
1836 id="path8455"
1837 inkscape:connector-curvature="0" />
1838 <path
1839 style="fill:#282828;fill-opacity:1;stroke:none"
1840 d="m 392.94938,261.88269 c 0.32292,0.69792 0.64583,1.39583 0.96875,2.09375 1.01042,0.67708 2.02083,1.35417 3.03125,2.03125 0.92708,-0.0521 1.85417,-0.10417 2.78125,-0.15625 0.14211,-0.0564 -0.15675,-0.12586 -0.21013,-0.18806 -2.19036,-1.26024 -4.38083,-2.52041 -6.57112,-3.78069 z"
1841 id="path6411"
1842 inkscape:connector-curvature="0" />
1843 <path
1844 style="fill:#595959;fill-opacity:1;stroke:none"
1845 d="m 392.91813,261.85144 c 0,2.63542 0,5.27083 0,7.90625 0.3125,-0.65625 0.625,-1.3125 0.9375,-1.96875 0.0224,-1.21914 0.0159,-2.44053 0.10149,-3.6573 0.0533,-0.15391 -0.0896,-0.29031 -0.13306,-0.43614 -0.27072,-0.59385 -0.54145,-1.18771 -0.81218,-1.78156 -0.0312,-0.0208 -0.0625,-0.0417 -0.0937,-0.0625 z"
1846 id="path6413"
1847 inkscape:connector-curvature="0" />
1848 <path
1849 style="fill:#1a1a1a;stroke:none"
1850 d="m 399.73063,265.85144 c -0.92708,0.0521 -1.85417,0.10417 -2.78125,0.15625 -1.01042,0.5625 -2.02083,1.125 -3.03125,1.6875 -0.33333,0.67708 -0.66667,1.35417 -1,2.03125 0.0492,0.0442 0.21494,-0.11256 0.30924,-0.14612 2.16774,-1.24293 4.33559,-2.48607 6.50326,-3.72888 z"
1851 id="path6415"
1852 inkscape:connector-curvature="0" />
1853 <path
1854 style="fill:#2b2b2b;fill-opacity:1;stroke:none;display:inline"
1855 d="m 398.30055,265.87526 c -1.60242,-0.92516 -3.20484,-1.85031 -4.80726,-2.77547 0,1.84618 0,3.69236 0,5.53854 1.60242,-0.92102 3.20484,-1.84205 4.80726,-2.76307 z"
1856 id="path8455-6"
1857 inkscape:connector-curvature="0" />
1858 </g>
1859 <path
1860 inkscape:connector-curvature="0"
1861 inkscape:export-ydpi="96"
1862 inkscape:export-xdpi="96"
1863 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1864 sodipodi:nodetypes="ccccc"
1865 id="path6390-4"
1866 d="m 77.509982,43.29852 c 0,0 -2.22674,-0.59595 -2.08757,-1.27702 l 0,-9.80756 c 0.0696,-0.95352 2.08758,-1.60055 2.08758,-1.60055 l -1e-5,12.68513 z"
1867 style="fill:url(#linearGradient4572);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
1868 <path
1869 inkscape:connector-curvature="0"
1870 inkscape:export-ydpi="96"
1871 inkscape:export-xdpi="96"
1872 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1873 sodipodi:nodetypes="ccccc"
1874 id="path6390-4-7"
1875 d="m 77.474772,99.472927 c 0,0 -3.10604,0.0286 -3.05693,-0.56816 l -0.0625,-10.636893 c 0.0129,-0.8278 3.11945,-0.74597 3.11945,-0.74597 z"
1876 style="fill:url(#linearGradient4574);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
1877 <path
1878 inkscape:connector-curvature="0"
1879 inkscape:export-ydpi="96"
1880 inkscape:export-xdpi="96"
1881 inkscape:export-filename="/home/simon/Desktop/DX50.png"
1882 sodipodi:nodetypes="ccccc"
1883 id="path6390-4-2-1"
1884 d="m 304.22694,96.830807 c 0,0 2.22674,-0.924813 2.08757,-1.981713 l 0,-15.21964 c -0.0696,-1.4797 -2.08758,-2.48378 -2.08758,-2.48378 l 1e-5,19.685133 z"
1885 style="fill:url(#linearGradient4576);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
1886 <path
1887 transform="translate(-8.4564067,-93.209401)"
1888 d="m 197.125,318.09375 a 1.0346626,1.0346626 0 0 0 -0.90625,1.03125 l 0,7.875 0,0.0312 a 1.0346626,1.0346626 0 0 0 1.53125,0.90625 l 6.78125,-3.875 0.0312,-0.0312 0.0312,0 a 1.0346626,1.0346626 0 0 0 0.0625,-1.84375 l -6.75,-3.875 a 1.0346626,1.0346626 0 0 0 -0.0312,-0.0312 1.0346626,1.0346626 0 0 0 -0.0625,-0.0312 1.0346626,1.0346626 0 0 0 -0.0625,-0.0312 1.0346626,1.0346626 0 0 0 -0.625,-0.125 z"
1889 id="path6837"
1890 style="opacity:0.19620254;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter6851)"
1891 inkscape:original="M 197.25 319.125 L 197.25 327 L 197.25 327.03125 L 204.0625 323.125 L 204.125 323.09375 L 197.34375 319.1875 L 197.28125 319.15625 L 197.25 319.125 z "
1892 inkscape:radius="1.0345591"
1893 sodipodi:type="inkscape:offset" />
1894 <g
1895 transform="translate(-204.10139,-35.936746)"
1896 id="g8542">
1897 <path
1898 style="fill:#232323;fill-opacity:1;stroke:none;display:inline"
1899 d="m 327.00633,269.44125 c 0,-1.11084 0,-2.22167 0,-3.33251 1.72734,1.10675 3.45467,2.21349 5.18201,3.32024 0,-1.11356 0,-2.22712 0,-3.34068 1.73872,1.11356 3.47743,2.22712 5.21615,3.34068 0,-2.40022 0,-4.80044 0,-7.20066 -1.73872,1.05359 -3.47743,2.10718 -5.21615,3.16077 0,-1.05359 0,-2.10718 0,-3.16077 -1.72734,1.04677 -3.45467,2.09354 -5.18201,3.14031 0,-1.05086 0,-2.10173 0,-3.15259 -0.45237,0 -0.90474,0 -1.35711,0 0,2.4084 0,4.81681 0,7.22521 0.45237,0 0.90474,0 1.35711,0 z"
1900 id="path7889-0-2-1-4"
1901 inkscape:connector-curvature="0" />
1902 <path
1903 style="fill:#1f1f1f;fill-opacity:1;stroke:none;display:inline"
1904 d="m 332.24812,262.10464 c -0.10841,0.14556 -0.21682,0.29111 -0.32523,0.43667 0.23534,0.0406 0.16,0.26734 0.16948,0.44327 10e-4,0.8304 0.002,1.66079 0.003,2.49119 0.17839,-0.17839 0.35677,-0.35678 0.53516,-0.53517 -0.0797,-0.6842 -0.0168,-1.37586 -0.0326,-2.06341 0.008,-0.29242 0.0376,-0.63321 -0.24068,-0.82327 -0.0365,0.0169 -0.0731,0.0338 -0.10962,0.0507 z m -4.82032,0.14453 c -0.16141,0.10162 -0.32282,0.20325 -0.48423,0.30487 -1e-5,0.97356 -1e-5,1.94712 -2e-5,2.92068 0.26207,-0.14668 0.37661,-0.43001 0.54362,-0.66474 -0.0308,-0.85054 -0.004,-1.7031 -0.0398,-2.5529 l -0.0196,-0.008 z m 4.60614,3.74231 c 0.20835,0.33784 0.19209,0.84621 0.629,0.99034 1.46558,0.86307 2.91963,1.7481 4.39244,2.59739 0.44409,0.21608 0.66901,-0.45455 0.14477,-0.50907 -0.30256,-0.21825 -0.69163,-0.41829 -1.02983,-0.62826 -1.37879,-0.8168 -2.75759,-1.6336 -4.13638,-2.4504 z m -5.10031,0.0153 c 0.097,0.26439 0.19403,0.52879 0.29105,0.79318 1.54358,0.91636 3.09222,1.82783 4.63794,2.74209 0.66335,0.22026 0.2732,-0.59301 -0.11379,-0.65415 -1.60507,-0.96037 -3.21013,-1.92075 -4.8152,-2.88112 z"
1905 id="path6567-3"
1906 inkscape:connector-curvature="0" />
1907 <path
1908 style="fill:#595959;fill-opacity:1;stroke:none;display:inline"
1909 d="m 337.53829,262.07146 c -0.10787,0.15263 -0.31294,0.26738 -0.35547,0.44548 0,2.17833 0,4.35666 0,6.53499 0.0729,0.16667 0.14583,0.33333 0.21875,0.5 0.42015,-0.19158 0.29245,-0.69003 0.3125,-1.05824 -0.002,-2.05345 0.003,-4.10716 -0.002,-6.16046 -0.004,-0.11255 -0.0791,-0.2083 -0.17347,-0.26177 z m -10.63672,3.91797 c 0,1.02083 0,2.04167 0,3.0625 -0.40625,0 -0.8125,0 -1.21875,0 -0.11458,0.15625 -0.22917,0.3125 -0.34375,0.46875 0.36996,0.12045 0.77333,0.0385 1.15894,0.0625 0.3255,0.006 0.74566,0.0428 0.89187,-0.33037 0.0869,-0.41956 0.0197,-0.85938 0.0371,-1.28796 -0.0114,-0.37548 0.0147,-0.76063 -0.0199,-1.13014 -0.16072,-0.27127 -0.28808,-0.5771 -0.46928,-0.82715 l -0.0263,-0.0131 -0.01,-0.005 -2e-5,-5e-5 z m 5.14844,0.0156 c -0.008,1.01562 -0.0156,2.03125 -0.0234,3.04687 0.025,0.14812 0.14073,0.33271 0.20046,0.49479 0.43549,-0.15196 0.31286,-0.66549 0.3308,-1.02333 0,-0.53205 0,-1.0641 0,-1.59615 0.12647,0.0484 -0.14412,-0.2712 -0.17884,-0.37221 -0.10967,-0.18333 -0.21935,-0.36665 -0.32902,-0.54997 z"
1910 id="path6567-4-7"
1911 inkscape:connector-curvature="0" />
1912 <path
1913 style="fill:#141414;fill-opacity:1;stroke:none;display:inline"
1914 d="m 325.59064,262.0246 c -0.41417,0.0673 -0.46651,0.51397 -0.4375,0.85444 0,2.09019 0,4.18037 0,6.27056 0.0227,0.43912 0.27928,0.37645 0.42348,0.0747 0.19113,-0.16833 0.0772,-0.44216 0.10777,-0.66602 0,-2.0008 0,-4.0016 0,-6.0024 0.4553,-0.009 0.92023,0.0189 1.36954,-0.0141 0.16509,-0.11541 0.59641,-0.20156 0.29562,-0.44703 -0.34143,-0.12983 -0.72414,-0.0462 -1.08537,-0.0701 -0.2245,-3e-5 -0.44917,8e-5 -0.67354,-7e-5 z m 6.40625,0 c -1.47016,0.848 -2.95976,1.66428 -4.43745,2.5 -0.2047,0.32234 -0.40941,0.64468 -0.61411,0.96702 1.69429,-0.95776 3.38857,-1.91551 5.08286,-2.87327 0.11458,-0.1875 0.22917,-0.375 0.34375,-0.5625 -0.11568,-0.0556 -0.25182,-0.0668 -0.37505,-0.0312 z m 5.125,0 c -1.54469,0.91549 -3.10534,1.80536 -4.6562,2.71094 -0.1224,0.25 -0.24479,0.5 -0.36719,0.75 1.73698,-0.97656 3.47396,-1.95313 5.21094,-2.92969 0.0757,-0.14715 0.38209,-0.30796 0.28793,-0.44505 -0.13014,-0.10717 -0.31597,-0.1492 -0.47548,-0.0862 z"
1915 id="path6567-4-3-5"
1916 inkscape:connector-curvature="0" />
1917 </g>
1918 <path
1919 inkscape:connector-curvature="0"
1920 id="path7889-0-2-1-4-4"
1921 d="m 258.99449,226.22799 c 0,1.11084 0,2.22167 0,3.33251 -1.72734,-1.10675 -3.45467,-2.21349 -5.18201,-3.32024 0,1.11356 0,2.22712 0,3.34068 -1.73872,-1.11356 -3.47743,-2.22712 -5.21615,-3.34068 0,2.40022 0,4.80044 0,7.20066 1.73872,-1.05359 3.47743,-2.10718 5.21615,-3.16077 0,1.05359 0,2.10718 0,3.16077 1.72734,-1.04677 3.45467,-2.09354 5.18201,-3.14031 0,1.05086 0,2.10173 0,3.15259 0.45237,0 0.90474,0 1.35711,0 0,-2.4084 0,-4.81681 0,-7.22521 -0.45237,0 -0.90474,0 -1.35711,0 z"
1922 style="fill:#232323;fill-opacity:1;stroke:none;display:inline" />
1923 <path
1924 inkscape:connector-curvature="0"
1925 id="path6567-3-4"
1926 d="m 253.7527,233.5646 c 0.10841,-0.14555 0.21682,-0.29111 0.32523,-0.43666 -0.23534,-0.0406 -0.16,-0.26734 -0.16948,-0.44327 -10e-4,-0.8304 -0.002,-1.66079 -0.003,-2.49119 -0.17839,0.17839 -0.35677,0.35678 -0.53516,0.53517 0.0797,0.68419 0.0168,1.37585 0.0326,2.0634 -0.008,0.29242 -0.0376,0.63321 0.24068,0.82327 0.0365,-0.0169 0.0731,-0.0338 0.10962,-0.0507 z m 4.82032,-0.14453 c 0.16141,-0.10162 0.32282,-0.20325 0.48423,-0.30487 10e-6,-0.97356 10e-6,-1.94712 2e-5,-2.92068 -0.26207,0.14668 -0.37661,0.43001 -0.54362,0.66474 0.0308,0.85054 0.004,1.7031 0.0398,2.5529 l 0.0196,0.008 z m -4.60614,-3.74231 c -0.20835,-0.33784 -0.19209,-0.84621 -0.629,-0.99034 -1.46558,-0.86307 -2.91963,-1.7481 -4.39244,-2.59739 -0.44409,-0.21608 -0.66901,0.45455 -0.14477,0.50907 0.30256,0.21825 0.69163,0.41829 1.02983,0.62826 1.37879,0.8168 2.75759,1.6336 4.13638,2.4504 z m 5.10031,-0.0153 c -0.097,-0.26439 -0.19403,-0.52879 -0.29105,-0.79318 -1.54358,-0.91636 -3.09222,-1.82783 -4.63794,-2.74209 -0.66335,-0.22026 -0.2732,0.59301 0.11379,0.65415 1.60507,0.96037 3.21013,1.92075 4.8152,2.88112 z"
1927 style="fill:#1c1c1c;fill-opacity:1;stroke:none;display:inline" />
1928 <path
1929 inkscape:connector-curvature="0"
1930 id="path6567-4-7-4"
1931 d="m 248.46253,233.59778 c 0.10787,-0.15263 0.31294,-0.26738 0.35547,-0.44548 0,-2.17833 0,-4.35666 0,-6.53499 -0.0729,-0.16667 -0.14583,-0.33333 -0.21875,-0.5 -0.42015,0.19158 -0.29245,0.69003 -0.3125,1.05824 0.002,2.05345 -0.003,4.10717 0.002,6.16046 0.004,0.11255 0.0791,0.2083 0.17347,0.26177 z m 10.63672,-3.91797 c 0,-1.02083 0,-2.04167 0,-3.0625 0.40625,0 0.8125,0 1.21875,0 0.11458,-0.15625 0.22917,-0.3125 0.34375,-0.46875 -0.36996,-0.12045 -0.77333,-0.0385 -1.15894,-0.0625 -0.3255,-0.006 -0.74566,-0.0428 -0.89187,0.33038 -0.0869,0.41955 -0.0197,0.85937 -0.0371,1.28795 0.0114,0.37548 -0.0147,0.76063 0.0199,1.13014 0.16072,0.27127 0.28808,0.5771 0.46928,0.82715 l 0.0263,0.0131 0.01,0.005 2e-5,5e-5 z m -5.14844,-0.0156 c 0.008,-1.01563 0.0156,-2.03125 0.0234,-3.04688 -0.025,-0.14812 -0.14073,-0.33271 -0.20046,-0.49479 -0.43549,0.15196 -0.31288,0.66549 -0.33081,1.02334 0,0.53204 0,1.06409 0,1.59614 -0.12647,-0.0484 0.14412,0.2712 0.17884,0.37221 0.10968,0.18333 0.21935,0.36665 0.32903,0.54998 z"
1932 style="fill:#141414;fill-opacity:1;stroke:none;display:inline" />
1933 <path
1934 inkscape:connector-curvature="0"
1935 id="path6567-4-3-5-7"
1936 d="m 260.41018,233.64464 c 0.41418,-0.0673 0.46651,-0.51397 0.4375,-0.85444 0,-2.09019 0,-4.18037 0,-6.27056 -0.0227,-0.43912 -0.27928,-0.37645 -0.42348,-0.0747 -0.19113,0.16833 -0.0772,0.44216 -0.10777,0.66603 0,2.00079 0,4.00159 0,6.00239 -0.4553,0.009 -0.92023,-0.0189 -1.36954,0.0141 -0.16508,0.11541 -0.59641,0.20156 -0.29562,0.44703 0.34143,0.12985 0.72414,0.0462 1.08537,0.0701 0.2245,3e-5 0.44915,-7e-5 0.67354,6e-5 z m -6.40625,0 c 1.47016,-0.848 2.95976,-1.66428 4.43745,-2.5 0.2047,-0.32234 0.40941,-0.64468 0.61411,-0.96702 -1.69429,0.95776 -3.38857,1.91551 -5.08286,2.87327 -0.11458,0.1875 -0.22917,0.375 -0.34375,0.5625 0.11568,0.0555 0.25182,0.0668 0.37505,0.0312 z m -5.125,0 c 1.54469,-0.91549 3.10534,-1.80536 4.6562,-2.71094 0.1224,-0.25 0.24479,-0.5 0.36719,-0.75 -1.73698,0.97656 -3.47396,1.95313 -5.21094,2.92969 -0.0757,0.14715 -0.38209,0.30797 -0.28793,0.44506 0.13014,0.10717 0.31597,0.1492 0.47548,0.0862 z"
1937 style="fill:#595959;fill-opacity:1;stroke:none;display:inline" />
1938 </g>
1939 <path
1940 style="fill:#4d4d4d;stroke:#4d4d4d;stroke-width:1.23570383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1941 id="path3725-79"
1942 d="m 189.38243,239.75116 124.33073,69.71405"
1943 inkscape:export-filename="/home/marko/Dropbox/Public/clipplus.png"
1944 inkscape:export-xdpi="96.824623"
1945 inkscape:export-ydpi="96.824623"
1946 inkscape:connector-curvature="0"
1947 sodipodi:nodetypes="cc" />
1948 <path
1949 style="fill:#4d4d4d;stroke:#4d4d4d;stroke-width:1.23570383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1950 id="path3725-0"
1951 d="m 259.7611,236.54405 54.45205,-1.57884"
1952 inkscape:export-filename="/home/marko/Dropbox/Public/clipplus.png"
1953 inkscape:export-xdpi="96.824623"
1954 inkscape:export-ydpi="96.824623"
1955 inkscape:connector-curvature="0"
1956 sodipodi:nodetypes="cc" />
1957 <path
1958 style="fill:#4d4d4d;stroke:#4d4d4d;stroke-width:1.23570383;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
1959 id="path3725-79-2"
1960 d="m 45.792482,222.25228 69.883508,6.42799"
1961 inkscape:export-filename="/home/marko/Dropbox/Public/clipplus.png"
1962 inkscape:export-xdpi="96.824623"
1963 inkscape:export-ydpi="96.824623"
1964 inkscape:connector-curvature="0"
1965 sodipodi:nodetypes="cc" />
1966</svg>
diff --git a/rbutil/ibassoboot/jni/Android.mk b/rbutil/ibassoboot/jni/Android.mk
new file mode 100644
index 0000000000..1d1566d8c0
--- /dev/null
+++ b/rbutil/ibassoboot/jni/Android.mk
@@ -0,0 +1,6 @@
1LOCAL_PATH := $(call my-dir)
2include $(CLEAR_VARS)
3
4LOCAL_MODULE := MangoPlayer
5LOCAL_SRC_FILES := ibassodualboot.c qdbmp.c
6include $(BUILD_EXECUTABLE)
diff --git a/rbutil/ibassoboot/jni/chooser.bmp b/rbutil/ibassoboot/jni/chooser.bmp
new file mode 100644
index 0000000000..3e6742d600
--- /dev/null
+++ b/rbutil/ibassoboot/jni/chooser.bmp
Binary files differ
diff --git a/rbutil/ibassoboot/jni/ibassodualboot.c b/rbutil/ibassoboot/jni/ibassodualboot.c
new file mode 100644
index 0000000000..3f20bbeecf
--- /dev/null
+++ b/rbutil/ibassoboot/jni/ibassodualboot.c
@@ -0,0 +1,439 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Ilia Sergachev
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 <dirent.h>
23#include <errno.h>
24#include <fcntl.h>
25
26#include <linux/fb.h>
27#include <linux/input.h>
28#include <linux/reboot.h>
29
30#include <stdbool.h>
31#include <string.h>
32#include <stdint.h>
33#include <stdio.h>
34#include <stdlib.h>
35
36#include <time.h>
37
38#include <sys/limits.h>
39#include <sys/mman.h>
40#include <sys/inotify.h>
41#include <sys/ioctl.h>
42#include <sys/poll.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/types.h>
46
47#include <unistd.h>
48
49#include "qdbmp.h"
50
51
52#define MIN_TIME 1395606821
53#define TIME_FILE "/data/time_store"
54#define TIME_CHECK_PERIOD 60 /* seconds */
55#define VOLD_LINK "/data/vold"
56#define PLAYER_FILE "/data/chosen_player"
57#define NOASK_FLAG "/data/no_ask_once"
58#define POLL_MS 10
59
60
61#define KEYCODE_HEADPHONES 114
62#define KEYCODE_HOLD 115
63#define KEYCODE_PWR 116
64#define KEYCODE_PWR_LONG 117
65#define KEYCODE_SD 143
66#define KEYCODE_VOLPLUS 158
67#define KEYCODE_VOLMINUS 159
68#define KEYCODE_PREV 160
69#define KEYCODE_NEXT 162
70#define KEYCODE_PLAY 161
71
72#define KEY_HOLD_OFF 16
73
74void checktime()
75{
76 time_t t_stored=0, t_current=time(NULL);
77
78 FILE *f = fopen(TIME_FILE, "r");
79 if(f!=NULL)
80 {
81 fscanf(f, "%ld", &t_stored);
82 fclose(f);
83 }
84
85 printf("stored time: %ld, current time: %ld\n", t_stored, t_current);
86
87 if(t_stored<MIN_TIME)
88 t_stored=MIN_TIME;
89
90 if(t_stored<t_current)
91 {
92 f = fopen(TIME_FILE, "w");
93 fprintf(f, "%ld", t_current);
94 fclose(f);
95 }
96 else
97 {
98 t_stored += TIME_CHECK_PERIOD;
99 struct tm *t = localtime(&t_stored);
100 struct timeval tv = {mktime(t), 0};
101 settimeofday(&tv, 0);
102 }
103}
104
105
106static struct pollfd *ufds;
107static char **device_names;
108static int nfds;
109
110
111
112static int open_device(const char *device, int print_flags)
113{
114 int fd;
115 struct pollfd *new_ufds;
116 char **new_device_names;
117
118 fd = open(device, O_RDWR);
119 if(fd < 0)
120 {
121 fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));
122 return -1;
123 }
124
125 new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
126 if(new_ufds == NULL)
127 {
128 fprintf(stderr, "out of memory\n");
129 return -1;
130 }
131 ufds = new_ufds;
132 new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
133 if(new_device_names == NULL)
134 {
135 fprintf(stderr, "out of memory\n");
136 return -1;
137 }
138 device_names = new_device_names;
139
140 ufds[nfds].fd = fd;
141 ufds[nfds].events = POLLIN;
142 device_names[nfds] = strdup(device);
143 nfds++;
144
145 return 0;
146}
147
148
149
150static int scan_dir(const char *dirname, int print_flags)
151{
152 char devname[PATH_MAX];
153 char *filename;
154 DIR *dir;
155 struct dirent *de;
156 dir = opendir(dirname);
157 if(dir == NULL)
158 return -1;
159 strcpy(devname, dirname);
160 filename = devname + strlen(devname);
161 *filename++ = '/';
162 while((de = readdir(dir)))
163 {
164 if(de->d_name[0] == '.' &&
165 (de->d_name[1] == '\0' ||
166 (de->d_name[1] == '.' && de->d_name[2] == '\0')))
167 continue;
168 strcpy(filename, de->d_name);
169 open_device(devname, print_flags);
170 }
171 closedir(dir);
172 return 0;
173}
174
175
176
177void button_init_device(void)
178{
179 int res;
180 int print_flags = 0;
181 const char *device = NULL;
182 const char *device_path = "/dev/input";
183
184 nfds = 1;
185 ufds = calloc(1, sizeof(ufds[0]));
186 ufds[0].fd = inotify_init();
187 ufds[0].events = POLLIN;
188 if(device)
189 {
190 res = open_device(device, print_flags);
191 if(res < 0) {
192 fprintf(stderr, "open device failed\n");
193 }
194 }
195 else
196 {
197 res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
198 if(res < 0)
199 {
200 fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));
201 }
202 res = scan_dir(device_path, print_flags);
203 if(res < 0)
204 {
205 fprintf(stderr, "scan dir failed for %s\n", device_path);
206 }
207 }
208}
209
210
211int draw()
212{
213 int fbfd = 0;
214 struct fb_var_screeninfo vinfo;
215 struct fb_fix_screeninfo finfo;
216 long int screensize = 0;
217 char *fbp = 0;
218 int x = 0, y = 0;
219 long int location = 0;
220
221 /* Open the file for reading and writing */
222 fbfd = open("/dev/graphics/fb0", O_RDWR);
223 if (fbfd == -1)
224 {
225 perror("Error: cannot open framebuffer device");
226 exit(1);
227 }
228 /* Get fixed screen information */
229 if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
230 {
231 perror("Error reading fixed information");
232 exit(2);
233 }
234
235 /* Get variable screen information */
236 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
237 {
238 perror("Error reading variable information");
239 exit(3);
240 }
241
242 /* Figure out the size of the screen in bytes */
243 screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
244
245 vinfo.xres = vinfo.xres_virtual = vinfo.width = 320;
246 vinfo.yres = vinfo.yres_virtual = vinfo.height = 240;
247 vinfo.xoffset = vinfo.yoffset = vinfo.sync = vinfo.vmode = 0;
248 vinfo.pixclock = 104377;
249 vinfo.left_margin = 20;
250 vinfo.right_margin = 50;
251 vinfo.upper_margin = 2;
252 vinfo.lower_margin = 4;
253 vinfo.hsync_len = 10;
254 vinfo.vsync_len = 2;
255 vinfo.red.offset = 11;
256 vinfo.red.length = 5;
257 vinfo.red.msb_right = 0;
258 vinfo.green.offset = 5;
259 vinfo.green.length = 6;
260 vinfo.green.msb_right = 0;
261 vinfo.blue.offset = 0;
262 vinfo.blue.length = 5;
263 vinfo.blue.msb_right = 0;
264 vinfo.transp.offset = vinfo.transp.length = vinfo.transp.msb_right = 0;
265 vinfo.nonstd = 4;
266
267 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo))
268 {
269 perror("fbset(ioctl)");
270 exit(4);
271 }
272
273
274 /* Map the device to memory */
275 fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
276 fbfd, 0);
277 if ((int)fbp == -1)
278 {
279 perror("Error: failed to map framebuffer device to memory");
280 exit(4);
281 }
282
283 BMP* bmp = BMP_ReadFile("/system/rockbox/chooser.bmp");
284 BMP_CHECK_ERROR( stderr, -1 );
285
286 UCHAR r, g, b;
287 unsigned short int t;
288
289 for (y = 0; y < 240; y++)
290 for (x = 0; x < 320; x++)
291 {
292 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
293 (y+vinfo.yoffset) * finfo.line_length;
294
295 BMP_GetPixelRGB(bmp, x, y, &r, &g, &b);
296 t = (r>>3)<<11 | (g>>2) << 5 | (b>>3);
297 *((unsigned short int*)(fbp + location)) = t;
298 }
299
300 BMP_Free( bmp );
301
302 munmap(fbp, screensize);
303 close(fbfd);
304 return 0;
305}
306
307
308int choose_player()
309{
310 int i;
311 int res;
312 struct input_event event;
313
314 while(true)
315 {
316 poll(ufds, nfds, POLL_MS);
317 for(i = 1; i < nfds; i++)
318 {
319 if(ufds[i].revents & POLLIN)
320 {
321 res = read(ufds[i].fd, &event, sizeof(event));
322 if(res < (int)sizeof(event))
323 {
324 fprintf(stderr, "could not get event\n");
325 }
326 if(event.type==1)
327 {
328 if(event.code==KEYCODE_NEXT)
329 {
330 puts("rockbox!");
331 return 1;
332 }
333 else if(event.code==KEYCODE_PREV)
334 {
335 puts("mango!");
336 return 0;
337 }
338 else if(event.code==KEYCODE_PWR || event.code==KEYCODE_PWR_LONG)
339 {
340 reboot(LINUX_REBOOT_CMD_POWER_OFF);
341 }
342 }
343 else if(event.type==3)
344 {
345 if(event.code==53) //x coord
346 {
347 if(event.value<160)
348 {
349 puts("mango!");
350 return 0;
351 }
352 else
353 {
354 puts("rockbox!");
355 return 1;
356 }
357 }
358 }
359 }
360 }
361 }
362 return true;
363}
364
365bool check_for_hold()
366{
367 FILE *f = fopen("/sys/class/axppower/holdkey", "r");
368 char x;
369 fscanf(f, "%c", &x);
370 fclose(f);
371
372 if(x & KEY_HOLD_OFF)
373 return false;
374 else
375 return true;
376}
377
378int main(int argc, char **argv)
379{
380 FILE *f;
381 int last_chosen_player = -1;
382
383 f = fopen(PLAYER_FILE, "r");
384 if(f!=NULL)
385 {
386 fscanf(f, "%d", &last_chosen_player);
387 fclose(f);
388 }
389 bool ask = (access(VOLD_LINK, F_OK) == -1) || ((access(NOASK_FLAG, F_OK) == -1) && check_for_hold()) || (last_chosen_player==-1);
390
391 if(ask)
392 {
393 draw();
394 button_init_device();
395 int player_chosen_now = choose_player();
396
397 if(last_chosen_player!=player_chosen_now)
398 {
399 f = fopen(PLAYER_FILE, "w");
400 fprintf(f, "%d", player_chosen_now);
401 fclose(f);
402 }
403
404 if(last_chosen_player!=player_chosen_now || (access(VOLD_LINK, F_OK) == -1))
405 {
406 system("rm "VOLD_LINK);
407
408 if(player_chosen_now)
409 system("ln -s /system/bin/vold_rockbox "VOLD_LINK);
410 else
411 system("ln -s /system/bin/vold_original "VOLD_LINK);
412
413 system("touch "NOASK_FLAG);
414 system("reboot");
415 }
416 last_chosen_player = player_chosen_now;
417 }
418
419 system("rm "NOASK_FLAG);
420
421 while(1)
422 {
423 if(last_chosen_player)
424 {
425// system("/system/bin/openadb");
426 system("/system/rockbox/lib/rockbox");
427 }
428 else
429// system("/system/bin/closeadb");
430 system("/system/bin/MangoPlayer_original");
431
432 sleep(1);
433 }
434
435 return 0;
436}
437
438
439
diff --git a/rbutil/ibassoboot/jni/qdbmp.c b/rbutil/ibassoboot/jni/qdbmp.c
new file mode 100644
index 0000000000..fd1337277d
--- /dev/null
+++ b/rbutil/ibassoboot/jni/qdbmp.c
@@ -0,0 +1,798 @@
1#include "qdbmp.h"
2#include <stdlib.h>
3#include <string.h>
4
5
6/* Bitmap header */
7typedef struct _BMP_Header
8{
9 USHORT Magic; /* Magic identifier: "BM" */
10 UINT FileSize; /* Size of the BMP file in bytes */
11 USHORT Reserved1; /* Reserved */
12 USHORT Reserved2; /* Reserved */
13 UINT DataOffset; /* Offset of image data relative to the file's start */
14 UINT HeaderSize; /* Size of the header in bytes */
15 UINT Width; /* Bitmap's width */
16 UINT Height; /* Bitmap's height */
17 USHORT Planes; /* Number of color planes in the bitmap */
18 USHORT BitsPerPixel; /* Number of bits per pixel */
19 UINT CompressionType; /* Compression type */
20 UINT ImageDataSize; /* Size of uncompressed image's data */
21 UINT HPixelsPerMeter; /* Horizontal resolution (pixels per meter) */
22 UINT VPixelsPerMeter; /* Vertical resolution (pixels per meter) */
23 UINT ColorsUsed; /* Number of color indexes in the color table that are actually used by the bitmap */
24 UINT ColorsRequired; /* Number of color indexes that are required for displaying the bitmap */
25} BMP_Header;
26
27
28/* Private data structure */
29struct _BMP
30{
31 BMP_Header Header;
32 UCHAR* Palette;
33 UCHAR* Data;
34};
35
36
37/* Holds the last error code */
38static BMP_STATUS BMP_LAST_ERROR_CODE = 0;
39
40
41/* Error description strings */
42static const char* BMP_ERROR_STRING[] =
43{
44 "",
45 "General error",
46 "Could not allocate enough memory to complete the operation",
47 "File input/output error",
48 "File not found",
49 "File is not a supported BMP variant (must be uncompressed 8, 24 or 32 BPP)",
50 "File is not a valid BMP image",
51 "An argument is invalid or out of range",
52 "The requested action is not compatible with the BMP's type"
53};
54
55
56/* Size of the palette data for 8 BPP bitmaps */
57#define BMP_PALETTE_SIZE ( 256 * 4 )
58
59
60
61/*********************************** Forward declarations **********************************/
62int ReadHeader ( BMP* bmp, FILE* f );
63int WriteHeader ( BMP* bmp, FILE* f );
64
65int ReadUINT ( UINT* x, FILE* f );
66int ReadUSHORT ( USHORT *x, FILE* f );
67
68int WriteUINT ( UINT x, FILE* f );
69int WriteUSHORT ( USHORT x, FILE* f );
70
71
72
73
74
75
76/*********************************** Public methods **********************************/
77
78
79/**************************************************************
80 Creates a blank BMP image with the specified dimensions
81 and bit depth.
82**************************************************************/
83BMP* BMP_Create( UINT width, UINT height, USHORT depth )
84{
85 BMP* bmp;
86 int bytes_per_pixel = depth >> 3;
87 UINT bytes_per_row;
88
89 if ( height <= 0 || width <= 0 )
90 {
91 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
92 return NULL;
93 }
94
95 if ( depth != 8 && depth != 24 && depth != 32 )
96 {
97 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED;
98 return NULL;
99 }
100
101
102 /* Allocate the bitmap data structure */
103 bmp = calloc( 1, sizeof( BMP ) );
104 if ( bmp == NULL )
105 {
106 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
107 return NULL;
108 }
109
110
111 /* Set header' default values */
112 bmp->Header.Magic = 0x4D42;
113 bmp->Header.Reserved1 = 0;
114 bmp->Header.Reserved2 = 0;
115 bmp->Header.HeaderSize = 40;
116 bmp->Header.Planes = 1;
117 bmp->Header.CompressionType = 0;
118 bmp->Header.HPixelsPerMeter = 0;
119 bmp->Header.VPixelsPerMeter = 0;
120 bmp->Header.ColorsUsed = 0;
121 bmp->Header.ColorsRequired = 0;
122
123
124 /* Calculate the number of bytes used to store a single image row. This is always
125 rounded up to the next multiple of 4. */
126 bytes_per_row = width * bytes_per_pixel;
127 bytes_per_row += ( bytes_per_row % 4 ? 4 - bytes_per_row % 4 : 0 );
128
129
130 /* Set header's image specific values */
131 bmp->Header.Width = width;
132 bmp->Header.Height = height;
133 bmp->Header.BitsPerPixel = depth;
134 bmp->Header.ImageDataSize = bytes_per_row * height;
135 bmp->Header.FileSize = bmp->Header.ImageDataSize + 54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 );
136 bmp->Header.DataOffset = 54 + ( depth == 8 ? BMP_PALETTE_SIZE : 0 );
137
138
139 /* Allocate palette */
140 if ( bmp->Header.BitsPerPixel == 8 )
141 {
142 bmp->Palette = (UCHAR*) calloc( BMP_PALETTE_SIZE, sizeof( UCHAR ) );
143 if ( bmp->Palette == NULL )
144 {
145 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
146 free( bmp );
147 return NULL;
148 }
149 }
150 else
151 {
152 bmp->Palette = NULL;
153 }
154
155
156 /* Allocate pixels */
157 bmp->Data = (UCHAR*) calloc( bmp->Header.ImageDataSize, sizeof( UCHAR ) );
158 if ( bmp->Data == NULL )
159 {
160 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
161 free( bmp->Palette );
162 free( bmp );
163 return NULL;
164 }
165
166
167 BMP_LAST_ERROR_CODE = BMP_OK;
168
169 return bmp;
170}
171
172
173/**************************************************************
174 Frees all the memory used by the specified BMP image.
175**************************************************************/
176void BMP_Free( BMP* bmp )
177{
178 if ( bmp == NULL )
179 {
180 return;
181 }
182
183 if ( bmp->Palette != NULL )
184 {
185 free( bmp->Palette );
186 }
187
188 if ( bmp->Data != NULL )
189 {
190 free( bmp->Data );
191 }
192
193 free( bmp );
194
195 BMP_LAST_ERROR_CODE = BMP_OK;
196}
197
198
199/**************************************************************
200 Reads the specified BMP image file.
201**************************************************************/
202BMP* BMP_ReadFile( const char* filename )
203{
204 BMP* bmp;
205 FILE* f;
206
207 if ( filename == NULL )
208 {
209 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
210 return NULL;
211 }
212
213
214 /* Allocate */
215 bmp = calloc( 1, sizeof( BMP ) );
216 if ( bmp == NULL )
217 {
218 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
219 return NULL;
220 }
221
222
223 /* Open file */
224 f = fopen( filename, "rb" );
225 if ( f == NULL )
226 {
227 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND;
228 free( bmp );
229 return NULL;
230 }
231
232
233 /* Read header */
234 if ( ReadHeader( bmp, f ) != BMP_OK || bmp->Header.Magic != 0x4D42 )
235 {
236 BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
237 fclose( f );
238 free( bmp );
239 return NULL;
240 }
241
242
243 /* Verify that the bitmap variant is supported */
244 if ( ( bmp->Header.BitsPerPixel != 32 && bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 8 )
245 || bmp->Header.CompressionType != 0 || bmp->Header.HeaderSize != 40 )
246 {
247 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_SUPPORTED;
248 fclose( f );
249 free( bmp );
250 return NULL;
251 }
252
253
254 /* Allocate and read palette */
255 if ( bmp->Header.BitsPerPixel == 8 )
256 {
257 bmp->Palette = (UCHAR*) malloc( BMP_PALETTE_SIZE * sizeof( UCHAR ) );
258 if ( bmp->Palette == NULL )
259 {
260 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
261 fclose( f );
262 free( bmp );
263 return NULL;
264 }
265
266 if ( fread( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f ) != BMP_PALETTE_SIZE )
267 {
268 BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
269 fclose( f );
270 free( bmp->Palette );
271 free( bmp );
272 return NULL;
273 }
274 }
275 else /* Not an indexed image */
276 {
277 bmp->Palette = NULL;
278 }
279
280
281 /* Allocate memory for image data */
282 bmp->Data = (UCHAR*) malloc( bmp->Header.ImageDataSize );
283 if ( bmp->Data == NULL )
284 {
285 BMP_LAST_ERROR_CODE = BMP_OUT_OF_MEMORY;
286 fclose( f );
287 free( bmp->Palette );
288 free( bmp );
289 return NULL;
290 }
291
292
293 /* Read image data */
294 if ( fread( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) != bmp->Header.ImageDataSize )
295 {
296 BMP_LAST_ERROR_CODE = BMP_FILE_INVALID;
297 fclose( f );
298 free( bmp->Data );
299 free( bmp->Palette );
300 free( bmp );
301 return NULL;
302 }
303
304
305 fclose( f );
306
307 BMP_LAST_ERROR_CODE = BMP_OK;
308
309 return bmp;
310}
311
312
313/**************************************************************
314 Writes the BMP image to the specified file.
315**************************************************************/
316void BMP_WriteFile( BMP* bmp, const char* filename )
317{
318 FILE* f;
319
320 if ( filename == NULL )
321 {
322 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
323 return;
324 }
325
326
327 /* Open file */
328 f = fopen( filename, "wb" );
329 if ( f == NULL )
330 {
331 BMP_LAST_ERROR_CODE = BMP_FILE_NOT_FOUND;
332 return;
333 }
334
335
336 /* Write header */
337 if ( WriteHeader( bmp, f ) != BMP_OK )
338 {
339 BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
340 fclose( f );
341 return;
342 }
343
344
345 /* Write palette */
346 if ( bmp->Palette )
347 {
348 if ( fwrite( bmp->Palette, sizeof( UCHAR ), BMP_PALETTE_SIZE, f ) != BMP_PALETTE_SIZE )
349 {
350 BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
351 fclose( f );
352 return;
353 }
354 }
355
356
357 /* Write data */
358 if ( fwrite( bmp->Data, sizeof( UCHAR ), bmp->Header.ImageDataSize, f ) != bmp->Header.ImageDataSize )
359 {
360 BMP_LAST_ERROR_CODE = BMP_IO_ERROR;
361 fclose( f );
362 return;
363 }
364
365
366 BMP_LAST_ERROR_CODE = BMP_OK;
367 fclose( f );
368}
369
370
371/**************************************************************
372 Returns the image's width.
373**************************************************************/
374UINT BMP_GetWidth( BMP* bmp )
375{
376 if ( bmp == NULL )
377 {
378 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
379 return -1;
380 }
381
382 BMP_LAST_ERROR_CODE = BMP_OK;
383
384 return ( bmp->Header.Width );
385}
386
387
388/**************************************************************
389 Returns the image's height.
390**************************************************************/
391UINT BMP_GetHeight( BMP* bmp )
392{
393 if ( bmp == NULL )
394 {
395 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
396 return -1;
397 }
398
399 BMP_LAST_ERROR_CODE = BMP_OK;
400
401 return ( bmp->Header.Height );
402}
403
404
405/**************************************************************
406 Returns the image's color depth (bits per pixel).
407**************************************************************/
408USHORT BMP_GetDepth( BMP* bmp )
409{
410 if ( bmp == NULL )
411 {
412 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
413 return -1;
414 }
415
416 BMP_LAST_ERROR_CODE = BMP_OK;
417
418 return ( bmp->Header.BitsPerPixel );
419}
420
421
422/**************************************************************
423 Populates the arguments with the specified pixel's RGB
424 values.
425**************************************************************/
426void BMP_GetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b )
427{
428 UCHAR* pixel;
429 UINT bytes_per_row;
430 UCHAR bytes_per_pixel;
431
432 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
433 {
434 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
435 }
436 else
437 {
438 BMP_LAST_ERROR_CODE = BMP_OK;
439
440 bytes_per_pixel = bmp->Header.BitsPerPixel >> 3;
441
442 /* Row's size is rounded up to the next multiple of 4 bytes */
443 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
444
445 /* Calculate the location of the relevant pixel (rows are flipped) */
446 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x * bytes_per_pixel );
447
448
449 /* In indexed color mode the pixel's value is an index within the palette */
450 if ( bmp->Header.BitsPerPixel == 8 )
451 {
452 pixel = bmp->Palette + *pixel * 4;
453 }
454
455 /* Note: colors are stored in BGR order */
456 if ( r ) *r = *( pixel + 2 );
457 if ( g ) *g = *( pixel + 1 );
458 if ( b ) *b = *( pixel + 0 );
459 }
460}
461
462
463/**************************************************************
464 Sets the specified pixel's RGB values.
465**************************************************************/
466void BMP_SetPixelRGB( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b )
467{
468 UCHAR* pixel;
469 UINT bytes_per_row;
470 UCHAR bytes_per_pixel;
471
472 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
473 {
474 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
475 }
476
477 else if ( bmp->Header.BitsPerPixel != 24 && bmp->Header.BitsPerPixel != 32 )
478 {
479 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
480 }
481
482 else
483 {
484 BMP_LAST_ERROR_CODE = BMP_OK;
485
486 bytes_per_pixel = bmp->Header.BitsPerPixel >> 3;
487
488 /* Row's size is rounded up to the next multiple of 4 bytes */
489 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
490
491 /* Calculate the location of the relevant pixel (rows are flipped) */
492 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x * bytes_per_pixel );
493
494 /* Note: colors are stored in BGR order */
495 *( pixel + 2 ) = r;
496 *( pixel + 1 ) = g;
497 *( pixel + 0 ) = b;
498 }
499}
500
501
502/**************************************************************
503 Gets the specified pixel's color index.
504**************************************************************/
505void BMP_GetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR* val )
506{
507 UCHAR* pixel;
508 UINT bytes_per_row;
509
510 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
511 {
512 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
513 }
514
515 else if ( bmp->Header.BitsPerPixel != 8 )
516 {
517 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
518 }
519
520 else
521 {
522 BMP_LAST_ERROR_CODE = BMP_OK;
523
524 /* Row's size is rounded up to the next multiple of 4 bytes */
525 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
526
527 /* Calculate the location of the relevant pixel */
528 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x );
529
530
531 if ( val ) *val = *pixel;
532 }
533}
534
535
536/**************************************************************
537 Sets the specified pixel's color index.
538**************************************************************/
539void BMP_SetPixelIndex( BMP* bmp, UINT x, UINT y, UCHAR val )
540{
541 UCHAR* pixel;
542 UINT bytes_per_row;
543
544 if ( bmp == NULL || x < 0 || x >= bmp->Header.Width || y < 0 || y >= bmp->Header.Height )
545 {
546 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
547 }
548
549 else if ( bmp->Header.BitsPerPixel != 8 )
550 {
551 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
552 }
553
554 else
555 {
556 BMP_LAST_ERROR_CODE = BMP_OK;
557
558 /* Row's size is rounded up to the next multiple of 4 bytes */
559 bytes_per_row = bmp->Header.ImageDataSize / bmp->Header.Height;
560
561 /* Calculate the location of the relevant pixel */
562 pixel = bmp->Data + ( ( bmp->Header.Height - y - 1 ) * bytes_per_row + x );
563
564 *pixel = val;
565 }
566}
567
568
569/**************************************************************
570 Gets the color value for the specified palette index.
571**************************************************************/
572void BMP_GetPaletteColor( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b )
573{
574 if ( bmp == NULL )
575 {
576 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
577 }
578
579 else if ( bmp->Header.BitsPerPixel != 8 )
580 {
581 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
582 }
583
584 else
585 {
586 if ( r ) *r = *( bmp->Palette + index * 4 + 2 );
587 if ( g ) *g = *( bmp->Palette + index * 4 + 1 );
588 if ( b ) *b = *( bmp->Palette + index * 4 + 0 );
589
590 BMP_LAST_ERROR_CODE = BMP_OK;
591 }
592}
593
594
595/**************************************************************
596 Sets the color value for the specified palette index.
597**************************************************************/
598void BMP_SetPaletteColor( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b )
599{
600 if ( bmp == NULL )
601 {
602 BMP_LAST_ERROR_CODE = BMP_INVALID_ARGUMENT;
603 }
604
605 else if ( bmp->Header.BitsPerPixel != 8 )
606 {
607 BMP_LAST_ERROR_CODE = BMP_TYPE_MISMATCH;
608 }
609
610 else
611 {
612 *( bmp->Palette + index * 4 + 2 ) = r;
613 *( bmp->Palette + index * 4 + 1 ) = g;
614 *( bmp->Palette + index * 4 + 0 ) = b;
615
616 BMP_LAST_ERROR_CODE = BMP_OK;
617 }
618}
619
620
621/**************************************************************
622 Returns the last error code.
623**************************************************************/
624BMP_STATUS BMP_GetError()
625{
626 return BMP_LAST_ERROR_CODE;
627}
628
629
630/**************************************************************
631 Returns a description of the last error code.
632**************************************************************/
633const char* BMP_GetErrorDescription()
634{
635 if ( BMP_LAST_ERROR_CODE > 0 && BMP_LAST_ERROR_CODE < BMP_ERROR_NUM )
636 {
637 return BMP_ERROR_STRING[ BMP_LAST_ERROR_CODE ];
638 }
639 else
640 {
641 return NULL;
642 }
643}
644
645
646
647
648
649/*********************************** Private methods **********************************/
650
651
652/**************************************************************
653 Reads the BMP file's header into the data structure.
654 Returns BMP_OK on success.
655**************************************************************/
656int ReadHeader( BMP* bmp, FILE* f )
657{
658 if ( bmp == NULL || f == NULL )
659 {
660 return BMP_INVALID_ARGUMENT;
661 }
662
663 /* The header's fields are read one by one, and converted from the format's
664 little endian to the system's native representation. */
665 if ( !ReadUSHORT( &( bmp->Header.Magic ), f ) ) return BMP_IO_ERROR;
666 if ( !ReadUINT( &( bmp->Header.FileSize ), f ) ) return BMP_IO_ERROR;
667 if ( !ReadUSHORT( &( bmp->Header.Reserved1 ), f ) ) return BMP_IO_ERROR;
668 if ( !ReadUSHORT( &( bmp->Header.Reserved2 ), f ) ) return BMP_IO_ERROR;
669 if ( !ReadUINT( &( bmp->Header.DataOffset ), f ) ) return BMP_IO_ERROR;
670 if ( !ReadUINT( &( bmp->Header.HeaderSize ), f ) ) return BMP_IO_ERROR;
671 if ( !ReadUINT( &( bmp->Header.Width ), f ) ) return BMP_IO_ERROR;
672 if ( !ReadUINT( &( bmp->Header.Height ), f ) ) return BMP_IO_ERROR;
673 if ( !ReadUSHORT( &( bmp->Header.Planes ), f ) ) return BMP_IO_ERROR;
674 if ( !ReadUSHORT( &( bmp->Header.BitsPerPixel ), f ) ) return BMP_IO_ERROR;
675 if ( !ReadUINT( &( bmp->Header.CompressionType ), f ) ) return BMP_IO_ERROR;
676 if ( !ReadUINT( &( bmp->Header.ImageDataSize ), f ) ) return BMP_IO_ERROR;
677 if ( !ReadUINT( &( bmp->Header.HPixelsPerMeter ), f ) ) return BMP_IO_ERROR;
678 if ( !ReadUINT( &( bmp->Header.VPixelsPerMeter ), f ) ) return BMP_IO_ERROR;
679 if ( !ReadUINT( &( bmp->Header.ColorsUsed ), f ) ) return BMP_IO_ERROR;
680 if ( !ReadUINT( &( bmp->Header.ColorsRequired ), f ) ) return BMP_IO_ERROR;
681
682 return BMP_OK;
683}
684
685
686/**************************************************************
687 Writes the BMP file's header into the data structure.
688 Returns BMP_OK on success.
689**************************************************************/
690int WriteHeader( BMP* bmp, FILE* f )
691{
692 if ( bmp == NULL || f == NULL )
693 {
694 return BMP_INVALID_ARGUMENT;
695 }
696
697 /* The header's fields are written one by one, and converted to the format's
698 little endian representation. */
699 if ( !WriteUSHORT( bmp->Header.Magic, f ) ) return BMP_IO_ERROR;
700 if ( !WriteUINT( bmp->Header.FileSize, f ) ) return BMP_IO_ERROR;
701 if ( !WriteUSHORT( bmp->Header.Reserved1, f ) ) return BMP_IO_ERROR;
702 if ( !WriteUSHORT( bmp->Header.Reserved2, f ) ) return BMP_IO_ERROR;
703 if ( !WriteUINT( bmp->Header.DataOffset, f ) ) return BMP_IO_ERROR;
704 if ( !WriteUINT( bmp->Header.HeaderSize, f ) ) return BMP_IO_ERROR;
705 if ( !WriteUINT( bmp->Header.Width, f ) ) return BMP_IO_ERROR;
706 if ( !WriteUINT( bmp->Header.Height, f ) ) return BMP_IO_ERROR;
707 if ( !WriteUSHORT( bmp->Header.Planes, f ) ) return BMP_IO_ERROR;
708 if ( !WriteUSHORT( bmp->Header.BitsPerPixel, f ) ) return BMP_IO_ERROR;
709 if ( !WriteUINT( bmp->Header.CompressionType, f ) ) return BMP_IO_ERROR;
710 if ( !WriteUINT( bmp->Header.ImageDataSize, f ) ) return BMP_IO_ERROR;
711 if ( !WriteUINT( bmp->Header.HPixelsPerMeter, f ) ) return BMP_IO_ERROR;
712 if ( !WriteUINT( bmp->Header.VPixelsPerMeter, f ) ) return BMP_IO_ERROR;
713 if ( !WriteUINT( bmp->Header.ColorsUsed, f ) ) return BMP_IO_ERROR;
714 if ( !WriteUINT( bmp->Header.ColorsRequired, f ) ) return BMP_IO_ERROR;
715
716 return BMP_OK;
717}
718
719
720/**************************************************************
721 Reads a little-endian unsigned int from the file.
722 Returns non-zero on success.
723**************************************************************/
724int ReadUINT( UINT* x, FILE* f )
725{
726 UCHAR little[ 4 ]; /* BMPs use 32 bit ints */
727
728 if ( x == NULL || f == NULL )
729 {
730 return 0;
731 }
732
733 if ( fread( little, 4, 1, f ) != 1 )
734 {
735 return 0;
736 }
737
738 *x = ( little[ 3 ] << 24 | little[ 2 ] << 16 | little[ 1 ] << 8 | little[ 0 ] );
739
740 return 1;
741}
742
743
744/**************************************************************
745 Reads a little-endian unsigned short int from the file.
746 Returns non-zero on success.
747**************************************************************/
748int ReadUSHORT( USHORT *x, FILE* f )
749{
750 UCHAR little[ 2 ]; /* BMPs use 16 bit shorts */
751
752 if ( x == NULL || f == NULL )
753 {
754 return 0;
755 }
756
757 if ( fread( little, 2, 1, f ) != 1 )
758 {
759 return 0;
760 }
761
762 *x = ( little[ 1 ] << 8 | little[ 0 ] );
763
764 return 1;
765}
766
767
768/**************************************************************
769 Writes a little-endian unsigned int to the file.
770 Returns non-zero on success.
771**************************************************************/
772int WriteUINT( UINT x, FILE* f )
773{
774 UCHAR little[ 4 ]; /* BMPs use 32 bit ints */
775
776 little[ 3 ] = (UCHAR)( ( x & 0xff000000 ) >> 24 );
777 little[ 2 ] = (UCHAR)( ( x & 0x00ff0000 ) >> 16 );
778 little[ 1 ] = (UCHAR)( ( x & 0x0000ff00 ) >> 8 );
779 little[ 0 ] = (UCHAR)( ( x & 0x000000ff ) >> 0 );
780
781 return ( f && fwrite( little, 4, 1, f ) == 1 );
782}
783
784
785/**************************************************************
786 Writes a little-endian unsigned short int to the file.
787 Returns non-zero on success.
788**************************************************************/
789int WriteUSHORT( USHORT x, FILE* f )
790{
791 UCHAR little[ 2 ]; /* BMPs use 16 bit shorts */
792
793 little[ 1 ] = (UCHAR)( ( x & 0xff00 ) >> 8 );
794 little[ 0 ] = (UCHAR)( ( x & 0x00ff ) >> 0 );
795
796 return ( f && fwrite( little, 2, 1, f ) == 1 );
797}
798
diff --git a/rbutil/ibassoboot/jni/qdbmp.h b/rbutil/ibassoboot/jni/qdbmp.h
new file mode 100644
index 0000000000..d6c0e6c452
--- /dev/null
+++ b/rbutil/ibassoboot/jni/qdbmp.h
@@ -0,0 +1,133 @@
1#ifndef _BMP_H_
2#define _BMP_H_
3
4
5/**************************************************************
6
7 QDBMP - Quick n' Dirty BMP
8
9 v1.0.0 - 2007-04-07
10 http://qdbmp.sourceforge.net
11
12
13 The library supports the following BMP variants:
14 1. Uncompressed 32 BPP (alpha values are ignored)
15 2. Uncompressed 24 BPP
16 3. Uncompressed 8 BPP (indexed color)
17
18 QDBMP is free and open source software, distributed
19 under the MIT licence.
20
21 Copyright (c) 2007 Chai Braudo (braudo@users.sourceforge.net)
22
23 Permission is hereby granted, free of charge, to any person obtaining a copy
24 of this software and associated documentation files (the "Software"), to deal
25 in the Software without restriction, including without limitation the rights
26 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 copies of the Software, and to permit persons to whom the Software is
28 furnished to do so, subject to the following conditions:
29
30 The above copyright notice and this permission notice shall be included in
31 all copies or substantial portions of the Software.
32
33 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 THE SOFTWARE.
40
41**************************************************************/
42
43#include <stdio.h>
44
45
46
47/* Type definitions */
48#ifndef UINT
49 #define UINT unsigned long int
50#endif
51
52#ifndef USHORT
53 #define USHORT unsigned short
54#endif
55
56#ifndef UCHAR
57 #define UCHAR unsigned char
58#endif
59
60
61/* Version */
62#define QDBMP_VERSION_MAJOR 1
63#define QDBMP_VERSION_MINOR 0
64#define QDBMP_VERSION_PATCH 1
65
66
67/* Error codes */
68typedef enum
69{
70 BMP_OK = 0, /* No error */
71 BMP_ERROR, /* General error */
72 BMP_OUT_OF_MEMORY, /* Could not allocate enough memory to complete the operation */
73 BMP_IO_ERROR, /* General input/output error */
74 BMP_FILE_NOT_FOUND, /* File not found */
75 BMP_FILE_NOT_SUPPORTED, /* File is not a supported BMP variant */
76 BMP_FILE_INVALID, /* File is not a BMP image or is an invalid BMP */
77 BMP_INVALID_ARGUMENT, /* An argument is invalid or out of range */
78 BMP_TYPE_MISMATCH, /* The requested action is not compatible with the BMP's type */
79 BMP_ERROR_NUM
80} BMP_STATUS;
81
82
83/* Bitmap image */
84typedef struct _BMP BMP;
85
86
87
88
89/*********************************** Public methods **********************************/
90
91
92/* Construction/destruction */
93BMP* BMP_Create ( UINT width, UINT height, USHORT depth );
94void BMP_Free ( BMP* bmp );
95
96
97/* I/O */
98BMP* BMP_ReadFile ( const char* filename );
99void BMP_WriteFile ( BMP* bmp, const char* filename );
100
101
102/* Meta info */
103UINT BMP_GetWidth ( BMP* bmp );
104UINT BMP_GetHeight ( BMP* bmp );
105USHORT BMP_GetDepth ( BMP* bmp );
106
107
108/* Pixel access */
109void BMP_GetPixelRGB ( BMP* bmp, UINT x, UINT y, UCHAR* r, UCHAR* g, UCHAR* b );
110void BMP_SetPixelRGB ( BMP* bmp, UINT x, UINT y, UCHAR r, UCHAR g, UCHAR b );
111void BMP_GetPixelIndex ( BMP* bmp, UINT x, UINT y, UCHAR* val );
112void BMP_SetPixelIndex ( BMP* bmp, UINT x, UINT y, UCHAR val );
113
114
115/* Palette handling */
116void BMP_GetPaletteColor ( BMP* bmp, UCHAR index, UCHAR* r, UCHAR* g, UCHAR* b );
117void BMP_SetPaletteColor ( BMP* bmp, UCHAR index, UCHAR r, UCHAR g, UCHAR b );
118
119
120/* Error handling */
121BMP_STATUS BMP_GetError ();
122const char* BMP_GetErrorDescription ();
123
124
125/* Useful macro that may be used after each BMP operation to check for an error */
126#define BMP_CHECK_ERROR( output_file, return_value ) \
127 if ( BMP_GetError() != BMP_OK ) \
128 { \
129 fprintf( ( output_file ), "BMP error: %s\n", BMP_GetErrorDescription() ); \
130 return( return_value ); \
131 } \
132
133#endif
diff --git a/tools/configure b/tools/configure
index 12025ba942..20b9095f73 100755
--- a/tools/configure
+++ b/tools/configure
@@ -664,14 +664,19 @@ androidcc () {
664 exit 664 exit
665 fi 665 fi
666 if [ -z "$ANDROID_NDK_PATH" ]; then 666 if [ -z "$ANDROID_NDK_PATH" ]; then
667 echo "ERROR: You need the Android NDK installed (r5 or higher) and have the ANDROID_NDK_PATH" 667 echo "ERROR: You need the Android NDK installed (r16 or higher) and have the ANDROID_NDK_PATH"
668 echo "environment variable point to the root directory of the Android NDK." 668 echo "environment variable point to the root directory of the Android NDK."
669 exit 669 exit
670 fi 670 fi
671 buildhost=$(uname | tr "[:upper:]" "[:lower:]") 671 buildhost=$(uname | tr "[:upper:]" "[:lower:]")
672 GCCOPTS=`echo $CCOPTS | sed -e s/-ffreestanding// -e s/-nostdlib// -e s/-Wundef//` 672 GCCOPTS=`echo $CCOPTS | sed -e s/-ffreestanding// -e s/-nostdlib// -e s/-Wundef//`
673 LDOPTS="$LDOPTS -Wl,-soname,librockbox.so -shared -ldl -llog" 673 LDOPTS="$LDOPTS -ldl -llog"
674 GLOBAL_LDOPTS="-Wl,-z,defs -Wl,-z,noexecstack -shared" 674 if [ "$modelname" != "ibassodx50" ] && [ "$modelname" != "ibassodx90" ]; then
675 LDOPTS="$LDOPTS -Wl,-soname,librockbox.so -shared"
676 fi
677 SHARED_LDFLAG="-shared"
678 SHARED_CFLAGS=''
679 GLOBAL_LDOPTS="-Wl,-z,defs -Wl,-z,noexecstack"
675 ANDROID_ARCH=$1 # for android.make too 680 ANDROID_ARCH=$1 # for android.make too
676 gccchoice="4.6" 681 gccchoice="4.6"
677 # arch dependant stuff 682 # arch dependant stuff
@@ -683,8 +688,8 @@ androidcc () {
683 # threads work fine so far 688 # threads work fine so far
684 thread_support="ASSEMBLER_THREADS" 689 thread_support="ASSEMBLER_THREADS"
685 GCCOPTS="$GCCOPTS -march=armv5te -mtune=xscale -msoft-float -fomit-frame-pointer \ 690 GCCOPTS="$GCCOPTS -march=armv5te -mtune=xscale -msoft-float -fomit-frame-pointer \
686 --sysroot=$ANDROID_NDK_PATH/platforms/android-5/arch-arm" 691 --sysroot=$ANDROID_NDK_PATH/platforms/android-16/arch-arm"
687 LDOPTS="$LDOPTS --sysroot=$ANDROID_NDK_PATH/platforms/android-5/arch-arm" 692 LDOPTS="$LDOPTS --sysroot=$ANDROID_NDK_PATH/platforms/android-16/arch-arm"
688 ;; 693 ;;
689 mips) 694 mips)
690 endian="little" 695 endian="little"
@@ -1336,13 +1341,10 @@ cat <<EOF
1336 203) Nokia N900 212) MA8 220) NWZ-E370/E380 series 1341 203) Nokia N900 212) MA8 220) NWZ-E370/E380 series
1337 204) Pandora 213) MA8C 221) NWZ-E360 series 1342 204) Pandora 213) MA8C 221) NWZ-E360 series
1338 205) Samsung YP-R0 1343 205) Samsung YP-R0
1339 206) Android MIPS 1344 206) Android MIPS ==IHIFI== ==iBasso==
1340 207) Android x86 1345 207) Android x86 230) 760 232) DX50
1341 208) Samsung YP-R1 1346 208) Samsung YP-R1 231) 960 233) DX90
1342 1347
1343==IHIFI==
1344 230) 760
1345 231) 960
1346 1348
1347EOF 1349EOF
1348 1350
@@ -3744,6 +3746,62 @@ fi
3744 t_model="ihifi" 3746 t_model="ihifi"
3745 ;; 3747 ;;
3746 3748
3749 232|ibassodx50)
3750 application="yes"
3751 target_id=94
3752 modelname="ibassodx50"
3753 target="DX50"
3754 app_type="android_standalone"
3755 lcd_orientation="landscape"
3756 sharedir="/system/rockbox/app_rockbox/rockbox"
3757 bindir="/system/rockbox/lib"
3758 libdir="/system/rockbox/app_rockbox"
3759 memory=32
3760 uname=`uname`
3761 androidcc armeabi
3762 tool="cp "
3763 boottool="cp "
3764 bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
3765 bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
3766 output="rockbox"
3767 bootoutput="rockbox"
3768 appextra="recorder:gui:radio:hosted/android"
3769 plugins="yes"
3770 swcodec="yes"
3771 # architecture, manufacturer and model for the target-tree build
3772 t_cpu="hosted"
3773 t_manufacturer="android"
3774 t_model="dx50"
3775 ;;
3776
3777 233|ibassodx90)
3778 application="yes"
3779 target_id=95
3780 modelname="ibassodx90"
3781 target="DX90"
3782 app_type="android_standalone"
3783 lcd_orientation="landscape"
3784 sharedir="/system/rockbox/app_rockbox/rockbox"
3785 bindir="/system/rockbox/lib"
3786 libdir="/system/rockbox/app_rockbox"
3787 memory=32
3788 uname=`uname`
3789 androidcc armeabi
3790 tool="cp "
3791 boottool="cp "
3792 bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
3793 bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
3794 output="rockbox"
3795 bootoutput="rockbox"
3796 appextra="recorder:gui:radio:hosted/android"
3797 plugins="yes"
3798 swcodec="yes"
3799 # architecture, manufacturer and model for the target-tree build
3800 t_cpu="hosted"
3801 t_manufacturer="android"
3802 t_model="dx50"
3803 ;;
3804
3747 *) 3805 *)
3748 echo "Please select a supported target platform!" 3806 echo "Please select a supported target platform!"
3749 exit 7 3807 exit 7