diff --git a/src/drivers/sdl/SConscript b/src/drivers/sdl/SConscript index a8bde4ac..b16ffbe7 100644 --- a/src/drivers/sdl/SConscript +++ b/src/drivers/sdl/SConscript @@ -13,6 +13,7 @@ source_list = Split( memview.cpp ramwatch.cpp debugger.cpp + glxwin.cpp sdl.cpp sdl-joystick.cpp sdl-sound.cpp diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp new file mode 100644 index 00000000..7f00b5c8 --- /dev/null +++ b/src/drivers/sdl/glxwin.cpp @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "glxwin.h" + +static Display *dpy = NULL; +static Window root; +static GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; +static XVisualInfo *vi = NULL; +static Colormap cmap; +static XSetWindowAttributes swa; +static Window win; +static GLXContext glc; +static XWindowAttributes gwa; +static XEvent xev; + +static GLuint gltexture = 0; + +glxwin_shm_t *glx_shm = NULL; + +static int screen_width = 512; +static int screen_height = 512; +//************************************************************************ +static glxwin_shm_t *open_shm(void) +{ + int shmId; + glxwin_shm_t *vaddr; + struct shmid_ds ds; + + shmId = shmget( IPC_PRIVATE, sizeof(struct glxwin_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG ); + + if ( shmId == -1 ) + { + perror("Error: GLX shmget Failed:"); + return NULL; + } + printf("Created ShmID: %i \n", shmId ); + + vaddr = (glxwin_shm_t*)shmat( shmId, NULL, 0); + + if ( vaddr == (glxwin_shm_t*)-1 ) + { + perror("Error: GLX shmat Failed:"); + return NULL; + } + memset( vaddr, 0, sizeof(struct glxwin_shm_t)); + + if ( shmctl( shmId, IPC_RMID, &ds ) != 0 ) + { + perror("Error: GLX shmctl IPC_RMID Failed:"); + } + + sem_init( &vaddr->sem, 1, 1 ); + + return vaddr; +} +//************************************************************************ +static void genTextures(void) +{ + int ipolate = 1; + + glEnable(GL_TEXTURE_2D); + glGenTextures(1, &gltexture); + + glBindTexture(GL_TEXTURE_2D, gltexture); + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + +} +//************************************************************************ +static int open_window(void) +{ + + dpy = XOpenDisplay(NULL); + + if (dpy == NULL) { + printf("\n\tcannot connect to X server\n\n"); + exit(0); + } + root = DefaultRootWindow(dpy); + + vi = glXChooseVisual(dpy, 0, att); + + if (vi == NULL) + { + printf("\n\tno appropriate visual found\n\n"); + exit(0); + } + else { + printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */ + } + + cmap = XCreateColormap(dpy, root, vi->visual, AllocNone); + + swa.colormap = cmap; + swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask; + + win = XCreateWindow(dpy, root, 0, 0, screen_width, screen_height, 0, + vi->depth, InputOutput, vi->visual, + CWColormap | CWEventMask, &swa); + + XMapWindow(dpy, win); + + XStoreName(dpy, win, "FCEUX VIEWPORT"); + + glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); + glXMakeCurrent(dpy, win, glc); + + genTextures(); + glDisable(GL_DEPTH_TEST); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black. + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // In a double buffered setup with page flipping, be sure to clear both buffers. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + return 0; +} +//************************************************************************ +static void print_pixbuf(void) +{ + for (int x=0; x<256; x++) + { + for (int y=0; y<256; y++) + { + printf("(%i,%i) = %08X \n", x, y, glx_shm->pixbuf[x*256+y] ); + } + } +} +//************************************************************************ +static void render_image(void) +{ + int l=0, r=GLX_NES_WIDTH; + int t=0, b=GLX_NES_HEIGHT; + + float xscale = (float)screen_width / (float)GLX_NES_WIDTH; + float yscale = (float)screen_height / (float)GLX_NES_HEIGHT; + if (xscale < yscale ) + { + yscale = xscale; + } + else + { + xscale = yscale; + } + int rw=(int)((r-l)*xscale); + int rh=(int)((b-t)*yscale); + int sx=(screen_width-rw)/2; + int sy=(screen_height-rh)/2; + + glXMakeCurrent(dpy, win, glc); + //printf("Viewport: (%i,%i) %i %i %i %i \n", + // screen_width, screen_height, sx, sy, rw, rh ); + //glViewport(sx, sy, rw, rh); + glViewport( 0, 0, screen_width, screen_height); + + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + + glDisable(GL_DEPTH_TEST); + glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_TEXTURE_2D); + //glBindTexture(GL_TEXTURE_2D, gltexture); + glBindTexture(GL_TEXTURE_2D, gltexture); + + //print_pixbuf(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, + GL_RGBA, GL_UNSIGNED_BYTE, glx_shm->pixbuf ); + + glBegin(GL_QUADS); + glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. + glVertex2f(-1.0f, -1.0f); // Bottom left of target. + + glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture. + glVertex2f( 1.0f, -1.0f); // Bottom right of target. + + glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture. + glVertex2f( 1.0f, 1.0f); // Top right of target. + + glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture. + glVertex2f(-1.0f, 1.0f); // Top left of target. + glEnd(); + + glDisable(GL_TEXTURE_2D); + + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + glLineWidth(5.0); + glBegin(GL_LINES); + glVertex2f(-1.0f, -1.0f); // Bottom left of target. + glVertex2f( 1.0f, 1.0f); // Top right of target. + glEnd(); + + glFlush(); + + glXSwapBuffers( dpy, win ); +} +//************************************************************************ +static int mainWindowLoop(void) +{ + + while( glx_shm->run ) + { + while ( XPending( dpy ) ) + { + XNextEvent(dpy, &xev); + + if (xev.type == Expose) + { + XGetWindowAttributes(dpy, win, &gwa); + //glViewport(0, 0, gwa.width, gwa.height); + //DrawAQuad(); + glXSwapBuffers(dpy, win); + printf("Expose\n"); + } + else if (xev.type == ConfigureNotify) + { + //XGetWindowAttributes(dpy, win, &gwa); + + screen_width = xev.xconfigure.width; + screen_height = xev.xconfigure.height; + + //if (gltexture) { + // glDeleteTextures(1, &gltexture); + //} + //gltexture=0; + + //genTextures(); + + printf("Resize Request: (%i,%i)\n", screen_width, screen_height ); + render_image(); + //glViewport(0, 0, gwa.width, gwa.height); + //DrawAQuad(); + //glXSwapBuffers(dpy, win); + } + else if (xev.type == KeyPress) + { + printf("Key press: %i %08X \n", xev.xkey.keycode, xev.xkey.state ); + + } + else if (xev.type == DestroyNotify) + { + printf("DestroyNotify\n"); + glx_shm->run = 0; + //glXMakeCurrent(dpy, None, NULL); + //glXDestroyContext(dpy, glc); + //XDestroyWindow(dpy, win); + //XCloseDisplay(dpy); + //exit(0); + } + } + + if ( glx_shm->blit_count != glx_shm->render_count ) + { + render_image(); + glx_shm->render_count++; + } + + usleep(10000); + } + + glXMakeCurrent(dpy, None, NULL); + glXDestroyContext(dpy, glc); + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); + exit(0); + return 0; +} +//************************************************************************ +int spawn_glxwin( int flags ) +{ + int pid; + + glx_shm = open_shm(); + + pid = fork(); + + if ( pid == 0 ) + { + // Child Process + glx_shm->run = 1; + glx_shm->pid = getpid(); + + printf("Child Process Running: %i\n", glx_shm->pid ); + + open_window(); + + mainWindowLoop(); + + exit(0); + } + else if ( pid > 0 ) + { // Parent Process + + } + else + { + // Error + printf("Error: Failed to Fork GLX Window Process\n"); + } + + return pid; +} +//************************************************************************ + +//************************************************************************ diff --git a/src/drivers/sdl/glxwin.h b/src/drivers/sdl/glxwin.h new file mode 100644 index 00000000..03f162c3 --- /dev/null +++ b/src/drivers/sdl/glxwin.h @@ -0,0 +1,59 @@ +// glxwin.cpp +// + +#ifndef __GLXWIN_H__ +#define __GLXWIN_H__ + +#include + +#include + +int spawn_glxwin( int flags ); + +#define GLX_NES_WIDTH 256 +#define GLX_NES_HEIGHT 256 + +struct glxwin_shm_t +{ + int pid; + int run; + uint32_t render_count; + uint32_t blit_count; + sem_t sem; + + // Pass Key Events back to GTK Gui + struct + { + int head; + int tail; + + struct { + int type; + int keycode; + int state; + } data[64]; + + } keyEventBuf; + + // Gui Command Event Queue + struct + { + int head; + int tail; + + struct { + int id; + + union { + int i32[4]; + float f32[4]; + } param; + } cmd[64]; + } guiEvent; + + uint32_t pixbuf[65536]; // 256 x 256 +}; + +extern glxwin_shm_t *glx_shm; + +#endif diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 8962f88f..ac71ef00 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -34,11 +34,23 @@ #include #endif +#ifdef APPLEOPENGL +#include +#include +#include +#else +#include +#include +#include +#endif + #include #include #include #include +#include "glxwin.h" + // Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS) #if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2 #define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX @@ -66,6 +78,9 @@ static GtkRadioMenuItem *stateSlot[10] = { NULL }; bool gtkIsStarted = false; bool menuTogglingEnabled = false; +static int drawAreaGL = 0; +static GLuint gltexture = 0; +static uint32_t *drawAreaGLpixBuf = NULL; unsigned int gtk_draw_area_width = NES_WIDTH; unsigned int gtk_draw_area_height = NES_HEIGHT; static unsigned int gtk_win_width = 0; @@ -3085,6 +3100,15 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event, uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) { + if ( drawAreaGL ) + { + if ( w ) *w = 256; + if ( h ) *h = 256; + if ( s ) *s = 256*4; + + //return NULL; + return glx_shm->pixbuf; + } if ( cairo_surface == NULL ) { @@ -3114,6 +3138,13 @@ uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) int guiPixelBufferReDraw(void) { + glx_shm->blit_count++; + + if ( drawAreaGL ) + { + gtk_gl_area_queue_render( (GtkGLArea*)evbox); + return 0; + } if ( cairo_surface != NULL ) { cairo_surface_mark_dirty( cairo_surface ); @@ -3148,20 +3179,30 @@ int guiClearSurface(void) static void setPixels(void) { - int32_t *p; + uint32_t *p; int i,x,y,width,height,w2,h2; - width = cairo_image_surface_get_width (cairo_surface); - height = cairo_image_surface_get_height (cairo_surface); + if ( drawAreaGL ) + { + width = 256; + height = 256; + //p = (uint32_t*)drawAreaGLpixBuf; + p = (uint32_t*)glx_shm->pixbuf; + } + else + { + width = cairo_image_surface_get_width (cairo_surface); + height = cairo_image_surface_get_height (cairo_surface); - cairo_surface_flush( cairo_surface ); + cairo_surface_flush( cairo_surface ); - p = (int32_t*)cairo_image_surface_get_data (cairo_surface); + p = (uint32_t*)cairo_image_surface_get_data (cairo_surface); + } w2 = width / 2; h2 = height / 2; - printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 ); + //printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 ); i=0; for (y=0; y 1.0 ) + { + red = 1.0; dir = 0; + } + } + else + { + red -= 0.01; + if ( red < 0.0 ) + { + red = 0.0; dir = 1; + } + } + //if(stretchx) { sx=0; rw=screen->w; } + //if(stretchy) { sy=0; rh=screen->h; } + //glViewport(sx, sy, rw, rh); + //glViewport(0, 0, gtk_draw_area_width, gtk_draw_area_height); + + //glLoadIdentity(); + //glPushMatrix(); + //glLoadIdentity(); + //glMatrixMode(GL_MODELVIEW); + //glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + + //printf("GL Render!\n"); + + glDisable(GL_DEPTH_TEST); + glClearColor( red, 0.0f, 0.0f, 0.0f); // Background color to black. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_TEXTURE_2D); + glEnable(GL_LINE_SMOOTH); + //glEnable(GL_TEXTURE_2D); + //glBindTexture(GL_TEXTURE_2D, gltexture); + glBindTexture(GL_TEXTURE_2D, gltexture); + + + //setPixels(); + + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, + // GL_RGBA, GL_UNSIGNED_BYTE, drawAreaGLpixBuf ); + + //glBegin(GL_QUADS); + //glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. + //glVertex2f(-1.0f, -1.0f); // Bottom left of target. + + //glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture. + //glVertex2f( 1.0f, -1.0f); // Bottom right of target. + + //glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture. + //glVertex2f( 1.0f, 1.0f); // Top right of target. + + //glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture. + //glVertex2f(-1.0f, 1.0f); // Top left of target. + //glEnd(); + + //glPushMatrix(); + + //glColor4f( 1.0, 1.0, 1.0, 1.0 ); + //glLineWidth(5.0); + //glBegin(GL_LINES); + //glVertex2f(-1.0f, -1.0f); // Bottom left of target. + //glVertex2f( 1.0f, 1.0f); // Top right of target. + //glEnd(); + + //glPopMatrix(); + + glDisable(GL_TEXTURE_2D); + + glFlush(); + + return TRUE; +} + +static void +glwin_realize (GtkGLArea *area) +{ + int ipolate = 0; + gboolean has_alpha; + + printf("GL Realize!\n"); + // We need to make the context current if we want to + // call GL API + gtk_gl_area_make_current (area); + + // If there were errors during the initialization or + // when trying to make the context current, this + // function will return a #GError for you to catch + if (gtk_gl_area_get_error (area) != NULL) + { + printf("GL Realize Error\n"); + return; + } + + if ( drawAreaGLpixBuf == NULL ) + { + int bufSize; + + bufSize = 256 * 256 * sizeof(uint32_t); + + drawAreaGLpixBuf = (uint32_t*)malloc ( bufSize ); + + if ( drawAreaGLpixBuf ) + { + memset( drawAreaGLpixBuf, 0, bufSize ); + } + } + + has_alpha = gtk_gl_area_get_has_alpha( area ); + + printf("Has Alpha: %i \n", has_alpha ); + + if ( has_alpha ) + { + gtk_gl_area_set_has_alpha( area, 0 ); + } + // Enable depth buffer: + gtk_gl_area_set_has_depth_buffer(area, TRUE); + + has_alpha = gtk_gl_area_get_has_alpha( area ); + + printf("Has Alpha: %i \n", has_alpha ); + + glEnable(GL_TEXTURE_2D); + glGenTextures(1, &gltexture); + + glBindTexture(GL_TEXTURE_2D, gltexture); + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glClearColor(1.0f, 0.0f, 0.0f, 0.0f); // Background color to black. + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // In a double buffered setup with page flipping, be sure to clear both buffers. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +} + /* Redraw the screen from the surface. Note that the ::draw * signal receives a ready-to-be-used cairo_t that is already * clipped to only draw the exposed areas of the widget @@ -3335,6 +3586,8 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) int InitGTKSubsystem (int argc, char **argv) { + + int s_useOpenGL=0; GtkWidget *vbox; MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -3367,8 +3620,22 @@ int InitGTKSubsystem (int argc, char **argv) // // prg - Bryan Cain, you are the man! - //evbox = gtk_event_box_new(); - evbox = gtk_drawing_area_new (); + #ifdef OPENGL + g_config->getOption("SDL.OpenGL", &s_useOpenGL); + #endif + + drawAreaGL = s_useOpenGL; + + if ( drawAreaGL ) + { + evbox = gtk_gl_area_new (); + gtk_gl_area_set_has_alpha( GTK_GL_AREA(evbox), TRUE); + gtk_gl_area_set_has_depth_buffer( GTK_GL_AREA(evbox), TRUE); + } + else + { + evbox = gtk_drawing_area_new (); + } gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0); double xscale, yscale; @@ -3394,9 +3661,19 @@ int InitGTKSubsystem (int argc, char **argv) g_signal_connect (MainWindow, "delete-event", quit, NULL); g_signal_connect (MainWindow, "destroy-event", quit, NULL); // resize handler - g_signal_connect (evbox, "configure-event", - G_CALLBACK (handle_resize), NULL); - g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); + if ( s_useOpenGL ) + { + g_signal_connect (evbox, "resize" , G_CALLBACK (glwin_resize ), NULL); + g_signal_connect (evbox, "realize", G_CALLBACK (glwin_realize), NULL); + g_signal_connect (evbox, "render" , G_CALLBACK (glwin_render ), NULL); + } + else + { + g_signal_connect (evbox, "configure-event", + G_CALLBACK (handle_resize), NULL); + + g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); + } gtk_widget_set_size_request (evbox, NES_WIDTH * xscale, NES_HEIGHT * yscale); diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index 7f5c0364..38aa34b1 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -252,8 +252,8 @@ int InitVideo(FCEUGI *gi) g_config->getOption("SDL.YScale", &s_eys); uint32_t rmask, gmask, bmask; - //s_exs = 1.0; - //s_eys = 1.0; + s_exs = 1.0; + s_eys = 1.0; xres = gtk_draw_area_width; yres = gtk_draw_area_height; // check the starting, ending, and total scan lines @@ -277,12 +277,12 @@ int InitVideo(FCEUGI *gi) FCEUI_SetShowFPS(show_fps); #ifdef LSB_FIRST - //rmask = 0x000000FF; - //gmask = 0x0000FF00; - //bmask = 0x00FF0000; - rmask = 0x00FF0000; + rmask = 0x000000FF; gmask = 0x0000FF00; - bmask = 0x000000FF; + bmask = 0x00FF0000; + //rmask = 0x00FF0000; + //gmask = 0x0000FF00; + //bmask = 0x000000FF; #else rmask = 0x00FF0000; gmask = 0x0000FF00; @@ -866,11 +866,11 @@ FCEUD_GetPalette(uint8 index, */ static void RedoPalette() { -#ifdef OPENGL - if(s_useOpenGL) - SetOpenGLPalette((uint8*)s_psdl); - else -#endif +//#ifdef OPENGL +// if(s_useOpenGL) +// SetOpenGLPalette((uint8*)s_psdl); +// else +//#endif { if(s_curbpp > 8) { SetPaletteBlitToHigh((uint8*)s_psdl); @@ -913,13 +913,13 @@ BlitScreen(uint8 *XBuf) s_paletterefresh = 0; } -#ifdef OPENGL - // OpenGL is handled separately - if(s_useOpenGL) { - BlitOpenGL(XBuf); - return; - } -#endif +//#ifdef OPENGL +// // OpenGL is handled separately +// if(s_useOpenGL) { +// BlitOpenGL(XBuf); +// return; +// } +//#endif // XXX soules - not entirely sure why this is being done yet XBuf += s_srendline * 256; @@ -956,7 +956,7 @@ BlitScreen(uint8 *XBuf) // XXX soules - again, I'm surprised SDL can't handle this // perform the blit, converting bpp if necessary if(s_curbpp > 8) { - if(s_BlitBuf) { + if(s_useOpenGL) { Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); } else { diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index a2c00cda..2e8beda7 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -16,6 +16,7 @@ #include "sdl.h" #include "sdl-video.h" #include "unix-netplay.h" +#include "glxwin.h" #include "../common/configSys.h" #include "../../oldmovie.h" @@ -857,6 +858,7 @@ int main(int argc, char *argv[]) #ifdef _GTK if(noGui == 0) { + int glxwin_pid = spawn_glxwin(0); gtk_init(&argc, &argv); InitGTKSubsystem(argc, argv); while(gtk_events_pending())