introduction of a libvisual based standalone client for alsa input only.

blatently stolen from libvisual-hackground code base



git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@1020 6778bc44-b910-0410-a7a0-be141de4315d
This commit is contained in:
w1z7ard
2008-05-23 03:26:02 +00:00
parent e6d6fdfce7
commit c94a2baba4
17 changed files with 2292 additions and 0 deletions

View File

@ -0,0 +1,44 @@
DONE A display abstraction thingy.
DONE Register SDL as the driver.
DONE handle gl
DONE handle framebuffer
DONE handle resize
DONE handle fullscreen
DONE support resize.
3 support a fps limiter.
DONE add support for libvisual it's gl param system (also make in lv).
DONE Add SDL events to a libvisual event queue.
DONE events to plugin.
Support switching between plugins. << in a different standalone example ?!
good object cleanup.
DONE support resolution selection
DONE support auto scaling on fullscreen, and return to old scale/position.
support keep position with gl switches.
When all is done, check where the API fails, and update in lv.
When all is done, let the playground make use of the display system (finally clean it up).
DONE make use of visibility events.
DONE make use of quit events.
add glx backend.
add support for a on texture renderer.
fix the x11 renderer
add fullscreen support to the x11 and glx renderer.
Make a few end clients:
simple.
bin and morphable.
complex (morphable and visui interface)
make sure all is abstract in a way that it's easy to include it in projects.

View File

@ -0,0 +1 @@
This is the experimental libvisual standalone port which allows alsa input only! More info later.

View File

@ -0,0 +1,259 @@
#include <caca.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "cacadriver.h"
#define CACA_NATIVE(obj) (VISUAL_CHECK_CAST ((obj), CacaNative))
typedef struct _CacaNative CacaNative;
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable);
static int native_close (SADisplay *display);
static int native_lock (SADisplay *display);
static int native_unlock (SADisplay *display);
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale);
static int native_getvideo (SADisplay *display, VisVideo *screen);
static int native_updaterect (SADisplay *display, VisRectangle *rect);
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue);
static int caca_initialized;
struct _CacaNative {
VisObject object;
struct caca_bitmap *bitmap;
unsigned char *area;
VisVideoDepth depth;
int width;
int height;
unsigned int red[256];
unsigned int green[256];
unsigned int blue[256];
unsigned int alpha[256];
};
SADisplayDriver *caca_driver_new ()
{
SADisplayDriver *driver;
driver = visual_mem_new0 (SADisplayDriver, 1);
visual_object_initialize (VISUAL_OBJECT (driver), TRUE, NULL);
driver->create = native_create;
driver->close = native_close;
driver->lock = native_lock;
driver->unlock = native_unlock;
driver->fullscreen = native_fullscreen;
driver->getvideo = native_getvideo;
driver->updaterect = native_updaterect;
driver->drainevents = native_drainevents;
return driver;
}
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable)
{
CacaNative *native = CACA_NATIVE (display->native);
unsigned int rmask;
unsigned int gmask;
unsigned int bmask;
unsigned int amask;
if (native == NULL) {
native = visual_mem_new0 (CacaNative, 1);
visual_object_initialize (VISUAL_OBJECT (native), TRUE, NULL);
}
if (caca_initialized == FALSE) {
if (caca_init () < 0)
return -1;
caca_set_window_title ("Libcaca libvisual display");
}
if (native->bitmap != NULL)
caca_free_bitmap (native->bitmap);
if (native->area != NULL)
visual_mem_free (native->area);
switch (depth) {
case VISUAL_VIDEO_DEPTH_32BIT:
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
break;
case VISUAL_VIDEO_DEPTH_24BIT:
rmask = 0xff0000;
gmask = 0x00ff00;
bmask = 0x0000ff;
amask = 0x000000;
break;
case VISUAL_VIDEO_DEPTH_16BIT:
rmask = 0x7c00;
gmask = 0x03e0;
bmask = 0x001f;
amask = 0x0000;
break;
case VISUAL_VIDEO_DEPTH_8BIT:
rmask = gmask = bmask = amask = 0;
break;
default:
rmask = gmask = bmask = amask = 0;
break;
}
native->bitmap = caca_create_bitmap (visual_video_depth_value_from_enum (depth),
width,
height,
width * (visual_video_depth_value_from_enum (depth) / 8),
rmask, gmask, bmask, amask);
native->area = visual_mem_malloc0 (width * height * (visual_video_depth_value_from_enum (depth) / 8));
native->width = width;
native->height = height;
native->depth = depth;
display->native = VISUAL_OBJECT (native);
caca_initialized = TRUE;
return 0;
}
static int native_close (SADisplay *display)
{
caca_end ();
return 0;
}
static int native_lock (SADisplay *display)
{
return 0;
}
static int native_unlock (SADisplay *display)
{
return 0;
}
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale)
{
return 0;
}
static int native_getvideo (SADisplay *display, VisVideo *screen)
{
CacaNative *native = CACA_NATIVE (display->native);
visual_video_set_depth (screen, native->depth);
visual_video_set_dimension (screen, native->width, native->height);
visual_video_set_buffer (screen, native->area);
return 0;
}
static int native_updaterect (SADisplay *display, VisRectangle *rect)
{
CacaNative *native = CACA_NATIVE (display->native);
VisPalette *pal;
int i;
pal = display->screen->pal;
if (display->screen->depth == VISUAL_VIDEO_DEPTH_8BIT) {
for (i = 0; i < 256; i++) {
native->red[i] = pal->colors[i].r * 16;
native->green[i] = pal->colors[i].g * 16;
native->blue[i] = pal->colors[i].b * 16;
}
caca_set_bitmap_palette (native->bitmap,
native->red,
native->green,
native->blue,
native->alpha);
}
caca_draw_bitmap (0, 0, caca_get_width() - 1, caca_get_height() - 1,
native->bitmap, native->area);
caca_refresh ();
return 0;
}
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue)
{
CacaNative *native = CACA_NATIVE (display->native);
unsigned int event;
while ((event = caca_get_event (CACA_EVENT_ANY)) > 0) {
if (event & CACA_EVENT_KEY_PRESS) {
visual_event_queue_add_keyboard (eventqueue, event & 0xff, 0,
VISUAL_KEY_DOWN);
} else if (event & CACA_EVENT_KEY_RELEASE) {
visual_event_queue_add_keyboard (eventqueue, event & 0xff, 0,
VISUAL_KEY_UP);
} else if (event & CACA_EVENT_MOUSE_MOTION) {
visual_event_queue_add_mousemotion (eventqueue, caca_get_mouse_x (), caca_get_mouse_y ());
} else if (event & CACA_EVENT_MOUSE_PRESS) {
visual_event_queue_add_mousebutton (eventqueue, event & 0xff, VISUAL_MOUSE_DOWN,
caca_get_mouse_x (), caca_get_mouse_y ());
} else if (event & CACA_EVENT_MOUSE_RELEASE) {
visual_event_queue_add_mousebutton (eventqueue, event & 0xff, VISUAL_MOUSE_UP,
caca_get_mouse_x (), caca_get_mouse_y ());
} else if (event & CACA_EVENT_RESIZE) {
native_create (display, display->screen->depth,
NULL,
caca_get_window_width (),
caca_get_window_height (),
TRUE);
visual_event_queue_add_resize (eventqueue, display->screen,
caca_get_window_width (),
caca_get_window_height ());
}
}
return 0;
}

View File

@ -0,0 +1,9 @@
#ifndef _LV_STANDALONE_CACADRIVER_H
#define _LV_STANDALONE_CACADRIVER_H
#include "display.h"
/* prototypes */
SADisplayDriver *caca_driver_new (void);
#endif /* _LV_STANDALONE_CACADRIVER_H */

View File

@ -0,0 +1,173 @@
/* When using the sdl driver and Xgl, sdl will show a nice empty window. Be sure to set the:
* XLIB_SKIP_ARGB_VISUALS environment variable to 1
*/
#include <libvisual/libvisual.h>
#include <stdlib.h>
#include "display.h"
#include "sdldriver.h"
#include "x11driver.h"
#include "glxdriver.h"
#include "cacadriver.h"
int main (int argc, char **argv)
{
SADisplay *display;
VisVideo *video;
VisInput *input;
VisActor *actor;
VisEventQueue *localqueue;
VisVideoAttributeOptions *vidoptions;
int running = TRUE;
int fullscreen = FALSE;
int visible = TRUE;
int depth;
//visual_mem_alloc_install_vtable (visual_mem_alloc_vtable_profile ());
visual_init (&argc, &argv);
display = display_new (sdl_driver_new ());
/* Libvisual stuff */
if (argc > 1)
actor = visual_actor_new (argv[1]);
else
actor = visual_actor_new ("projectM");
if (argc > 3) {
depth = visual_video_depth_enum_from_value (atoi (argv[3]));
} else
depth = visual_video_depth_get_highest (visual_actor_get_supported_depth (actor));
vidoptions = visual_actor_get_video_attribute_options (actor);
display_create (display, depth, vidoptions, 480, 360, TRUE);
visual_actor_realize (actor);
video = display_get_video (display);
visual_actor_set_video (actor, video);
visual_actor_video_negotiate (actor, 0, FALSE, FALSE);
if (argc > 2)
input = visual_input_new (argv[2]);
else
input = visual_input_new ("alsa");
visual_input_realize (input);
localqueue = visual_event_queue_new ();
while (running) {
VisEventQueue *pluginqueue;
VisEvent *ev;
/* Handle all events */
display_drain_events (display, localqueue);
pluginqueue = visual_plugin_get_eventqueue (visual_actor_get_plugin (actor));
while (visual_event_queue_poll_by_reference (localqueue, &ev)) {
if (ev->type != VISUAL_EVENT_RESIZE)
visual_event_queue_add (pluginqueue, ev);
switch (ev->type) {
case VISUAL_EVENT_RESIZE:
video = display_get_video (display);
visual_actor_set_video (actor, video);
visual_actor_video_negotiate (actor, depth, FALSE, FALSE);
break;
case VISUAL_EVENT_MOUSEMOTION:
break;
case VISUAL_EVENT_MOUSEBUTTONDOWN:
break;
case VISUAL_EVENT_MOUSEBUTTONUP:
break;
case VISUAL_EVENT_KEYDOWN:
switch (ev->event.keyboard.keysym.sym) {
case VKEY_ESCAPE:
running = FALSE;
break;
case VKEY_TAB:
fullscreen = !fullscreen;
display_set_fullscreen (display, fullscreen, TRUE);
/* Resync video */
video = display_get_video (display);
visual_actor_set_video (actor, video);
visual_actor_video_negotiate (actor, depth, FALSE, FALSE);
break;
default:
printf ("key: %c\n", ev->event.keyboard.keysym.sym);
break;
}
break;
case VISUAL_EVENT_KEYUP:
break;
case VISUAL_EVENT_QUIT:
running = FALSE;
break;
case VISUAL_EVENT_VISIBILITY:
visible = ev->event.visibility.is_visible;
break;
default:
break;
}
}
if (visible == FALSE) {
visual_input_run (input);
visual_time_usleep (10000);
continue;
}
/* Do a run cycle */
visual_input_run (input);
display_lock (display);
visual_actor_run (actor, input->audio);
display_unlock (display);
display_update_all (display);
display_fps_limit (display, 30);
}
/* Termination procedure */
display_set_fullscreen (display, FALSE, TRUE);
display_close (display);
visual_quit ();
//visual_mem_alloc_profile ();
printf ("Total frames: %d, average fps: %f\n", display_fps_total (display), display_fps_average (display));
return 0;
}

View File

@ -0,0 +1,93 @@
#include "display.h"
SADisplay *display_new (SADisplayDriver *driver)
{
SADisplay *display;
display = visual_mem_new0 (SADisplay, 1);
visual_object_initialize (VISUAL_OBJECT (display), TRUE, NULL);
display->driver = driver;
display->screen = visual_video_new ();
return display;
}
int display_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable)
{
return display->driver->create (display, depth, vidoptions, width, height, resizable);
}
int display_close (SADisplay *display)
{
return display->driver->close (display);
}
VisVideo *display_get_video (SADisplay *display)
{
display->driver->getvideo (display, display->screen);
return display->screen;
}
int display_lock (SADisplay *display)
{
return display->driver->lock (display);
}
int display_unlock (SADisplay *display)
{
return display->driver->unlock (display);
}
int display_update_all (SADisplay *display)
{
VisRectangle rect;
VisVideo *video = display_get_video (display);
rect.x = 0;
rect.y = 0;
rect.width = video->width;
rect.height = video->height;
display->frames_drawn++;
if (visual_timer_is_active (&display->timer) == FALSE)
visual_timer_start (&display->timer);
return display_update_rectangle (display, &rect);
}
int display_update_rectangle (SADisplay *display, VisRectangle *rect)
{
return display->driver->updaterect (display, rect);
}
int display_set_fullscreen (SADisplay *display, int fullscreen, int autoscale)
{
return display->driver->fullscreen (display, fullscreen, autoscale);
}
int display_drain_events (SADisplay *display, VisEventQueue *eventqueue)
{
return display->driver->drainevents (display, eventqueue);
}
int display_fps_limit (SADisplay *display, int fps)
{
return 0;
}
int display_fps_total (SADisplay *display)
{
return display->frames_drawn;
}
float display_fps_average (SADisplay *display)
{
return display->frames_drawn / (visual_timer_elapsed_usecs (&display->timer) / (float) VISUAL_USEC_PER_SEC);
}

View File

@ -0,0 +1,69 @@
#ifndef _LV_STANDALONE_DISPLAY_H
#define _LV_STANDALONE_DISPLAY_H
#include <libvisual/libvisual.h>
typedef struct _SADisplayDriver SADisplayDriver;
typedef struct _SADisplay SADisplay;
typedef int (*SADisplayDriverCreateFunc)(SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable);
typedef int (*SADisplayDriverCloseFunc)(SADisplay *display);
typedef int (*SADisplayDriverLockFunc)(SADisplay *display);
typedef int (*SADisplayDriverUnlockFunc)(SADisplay *display);
typedef int (*SADisplayDriverFullScreenFunc)(SADisplay *display, int fullscreen, int autoscale);
typedef int (*SADisplayDriverGetVideoFunc)(SADisplay *display, VisVideo *video);
typedef int (*SADisplayDriverUpdateRectFunc)(SADisplay *display, VisRectangle *rect);
typedef int (*SADisplayDriverDrainEventsFunc)(SADisplay *display, VisEventQueue *eventqueue);
struct _SADisplayDriver {
VisObject object;
SADisplayDriverCreateFunc create;
SADisplayDriverCloseFunc close;
SADisplayDriverLockFunc lock;
SADisplayDriverUnlockFunc unlock;
SADisplayDriverFullScreenFunc fullscreen;
SADisplayDriverGetVideoFunc getvideo;
SADisplayDriverUpdateRectFunc updaterect;
SADisplayDriverDrainEventsFunc drainevents;
};
struct _SADisplay {
VisObject object;
SADisplayDriver *driver;
VisVideo *screen;
VisObject *native;
int frames_drawn;
VisTimer timer;
};
/* prototypes */
SADisplay *display_new (SADisplayDriver *driver);
int display_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable);
int display_close (SADisplay *display);
VisVideo *display_get_video (SADisplay *display);
int display_lock (SADisplay *display);
int display_unlock (SADisplay *display);
int display_update_all (SADisplay *display);
int display_update_rectangle (SADisplay *display, VisRectangle *rect);
int display_set_fullscreen (SADisplay *display, int fullscreen, int autoscale);
int display_drain_events (SADisplay *display, VisEventQueue *eventqueue);
int display_fps_limit (SADisplay *display, int fps);
int display_fps_total (SADisplay *display);
float display_fps_average (SADisplay *display);
#endif /* _LV_STANDALONE_DISPLAY_H */

View File

