#include <GL/glx.h>
/* Local prototypes */
-static int CreateWindow( galaktos_thread_t *p_thread, int i_width,
- int i_height );
+static int CreateWindow( galaktos_thread_t *p_thread, XVisualInfo *p_vi,
+ int i_width, int i_height );
typedef struct
{
Display *p_display;
- GLXFBConfig fbconf;
+ GLXContext gwctx;
Window wnd;
GLXWindow gwnd;
+ GLXPbuffer gpbuf;
+ GLXContext gpctx;
+ Atom wm_delete;
}
glx_data_t;
#define OS_DATA ((glx_data_t*)(p_thread->p_os_data))
int i_maj, i_min;
int i_nbelem;
GLXFBConfig *p_fbconfs, fbconf;
- static const int p_attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5,
- GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True,
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 };
+ XVisualInfo *p_vi;
+ GLXContext gwctx;
+ int i;
+ GLXPbuffer gpbuf;
+ int p_attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5,
+ GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 };
/* Initialize OS data */
p_thread->p_os_data = malloc( sizeof( glx_data_t ) );
}
return -1;
}
- OS_DATA->fbconf = fbconf = p_fbconfs[0];
+ fbconf = p_fbconfs[0];
+
+ /* Get the X11 visual */
+ p_vi = glXGetVisualFromFBConfig( p_display, fbconf );
+ if( !p_vi )
+ {
+ msg_Err( p_thread, "Cannot get X11 visual" );
+ XFree( p_fbconfs );
+ return -1;
+ }
+
+ /* Create the window */
+ if( CreateWindow( p_thread, p_vi, i_width, i_height ) == -1 )
+ {
+ XFree( p_fbconfs );
+ XFree( p_vi );
+ return -1;
+ }
+ XFree( p_vi );
+
+ /* Create the GLX window */
+ OS_DATA->gwnd = glXCreateWindow( p_display, fbconf, OS_DATA->wnd, NULL );
+ if( OS_DATA->gwnd == None )
+ {
+ msg_Err( p_thread, "Cannot create GLX window" );
+ return -1;
+ }
+
+ /* Create an OpenGL context */
+ OS_DATA->gwctx = gwctx = glXCreateNewContext( p_display, fbconf,
+ GLX_RGBA_TYPE, NULL, True );
+ if( !gwctx )
+ {
+ msg_Err( p_thread, "Cannot create OpenGL context");
+ XFree( p_fbconfs );
+ return -1;
+ }
+ XFree( p_fbconfs );
+
+ /* Get a FB config for the pbuffer */
+ p_attr[1] = 8; // RED_SIZE
+ p_attr[3] = 8; // GREEN_SIZE
+ p_attr[5] = 8; // BLUE_SIZE
+ p_attr[7] = False; // DOUBLEBUFFER
+ p_attr[9] = GLX_PBUFFER_BIT; // DRAWABLE_TYPE
+ p_fbconfs = glXChooseFBConfig( p_display, 0, p_attr, &i_nbelem );
+ if( (i_nbelem <= 0) || !p_fbconfs )
+ {
+ msg_Err( p_thread, "Cannot get FB configurations for pbuffer");
+ if( p_fbconfs )
+ {
+ XFree( p_fbconfs );
+ }
+ return -1;
+ }
+ fbconf = p_fbconfs[0];
+
+ /* Create a pbuffer */
+ i = 0;
+ p_attr[i++] = GLX_PBUFFER_WIDTH;
+ p_attr[i++] = 512;
+ p_attr[i++] = GLX_PBUFFER_HEIGHT;
+ p_attr[i++] = 512;
+ p_attr[i++] = GLX_PRESERVED_CONTENTS;
+ p_attr[i++] = True;
+ p_attr[i++] = 0;
+ OS_DATA->gpbuf = gpbuf = glXCreatePbuffer( p_display, fbconf, p_attr );
+ if( !gpbuf )
+ {
+ msg_Err( p_thread, "Failed to create GLX pbuffer" );
+ XFree( p_fbconfs );
+ return -1;
+ }
- if( CreateWindow( p_thread, i_width, i_height ) == -1 )
+ /* Create the pbuffer context */
+ OS_DATA->gpctx = glXCreateNewContext( p_display, fbconf, GLX_RGBA_TYPE,
+ gwctx, True );
+ if( !OS_DATA->gpctx )
{
+ msg_Err( p_thread, "Failed to create pbuffer context" );
XFree( p_fbconfs );
return -1;
}
- msg_Err( p_thread, "NOT IMPLEMENTED YET ;)" );
+ XFree( p_fbconfs );
+
+ XMapWindow( p_display, OS_DATA->wnd );
+ XFlush( p_display );
+ glXMakeContextCurrent( p_display, OS_DATA->gwnd, OS_DATA->gwnd, gwctx );
+
return 0;
}
-int CreateWindow( galaktos_thread_t *p_thread, int i_width, int i_height )
+int galaktos_glx_handle_events( galaktos_thread_t *p_thread )
{
Display *p_display;
- XVisualInfo *p_vi;
- XSetWindowAttributes xattr;
- Window wnd;
p_display = OS_DATA->p_display;
- /* Get the X11 visual */
- p_vi = glXGetVisualFromFBConfig( p_display, OS_DATA->fbconf );
- if( !p_vi )
+
+ /* loop on X11 events */
+ while( XPending( p_display ) > 0 )
{
- msg_Err( p_thread, "Cannot get X11 visual" );
- return -1;
+ XEvent evt;
+ XNextEvent( p_display, &evt );
+ switch( evt.type )
+ {
+ case ClientMessage:
+ {
+ /* Delete notification */
+ if( (evt.xclient.format == 32) &&
+ ((Atom)evt.xclient.data.l[0] == OS_DATA->wm_delete) )
+ {
+ return 1;
+ }
+ break;
+ }
+ }
}
+ return 0;
+}
+
+
+void galaktos_glx_swap( galaktos_thread_t *p_thread )
+{
+ glXSwapBuffers( OS_DATA->p_display, OS_DATA->gwnd );
+}
+
+
+void galaktos_glx_done( galaktos_thread_t *p_thread )
+{
+ Display *p_display;
+
+ p_display = OS_DATA->p_display;
+ glXDestroyContext( p_display, OS_DATA->gpctx );
+ glXDestroyPbuffer( p_display, OS_DATA->gpbuf );
+ glXDestroyContext( p_display, OS_DATA->gwctx );
+ glXDestroyWindow( p_display, OS_DATA->gwnd );
+ XDestroyWindow( p_display, OS_DATA->wnd );
+ XCloseDisplay( p_display );
+}
+
+
+int CreateWindow( galaktos_thread_t *p_thread, XVisualInfo *p_vi,
+ int i_width, int i_height )
+{
+ Display *p_display;
+ XSetWindowAttributes xattr;
+ Window wnd;
+ XSizeHints* p_size_hints;
+ p_display = OS_DATA->p_display;
/* Create the window */
xattr.background_pixel = BlackPixel( p_display, DefaultScreen(p_display) );
xattr.border_pixel = 0;
OS_DATA->wnd = wnd = XCreateWindow( p_display, DefaultRootWindow(p_display),
0, 0, i_width, i_height, 0, p_vi->depth, InputOutput, p_vi->visual,
CWBackPixel | CWBorderPixel, &xattr);
- XFree( p_vi );
- /* Create the GLX window */
- OS_DATA->gwnd = glXCreateWindow( p_display, OS_DATA->fbconf, wnd, NULL );
- if( OS_DATA->gwnd == None )
- {
- msg_Err( p_thread, "Cannot create GLX window" );
- return -1;
- }
+ /* Allow the window to be deleted by the window manager */
+ OS_DATA->wm_delete = XInternAtom( p_display, "WM_DELETE_WINDOW", False );
+ XSetWMProtocols( p_display, wnd, &OS_DATA->wm_delete, 1 );
+
+ /* Prevent the window from being resized */
+ p_size_hints = XAllocSizeHints();
+ p_size_hints->flags = PMinSize | PMaxSize;
+ p_size_hints->min_width = i_width;
+ p_size_hints->min_height = i_height;
+ p_size_hints->max_width = i_width;
+ p_size_hints->max_height = i_height;
+ XSetWMNormalHints( p_display, wnd, p_size_hints );
+ XFree( p_size_hints );
+
+ XSelectInput( p_display, wnd, KeyPressMask );
return 0;
}
--- /dev/null
+/*****************************************************************************
+ * main.c:
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Cyril Deguet <asmax@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include "glx.h"
+#include <GL/gl.h>
+#include <unistd.h>
+#include <math.h>
+
+int galaktos_update( galaktos_thread_t *p_thread, int16_t p_data[2][512] )
+{
+ int j;
+
+ /* Process X11 events */
+ if( galaktos_glx_handle_events( p_thread ) == 1 )
+ {
+ return 1;
+ }
+
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glColor3f( 0.5f, 0.0f, 0.0f);
+ glVertex2f( -1.0f, 1.0f);
+ glColor3f( 0.2f, 0.2f, 0.0f);
+ glVertex2f( 1.0f, 1.0f);
+ glColor3f( 0.0f, 0.2f, 0.2f);
+ glVertex2f( -1.0f, -1.0f);
+ glColor3f( 0.0f, 0.0f, 0.5f);
+ glVertex2f( 1.0f, -1.0f);
+ glEnd();
+ glBegin(GL_LINE_STRIP);
+ glColor3f( 1.0f, 1.0f, 1.0f);
+ glVertex2f( -1.0f, 0.0f);
+ for(j=0; j<512; j++)
+ {
+ glVertex2f( (float)j/256-1.0f, (float)p_data[0][j]/32000);
+ }
+ glEnd();
+
+ galaktos_glx_swap( p_thread );
+
+ return 0;
+}
+
+
*****************************************************************************/
#include "plugin.h"
#include "glx.h"
+#include "main.h"
#include <vlc/input.h>
#include <vlc/vout.h>
vlc_object_create( p_filter, sizeof( galaktos_thread_t ) );
vlc_object_attach( p_thread, p_this );
- galaktos_glx_init( p_thread, 512, 512 );
/*
var_Create( p_thread, "galaktos-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Get( p_thread, "galaktos-width", &width );
audio_date_t i_pts;
int16_t p_data[2][512];
int i_data = 0, i_count = 0;
+ int i;
+
+ galaktos_glx_init( p_thread, 512, 512 );
while( !p_thread->b_die )
{
+ /* goom_update is damn slow, so just copy data and release the lock */
+ vlc_mutex_lock( &p_thread->lock );
+ if( FillBuffer( (int16_t *)p_data, &i_data, &i_pts,
+ &p_thread->date, p_thread ) != VLC_SUCCESS )
+ vlc_cond_wait( &p_thread->wait, &p_thread->lock );
+ vlc_mutex_unlock( &p_thread->lock );
+
+ if( galaktos_update( p_thread, p_data ) == 1 )
+ {
+ p_thread->b_die = 1;
+ }
+
+ if( p_thread->psz_title )
+ {
+ free( p_thread->psz_title );
+ p_thread->psz_title = NULL;
+ }
+
msleep( VOUT_OUTMEM_SLEEP );
}
+
+ galaktos_glx_done( p_thread );
}
/*****************************************************************************