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 + -
显示快捷键?