@ -0,0 +1,471 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/keysym.h>
//#include "lv_gl_sdl.h"
#include "glxdriver.h"
#include "lv_x11_key.h"
#define GLX_NATIVE(obj) (VISUAL_CHECK_CAST ((obj), GLXNative))
typedef struct _GLXNative GLXNative;
static int __lv_glx_gl_attribute_map[] = {
[VISUAL_GL_ATTRIBUTE_NONE] = -1,
[VISUAL_GL_ATTRIBUTE_BUFFER_SIZE] = GLX_BUFFER_SIZE,
[VISUAL_GL_ATTRIBUTE_LEVEL] = GLX_LEVEL,
[VISUAL_GL_ATTRIBUTE_RGBA] = GLX_RGBA,
[VISUAL_GL_ATTRIBUTE_DOUBLEBUFFER] = GLX_DOUBLEBUFFER,
[VISUAL_GL_ATTRIBUTE_STEREO] = GLX_STEREO,
[VISUAL_GL_ATTRIBUTE_AUX_BUFFERS] = GLX_AUX_BUFFERS,
[VISUAL_GL_ATTRIBUTE_RED_SIZE] = GLX_RED_SIZE,
[VISUAL_GL_ATTRIBUTE_GREEN_SIZE] = GLX_GREEN_SIZE,
[VISUAL_GL_ATTRIBUTE_BLUE_SIZE] = GLX_BLUE_SIZE,
[VISUAL_GL_ATTRIBUTE_ALPHA_SIZE] = GLX_ALPHA_SIZE,
[VISUAL_GL_ATTRIBUTE_DEPTH_SIZE] = GLX_DEPTH_SIZE,
[VISUAL_GL_ATTRIBUTE_STENCIL_SIZE] = GLX_STENCIL_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_RED_SIZE] = GLX_ACCUM_RED_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_GREEN_SIZE] = GLX_ACCUM_GREEN_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_BLUE_SIZE] = GLX_ACCUM_BLUE_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_ALPHA_SIZE] = GLX_ACCUM_ALPHA_SIZE,
[VISUAL_GL_ATTRIBUTE_LAST] = -1
};
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable);
static int native_close (SADisplay *display);
static int native_lock (SADisplay *display);
static int native_unlock (SADisplay *display);
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale);
static int native_getvideo (SADisplay *display, VisVideo *screen);
static int native_updaterect (SADisplay *display, VisRectangle *rect);
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue);
static int get_nearest_resolution (SADisplay *display, int *width, int *height);
static int X11_Pending(Display *display);
static XVisualInfo *get_xvisualinfo_filter_capabilities (Display *dpy, int screen, VisVideoAttributeOptions *vidoptions);
struct _GLXNative {
VisObject object;
Display *dpy;
Window win;
int screen;
GLXContext ctx;
XSetWindowAttributes attr;
Bool fs;
Bool doubleBuffered;
XF86VidModeModeInfo deskMode;
VisVideoDepth requested_depth;
LVX11Key key;
unsigned int lastwidth;
unsigned int lastheight;
unsigned int width;
unsigned int height;
int x;
int y;
unsigned int depth;
int oldx;
int oldy;
int oldwidth;
int oldheight;
int resizable;
int active;
VisVideo *video;
/* Atoms */
Atom WM_DELETE_WINDOW;
};
SADisplayDriver *glx_driver_new ()
{
SADisplayDriver *driver;
driver = visual_mem_new0 (SADisplayDriver, 1);
visual_object_initialize (VISUAL_OBJECT (driver), TRUE, NULL);
driver->create = native_create;
driver->close = native_close;
driver->lock = native_lock;
driver->unlock = native_unlock;
driver->fullscreen = native_fullscreen;
driver->getvideo = native_getvideo;
driver->updaterect = native_updaterect;
driver->drainevents = native_drainevents;
return driver;
}
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable)
{
GLXNative *native = GLX_NATIVE (display->native);
XVisualInfo *vi;
Colormap cmap;
int dpyWidth, dpyHeight;
int i;
int glxMajorVersion, glxMinorVersion;
int vidModeMajorVersion, vidModeMinorVersion;
XF86VidModeModeInfo **modes;
int modeNum;
int bestMode;
Atom wmDelete;
Window winDummy;
unsigned int borderDummy;
if (native != NULL)
visual_object_unref (VISUAL_OBJECT (native));
native = visual_mem_new0 (GLXNative, 1);
visual_object_initialize (VISUAL_OBJECT (native), TRUE, NULL);
lv_x11_key_init (&native->key);
/* set best mode to current */
bestMode = 0;
/* get a connection */
native->dpy = XOpenDisplay(0);
native->screen = DefaultScreen(native->dpy);
XF86VidModeQueryVersion(native->dpy, &vidModeMajorVersion,
&vidModeMinorVersion);
printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
vidModeMinorVersion);
XF86VidModeGetAllModeLines(native->dpy, native->screen, &modeNum, &modes);
/* save desktop-resolution before switching modes */
native->deskMode = *modes[0];
/* look for mode with requested resolution */
for (i = 0; i < modeNum; i++)
{
if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
{
bestMode = i;
}
}
/* get an appropriate visual */
vi = get_xvisualinfo_filter_capabilities (native->dpy, native->screen, vidoptions);
if (vi == NULL) {
printf ("No visual found.\n");
visual_error_raise ();
}
glXQueryVersion(native->dpy, &glxMajorVersion, &glxMinorVersion);
printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
/* create a GLX context */
native->ctx = glXCreateContext(native->dpy, vi, 0, GL_TRUE);
/* create a color map */
cmap = XCreateColormap(native->dpy, RootWindow(native->dpy, vi->screen),
vi->visual, AllocNone);
native->attr.colormap = cmap;
native->attr.border_pixel = 0;
/* create a window in window mode*/
native->attr.event_mask = KeyPressMask | ButtonPressMask |
StructureNotifyMask | VisibilityChangeMask | KeyReleaseMask | ButtonReleaseMask;
native->win = XCreateWindow(native->dpy, RootWindow(native->dpy, vi->screen),
0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &native->attr);
XFree (vi);
/* only set window title and handle wm_delete_events if in windowed mode */
wmDelete = XInternAtom(native->dpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(native->dpy, native->win, &wmDelete, 1);
XSetStandardProperties(native->dpy, native->win, "jahoor",
"jahoor", None, NULL, 0, NULL);
XMapRaised(native->dpy, native->win);
/* connect the glx-context to the window */
glXMakeCurrent(native->dpy, native->win, native->ctx);
XGetGeometry(native->dpy, native->win, &winDummy, &native->x, &native->y,
&native->width, &native->height, &borderDummy, &native->depth);
printf("Depth %d\n", native->depth);
if (glXIsDirect(native->dpy, native->ctx))
printf("Congrats, you have Direct Rendering!\n");
else
printf("Sorry, no Direct Rendering possible!\n");
native->WM_DELETE_WINDOW = XInternAtom(native->dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(native->dpy, native->win, &native->WM_DELETE_WINDOW, 1);
native->lastwidth = width;
native->lastheight = height;
display->native = VISUAL_OBJECT (native);
return 0;
}
static int native_close (SADisplay *display)
{
GLXNative *native = GLX_NATIVE (display->native);
if (native->ctx) {
if (!glXMakeCurrent(native->dpy, None, NULL)) {
printf("Could not release drawing context.\n");
}
glXDestroyContext(native->dpy, native->ctx);
native->ctx = NULL;
}
/* switch back to original desktop resolution if we were in fs */
if (native->fs)
{
XF86VidModeSwitchToMode(native->dpy, native->screen, &native->deskMode);
XF86VidModeSetViewPort(native->dpy, native->screen, 0, 0);
}
XCloseDisplay(native->dpy);
return 0;
}
static int native_lock (SADisplay *display)
{
return 0;
}
static int native_unlock (SADisplay *display)
{
return 0;
}
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale)
{
GLXNative *native = GLX_NATIVE (display->native);
// Surface *screen = native->screen;
/*
if (fullscreen == TRUE) {
if (!(screen->flags & FULLSCREEN)) {
if (autoscale == TRUE) {
int width = display->screen->width;
int height = display->screen->height;
native->oldwidth = width;
native->oldheight = height;
get_nearest_resolution (display, &width, &height);
native_create (display, native->requested_depth, NULL, width, height, native->resizable);
}
ShowCursor (SDL_FALSE);
WM_ToggleFullScreen (screen);
}
} else {
if ((screen->flags & FULLSCREEN)) {
ShowCursor (SDL_TRUE);
WM_ToggleFullScreen (screen);
if (autoscale == TRUE)
native_create (display, native->requested_depth, NULL, native->oldwidth,
native->oldheight, native->resizable);
}
}
*/
return 0;
}
static int native_getvideo (SADisplay *display, VisVideo *screen)
{
GLXNative *native = GLX_NATIVE (display->native);
visual_video_set_depth (screen, VISUAL_VIDEO_DEPTH_GL);
visual_video_set_dimension (screen, native->width, native->height);
native->video = screen;
return 0;
}
static int native_updaterect (SADisplay *display, VisRectangle *rect)
{
GLXNative *native = GLX_NATIVE (display->native);
glXSwapBuffers (native->dpy, native->win);
return 0;
}
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue)
{
GLXNative *native = GLX_NATIVE (display->native);
XEvent xevent;
int sym;
int mod;
while (X11_Pending (native->dpy) > 0) {
VisKeySym keysym;
XNextEvent (native->dpy, &xevent);
switch (xevent.type) {
case ConfigureNotify:
if ((xevent.xconfigure.width != native->lastwidth) ||
(xevent.xconfigure.height != native->lastheight)) {
native->width = xevent.xconfigure.width;
native->height = xevent.xconfigure.height;
visual_event_queue_add_resize (eventqueue, native->video,
xevent.xconfigure.width, xevent.xconfigure.height);
}
break;
case ButtonPress:
visual_event_queue_add_mousebutton (eventqueue, xevent.xbutton.button, VISUAL_MOUSE_DOWN,
xevent.xbutton.x, xevent.xbutton.y);
break;
case ButtonRelease:
visual_event_queue_add_mousebutton (eventqueue, xevent.xbutton.button, VISUAL_MOUSE_UP,
xevent.xbutton.x, xevent.xbutton.y);
break;
case KeyPress:
lv_x11_key_lookup (&native->key, native->dpy, &xevent.xkey, xevent.xkey.keycode, &keysym,
TRUE);
visual_event_queue_add_keyboard (eventqueue, keysym.sym, keysym.mod,
VISUAL_KEY_DOWN);
break;
case KeyRelease:
lv_x11_key_lookup (&native->key, native->dpy, &xevent.xkey, xevent.xkey.keycode, &keysym,
FALSE);
visual_event_queue_add_keyboard (eventqueue, keysym.sym, keysym.mod,
VISUAL_KEY_UP);
break;
case ClientMessage:
if ((xevent.xclient.format == 32) &&
(xevent.xclient.data.l[0] == native->WM_DELETE_WINDOW)) {
visual_event_queue_add_quit (eventqueue, FALSE);
}
break;
case MotionNotify:
visual_event_queue_add_mousemotion (eventqueue, xevent.xmotion.x, xevent.xmotion.y);
break;
case VisibilityNotify:
if (xevent.xvisibility.state == VisibilityUnobscured ||
xevent.xvisibility.state == VisibilityPartiallyObscured) {
visual_event_queue_add_visibility (eventqueue, TRUE);
} else if (xevent.xvisibility.state == VisibilityFullyObscured) {
visual_event_queue_add_visibility (eventqueue, FALSE);
}
break;
}
}
return 0;
}
static int get_nearest_resolution (SADisplay *display, int *width, int *height)
{
return 0;
}
/* Ack! XPending() actually performs a blocking read if no events available */
/* Taken from SDL */
static int X11_Pending(Display *display)
{
/* Flush the display connection and look to see if events are queued */
XFlush(display);
if ( XEventsQueued(display, QueuedAlready) ) {
return(1);
}
/* More drastic measures are required -- see if X is ready to talk */
{
static struct timeval zero_time; /* static == 0 */
int x11_fd;
fd_set fdset;
x11_fd = ConnectionNumber(display);
FD_ZERO(&fdset);
FD_SET(x11_fd, &fdset);
if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 ) {
return(XPending(display));
}
}
/* Oh well, nothing is ready .. */
return(0);
}
static XVisualInfo *get_xvisualinfo_filter_capabilities (Display *dpy, int screen, VisVideoAttributeOptions *vidoptions)
{
int attrList[64];
int attrc = 0;
int i;
if (vidoptions == NULL)
return NULL;
/* FIXME filter for capabilities, like doublebuffer */
for (i = VISUAL_GL_ATTRIBUTE_NONE; i < VISUAL_GL_ATTRIBUTE_LAST; i++) {
if (vidoptions->gl_attributes[i].mutated == TRUE) {
int glx_attribute =
__lv_glx_gl_attribute_map[
vidoptions->gl_attributes[i].attribute];
if (glx_attribute < 0)
continue;
attrList[attrc++] = glx_attribute;
/* Check if it's a non boolean attribute */
if (glx_attribute != GLX_RGBA && glx_attribute != GLX_DOUBLEBUFFER && glx_attribute != GLX_STEREO) {
attrList[attrc++] = vidoptions->gl_attributes[i].value;
}
}
}
attrList[attrc++] = None;
return glXChooseVisual (dpy, screen, attrList);
}

