~ubuntu-branches/ubuntu/natty/vlc/natty

« back to all changes in this revision

Viewing changes to modules/video_output/msw/glwin32.c

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2010-06-25 01:09:16 UTC
  • mfrom: (1.1.30 upstream)
  • Revision ID: james.westby@ubuntu.com-20100625010916-asxhep2mutg6g6pd
Tags: 1.1.0-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - build and install the libx264 plugin
  - add Xb-Npp header to vlc package
  - Add apport hook to include more vlc dependencies in bug reports
* Drop xulrunner patches.
* Drop 502_xulrunner_191.diff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * glwin32.c: Windows OpenGL provider
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2001-2009 the VideoLAN team
5
 
 * $Id: 4f1d81e7a90b72c35a0ab7346f226417c09fa495 $
 
5
 * $Id: 4619b7fff145076e8b613ac9cac4f6d1d86eeb7f $
6
6
 *
7
7
 * Authors: Gildas Bazin <gbazin@videolan.org>
8
8
 *
20
20
 * along with this program; if not, write to the Free Software
21
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
22
 *****************************************************************************/
23
 
 
24
 
#include <errno.h>                                                 /* ENOMEM */
25
 
 
26
23
#ifdef HAVE_CONFIG_H
27
24
# include "config.h"
28
25
#endif
29
26
 
30
27
#include <vlc_common.h>
31
28
#include <vlc_plugin.h>
32
 
#include <vlc_interface.h>
33
 
#include <vlc_vout.h>
 
29
#include <vlc_vout_display.h>
34
30
 
35
31
#include <windows.h>
36
32
#include <ddraw.h>
43
39
#   define MONITOR_DEFAULTTONEAREST 2
44
40
#endif
45
41
 
46
 
#include <GL/gl.h>
47
 
 
48
 
#include "vout.h"
 
42
#include "../opengl.h"
 
43
#include "common.h"
 
44
 
 
45
/*****************************************************************************
 
46
 * Module descriptor
 
47
 *****************************************************************************/
 
48
static int  Open (vlc_object_t *);
 
49
static void Close(vlc_object_t *);
 
50
 
 
51
vlc_module_begin()
 
52
    set_category(CAT_VIDEO)
 
53
    set_subcategory(SUBCAT_VIDEO_VOUT)
 
54
    set_shortname("OpenGL")
 
55
    set_description(N_("OpenGL video output"))
 
56
    set_capability("vout display", 20)
 
57
    add_shortcut("glwin32")
 
58
    add_shortcut("opengl")
 
59
    set_callbacks(Open, Close)
 
60
vlc_module_end()
49
61
 
50
62
/*****************************************************************************
51
63
 * Local prototypes.
52
64
 *****************************************************************************/
53
 
static int  OpenVideo  ( vlc_object_t * );
54
 
static void CloseVideo ( vlc_object_t * );
55
 
 
56
 
static int  Init      ( vout_thread_t * );
57
 
static void End       ( vout_thread_t * );
58
 
static int  Manage    ( vout_thread_t * );
59
 
static void GLSwapBuffers( vout_thread_t * );
60
 
static void FirstSwap( vout_thread_t * );
61
 
 
62
 
/*****************************************************************************
63
 
 * Module descriptor
64
 
 *****************************************************************************/
65
 
vlc_module_begin ()
66
 
    set_category( CAT_VIDEO )
67
 
    set_subcategory( SUBCAT_VIDEO_VOUT )
68
 
    set_shortname( "OpenGL" )
69
 
    set_description( N_("OpenGL video output") )
70
 
    set_capability( "opengl provider", 100 )
71
 
    add_shortcut( "glwin32" )
72
 
    set_callbacks( OpenVideo, CloseVideo )
73
 
 
74
 
    /* FIXME: Hack to avoid unregistering our window class */
75
 
    linked_with_a_crap_library_which_uses_atexit ()
76
 
vlc_module_end ()
77
 
 
78
 
#if 0 /* FIXME */
79
 
    /* check if we registered a window class because we need to
80
 
     * unregister it */
81
 
    WNDCLASS wndclass;
82
 
    if( GetClassInfo( GetModuleHandle(NULL), "VLC DirectX", &wndclass ) )
83
 
        UnregisterClass( "VLC DirectX", GetModuleHandle(NULL) );
84
 
#endif
85
 
 
86
 
/*****************************************************************************
87
 
 * OpenVideo: allocate OpenGL provider
88
 
 *****************************************************************************
89
 
 * This function creates and initializes a video window.
90
 
 *****************************************************************************/
91
 
static int OpenVideo( vlc_object_t *p_this )
 
65
static picture_pool_t *Pool  (vout_display_t *, unsigned);
 
66
static void           Prepare(vout_display_t *, picture_t *);
 
67
static void           Display(vout_display_t *, picture_t *);
 
68
static int            Control(vout_display_t *, int, va_list);
 
69
static void           Manage (vout_display_t *);
 
70
 
 
71
static void           Swap   (vout_opengl_t *);
 
72
 
 
73
/**
 
74
 * It creates an OpenGL vout display.
 
75
 */
 
76
static int Open(vlc_object_t *object)
92
77
{
93
 
    vout_thread_t * p_vout = (vout_thread_t *)p_this;
 
78
    vout_display_t *vd = (vout_display_t *)object;
 
79
    vout_display_sys_t *sys;
94
80
 
95
81
    /* Allocate structure */
96
 
    p_vout->p_sys = calloc( 1, sizeof( vout_sys_t ) );
97
 
    if( p_vout->p_sys == NULL )
 
82
    vd->sys = sys = calloc(1, sizeof(*sys));
 
83
    if (!sys)
98
84
        return VLC_ENOMEM;
99
85
 
100
 
    /* Initialisations */
101
 
    p_vout->pf_init = Init;
102
 
    p_vout->pf_end = End;
103
 
    p_vout->pf_manage = Manage;
104
 
    p_vout->pf_swap = FirstSwap;
105
 
 
106
 
    p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL;
107
 
    p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL;
108
 
    p_vout->p_sys->i_changes = 0;
109
 
    vlc_mutex_init( &p_vout->p_sys->lock );
110
 
    SetRectEmpty( &p_vout->p_sys->rect_display );
111
 
    SetRectEmpty( &p_vout->p_sys->rect_parent );
112
 
 
113
 
    var_Create( p_vout, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
114
 
 
115
 
    p_vout->p_sys->b_cursor_hidden = 0;
116
 
    p_vout->p_sys->i_lastmoved = mdate();
117
 
    p_vout->p_sys->i_mouse_hide_timeout =
118
 
        var_GetInteger(p_vout, "mouse-hide-timeout") * 1000;
119
 
 
120
 
    /* Set main window's size */
121
 
    p_vout->p_sys->i_window_width = p_vout->i_window_width;
122
 
    p_vout->p_sys->i_window_height = p_vout->i_window_height;
123
 
 
124
 
    /* Create the Vout EventThread, this thread is created by us to isolate
125
 
     * the Win32 PeekMessage function calls. We want to do this because
126
 
     * Windows can stay blocked inside this call for a long time, and when
127
 
     * this happens it thus blocks vlc's video_output thread.
128
 
     * Vout EventThread will take care of the creation of the video
129
 
     * window (because PeekMessage has to be called from the same thread which
130
 
     * created the window). */
131
 
    msg_Dbg( p_vout, "creating Vout EventThread" );
132
 
    p_vout->p_sys->p_event =
133
 
        vlc_object_create( p_vout, sizeof(event_thread_t) );
134
 
    p_vout->p_sys->p_event->p_vout = p_vout;
135
 
    p_vout->p_sys->p_event->window_ready = CreateEvent( NULL, TRUE, FALSE, NULL );
136
 
    if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",
137
 
                           EventThread, 0 ) )
138
 
    {
139
 
        msg_Err( p_vout, "cannot create Vout EventThread" );
140
 
        CloseHandle( p_vout->p_sys->p_event->window_ready );
141
 
        vlc_object_release( p_vout->p_sys->p_event );
142
 
        p_vout->p_sys->p_event = NULL;
143
 
        goto error;
144
 
    }
145
 
    WaitForSingleObject( p_vout->p_sys->p_event->window_ready, INFINITE );
146
 
    CloseHandle( p_vout->p_sys->p_event->window_ready );
147
 
 
148
 
    if( p_vout->p_sys->p_event->b_error )
149
 
    {
150
 
        msg_Err( p_vout, "Vout EventThread failed" );
151
 
        goto error;
152
 
    }
153
 
 
154
 
    vlc_object_attach( p_vout->p_sys->p_event, p_vout );
155
 
 
156
 
    msg_Dbg( p_vout, "Vout EventThread running" );
157
 
 
158
 
    /* Variable to indicate if the window should be on top of others */
159
 
    /* Trigger a callback right now */
160
 
    var_TriggerCallback( p_vout, "video-on-top" );
161
 
 
162
 
    return VLC_SUCCESS;
163
 
 
164
 
 error:
165
 
    CloseVideo( VLC_OBJECT(p_vout) );
166
 
    return VLC_EGENERIC;
167
 
}
168
 
 
169
 
/*****************************************************************************
170
 
 * Init: initialize video thread output method
171
 
 *****************************************************************************/
172
 
static int Init( vout_thread_t *p_vout )
173
 
{
 
86
    /* */
 
87
    if (CommonInit(vd))
 
88
        goto error;
 
89
 
 
90
    EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)");
 
91
 
 
92
    /* */
 
93
    sys->hGLDC = GetDC(sys->hvideownd);
 
94
 
 
95
    /* Set the pixel format for the DC */
174
96
    PIXELFORMATDESCRIPTOR pfd;
175
 
    int iFormat;
176
 
 
177
 
    /* Change the window title bar text */
178
 
    PostMessage( p_vout->p_sys->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
179
 
 
180
 
    p_vout->p_sys->hGLDC = GetDC( p_vout->p_sys->hvideownd );
181
 
 
182
 
    /* Set the pixel format for the DC */
183
 
    memset( &pfd, 0, sizeof( pfd ) );
184
 
    pfd.nSize = sizeof( pfd );
 
97
    memset(&pfd, 0, sizeof(pfd));
 
98
    pfd.nSize = sizeof(pfd);
185
99
    pfd.nVersion = 1;
186
100
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
187
101
    pfd.iPixelType = PFD_TYPE_RGBA;
188
102
    pfd.cColorBits = 24;
189
103
    pfd.cDepthBits = 16;
190
104
    pfd.iLayerType = PFD_MAIN_PLANE;
191
 
    iFormat = ChoosePixelFormat( p_vout->p_sys->hGLDC, &pfd );
192
 
    SetPixelFormat( p_vout->p_sys->hGLDC, iFormat, &pfd );
 
105
    SetPixelFormat(sys->hGLDC,
 
106
                   ChoosePixelFormat(sys->hGLDC, &pfd), &pfd);
193
107
 
194
108
    /* Create and enable the render context */
195
 
    p_vout->p_sys->hGLRC = wglCreateContext( p_vout->p_sys->hGLDC );
196
 
    wglMakeCurrent( p_vout->p_sys->hGLDC, p_vout->p_sys->hGLRC );
197
 
 
198
 
    return VLC_SUCCESS;
199
 
}
200
 
 
201
 
/*****************************************************************************
202
 
 * End: terminate Sys video thread output method
203
 
 *****************************************************************************
204
 
 * Terminate an output method created by Create.
205
 
 * It is called at the end of the thread.
206
 
 *****************************************************************************/
207
 
static void End( vout_thread_t *p_vout )
208
 
{
209
 
    wglMakeCurrent( NULL, NULL );
210
 
    wglDeleteContext( p_vout->p_sys->hGLRC );
211
 
    ReleaseDC( p_vout->p_sys->hvideownd, p_vout->p_sys->hGLDC );
212
 
    return;
213
 
}
214
 
 
215
 
/*****************************************************************************
216
 
 * CloseVideo: destroy Sys video thread output method
217
 
 *****************************************************************************
218
 
 * Terminate an output method created by Create
219
 
 *****************************************************************************/
220
 
static void CloseVideo( vlc_object_t *p_this )
221
 
{
222
 
    vout_thread_t * p_vout = (vout_thread_t *)p_this;
223
 
 
224
 
    if( p_vout->b_fullscreen )
225
 
    {
226
 
        msg_Dbg( p_vout, "Quitting fullscreen" );
227
 
        Win32ToggleFullscreen( p_vout );
228
 
        /* Force fullscreen in the core for the next video */
229
 
        var_SetBool( p_vout, "fullscreen", true );
230
 
    }
231
 
 
232
 
    if( p_vout->p_sys->p_event )
233
 
    {
234
 
        vlc_object_detach( p_vout->p_sys->p_event );
235
 
 
236
 
        /* Kill Vout EventThread */
237
 
        vlc_object_kill( p_vout->p_sys->p_event );
238
 
 
239
 
        /* we need to be sure Vout EventThread won't stay stuck in
240
 
         * GetMessage, so we send a fake message */
241
 
        if( p_vout->p_sys->hwnd )
242
 
        {
243
 
            PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
244
 
        }
245
 
 
246
 
        vlc_thread_join( p_vout->p_sys->p_event );
247
 
        vlc_object_release( p_vout->p_sys->p_event );
248
 
    }
249
 
 
250
 
    vlc_mutex_destroy( &p_vout->p_sys->lock );
251
 
 
252
 
    free( p_vout->p_sys );
253
 
    p_vout->p_sys = NULL;
254
 
}
255
 
 
256
 
/*****************************************************************************
257
 
 * Manage: handle Sys events
258
 
 *****************************************************************************
259
 
 * This function should be called regularly by the video output thread.
260
 
 * It returns a non null value if an error occurred.
261
 
 *****************************************************************************/
262
 
static int Manage( vout_thread_t *p_vout )
263
 
{
264
 
    int i_width = p_vout->p_sys->rect_dest.right -
265
 
        p_vout->p_sys->rect_dest.left;
266
 
    int i_height = p_vout->p_sys->rect_dest.bottom -
267
 
        p_vout->p_sys->rect_dest.top;
268
 
    glViewport( 0, 0, i_width, i_height );
269
 
 
270
 
    /* If we do not control our window, we check for geometry changes
271
 
     * ourselves because the parent might not send us its events. */
272
 
    vlc_mutex_lock( &p_vout->p_sys->lock );
273
 
    if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
274
 
    {
275
 
        RECT rect_parent;
276
 
        POINT point;
277
 
 
278
 
        vlc_mutex_unlock( &p_vout->p_sys->lock );
279
 
 
280
 
        GetClientRect( p_vout->p_sys->hparent, &rect_parent );
281
 
        point.x = point.y = 0;
282
 
        ClientToScreen( p_vout->p_sys->hparent, &point );
283
 
        OffsetRect( &rect_parent, point.x, point.y );
284
 
 
285
 
        if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )
286
 
        {
287
 
            p_vout->p_sys->rect_parent = rect_parent;
288
 
 
289
 
            /* This one is to force the update even if only
290
 
             * the position has changed */
291
 
            SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1,
292
 
                          rect_parent.right - rect_parent.left,
293
 
                          rect_parent.bottom - rect_parent.top, 0 );
294
 
 
295
 
            SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
296
 
                          rect_parent.right - rect_parent.left,
297
 
                          rect_parent.bottom - rect_parent.top, 0 );
298
 
        }
299
 
    }
300
 
    else
301
 
    {
302
 
        vlc_mutex_unlock( &p_vout->p_sys->lock );
303
 
    }
304
 
 
305
 
    /* autoscale toggle */
306
 
    if( p_vout->i_changes & VOUT_SCALE_CHANGE )
307
 
    {
308
 
        p_vout->i_changes &= ~VOUT_SCALE_CHANGE;
309
 
 
310
 
        p_vout->b_autoscale = var_GetBool( p_vout, "autoscale" );
311
 
        p_vout->i_zoom = (int) ZOOM_FP_FACTOR;
312
 
 
313
 
        UpdateRects( p_vout, true );
314
 
    }
315
 
 
316
 
    /* scaling factor */
317
 
    if( p_vout->i_changes & VOUT_ZOOM_CHANGE )
318
 
    {
319
 
        p_vout->i_changes &= ~VOUT_ZOOM_CHANGE;
320
 
 
321
 
        p_vout->b_autoscale = false;
322
 
        p_vout->i_zoom =
323
 
            (int)( ZOOM_FP_FACTOR * var_GetFloat( p_vout, "scale" ) );
324
 
        UpdateRects( p_vout, true );
325
 
    }
326
 
 
327
 
    /* Check for cropping / aspect changes */
328
 
    if( p_vout->i_changes & VOUT_CROP_CHANGE ||
329
 
        p_vout->i_changes & VOUT_ASPECT_CHANGE )
330
 
    {
331
 
        p_vout->i_changes &= ~VOUT_CROP_CHANGE;
332
 
        p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
333
 
 
334
 
        p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;
335
 
        p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;
336
 
        p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;
337
 
        p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;
338
 
        p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;
339
 
        p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
340
 
        p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
341
 
        p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
342
 
        UpdateRects( p_vout, true );
343
 
    }
