Commit 974aa232 authored by Tony Castley's avatar Tony Castley

Implemented simple BDirectWindow (DMA) support

parent a278da2f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* VideoWindow.h: BeOS video window class prototype * VideoWindow.h: BeOS video window class prototype
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: VideoWindow.h,v 1.7 2001/10/21 06:06:20 tcastley Exp $ * $Id: VideoWindow.h,v 1.8 2001/12/01 06:38:53 tcastley Exp $
* *
* Authors: Jean-Marc Dressler <polux@via.ecp.fr> * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au> * Tony Castley <tcastley@mail.powerup.com.au>
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
#include <Slider.h>
#include <Accelerant.h>
#include <Bitmap.h> #include <Bitmap.h>
class VLCView : public BView class VLCView : public BView
...@@ -32,44 +30,65 @@ public: ...@@ -32,44 +30,65 @@ public:
VLCView( BRect bounds); VLCView( BRect bounds);
~VLCView(); ~VLCView();
virtual void MouseDown(BPoint point); void MouseDown(BPoint point);
}; };
class VideoWindow : public BWindow class VideoWindow
{ {
public: public:
// standard constructor and destructor // standard constructor and destructor
VideoWindow( BRect frame, const char *name, VideoWindow( int width, int height,
struct vout_thread_s *p_video_output); struct vout_thread_s *p_video_output);
~VideoWindow(); ~VideoWindow();
// standard window member void resizeIfRequired(int newWidth, int newHeight);
virtual bool QuitRequested(); void drawBuffer(int bufferIndex);
virtual void FrameResized(float width, float height);
virtual void MessageReceived(BMessage *message);
virtual void Zoom(BPoint origin, float width, float height);
// this is the hook controling direct screen connection // this is the hook controling direct screen connection
int32 i_bytes_per_pixel;
int32 i_screen_depth;
int32 i_width; int32 i_width;
int32 i_height; int32 i_height;
int32 fRowBytes;
int i_buffer_index;
BBitmap *bitmap[2]; BBitmap *bitmap[2];
VLCView *view; VLCView *view;
thread_id fDrawThreadID; BWindow *voutWindow;
int i_buffer;
bool teardownwindow; bool teardownwindow;
bool is_zoomed;
private:
// display_mode old_mode;
thread_id fDrawThreadID;
struct vout_thread_s *p_vout; struct vout_thread_s *p_vout;
private: };
// display_mode old_mode;
BRect rect;
class bitmapWindow : public BWindow
{
public:
bitmapWindow(BRect frame, VideoWindow *theOwner);
~bitmapWindow();
// standard window member
virtual void FrameResized(float width, float height);
virtual void Zoom(BPoint origin, float width, float height);
private:
bool is_zoomed;
BRect origRect;
VideoWindow *owner;
}; };
class directWindow : public BDirectWindow
{
public:
// standard constructor and destructor
directWindow( BRect frame, VideoWindow *theOwner);
~directWindow();
// standard window member
virtual void FrameResized(float width, float height);
virtual void Zoom(BPoint origin, float width, float height);
virtual void DirectConnected(direct_buffer_info *info);
private:
bool is_zoomed;
BRect origRect;
VideoWindow *owner;
};
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_beos.cpp: beos video output display method * vout_beos.cpp: beos video output display method
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: vout_beos.cpp,v 1.32 2001/11/28 15:08:05 massiot Exp $ * $Id: vout_beos.cpp,v 1.33 2001/12/01 06:38:53 tcastley Exp $
* *
* Authors: Jean-Marc Dressler <polux@via.ecp.fr> * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -36,14 +36,10 @@ ...@@ -36,14 +36,10 @@
#include <stdlib.h> /* free() */ #include <stdlib.h> /* free() */
#include <stdio.h> #include <stdio.h>
#include <string.h> /* strerror() */ #include <string.h> /* strerror() */
#include <kernel/OS.h> #include <InterfaceKit.h>
#include <View.h> #include <DirectWindow.h>
#include <Application.h> #include <Application.h>
#include <Window.h> #include <Bitmap.h>
#include <Locker.h>
#include <Screen.h>
#include <malloc.h>
#include <string.h>
extern "C" extern "C"
{ {
...@@ -66,12 +62,9 @@ extern "C" ...@@ -66,12 +62,9 @@ extern "C"
} }
#include "VideoWindow.h" #include "VideoWindow.h"
#include <Screen.h>
#define WIDTH 128 #define BITS_PER_PLANE 32
#define HEIGHT 64 #define BYTES_PER_PIXEL 4
#define BITS_PER_PLANE 16
#define BYTES_PER_PIXEL 2
/***************************************************************************** /*****************************************************************************
* vout_sys_t: BeOS video output method descriptor * vout_sys_t: BeOS video output method descriptor
...@@ -79,7 +72,6 @@ extern "C" ...@@ -79,7 +72,6 @@ extern "C"
* This structure is part of the video output thread descriptor. * This structure is part of the video output thread descriptor.
* It describes the BeOS specific properties of an output thread. * It describes the BeOS specific properties of an output thread.
*****************************************************************************/ *****************************************************************************/
typedef struct vout_sys_s typedef struct vout_sys_s
{ {
VideoWindow * p_window; VideoWindow * p_window;
...@@ -93,7 +85,6 @@ typedef struct vout_sys_s ...@@ -93,7 +85,6 @@ typedef struct vout_sys_s
/***************************************************************************** /*****************************************************************************
* beos_GetAppWindow : retrieve a BWindow pointer from the window name * beos_GetAppWindow : retrieve a BWindow pointer from the window name
*****************************************************************************/ *****************************************************************************/
BWindow *beos_GetAppWindow(char *name) BWindow *beos_GetAppWindow(char *name)
{ {
int32 index; int32 index;
...@@ -120,74 +111,103 @@ BWindow *beos_GetAppWindow(char *name) ...@@ -120,74 +111,103 @@ BWindow *beos_GetAppWindow(char *name)
/***************************************************************************** /*****************************************************************************
* DrawingThread : thread that really does the drawing * DrawingThread : thread that really does the drawing
*****************************************************************************/ *****************************************************************************/
int32 Draw(void *data) int32 Draw(void *data)
{ {
VideoWindow *p_win; VideoWindow* p_win;
p_win = (VideoWindow*) data; p_win = (VideoWindow *) data;
if (p_win->LockLooper()) if ( p_win->voutWindow->LockLooper() )
{ {
p_win->view->DrawBitmap( p_win->bitmap[p_win->i_buffer_index], p_win->view->DrawBitmap( p_win->bitmap[p_win->i_buffer],
p_win->bitmap[p_win->i_buffer_index]->Bounds(), p_win->bitmap[p_win->i_buffer]->Bounds(),
p_win->Bounds()); p_win->voutWindow->Bounds() );
p_win->UnlockLooper(); p_win->voutWindow->UnlockLooper();
} }
return B_OK; return B_OK;
} }
/***************************************************************************** /*****************************************************************************
* VideoWindow constructor and destructor * bitmapWindow : This is the bitmap window output
*****************************************************************************/ *****************************************************************************/
bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner)
VideoWindow::VideoWindow(BRect frame, const char *name, vout_thread_t *p_video_output ) : BWindow( frame, NULL, B_TITLED_WINDOW,
: BWindow(frame, name, B_TITLED_WINDOW, B_OUTLINE_RESIZE) B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{ {
/* set the VideoWindow variables */
teardownwindow = false;
is_zoomed = false; is_zoomed = false;
p_video_output->b_YCbr = false; origRect = frame;
owner = theOwner;
/* create the view to do the display */
view = new VLCView(Bounds());
AddChild(view);
/* Bitmap mode overlay not available */
bitmap[0] = new BBitmap(Bounds(), B_RGB32);
bitmap[1] = new BBitmap(Bounds(), B_RGB32);
i_screen_depth = 32;
SetTitle(VOUT_TITLE " (BBitmap output)"); SetTitle(VOUT_TITLE " (BBitmap output)");
}
memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength()); bitmapWindow::~bitmapWindow()
memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength()); {
i_width = bitmap[0]->Bounds().IntegerWidth();
i_height = bitmap[0]->Bounds().IntegerHeight();
i_bytes_per_pixel = bitmap[0]->BytesPerRow()/i_width;
fRowBytes = bitmap[0]->BytesPerRow();
i_screen_depth = 8 * i_bytes_per_pixel;
Show();
} }
VideoWindow::~VideoWindow() void bitmapWindow::FrameResized( float width, float height )
{ {
int32 result; if (is_zoomed)
{
return;
}
float width_scale;
float height_scale;
Hide(); width_scale = width / origRect.Width();
Sync(); height_scale = height / origRect.Height();
teardownwindow = true;
wait_for_thread(fDrawThreadID, &result); /* if the width is proportionally smaller */
delete bitmap[0]; if (width_scale <= height_scale)
delete bitmap[1]; {
ResizeTo(width, origRect.Height() * width_scale);
} }
else /* if the height is proportionally smaller */
{
ResizeTo(origRect.Width() * height_scale, height);
}
}
void bitmapWindow::Zoom(BPoint origin, float width, float height )
{
if(is_zoomed)
{
MoveTo(origRect.left, origRect.top);
ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
be_app->ShowCursor();
}
else
{
BScreen *screen;
screen = new BScreen(this);
BRect rect = screen->Frame();
delete screen;
MoveTo(0,0);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
be_app->HideCursor();
}
is_zoomed = !is_zoomed;
}
/***************************************************************************** /*****************************************************************************
* VideoWindow::FrameResized * directWindow : This is the bitmap window output
*****************************************************************************/ *****************************************************************************/
void VideoWindow::FrameResized( float width, float height ) directWindow::directWindow(BRect frame, VideoWindow *theOwner)
: BDirectWindow( frame, NULL, B_TITLED_WINDOW,
B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
{
is_zoomed = false;
origRect = frame;
owner = theOwner;
SetTitle(VOUT_TITLE " (DirectWindow output)");
}
directWindow::~directWindow()
{
}
void directWindow::DirectConnected(direct_buffer_info *info)
{
}
void directWindow::FrameResized( float width, float height )
{ {
if (is_zoomed) if (is_zoomed)
{ {
...@@ -195,38 +215,33 @@ void VideoWindow::FrameResized( float width, float height ) ...@@ -195,38 +215,33 @@ void VideoWindow::FrameResized( float width, float height )
} }
float width_scale; float width_scale;
float height_scale; float height_scale;
float orig_width = bitmap[0]->Bounds().Width();
float orig_height = bitmap[0]->Bounds().Height();
width_scale = width / orig_width; width_scale = width / origRect.Width();
height_scale = height / orig_height; height_scale = height / origRect.Height();
/* if the width is proportionally smaller */ /* if the width is proportionally smaller */
if (width_scale <= height_scale) if (width_scale <= height_scale)
{ {
ResizeTo(width, orig_height * width_scale); ResizeTo(width, origRect.Height() * width_scale);
} }
else /* if the height is proportionally smaller */ else /* if the height is proportionally smaller */
{ {
ResizeTo(orig_width * height_scale, height); ResizeTo(origRect.Width() * height_scale, height);
} }
} }
/***************************************************************************** void directWindow::Zoom(BPoint origin, float width, float height )
* VideoWindow::Zoom
*****************************************************************************/
void VideoWindow::Zoom(BPoint origin, float width, float height )
{ {
if(is_zoomed) if(is_zoomed)
{ {
MoveTo(rect.left, rect.top); SetFullScreen(false);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight()); MoveTo(origRect.left, origRect.top);
ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
be_app->ShowCursor(); be_app->ShowCursor();
} }
else else
{ {
rect = Frame(); SetFullScreen(true);
BScreen *screen; BScreen *screen;
screen = new BScreen(this); screen = new BScreen(this);
BRect rect = screen->Frame(); BRect rect = screen->Frame();
...@@ -239,41 +254,81 @@ void VideoWindow::Zoom(BPoint origin, float width, float height ) ...@@ -239,41 +254,81 @@ void VideoWindow::Zoom(BPoint origin, float width, float height )
} }
/***************************************************************************** /*****************************************************************************
* VideoWindow::MessageReceived * VideoWindow constructor and destructor
*****************************************************************************/ *****************************************************************************/
VideoWindow::VideoWindow( int width, int height,
vout_thread_t *p_video_output )
{
if ( BDirectWindow::SupportsWindowMode() )
{
voutWindow = new directWindow( BRect( 80, 50,
80 + width, 50 + height ), this );
}
else
{
voutWindow = new bitmapWindow( BRect( 80, 50,
80 + width, 50 + height ), this );
}
/* set the VideoWindow variables */
teardownwindow = false;
void VideoWindow::MessageReceived( BMessage * p_message ) /* create the view to do the display */
view = new VLCView( voutWindow->Bounds() );
voutWindow->AddChild(view);
/* Bitmap mode overlay not available */
bitmap[0] = new BBitmap( voutWindow->Bounds(), B_RGB32);
bitmap[1] = new BBitmap( voutWindow->Bounds(), B_RGB32);
memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
i_width = bitmap[0]->Bounds().IntegerWidth();
i_height = bitmap[0]->Bounds().IntegerHeight();
voutWindow->Show();
}
VideoWindow::~VideoWindow()
{ {
BWindow * p_win; int32 result;
switch( p_message->what ) voutWindow->Hide();
voutWindow->Sync();
voutWindow->Lock();
voutWindow->Quit();
teardownwindow = true;
wait_for_thread(fDrawThreadID, &result);
delete bitmap[0];
delete bitmap[1];
}
void VideoWindow::resizeIfRequired( int newWidth, int newHeight )
{
if (( newWidth != i_width + 1) &&
( newHeight != i_height + 1) &&
( newWidth != 0 ))
{ {
case B_KEY_DOWN: if ( voutWindow->Lock() )
case B_SIMPLE_DATA:
// post the message to the interface window which will handle it
p_win = beos_GetAppWindow( "interface" );
if( p_win != NULL )
{ {
p_win->PostMessage( p_message ); view->ClearViewBitmap();
i_width = newWidth - 1;
i_height = newHeight -1;
voutWindow->ResizeTo((float) i_width, (float) i_height);
voutWindow->Unlock();
} }
break;
default:
BWindow::MessageReceived( p_message );
break;
} }
} }
/***************************************************************************** void VideoWindow::drawBuffer(int bufferIndex)
* VideoWindow::QuitRequested
*****************************************************************************/
bool VideoWindow::QuitRequested()
{ {
/* FIXME: send a message ! */ status_t status;
p_main->p_intf->b_die = 1;
teardownwindow = true; i_buffer = bufferIndex;
return( false );
fDrawThreadID = spawn_thread(Draw, "drawing_thread",
B_DISPLAY_PRIORITY, (void*) this);
wait_for_thread(fDrawThreadID, &status);
} }
/***************************************************************************** /*****************************************************************************
...@@ -289,7 +344,6 @@ VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW) ...@@ -289,7 +344,6 @@ VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW)
*****************************************************************************/ *****************************************************************************/
VLCView::~VLCView() VLCView::~VLCView()
{ {
} }
/***************************************************************************** /*****************************************************************************
...@@ -297,12 +351,8 @@ VLCView::~VLCView() ...@@ -297,12 +351,8 @@ VLCView::~VLCView()
*****************************************************************************/ *****************************************************************************/
void VLCView::MouseDown(BPoint point) void VLCView::MouseDown(BPoint point)
{ {
VideoWindow *w = (VideoWindow *) Window();
if(w->is_zoomed)
{
BWindow *win = Window(); BWindow *win = Window();
win->Zoom(); win->Zoom();
}
} }
extern "C" extern "C"
...@@ -368,6 +418,7 @@ int vout_Create( vout_thread_t *p_vout ) ...@@ -368,6 +418,7 @@ int vout_Create( vout_thread_t *p_vout )
return( 1 ); return( 1 );
} }
/* force scaling off */
p_vout->b_scale = false; p_vout->b_scale = false;
/* Open and initialize device */ /* Open and initialize device */
...@@ -387,8 +438,7 @@ int vout_Create( vout_thread_t *p_vout ) ...@@ -387,8 +438,7 @@ int vout_Create( vout_thread_t *p_vout )
int vout_Init( vout_thread_t *p_vout ) int vout_Init( vout_thread_t *p_vout )
{ {
VideoWindow * p_win = p_vout->p_sys->p_window; VideoWindow * p_win = p_vout->p_sys->p_window;
u32 i_page_size;
i_page_size = p_vout->i_width * p_vout->i_height * p_vout->i_bytes_per_pixel;
if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL)) if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
{ {
p_vout->pf_setbuffers( p_vout, p_vout->pf_setbuffers( p_vout,
...@@ -403,6 +453,7 @@ int vout_Init( vout_thread_t *p_vout ) ...@@ -403,6 +453,7 @@ int vout_Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
void vout_End( vout_thread_t *p_vout ) void vout_End( vout_thread_t *p_vout )
{ {
/* place code here to end the video */
} }
/***************************************************************************** /*****************************************************************************
...@@ -426,24 +477,9 @@ int vout_Manage( vout_thread_t *p_vout ) ...@@ -426,24 +477,9 @@ int vout_Manage( vout_thread_t *p_vout )
{ {
VideoWindow * p_win = p_vout->p_sys->p_window; VideoWindow * p_win = p_vout->p_sys->p_window;
if ((p_vout->p_buffer[p_vout->i_buffer_index].i_pic_width != p_win->i_width + 1) && p_win->resizeIfRequired(p_vout->p_buffer[p_vout->i_buffer_index].i_pic_width,
(p_vout->p_buffer[p_vout->i_buffer_index].i_pic_height != p_win->i_height + 1) && p_vout->p_buffer[p_vout->i_buffer_index].i_pic_height);
(p_vout->p_buffer[p_vout->i_buffer_index].i_pic_width != 0 ))
{
if (p_win->Lock())
{
p_win->view->ClearViewBitmap();
intf_Msg("Starting Change");
intf_Msg("New width: %d Height: %d",
p_vout->p_buffer[p_vout->i_buffer_index ].i_pic_width,
p_vout->p_buffer[p_vout->i_buffer_index ].i_pic_height);
p_win->i_width = p_vout->p_buffer[p_vout->i_buffer_index].i_pic_width - 1;
p_win->i_height = p_vout->p_buffer[p_vout->i_buffer_index].i_pic_height -1;
p_win->ResizeTo((float) p_win->i_width, (float) p_win->i_height);
p_win->Unlock();
}
}
return( 0 ); return( 0 );
} }
...@@ -455,53 +491,50 @@ int vout_Manage( vout_thread_t *p_vout ) ...@@ -455,53 +491,50 @@ int vout_Manage( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
void vout_Display( vout_thread_t *p_vout ) void vout_Display( vout_thread_t *p_vout )
{ {
status_t status;
VideoWindow * p_win = p_vout->p_sys->p_window; VideoWindow * p_win = p_vout->p_sys->p_window;
/* draw buffer if required */
p_win->i_buffer_index = p_vout->i_buffer_index;
p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
if (!p_win->teardownwindow) if (!p_win->teardownwindow)
{ {
p_win->fDrawThreadID = spawn_thread(Draw, "drawing_thread", p_win->drawBuffer(p_vout->i_buffer_index);
B_DISPLAY_PRIORITY, (void*) p_win);
wait_for_thread(p_win->fDrawThreadID, &status);
} }
/* change buffer */
p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
} }
/* following functions are local */ /* following functions are local */
/***************************************************************************** /*****************************************************************************
* BeosOpenDisplay: open and initialize BeOS device * BeosOpenDisplay: open and initialize BeOS device
*****************************************************************************
* XXX?? The framebuffer mode is only provided as a fast and efficient way to
* display video, providing the card is configured and the mode ok. It is
* not portable, and is not supposed to work with many cards. Use at your
* own risk !
*****************************************************************************/ *****************************************************************************/
static int BeosOpenDisplay( vout_thread_t *p_vout ) static int BeosOpenDisplay( vout_thread_t *p_vout )
{ {
p_vout->p_sys->p_window = VideoWindow * p_win = new VideoWindow( p_vout->i_width - 1,
new VideoWindow( BRect( 80, 50, 80+p_vout->i_width-1, 50+p_vout->i_height-1 ), NULL, p_vout ); p_vout->i_height - 1,
if( p_vout->p_sys->p_window == 0 ) p_vout );
if( p_win == 0 )
{ {
free( p_vout->p_sys ); free( p_vout->p_sys );
intf_ErrMsg( "error: cannot allocate memory for VideoWindow" ); intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
return( 1 ); return( 1 );
} }
VideoWindow * p_win = p_vout->p_sys->p_window;
p_vout->i_screen_depth = p_win->i_screen_depth; p_vout->p_sys->p_window = p_win;
p_vout->i_bytes_per_pixel = p_win->i_bytes_per_pixel; /* set the system to 32bits always
let BeOS do all the work */
p_vout->b_YCbr = false;
p_vout->i_screen_depth = BITS_PER_PLANE;
p_vout->i_bytes_per_pixel = BYTES_PER_PIXEL;
p_vout->i_width = p_win->i_width + 1; p_vout->i_width = p_win->i_width + 1;
p_vout->i_height = p_win->i_height + 1; p_vout->i_height = p_win->i_height + 1;
p_vout->i_bytes_per_line = p_vout->i_width*p_win->i_bytes_per_pixel; p_vout->i_bytes_per_line = p_vout->i_width * BYTES_PER_PIXEL;
p_vout->i_red_mask = 0xff0000; p_vout->i_red_mask = 0xff0000;
p_vout->i_green_mask = 0x00ff00; p_vout->i_green_mask = 0x00ff00;
p_vout->i_blue_mask = 0x0000ff; p_vout->i_blue_mask = 0x0000ff;
return( 0 ); return( 0 );
} }
...@@ -514,8 +547,7 @@ static int BeosOpenDisplay( vout_thread_t *p_vout ) ...@@ -514,8 +547,7 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
static void BeosCloseDisplay( vout_thread_t *p_vout ) static void BeosCloseDisplay( vout_thread_t *p_vout )
{ {
/* Destroy the video window */ /* Destroy the video window */
p_vout->p_sys->p_window->Lock(); delete p_vout->p_sys->p_window;
p_vout->p_sys->p_window->Quit();
} }
} /* extern "C" */ } /* extern "C" */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment