⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wingdi.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
 *****************************************************************************/static void End( vout_thread_t *p_vout ){}/***************************************************************************** * Manage: handle events ***************************************************************************** * This function should be called regularly by video output thread. It manages * console events. It returns a non null value on error. *****************************************************************************/static int Manage( vout_thread_t *p_vout ){#ifndef UNDER_CE    WINDOWPLACEMENT window_placement;#endif    /* If we do not control our window, we check for geometry changes     * ourselves because the parent might not send us its events. */    if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )    {        RECT rect_parent;        POINT point;        GetClientRect( p_vout->p_sys->hparent, &rect_parent );        point.x = point.y = 0;        ClientToScreen( p_vout->p_sys->hparent, &point );        OffsetRect( &rect_parent, point.x, point.y );        if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )        {            int i_x, i_y, i_width, i_height;            p_vout->p_sys->rect_parent = rect_parent;            /* This one is to force the update even if only             * the position has changed */            SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1,                          rect_parent.right - rect_parent.left,                          rect_parent.bottom - rect_parent.top, 0 );            SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,                          rect_parent.right - rect_parent.left,                          rect_parent.bottom - rect_parent.top, 0 );            vout_PlacePicture( p_vout, rect_parent.right - rect_parent.left,                               rect_parent.bottom - rect_parent.top,                               &i_x, &i_y, &i_width, &i_height );            SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,                          i_x, i_y, i_width, i_height, 0 );        }    }    /* We used to call the Win32 PeekMessage function here to read the window     * messages. But since window can stay blocked into this function for a     * long time (for example when you move your window on the screen), I     * decided to isolate PeekMessage in another thread. */    /*     * Fullscreen change     */    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE        || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )    {        int i_style = 0;        vlc_value_t val;        HWND hwnd = (p_vout->p_sys->hparent && p_vout->p_sys->hfswnd) ?            p_vout->p_sys->hfswnd : p_vout->p_sys->hwnd;        p_vout->b_fullscreen = ! p_vout->b_fullscreen;        /* We need to switch between Maximized and Normal sized window */#ifndef UNDER_CE        window_placement.length = sizeof(WINDOWPLACEMENT);        GetWindowPlacement( hwnd, &window_placement );#endif        if( p_vout->b_fullscreen )        {#ifndef UNDER_CE            /* Change window style, no borders and no title bar */            int i_style = WS_CLIPCHILDREN | WS_VISIBLE;            SetWindowLong( hwnd, GWL_STYLE, i_style );            if( p_vout->p_sys->hparent )            {                /* Retrieve current window position so fullscreen will happen                 * on the right screen */                POINT point = {0,0};                RECT rect;                ClientToScreen( p_vout->p_sys->hwnd, &point );                GetClientRect( p_vout->p_sys->hwnd, &rect );                SetWindowPos( hwnd, 0, point.x, point.y,                              rect.right, rect.bottom,                              SWP_NOZORDER|SWP_FRAMECHANGED );                GetWindowPlacement( hwnd, &window_placement );            }            /* Maximize window */            window_placement.showCmd = SW_SHOWMAXIMIZED;            SetWindowPlacement( hwnd, &window_placement );            SetWindowPos( hwnd, 0, 0, 0, 0, 0,                          SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);#endif            if( p_vout->p_sys->hparent )            {                RECT rect;                GetClientRect( hwnd, &rect );                SetParent( p_vout->p_sys->hwnd, hwnd );                SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,                              rect.right, rect.bottom,                              SWP_NOZORDER|SWP_FRAMECHANGED );            }            ShowWindow( hwnd, SW_SHOW );            SetForegroundWindow( hwnd );        }        else        {            /* Change window style, no borders and no title bar */            //SetWindowLong( hwnd, GWL_STYLE, p_vout->p_sys->i_window_style );#ifndef UNDER_CE            /* Normal window */            window_placement.showCmd = SW_SHOWNORMAL;            SetWindowPlacement( hwnd, &window_placement );            SetWindowPos( hwnd, 0, 0, 0, 0, 0,                          SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);#endif            if( p_vout->p_sys->hparent )            {                RECT rect;                GetClientRect( p_vout->p_sys->hparent, &rect );                SetParent( p_vout->p_sys->hwnd, p_vout->p_sys->hparent );                SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,                              rect.right, rect.bottom,                              SWP_NOZORDER|SWP_FRAMECHANGED );                ShowWindow( hwnd, SW_HIDE );                SetForegroundWindow( p_vout->p_sys->hparent );            }            /* Make sure the mouse cursor is displayed */            //PostMessage( p_vout->p_sys->hwnd, WM_VLC_SHOW_MOUSE, 0, 0 );        }        /* Change window style, borders and title bar */        ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );        UpdateWindow( p_vout->p_sys->hwnd );        /* Update the object variable and trigger callback */        val.b_bool = p_vout->b_fullscreen;        var_Set( p_vout, "fullscreen", val );        p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;        p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;    }    return VLC_SUCCESS;}/***************************************************************************** * Render: render previously calculated output *****************************************************************************/static void Render( vout_thread_t *p_vout, picture_t *p_pic ){    /* No need to do anything, the fake direct buffers stay as they are */}/***************************************************************************** * Display: displays previously rendered output *****************************************************************************/#define rect_src p_vout->p_sys->rect_src#define rect_src_clipped p_vout->p_sys->rect_src_clipped#define rect_dest p_vout->p_sys->rect_dest#define rect_dest_clipped p_vout->p_sys->rect_dest_clipped#ifndef MODULE_NAME_IS_wingapistatic void DisplayGDI( vout_thread_t *p_vout, picture_t *p_pic ){    vout_sys_t *p_sys = p_vout->p_sys;    RECT rect_dst = rect_dest_clipped;    HDC hdc = GetDC( p_sys->hvideownd );    OffsetRect( &rect_dst, -rect_dest.left, -rect_dest.top );    SelectObject( p_sys->off_dc, p_sys->off_bitmap );    if( rect_dest_clipped.right - rect_dest_clipped.left !=        rect_src_clipped.right - rect_src_clipped.left ||        rect_dest_clipped.bottom - rect_dest_clipped.top !=        rect_src_clipped.bottom - rect_src_clipped.top )    {        StretchBlt( hdc, rect_dst.left, rect_dst.top,                    rect_dst.right, rect_dst.bottom,                    p_sys->off_dc, rect_src_clipped.left, rect_src_clipped.top,                    rect_src_clipped.right, rect_src_clipped.bottom, SRCCOPY );    }    else    {        BitBlt( hdc, rect_dst.left, rect_dst.top,                rect_dst.right, rect_dst.bottom,                p_sys->off_dc, rect_src_clipped.left,                rect_src_clipped.top, SRCCOPY );    }    ReleaseDC( p_sys->hwnd, hdc );}#elsestatic int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic ){    vout_sys_t *p_sys = p_vout->p_sys;    int i_x, i_y, i_width, i_height;    RECT video_rect;    POINT point;    /* Undo the display */    if( ( GetForegroundWindow() != GetParent(p_sys->hwnd) ) ||        ( p_sys->b_video_display == VLC_FALSE ) )    {        //return VLC_EGENERIC;    }    GetClientRect( p_sys->hwnd, &video_rect);    vout_PlacePicture( p_vout, video_rect.right - video_rect.left,                       video_rect.bottom - video_rect.top,                       &i_x, &i_y, &i_width, &i_height );    point.x = point.y = 0;    ClientToScreen( p_sys->hwnd, &point );    i_x += point.x + video_rect.left;    i_y += point.y + video_rect.top;    if( i_width != p_vout->output.i_width ||        i_height != p_vout->output.i_height )    {        GXDisplayProperties gxdisplayprop = GXGetDisplayProperties();        p_sys->render_width = i_width;        p_sys->render_height = i_height;        p_vout->i_changes |= VOUT_SIZE_CHANGE;        msg_Dbg( p_vout, "vout size change (%ix%i -> %ix%i)",                 i_width, i_height, p_vout->output.i_width,                 p_vout->output.i_height );        p_vout->p_sys->i_pic_pixel_pitch = gxdisplayprop.cbxPitch;        p_vout->p_sys->i_pic_pitch = gxdisplayprop.cbyPitch;        return VLC_EGENERIC;    }    else    {        GXDisplayProperties gxdisplayprop;        RECT display_rect, dest_rect;        uint8_t *p_dest, *p_src = p_pic->p->p_pixels;        video_rect.left = i_x; video_rect.top = i_y;        video_rect.right = i_x + i_width;        video_rect.bottom = i_y + i_height;        gxdisplayprop = GXGetDisplayProperties();        display_rect.left = 0; display_rect.top = 0;        display_rect.right = gxdisplayprop.cxWidth;        display_rect.bottom = gxdisplayprop.cyHeight;        if( !IntersectRect( &dest_rect, &video_rect, &display_rect ) )        {            return VLC_EGENERIC;        }#if 0        msg_Err( p_vout, "video (%d,%d,%d,%d) display (%d,%d,%d,%d) "                 "dest (%d,%d,%d,%d)",                 video_rect.left, video_rect.right,                 video_rect.top, video_rect.bottom,                 display_rect.left, display_rect.right,                 display_rect.top, display_rect.bottom,                 dest_rect.left, dest_rect.right,                 dest_rect.top, dest_rect.bottom );#endif        if( !(p_dest = GXBeginDraw()) )        {#if 0            msg_Err( p_vout, "GXBeginDraw error %d ", GetLastError() );#endif            return VLC_EGENERIC;        }        p_src += (dest_rect.left - video_rect.left) * gxdisplayprop.cbxPitch +            (dest_rect.top - video_rect.top) * p_pic->p->i_pitch;        p_dest += dest_rect.left * gxdisplayprop.cbxPitch +            dest_rect.top * gxdisplayprop.cbyPitch;        i_width = dest_rect.right - dest_rect.left;        i_height = dest_rect.bottom - dest_rect.top;        p_pic->p->p_pixels = p_dest;    }    return VLC_SUCCESS;}static int GAPIUnlockSurface( vout_thread_t *p_vout, picture_t *p_pic ){    GXEndDraw();    return VLC_SUCCESS;}static void DisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic ){}#endif#undef rect_src#undef rect_src_clipped#undef rect_dest#undef rect_dest_clipped/***************************************************************************** * SetPalette: sets an 8 bpp palette *****************************************************************************/static void SetPalette( vout_thread_t *p_vout,                        uint16_t *red, uint16_t *green, uint16_t *blue ){    msg_Err( p_vout, "FIXME: SetPalette unimplemented" );}/***************************************************************************** * EventThread: Event handling thread *****************************************************************************/static void EventThread ( vlc_object_t *p_event ){    vout_thread_t *p_vout;    vlc_value_t   val;    int        i_style;    WNDCLASS   wc;    MSG        msg;    /* Initialisations */    var_Get( p_event, "p_vout", &val );    p_vout = (vout_thread_t *)val.p_address;    /* Register window class */    memset( &wc, 0, sizeof(wc) );    wc.style          = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc    = (WNDPROC)WndProc;    wc.cbClsExtra     = 0;    wc.cbWndExtra     = 0;    wc.hInstance      = GetModuleHandle(NULL);    wc.hIcon          = 0;    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground  = (HBRUSH)GetStockObject( BLACK_BRUSH );    wc.lpszMenuName   = 0;    wc.lpszClassName  = _T("VLC WinGDI");    RegisterClass( &wc );    /* Register the video sub-window class */    wc.lpszClassName = _T("VLC WinGDI video"); wc.hIcon = 0;    RegisterClass(&wc);    /* Create output window */    p_vout->p_sys->hparent = (HWND)        vout_RequestWindow( p_vout, &p_vout->p_sys->i_window_x,                            &p_vout->p_sys->i_window_y,                            (unsigned int *)&p_vout->p_sys->i_window_width,                            (unsigned int *)&p_vout->p_sys->i_window_height );    if( p_vout->p_sys->hparent )        ShowWindow( p_vout->p_sys->hparent, SW_SHOW );    if( p_vout->p_sys->hparent )        i_style = WS_VISIBLE|WS_CLIPCHILDREN|WS_CHILD;    else        i_style = WS_OVERLAPPEDWINDOW|WS_SIZEBOX|WS_VISIBLE|WS_CLIPCHILDREN;    p_vout->p_sys->hwnd =        CreateWindow( _T("VLC WinGDI"), _T(VOUT_TITLE), i_style,                      (p_vout->p_sys->i_window_x < 0) ? CW_USEDEFAULT :                      p_vout->p_sys->i_window_x,   /* default X coordinate */                      (p_vout->p_sys->i_window_y < 0) ? CW_USEDEFAULT :                      p_vout->p_sys->i_window_y,   /* default Y coordinate */                      p_vout->p_sys->i_window_width,                      p_vout->p_sys->i_window_height + 10,                      p_vout->p_sys->hparent, NULL,                      GetModuleHandle(NULL), (LPVOID)p_vout );    if( !p_vout->p_sys->hwnd )    {        msg_Warn( p_vout, "couldn't create window" );        return;    }    msg_Warn( p_vout, "Created WinGDI window" );    if( p_vout->p_sys->hparent )    {        LONG i_style;        /* We don't want the window owner to overwrite our client area */        i_style = GetWindowLong( p_vout->p_sys->hparent, GWL_STYLE );        if( !(i_style & WS_CLIPCHILDREN) )            /* Hmmm, apparently this is a blocking call... */            SetWindowLong( p_vout->p_sys->hparent, GWL_STYLE,                           i_style | WS_CLIPCHILDREN );        /* Create our fullscreen window */        p_vout->p_sys->hfswnd =            CreateWindowEx( WS_EX_APPWINDOW, _T("VLC WinGDI"),                            _T(VOUT_TITLE),                            WS_NONAVDONEBUTTON|WS_CLIPCHILDREN,                            CW_USEDEFAULT, CW_USEDEFAULT,                            CW_USEDEFAULT, CW_USEDEFAULT,                            NULL, NULL, GetModuleHandle(NULL), (LPVOID)p_vout);    }    /* Display our window */    ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );    UpdateWindow( p_vout->p_sys->hwnd );    /* Create video sub-window */    p_vout->p_sys->hvideownd =        CreateWindow( _T("VLC WinGDI video"), _T(""),   /* window class */                    WS_CHILD | WS_VISIBLE,                   /* window style */                    CW_USEDEFAULT, CW_USEDEFAULT,     /* default coordinates */                    CW_USEDEFAULT, CW_USEDEFAULT,                    p_vout->p_sys->hwnd,                  /* parent window */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -