sdl: remove deprecated API usage
In addition framebuffer resizing is now also supported. Fixes #2583.
This commit is contained in:
parent
86c1f65dfe
commit
6ca8f4c174
|
@ -0,0 +1,5 @@
|
||||||
|
SRC_CC = sdl_main.cc
|
||||||
|
|
||||||
|
LIBS += libc
|
||||||
|
|
||||||
|
vpath sdl_main.cc $(REP_DIR)/src/lib/sdl
|
|
@ -115,7 +115,7 @@ append boot_modules {
|
||||||
core init timer } [audio_drv_binary] { avplay
|
core init timer } [audio_drv_binary] { avplay
|
||||||
ld.lib.so libc.lib.so libm.lib.so pthread.lib.so zlib.lib.so sdl.lib.so
|
ld.lib.so libc.lib.so libm.lib.so pthread.lib.so zlib.lib.so sdl.lib.so
|
||||||
avfilter.lib.so avutil.lib.so avcodec.lib.so avformat.lib.so swscale.lib.so
|
avfilter.lib.so avutil.lib.so avcodec.lib.so avformat.lib.so swscale.lib.so
|
||||||
avresample.lib.so posix.lib.so
|
avresample.lib.so
|
||||||
mediafile
|
mediafile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ set boot_modules {
|
||||||
core init
|
core init
|
||||||
timer
|
timer
|
||||||
test-sdl
|
test-sdl
|
||||||
ld.lib.so libc.lib.so libm.lib.so sdl.lib.so pthread.lib.so posix.lib.so
|
ld.lib.so libc.lib.so libm.lib.so sdl.lib.so pthread.lib.so
|
||||||
}
|
}
|
||||||
|
|
||||||
# platform-specific modules
|
# platform-specific modules
|
||||||
|
|
|
@ -3,7 +3,7 @@ include $(REP_DIR)/lib/import/import-av.inc
|
||||||
TARGET = avplay
|
TARGET = avplay
|
||||||
SRC_C = avplay.c cmdutils.c libc_dummies.c
|
SRC_C = avplay.c cmdutils.c libc_dummies.c
|
||||||
LIBS += avfilter avformat avcodec avutil avresample swscale
|
LIBS += avfilter avformat avcodec avutil avresample swscale
|
||||||
LIBS += sdl posix
|
LIBS += sdl sdlmain libc libm
|
||||||
|
|
||||||
CC_WARN += -Wno-parentheses -Wno-switch -Wno-uninitialized \
|
CC_WARN += -Wno-parentheses -Wno-switch -Wno-uninitialized \
|
||||||
-Wno-format-zero-length -Wno-pointer-sign
|
-Wno-format-zero-length -Wno-pointer-sign
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* \brief Genode-specific data structures
|
||||||
|
* \author Josef Soentgen
|
||||||
|
* \date 2017-11-21
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SDL_GENODE_INTERNAL_H_
|
||||||
|
#define _SDL_GENODE_INTERNAL_H_
|
||||||
|
|
||||||
|
struct Video
|
||||||
|
{
|
||||||
|
bool resize_pending;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _SDL_GENODE_INTERNAL_H_ */
|
|
@ -14,6 +14,7 @@
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
#include <base/allocator_avl.h>
|
#include <base/allocator_avl.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
@ -21,6 +22,13 @@
|
||||||
#include <audio_out_session/connection.h>
|
#include <audio_out_session/connection.h>
|
||||||
#include <util/reconstructible.h>
|
#include <util/reconstructible.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include <SDL_genode_internal.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern Genode::Env *global_env();
|
||||||
|
extern Genode::Lock event_lock;
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AUDIO_CHANNELS = 2,
|
AUDIO_CHANNELS = 2,
|
||||||
|
@ -34,7 +42,6 @@ using Genode::Hex;
|
||||||
using Genode::Constructible;
|
using Genode::Constructible;
|
||||||
|
|
||||||
static const char *channel_names[] = { "front left", "front right" };
|
static const char *channel_names[] = { "front left", "front right" };
|
||||||
static float volume = 1.0;
|
|
||||||
static Signal_context config_signal_context;
|
static Signal_context config_signal_context;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -54,48 +61,55 @@ extern "C" {
|
||||||
/* The tag name used by Genode audio */
|
/* The tag name used by Genode audio */
|
||||||
#define GENODEAUD_DRIVER_NAME "genode"
|
#define GENODEAUD_DRIVER_NAME "genode"
|
||||||
|
|
||||||
|
struct Volume_config
|
||||||
|
{
|
||||||
|
Genode::Env &_env;
|
||||||
|
|
||||||
|
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
|
||||||
|
|
||||||
|
float volume { 1.0f };
|
||||||
|
|
||||||
|
void _handle_config_update()
|
||||||
|
{
|
||||||
|
_config_rom.update();
|
||||||
|
|
||||||
|
if (!_config_rom.valid()) { return; }
|
||||||
|
|
||||||
|
Genode::Lock_guard<Genode::Lock> guard(event_lock);
|
||||||
|
|
||||||
|
Genode::Xml_node config = _config_rom.xml();
|
||||||
|
|
||||||
|
try {
|
||||||
|
unsigned int config_volume;
|
||||||
|
config.sub_node("sdl_audio_volume").attribute("value")
|
||||||
|
.value(&config_volume);
|
||||||
|
volume = (float)config_volume / 100;
|
||||||
|
} catch (...) { }
|
||||||
|
|
||||||
|
Genode::log("Change SDL audio volume to ", volume * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::Signal_handler<Volume_config> _config_handler {
|
||||||
|
_env.ep(), *this, &Volume_config::_handle_config_update };
|
||||||
|
|
||||||
|
Volume_config(Genode::Env &env) : _env(env)
|
||||||
|
{
|
||||||
|
_config_rom.sigh(_config_handler);
|
||||||
|
_handle_config_update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct SDL_PrivateAudioData {
|
struct SDL_PrivateAudioData {
|
||||||
Uint8 *mixbuf;
|
Uint8 *mixbuf;
|
||||||
Uint32 mixlen;
|
Uint32 mixlen;
|
||||||
|
Constructible<Volume_config> volume_config;
|
||||||
Constructible<Audio_out::Connection> audio[AUDIO_CHANNELS];
|
Constructible<Audio_out::Connection> audio[AUDIO_CHANNELS];
|
||||||
Audio_out::Packet *packet[AUDIO_CHANNELS];
|
Audio_out::Packet *packet[AUDIO_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The first 'Signal_receiver' object in a process creates a signal receiver
|
|
||||||
* thread. Currently this must not happen before the main program has started
|
|
||||||
* or else the thread's stack area would get overmapped on Genode/Linux when
|
|
||||||
* the main program calls 'main_thread_bootstrap()' from '_main()'.
|
|
||||||
*/
|
|
||||||
static Signal_receiver *signal_receiver()
|
|
||||||
{
|
|
||||||
static Signal_receiver _signal_receiver;
|
|
||||||
return &_signal_receiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void read_config(Genode::Signal_context_capability sigh =
|
|
||||||
Genode::Signal_context_capability())
|
|
||||||
{
|
|
||||||
/* read volume from config file */
|
|
||||||
try {
|
|
||||||
unsigned int config_volume;
|
|
||||||
|
|
||||||
Genode::Attached_rom_dataspace config("config");
|
|
||||||
if (sigh.valid()) config.sigh(sigh);
|
|
||||||
else config.update();
|
|
||||||
config.xml().sub_node("sdl_audio_volume")
|
|
||||||
.attribute("value").value(&config_volume);
|
|
||||||
|
|
||||||
volume = (float)config_volume / 100;
|
|
||||||
}
|
|
||||||
catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
|
||||||
catch (Genode::Xml_node::Nonexistent_attribute) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Audio driver functions */
|
/* Audio driver functions */
|
||||||
static int GENODEAUD_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
static int GENODEAUD_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
||||||
static void GENODEAUD_WaitAudio(_THIS);
|
static void GENODEAUD_WaitAudio(_THIS);
|
||||||
|
@ -153,7 +167,7 @@ static SDL_AudioDevice *GENODEAUD_CreateDevice(int devindex)
|
||||||
/* connect to 'Audio_out' service */
|
/* connect to 'Audio_out' service */
|
||||||
for (int channel = 0; channel < AUDIO_CHANNELS; channel++) {
|
for (int channel = 0; channel < AUDIO_CHANNELS; channel++) {
|
||||||
try {
|
try {
|
||||||
_this->hidden->audio[channel].construct(
|
_this->hidden->audio[channel].construct(*global_env(),
|
||||||
channel_names[channel], false, channel == 0 ? true : false);
|
channel_names[channel], false, channel == 0 ? true : false);
|
||||||
_this->hidden->audio[channel]->start();
|
_this->hidden->audio[channel]->start();
|
||||||
}
|
}
|
||||||
|
@ -167,7 +181,7 @@ static SDL_AudioDevice *GENODEAUD_CreateDevice(int devindex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
read_config(signal_receiver()->manage(&config_signal_context));
|
_this->hidden->volume_config.construct(*global_env());
|
||||||
|
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
|
@ -200,6 +214,8 @@ static void GENODEAUD_WaitAudio(_THIS)
|
||||||
|
|
||||||
static void GENODEAUD_PlayAudio(_THIS)
|
static void GENODEAUD_PlayAudio(_THIS)
|
||||||
{
|
{
|
||||||
|
Genode::Lock_guard<Genode::Lock> guard(event_lock);
|
||||||
|
|
||||||
Audio_out::Connection *c[AUDIO_CHANNELS];
|
Audio_out::Connection *c[AUDIO_CHANNELS];
|
||||||
Audio_out::Packet *p[AUDIO_CHANNELS];
|
Audio_out::Packet *p[AUDIO_CHANNELS];
|
||||||
for (int channel = 0; channel < AUDIO_CHANNELS; channel++) {
|
for (int channel = 0; channel < AUDIO_CHANNELS; channel++) {
|
||||||
|
@ -214,6 +230,8 @@ static void GENODEAUD_PlayAudio(_THIS)
|
||||||
init = true;
|
init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float const volume = _this->hidden->volume_config->volume;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get new packet for left channel and use it to synchronize
|
* Get new packet for left channel and use it to synchronize
|
||||||
* the right channel
|
* the right channel
|
||||||
|
@ -222,11 +240,6 @@ static void GENODEAUD_PlayAudio(_THIS)
|
||||||
unsigned ppos = c[0]->stream()->packet_position(p[0]);
|
unsigned ppos = c[0]->stream()->packet_position(p[0]);
|
||||||
p[1] = c[1]->stream()->get(ppos);
|
p[1] = c[1]->stream()->get(ppos);
|
||||||
|
|
||||||
if (signal_receiver()->pending()) {
|
|
||||||
signal_receiver()->wait_for_signal();
|
|
||||||
read_config();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int sample = 0; sample < Audio_out::PERIOD; sample++)
|
for (int sample = 0; sample < Audio_out::PERIOD; sample++)
|
||||||
for (int channel = 0; channel < AUDIO_CHANNELS; channel++)
|
for (int channel = 0; channel < AUDIO_CHANNELS; channel++)
|
||||||
p[channel]->content()[sample] =
|
p[channel]->content()[sample] =
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* \brief Entry point for SDL applications with a main() function
|
||||||
|
* \author Josef Soentgen
|
||||||
|
* \date 2017-11-21
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/sleep.h>
|
||||||
|
#include <libc/component.h>
|
||||||
|
|
||||||
|
/* libc includes */
|
||||||
|
#include <stdlib.h> /* 'malloc' and 'exit' */
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
extern char **genode_argv;
|
||||||
|
extern int genode_argc;
|
||||||
|
extern char **genode_envp;
|
||||||
|
|
||||||
|
/* initial environment for the FreeBSD libc implementation */
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
|
/* provided by the application */
|
||||||
|
extern "C" int main(int argc, char *argv[], char *envp[]);
|
||||||
|
|
||||||
|
|
||||||
|
/* provided by our SDL backend */
|
||||||
|
extern void sdl_init_genode(Genode::Env &env);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void* sdl_main(void *)
|
||||||
|
{
|
||||||
|
exit(main(genode_argc, genode_argv, genode_envp));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Libc::Component::construct(Libc::Env &env)
|
||||||
|
{
|
||||||
|
using Genode::Xml_node;
|
||||||
|
using Genode::Xml_attribute;
|
||||||
|
|
||||||
|
env.config([&] (Xml_node const &node) {
|
||||||
|
int argc = 0;
|
||||||
|
int envc = 0;
|
||||||
|
char **argv;
|
||||||
|
char **envp;
|
||||||
|
|
||||||
|
/* count the number of arguments and environment variables */
|
||||||
|
node.for_each_sub_node([&] (Xml_node const &node) {
|
||||||
|
/* check if the 'value' attribute exists */
|
||||||
|
if (node.has_type("arg") && node.has_attribute("value"))
|
||||||
|
++argc;
|
||||||
|
else
|
||||||
|
if (node.has_type("env") && node.has_attribute("key") && node.has_attribute("value"))
|
||||||
|
++envc;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (argc == 0 && envc == 0)
|
||||||
|
return; /* from lambda */
|
||||||
|
|
||||||
|
/* arguments and environment are a contiguous array (but don't count on it) */
|
||||||
|
argv = (char**)malloc((argc + envc + 1) * sizeof(char*));
|
||||||
|
envp = &argv[argc];
|
||||||
|
|
||||||
|
/* read the arguments */
|
||||||
|
int arg_i = 0;
|
||||||
|
int env_i = 0;
|
||||||
|
node.for_each_sub_node([&] (Xml_node const &node) {
|
||||||
|
/* insert an argument */
|
||||||
|
if (node.has_type("arg")) try {
|
||||||
|
Xml_attribute attr = node.attribute("value");
|
||||||
|
|
||||||
|
Genode::size_t const arg_len = attr.value_size()+1;
|
||||||
|
char *arg = argv[arg_i] = (char*)malloc(arg_len);
|
||||||
|
|
||||||
|
attr.value(arg, arg_len);
|
||||||
|
++arg_i;
|
||||||
|
|
||||||
|
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
/* insert an environment variable */
|
||||||
|
if (node.has_type("env")) try {
|
||||||
|
Xml_attribute key_attr = node.attribute("key");
|
||||||
|
Xml_attribute val_attr = node.attribute("value");
|
||||||
|
|
||||||
|
Genode::size_t const pair_len =
|
||||||
|
key_attr.value_size() +
|
||||||
|
val_attr.value_size() + 1;
|
||||||
|
char *env = envp[env_i] = (char*)malloc(pair_len);
|
||||||
|
|
||||||
|
Genode::size_t off = 0;
|
||||||
|
key_attr.value(&env[off], key_attr.value_size()+1);
|
||||||
|
off = key_attr.value_size();
|
||||||
|
env[off++] = '=';
|
||||||
|
val_attr.value(&env[off], val_attr.value_size()+1);
|
||||||
|
++env_i;
|
||||||
|
|
||||||
|
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
|
});
|
||||||
|
|
||||||
|
envp[env_i] = NULL;
|
||||||
|
|
||||||
|
/* register command-line arguments at Genode's startup code */
|
||||||
|
genode_argc = argc;
|
||||||
|
genode_argv = argv;
|
||||||
|
genode_envp = environ = envp;
|
||||||
|
});
|
||||||
|
|
||||||
|
/* pass env to SDL backend */
|
||||||
|
sdl_init_genode(env);
|
||||||
|
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_t main_thread;
|
||||||
|
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setstacksize(&attr, 768 * 1024);
|
||||||
|
|
||||||
|
if (pthread_create(&main_thread, &attr, sdl_main, nullptr)) {
|
||||||
|
Genode::error("failed to create SDL main thread");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,11 +28,41 @@
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <input_session/connection.h>
|
#include <input_session/connection.h>
|
||||||
#include <input/event.h>
|
#include <input/event.h>
|
||||||
#include <input/keycodes.h>
|
#include <input/keycodes.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include <SDL_genode_internal.h>
|
||||||
|
|
||||||
|
|
||||||
|
Genode::Lock event_lock;
|
||||||
|
Video video_events;
|
||||||
|
|
||||||
|
|
||||||
|
static Genode::Env *_global_env = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
Genode::Env *global_env()
|
||||||
|
{
|
||||||
|
if (!_global_env) {
|
||||||
|
Genode::error("sdl_init_genode() not called, aborting");
|
||||||
|
throw Genode::Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _global_env;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sdl_init_genode(Genode::Env &env)
|
||||||
|
{
|
||||||
|
_global_env = &env;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
@ -40,7 +70,8 @@ extern "C" {
|
||||||
#include "SDL_sysevents.h"
|
#include "SDL_sysevents.h"
|
||||||
#include "SDL_genode_fb_events.h"
|
#include "SDL_genode_fb_events.h"
|
||||||
|
|
||||||
static Input::Connection *input = 0;
|
|
||||||
|
static Genode::Constructible<Input::Connection> input;
|
||||||
static const int KEYNUM_MAX = 512;
|
static const int KEYNUM_MAX = 512;
|
||||||
static SDLKey keymap[KEYNUM_MAX];
|
static SDLKey keymap[KEYNUM_MAX];
|
||||||
static int buttonmap[KEYNUM_MAX];
|
static int buttonmap[KEYNUM_MAX];
|
||||||
|
@ -58,8 +89,17 @@ extern "C" {
|
||||||
|
|
||||||
void Genode_Fb_PumpEvents(SDL_VideoDevice *t)
|
void Genode_Fb_PumpEvents(SDL_VideoDevice *t)
|
||||||
{
|
{
|
||||||
|
Genode::Lock_guard<Genode::Lock> guard(event_lock);
|
||||||
|
|
||||||
|
if (video_events.resize_pending) {
|
||||||
|
video_events.resize_pending = false;
|
||||||
|
|
||||||
|
SDL_PrivateResize(video_events.width, video_events.height);
|
||||||
|
}
|
||||||
|
|
||||||
if (!input->pending())
|
if (!input->pending())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
input->for_each_event([&] (Input::Event const &curr) {
|
input->for_each_event([&] (Input::Event const &curr) {
|
||||||
SDL_keysym ksym;
|
SDL_keysym ksym;
|
||||||
switch(curr.type())
|
switch(curr.type())
|
||||||
|
@ -104,14 +144,15 @@ extern "C" {
|
||||||
|
|
||||||
void Genode_Fb_InitOSKeymap(SDL_VideoDevice *t)
|
void Genode_Fb_InitOSKeymap(SDL_VideoDevice *t)
|
||||||
{
|
{
|
||||||
using namespace Input;
|
try {
|
||||||
input = new(Genode::env()->heap()) Connection();
|
input.construct(*_global_env);
|
||||||
if(!input->cap().valid())
|
} catch (...) {
|
||||||
{
|
|
||||||
Genode::error("no input driver available!");
|
Genode::error("no input driver available!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace Input;
|
||||||
|
|
||||||
/* Prepare button mappings */
|
/* Prepare button mappings */
|
||||||
for (int i=0; i<KEYNUM_MAX; i++)
|
for (int i=0; i<KEYNUM_MAX; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,16 @@
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <framebuffer_session/connection.h>
|
#include <framebuffer_session/connection.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
#include <SDL_genode_internal.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern Genode::Env *global_env();
|
||||||
|
|
||||||
|
extern Genode::Lock event_lock;
|
||||||
|
extern Video video_events;
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -47,10 +57,52 @@ extern "C" {
|
||||||
#include "SDL_genode_fb_events.h"
|
#include "SDL_genode_fb_events.h"
|
||||||
#include "SDL_genode_fb_video.h"
|
#include "SDL_genode_fb_video.h"
|
||||||
|
|
||||||
static Framebuffer::Connection *framebuffer = 0;
|
static SDL_Rect df_mode;
|
||||||
|
|
||||||
|
struct Sdl_framebuffer
|
||||||
|
{
|
||||||
|
Genode::Env &_env;
|
||||||
|
|
||||||
|
Framebuffer::Mode _mode;
|
||||||
|
Framebuffer::Connection _fb { _env, _mode };
|
||||||
|
|
||||||
|
void _handle_mode_change()
|
||||||
|
{
|
||||||
|
Genode::Lock_guard<Genode::Lock> guard(event_lock);
|
||||||
|
|
||||||
|
Framebuffer::Mode mode = _fb.mode();
|
||||||
|
df_mode.w = mode.width();
|
||||||
|
df_mode.h = mode.height();
|
||||||
|
|
||||||
|
video_events.resize_pending = true;
|
||||||
|
video_events.width = mode.width();
|
||||||
|
video_events.height = mode.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::Signal_handler<Sdl_framebuffer> _mode_handler {
|
||||||
|
_env.ep(), *this, &Sdl_framebuffer::_handle_mode_change };
|
||||||
|
|
||||||
|
Sdl_framebuffer(Genode::Env &env) : _env(env) {
|
||||||
|
_fb.mode_sigh(_mode_handler); }
|
||||||
|
|
||||||
|
bool valid() const { return _fb.cap().valid(); }
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Framebuffer::Session Interface **
|
||||||
|
************************************/
|
||||||
|
|
||||||
|
Genode::Dataspace_capability dataspace() { return _fb.dataspace(); }
|
||||||
|
|
||||||
|
Framebuffer::Mode mode() const { return _fb.mode(); }
|
||||||
|
|
||||||
|
void refresh(int x, int y, int w, int h) {
|
||||||
|
_fb.refresh(x, y, w, h); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static Genode::Constructible<Sdl_framebuffer> framebuffer;
|
||||||
static Framebuffer::Mode scr_mode;
|
static Framebuffer::Mode scr_mode;
|
||||||
static SDL_Rect *modes[2];
|
static SDL_Rect *modes[2];
|
||||||
static SDL_Rect df_mode;
|
|
||||||
|
|
||||||
#if defined(SDL_VIDEO_OPENGL)
|
#if defined(SDL_VIDEO_OPENGL)
|
||||||
|
|
||||||
|
@ -216,11 +268,11 @@ extern "C" {
|
||||||
|
|
||||||
static int Genode_Fb_Available(void)
|
static int Genode_Fb_Available(void)
|
||||||
{
|
{
|
||||||
if (framebuffer == nullptr) {
|
if (!framebuffer.constructed()) {
|
||||||
framebuffer = new (Genode::env()->heap()) Framebuffer::Connection();
|
framebuffer.construct(*global_env());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!framebuffer->cap().valid()) {
|
if (!framebuffer->valid()) {
|
||||||
Genode::error("could not obtain framebuffer session");
|
Genode::error("could not obtain framebuffer session");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -231,12 +283,9 @@ extern "C" {
|
||||||
|
|
||||||
static void Genode_Fb_DeleteDevice(SDL_VideoDevice *device)
|
static void Genode_Fb_DeleteDevice(SDL_VideoDevice *device)
|
||||||
{
|
{
|
||||||
Genode::log("free framebuffer session object");
|
if (framebuffer.constructed()) {
|
||||||
if(framebuffer != nullptr) {
|
framebuffer.destruct();
|
||||||
Genode::destroy(Genode::env()->heap(), framebuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
framebuffer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,9 +359,8 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
int Genode_Fb_VideoInit(SDL_VideoDevice *t, SDL_PixelFormat *vformat)
|
int Genode_Fb_VideoInit(SDL_VideoDevice *t, SDL_PixelFormat *vformat)
|
||||||
{
|
{
|
||||||
if (framebuffer == 0)
|
if (!framebuffer.constructed()) {
|
||||||
{
|
Genode::error("framebuffer not initialized");
|
||||||
Genode::error("framebuffer isn't initialized");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,17 +393,30 @@ extern "C" {
|
||||||
df_mode.h = scr_mode.height();
|
df_mode.h = scr_mode.height();
|
||||||
modes[1] = 0;
|
modes[1] = 0;
|
||||||
|
|
||||||
/* Map the buffer */
|
t->hidden->buffer = 0;
|
||||||
Genode::Dataspace_capability fb_ds_cap = framebuffer->dataspace();
|
|
||||||
if (!fb_ds_cap.valid()) {
|
|
||||||
Genode::error("could not request dataspace for frame buffer");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
t->hidden->buffer = Genode::env()->rm_session()->attach(fb_ds_cap);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Note: If we are terminated, this could be called in the middle of
|
||||||
|
* another SDL video routine -- notably UpdateRects.
|
||||||
|
*/
|
||||||
|
void Genode_Fb_VideoQuit(SDL_VideoDevice *t)
|
||||||
|
{
|
||||||
|
Genode::log("Quit video device ...");
|
||||||
|
|
||||||
|
if (t->screen->pixels) {
|
||||||
|
t->screen->pixels = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->hidden->buffer) {
|
||||||
|
global_env()->rm().detach(t->hidden->buffer);
|
||||||
|
t->hidden->buffer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List the available video modes for the given pixel format,
|
* List the available video modes for the given pixel format,
|
||||||
* sorted from largest to smallest.
|
* sorted from largest to smallest.
|
||||||
|
@ -383,13 +444,32 @@ extern "C" {
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int bpp, Uint32 flags)
|
int bpp, Uint32 flags)
|
||||||
{
|
{
|
||||||
Genode::log("Set video mode to: "
|
/* for now we do not support this */
|
||||||
"width=", width, " " "height=", height, " " "bpp=", bpp);
|
if (t->hidden->buffer && flags & SDL_OPENGL) {
|
||||||
|
Genode::error("resizing a OpenGL window not possible");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map the buffer */
|
||||||
|
Genode::Dataspace_capability fb_ds_cap = framebuffer->dataspace();
|
||||||
|
if (!fb_ds_cap.valid()) {
|
||||||
|
Genode::error("could not request dataspace for frame buffer");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->hidden->buffer) {
|
||||||
|
global_env()->rm().detach(t->hidden->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
t->hidden->buffer = global_env()->rm().attach(fb_ds_cap);
|
||||||
|
|
||||||
if (!t->hidden->buffer) {
|
if (!t->hidden->buffer) {
|
||||||
Genode::error("no buffer for requested mode");
|
Genode::error("no buffer for requested mode");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Genode::log("Set video mode to: ", width, "x", height, "@", bpp);
|
||||||
|
|
||||||
SDL_memset(t->hidden->buffer, 0, width * height * (bpp / 8));
|
SDL_memset(t->hidden->buffer, 0, width * height * (bpp / 8));
|
||||||
|
|
||||||
if (!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
|
if (!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
|
||||||
|
@ -481,21 +561,6 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*Note: If we are terminated, this could be called in the middle of
|
|
||||||
* another SDL video routine -- notably UpdateRects.
|
|
||||||
*/
|
|
||||||
void Genode_Fb_VideoQuit(SDL_VideoDevice *t)
|
|
||||||
{
|
|
||||||
Genode::log("Quit video device ...");
|
|
||||||
if (t->screen->pixels != 0)
|
|
||||||
{
|
|
||||||
SDL_free(t->screen->pixels);
|
|
||||||
t->screen->pixels = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Genode_Fb_GL_MakeCurrent(SDL_VideoDevice *t)
|
int Genode_Fb_GL_MakeCurrent(SDL_VideoDevice *t)
|
||||||
{
|
{
|
||||||
Genode::warning(__func__, ": not yet implemented");
|
Genode::warning(__func__, ": not yet implemented");
|
||||||
|
@ -523,5 +588,4 @@ extern "C" {
|
||||||
{
|
{
|
||||||
return !__mesa ? nullptr : dlsym(__mesa, proc);
|
return !__mesa ? nullptr : dlsym(__mesa, proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} //extern "C"
|
} //extern "C"
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
TARGET = test-sdl
|
TARGET := test-sdl
|
||||||
LIBS = sdl posix
|
LIBS := libc sdl sdlmain
|
||||||
SRC_CC = main.cc
|
SRC_CC := main.cc
|
||||||
|
|
|
@ -88,7 +88,7 @@ append config {
|
||||||
<resource name="RAM" quantum="1M"/>
|
<resource name="RAM" quantum="1M"/>
|
||||||
<provides><service name="Timer"/></provides>
|
<provides><service name="Timer"/></provides>
|
||||||
</start>
|
</start>
|
||||||
<start name="dosbox">
|
<start name="dosbox" caps="200">
|
||||||
<resource name="RAM" quantum="128M"/>
|
<resource name="RAM" quantum="128M"/>
|
||||||
<config>
|
<config>
|
||||||
<sdl_audio_volume value="100"/>
|
<sdl_audio_volume value="100"/>
|
||||||
|
@ -121,7 +121,7 @@ if {![file exists bin/dosbox.tar]} {
|
||||||
append boot_modules {
|
append boot_modules {
|
||||||
core init timer } [audio_drv_binary] {
|
core init timer } [audio_drv_binary] {
|
||||||
ld.lib.so
|
ld.lib.so
|
||||||
libc.lib.so posix.lib.so
|
libc.lib.so
|
||||||
libm.lib.so lwip.lib.so libpng.lib.so
|
libm.lib.so lwip.lib.so libpng.lib.so
|
||||||
stdcxx.lib.so sdl.lib.so sdl_net.lib.so pthread.lib.so zlib.lib.so
|
stdcxx.lib.so sdl.lib.so sdl_net.lib.so pthread.lib.so zlib.lib.so
|
||||||
dosbox dosbox.tar
|
dosbox dosbox.tar
|
||||||
|
|
|
@ -55,5 +55,5 @@ CC_WARN += -Wno-unused-variable -Wno-unused-function -Wno-switch -Wno-unused-val
|
||||||
-Wno-sign-compare -Wno-narrowing -Wno-missing-braces -Wno-array-bounds \
|
-Wno-sign-compare -Wno-narrowing -Wno-missing-braces -Wno-array-bounds \
|
||||||
-Wno-parentheses
|
-Wno-parentheses
|
||||||
|
|
||||||
LIBS += posix libpng sdl sdl_net stdcxx zlib
|
LIBS += libpng libc sdl sdlmain sdl_net stdcxx zlib
|
||||||
LIBS += libc_lwip_nic_dhcp
|
LIBS += libc_lwip_nic_dhcp
|
||||||
|
|
Loading…
Reference in New Issue