From c94a2baba4add9458ffc481a7d3db0ed6f448337 Mon Sep 17 00:00:00 2001 From: w1z7ard Date: Fri, 23 May 2008 03:26:02 +0000 Subject: [PATCH] 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 --- src/projectM-libvisual-alsa/DESIGN | 44 ++ src/projectM-libvisual-alsa/README | 1 + src/projectM-libvisual-alsa/cacadriver.c | 259 ++++++++++++ src/projectM-libvisual-alsa/cacadriver.h | 9 + src/projectM-libvisual-alsa/client.c | 173 ++++++++ src/projectM-libvisual-alsa/display.c | 93 +++++ src/projectM-libvisual-alsa/display.h | 69 ++++ src/projectM-libvisual-alsa/glxdriver.c | 471 ++++++++++++++++++++++ src/projectM-libvisual-alsa/glxdriver.h | 9 + src/projectM-libvisual-alsa/lv_x11_key.c | 330 +++++++++++++++ src/projectM-libvisual-alsa/lv_x11_key.h | 56 +++ src/projectM-libvisual-alsa/morphclient.c | 181 +++++++++ src/projectM-libvisual-alsa/rebuild | 13 + src/projectM-libvisual-alsa/sdldriver.c | 376 +++++++++++++++++ src/projectM-libvisual-alsa/sdldriver.h | 9 + src/projectM-libvisual-alsa/x11driver.c | 190 +++++++++ src/projectM-libvisual-alsa/x11driver.h | 9 + 17 files changed, 2292 insertions(+) create mode 100644 src/projectM-libvisual-alsa/DESIGN create mode 100644 src/projectM-libvisual-alsa/README create mode 100644 src/projectM-libvisual-alsa/cacadriver.c create mode 100644 src/projectM-libvisual-alsa/cacadriver.h create mode 100644 src/projectM-libvisual-alsa/client.c create mode 100644 src/projectM-libvisual-alsa/display.c create mode 100644 src/projectM-libvisual-alsa/display.h create mode 100644 src/projectM-libvisual-alsa/glxdriver.c create mode 100644 src/projectM-libvisual-alsa/glxdriver.h create mode 100644 src/projectM-libvisual-alsa/lv_x11_key.c create mode 100644 src/projectM-libvisual-alsa/lv_x11_key.h create mode 100644 src/projectM-libvisual-alsa/morphclient.c create mode 100755 src/projectM-libvisual-alsa/rebuild create mode 100644 src/projectM-libvisual-alsa/sdldriver.c create mode 100644 src/projectM-libvisual-alsa/sdldriver.h create mode 100644 src/projectM-libvisual-alsa/x11driver.c create mode 100644 src/projectM-libvisual-alsa/x11driver.h diff --git a/src/projectM-libvisual-alsa/DESIGN b/src/projectM-libvisual-alsa/DESIGN new file mode 100644 index 000000000..1b65f9e75 --- /dev/null +++ b/src/projectM-libvisual-alsa/DESIGN @@ -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. + + diff --git a/src/projectM-libvisual-alsa/README b/src/projectM-libvisual-alsa/README new file mode 100644 index 000000000..92ad40bd4 --- /dev/null +++ b/src/projectM-libvisual-alsa/README @@ -0,0 +1 @@ +This is the experimental libvisual standalone port which allows alsa input only! More info later. \ No newline at end of file diff --git a/src/projectM-libvisual-alsa/cacadriver.c b/src/projectM-libvisual-alsa/cacadriver.c new file mode 100644 index 000000000..a70521e47 --- /dev/null +++ b/src/projectM-libvisual-alsa/cacadriver.c @@ -0,0 +1,259 @@ +#include + +#include +#include +#include + +#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; +} + diff --git a/src/projectM-libvisual-alsa/cacadriver.h b/src/projectM-libvisual-alsa/cacadriver.h new file mode 100644 index 000000000..808521dbb --- /dev/null +++ b/src/projectM-libvisual-alsa/cacadriver.h @@ -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 */ diff --git a/src/projectM-libvisual-alsa/client.c b/src/projectM-libvisual-alsa/client.c new file mode 100644 index 000000000..7354d4b1e --- /dev/null +++ b/src/projectM-libvisual-alsa/client.c @@ -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 + +#include + +#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; +} diff --git a/src/projectM-libvisual-alsa/display.c b/src/projectM-libvisual-alsa/display.c new file mode 100644 index 000000000..7a72432b5 --- /dev/null +++ b/src/projectM-libvisual-alsa/display.c @@ -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); +} + diff --git a/src/projectM-libvisual-alsa/display.h b/src/projectM-libvisual-alsa/display.h new file mode 100644 index 000000000..1b1b8e247 --- /dev/null +++ b/src/projectM-libvisual-alsa/display.h @@ -0,0 +1,69 @@ +#ifndef _LV_STANDALONE_DISPLAY_H +#define _LV_STANDALONE_DISPLAY_H + +#include + +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 */ diff --git a/src/projectM-libvisual-alsa/glxdriver.c b/src/projectM-libvisual-alsa/glxdriver.c new file mode 100644 index 000000000..7badcd739 --- /dev/null +++ b/src/projectM-libvisual-alsa/glxdriver.c @@ -0,0 +1,471 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +//#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); +} + diff --git a/src/projectM-libvisual-alsa/glxdriver.h b/src/projectM-libvisual-alsa/glxdriver.h new file mode 100644 index 000000000..b8d79c46a --- /dev/null +++ b/src/projectM-libvisual-alsa/glxdriver.h @@ -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 */ diff --git a/src/projectM-libvisual-alsa/lv_x11_key.c b/src/projectM-libvisual-alsa/lv_x11_key.c new file mode 100644 index 000000000..19a6bdd9c --- /dev/null +++ b/src/projectM-libvisual-alsa/lv_x11_key.c @@ -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 +#include +#include +#include +#include +#include +#include +#ifdef __SVR4 +#include +#endif +#include +#include +#include + +#include "lv_x11_key.h" + +int lv_x11_key_init (LVX11Key *x11key) +{ + int i; + + /* Odd keys used in international keyboards */ + for ( i=0; iODD_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; iMISC_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 diff --git a/src/projectM-libvisual-alsa/lv_x11_key.h b/src/projectM-libvisual-alsa/lv_x11_key.h new file mode 100644 index 000000000..904e6e48f --- /dev/null +++ b/src/projectM-libvisual-alsa/lv_x11_key.h @@ -0,0 +1,56 @@ +/* Libvisual - The audio visualisation framework. + * + * Copyright (C) 2004, 2005, 2006 Dennis Smit + * + * Authors: Dennis Smit + * + * $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 + +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 */ diff --git a/src/projectM-libvisual-alsa/morphclient.c b/src/projectM-libvisual-alsa/morphclient.c new file mode 100644 index 000000000..52badf910 --- /dev/null +++ b/src/projectM-libvisual-alsa/morphclient.c @@ -0,0 +1,181 @@ + + +#include + +#include + +#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; +} +} \ No newline at end of file diff --git a/src/projectM-libvisual-alsa/rebuild b/src/projectM-libvisual-alsa/rebuild new file mode 100755 index 000000000..72c5ca438 --- /dev/null +++ b/src/projectM-libvisual-alsa/rebuild @@ -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 diff --git a/src/projectM-libvisual-alsa/sdldriver.c b/src/projectM-libvisual-alsa/sdldriver.c new file mode 100644 index 000000000..2f1648203 --- /dev/null +++ b/src/projectM-libvisual-alsa/sdldriver.c @@ -0,0 +1,376 @@ +#include + +#include +#include +#include + +#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; +} + diff --git a/src/projectM-libvisual-alsa/sdldriver.h b/src/projectM-libvisual-alsa/sdldriver.h new file mode 100644 index 000000000..6df7a8428 --- /dev/null +++ b/src/projectM-libvisual-alsa/sdldriver.h @@ -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 */ diff --git a/src/projectM-libvisual-alsa/x11driver.c b/src/projectM-libvisual-alsa/x11driver.c new file mode 100644 index 000000000..2fa6fa4f4 --- /dev/null +++ b/src/projectM-libvisual-alsa/x11driver.c @@ -0,0 +1,190 @@ +#include +#include +#include + +#include +#include + +//#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; +} + diff --git a/src/projectM-libvisual-alsa/x11driver.h b/src/projectM-libvisual-alsa/x11driver.h new file mode 100644 index 000000000..6fdc058d8 --- /dev/null +++ b/src/projectM-libvisual-alsa/x11driver.h @@ -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 */