Skip to content

Instantly share code, notes, and snippets.

@arbruijn
Last active October 15, 2021 17:57
Show Gist options
  • Save arbruijn/b2b940c2d5e7b963c866a411447bf59a to your computer and use it in GitHub Desktop.
Save arbruijn/b2b940c2d5e7b963c866a411447bf59a to your computer and use it in GitHub Desktop.
Dual Head fbdev SDL hack
// Access both /dev/fb0 and /dev/fb1 with SDL
// Uses dlmopen to load a separate libSDL in another dynamic loader namespace
#define _GNU_SOURCE
#include <dlfcn.h>
#include <SDL/SDL.h>
typedef int (*SDL_Init_t)(Uint32);
typedef SDL_Surface *(*SDL_SetVideoMode_t)(int, int, int, Uint32);
typedef int (*SDL_Flip_t)(SDL_Surface *);
typedef void (*SDL_Quit_t)(void);
typedef int (*putenv_t)(char *);
typedef char *(*SDL_GetError_t)(void);
typedef int (*SDL_ShowCursor_t)(int);
#define WIDTH 640
#define HEIGHT 480
int setup_sdl(SDL_Init_t SDL_Init, SDL_SetVideoMode_t SDL_SetVideoMode, SDL_Flip_t SDL_Flip,
SDL_GetError_t SDL_GetError, SDL_ShowCursor_t SDL_ShowCursor) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
printf("SDL_Init: %s\n", SDL_GetError());
return 1;
}
SDL_Surface *scr = SDL_SetVideoMode(WIDTH, HEIGHT, 32 ,0);
if (!scr) {
printf("SDL_SetVideoMode: %s\n", SDL_GetError());
return 1;
}
SDL_ShowCursor(0);
Uint32 *frameBuffer = (Uint32*) scr->pixels;
int pitch = scr->pitch / sizeof(Uint32);
// show a red/green gradient
for (int y = 0; y < HEIGHT; y++)
for (int x = 0; x < WIDTH; x++)
frameBuffer[y * pitch + x] = ((x * 255 / WIDTH) << 16) | ((y * 255 / HEIGHT) << 8);
SDL_Flip(scr);
return 0;
}
int main(int argc, char **argv) {
void *sdl = dlmopen(LM_ID_NEWLM, "libSDL.so", RTLD_LAZY);
if (!sdl) {
printf("dlmopen: %s\n", dlerror());
return 1;
}
// setup primary SDL
if (setup_sdl(SDL_Init, SDL_SetVideoMode, SDL_Flip, SDL_GetError, SDL_ShowCursor))
return 1;
// setup secondary SDL on /dev/fb1
putenv_t putenv_fun = dlsym(sdl, "putenv");
putenv_fun("SDL_FBDEV=/dev/fb1");
putenv_fun("SDL_NOVT=1"); // needs SDL patch! needed to prevent hang
if (setup_sdl(dlsym(sdl, "SDL_Init"), dlsym(sdl, "SDL_SetVideoMode"),
dlsym(sdl, "SDL_Flip"), dlsym(sdl, "SDL_GetError"),
dlsym(sdl, "SDL_ShowCursor"))) {
SDL_Quit();
return 1;
}
int done = 0;
SDL_Event event;
while (!done) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
done = 1;
break;
case SDL_QUIT:
done = 1;
break;
}
}
if (!done)
SDL_Delay(1);
}
SDL_Quit_t quit_fun = dlsym(sdl, "SDL_Quit");
quit_fun();
SDL_Quit();
return 0;
}
diff --git a/src/video/fbcon/SDL_fbevents.c b/src/video/fbcon/SDL_fbevents.c
index 2bb74580..dd8c4337 100644
--- a/src/video/fbcon/SDL_fbevents.c
+++ b/src/video/fbcon/SDL_fbevents.c
@@ -258,7 +258,8 @@ int FB_OpenKeyboard(_THIS)
if ( tty0_fd < 0 ) {
tty0_fd = dup(0); /* Maybe stdin is a VT? */
}
- ioctl(tty0_fd, VT_OPENQRY, &current_vt);
+ if ( ! SDL_getenv("SDL_NOVT") )
+ ioctl(tty0_fd, VT_OPENQRY, &current_vt);
close(tty0_fd);
if ( current_vt > 0 ) {
for ( i=0; vcs[i] && (keyboard_fd < 0); ++i ) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment