1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2013 Google, Inc
8 #include <linux/input.h>
10 #include <asm/state.h>
13 * struct buf_info - a data buffer holding audio data
15 * @pos: Current position playing in audio buffer
16 * @size: Size of data in audio buffer (0=empty)
17 * @alloced: Allocated size of audio buffer (max size it can hold)
27 static struct sdl_info {
38 struct buf_info buf[2];
42 static void sandbox_sdl_poll_events(void)
45 * We don't want to include common.h in this file since it uses
46 * system headers. So add a declation here.
48 extern void reset_cpu(unsigned long addr);
51 while (SDL_PollEvent(&event)) {
54 puts("LCD window closed - quitting\n");
61 static int sandbox_sdl_ensure_init(void)
64 if (SDL_Init(0) < 0) {
65 printf("Unable to initialize SDL: %s\n",
77 int sandbox_sdl_init_display(int width, int height, int log2_bpp)
79 struct sandbox_state *state = state_get_current();
82 if (!width || !state->show_lcd)
84 err = sandbox_sdl_ensure_init();
87 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
88 printf("Unable to initialize SDL LCD: %s\n", SDL_GetError());
91 SDL_WM_SetCaption("U-Boot", "U-Boot");
95 sdl.depth = 1 << log2_bpp;
96 sdl.pitch = sdl.width * sdl.depth / 8;
97 sdl.screen = SDL_SetVideoMode(width, height, 0, 0);
98 sandbox_sdl_poll_events();
103 int sandbox_sdl_sync(void *lcd_base)
107 frame = SDL_CreateRGBSurfaceFrom(lcd_base, sdl.width, sdl.height,
108 sdl.depth, sdl.pitch,
109 0x1f << 11, 0x3f << 5, 0x1f << 0, 0);
110 SDL_BlitSurface(frame, NULL, sdl.screen, NULL);
111 SDL_FreeSurface(frame);
112 SDL_UpdateRect(sdl.screen, 0, 0, 0, 0);
113 sandbox_sdl_poll_events();
119 #define NUM_SDL_CODES (SDLK_UNDO + 1)
121 static int16_t sdl_to_keycode[NUM_SDL_CODES] = {
123 NONE, NONE, NONE, NONE, NONE,
124 NONE, NONE, NONE, KEY_BACKSPACE, KEY_TAB,
125 NONE, NONE, NONE, KEY_ENTER, NONE,
126 NONE, NONE, NONE, NONE, KEY_POWER, /* use PAUSE as POWER */
129 NONE, NONE, NONE, NONE, NONE,
130 NONE, NONE, KEY_ESC, NONE, NONE,
131 NONE, NONE, KEY_SPACE, NONE, NONE,
132 NONE, NONE, NONE, NONE, NONE,
135 NONE, NONE, NONE, NONE, KEY_COMMA,
136 KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1,
137 KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
138 KEY_7, KEY_8, KEY_9, NONE, KEY_SEMICOLON,
141 NONE, KEY_EQUAL, NONE, NONE, NONE,
142 NONE, NONE, NONE, NONE, NONE,
143 NONE, NONE, NONE, NONE, NONE,
144 NONE, NONE, NONE, NONE, NONE,
147 NONE, NONE, NONE, NONE, NONE,
148 NONE, NONE, NONE, NONE, NONE,
149 NONE, NONE, KEY_BACKSLASH, NONE, NONE,
150 NONE, KEY_GRAVE, KEY_A, KEY_B, KEY_C,
153 KEY_D, KEY_E, KEY_F, KEY_G, KEY_H,
154 KEY_I, KEY_J, KEY_K, KEY_L, KEY_M,
155 KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R,
156 KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
159 KEY_X, KEY_Y, KEY_Z, NONE, NONE,
160 NONE, NONE, KEY_DELETE, NONE, NONE,
161 NONE, NONE, NONE, NONE, NONE,
162 NONE, NONE, NONE, NONE, NONE,
165 NONE, NONE, NONE, NONE, NONE,
166 NONE, NONE, NONE, NONE, NONE,
167 NONE, NONE, NONE, NONE, NONE,
168 NONE, NONE, NONE, NONE, NONE,
171 NONE, NONE, NONE, NONE, NONE,
172 NONE, NONE, NONE, NONE, NONE,
173 NONE, NONE, NONE, NONE, NONE,
174 NONE, NONE, NONE, NONE, NONE,
177 NONE, NONE, NONE, NONE, NONE,
178 NONE, NONE, NONE, NONE, NONE,
179 NONE, NONE, NONE, NONE, NONE,
180 NONE, NONE, NONE, NONE, NONE,
183 NONE, NONE, NONE, NONE, NONE,
184 NONE, NONE, NONE, NONE, NONE,
185 NONE, NONE, NONE, NONE, NONE,
186 NONE, NONE, NONE, NONE, NONE,
189 NONE, NONE, NONE, NONE, NONE,
190 NONE, NONE, NONE, NONE, NONE,
191 NONE, NONE, NONE, NONE, NONE,
192 NONE, NONE, NONE, NONE, NONE,
195 NONE, NONE, NONE, NONE, NONE,
196 NONE, NONE, NONE, NONE, NONE,
197 NONE, NONE, NONE, NONE, NONE,
198 NONE, KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3,
201 KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8,
202 KEY_KP9, KEY_KPDOT, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS,
203 KEY_KPPLUS, KEY_KPENTER, KEY_KPEQUAL, KEY_UP, KEY_DOWN,
204 KEY_RIGHT, KEY_LEFT, KEY_INSERT, KEY_HOME, KEY_END,
207 KEY_PAGEUP, KEY_PAGEDOWN, KEY_F1, KEY_F2, KEY_F3,
208 KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8,
209 KEY_F9, KEY_F10, KEY_F11, KEY_F12, NONE,
210 NONE, NONE, NONE, NONE, NONE,
213 KEY_NUMLOCK, KEY_CAPSLOCK, KEY_SCROLLLOCK, KEY_RIGHTSHIFT,
215 KEY_RIGHTCTRL, KEY_LEFTCTRL, KEY_RIGHTALT, KEY_LEFTALT, KEY_RIGHTMETA,
216 KEY_LEFTMETA, NONE, KEY_FN, NONE, KEY_COMPOSE,
217 NONE, KEY_PRINT, KEY_SYSRQ, KEY_PAUSE, NONE,
223 int sandbox_sdl_scan_keys(int key[], int max_keys)
228 sandbox_sdl_poll_events();
229 keystate = SDL_GetKeyState(NULL);
230 for (i = count = 0; i < NUM_SDL_CODES; i++) {
231 if (count >= max_keys)
233 else if (keystate[i])
234 key[count++] = sdl_to_keycode[i];
240 int sandbox_sdl_key_pressed(int keycode)
242 int key[8]; /* allow up to 8 keys to be pressed at once */
246 count = sandbox_sdl_scan_keys(key, sizeof(key) / sizeof(key[0]));
247 for (i = 0; i < count; i++) {
248 if (key[i] == keycode)
255 void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len)
257 struct buf_info *buf;
261 for (i = 0; i < 2; i++) {
262 buf = &sdl.buf[sdl.cur_buf];
263 avail = buf->size - buf->pos;
265 sdl.cur_buf = 1 - sdl.cur_buf;
271 SDL_MixAudio(stream, buf->data + buf->pos, avail,
276 /* Move to next buffer if we are at the end */
277 if (buf->pos == buf->size)
284 int sandbox_sdl_sound_init(int rate, int channels)
286 SDL_AudioSpec wanted;
289 if (sandbox_sdl_ensure_init())
292 if (sdl.audio_active)
295 /* Set the audio format */
297 wanted.format = AUDIO_S16;
298 wanted.channels = channels;
299 wanted.samples = 1024; /* Good low-latency value for callback */
300 wanted.callback = sandbox_sdl_fill_audio;
301 wanted.userdata = NULL;
303 for (i = 0; i < 2; i++) {
304 struct buf_info *buf = &sdl.buf[i];
306 buf->alloced = sizeof(uint16_t) * wanted.freq * wanted.channels;
307 buf->data = malloc(buf->alloced);
309 printf("%s: Out of memory\n", __func__);
311 free(sdl.buf[0].data);
318 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
319 printf("Unable to initialize SDL audio: %s\n", SDL_GetError());
323 /* Open the audio device, forcing the desired format */
324 if (SDL_OpenAudio(&wanted, NULL) < 0) {
325 printf("Couldn't open audio: %s\n", SDL_GetError());
328 sdl.audio_active = true;
329 sdl.sample_rate = wanted.freq;
336 for (i = 0; i < 2; i++)
337 free(sdl.buf[i].data);
341 int sandbox_sdl_sound_play(const void *data, uint size)
343 struct buf_info *buf;
345 if (!sdl.audio_active)
354 if (size > buf->alloced)
357 memcpy(buf->data, data, size);
368 int sandbox_sdl_sound_stop(void)