| 95 | | p_vout->p_sys = malloc( sizeof(vout_sys_t) ); |
|---|
| 96 | | if( !p_vout->p_sys ) |
|---|
| 97 | | { |
|---|
| 98 | | return VLC_ENOMEM; |
|---|
| 99 | | } |
|---|
| 100 | | |
|---|
| 101 | | p_vout->p_sys->p_event = vlc_object_create( p_vout, VLC_OBJECT_GENERIC ); |
|---|
| | 217 | p_vout->p_sys = (vout_sys_t *)malloc( sizeof(vout_sys_t) ); |
|---|
| | 218 | if( !p_vout->p_sys ) return VLC_ENOMEM; |
|---|
| | 219 | |
|---|
| | 220 | #ifdef MODULE_NAME_IS_gapi |
|---|
| | 221 | /* Load GAPI */ |
|---|
| | 222 | p_vout->p_sys->gapi_dll = LoadLibrary( _T("GX.DLL") ); |
|---|
| | 223 | if( p_vout->p_sys->gapi_dll == NULL ) |
|---|
| | 224 | { |
|---|
| | 225 | msg_Warn( p_vout, "failed loading gx.dll" ); |
|---|
| | 226 | free( p_vout->p_sys ); |
|---|
| | 227 | return VLC_EGENERIC; |
|---|
| | 228 | } |
|---|
| | 229 | |
|---|
| | 230 | GXOpenDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 231 | _T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z") ); |
|---|
| | 232 | GXCloseDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 233 | _T("?GXCloseDisplay@@YAHXZ") ); |
|---|
| | 234 | GXBeginDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 235 | _T("?GXBeginDraw@@YAPAXXZ") ); |
|---|
| | 236 | GXEndDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 237 | _T("?GXEndDraw@@YAHXZ") ); |
|---|
| | 238 | GXGetDisplayProperties = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 239 | _T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ") ); |
|---|
| | 240 | GXSuspend = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 241 | _T("?GXSuspend@@YAHXZ") ); |
|---|
| | 242 | GXResume = GetProcAddress( p_vout->p_sys->gapi_dll, |
|---|
| | 243 | _T("?GXResume@@YAHXZ") ); |
|---|
| | 244 | |
|---|
| | 245 | if( !GXOpenDisplay || !GXCloseDisplay || !GXBeginDraw || !GXEndDraw || |
|---|
| | 246 | !GXGetDisplayProperties || !GXSuspend || !GXResume ) |
|---|
| | 247 | { |
|---|
| | 248 | msg_Err( p_vout, "failed GetProcAddress on gapi.dll" ); |
|---|
| | 249 | free( p_vout->p_sys ); |
|---|
| | 250 | return VLC_EGENERIC; |
|---|
| | 251 | } |
|---|
| | 252 | |
|---|
| | 253 | msg_Dbg( p_vout, "GAPI DLL loaded" ); |
|---|
| | 254 | |
|---|
| | 255 | p_vout->p_sys->render_width = p_vout->render.i_width; |
|---|
| | 256 | p_vout->p_sys->render_height = p_vout->render.i_height; |
|---|
| | 257 | #endif |
|---|
| | 258 | |
|---|
| | 259 | p_vout->p_sys->p_event = (vlc_object_t *) |
|---|
| | 260 | vlc_object_create( p_vout, VLC_OBJECT_GENERIC ); |
|---|
| 153 | | case 8: |
|---|
| 154 | | p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); |
|---|
| 155 | | p_vout->output.pf_setpalette = SetPalette; |
|---|
| 156 | | break; |
|---|
| 157 | | case 24: |
|---|
| 158 | | p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4'); |
|---|
| 159 | | p_vout->output.i_rmask = 0x00ff0000; |
|---|
| 160 | | p_vout->output.i_gmask = 0x0000ff00; |
|---|
| 161 | | p_vout->output.i_bmask = 0x000000ff; |
|---|
| 162 | | break; |
|---|
| 163 | | case 32: |
|---|
| 164 | | p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); |
|---|
| 165 | | p_vout->output.i_rmask = 0x00ff0000; |
|---|
| 166 | | p_vout->output.i_gmask = 0x0000ff00; |
|---|
| 167 | | p_vout->output.i_bmask = 0x000000ff; |
|---|
| 168 | | break; |
|---|
| 169 | | default: |
|---|
| 170 | | case 16: |
|---|
| 171 | | p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); |
|---|
| 172 | | p_vout->output.i_rmask = 0x7c00; |
|---|
| 173 | | p_vout->output.i_gmask = 0x03e0; |
|---|
| 174 | | p_vout->output.i_bmask = 0x001f; |
|---|
| 175 | | break; |
|---|
| 176 | | } |
|---|
| 177 | | |
|---|
| | 337 | case 8: |
|---|
| | 338 | p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); |
|---|
| | 339 | p_vout->output.pf_setpalette = SetPalette; |
|---|
| | 340 | break; |
|---|
| | 341 | case 15: |
|---|
| | 342 | p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); |
|---|
| | 343 | p_vout->output.i_rmask = 0x7c00; |
|---|
| | 344 | p_vout->output.i_gmask = 0x03e0; |
|---|
| | 345 | p_vout->output.i_bmask = 0x001f; |
|---|
| | 346 | break; |
|---|
| | 347 | case 16: |
|---|
| | 348 | p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6'); |
|---|
| | 349 | p_vout->output.i_rmask = 0xf800; |
|---|
| | 350 | p_vout->output.i_gmask = 0x07e0; |
|---|
| | 351 | p_vout->output.i_bmask = 0x001f; |
|---|
| | 352 | break; |
|---|
| | 353 | case 24: |
|---|
| | 354 | p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4'); |
|---|
| | 355 | p_vout->output.i_rmask = 0x00ff0000; |
|---|
| | 356 | p_vout->output.i_gmask = 0x0000ff00; |
|---|
| | 357 | p_vout->output.i_bmask = 0x000000ff; |
|---|
| | 358 | break; |
|---|
| | 359 | case 32: |
|---|
| | 360 | p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); |
|---|
| | 361 | p_vout->output.i_rmask = 0x00ff0000; |
|---|
| | 362 | p_vout->output.i_gmask = 0x0000ff00; |
|---|
| | 363 | p_vout->output.i_bmask = 0x000000ff; |
|---|
| | 364 | break; |
|---|
| | 365 | default: |
|---|
| | 366 | msg_Err( p_vout, "screen depth %i not supported", |
|---|
| | 367 | p_vout->p_sys->i_depth ); |
|---|
| | 368 | return VLC_EGENERIC; |
|---|
| | 369 | break; |
|---|
| | 370 | } |
|---|
| | 371 | |
|---|
| | 372 | #ifdef MODULE_NAME_IS_gapi |
|---|
| | 373 | p_vout->output.i_width = p_vout->p_sys->render_width; |
|---|
| | 374 | p_vout->output.i_height = p_vout->p_sys->render_height; |
|---|
| | 375 | #else |
|---|
| | 440 | #ifndef UNDER_CE |
|---|
| | 441 | WINDOWPLACEMENT window_placement; |
|---|
| | 442 | #endif |
|---|
| | 443 | |
|---|
| | 444 | /* If we do not control our window, we check for geometry changes |
|---|
| | 445 | * ourselves because the parent might not send us its events. */ |
|---|
| | 446 | if( p_vout->p_sys->hparent && !p_vout->b_fullscreen ) |
|---|
| | 447 | { |
|---|
| | 448 | RECT rect_parent; |
|---|
| | 449 | POINT point; |
|---|
| | 450 | |
|---|
| | 451 | GetClientRect( p_vout->p_sys->hparent, &rect_parent ); |
|---|
| | 452 | point.x = point.y = 0; |
|---|
| | 453 | ClientToScreen( p_vout->p_sys->hparent, &point ); |
|---|
| | 454 | OffsetRect( &rect_parent, point.x, point.y ); |
|---|
| | 455 | |
|---|
| | 456 | if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) ) |
|---|
| | 457 | { |
|---|
| | 458 | int i_x, i_y, i_width, i_height; |
|---|
| | 459 | p_vout->p_sys->rect_parent = rect_parent; |
|---|
| | 460 | |
|---|
| | 461 | /* This one is to force the update even if only |
|---|
| | 462 | * the position has changed */ |
|---|
| | 463 | SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1, |
|---|
| | 464 | rect_parent.right - rect_parent.left, |
|---|
| | 465 | rect_parent.bottom - rect_parent.top, 0 ); |
|---|
| | 466 | |
|---|
| | 467 | SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0, |
|---|
| | 468 | rect_parent.right - rect_parent.left, |
|---|
| | 469 | rect_parent.bottom - rect_parent.top, 0 ); |
|---|
| | 470 | |
|---|
| | 471 | vout_PlacePicture( p_vout, rect_parent.right - rect_parent.left, |
|---|
| | 472 | rect_parent.bottom - rect_parent.top, |
|---|
| | 473 | &i_x, &i_y, &i_width, &i_height ); |
|---|
| | 474 | |
|---|
| | 475 | SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP, |
|---|
| | 476 | i_x, i_y, i_width, i_height, 0 ); |
|---|
| | 477 | } |
|---|
| | 478 | } |
|---|
| | 479 | |
|---|
| | 480 | /* We used to call the Win32 PeekMessage function here to read the window |
|---|
| | 481 | * messages. But since window can stay blocked into this function for a |
|---|
| | 482 | * long time (for example when you move your window on the screen), I |
|---|
| | 483 | * decided to isolate PeekMessage in another thread. */ |
|---|
| | 484 | |
|---|
| | 485 | /* |
|---|
| | 486 | * Fullscreen change |
|---|
| | 487 | */ |
|---|
| | 488 | if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE |
|---|
| | 489 | || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE ) |
|---|
| | 490 | { |
|---|
| | 491 | int i_style = 0; |
|---|
| | 492 | vlc_value_t val; |
|---|
| | 493 | |
|---|
| | 494 | HWND hwnd = (p_vout->p_sys->hparent && p_vout->p_sys->hfswnd) ? |
|---|
| | 495 | p_vout->p_sys->hfswnd : p_vout->p_sys->hwnd; |
|---|
| | 496 | |
|---|
| | 497 | p_vout->b_fullscreen = ! p_vout->b_fullscreen; |
|---|
| | 498 | |
|---|
| | 499 | /* We need to switch between Maximized and Normal sized window */ |
|---|
| | 500 | #ifndef UNDER_CE |
|---|
| | 501 | window_placement.length = sizeof(WINDOWPLACEMENT); |
|---|
| | 502 | GetWindowPlacement( hwnd, &window_placement ); |
|---|
| | 503 | #endif |
|---|
| | 504 | if( p_vout->b_fullscreen ) |
|---|
| | 505 | { |
|---|
| | 506 | #ifndef UNDER_CE |
|---|
| | 507 | /* Change window style, no borders and no title bar */ |
|---|
| | 508 | int i_style = WS_CLIPCHILDREN | WS_VISIBLE; |
|---|
| | 509 | SetWindowLong( hwnd, GWL_STYLE, i_style ); |
|---|
| | 510 | |
|---|
| | 511 | if( p_vout->p_sys->hparent ) |
|---|
| | 512 | { |
|---|
| | 513 | /* Retrieve current window position so fullscreen will happen |
|---|
| | 514 | * on the right screen */ |
|---|
| | 515 | POINT point = {0,0}; |
|---|
| | 516 | RECT rect; |
|---|
| | 517 | ClientToScreen( p_vout->p_sys->hwnd, &point ); |
|---|
| | 518 | GetClientRect( p_vout->p_sys->hwnd, &rect ); |
|---|
| | 519 | SetWindowPos( hwnd, 0, point.x, point.y, |
|---|
| | 520 | rect.right, rect.bottom, |
|---|
| | 521 | SWP_NOZORDER|SWP_FRAMECHANGED ); |
|---|
| | 522 | GetWindowPlacement( hwnd, &window_placement ); |
|---|
| | 523 | } |
|---|
| | 524 | |
|---|
| | 525 | /* Maximize window */ |
|---|
| | 526 | window_placement.showCmd = SW_SHOWMAXIMIZED; |
|---|
| | 527 | SetWindowPlacement( hwnd, &window_placement ); |
|---|
| | 528 | SetWindowPos( hwnd, 0, 0, 0, 0, 0, |
|---|
| | 529 | SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); |
|---|
| | 530 | #endif |
|---|
| | 531 | |
|---|
| | 532 | if( p_vout->p_sys->hparent ) |
|---|
| | 533 | { |
|---|
| | 534 | RECT rect; |
|---|
| | 535 | GetClientRect( hwnd, &rect ); |
|---|
| | 536 | SetParent( p_vout->p_sys->hwnd, hwnd ); |
|---|
| | 537 | SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0, |
|---|
| | 538 | rect.right, rect.bottom, |
|---|
| | 539 | SWP_NOZORDER|SWP_FRAMECHANGED ); |
|---|
| | 540 | } |
|---|
| | 541 | |
|---|
| | 542 | ShowWindow( hwnd, SW_SHOW ); |
|---|
| | 543 | SetForegroundWindow( hwnd ); |
|---|
| | 544 | } |
|---|
| | 545 | else |
|---|
| | 546 | { |
|---|
| | 547 | /* Change window style, no borders and no title bar */ |
|---|
| | 548 | //SetWindowLong( hwnd, GWL_STYLE, p_vout->p_sys->i_window_style ); |
|---|
| | 549 | |
|---|
| | 550 | #ifndef UNDER_CE |
|---|
| | 551 | /* Normal window */ |
|---|
| | 552 | window_placement.showCmd = SW_SHOWNORMAL; |
|---|
| | 553 | SetWindowPlacement( hwnd, &window_placement ); |
|---|
| | 554 | SetWindowPos( hwnd, 0, 0, 0, 0, 0, |
|---|
| | 555 | SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); |
|---|
| | 556 | #endif |
|---|
| | 557 | |
|---|
| | 558 | if( p_vout->p_sys->hparent ) |
|---|
| | 559 | { |
|---|
| | 560 | RECT rect; |
|---|
| | 561 | GetClientRect( p_vout->p_sys->hparent, &rect ); |
|---|
| | 562 | SetParent( p_vout->p_sys->hwnd, p_vout->p_sys->hparent ); |
|---|
| | 563 | SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0, |
|---|
| | 564 | rect.right, rect.bottom, |
|---|
| | 565 | SWP_NOZORDER|SWP_FRAMECHANGED ); |
|---|
| | 566 | |
|---|
| | 567 | ShowWindow( hwnd, SW_HIDE ); |
|---|
| | 568 | SetForegroundWindow( p_vout->p_sys->hparent ); |
|---|
| | 569 | } |
|---|
| | 570 | |
|---|
| | 571 | /* Make sure the mouse cursor is displayed */ |
|---|
| | 572 | //PostMessage( p_vout->p_sys->hwnd, WM_VLC_SHOW_MOUSE, 0, 0 ); |
|---|
| | 573 | } |
|---|
| | 574 | |
|---|
| | 575 | #ifdef MODULE_NAME_IS_gapi |
|---|
| | 576 | GXCloseDisplay(); |
|---|
| | 577 | #endif |
|---|
| | 578 | |
|---|
| | 579 | /* Change window style, borders and title bar */ |
|---|
| | 580 | ShowWindow( p_vout->p_sys->hwnd, SW_SHOW ); |
|---|
| | 581 | UpdateWindow( p_vout->p_sys->hwnd ); |
|---|
| | 582 | |
|---|
| | 583 | #ifdef MODULE_NAME_IS_gapi |
|---|
| | 584 | GXOpenDisplay( p_vout->p_sys->hvideownd, GX_FULLSCREEN ); |
|---|
| | 585 | #endif |
|---|
| | 586 | |
|---|
| | 587 | /* Update the object variable and trigger callback */ |
|---|
| | 588 | val.b_bool = p_vout->b_fullscreen; |
|---|
| | 589 | var_Set( p_vout, "fullscreen", val ); |
|---|
| | 590 | |
|---|
| | 591 | p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; |
|---|
| | 592 | p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE; |
|---|
| | 593 | } |
|---|
| | 594 | |
|---|
| 287 | | |
|---|
| 288 | | BitBlt( hdc, 0, 0, p_vout->output.i_width, p_vout->output.i_height, |
|---|
| 289 | | p_vout->p_sys->off_dc, 0, 0, SRCCOPY ); |
|---|
| 290 | | |
|---|
| 291 | | ReleaseDC( p_vout->p_sys->window, hdc ); |
|---|
| | 640 | #endif |
|---|
| | 641 | |
|---|
| | 642 | if( rect_dest_clipped.right - rect_dest_clipped.left != |
|---|
| | 643 | rect_src_clipped.right - rect_src_clipped.left || |
|---|
| | 644 | rect_dest_clipped.bottom - rect_dest_clipped.top != |
|---|
| | 645 | rect_src_clipped.bottom - rect_src_clipped.top ) |
|---|
| | 646 | { |
|---|
| | 647 | StretchBlt( hdc, rect_dst.left, rect_dst.top, |
|---|
| | 648 | rect_dst.right, rect_dst.bottom, |
|---|
| | 649 | p_sys->off_dc, rect_src_clipped.left, rect_src_clipped.top, |
|---|
| | 650 | rect_src_clipped.right, rect_src_clipped.bottom, SRCCOPY ); |
|---|
| | 651 | } |
|---|
| | 652 | else |
|---|
| | 653 | { |
|---|
| | 654 | BitBlt( hdc, rect_dst.left, rect_dst.top, |
|---|
| | 655 | rect_dst.right, rect_dst.bottom, |
|---|
| | 656 | p_sys->off_dc, rect_src_clipped.left, |
|---|
| | 657 | rect_src_clipped.top, SRCCOPY ); |
|---|
| | 658 | } |
|---|
| | 659 | |
|---|
| | 660 | ReleaseDC( p_sys->hwnd, hdc ); |
|---|
| 293 | | |
|---|
| | 662 | #else |
|---|
| | 663 | |
|---|
| | 664 | static void DisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic ) |
|---|
| | 665 | { |
|---|
| | 666 | vout_sys_t *p_sys = p_vout->p_sys; |
|---|
| | 667 | int i_x, i_y, i_width, i_height; |
|---|
| | 668 | RECT video_rect; |
|---|
| | 669 | POINT point; |
|---|
| | 670 | |
|---|
| | 671 | /* Undo the display */ |
|---|
| | 672 | if( ( GetForegroundWindow() != GetParent(p_sys->hwnd) ) || |
|---|
| | 673 | ( p_sys->b_video_display == VLC_FALSE ) ) |
|---|
| | 674 | { |
|---|
| | 675 | return; |
|---|
| | 676 | } |
|---|
| | 677 | |
|---|
| | 678 | GetClientRect( p_sys->hwnd, &video_rect); |
|---|
| | 679 | vout_PlacePicture( p_vout, video_rect.right - video_rect.left, |
|---|
| | 680 | video_rect.bottom - video_rect.top, |
|---|
| | 681 | &i_x, &i_y, &i_width, &i_height ); |
|---|
| | 682 | point.x = point.y = 0; |
|---|
| | 683 | ClientToScreen( p_sys->hwnd, &point ); |
|---|
| | 684 | i_x += point.x + video_rect.left; |
|---|
| | 685 | i_y += point.y + video_rect.top; |
|---|
| | 686 | |
|---|
| | 687 | if( i_width != p_vout->output.i_width || |
|---|
| | 688 | i_height != p_vout->output.i_height ) |
|---|
| | 689 | { |
|---|
| | 690 | p_sys->render_width = i_width; |
|---|
| | 691 | p_sys->render_height = i_height; |
|---|
| | 692 | p_vout->i_changes |= VOUT_SIZE_CHANGE; |
|---|
| | 693 | } |
|---|
| | 694 | else |
|---|
| | 695 | { |
|---|
| | 696 | GXDisplayProperties gxdisplayprop; |
|---|
| | 697 | RECT display_rect, dest_rect; |
|---|
| | 698 | uint8_t *p_dest, *p_src = p_pic->p->p_pixels; |
|---|
| | 699 | |
|---|
| | 700 | video_rect.left = i_x; video_rect.top = i_y; |
|---|
| | 701 | video_rect.right = i_x + i_width; |
|---|
| | 702 | video_rect.bottom = i_y + i_height; |
|---|
| | 703 | |
|---|
| | 704 | gxdisplayprop = GXGetDisplayProperties(); |
|---|
| | 705 | display_rect.left = 0; display_rect.top = 0; |
|---|
| | 706 | display_rect.right = gxdisplayprop.cxWidth; |
|---|
| | 707 | display_rect.bottom = gxdisplayprop.cyHeight; |
|---|
| | 708 | |
|---|
| | 709 | if( !IntersectRect( &dest_rect, &video_rect, &display_rect ) ) |
|---|
| | 710 | { |
|---|
| | 711 | return; |
|---|
| | 712 | } |
|---|
| | 713 | |
|---|
| | 714 | #if 0 |
|---|
| | 715 | msg_Err( p_vout, "video (%d,%d,%d,%d) display (%d,%d,%d,%d) " |
|---|
| | 716 | "dest (%d,%d,%d,%d)", |
|---|
| | 717 | video_rect.left, video_rect.right, |
|---|
| | 718 | video_rect.top, video_rect.bottom, |
|---|
| | 719 | display_rect.left, display_rect.right, |
|---|
| | 720 | display_rect.top, display_rect.bottom, |
|---|
| | 721 | dest_rect.left, dest_rect.right, |
|---|
| | 722 | dest_rect.top, dest_rect.bottom ); |
|---|
| | 723 | #endif |
|---|
| | 724 | |
|---|
| | 725 | if( !(p_dest = GXBeginDraw()) ) |
|---|
| | 726 | { |
|---|
| | 727 | msg_Err( p_vout, "GXBeginDraw error %d ", GetLastError() ); |
|---|
| | 728 | return; |
|---|
| | 729 | } |
|---|
| | 730 | |
|---|
| | 731 | p_src += (dest_rect.left - video_rect.left) * gxdisplayprop.cbxPitch + |
|---|
| | 732 | (dest_rect.top - video_rect.top) * p_pic->p->i_pitch; |
|---|
| | 733 | p_dest += dest_rect.left * gxdisplayprop.cbxPitch + |
|---|
| | 734 | dest_rect.top * gxdisplayprop.cbyPitch; |
|---|
| | 735 | i_width = dest_rect.right - dest_rect.left; |
|---|
| | 736 | i_height = dest_rect.bottom - dest_rect.top; |
|---|
| | 737 | |
|---|
| | 738 | while( i_height-- ) |
|---|
| | 739 | { |
|---|
| | 740 | p_vout->p_vlc->pf_memcpy( p_dest, p_src, |
|---|
| | 741 | i_width * gxdisplayprop.cbxPitch ); |
|---|
| | 742 | p_src += p_pic->p->i_pitch; |
|---|
| | 743 | p_dest += gxdisplayprop.cbyPitch; |
|---|
| | 744 | } |
|---|
| | 745 | } |
|---|
| | 746 | |
|---|
| | 747 | GXEndDraw(); |
|---|
| | 748 | } |
|---|
| | 749 | #endif |
|---|
| | 750 | |
|---|
| | 751 | #undef rect_src |
|---|
| | 752 | #undef rect_src_clipped |
|---|
| | 753 | #undef rect_dest |
|---|
| | 754 | #undef rect_dest_clipped |
|---|
| 344 | | p_vout->p_sys->window = |
|---|
| 345 | | CreateWindow( psz_class, psz_title, |
|---|
| 346 | | WS_VISIBLE | WS_SIZEBOX | WS_CAPTION, |
|---|
| 347 | | CW_USEDEFAULT, CW_USEDEFAULT, |
|---|
| 348 | | p_vout->render.i_width, |
|---|
| 349 | | p_vout->render.i_height + 10, |
|---|
| 350 | | NULL, NULL, instance, (LPVOID)p_vout ); |
|---|
| | 798 | p_vout->p_sys->hparent = p_vout->p_sys->hwnd = (HWND) |
|---|
| | 799 | vout_RequestWindow( p_vout, &p_vout->p_sys->i_window_x, |
|---|
| | 800 | &p_vout->p_sys->i_window_y, |
|---|
| | 801 | (unsigned int *)&p_vout->p_sys->i_window_width, |
|---|
| | 802 | (unsigned int *)&p_vout->p_sys->i_window_height ); |
|---|
| | 803 | |
|---|
| | 804 | ShowWindow( p_vout->p_sys->hparent, SW_SHOW ); |
|---|
| | 805 | |
|---|
| | 806 | if( p_vout->p_sys->hparent ) |
|---|
| | 807 | i_style = WS_VISIBLE|WS_CLIPCHILDREN|WS_CHILD; |
|---|
| | 808 | else |
|---|
| | 809 | i_style = WS_OVERLAPPEDWINDOW|WS_SIZEBOX|WS_VISIBLE|WS_CLIPCHILDREN; |
|---|
| | 810 | |
|---|
| | 811 | p_vout->p_sys->hwnd = |
|---|
| | 812 | CreateWindow( _T("VLC WinGDI"), _T(VOUT_TITLE), i_style, |
|---|
| | 813 | (p_vout->p_sys->i_window_x < 0) ? CW_USEDEFAULT : |
|---|
| | 814 | p_vout->p_sys->i_window_x, /* default X coordinate */ |
|---|
| | 815 | (p_vout->p_sys->i_window_y < 0) ? CW_USEDEFAULT : |
|---|
| | 816 | p_vout->p_sys->i_window_y, /* default Y coordinate */ |
|---|
| | 817 | p_vout->p_sys->i_window_width, |
|---|
| | 818 | p_vout->p_sys->i_window_height + 10, |
|---|
| | 819 | p_vout->p_sys->hparent, NULL, |
|---|
| | 820 | GetModuleHandle(NULL), (LPVOID)p_vout ); |
|---|
| | 821 | |
|---|
| | 822 | if( !p_vout->p_sys->hwnd ) |
|---|
| | 823 | { |
|---|
| | 824 | msg_Warn( p_vout, "couldn't create window" ); |
|---|
| | 825 | return; |
|---|
| | 826 | } |
|---|
| | 827 | msg_Warn( p_vout, "Created WinGDI window" ); |
|---|
| | 828 | |
|---|
| | 829 | if( p_vout->p_sys->hparent ) |
|---|
| | 830 | { |
|---|
| | 831 | LONG i_style; |
|---|
| | 832 | |
|---|
| | 833 | /* We don't want the window owner to overwrite our client area */ |
|---|
| | 834 | i_style = GetWindowLong( p_vout->p_sys->hparent, GWL_STYLE ); |
|---|
| | 835 | |
|---|
| | 836 | if( !(i_style & WS_CLIPCHILDREN) ) |
|---|
| | 837 | /* Hmmm, apparently this is a blocking call... */ |
|---|
| | 838 | SetWindowLong( p_vout->p_sys->hparent, GWL_STYLE, |
|---|
| | 839 | i_style | WS_CLIPCHILDREN ); |
|---|
| | 840 | |
|---|
| | 841 | /* Create our fullscreen window */ |
|---|
| | 842 | p_vout->p_sys->hfswnd = |
|---|
| | 843 | CreateWindowEx( WS_EX_APPWINDOW, _T("VLC WinGDI"), |
|---|
| | 844 | _T(VOUT_TITLE), |
|---|
| | 845 | WS_NONAVDONEBUTTON|WS_CLIPCHILDREN, |
|---|
| | 846 | CW_USEDEFAULT, CW_USEDEFAULT, |
|---|
| | 847 | CW_USEDEFAULT, CW_USEDEFAULT, |
|---|
| | 848 | NULL, NULL, GetModuleHandle(NULL), NULL ); |
|---|
| | 849 | } |
|---|
| | 850 | |
|---|
| | 851 | /* Display our window */ |
|---|
| | 852 | ShowWindow( p_vout->p_sys->hwnd, SW_SHOW ); |
|---|
| | 853 | UpdateWindow( p_vout->p_sys->hwnd ); |
|---|
| | 854 | |
|---|
| | 855 | /* Create video sub-window */ |
|---|
| | 856 | p_vout->p_sys->hvideownd = |
|---|
| | 857 | CreateWindow( _T("VLC WinGDI video"), _T(""), /* window class */ |
|---|
| | 858 | WS_CHILD | WS_VISIBLE, /* window style */ |
|---|
| | 859 | CW_USEDEFAULT, CW_USEDEFAULT, /* default coordinates */ |
|---|
| | 860 | CW_USEDEFAULT, CW_USEDEFAULT, |
|---|
| | 861 | p_vout->p_sys->hwnd, /* parent window */ |
|---|
| | 862 | NULL, GetModuleHandle(NULL), |
|---|
| | 863 | (LPVOID)p_vout ); /* send p_vout to WM_CREATE */ |
|---|
| | 864 | |
|---|
| | 865 | ShowWindow( p_vout->p_sys->hvideownd, SW_SHOW ); |
|---|
| | 930 | * UpdateRects: update clipping rectangles |
|---|
| | 931 | ***************************************************************************** |
|---|
| | 932 | * This function is called when the window position or size are changed, and |
|---|
| | 933 | * its job is to update the source and destination RECTs used to display the |
|---|
| | 934 | * picture. |
|---|
| | 935 | *****************************************************************************/ |
|---|
| | 936 | static void UpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force ) |
|---|
| | 937 | { |
|---|
| | 938 | #define rect_src p_vout->p_sys->rect_src |
|---|
| | 939 | #define rect_src_clipped p_vout->p_sys->rect_src_clipped |
|---|
| | 940 | #define rect_dest p_vout->p_sys->rect_dest |
|---|
| | 941 | #define rect_dest_clipped p_vout->p_sys->rect_dest_clipped |
|---|
| | 942 | |
|---|
| | 943 | int i_width, i_height, i_x, i_y; |
|---|
| | 944 | |
|---|
| | 945 | RECT rect; |
|---|
| | 946 | POINT point; |
|---|
| | 947 | |
|---|
| | 948 | /* Retrieve the window size */ |
|---|
| | 949 | GetClientRect( p_vout->p_sys->hwnd, &rect ); |
|---|
| | 950 | |
|---|
| | 951 | /* Retrieve the window position */ |
|---|
| | 952 | point.x = point.y = 0; |
|---|
| | 953 | ClientToScreen( p_vout->p_sys->hwnd, &point ); |
|---|
| | 954 | |
|---|
| | 955 | /* If nothing changed, we can return */ |
|---|
| | 956 | if( !b_force |
|---|
| | 957 | && p_vout->p_sys->i_window_width == rect.right |
|---|
| | 958 | && p_vout->p_sys->i_window_height == rect.bottom |
|---|
| | 959 | && p_vout->p_sys->i_window_x == point.x |
|---|
| | 960 | && p_vout->p_sys->i_window_y == point.y ) |
|---|
| | 961 | { |
|---|
| | 962 | return; |
|---|
| | 963 | } |
|---|
| | 964 | |
|---|
| | 965 | /* Update the window position and size */ |
|---|
| | 966 | p_vout->p_sys->i_window_x = point.x; |
|---|
| | 967 | p_vout->p_sys->i_window_y = point.y; |
|---|
| | 968 | p_vout->p_sys->i_window_width = rect.right; |
|---|
| | 969 | p_vout->p_sys->i_window_height = rect.bottom; |
|---|
| | 970 | |
|---|
| | 971 | vout_PlacePicture( p_vout, rect.right, rect.bottom, |
|---|
| | 972 | &i_x, &i_y, &i_width, &i_height ); |
|---|
| | 973 | |
|---|
| | 974 | if( p_vout->p_sys->hvideownd ) |
|---|
| | 975 | SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP, |
|---|
| | 976 | i_x, i_y, i_width, i_height, 0 ); |
|---|
| | 977 | |
|---|
| | 978 | /* Destination image position and dimensions */ |
|---|
| | 979 | rect_dest.left = point.x + i_x; |
|---|
| | 980 | rect_dest.right = rect_dest.left + i_width; |
|---|
| | 981 | rect_dest.top = point.y + i_y; |
|---|
| | 982 | rect_dest.bottom = rect_dest.top + i_height; |
|---|
| | 983 | |
|---|
| | 984 | /* Clip the destination window */ |
|---|
| | 985 | if( !IntersectRect( &rect_dest_clipped, &rect_dest, |
|---|
| | 986 | &p_vout->p_sys->rect_display ) ) |
|---|
| | 987 | { |
|---|
| | 988 | SetRectEmpty( &rect_src_clipped ); |
|---|
| | 989 | return; |
|---|
| | 990 | } |
|---|
| | 991 | |
|---|
| | 992 | #if 0 |
|---|
| | 993 | msg_Dbg( p_vout, "image_dst_clipped coords: %i,%i,%i,%i", |
|---|
| | 994 | rect_dest_clipped.left, rect_dest_clipped.top, |
|---|
| | 995 | rect_dest_clipped.right, rect_dest_clipped.bottom ); |
|---|
| | 996 | #endif |
|---|
| | 997 | |
|---|
| | 998 | /* the 2 following lines are to fix a bug when clicking on the desktop */ |
|---|
| | 999 | if( (rect_dest_clipped.right - rect_dest_clipped.left)==0 || |
|---|
| | 1000 | (rect_dest_clipped.bottom - rect_dest_clipped.top)==0 ) |
|---|
| | 1001 | { |
|---|
| | 1002 | SetRectEmpty( &rect_src_clipped ); |
|---|
| | 1003 | return; |
|---|
| | 1004 | } |
|---|
| | 1005 | |
|---|
| | 1006 | /* src image dimensions */ |
|---|
| | 1007 | rect_src.left = 0; |
|---|
| | 1008 | rect_src.top = 0; |
|---|
| | 1009 | rect_src.right = p_vout->output.i_width; |
|---|
| | 1010 | rect_src.bottom = p_vout->output.i_height; |
|---|
| | 1011 | |
|---|
| | 1012 | /* Clip the source image */ |
|---|
| | 1013 | rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) * |
|---|
| | 1014 | p_vout->output.i_width / (rect_dest.right - rect_dest.left); |
|---|
| | 1015 | rect_src_clipped.right = p_vout->output.i_width - |
|---|
| | 1016 | (rect_dest.right - rect_dest_clipped.right) * p_vout->output.i_width / |
|---|
| | 1017 | (rect_dest.right - rect_dest.left); |
|---|
| | 1018 | rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) * |
|---|
| | 1019 | p_vout->output.i_height / (rect_dest.bottom - rect_dest.top); |
|---|
| | 1020 | rect_src_clipped.bottom = p_vout->output.i_height - |
|---|
| | 1021 | (rect_dest.bottom - rect_dest_clipped.bottom) * p_vout->output.i_height / |
|---|
| | 1022 | (rect_dest.bottom - rect_dest.top); |
|---|
| | 1023 | |
|---|
| | 1024 | #if 0 |
|---|
| | 1025 | msg_Dbg( p_vout, "image_src_clipped coords: %i,%i,%i,%i", |
|---|
| | 1026 | rect_src_clipped.left, rect_src_clipped.top, |
|---|
| | 1027 | &nb |
|---|