00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include <vlc/vlc.h>
00032 #include <vlc/intf.h>
00033 #include <vlc/vout.h>
00034
00035 #include <commctrl.h>
00036
00037 #define SHFS_SHOWSIPBUTTON 0x0004
00038 #define SHFS_HIDESIPBUTTON 0x0008
00039
00040 #if defined(UNDER_CE) && !defined(__PLUGIN__)
00041 # define MENU_HEIGHT 26
00042 BOOL SHFullScreen(HWND hwndRequester, DWORD dwState);
00043 #else
00044 # define MENU_HEIGHT 0
00045 # define SHFullScreen(a,b)
00046 #endif
00047
00048 #ifdef MODULE_NAME_IS_wingapi
00049 typedef struct GXDisplayProperties {
00050 DWORD cxWidth;
00051 DWORD cyHeight;
00052 long cbxPitch;
00053 long cbyPitch;
00054 long cBPP;
00055 DWORD ffFormat;
00056 } GXDisplayProperties;
00057
00058 typedef struct GXScreenRect {
00059 DWORD dwTop;
00060 DWORD dwLeft;
00061 DWORD dwWidth;
00062 DWORD dwHeight;
00063 } GXScreenRect;
00064
00065 # define GX_FULLSCREEN 0x01
00066 # define GX_NORMALKEYS 0x02
00067 # define GX_LANDSCAPEKEYS 0x03
00068
00069 # ifndef kfLandscape
00070 # define kfLandscape 0x8
00071 # define kfPalette 0x10
00072 # define kfDirect 0x20
00073 # define kfDirect555 0x40
00074 # define kfDirect565 0x80
00075 # define kfDirect888 0x100
00076 # define kfDirect444 0x200
00077 # define kfDirectInverted 0x400
00078 # endif
00079 #endif
00080
00081 #define MAX_DIRECTBUFFERS 10
00082
00083 #ifdef UNDER_CE
00084 #ifndef WS_OVERLAPPEDWINDOW
00085 # define WS_OVERLAPPEDWINDOW 0xcf0000
00086 #endif
00087 #ifndef WS_EX_NOPARENTNOTIFY
00088 # define WS_EX_NOPARENTNOTIFY 4
00089 #endif
00090 #ifndef WS_EX_APPWINDOW
00091 #define WS_EX_APPWINDOW 0x40000
00092 #endif
00093 #define SetWindowLongPtr SetWindowLong
00094 #define GetWindowLongPtr GetWindowLong
00095 #define GWLP_USERDATA GWL_USERDATA
00096 #define AdjustWindowRect(a,b,c)
00097 #endif //UNDER_CE
00098
00099 #ifndef WS_NONAVDONEBUTTON
00100 #define WS_NONAVDONEBUTTON 0
00101 #endif
00102
00103
00104
00105 static int OpenVideo ( vlc_object_t * );
00106 static void CloseVideo ( vlc_object_t * );
00107
00108 static int Init ( vout_thread_t * );
00109 static void End ( vout_thread_t * );
00110 static int Manage ( vout_thread_t * );
00111 static void Render ( vout_thread_t *, picture_t * );
00112 #ifdef MODULE_NAME_IS_wingapi
00113 static void DisplayGAPI( vout_thread_t *, picture_t * );
00114 static int GAPILockSurface( vout_thread_t *, picture_t * );
00115 static int GAPIUnlockSurface( vout_thread_t *, picture_t * );
00116 #else
00117 static void DisplayGDI( vout_thread_t *, picture_t * );
00118 #endif
00119 static void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );
00120
00121 static void EventThread ( vlc_object_t * );
00122 static long FAR PASCAL WndProc ( HWND, UINT, WPARAM, LPARAM );
00123 static void InitBuffers ( vout_thread_t * );
00124 static void UpdateRects ( vout_thread_t *, vlc_bool_t );
00125
00126 static int Control( vout_thread_t *p_vout, int i_query, va_list args );
00127
00128
00129
00130
00131 struct vout_sys_t
00132 {
00133
00134 vlc_object_t * p_event;
00135
00136
00137 HWND hwnd;
00138 HWND hvideownd;
00139 HWND hfswnd;
00140 int i_depth;
00141 HWND hparent;
00142 WNDPROC pf_wndproc;
00143 volatile uint16_t i_changes;
00144 RECT window_placement;
00145
00146
00147 int i_window_x;
00148 int i_window_y;
00149 int i_window_width;
00150 int i_window_height;
00151 int i_window_style;
00152 int render_width;
00153 int render_height;
00154
00155
00156 RECT rect_src;
00157 RECT rect_src_clipped;
00158 RECT rect_dest;
00159 RECT rect_dest_clipped;
00160 RECT rect_parent;
00161 RECT rect_display;
00162
00163
00164 HDC off_dc;
00165 HBITMAP off_bitmap;
00166 uint8_t * p_pic_buffer;
00167 int i_pic_pitch;
00168 int i_pic_pixel_pitch;
00169
00170 BITMAPINFO bitmapinfo;
00171 RGBQUAD red;
00172 RGBQUAD green;
00173 RGBQUAD blue;
00174
00175
00176 vlc_bool_t b_video_display;
00177
00178
00179 vlc_bool_t b_focus;
00180 vlc_bool_t b_parent_focus;
00181
00182 #ifdef MODULE_NAME_IS_wingapi
00183 HINSTANCE gapi_dll;
00184
00185
00186 int (*GXOpenDisplay)( HWND hWnd, DWORD dwFlags );
00187 int (*GXCloseDisplay)();
00188 void *(*GXBeginDraw)();
00189 int (*GXEndDraw)();
00190 GXDisplayProperties (*GXGetDisplayProperties)();
00191 int (*GXSuspend)();
00192 int (*GXResume)();
00193 #endif
00194 };
00195
00196 #define GXOpenDisplay p_vout->p_sys->GXOpenDisplay
00197 #define GXCloseDisplay p_vout->p_sys->GXCloseDisplay
00198 #define GXBeginDraw p_vout->p_sys->GXBeginDraw
00199 #define GXEndDraw p_vout->p_sys->GXEndDraw
00200 #define GXGetDisplayProperties p_vout->p_sys->GXGetDisplayProperties
00201
00202 #ifdef MODULE_NAME_IS_wingapi
00203 # define GXSuspend p_vout->p_sys->GXSuspend
00204 # define GXResume p_vout->p_sys->GXResume
00205 #else
00206 # define GXSuspend()
00207 # define GXResume()
00208 #endif
00209
00210 #define DX_POSITION_CHANGE 0x1000
00211
00212
00213
00214
00215 vlc_module_begin();
00216 set_category( CAT_VIDEO );
00217 set_subcategory( SUBCAT_VIDEO_VOUT );
00218 #ifdef MODULE_NAME_IS_wingapi
00219 set_shortname( _("Windows GAPI") );
00220 set_description( _("Windows GAPI video output") );
00221 set_capability( "video output", 20 );
00222 #else
00223 set_shortname( _("Windows GDI") );
00224 set_description( _("Windows GDI video output") );
00225 set_capability( "video output", 10 );
00226 #endif
00227 set_callbacks( OpenVideo, CloseVideo );
00228 vlc_module_end();
00229
00230
00231
00232
00233 static int OpenVideo ( vlc_object_t *p_this )
00234 {
00235 vout_thread_t * p_vout = (vout_thread_t *)p_this;
00236 vlc_value_t val;
00237
00238 p_vout->p_sys = (vout_sys_t *)malloc( sizeof(vout_sys_t) );
00239 if( !p_vout->p_sys ) return VLC_ENOMEM;
00240
00241 #ifdef MODULE_NAME_IS_wingapi
00242
00243 p_vout->p_sys->gapi_dll = LoadLibrary( _T("GX.DLL") );
00244 if( p_vout->p_sys->gapi_dll == NULL )
00245 {
00246 msg_Warn( p_vout, "failed loading gx.dll" );
00247 free( p_vout->p_sys );
00248 return VLC_EGENERIC;
00249 }
00250
00251 GXOpenDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll,
00252 _T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z") );
00253 GXCloseDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll,
00254 _T("?GXCloseDisplay@@YAHXZ") );
00255 GXBeginDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll,
00256 _T("?GXBeginDraw@@YAPAXXZ") );
00257 GXEndDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll,
00258 _T("?GXEndDraw@@YAHXZ") );
00259 GXGetDisplayProperties = (void *)GetProcAddress( p_vout->p_sys->gapi_dll,
00260 _T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ") );
00261 GXSuspend = (void *)GetProcAddress( p_vout->p_sys->gapi_dll,
00262 _T("?GXSuspend@@YAHXZ") );
00263 GXResume = GetProcAddress( p_vout->p_sys->gapi_dll,
00264 _T("?GXResume@@YAHXZ") );
00265
00266 if( !GXOpenDisplay || !GXCloseDisplay || !GXBeginDraw || !GXEndDraw ||
00267 !GXGetDisplayProperties || !GXSuspend || !GXResume )
00268 {
00269 msg_Err( p_vout, "failed GetProcAddress on gapi.dll" );
00270 free( p_vout->p_sys );
00271 return VLC_EGENERIC;
00272 }
00273
00274 msg_Dbg( p_vout, "GAPI DLL loaded" );
00275
00276 p_vout->p_sys->render_width = p_vout->render.i_width;
00277 p_vout->p_sys->render_height = p_vout->render.i_height;
00278 #endif
00279
00280 p_vout->p_sys->p_event = (vlc_object_t *)
00281 vlc_object_create( p_vout, VLC_OBJECT_GENERIC );
00282 if( !p_vout->p_sys->p_event )
00283 {
00284 free( p_vout->p_sys );
00285 return VLC_ENOMEM;
00286 }
00287
00288 var_Create( p_vout->p_sys->p_event, "p_vout", VLC_VAR_ADDRESS );
00289 val.p_address = (void *)p_vout;
00290 var_Set( p_vout->p_sys->p_event, "p_vout", val );
00291
00292 SetRectEmpty( &p_vout->p_sys->rect_display );
00293 SetRectEmpty( &p_vout->p_sys->rect_parent );
00294
00295 if( vlc_thread_create( p_vout->p_sys->p_event, "GDI Event Thread",
00296 EventThread, 0, 1 ) )
00297 {
00298 msg_Err( p_vout, "cannot spawn EventThread" );
00299 return VLC_ETHREAD;
00300 }
00301
00302 p_vout->pf_init = Init;
00303 p_vout->pf_end = End;
00304 p_vout->pf_manage = Manage;
00305 p_vout->pf_render = Render;
00306 #ifdef MODULE_NAME_IS_wingapi
00307 p_vout->pf_display = DisplayGAPI;
00308 #else
00309 p_vout->pf_display = DisplayGDI;
00310 #endif
00311 p_vout->p_sys->i_changes = 0;
00312
00313 p_vout->p_sys->b_focus = 0;
00314 p_vout->p_sys->b_parent_focus = 0;
00315
00316 return VLC_SUCCESS;
00317 }
00318
00319
00320
00321
00322 static void CloseVideo ( vlc_object_t *p_this )
00323 {
00324 vout_thread_t * p_vout = (vout_thread_t *)p_this;
00325
00326 p_vout->p_sys->p_event->b_die = VLC_TRUE;
00327 PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0 );
00328 vlc_thread_join( p_vout->p_sys->p_event );
00329
00330 #ifdef MODULE_NAME_IS_wingapi
00331 FreeLibrary( p_vout->p_sys->gapi_dll );
00332 #endif
00333
00334 var_Destroy( p_vout->p_sys->p_event, "p_vout" );
00335 vlc_object_destroy( p_vout->p_sys->p_event );
00336 free( p_vout->p_sys );
00337 }
00338
00339
00340
00341
00342 static int Init( vout_thread_t *p_vout )
00343 {
00344 picture_t *p_pic;
00345
00346 p_vout->p_sys->rect_display.left = 0;
00347 p_vout->p_sys->rect_display.top = 0;
00348 p_vout->p_sys->rect_display.right = GetSystemMetrics(SM_CXSCREEN);
00349 p_vout->p_sys->rect_display.bottom = GetSystemMetrics(SM_CYSCREEN);
00350
00351 p_vout->p_sys->b_video_display = VLC_TRUE;
00352 p_vout->p_sys->p_event->b_die = VLC_FALSE;
00353
00354 I_OUTPUTPICTURES = 0;
00355
00356
00357 switch( p_vout->p_sys->i_depth )
00358 {
00359 case 8:
00360 p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
00361 p_vout->output.pf_setpalette = SetPalette;
00362 break;
00363 case 15:
00364 p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5');
00365 p_vout->output.i_rmask = 0x7c00;
00366 p_vout->output.i_gmask = 0x03e0;
00367 p_vout->output.i_bmask = 0x001f;
00368 break;
00369 case 16:
00370 p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6');
00371 p_vout->output.i_rmask = 0xf800;
00372 p_vout->output.i_gmask = 0x07e0;
00373 p_vout->output.i_bmask = 0x001f;
00374 break;
00375 case 24:
00376 p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4');
00377 p_vout->output.i_rmask = 0x00ff0000;
00378 p_vout->output.i_gmask = 0x0000ff00;
00379 p_vout->output.i_bmask = 0x000000ff;
00380 break;
00381 case 32:
00382 p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');
00383 p_vout->output.i_rmask = 0x00ff0000;
00384 p_vout->output.i_gmask = 0x0000ff00;
00385 p_vout->output.i_bmask = 0x000000ff;
00386 break;
00387 default:
00388 msg_Err( p_vout, "screen depth %i not supported",
00389 p_vout->p_sys->i_depth );
00390 return VLC_EGENERIC;
00391 break;
00392 }
00393
00394 p_pic = &p_vout->p_picture[0];
00395
00396 #ifdef MODULE_NAME_IS_wingapi
00397 p_vout->output.i_width = 0;
00398 p_vout->output.i_height = 0;
00399 p_pic->pf_lock = GAPILockSurface;
00400 p_pic->pf_unlock = GAPIUnlockSurface;
00401 Manage( p_vout );
00402 GAPILockSurface( p_vout, p_pic );
00403 p_vout->i_changes = 0;
00404 p_vout->output.i_width = p_vout->p_sys->render_width;
00405 p_vout->output.i_height = p_vout->p_sys->render_height;
00406
00407 #else
00408 p_vout->output.i_width = p_vout->render.i_width;
00409 p_vout->output.i_height = p_vout->render.i_height;
00410
00411 p_vout->fmt_out = p_vout->fmt_in;
00412 p_vout->fmt_out.i_chroma = p_vout->output.i_chroma;
00413 #endif
00414
00415 p_vout->output.i_aspect = p_vout->render.i_aspect;
00416
00417 p_pic->p->p_pixels = p_vout->p_sys->p_pic_buffer;
00418 p_pic->p->i_lines = p_vout->output.i_height;
00419 p_pic->p->i_visible_lines = p_vout->output.i_height;
00420 p_pic->p->i_pitch = p_vout->p_sys->i_pic_pitch;
00421 p_pic->p->i_pixel_pitch = p_vout->p_sys->i_pic_pixel_pitch;
00422 p_pic->p->i_visible_pitch = p_vout->output.i_width *
00423 p_pic->p->i_pixel_pitch;
00424 p_pic->i_planes = 1;
00425 p_pic->i_status = DESTROYED_PICTURE;
00426 p_pic->i_type = DIRECT_PICTURE;
00427
00428 PP_OUTPUTPICTURE[ I_OUTPUTPICTURES++ ] = p_pic;
00429
00430 return VLC_SUCCESS;
00431 }
00432
00433
00434
00435
00436 static void End( vout_thread_t *p_vout )
00437 {
00438 }
00439
00440
00441
00442
00443
00444
00445
00446 static int Manage( vout_thread_t *p_vout )
00447 {
00448 #ifndef UNDER_CE
00449 WINDOWPLACEMENT window_placement;
00450 #endif
00451
00452
00453
00454 if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
00455 {
00456 RECT rect_parent;
00457 POINT point;
00458
00459 GetClientRect( p_vout->p_sys->hparent, &rect_parent );
00460 point.x = point.y = 0;
00461 ClientToScreen( p_vout->p_sys->hparent, &point );
00462 OffsetRect( &rect_parent, point.x, point.y );
00463
00464 if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )
00465 {
00466 int i_x, i_y, i_width, i_height;
00467 p_vout->p_sys->rect_parent = rect_parent;
00468
00469
00470
00471 SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1,
00472 rect_parent.right - rect_parent.left,
00473 rect_parent.bottom - rect_parent.top, 0 );
00474
00475 SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
00476 rect_parent.right - rect_parent.left,
00477 rect_parent.bottom - rect_parent.top, 0 );
00478
00479 vout_PlacePicture( p_vout, rect_parent.right - rect_parent.left,
00480 rect_parent.bottom - rect_parent.top,
00481 &i_x, &i_y, &i_width, &i_height );
00482
00483 SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,
00484 i_x, i_y, i_width, i_height, 0 );
00485 }
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE
00497 || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )
00498 {
00499 int i_style = 0;
00500 vlc_value_t val;
00501
00502 HWND hwnd = (p_vout->p_sys->hparent && p_vout->p_sys->hfswnd) ?
00503 p_vout->p_sys->hfswnd : p_vout->p_sys->hwnd;
00504
00505 p_vout->b_fullscreen = ! p_vout->b_fullscreen;
00506
00507
00508 #ifndef UNDER_CE
00509 window_placement.length = sizeof(WINDOWPLACEMENT);
00510 GetWindowPlacement( hwnd, &window_placement );
00511 #endif
00512 if( p_vout->b_fullscreen )
00513 {
00514 #ifndef UNDER_CE
00515
00516 int i_style = WS_CLIPCHILDREN | WS_VISIBLE;
00517 SetWindowLong( hwnd, GWL_STYLE, i_style );
00518
00519 if( p_vout->p_sys->hparent )
00520 {
00521
00522
00523 POINT point = {0,0};
00524 RECT rect;
00525 ClientToScreen( p_vout->p_sys->hwnd, &point );
00526 GetClientRect( p_vout->p_sys->hwnd, &rect );
00527 SetWindowPos( hwnd, 0, point.x, point.y,
00528 rect.right, rect.bottom,
00529 SWP_NOZORDER|SWP_FRAMECHANGED );
00530 GetWindowPlacement( hwnd, &window_placement );
00531 }
00532
00533
00534 window_placement.showCmd = SW_SHOWMAXIMIZED;
00535 SetWindowPlacement( hwnd, &window_placement );
00536 SetWindowPos( hwnd, 0, 0, 0, 0, 0,
00537 SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
00538 #endif
00539
00540 if( p_vout->p_sys->hparent )
00541 {
00542 RECT rect;
00543 GetClientRect( hwnd, &rect );
00544 SetParent( p_vout->p_sys->hwnd, hwnd );
00545 SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
00546 rect.right, rect.bottom,
00547 SWP_NOZORDER|SWP_FRAMECHANGED );
00548 }
00549
00550 ShowWindow( hwnd, SW_SHOW );
00551 SetForegroundWindow( hwnd );
00552 }
00553 else
00554 {
00555
00556
00557
00558 #ifndef UNDER_CE
00559
00560 window_placement.showCmd = SW_SHOWNORMAL;
00561 SetWindowPlacement( hwnd, &window_placement );
00562 SetWindowPos( hwnd, 0, 0, 0, 0, 0,
00563 SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
00564 #endif
00565
00566 if( p_vout->p_sys->hparent )
00567 {
00568 RECT rect;
00569 GetClientRect( p_vout->p_sys->hparent, &rect );
00570 SetParent( p_vout->p_sys->hwnd, p_vout->p_sys->hparent );
00571 SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
00572 rect.right, rect.bottom,
00573 SWP_NOZORDER|SWP_FRAMECHANGED );
00574
00575 ShowWindow( hwnd, SW_HIDE );
00576 SetForegroundWindow( p_vout->p_sys->hparent );
00577 }
00578
00579
00580
00581 }
00582
00583
00584 ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
00585 UpdateWindow( p_vout->p_sys->hwnd );
00586
00587
00588 val.b_bool = p_vout->b_fullscreen;
00589 var_Set( p_vout, "fullscreen", val );
00590
00591 p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
00592 p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
00593 }
00594
00595 return VLC_SUCCESS;
00596 }
00597
00598
00599
00600
00601 static void Render( vout_thread_t *p_vout, picture_t *p_pic )
00602 {
00603
00604 }
00605
00606
00607
00608
00609 #define rect_src p_vout->p_sys->rect_src
00610 #define rect_src_clipped p_vout->p_sys->rect_src_clipped
00611 #define rect_dest p_vout->p_sys->rect_dest
00612 #define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
00613
00614 #ifndef MODULE_NAME_IS_wingapi
00615 static void DisplayGDI( vout_thread_t *p_vout, picture_t *p_pic )
00616 {
00617 vout_sys_t *p_sys = p_vout->p_sys;
00618 RECT rect_dst = rect_dest_clipped;
00619 HDC hdc = GetDC( p_sys->hvideownd );
00620
00621 OffsetRect( &rect_dst, -rect_dest.left, -rect_dest.top );
00622 SelectObject( p_sys->off_dc, p_sys->off_bitmap );
00623
00624 if( rect_dest_clipped.right - rect_dest_clipped.left !=
00625 rect_src_clipped.right - rect_src_clipped.left ||
00626 rect_dest_clipped.bottom - rect_dest_clipped.top !=
00627 rect_src_clipped.bottom - rect_src_clipped.top )
00628 {
00629 StretchBlt( hdc, rect_dst.left, rect_dst.top,
00630 rect_dst.right, rect_dst.bottom,
00631 p_sys->off_dc, rect_src_clipped.left, rect_src_clipped.top,
00632 rect_src_clipped.right, rect_src_clipped.bottom, SRCCOPY );
00633 }
00634 else
00635 {
00636 BitBlt( hdc, rect_dst.left, rect_dst.top,
00637 rect_dst.right, rect_dst.bottom,
00638 p_sys->off_dc, rect_src_clipped.left,
00639 rect_src_clipped.top, SRCCOPY );
00640 }
00641
00642 ReleaseDC( p_sys->hwnd, hdc );
00643 }
00644 #else
00645
00646 static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic )
00647 {
00648 vout_sys_t *p_sys = p_vout->p_sys;
00649 int i_x, i_y, i_width, i_height;
00650 RECT video_rect;
00651 POINT point;
00652
00653
00654 if( ( GetForegroundWindow() != GetParent(p_sys->hwnd) ) ||
00655 ( p_sys->b_video_display == VLC_FALSE ) )
00656 {
00657
00658 }
00659
00660 GetClientRect( p_sys->hwnd, &video_rect);
00661 vout_PlacePicture( p_vout, video_rect.right - video_rect.left,
00662 video_rect.bottom - video_rect.top,
00663 &i_x, &i_y, &i_width, &i_height );
00664 point.x = point.y = 0;
00665 ClientToScreen( p_sys->hwnd, &point );
00666 i_x += point.x + video_rect.left;
00667 i_y += point.y + video_rect.top;
00668
00669 if( i_width != p_vout->output.i_width ||
00670 i_height != p_vout->output.i_height )
00671 {
00672 GXDisplayProperties gxdisplayprop = GXGetDisplayProperties();
00673
00674 p_sys->render_width = i_width;
00675 p_sys->render_height = i_height;
00676 p_vout->i_changes |= VOUT_SIZE_CHANGE;
00677
00678 msg_Dbg( p_vout, "vout size change (%ix%i -> %ix%i)",
00679 i_width, i_height, p_vout->output.i_width,
00680 p_vout->output.i_height );
00681
00682 p_vout->p_sys->i_pic_pixel_pitch = gxdisplayprop.cbxPitch;
00683 p_vout->p_sys->i_pic_pitch = gxdisplayprop.cbyPitch;
00684 return VLC_EGENERIC;
00685 }
00686 else
00687 {
00688 GXDisplayProperties gxdisplayprop;
00689 RECT display_rect, dest_rect;
00690 uint8_t *p_dest, *p_src = p_pic->p->p_pixels;
00691
00692 video_rect.left = i_x; video_rect.top = i_y;
00693 video_rect.right = i_x + i_width;
00694 video_rect.bottom = i_y + i_height;
00695
00696 gxdisplayprop = GXGetDisplayProperties();
00697 display_rect.left = 0; display_rect.top = 0;
00698 display_rect.right = gxdisplayprop.cxWidth;
00699 display_rect.bottom = gxdisplayprop.cyHeight;
00700
00701 if( !IntersectRect( &dest_rect, &video_rect, &display_rect ) )
00702 {
00703 return VLC_EGENERIC;
00704 }
00705
00706 #if 0
00707 msg_Err( p_vout, "video (%d,%d,%d,%d) display (%d,%d,%d,%d) "
00708 "dest (%d,%d,%d,%d)",
00709 video_rect.left, video_rect.right,
00710 video_rect.top, video_rect.bottom,
00711 display_rect.left, display_rect.right,
00712 display_rect.top, display_rect.bottom,
00713 dest_rect.left, dest_rect.right,
00714 dest_rect.top, dest_rect.bottom );
00715 #endif
00716
00717 if( !(p_dest = GXBeginDraw()) )
00718 {
00719 #if 0
00720 msg_Err( p_vout, "GXBeginDraw error %d ", GetLastError() );
00721 #endif
00722 return VLC_EGENERIC;
00723 }
00724
00725 p_src += (dest_rect.left - video_rect.left) * gxdisplayprop.cbxPitch +
00726 (dest_rect.top - video_rect.top) * p_pic->p->i_pitch;
00727 p_dest += dest_rect.left * gxdisplayprop.cbxPitch +
00728 dest_rect.top * gxdisplayprop.cbyPitch;
00729 i_width = dest_rect.right - dest_rect.left;
00730 i_height = dest_rect.bottom - dest_rect.top;
00731
00732 p_pic->p->p_pixels = p_dest;
00733 }
00734
00735 return VLC_SUCCESS;
00736 }
00737
00738 static int GAPIUnlockSurface( vout_thread_t *p_vout, picture_t *p_pic )
00739 {
00740 GXEndDraw();
00741 return VLC_SUCCESS;
00742 }
00743
00744 static void DisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic )
00745 {
00746 }
00747 #endif
00748
00749 #undef rect_src
00750 #undef rect_src_clipped
00751 #undef rect_dest
00752 #undef rect_dest_clipped
00753
00754
00755
00756 static void SetPalette( vout_thread_t *p_vout,
00757 uint16_t *red, uint16_t *green, uint16_t *blue )
00758 {
00759 msg_Err( p_vout, "FIXME: SetPalette unimplemented" );
00760 }
00761
00762
00763
00764
00765 static void EventThread ( vlc_object_t *p_event )
00766 {
00767 vout_thread_t *p_vout;
00768 vlc_value_t val;
00769
00770 int i_style;
00771 WNDCLASS wc;
00772 MSG msg;
00773
00774
00775 var_Get( p_event, "p_vout", &val );
00776 p_vout = (vout_thread_t *)val.p_address;
00777
00778
00779 memset( &wc, 0, sizeof(wc) );
00780 wc.style = CS_HREDRAW | CS_VREDRAW;
00781 wc.lpfnWndProc = (WNDPROC)WndProc;
00782 wc.cbClsExtra = 0;
00783 wc.cbWndExtra = 0;
00784 wc.hInstance = GetModuleHandle(NULL);
00785 wc.hIcon = 0;
00786 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00787 wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
00788 wc.lpszMenuName = 0;
00789 wc.lpszClassName = _T("VLC WinGDI");
00790 RegisterClass( &wc );
00791
00792
00793 wc.lpszClassName = _T("VLC WinGDI video"); wc.hIcon = 0;
00794 RegisterClass(&wc);
00795
00796
00797 p_vout->p_sys->hparent = (HWND)
00798 vout_RequestWindow( p_vout, &p_vout->p_sys->i_window_x,
00799 &p_vout->p_sys->i_window_y,
00800 (unsigned int *)&p_vout->p_sys->i_window_width,
00801 (unsigned int *)&p_vout->p_sys->i_window_height );
00802
00803 if( p_vout->p_sys->hparent )
00804 ShowWindow( p_vout->p_sys->hparent, SW_SHOW );
00805
00806 if( p_vout->p_sys->hparent )
00807 i_style = WS_VISIBLE|WS_CLIPCHILDREN|WS_CHILD;
00808 else
00809 i_style = WS_OVERLAPPEDWINDOW|WS_SIZEBOX|WS_VISIBLE|WS_CLIPCHILDREN;
00810
00811 p_vout->p_sys->i_window_style = i_style;
00812
00813 p_vout->p_sys->hwnd =
00814 CreateWindow( _T("VLC WinGDI"), _T(VOUT_TITLE), i_style,
00815 (p_vout->p_sys->i_window_x < 0) ? CW_USEDEFAULT :
00816 p_vout->p_sys->i_window_x,
00817 (p_vout->p_sys->i_window_y < 0) ? CW_USEDEFAULT :
00818 p_vout->p_sys->i_window_y,
00819 p_vout->p_sys->i_window_width,
00820 p_vout->p_sys->i_window_height + 10,
00821 p_vout->p_sys->hparent, NULL,
00822 GetModuleHandle(NULL), (LPVOID)p_vout );
00823
00824 if( !p_vout->p_sys->hwnd )
00825 {
00826 msg_Warn( p_vout, "couldn't create window" );
00827 return;
00828 }
00829 msg_Warn( p_vout, "Created WinGDI window" );
00830
00831 if( p_vout->p_sys->hparent )
00832 {
00833 LONG i_style;
00834
00835
00836 i_style = GetWindowLong( p_vout->p_sys->hparent, GWL_STYLE );
00837
00838 if( !(i_style & WS_CLIPCHILDREN) )
00839
00840 SetWindowLong( p_vout->p_sys->hparent, GWL_STYLE,
00841 i_style | WS_CLIPCHILDREN );
00842
00843
00844 p_vout->p_sys->hfswnd =
00845 CreateWindowEx( WS_EX_APPWINDOW, _T("VLC WinGDI"),
00846 _T(VOUT_TITLE),
00847 WS_NONAVDONEBUTTON|WS_CLIPCHILDREN,
00848 CW_USEDEFAULT, CW_USEDEFAULT,
00849 CW_USEDEFAULT, CW_USEDEFAULT,
00850 NULL, NULL, GetModuleHandle(NULL), (LPVOID)p_vout);
00851 }
00852
00853
00854 ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
00855 UpdateWindow( p_vout->p_sys->hwnd );
00856
00857
00858 p_vout->p_sys->hvideownd =
00859 CreateWindow( _T("VLC WinGDI video"), _T(""),
00860 WS_CHILD | WS_VISIBLE,
00861 CW_USEDEFAULT, CW_USEDEFAULT,
00862 CW_USEDEFAULT, CW_USEDEFAULT,
00863 p_vout->p_sys->hwnd,
00864 NULL, GetModuleHandle(NULL),
00865 (LPVOID)p_vout );
00866
00867
00868 InitBuffers( p_vout );
00869
00870 p_vout->pf_control = Control;
00871
00872
00873 vlc_thread_ready( p_event );
00874
00875 while( !p_event->b_die && GetMessage( &msg, 0, 0, 0 ) )
00876 {
00877
00878 if( p_event->b_die ) break;
00879
00880 switch( msg.message )
00881 {
00882 case WM_KEYDOWN:
00883 switch( msg.wParam )
00884 {
00885 case VK_ESCAPE:
00886 p_event->p_vlc->b_die = VLC_TRUE;
00887 break;
00888 }
00889 TranslateMessage( &msg );
00890 break;
00891
00892 case WM_CHAR:
00893 switch( msg.wParam )
00894 {
00895 case 'q':
00896 case 'Q':
00897 p_event->p_vlc->b_die = VLC_TRUE;
00898 break;
00899 }
00900 break;
00901
00902 default:
00903 TranslateMessage( &msg );
00904 DispatchMessage( &msg );
00905 break;
00906 }
00907 }
00908
00909 msg_Dbg( p_vout, "CloseWindow" );
00910
00911 #ifdef MODULE_NAME_IS_wingapi
00912 GXCloseDisplay();
00913 #else
00914 DeleteDC( p_vout->p_sys->off_dc );
00915 DeleteObject( p_vout->p_sys->off_bitmap );
00916 #endif
00917
00918 DestroyWindow( p_vout->p_sys->hwnd );
00919 if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd );
00920
00921 if( p_vout->p_sys->hparent )
00922 vout_ReleaseWindow( p_vout, (void *)p_vout->p_sys->hparent );
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932 static void UpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
00933 {
00934 #define rect_src p_vout->p_sys->rect_src
00935 #define rect_src_clipped p_vout->p_sys->rect_src_clipped
00936 #define rect_dest p_vout->p_sys->rect_dest
00937 #define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
00938
00939 int i_width, i_height, i_x, i_y;
00940
00941 RECT rect;
00942 POINT point;
00943
00944
00945 GetClientRect( p_vout->p_sys->hwnd, &rect );
00946
00947
00948 point.x = point.y = 0;
00949 ClientToScreen( p_vout->p_sys->hwnd, &point );
00950
00951
00952 if( !b_force
00953 && p_vout->p_sys->i_window_width == rect.right
00954 && p_vout->p_sys->i_window_height == rect.bottom
00955 && p_vout->p_sys->i_window_x == point.x
00956 && p_vout->p_sys->i_window_y == point.y )
00957 {
00958 return;
00959 }
00960
00961
00962 p_vout->p_sys->i_window_x = point.x;
00963 p_vout->p_sys->i_window_y = point.y;
00964 p_vout->p_sys->i_window_width = rect.right;
00965 p_vout->p_sys->i_window_height = rect.bottom;
00966
00967 vout_PlacePicture( p_vout, rect.right, rect.bottom,
00968 &i_x, &i_y, &i_width, &i_height );
00969
00970 if( p_vout->p_sys->hvideownd )
00971 SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,
00972 i_x, i_y, i_width, i_height, 0 );
00973
00974
00975 rect_dest.left = point.x + i_x;
00976 rect_dest.right = rect_dest.left + i_width;
00977 rect_dest.top = point.y + i_y;
00978 rect_dest.bottom = rect_dest.top + i_height;
00979
00980
00981 if( !IntersectRect( &rect_dest_clipped, &rect_dest,
00982 &p_vout->p_sys->rect_display ) )
00983 {
00984 SetRectEmpty( &rect_src_clipped );
00985 return;
00986 }
00987
00988 #if 0
00989 msg_Dbg( p_vout, "image_dst_clipped coords: %i,%i,%i,%i",
00990 rect_dest_clipped.left, rect_dest_clipped.top,
00991 rect_dest_clipped.right, rect_dest_clipped.bottom );
00992 #endif
00993
00994
00995 if( (rect_dest_clipped.right - rect_dest_clipped.left)==0 ||
00996 (rect_dest_clipped.bottom - rect_dest_clipped.top)==0 )
00997 {
00998 SetRectEmpty( &rect_src_clipped );
00999 return;
01000 }
01001
01002
01003 rect_src.left = 0;
01004 rect_src.top = 0;
01005 rect_src.right = p_vout->output.i_width;
01006 rect_src.bottom = p_vout->output.i_height;
01007
01008
01009 rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) *
01010 p_vout->output.i_width / (rect_dest.right - rect_dest.left);
01011 rect_src_clipped.right = p_vout->output.i_width -
01012 (rect_dest.right - rect_dest_clipped.right) * p_vout->output.i_width /
01013 (rect_dest.right - rect_dest.left);
01014 rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) *
01015 p_vout->output.i_height / (rect_dest.bottom - rect_dest.top);
01016 rect_src_clipped.bottom = p_vout->output.i_height -
01017 (rect_dest.bottom - rect_dest_clipped.bottom) * p_vout->output.i_height /
01018 (rect_dest.bottom - rect_dest.top);
01019
01020 #if 0
01021 msg_Dbg( p_vout, "image_src_clipped coords: %i,%i,%i,%i",
01022 rect_src_clipped.left, rect_src_clipped.top,
01023 rect_src_clipped.right, rect_src_clipped.bottom );
01024 #endif
01025
01026
01027
01028 rect_dest_clipped.left -= p_vout->p_sys->rect_display.left;
01029 rect_dest_clipped.right -= p_vout->p_sys->rect_display.left;
01030 rect_dest_clipped.top -= p_vout->p_sys->rect_display.top;
01031 rect_dest_clipped.bottom -= p_vout->p_sys->rect_display.top;
01032
01033
01034 p_vout->p_sys->i_changes |= DX_POSITION_CHANGE;
01035
01036 #undef rect_src
01037 #undef rect_src_clipped
01038 #undef rect_dest
01039 #undef rect_dest_clipped
01040 }
01041
01042
01043
01044
01045 static long FAR PASCAL WndProc( HWND hWnd, UINT message,
01046 WPARAM wParam, LPARAM lParam )
01047 {
01048 vout_thread_t *p_vout;
01049
01050 if( message == WM_CREATE )
01051 {
01052
01053 p_vout = (vout_thread_t *)((CREATESTRUCT *)lParam)->lpCreateParams;
01054 SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)p_vout );
01055 if( p_vout ) msg_Dbg( p_vout, "create: %p", hWnd );
01056 }
01057 else
01058 {
01059 p_vout = (vout_thread_t *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
01060 }
01061
01062 #ifndef UNDER_CE
01063
01064 if( message == WM_SYSCOMMAND &&
01065 ( (wParam & 0xFFF0) == SC_SCREENSAVE || (wParam & 0xFFF0) == SC_MONITORPOWER ) )
01066 {
01067
01068 return 0;
01069 }
01070 #endif
01071
01072 if( !p_vout )
01073 {
01074
01075
01076 return DefWindowProc(hWnd, message, wParam, lParam);
01077 }
01078
01079 if( hWnd != p_vout->p_sys->hwnd &&
01080 hWnd != p_vout->p_sys->hfswnd &&
01081 hWnd != p_vout->p_sys->hvideownd )
01082 return DefWindowProc(hWnd, message, wParam, lParam);
01083
01084 switch( message )
01085 {
01086 case WM_WINDOWPOSCHANGED:
01087 if( hWnd == p_vout->p_sys->hwnd )
01088 UpdateRects( p_vout, VLC_TRUE );
01089 break;
01090
01091 #if 0
01092 case WM_ACTIVATE:
01093 msg_Err( p_vout, "WM_ACTIVATE: %i", wParam );
01094 if( wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE )
01095 GXResume();
01096 else if( wParam == WA_INACTIVE )
01097 GXSuspend();
01098 break;
01099 #endif
01100
01101 case WM_KILLFOCUS:
01102 p_vout->p_sys->b_focus = VLC_FALSE;
01103 if( !p_vout->p_sys->b_parent_focus ) GXSuspend();
01104
01105 if( hWnd == p_vout->p_sys->hfswnd )
01106 {
01107 #ifdef UNDER_CE
01108 HWND htbar = FindWindow( _T("HHTaskbar"), NULL );
01109 ShowWindow( htbar, SW_SHOW );
01110 #endif
01111 }
01112
01113 if( !p_vout->p_sys->hparent ||
01114 hWnd == p_vout->p_sys->hfswnd )
01115 {
01116 SHFullScreen( hWnd, SHFS_SHOWSIPBUTTON );
01117 }
01118 break;
01119
01120 case WM_SETFOCUS:
01121 p_vout->p_sys->b_focus = VLC_TRUE;
01122 GXResume();
01123
01124 if( p_vout->p_sys->hparent &&
01125 hWnd != p_vout->p_sys->hfswnd && p_vout->b_fullscreen )
01126 p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
01127
01128 if( hWnd == p_vout->p_sys->hfswnd )
01129 {
01130 #ifdef UNDER_CE
01131 HWND htbar = FindWindow( _T("HHTaskbar"), NULL );
01132 ShowWindow( htbar, SW_HIDE );
01133 #endif
01134 }
01135
01136 if( !p_vout->p_sys->hparent ||
01137 hWnd == p_vout->p_sys->hfswnd )
01138 {
01139 SHFullScreen( hWnd, SHFS_HIDESIPBUTTON );
01140 }
01141 break;
01142
01143 case WM_LBUTTONDOWN:
01144 p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
01145 break;
01146 case WM_MOUSEMOVE:
01147 break;
01148 case WM_LBUTTONUP:
01149 break;
01150
01151 case WM_INITMENUPOPUP:
01152 p_vout->p_sys->b_video_display = VLC_FALSE;
01153 break;
01154
01155 case WM_NOTIFY:
01156
01157
01158 if( (((NMHDR *)lParam)->code) == NM_CUSTOMDRAW )
01159 p_vout->p_sys->b_video_display = VLC_TRUE;
01160 break;
01161
01162
01163 case WM_CLOSE:
01164 {
01165 playlist_t * p_playlist =
01166 (playlist_t *)vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
01167 FIND_ANYWHERE );
01168 if( p_playlist == NULL ) return 0;
01169
01170 playlist_Stop( p_playlist );
01171 vlc_object_release( p_playlist );
01172 return 0;
01173 }
01174
01175 case WM_DESTROY:
01176 msg_Dbg( p_vout, "WinProc WM_DESTROY" );
01177 PostQuitMessage( 0 );
01178 break;
01179
01180 default:
01181 return DefWindowProc( hWnd, message, wParam, lParam );
01182 }
01183
01184 return 0;
01185 }
01186
01187
01188
01189
01190 static void InitBuffers( vout_thread_t *p_vout )
01191 {
01192 BITMAPINFOHEADER *p_header = &p_vout->p_sys->bitmapinfo.bmiHeader;
01193 BITMAPINFO *p_info = &p_vout->p_sys->bitmapinfo;
01194 int i_pixels = p_vout->render.i_height * p_vout->render.i_width;
01195 HDC window_dc = GetDC( p_vout->p_sys->hvideownd );
01196
01197
01198 #ifdef MODULE_NAME_IS_wingapi
01199 GXDisplayProperties gx_displayprop = GXGetDisplayProperties();
01200 p_vout->p_sys->i_depth = gx_displayprop.cBPP;
01201 #else
01202 p_vout->p_sys->i_depth = GetDeviceCaps( window_dc, PLANES ) *
01203 GetDeviceCaps( window_dc, BITSPIXEL );
01204 #endif
01205 msg_Dbg( p_vout, "GDI depth is %i", p_vout->p_sys->i_depth );
01206
01207 #ifdef MODULE_NAME_IS_wingapi
01208 GXOpenDisplay( p_vout->p_sys->hvideownd, GX_FULLSCREEN );
01209
01210 #else
01211
01212
01213 memset( p_info, 0, sizeof( BITMAPINFO ) + 3 * sizeof( RGBQUAD ) );
01214
01215 p_header->biSize = sizeof( BITMAPINFOHEADER );
01216 p_header->biSizeImage = 0;
01217 p_header->biPlanes = 1;
01218 switch( p_vout->p_sys->i_depth )
01219 {
01220 case 8:
01221 p_header->biBitCount = 8;
01222 p_header->biCompression = BI_RGB;
01223
01224 break;
01225 case 15:
01226 p_header->biBitCount = 15;
01227 p_header->biCompression = BI_BITFIELDS;
01228 ((DWORD*)p_info->bmiColors)[0] = 0x00007c00;
01229 ((DWORD*)p_info->bmiColors)[1] = 0x000003e0;
01230 ((DWORD*)p_info->bmiColors)[2] = 0x0000001f;
01231 break;
01232 case 16:
01233 p_header->biBitCount = 16;
01234 p_header->biCompression = BI_BITFIELDS;
01235 ((DWORD*)p_info->bmiColors)[0] = 0x0000f800;
01236 ((DWORD*)p_info->bmiColors)[1] = 0x000007e0;
01237 ((DWORD*)p_info->bmiColors)[2] = 0x0000001f;
01238 break;
01239 case 24:
01240 p_header->biBitCount = 24;
01241 p_header->biCompression = BI_RGB;
01242 ((DWORD*)p_info->bmiColors)[0] = 0x00ff0000;
01243 ((DWORD*)p_info->bmiColors)[1] = 0x0000ff00;
01244 ((DWORD*)p_info->bmiColors)[2] = 0x000000ff;
01245 break;
01246 case 32:
01247 p_header->biBitCount = 32;
01248 p_header->biCompression = BI_RGB;
01249 ((DWORD*)p_info->bmiColors)[0] = 0x00ff0000;
01250 ((DWORD*)p_info->bmiColors)[1] = 0x0000ff00;
01251 ((DWORD*)p_info->bmiColors)[2] = 0x000000ff;
01252 break;
01253 default:
01254 msg_Err( p_vout, "screen depth %i not supported",
01255 p_vout->p_sys->i_depth );
01256 return;
01257 break;
01258 }
01259 p_header->biWidth = p_vout->render.i_width;
01260 p_header->biHeight = -p_vout->render.i_height;
01261 p_header->biClrImportant = 0;
01262 p_header->biClrUsed = 0;
01263 p_header->biXPelsPerMeter = 0;
01264 p_header->biYPelsPerMeter = 0;
01265
01266 p_vout->p_sys->i_pic_pixel_pitch = p_header->biBitCount / 8;
01267 p_vout->p_sys->i_pic_pitch = p_header->biBitCount * p_header->biWidth / 8;
01268
01269 p_vout->p_sys->off_bitmap =
01270 CreateDIBSection( window_dc, (BITMAPINFO *)p_header, DIB_RGB_COLORS,
01271 (void**)&p_vout->p_sys->p_pic_buffer, NULL, 0 );
01272
01273 p_vout->p_sys->off_dc = CreateCompatibleDC( window_dc );
01274
01275 SelectObject( p_vout->p_sys->off_dc, p_vout->p_sys->off_bitmap );
01276 ReleaseDC( 0, window_dc );
01277 #endif
01278 }
01279
01280
01281
01282
01283 static int Control( vout_thread_t *p_vout, int i_query, va_list args )
01284 {
01285 vlc_bool_t b_bool;
01286 double f_arg;
01287 RECT rect_window;
01288 POINT point;
01289
01290 switch( i_query )
01291 {
01292 case VOUT_SET_ZOOM:
01293 if( p_vout->p_sys->hparent )
01294 return vout_ControlWindow( p_vout,
01295 (void *)p_vout->p_sys->hparent, i_query, args );
01296
01297
01298 rect_window.top = rect_window.left = 0;
01299 rect_window.right = p_vout->i_window_width;
01300 rect_window.bottom = p_vout->i_window_height;
01301 AdjustWindowRect( &rect_window, p_vout->p_sys->i_window_style, 0 );
01302
01303 SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
01304 rect_window.right - rect_window.left,
01305 rect_window.bottom - rect_window.top, SWP_NOMOVE );
01306
01307 return VLC_SUCCESS;
01308
01309 case VOUT_CLOSE:
01310 ShowWindow( p_vout->p_sys->hwnd, SW_HIDE );
01311 case VOUT_REPARENT:
01312
01313
01314 p_vout->p_sys->hparent = 0;
01315
01316
01317
01318 point.x = point.y = 0;
01319 ClientToScreen( p_vout->p_sys->hwnd, &point );
01320
01321 SetParent( p_vout->p_sys->hwnd, 0 );
01322 p_vout->p_sys->i_window_style =
01323 WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW | WS_SIZEBOX;
01324 SetWindowLong( p_vout->p_sys->hwnd, GWL_STYLE,
01325 p_vout->p_sys->i_window_style |
01326 (i_query == VOUT_CLOSE ? 0 : WS_VISIBLE) );
01327 SetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW );
01328 SetWindowPos( p_vout->p_sys->hwnd, 0, point.x, point.y, 0, 0,
01329 SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED );
01330
01331 return vout_vaControlDefault( p_vout, i_query, args );
01332
01333 case VOUT_SET_FOCUS:
01334 b_bool = va_arg( args, vlc_bool_t );
01335
01336 p_vout->p_sys->b_parent_focus = b_bool;
01337 if( b_bool ) GXResume();
01338 else if( !p_vout->p_sys->b_focus ) GXSuspend();
01339
01340 return VLC_SUCCESS;
01341
01342 default:
01343 return vout_vaControlDefault( p_vout, i_query, args );
01344 }
01345 }