344
 
 
345
 
    /* We used to call the Win32 PeekMessage function here to read the window
346
 
     * messages. But since window can stay blocked into this function for a
347
 
     * long time (for example when you move your window on the screen), I
348
 
     * decided to isolate PeekMessage in another thread. */
349
 
 
350
 
    /*
351
 
     * Fullscreen change
352
 
     */
353
 
    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE
354
 
        || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )
355
 
    {
356
 
        Win32ToggleFullscreen( p_vout );
357
 
 
358
 
        p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
359
 
        p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
360
 
    }
361
 
 
362
 
    /*
363
 
     * Pointer change
364
 
     */
365
 
    if( p_vout->b_fullscreen && !p_vout->p_sys->b_cursor_hidden &&
366
 
        (mdate() - p_vout->p_sys->i_lastmoved) >
367
 
            p_vout->p_sys->i_mouse_hide_timeout )
368
 
    {
369
 
        POINT point;
370
 
        HWND hwnd;
371
 
 
372
 
        /* Hide the cursor only if it is inside our window */
373
 
        GetCursorPos( &point );
374
 
        hwnd = WindowFromPoint(point);
375
 
        if( hwnd == p_vout->p_sys->hwnd || hwnd == p_vout->p_sys->hvideownd )
376
 
        {
377
 
            PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
378
 
        }
379
 
        else
380
 
        {
381
 
            p_vout->p_sys->i_lastmoved = mdate();
382
 
        }
383
 
    }
384
 
 
385
 
    /*
386
 
     * "Always on top" status change
387
 
     */
388
 
    if( p_vout->p_sys->b_on_top_change )
389
 
    {
390
 
        vlc_value_t val;
391
 
        HMENU hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
392
 
 
393
 
        var_Get( p_vout, "video-on-top", &val );
394
 
 
395
 
        /* Set the window on top if necessary */
396
 
        if( val.b_bool && !( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
397
 
                           & WS_EX_TOPMOST ) )
398
 
        {
399
 
            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
400
 
                           MF_BYCOMMAND | MFS_CHECKED );
401
 
            SetWindowPos( p_vout->p_sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0,
402
 
                          SWP_NOSIZE | SWP_NOMOVE );
403
 
        }
404
 
        else
405
 
        /* The window shouldn't be on top */
406
 
        if( !val.b_bool && ( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
407
 
                           & WS_EX_TOPMOST ) )
408
 
        {
409
 
            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
410
 
                           MF_BYCOMMAND | MFS_UNCHECKED );
411
 
            SetWindowPos( p_vout->p_sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
412
 
                          SWP_NOSIZE | SWP_NOMOVE );
413
 
        }
414
 
 
415
 
        p_vout->p_sys->b_on_top_change = false;
416
 
    }
417
 
 
418
 
    /* Check if the event thread is still running */
419
 
    if( !vlc_object_alive (p_vout->p_sys->p_event) )
420
 
    {
421
 
        return VLC_EGENERIC; /* exit */
422
 
    }
423
 
 
424
 
    return VLC_SUCCESS;
425
 
}
426
 
 
427
 
/*****************************************************************************
428
 
 * GLSwapBuffers: swap front/back buffers
429
 
 *****************************************************************************/
430
 
static void GLSwapBuffers( vout_thread_t *p_vout )
431
 
{
432
 
    SwapBuffers( p_vout->p_sys->hGLDC );
433
 
}
434
 
 
435
 
/*
436
 
** this function is only used once when the first picture is received
437
 
** this function will show the video window once a picture is ready
438
 
*/
439
 
 
440
 
static void FirstSwap( vout_thread_t *p_vout )
441
 
{
442
 
    /* get initial picture buffer swapped to front buffer */
443
 
    GLSwapBuffers( p_vout );
444
 
 
445
 
    /*
446
 
    ** Video window is initially hidden, show it now since we got a
447
 
    ** picture to show.
448
 
    */
449
 
    SetWindowPos( p_vout->p_sys->hvideownd, NULL, 0, 0, 0, 0,
450
 
        SWP_ASYNCWINDOWPOS|
451
 
        SWP_FRAMECHANGED|
452
 
        SWP_SHOWWINDOW|
453
 
        SWP_NOMOVE|
454
 
        SWP_NOSIZE|
455
 
        SWP_NOZORDER );
456
 
 
457
 
    /* use and restores proper swap function for further pictures */
458
 
    p_vout->pf_swap = GLSwapBuffers;
459
 
}
 
109
    sys->hGLRC = wglCreateContext(sys->hGLDC);
 
110
    wglMakeCurrent(sys->hGLDC, sys->hGLRC);
 
111
 
 
112
    /* */
 
113
    sys->gl.lock = NULL;
 
114
    sys->gl.unlock = NULL;
 
115
    sys->gl.swap = Swap;
 
116
    sys->gl.sys = vd;
 
117
 
 
118
    video_format_t fmt = vd->fmt;
 
119
    if (vout_display_opengl_Init(&sys->vgl, &fmt, &sys->gl))
 
120
        goto error;
 
121
 
 
122
    vout_display_info_t info = vd->info;
 
123
    info.has_double_click = true;
 
124
    info.has_hide_mouse = false;
 
125
    info.has_pictures_invalid = true;
 
126
 
 
127
   /* Setup vout_display now that everything is fine */
 
128
    vd->fmt  = fmt;
 
129
    vd->info = info;
 
130
 
 
131
    vd->pool    = Pool;
 
132
    vd->prepare = Prepare;
 
133
    vd->display = Display;
 
134
    vd->control = Control;
 
135
    vd->manage  = Manage;
 
136
 
 
137
    return VLC_SUCCESS;
 
138
 
 
139
error:
 
140
    Close(object);
 
141
    return VLC_EGENERIC;
 
142
}
 
143
 
 
144
/**
 
145
 * It destroys an OpenGL vout display.
 
146
 */
 
147
static void Close(vlc_object_t *object)
 
148
{
 
149
    vout_display_t *vd = (vout_display_t *)object;
 
150
    vout_display_sys_t *sys = vd->sys;
 
151
 
 
152
    if (sys->vgl.gl)
 
153
        vout_display_opengl_Clean(&sys->vgl);
 
154
 
 
155
    if (sys->hGLDC && sys->hGLRC)
 
156
        wglMakeCurrent(NULL, NULL);
 
157
    if (sys->hGLRC)
 
158
        wglDeleteContext(sys->hGLRC);
 
159
    if (sys->hGLDC)
 
160
        ReleaseDC(sys->hvideownd, sys->hGLDC);
 
161
 
 
162
    CommonClean(vd);
 
163
 
 
164
    free(sys);
 
165
}
 
166
 
 
167
/* */
 
168
static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
 
169
{
 
170
    vout_display_sys_t *sys = vd->sys;
 
171
    VLC_UNUSED(count);
 
172
 
 
173
    if (!sys->pool)
 
174
        sys->pool = vout_display_opengl_GetPool(&sys->vgl);
 
175
    return sys->pool;
 
176
}
 
177
 
 
178
static void Prepare(vout_display_t *vd, picture_t *picture)
 
179
{
 
180
    vout_display_sys_t *sys = vd->sys;
 
181
 
 
182
    vout_display_opengl_Prepare(&sys->vgl, picture);
 
183
}
 
184
 
 
185
static void Display(vout_display_t *vd, picture_t *picture)
 
186
{
 
187
    vout_display_sys_t *sys = vd->sys;
 
188
 
 
189
    vout_display_opengl_Display(&sys->vgl, &vd->source);
 
190
 
 
191
    picture_Release(picture);
 
192
 
 
193
    CommonDisplay(vd);
 
194
}
 
195
 
 
196
static int Control(vout_display_t *vd, int query, va_list args)
 
197
{
 
198
    switch (query) {
 
199
    case VOUT_DISPLAY_GET_OPENGL: {
 
200
        vout_opengl_t **gl = va_arg(args, vout_opengl_t **);
 
201
        *gl = &vd->sys->gl;
 
202
        return VLC_SUCCESS;
 
203
    }
 
204
    default:
 
205
        return CommonControl(vd, query, args);
 
206
    }
 
207
}
 
208
 
 
209
static void Manage (vout_display_t *vd)
 
210
{
 
211
    vout_display_sys_t *sys = vd->sys;
 
212
 
 
213
    CommonManage(vd);
 
214
 
 
215
    const int width  = sys->rect_dest.right  - sys->rect_dest.left;
 
216
    const int height = sys->rect_dest.bottom - sys->rect_dest.top;
 
217
    glViewport(0, 0, width, height);
 
218
}
 
219
 
 
220
static void Swap(vout_opengl_t *gl)
 
221
{
 
222
    vout_display_t *vd = gl->sys;
 
223
 
 
224
    SwapBuffers(vd->sys->hGLDC);
 
225
}
 
226