View File

@ -0,0 +1,9 @@
#ifndef _LV_STANDALONE_GLXDRIVER_H
#define _LV_STANDALONE_GLXDRIVER_H
#include "display.h"
/* prototypes */
SADisplayDriver *glx_driver_new (void);
#endif /* _LV_STANDALONE_GLXDRIVER_H */

View File

@ -0,0 +1,330 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#ifdef __SVR4
#include <X11/Sunkeysym.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include "lv_x11_key.h"
int lv_x11_key_init (LVX11Key *x11key)
{
int i;
/* Odd keys used in international keyboards */
for ( i=0; i<VISUAL_TABLESIZE(x11key->ODD_keymap); ++i )
x11key->ODD_keymap[i] = VKEY_UNKNOWN;
#ifdef XK_dead_circumflex
/* These X keysyms have 0xFE as the high byte */
x11key->ODD_keymap[XK_dead_circumflex&0xFF] = VKEY_CARET;
#endif
#ifdef XK_ISO_Level3_Shift
x11key->ODD_keymap[XK_ISO_Level3_Shift&0xFF] = VKEY_MODE; /* "Alt Gr" key */
#endif
/* Map the miscellaneous keys */
for ( i=0; i<VISUAL_TABLESIZE(x11key->MISC_keymap); ++i )
x11key->MISC_keymap[i] = VKEY_UNKNOWN;
/* These X keysyms have 0xFF as the high byte */
x11key->MISC_keymap[XK_BackSpace&0xFF] = VKEY_BACKSPACE;
x11key->MISC_keymap[XK_Tab&0xFF] = VKEY_TAB;
x11key->MISC_keymap[XK_Clear&0xFF] = VKEY_CLEAR;
x11key->MISC_keymap[XK_Return&0xFF] = VKEY_RETURN;
x11key->MISC_keymap[XK_Pause&0xFF] = VKEY_PAUSE;
x11key->MISC_keymap[XK_Escape&0xFF] = VKEY_ESCAPE;
x11key->MISC_keymap[XK_Delete&0xFF] = VKEY_DELETE;
x11key->MISC_keymap[XK_KP_0&0xFF] = VKEY_KP0; /* Keypad 0-9 */
x11key->MISC_keymap[XK_KP_1&0xFF] = VKEY_KP1;
x11key->MISC_keymap[XK_KP_2&0xFF] = VKEY_KP2;
x11key->MISC_keymap[XK_KP_3&0xFF] = VKEY_KP3;
x11key->MISC_keymap[XK_KP_4&0xFF] = VKEY_KP4;
x11key->MISC_keymap[XK_KP_5&0xFF] = VKEY_KP5;
x11key->MISC_keymap[XK_KP_6&0xFF] = VKEY_KP6;
x11key->MISC_keymap[XK_KP_7&0xFF] = VKEY_KP7;
x11key->MISC_keymap[XK_KP_8&0xFF] = VKEY_KP8;
x11key->MISC_keymap[XK_KP_9&0xFF] = VKEY_KP9;
x11key->MISC_keymap[XK_KP_Insert&0xFF] = VKEY_KP0;
x11key->MISC_keymap[XK_KP_End&0xFF] = VKEY_KP1;
x11key->MISC_keymap[XK_KP_Down&0xFF] = VKEY_KP2;
x11key->MISC_keymap[XK_KP_Page_Down&0xFF] = VKEY_KP3;
x11key->MISC_keymap[XK_KP_Left&0xFF] = VKEY_KP4;
x11key->MISC_keymap[XK_KP_Begin&0xFF] = VKEY_KP5;
x11key->MISC_keymap[XK_KP_Right&0xFF] = VKEY_KP6;
x11key->MISC_keymap[XK_KP_Home&0xFF] = VKEY_KP7;
x11key->MISC_keymap[XK_KP_Up&0xFF] = VKEY_KP8;
x11key->MISC_keymap[XK_KP_Page_Up&0xFF] = VKEY_KP9;
x11key->MISC_keymap[XK_KP_Delete&0xFF] = VKEY_KP_PERIOD;
x11key->MISC_keymap[XK_KP_Decimal&0xFF] = VKEY_KP_PERIOD;
x11key->MISC_keymap[XK_KP_Divide&0xFF] = VKEY_KP_DIVIDE;
x11key->MISC_keymap[XK_KP_Multiply&0xFF] = VKEY_KP_MULTIPLY;
x11key->MISC_keymap[XK_KP_Subtract&0xFF] = VKEY_KP_MINUS;
x11key->MISC_keymap[XK_KP_Add&0xFF] = VKEY_KP_PLUS;
x11key->MISC_keymap[XK_KP_Enter&0xFF] = VKEY_KP_ENTER;
x11key->MISC_keymap[XK_KP_Equal&0xFF] = VKEY_KP_EQUALS;
x11key->MISC_keymap[XK_Up&0xFF] = VKEY_UP;
x11key->MISC_keymap[XK_Down&0xFF] = VKEY_DOWN;
x11key->MISC_keymap[XK_Right&0xFF] = VKEY_RIGHT;
x11key->MISC_keymap[XK_Left&0xFF] = VKEY_LEFT;
x11key->MISC_keymap[XK_Insert&0xFF] = VKEY_INSERT;
x11key->MISC_keymap[XK_Home&0xFF] = VKEY_HOME;
x11key->MISC_keymap[XK_End&0xFF] = VKEY_END;
x11key->MISC_keymap[XK_Page_Up&0xFF] = VKEY_PAGEUP;
x11key->MISC_keymap[XK_Page_Down&0xFF] = VKEY_PAGEDOWN;
x11key->MISC_keymap[XK_F1&0xFF] = VKEY_F1;
x11key->MISC_keymap[XK_F2&0xFF] = VKEY_F2;
x11key->MISC_keymap[XK_F3&0xFF] = VKEY_F3;
x11key->MISC_keymap[XK_F4&0xFF] = VKEY_F4;
x11key->MISC_keymap[XK_F5&0xFF] = VKEY_F5;
x11key->MISC_keymap[XK_F6&0xFF] = VKEY_F6;
x11key->MISC_keymap[XK_F7&0xFF] = VKEY_F7;
x11key->MISC_keymap[XK_F8&0xFF] = VKEY_F8;
x11key->MISC_keymap[XK_F9&0xFF] = VKEY_F9;
x11key->MISC_keymap[XK_F10&0xFF] = VKEY_F10;
x11key->MISC_keymap[XK_F11&0xFF] = VKEY_F11;
x11key->MISC_keymap[XK_F12&0xFF] = VKEY_F12;
x11key->MISC_keymap[XK_F13&0xFF] = VKEY_F13;
x11key->MISC_keymap[XK_F14&0xFF] = VKEY_F14;
x11key->MISC_keymap[XK_F15&0xFF] = VKEY_F15;
x11key->MISC_keymap[XK_Num_Lock&0xFF] = VKEY_NUMLOCK;
x11key->MISC_keymap[XK_Caps_Lock&0xFF] = VKEY_CAPSLOCK;
x11key->MISC_keymap[XK_Scroll_Lock&0xFF] = VKEY_SCROLLOCK;
x11key->MISC_keymap[XK_Shift_R&0xFF] = VKEY_RSHIFT;
x11key->MISC_keymap[XK_Shift_L&0xFF] = VKEY_LSHIFT;
x11key->MISC_keymap[XK_Control_R&0xFF] = VKEY_RCTRL;
x11key->MISC_keymap[XK_Control_L&0xFF] = VKEY_LCTRL;
x11key->MISC_keymap[XK_Alt_R&0xFF] = VKEY_RALT;
x11key->MISC_keymap[XK_Alt_L&0xFF] = VKEY_LALT;
x11key->MISC_keymap[XK_Meta_R&0xFF] = VKEY_RMETA;
x11key->MISC_keymap[XK_Meta_L&0xFF] = VKEY_LMETA;
x11key->MISC_keymap[XK_Super_L&0xFF] = VKEY_LSUPER; /* Left "Windows" */
x11key->MISC_keymap[XK_Super_R&0xFF] = VKEY_RSUPER; /* Right "Windows */
x11key->MISC_keymap[XK_Mode_switch&0xFF] = VKEY_MODE; /* "Alt Gr" key */
x11key->MISC_keymap[XK_Multi_key&0xFF] = VKEY_COMPOSE; /* Multi-key compose */
x11key->MISC_keymap[XK_Help&0xFF] = VKEY_HELP;
x11key->MISC_keymap[XK_Print&0xFF] = VKEY_PRINT;
x11key->MISC_keymap[XK_Sys_Req&0xFF] = VKEY_SYSREQ;
x11key->MISC_keymap[XK_Break&0xFF] = VKEY_BREAK;
x11key->MISC_keymap[XK_Menu&0xFF] = VKEY_MENU;
x11key->MISC_keymap[XK_Hyper_R&0xFF] = VKEY_MENU; /* Windows "Menu" key */
return 0;
}
VisKeySym *lv_x11_key_lookup (LVX11Key *x11key, Display *display, XKeyEvent *xkey, KeyCode kc, VisKeySym *keysym,
int pressed)
{
KeySym xsym;
/* Get the raw keyboard scancode */
// keysym->scancode = kc;
xsym = XKeycodeToKeysym(display, kc, 0);
#ifdef DEBUG_KEYS
fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, kc);
#endif
/* Get the translated SDL virtual keysym */
keysym->sym = VKEY_UNKNOWN;
if ( xsym ) {
switch (xsym>>8) {
case 0x1005FF:
#ifdef SunXK_F36
if ( xsym == SunXK_F36 )
keysym->sym = VKEY_F11;
#endif
#ifdef SunXK_F37
if ( xsym == SunXK_F37 )
keysym->sym = VKEY_F12;
#endif
break;
case 0x00: /* Latin 1 */
case 0x01: /* Latin 2 */
case 0x02: /* Latin 3 */
case 0x03: /* Latin 4 */
case 0x04: /* Katakana */
case 0x05: /* Arabic */
case 0x06: /* Cyrillic */
case 0x07: /* Greek */
case 0x08: /* Technical */
case 0x0A: /* Publishing */
case 0x0C: /* Hebrew */
case 0x0D: /* Thai */
keysym->sym = (VisKey)(xsym&0xFF);
/* Map capital letter syms to lowercase */
if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
keysym->sym += ('a'-'A');
break;
case 0xFE:
keysym->sym = x11key->ODD_keymap[xsym&0xFF];
break;
case 0xFF:
keysym->sym = x11key->MISC_keymap[xsym&0xFF];
break;
default:
fprintf(stderr,
"X11: Unknown xsym, sym = 0x%04x\n",
(unsigned int)xsym);
break;
}
} else {
/* X11 doesn't know how to translate the key! */
switch (kc) {
/* Caution:
These keycodes are from the Microsoft Keyboard
*/
case 115:
keysym->sym = VKEY_LSUPER;
break;
case 116:
keysym->sym = VKEY_RSUPER;
break;
case 117:
keysym->sym = VKEY_MENU;
break;
default:
/*
* no point in an error message; happens for
* several keys when we get a keymap notify
*/
break;
}
}
keysym->mod = VKMOD_NONE;
if (keysym->sym == VKEY_LSHIFT)
x11key->lshift = pressed;
else if (keysym->sym == VKEY_RSHIFT)
x11key->rshift = pressed;
else if (keysym->sym == VKEY_LCTRL)
x11key->lctrl = pressed;
else if (keysym->sym == VKEY_RCTRL)
x11key->rctrl = pressed;
else if (keysym->sym == VKEY_LALT)
x11key->lalt = pressed;
else if (keysym->sym == VKEY_RALT)
x11key->ralt = pressed;
else if (keysym->sym == VKEY_NUMLOCK)
x11key->num = pressed;
else if (keysym->sym == VKEY_CAPSLOCK)
x11key->caps = pressed;
keysym->mod |= x11key->lshift ? VKMOD_LSHIFT : VKMOD_NONE;
keysym->mod |= x11key->rshift ? VKMOD_RSHIFT : VKMOD_NONE;
keysym->mod |= x11key->lctrl ? VKMOD_LCTRL : VKMOD_NONE;
keysym->mod |= x11key->rctrl ? VKMOD_RCTRL : VKMOD_NONE;
keysym->mod |= x11key->lalt ? VKMOD_LALT : VKMOD_NONE;
keysym->mod |= x11key->ralt ? VKMOD_RALT : VKMOD_NONE;
keysym->mod |= x11key->num ? VKMOD_NUM : VKMOD_NONE;
keysym->mod |= x11key->caps ? VKMOD_CAPS : VKMOD_NONE;
/* If UNICODE is on, get the UNICODE value for the key */
#if 0
keysym->unicode = 0;
if ( SDL_TranslateUNICODE && xkey ) {
static XComposeStatus state;
/* Until we handle the IM protocol, use XLookupString() */
unsigned char keybuf[32];
#define BROKEN_XFREE86_INTERNATIONAL_KBD
/* This appears to be a magical flag that is used with AltGr on
international keyboards to signal alternate key translations.
The flag doesn't show up when in fullscreen mode (?)
FIXME: Check to see if this code is safe for other servers.
*/
#ifdef BROKEN_XFREE86_INTERNATIONAL_KBD
/* Work around what appears to be a bug in XFree86 */
if ( SDL_GetModState() & VKMOD_MODE ) {
xkey->state |= (1<<13);
}
#endif
/* Look up the translated value for the key event */
if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf),
NULL, &state) ) {
/*
* FIXME,: XLookupString() may yield more than one
* character, so we need a mechanism to allow for
* this (perhaps generate null keypress events with
* a unicode value)
*/
keysym->unicode = keybuf[0];
}
}
#endif
return(keysym);
}
#if 0
static void get_modifier_masks(Display *display)
{
static unsigned got_masks;
int i, j;
XModifierKeymap *xmods;
unsigned n;
if(got_masks)
return;
xmods = XGetModifierMapping(display);
n = xmods->max_keypermod;
for(i = 3; i < 8; i++) {
for(j = 0; j < n; j++) {
KeyCode kc = xmods->modifiermap[i * n + j];
KeySym ks = XKeycodeToKeysym(display, kc, 0);
unsigned mask = 1 << i;
switch(ks) {
case XK_Num_Lock:
num_mask = mask; break;
case XK_Alt_L:
alt_l_mask = mask; break;
case XK_Alt_R:
alt_r_mask = mask; break;
case XK_Meta_L:
meta_l_mask = mask; break;
case XK_Meta_R:
meta_r_mask = mask; break;
case XK_Mode_switch:
mode_switch_mask = mask; break;
}
}
}
XFreeModifiermap(xmods);
got_masks = 1;
}
#endif

