wingdi.c

来自「video linux conference」· C语言 代码 · 共 1,280 行 · 第 1/3 页

C
1,280
字号
                    NULL, GetModuleHandle(NULL),                    (LPVOID)p_vout );            /* send p_vout to WM_CREATE */    /* Initialize offscreen buffer */    InitBuffers( p_vout );    p_vout->pf_control = Control;    /* Tell the video output we're ready to receive data */    vlc_thread_ready( p_event );    while( !p_event->b_die && GetMessage( &msg, 0, 0, 0 ) )    {        /* Check if we are asked to exit */        if( p_event->b_die ) break;        switch( msg.message )        {        case WM_KEYDOWN:            switch( msg.wParam )            {            case VK_ESCAPE:                p_event->p_vlc->b_die = VLC_TRUE;                break;            }            TranslateMessage( &msg );            break;        case WM_CHAR:            switch( msg.wParam )            {            case 'q':            case 'Q':                p_event->p_vlc->b_die = VLC_TRUE;                break;            }            break;        default:            TranslateMessage( &msg );            DispatchMessage( &msg );            break;        }    }    msg_Dbg( p_vout, "CloseWindow" );#ifdef MODULE_NAME_IS_wingapi    GXCloseDisplay();#else    DeleteDC( p_vout->p_sys->off_dc );    DeleteObject( p_vout->p_sys->off_bitmap );#endif    DestroyWindow( p_vout->p_sys->hwnd );    if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd );    if( p_vout->p_sys->hparent )        vout_ReleaseWindow( p_vout, (void *)p_vout->p_sys->hparent );}/***************************************************************************** * UpdateRects: update clipping rectangles ***************************************************************************** * This function is called when the window position or size are changed, and * its job is to update the source and destination RECTs used to display the * picture. *****************************************************************************/static void UpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force ){#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    int i_width, i_height, i_x, i_y;    RECT  rect;    POINT point;    /* Retrieve the window size */    GetClientRect( p_vout->p_sys->hwnd, &rect );    /* Retrieve the window position */    point.x = point.y = 0;    ClientToScreen( p_vout->p_sys->hwnd, &point );    /* If nothing changed, we can return */    if( !b_force         && p_vout->p_sys->i_window_width == rect.right         && p_vout->p_sys->i_window_height == rect.bottom         && p_vout->p_sys->i_window_x == point.x         && p_vout->p_sys->i_window_y == point.y )    {        return;    }    /* Update the window position and size */    p_vout->p_sys->i_window_x = point.x;    p_vout->p_sys->i_window_y = point.y;    p_vout->p_sys->i_window_width = rect.right;    p_vout->p_sys->i_window_height = rect.bottom;    vout_PlacePicture( p_vout, rect.right, rect.bottom,                       &i_x, &i_y, &i_width, &i_height );    if( p_vout->p_sys->hvideownd )        SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,                      i_x, i_y, i_width, i_height, 0 );    /* Destination image position and dimensions */    rect_dest.left = point.x + i_x;    rect_dest.right = rect_dest.left + i_width;    rect_dest.top = point.y + i_y;    rect_dest.bottom = rect_dest.top + i_height;    /* Clip the destination window */    if( !IntersectRect( &rect_dest_clipped, &rect_dest,                        &p_vout->p_sys->rect_display ) )    {        SetRectEmpty( &rect_src_clipped );        return;    }#if 0    msg_Dbg( p_vout, "image_dst_clipped coords: %i,%i,%i,%i",                     rect_dest_clipped.left, rect_dest_clipped.top,                     rect_dest_clipped.right, rect_dest_clipped.bottom );#endif    /* the 2 following lines are to fix a bug when clicking on the desktop */    if( (rect_dest_clipped.right - rect_dest_clipped.left)==0 ||        (rect_dest_clipped.bottom - rect_dest_clipped.top)==0 )    {        SetRectEmpty( &rect_src_clipped );        return;    }    /* src image dimensions */    rect_src.left = 0;    rect_src.top = 0;    rect_src.right = p_vout->output.i_width;    rect_src.bottom = p_vout->output.i_height;    /* Clip the source image */    rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) *      p_vout->output.i_width / (rect_dest.right - rect_dest.left);    rect_src_clipped.right = p_vout->output.i_width -      (rect_dest.right - rect_dest_clipped.right) * p_vout->output.i_width /      (rect_dest.right - rect_dest.left);    rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) *      p_vout->output.i_height / (rect_dest.bottom - rect_dest.top);    rect_src_clipped.bottom = p_vout->output.i_height -      (rect_dest.bottom - rect_dest_clipped.bottom) * p_vout->output.i_height /      (rect_dest.bottom - rect_dest.top);#if 0    msg_Dbg( p_vout, "image_src_clipped coords: %i,%i,%i,%i",                     rect_src_clipped.left, rect_src_clipped.top,                     rect_src_clipped.right, rect_src_clipped.bottom );#endif    /* The destination coordinates need to be relative to the current     * directdraw primary surface (display) */    rect_dest_clipped.left -= p_vout->p_sys->rect_display.left;    rect_dest_clipped.right -= p_vout->p_sys->rect_display.left;    rect_dest_clipped.top -= p_vout->p_sys->rect_display.top;    rect_dest_clipped.bottom -= p_vout->p_sys->rect_display.top;    /* Signal the change in size/position */    p_vout->p_sys->i_changes |= DX_POSITION_CHANGE;#undef rect_src#undef rect_src_clipped#undef rect_dest#undef rect_dest_clipped}/***************************************************************************** * Message handler for the main window *****************************************************************************/static long FAR PASCAL WndProc( HWND hWnd, UINT message,                                WPARAM wParam, LPARAM lParam ){    vout_thread_t *p_vout;    if( message == WM_CREATE )    {        /* Store p_vout for future use */        p_vout = (vout_thread_t *)((CREATESTRUCT *)lParam)->lpCreateParams;        SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)p_vout );        if( p_vout ) msg_Dbg( p_vout, "create: %p", hWnd );    }    else    {        p_vout = (vout_thread_t *)GetWindowLongPtr( hWnd, GWLP_USERDATA );    }#ifndef UNDER_CE    /* Catch the screensaver and the monitor turn-off */    if( message == WM_SYSCOMMAND &&        ( wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER ) )    {        //if( p_vout ) msg_Dbg( p_vout, "WinProc WM_SYSCOMMAND screensaver" );        return 0; /* this stops them from happening */    }#endif    if( !p_vout )    {        /* Hmmm mozilla does manage somehow to save the pointer to our         * windowproc and still calls it after the vout has been closed. */        return DefWindowProc(hWnd, message, wParam, lParam);    }    if( hWnd != p_vout->p_sys->hwnd &&        hWnd != p_vout->p_sys->hfswnd &&        hWnd != p_vout->p_sys->hvideownd )        return DefWindowProc(hWnd, message, wParam, lParam);    switch( message )    {    case WM_WINDOWPOSCHANGED:        if( hWnd == p_vout->p_sys->hwnd )            UpdateRects( p_vout, VLC_TRUE );        break;#if 0    case WM_ACTIVATE:        msg_Err( p_vout, "WM_ACTIVATE: %i", wParam );        if( wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE )            GXResume();        else if( wParam == WA_INACTIVE )            GXSuspend();        break;#endif    case WM_KILLFOCUS:        p_vout->p_sys->b_focus = VLC_FALSE;        if( !p_vout->p_sys->b_parent_focus ) GXSuspend();        if( hWnd == p_vout->p_sys->hfswnd )        {#ifdef UNDER_CE            HWND htbar = FindWindow( _T("HHTaskbar"), NULL );            ShowWindow( htbar, SW_SHOW );#endif        }        if( !p_vout->p_sys->hparent ||            hWnd == p_vout->p_sys->hfswnd )        {            SHFullScreen( hWnd, SHFS_SHOWSIPBUTTON );        }        break;    case WM_SETFOCUS:        p_vout->p_sys->b_focus = VLC_TRUE;        GXResume();        if( p_vout->p_sys->hparent &&            hWnd != p_vout->p_sys->hfswnd && p_vout->b_fullscreen )            p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;        if( hWnd == p_vout->p_sys->hfswnd )        {#ifdef UNDER_CE            HWND htbar = FindWindow( _T("HHTaskbar"), NULL );            ShowWindow( htbar, SW_HIDE );#endif        }        if( !p_vout->p_sys->hparent ||            hWnd == p_vout->p_sys->hfswnd )        {            SHFullScreen( hWnd, SHFS_HIDESIPBUTTON );        }        break;    case WM_LBUTTONDOWN:        p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;        break;    case WM_MOUSEMOVE:        break;    case WM_LBUTTONUP:        break;    case WM_INITMENUPOPUP:        p_vout->p_sys->b_video_display = VLC_FALSE;        break;    case WM_NOTIFY:        // Redo the video display because menu can be closed        // FIXME verify if p_child_window exits        if( (((NMHDR *)lParam)->code) == NM_CUSTOMDRAW )            p_vout->p_sys->b_video_display = VLC_TRUE;        break;    case WM_DESTROY:        msg_Dbg( p_vout, "WinProc WM_DESTROY" );        PostQuitMessage( 0 );        break;    default:        return DefWindowProc( hWnd, message, wParam, lParam );    }    return 0;}/***************************************************************************** * InitBuffers: initialize an offscreen bitmap for direct buffer operations. *****************************************************************************/static void InitBuffers( vout_thread_t *p_vout ){    BITMAPINFOHEADER *p_header = &p_vout->p_sys->bitmapinfo.bmiHeader;    BITMAPINFO *p_info = &p_vout->p_sys->bitmapinfo;    int i_pixels = p_vout->render.i_height * p_vout->render.i_width;    HDC window_dc = GetDC( p_vout->p_sys->hvideownd );    /* Get screen properties */#ifdef MODULE_NAME_IS_wingapi    GXDisplayProperties gx_displayprop = GXGetDisplayProperties();    p_vout->p_sys->i_depth = gx_displayprop.cBPP;#else    p_vout->p_sys->i_depth = GetDeviceCaps( window_dc, PLANES ) *        GetDeviceCaps( window_dc, BITSPIXEL );#endif    msg_Dbg( p_vout, "GDI depth is %i", p_vout->p_sys->i_depth );#ifdef MODULE_NAME_IS_wingapi    GXOpenDisplay( p_vout->p_sys->hvideownd, GX_FULLSCREEN );#else    /* Initialize offscreen bitmap */    memset( p_info, 0, sizeof( BITMAPINFO ) + 3 * sizeof( RGBQUAD ) );    p_header->biSize = sizeof( BITMAPINFOHEADER );    p_header->biSizeImage = 0;    p_header->biPlanes = 1;    switch( p_vout->p_sys->i_depth )    {    case 8:        p_header->biBitCount = 8;        p_header->biCompression = BI_RGB;        /* FIXME: we need a palette here */        break;    case 15:        p_header->biBitCount = 15;        p_header->biCompression = BI_BITFIELDS;//BI_RGB;        ((DWORD*)p_info->bmiColors)[0] = 0x00007c00;        ((DWORD*)p_info->bmiColors)[1] = 0x000003e0;        ((DWORD*)p_info->bmiColors)[2] = 0x0000001f;        break;    case 16:        p_header->biBitCount = 16;        p_header->biCompression = BI_BITFIELDS;//BI_RGB;        ((DWORD*)p_info->bmiColors)[0] = 0x0000f800;        ((DWORD*)p_info->bmiColors)[1] = 0x000007e0;        ((DWORD*)p_info->bmiColors)[2] = 0x0000001f;        break;    case 24:        p_header->biBitCount = 24;        p_header->biCompression = BI_RGB;        ((DWORD*)p_info->bmiColors)[0] = 0x00ff0000;        ((DWORD*)p_info->bmiColors)[1] = 0x0000ff00;        ((DWORD*)p_info->bmiColors)[2] = 0x000000ff;        break;    case 32:        p_header->biBitCount = 32;        p_header->biCompression = BI_RGB;        ((DWORD*)p_info->bmiColors)[0] = 0x00ff0000;        ((DWORD*)p_info->bmiColors)[1] = 0x0000ff00;        ((DWORD*)p_info->bmiColors)[2] = 0x000000ff;        break;    default:        msg_Err( p_vout, "screen depth %i not supported",                 p_vout->p_sys->i_depth );        return;        break;    }    p_header->biWidth = p_vout->render.i_width;    p_header->biHeight = -p_vout->render.i_height;    p_header->biClrImportant = 0;    p_header->biClrUsed = 0;    p_header->biXPelsPerMeter = 0;    p_header->biYPelsPerMeter = 0;    p_vout->p_sys->i_pic_pixel_pitch = p_header->biBitCount / 8;    p_vout->p_sys->i_pic_pitch = p_header->biBitCount * p_header->biWidth / 8;    p_vout->p_sys->off_bitmap =        CreateDIBSection( window_dc, (BITMAPINFO *)p_header, DIB_RGB_COLORS,                          (void**)&p_vout->p_sys->p_pic_buffer, NULL, 0 );    p_vout->p_sys->off_dc = CreateCompatibleDC( window_dc );    SelectObject( p_vout->p_sys->off_dc, p_vout->p_sys->off_bitmap );    ReleaseDC( 0, window_dc );#endif}/***************************************************************************** * Control: control facility for the vout *****************************************************************************/static int Control( vout_thread_t *p_vout, int i_query, va_list args ){    vlc_bool_t b_bool;    switch( i_query )    {    case VOUT_SET_FOCUS:        b_bool = va_arg( args, vlc_bool_t );        p_vout->p_sys->b_parent_focus = b_bool;        if( b_bool ) GXResume();        else if( !p_vout->p_sys->b_focus ) GXSuspend();        return VLC_SUCCESS;    default:        return vout_vaControlDefault( p_vout, i_query, args );    }}

⌨️ 快捷键说明

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