* wingdi.c : Win32 / WinCE GDI video output plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: wingdi.c,v 1.2 2002/11/22 15:19:47 sam Exp $
+ * $Id: wingdi.c,v 1.5 2003/01/15 13:16:39 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#include <windows.h>
#define MAX_DIRECTBUFFERS 10
-#define DEFAULT_BPP 8
/*****************************************************************************
* Local prototypes
static int Manage ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * );
static void Display ( vout_thread_t *, picture_t * );
-static void SetPalette( vout_thread_t *, u16 *, u16 *, u16 * );
+static void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );
static void EventThread ( vlc_object_t * );
static long FAR PASCAL WndProc ( HWND, UINT, WPARAM, LPARAM );
-static void InitOffscreen ( vout_thread_t * );
+static void InitBuffers ( vout_thread_t * );
/*****************************************************************************
* Private structure
/* Our video output window */
HWND window;
+ int i_depth;
/* Our offscreen bitmap and its framebuffer */
HDC off_dc;
HBITMAP off_bitmap;
- BITMAPINFO bitmapinfo;
uint8_t * p_buffer;
+
+ BITMAPINFO bitmapinfo;
+ RGBQUAD red;
+ RGBQUAD green;
+ RGBQUAD blue;
};
/*****************************************************************************
I_OUTPUTPICTURES = 0;
- /* Initialize the output structure - we can use either 8 or 15bpp */
-#if DEFAULT_BPP == 8
- p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
- p_vout->output.pf_setpalette = SetPalette;
-#else
- p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5');
- p_vout->output.i_rmask = 0x7c00;
- p_vout->output.i_gmask = 0x03e0;
- p_vout->output.i_bmask = 0x001f;
-#endif
+ /* Initialize the output structure */
+ switch( p_vout->p_sys->i_depth )
+ {
+ case 8:
+ p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
+ p_vout->output.pf_setpalette = SetPalette;
+ break;
+ case 24:
+ p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');
+ p_vout->output.i_rmask = 0x00ff0000;
+ p_vout->output.i_gmask = 0x0000ff00;
+ p_vout->output.i_bmask = 0x000000ff;
+ break;
+ default:
+ case 16:
+ p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5');
+ p_vout->output.i_rmask = 0x7c00;
+ p_vout->output.i_gmask = 0x03e0;
+ p_vout->output.i_bmask = 0x001f;
+ break;
+ }
+
p_vout->output.i_width = p_vout->render.i_width;
p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
{
/* No need to do anything, the fake direct buffers stay as they are */
HDC hdc;
- int y;
+ int i_src_bytes, i_dest_bytes;
hdc = GetDC( p_vout->p_sys->window );
SelectObject( p_vout->p_sys->off_dc, p_vout->p_sys->off_bitmap );
/* Stupid GDI is upside-down */
- for( y = p_pic->p->i_lines ; y-- ; )
+ i_src_bytes = p_pic->p->i_lines * p_pic->p->i_pitch;
+ i_dest_bytes = 0;
+
+ while( i_src_bytes )
{
- memcpy( p_vout->p_sys->p_buffer
- + p_pic->p->i_pitch * (p_pic->p->i_lines-y),
- p_pic->p->p_pixels + p_pic->p->i_pitch * y,
- p_pic->p->i_pitch );
+ i_src_bytes -= p_pic->p->i_pitch;
+
+ p_vout->p_vlc->pf_memcpy( p_vout->p_sys->p_buffer + i_dest_bytes,
+ p_pic->p->p_pixels + i_src_bytes,
+ p_pic->p->i_visible_pitch );
+
+ i_dest_bytes += p_pic->p->i_pitch;
}
BitBlt( hdc, 0, 0, p_vout->output.i_width, p_vout->output.i_height,
/*****************************************************************************
* SetPalette: sets an 8 bpp palette
*****************************************************************************/
-static void SetPalette( vout_thread_t *p_vout, u16 *red, u16 *green, u16 *blue )
+static void SetPalette( vout_thread_t *p_vout,
+ uint16_t *red, uint16_t *green, uint16_t *blue )
{
msg_Err( p_vout, "FIXME: SetPalette unimplemented" );
}
WNDCLASS wc;
MSG msg;
+#ifdef UNDER_CE
+ wchar_t *psz_class = L"VOUT";
+ wchar_t *psz_title = L"Video Output";
+#else
+ char *psz_class = "VOUT";
+ char *psz_title = "Video Output";
+#endif
+
var_Get( p_event, "p_vout", &val );
p_vout = (vout_thread_t *)val.p_address;
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = 0;
- wc.lpszClassName = L"VOUT";
+ wc.lpszClassName = psz_class;
RegisterClass( &wc );
/* Create output window */
p_vout->p_sys->window =
- CreateWindow( L"VOUT", L"Video Output",
+ CreateWindow( psz_class, psz_title,
WS_VISIBLE | WS_SIZEBOX | WS_CAPTION,
CW_USEDEFAULT, CW_USEDEFAULT,
p_vout->render.i_width,
p_vout->render.i_height + 10,
NULL, NULL, instance, (LPVOID)p_vout );
+ /* Initialize offscreen buffer */
+ InitBuffers( p_vout );
+
+ /* Tell the video output we're ready to receive data */
+ vlc_thread_ready( p_event );
+
/* Display our window */
ShowWindow( p_vout->p_sys->window, SW_SHOWNORMAL );
UpdateWindow( p_vout->p_sys->window );
- vlc_thread_ready( p_event );
-
while( !p_event->b_die
&& GetMessage( &msg, p_vout->p_sys->window, 0, 0 ) )
{
break;
}
- DispatchMessage( &msg );
+ 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;
+ }
}
DestroyWindow( p_vout->p_sys->window );
+
+ DeleteDC( p_vout->p_sys->off_dc );
+ DeleteObject( p_vout->p_sys->off_bitmap );
}
/*****************************************************************************
break;
case WM_CREATE:
- InitOffscreen( p_vout );
break;
case WM_DESTROY:
- DeleteDC( p_vout->p_sys->off_dc );
- DeleteObject( p_vout->p_sys->off_bitmap );
PostQuitMessage( 0 );
break;
}
/*****************************************************************************
- * InitOffscreen: initialize an offscreen bitmap for direct buffer operations.
+ * InitBuffers: initialize an offscreen bitmap for direct buffer operations.
*****************************************************************************/
-static void InitOffscreen( vout_thread_t *p_vout )
+static void InitBuffers( vout_thread_t *p_vout )
{
- BITMAPINFOHEADER *p_header = &p_vout->p_sys->bitmapinfo.bmiHeader;
+ 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;
window_dc = GetDC( p_vout->p_sys->window );
+ /* Get screen properties */
+ p_vout->p_sys->i_depth = GetDeviceCaps( window_dc, PLANES )
+ * GetDeviceCaps( window_dc, BITSPIXEL );
+ msg_Dbg( p_vout, "GDI depth is %i", p_vout->p_sys->i_depth );
+
+ /* Initialize offscreen bitmap */
+ memset( p_info, 0, sizeof( BITMAPINFO ) + 3 * sizeof( RGBQUAD ) );
+
p_header->biSize = sizeof( BITMAPINFOHEADER );
p_header->biPlanes = 1;
- p_header->biCompression = BI_RGB;
-#if DEFAULT_BPP == 8
- p_header->biBitCount = 8;
- p_header->biSizeImage =
- p_vout->render.i_height * p_vout->render.i_width;
-#else
- p_header->biBitCount = 16;
- p_header->biSizeImage =
- p_vout->render.i_height * p_vout->render.i_width * 2;
-#endif
+ switch( p_vout->p_sys->i_depth )
+ {
+ case 8:
+ p_header->biBitCount = 8;
+ p_header->biSizeImage = i_pixels;
+ p_header->biCompression = BI_RGB;
+ /* FIXME: we need a palette here */
+ break;
+ case 24:
+ case 32:
+ p_header->biBitCount = 32;
+ p_header->biSizeImage = i_pixels * 4;
+ p_header->biCompression = BI_BITFIELDS;
+ ((DWORD*)p_info->bmiColors)[0] = 0x00ff0000;
+ ((DWORD*)p_info->bmiColors)[1] = 0x0000ff00;
+ ((DWORD*)p_info->bmiColors)[2] = 0x000000ff;
+ break;
+ case 16:
+ default:
+ p_header->biBitCount = 16;
+ p_header->biSizeImage = i_pixels * 2;
+ p_header->biCompression = BI_BITFIELDS;
+ ((DWORD*)p_info->bmiColors)[0] = 0x00007c00;
+ ((DWORD*)p_info->bmiColors)[1] = 0x000003e0;
+ ((DWORD*)p_info->bmiColors)[2] = 0x0000001f;
+ break;
+ }
p_header->biWidth = p_vout->render.i_width;
p_header->biHeight = p_vout->render.i_height;
p_header->biClrImportant = 0;