View File

@ -0,0 +1,56 @@
/* Libvisual - The audio visualisation framework.
*
* Copyright (C) 2004, 2005, 2006 Dennis Smit <ds@nerds-incorporated.org>
*
* Authors: Dennis Smit <ds@nerds-incorporated.org>
*
* $Id: lv_x11_key.h,v 1.2 2006/03/22 18:24:09 synap Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LV_X11_KEY_H
#define _LV_X11_KEY_H
#include <libvisual/libvisual.h>
VISUAL_BEGIN_DECLS
typedef struct _LVX11Key LVX11Key;
struct _LVX11Key {
VisKey ODD_keymap[256];
VisKey MISC_keymap[256];
XComposeStatus compose_state;
int lshift;
int rshift;
int lctrl;
int rctrl;
int lalt;
int ralt;
int num;
int caps;
};
int lv_x11_key_init (LVX11Key *x11key);
VisKeySym *lv_x11_key_lookup (LVX11Key *x11key, Display *display, XKeyEvent *xkey, KeyCode kc, VisKeySym *keysym,
int pressed);
VISUAL_END_DECLS
#endif /* _LV_X11_KEY_H */

View File

@ -0,0 +1,181 @@
#include <libvisual/libvisual.h>
#include <stdlib.h>
#include "display.h"
#include "sdldriver.h"
int main (int argc, char **argv)
{
SADisplay *display;
VisVideo *video;
VisBin *bin;
VisEventQueue *localqueue;
VisVideoAttributeOptions *vidoptions;
//char *actorn = "gforce";
/* Setting projectm to default visualization
* Make sure you have it correctly installed ... */
char *actorn = "projectm";
char *inputn = "alsa";
int running = TRUE;
int fullscreen = FALSE;
int visible = TRUE;
int depth;
visual_init (&argc, &argv);
display = display_new (sdl_driver_new ());
/* Libvisual stuff */
if (argc > 1)
actorn = argv[1];
if (argc > 2)
inputn = argv[2];
bin = visual_bin_new ();
visual_bin_set_supported_depth (bin, VISUAL_VIDEO_DEPTH_ALL);
visual_bin_connect_by_names (bin, actorn, inputn);
vidoptions = visual_actor_get_video_attribute_options (visual_bin_get_actor (bin));
depth = visual_video_depth_get_highest (visual_actor_get_supported_depth (visual_bin_get_actor (bin)));
display_create (display, depth, vidoptions, 1024, 768, TRUE);
video = display_get_video (display);
visual_bin_set_video (bin, video);
visual_bin_depth_changed (bin);
visual_bin_switch_set_style (bin, VISUAL_SWITCH_STYLE_MORPH);
visual_bin_switch_set_automatic (bin, TRUE);
visual_bin_switch_set_mode (bin, VISUAL_MORPH_MODE_TIME);
visual_bin_switch_set_time (bin, 4, 0);
visual_bin_realize (bin);
visual_bin_sync (bin, FALSE);
localqueue = visual_event_queue_new ();
/* RUNNING IN FULLSCREEN BY DEFAULT */
display_set_fullscreen (display, fullscreen, FALSE);
while (running) {
VisEventQueue *pluginqueue;
VisEvent *ev;
/* Handle all events */
display_drain_events (display, localqueue);
pluginqueue = visual_plugin_get_eventqueue (visual_actor_get_plugin (visual_bin_get_actor (bin)));
while (visual_event_queue_poll_by_reference (localqueue, &ev)) {
if (ev->type != VISUAL_EVENT_RESIZE)
visual_event_queue_add (pluginqueue, ev);
switch (ev->type) {
case VISUAL_EVENT_RESIZE:
video = display_get_video (display);
visual_bin_set_video (bin, video);
visual_bin_sync (bin, FALSE);
break;
case VISUAL_EVENT_MOUSEMOTION:
break;
case VISUAL_EVENT_MOUSEBUTTONDOWN:
case VISUAL_EVENT_MOUSEBUTTONUP:
break;
case VISUAL_EVENT_KEYDOWN:
switch (ev->event.keyboard.keysym.sym) {
case VKEY_ESCAPE:
running = FALSE;
break;
case VKEY_TAB:
fullscreen = !fullscreen;
display_set_fullscreen (display, fullscreen, TRUE);
/* Resync video */
video = display_get_video (display);
visual_bin_set_video (bin, video);
visual_bin_sync (bin, FALSE);
break;
case VKEY_PAGEUP:
visual_bin_set_morph_by_name (bin, "tentacle");
visual_bin_switch_actor_by_name (bin, "oinksie");
break;
case VKEY_PAGEDOWN:
break;
default:
break;
}
break;
case VISUAL_EVENT_KEYUP:
break;
case VISUAL_EVENT_QUIT:
running = FALSE;
break;
case VISUAL_EVENT_VISIBILITY:
visible = ev->event.visibility.is_visible;
break;
default:
break;
} if (visual_bin_depth_changed (bin) == TRUE) {
vidoptions = visual_actor_get_video_attribute_options (visual_bin_get_actor (bin));
depth = visual_bin_get_depth (bin);
display_create (display, depth, vidoptions, video->width, video->height, TRUE);
video = display_get_video (display);
visual_bin_set_video (bin, video);
visual_bin_sync (bin, TRUE);
}
/* Do a run cycle */
display_lock (display);
display_unlock (display);
visual_bin_run (bin);
display_update_all (display);
display_fps_limit (display, 30);
}
/* Termination procedure */
display_set_fullscreen (display, FALSE, TRUE);
printf ("Total frames: %d, average fps: %f\n", display_fps_total (display), display_fps_average (display));
return 0;
}
}

View File

@ -0,0 +1,13 @@
#!/bin/sh
gcc -Wall -o lv-standalone client.c display.c glxdriver.c x11driver.c sdldriver.c lv_x11_key.c \
-L/usr/X11R6/lib -lGL -lGLU -lXxf86vm \
`pkg-config --cflags --libs libvisual-0.4` \
`sdl-config --libs --cflags` \
`caca-config --libs --cflags` \
-ggdb
gcc -Wall -o lv-morph morphclient.c display.c sdldriver.c \
`pkg-config --cflags --libs libvisual-0.4` \
`sdl-config --libs --cflags` \
-ggdb

View File

@ -0,0 +1,376 @@
#include <SDL/SDL.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "sdldriver.h"
#define SDL_NATIVE(obj) (VISUAL_CHECK_CAST ((obj), SDLNative))
typedef struct _SDLNative SDLNative;
static SDL_GLattr __lv_sdl_gl_attribute_map[] = {
[VISUAL_GL_ATTRIBUTE_NONE] = -1,
[VISUAL_GL_ATTRIBUTE_BUFFER_SIZE] = SDL_GL_BUFFER_SIZE,
[VISUAL_GL_ATTRIBUTE_LEVEL] = -1,
[VISUAL_GL_ATTRIBUTE_RGBA] = -1,
[VISUAL_GL_ATTRIBUTE_DOUBLEBUFFER] = SDL_GL_DOUBLEBUFFER,
[VISUAL_GL_ATTRIBUTE_STEREO] = SDL_GL_STEREO,
[VISUAL_GL_ATTRIBUTE_AUX_BUFFERS] = -1,
[VISUAL_GL_ATTRIBUTE_RED_SIZE] = SDL_GL_RED_SIZE,
[VISUAL_GL_ATTRIBUTE_GREEN_SIZE] = SDL_GL_GREEN_SIZE,
[VISUAL_GL_ATTRIBUTE_BLUE_SIZE] = SDL_GL_BLUE_SIZE,
[VISUAL_GL_ATTRIBUTE_ALPHA_SIZE] = SDL_GL_ALPHA_SIZE,
[VISUAL_GL_ATTRIBUTE_DEPTH_SIZE] = SDL_GL_DEPTH_SIZE,
[VISUAL_GL_ATTRIBUTE_STENCIL_SIZE] = SDL_GL_STENCIL_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_RED_SIZE] = SDL_GL_ACCUM_RED_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_GREEN_SIZE] = SDL_GL_ACCUM_GREEN_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_BLUE_SIZE] = SDL_GL_ACCUM_BLUE_SIZE,
[VISUAL_GL_ATTRIBUTE_ACCUM_ALPHA_SIZE] = SDL_GL_ACCUM_ALPHA_SIZE,
[VISUAL_GL_ATTRIBUTE_LAST] = -1
};
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable);
static int native_close (SADisplay *display);
static int native_lock (SADisplay *display);
static int native_unlock (SADisplay *display);
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale);
static int native_getvideo (SADisplay *display, VisVideo *screen);
static int native_updaterect (SADisplay *display, VisRectangle *rect);
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue);
static int get_nearest_resolution (SADisplay *display, int *width, int *height);
static int sdl_initialized;
struct _SDLNative {
VisObject object;
SDL_Surface *screen;
VisVideoDepth requested_depth;
int oldx;
int oldy;
int oldwidth;
int oldheight;
int resizable;
int active;
};
SADisplayDriver *sdl_driver_new ()
{
SADisplayDriver *driver;
driver = visual_mem_new0 (SADisplayDriver, 1);
visual_object_initialize (VISUAL_OBJECT (driver), TRUE, NULL);
driver->create = native_create;
driver->close = native_close;
driver->lock = native_lock;
driver->unlock = native_unlock;
driver->fullscreen = native_fullscreen;
driver->getvideo = native_getvideo;
driver->updaterect = native_updaterect;
driver->drainevents = native_drainevents;
return driver;
}
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable)
{
SDLNative *native = SDL_NATIVE (display->native);
const SDL_VideoInfo *videoinfo;
int videoflags = 0;
int bpp;
int i;
if (native == NULL) {
native = visual_mem_new0 (SDLNative, 1);
visual_object_initialize (VISUAL_OBJECT (native), TRUE, NULL);
}
if (native->screen != NULL) {
SDL_FreeSurface (native->screen);
}
videoflags |= resizable ? SDL_RESIZABLE : 0;
if (sdl_initialized == FALSE) {
if (SDL_Init (SDL_INIT_VIDEO) < 0) {
fprintf (stderr, "Unable to init SDL VIDEO: %s\n", SDL_GetError ());
exit (0);
}
sdl_initialized = TRUE;
}
native->resizable = resizable;
native->requested_depth = depth;
if (depth == VISUAL_VIDEO_DEPTH_GL) {
videoinfo = SDL_GetVideoInfo ();
if (!videoinfo) {
return -1;
}
videoflags |= SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE;
if (videoinfo->hw_available)
videoflags |= SDL_HWSURFACE;
else
videoflags |= SDL_SWSURFACE;
if (videoinfo->blit_hw)
videoflags |= SDL_HWACCEL;
if (vidoptions != NULL) {
for (i = VISUAL_GL_ATTRIBUTE_NONE; i < VISUAL_GL_ATTRIBUTE_LAST; i++) {
if (vidoptions->gl_attributes[i].mutated == TRUE) {
SDL_GLattr sdl_attribute =
__lv_sdl_gl_attribute_map[
vidoptions->gl_attributes[i].attribute];
if (sdl_attribute < 0)
continue;
SDL_GL_SetAttribute (sdl_attribute, vidoptions->gl_attributes[i].value);
}
}
}
bpp = videoinfo->vfmt->BitsPerPixel;
native->screen = SDL_SetVideoMode (width, height, bpp, videoflags);
} else {
native->screen = SDL_SetVideoMode (width, height,
visual_video_depth_value_from_enum (depth),
videoflags);
}
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
display->native = VISUAL_OBJECT (native);
return 0;
}
static int native_close (SADisplay *display)
{
return 0;
}
static int native_lock (SADisplay *display)
{
SDLNative *native = SDL_NATIVE (display->native);
SDL_Surface *screen = native->screen;
if (SDL_MUSTLOCK (screen) == SDL_TRUE)
SDL_LockSurface (screen);
return 0;
}
static int native_unlock (SADisplay *display)
{
SDLNative *native = SDL_NATIVE (display->native);
SDL_Surface *screen = native->screen;
if (SDL_MUSTLOCK (screen) == SDL_TRUE)
SDL_UnlockSurface (screen);
return 0;
}
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale)
{
SDLNative *native = SDL_NATIVE (display->native);
SDL_Surface *screen = native->screen;
if (fullscreen == TRUE) {
if (!(screen->flags & SDL_FULLSCREEN)) {
if (autoscale == TRUE) {
int width = display->screen->width;
int height = display->screen->height;
native->oldwidth = width;
native->oldheight = height;
get_nearest_resolution (display, &width, &height);
native_create (display, native->requested_depth, NULL, width, height, native->resizable);
}
SDL_ShowCursor (SDL_FALSE);
SDL_WM_ToggleFullScreen (screen);
}
} else {
if ((screen->flags & SDL_FULLSCREEN)) {
SDL_ShowCursor (SDL_TRUE);
SDL_WM_ToggleFullScreen (screen);
if (autoscale == TRUE)
native_create (display, native->requested_depth, NULL, native->oldwidth,
native->oldheight, native->resizable);
}
}
return 0;
}
static int native_getvideo (SADisplay *display, VisVideo *screen)
{
SDLNative *native = SDL_NATIVE (display->native);
SDL_Surface *sdlscreen = native->screen;
if (native->requested_depth == VISUAL_VIDEO_DEPTH_GL)
visual_video_set_depth (screen, VISUAL_VIDEO_DEPTH_GL);
else
visual_video_set_depth (screen, visual_video_depth_enum_from_value (sdlscreen->format->BitsPerPixel));
visual_video_set_dimension (screen, sdlscreen->w, sdlscreen->h);
visual_video_set_pitch (screen, sdlscreen->pitch);
visual_video_set_buffer (screen, sdlscreen->pixels);
return 0;
}
static int native_updaterect (SADisplay *display, VisRectangle *rect)
{
SDLNative *native = SDL_NATIVE (display->native);
SDL_Surface *sdlscreen = native->screen;
if (sdlscreen->format->BitsPerPixel == 8) {
SDL_Color colors[256];
VisPalette *pal = display->screen->pal;
visual_mem_set (colors, 0, sizeof (colors));
if (pal != NULL && pal->ncolors <= 256) {
int i;
for (i = 0; i < pal->ncolors; i++) {
colors[i].r = pal->colors[i].r;
colors[i].g = pal->colors[i].g;
colors[i].b = pal->colors[i].b;
}
SDL_SetColors (sdlscreen, colors, 0, 256);
}
}
if (native->requested_depth == VISUAL_VIDEO_DEPTH_GL)
SDL_GL_SwapBuffers ();
else
SDL_UpdateRect (sdlscreen, rect->x, rect->y, rect->width, rect->height);
return 0;
}
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue)
{
SDLNative *native = SDL_NATIVE (display->native);
SDL_Event event;
/* Visible or not */
if (((SDL_GetAppState () & SDL_APPACTIVE) == 0) && (native->active == TRUE)) {
native->active = FALSE;
visual_event_queue_add_visibility (eventqueue, FALSE);
} else if (((SDL_GetAppState () & SDL_APPACTIVE) != 0) && (native->active == FALSE)) {
native->active = TRUE;
visual_event_queue_add_visibility (eventqueue, TRUE);
}
/* Events */
while (SDL_PollEvent (&event)) {
switch (event.type) {
case SDL_KEYUP:
visual_event_queue_add_keyboard (eventqueue, event.key.keysym.sym, event.key.keysym.mod,
VISUAL_KEY_UP);
break;
case SDL_KEYDOWN:
visual_event_queue_add_keyboard (eventqueue, event.key.keysym.sym, event.key.keysym.mod,
VISUAL_KEY_DOWN);
break;
case SDL_VIDEORESIZE:
visual_event_queue_add_resize (eventqueue, display->screen, event.resize.w, event.resize.h);
native_create (display, display->screen->depth, NULL, event.resize.w, event.resize.h, native->resizable);
break;
case SDL_MOUSEMOTION:
visual_event_queue_add_mousemotion (eventqueue, event.motion.x, event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
visual_event_queue_add_mousebutton (eventqueue, event.button.button, VISUAL_MOUSE_DOWN,
event.button.x, event.button.y);
break;
case SDL_MOUSEBUTTONUP:
visual_event_queue_add_mousebutton (eventqueue, event.button.button, VISUAL_MOUSE_UP,
event.button.x, event.button.y);
break;
case SDL_QUIT:
visual_event_queue_add_quit (eventqueue, FALSE);
break;
default:
break;
}
}
return 0;
}
static int get_nearest_resolution (SADisplay *display, int *width, int *height)
{
SDL_Rect **modelist;
int w, h;
int i;
modelist = SDL_ListModes (NULL, SDL_FULLSCREEN);
if (modelist == NULL)
return -1;
w = *width;
h = *height;
/* Window is bigger than highest resolution */
if (modelist[0]->w <= *width || modelist[0]->h <= *height) {
*width = modelist[0]->w;
*height = modelist[0]->h;
return 0;
}
for (i = 0; modelist[i]; i++) {
if (modelist[i]->w >= *width && modelist[i]->h >= *height) {
w = modelist[i]->w;
h = modelist[i]->h;
}
}
*width = w;
*height = h;
return 0;
}

View File

@ -0,0 +1,9 @@
#ifndef _LV_STANDALONE_SDLDRIVER_H
#define _LV_STANDALONE_SDLDRIVER_H
#include "display.h"
/* prototypes */
SADisplayDriver *sdl_driver_new (void);
#endif /* _LV_STANDALONE_SDLDRIVER_H */

View File

@ -0,0 +1,190 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
//#include "lv_gl_sdl.h"
#include "x11driver.h"
#define X11_NATIVE(obj) (VISUAL_CHECK_CAST ((obj), X11Native))
// http://xander.ncl.ac.uk/game/src6/
typedef struct _X11Native X11Native;
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable);
static int native_close (SADisplay *display);
static int native_lock (SADisplay *display);
static int native_unlock (SADisplay *display);
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale);
static int native_getvideo (SADisplay *display, VisVideo *screen);
static int native_updaterect (SADisplay *display, VisRectangle *rect);
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue);
static int get_nearest_resolution (SADisplay *display, int *width, int *height);
struct _X11Native {
VisObject object;
Display *dpy;
Window win;
int screen;
VisVideoDepth requested_depth;
int oldx;
int oldy;
int oldwidth;
int oldheight;
int resizable;
int active;
};
SADisplayDriver *x11_driver_new ()
{
SADisplayDriver *driver;
driver = visual_mem_new0 (SADisplayDriver, 1);
visual_object_initialize (VISUAL_OBJECT (driver), TRUE, NULL);
driver->create = native_create;
driver->close = native_close;
driver->lock = native_lock;
driver->unlock = native_unlock;
driver->fullscreen = native_fullscreen;
driver->getvideo = native_getvideo;
driver->updaterect = native_updaterect;
driver->drainevents = native_drainevents;
// visual_gl_set_callback_attribute_set (native_gl_attribute_set);
// visual_gl_set_callback_attribute_get (native_gl_attribute_get);
return driver;
}
static int native_create (SADisplay *display, VisVideoDepth depth, VisVideoAttributeOptions *vidoptions,
int width, int height, int resizable)
{
X11Native *native = X11_NATIVE (display->native);
Window rootwin;
if (native != NULL)
visual_object_unref (VISUAL_OBJECT (native));
native = visual_mem_new0 (X11Native, 1);
visual_object_initialize (VISUAL_OBJECT (native), TRUE, NULL);
native->dpy = XOpenDisplay (NULL);
if (native->dpy == NULL)
visual_log (VISUAL_LOG_ERROR, "Can't open X Display");
native->screen = DefaultScreen (display);
rootwin = RootWindow (native->dpy, native->screen);
native->win = XCreateSimpleWindow (native->dpy, rootwin, 10, 10, width, height, 0, 0, 0);
XMapWindow (native->dpy, native->win);
display->native = VISUAL_OBJECT (native);
return 0;
}
static int native_close (SADisplay *display)
{
return 0;
}
static int native_lock (SADisplay *display)
{
return 0;
}
static int native_unlock (SADisplay *display)
{
return 0;
}
static int native_fullscreen (SADisplay *display, int fullscreen, int autoscale)
{
X11Native *native = X11_NATIVE (display->native);
// SDL_Surface *screen = native->screen;
/*
if (fullscreen == TRUE) {
if (!(screen->flags & SDL_FULLSCREEN)) {
if (autoscale == TRUE) {
int width = display->screen->width;
int height = display->screen->height;
native->oldwidth = width;
native->oldheight = height;
get_nearest_resolution (display, &width, &height);
native_create (display, native->requested_depth, NULL, width, height, native->resizable);
}
SDL_ShowCursor (SDL_FALSE);
SDL_WM_ToggleFullScreen (screen);
}
} else {
if ((screen->flags & SDL_FULLSCREEN)) {
SDL_ShowCursor (SDL_TRUE);
SDL_WM_ToggleFullScreen (screen);
if (autoscale == TRUE)
native_create (display, native->requested_depth, NULL, native->oldwidth,
native->oldheight, native->resizable);
}
}
*/
return 0;
}
static int native_getvideo (SADisplay *display, VisVideo *screen)
{
/*
X11Native *native = X11_NATIVE (display->native);
SDL_Surface *sdlscreen = native->screen;
if (native->requested_depth == VISUAL_VIDEO_DEPTH_GL)
visual_video_set_depth (screen, VISUAL_VIDEO_DEPTH_GL);
else
visual_video_set_depth (screen, visual_video_depth_enum_from_value (sdlscreen->format->BitsPerPixel));
visual_video_set_dimension (screen, sdlscreen->w, sdlscreen->h);
visual_video_set_pitch (screen, sdlscreen->pitch);
visual_video_set_buffer (screen, sdlscreen->pixels);
*/
return 0;
}
static int native_updaterect (SADisplay *display, VisRectangle *rect)
{
X11Native *native = X11_NATIVE (display->native);
return 0;
}
static int native_drainevents (SADisplay *display, VisEventQueue *eventqueue)
{
X11Native *native = X11_NATIVE (display->native);
return 0;
}
static int get_nearest_resolution (SADisplay *display, int *width, int *height)
{
return 0;
}

View File

@ -0,0 +1,9 @@
#ifndef _LV_STANDALONE_X11DRIVER_H
#define _LV_STANDALONE_X11DRIVER_H
#include "display.h"
/* prototypes */
SADisplayDriver *x11_driver_new (void);
#endif /* _LV_STANDALONE_X11DRIVER_H */