* aout_directx.c: Windows DirectX audio output method
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: aout_directx.c,v 1.3 2001/06/14 01:49:44 sam Exp $
+ * $Id: aout_directx.c,v 1.4 2001/07/08 17:45:52 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
byte_t *buffer, int i_size );
static void aout_Close ( aout_thread_t *p_aout );
-/* local function */
+/* local functions */
static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout );
static int DirectxInitDSound( aout_thread_t *p_aout );
intf_WarnMsg( 3, "aout: can't set primary buffer format");
}
+#if 0
/* ensure the primary buffer is playing. We won't actually hear anything
* until the secondary buffer is playing */
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer_primary,
p_aout->p_sys->p_dsbuffer_primary = NULL;
return( 1 );
}
+#endif
return( 0 );
}
return( l_buffer_limit );
}
+#if 0
/* temporary hack. When you start playing a new file, the play position
* doesn't start changing immediatly, even though sound is already
* playing from the sound card */
intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_buffer_limit);
return( l_buffer_limit );
}
+#endif
l_result = (p_aout->p_sys->l_write_position >= l_play_position) ?
(p_aout->p_sys->l_write_position - l_play_position) /2
intf_WarnMsg( 3, "aout: DirectX aout_Play can'get buffer position");
}
+#if 1
/* check that we are not overflowing the circular buffer (everything should
* be alright but just in case) */
l_buffer_free_length = l_play_position - p_aout->p_sys->l_write_position;
}
else
{
+#if 0
intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: size %i, free %i !!!"
, i_size, l_buffer_free_length);
intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
-
+#endif
}
+#endif
/* Before copying anything, we have to lock the buffer */
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
/* Now do the actual memcopy (two memcpy because the buffer is circular) */
memcpy( p_write_position, buffer, l_bytes1 );
if( p_start_buffer != NULL )
+ {
memcpy( p_start_buffer, buffer + l_bytes1, l_bytes2 );
+ }
/* Now the data has been copied, unlock the buffer */
IDirectSoundBuffer_Unlock( p_aout->p_sys->p_dsbuffer,
WAVEFORMATEX waveformat;
DSBUFFERDESC dsbdesc;
DSBCAPS dsbcaps;
- HRESULT dsresult;
/* First set the buffer format */
memset(&waveformat, 0, sizeof(WAVEFORMATEX));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
| DSBCAPS_GLOBALFOCUS; /* Allows background playing */
- dsbdesc.dwBufferBytes = waveformat.nAvgBytesPerSec * 4; /* 4 sec buffer */
+ dsbdesc.dwBufferBytes = waveformat.nAvgBytesPerSec * 2; /* 2 sec buffer */
dsbdesc.lpwfxFormat = &waveformat;
if( IDirectSound_CreateSoundBuffer( p_aout->p_sys->p_dsobject,
* vout_directx.c: Windows DirectX video output display method
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vout_directx.c,v 1.5 2001/06/28 22:12:04 gbazin Exp $
+ * $Id: vout_directx.c,v 1.6 2001/07/08 17:45:52 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
static void DirectXCloseWindow ( vout_thread_t *p_vout );
static void DirectXCloseDisplay ( vout_thread_t *p_vout );
static void DirectXCloseSurface ( vout_thread_t *p_vout );
+static void DirectXKeepAspectRatio( vout_thread_t *p_vout, RECT *coordinates );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
WINDOWPLACEMENT window_placement;
boolean_t b_dispatch_msg = TRUE;
- while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
+ while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
- if( GetMessage(&msg, NULL, 0, 0) >= 0 )
+ switch( msg.message )
{
- switch( msg.message )
- {
- case WM_CLOSE:
- intf_WarnMsg( 4, "vout: vout_Manage WM_CLOSE" );
- p_vout->b_die = 1;
- break;
-
- case WM_QUIT:
- intf_WarnMsg( 4, "vout: vout_Manage WM_QUIT" );
- p_main->p_intf->b_die = 1;
- break;
-
- case WM_MOVE:
- intf_WarnMsg( 3, "vout: vout_Manage WM_MOVE" );
- if( !p_vout->b_need_render )
- {
- p_vout->i_changes |= VOUT_SIZE_CHANGE;
- }
- /* don't create a never ending loop */
- b_dispatch_msg = FALSE;
- break;
-
- case WM_APP:
- intf_WarnMsg( 3, "vout: vout_Manage WM_APP" );
- if( !p_vout->b_need_render )
- {
- p_vout->i_changes |= VOUT_SIZE_CHANGE;
- }
- /* don't create a never ending loop */
- b_dispatch_msg = FALSE;
- break;
-
- case WM_PAINT:
- intf_WarnMsg( 4, "vout: vout_Manage WM_PAINT" );
- break;
-
- case WM_ERASEBKGND:
- intf_WarnMsg( 4, "vout: vout_Manage WM_ERASEBKGND" );
- break;
-
- case WM_MOUSEMOVE:
- intf_WarnMsg( 4, "vout: vout_Manage WM_MOUSEMOVE" );
- if( p_vout->p_sys->b_cursor )
- {
- if( p_vout->p_sys->b_cursor_autohidden )
- {
- p_vout->p_sys->b_cursor_autohidden = 0;
- p_vout->p_sys->i_lastmoved = mdate();
- ShowCursor( TRUE );
- }
- else
- {
- p_vout->p_sys->i_lastmoved = mdate();
- }
- }
- break;
-
- case WM_KEYDOWN:
- /* the key events are first processed here. The next
- * message processed by this main message loop will be the
- * char translation of the key event */
- intf_WarnMsg( 3, "vout: vout_Manage WM_KEYDOWN" );
- switch( msg.wParam )
- {
- case VK_ESCAPE:
- case VK_F12:
- p_main->p_intf->b_die = 1;
- break;
- }
- TranslateMessage(&msg);
- b_dispatch_msg = FALSE;
- break;
-
- case WM_CHAR:
- intf_WarnMsg( 3, "vout: vout_Manage WM_CHAR" );
- switch( msg.wParam )
- {
- case 'q':
- case 'Q':
- p_main->p_intf->b_die = 1;
- break;
-
- case 'f': /* switch to fullscreen */
- case 'F':
- p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
- break;
-
- case 'y': /* switch to hard YUV */
- case 'Y':
- p_vout->i_changes |= VOUT_YUV_CHANGE;
- break;
-
- case 'c': /* toggle grayscale */
- case 'C':
- p_vout->b_grayscale = ! p_vout->b_grayscale;
- p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
- break;
-
- case 'i': /* toggle info */
- case 'I':
- p_vout->b_info = ! p_vout->b_info;
- p_vout->i_changes |= VOUT_INFO_CHANGE;
- break;
-
- case 's': /* toggle scaling */
- case 'S':
- p_vout->b_scale = ! p_vout->b_scale;
- p_vout->i_changes |= VOUT_SCALE_CHANGE;
- break;
-
- case ' ': /* toggle interface */
- p_vout->b_interface = ! p_vout->b_interface;
- p_vout->i_changes |= VOUT_INTF_CHANGE;
- break;
-
- case '0': network_ChannelJoin( 0 ); break;
- case '1': network_ChannelJoin( 1 ); break;
- case '2': network_ChannelJoin( 2 ); break;
- case '3': network_ChannelJoin( 3 ); break;
- case '4': network_ChannelJoin( 4 ); break;
- case '5': network_ChannelJoin( 5 ); break;
- case '6': network_ChannelJoin( 6 ); break;
- case '7': network_ChannelJoin( 7 ); break;
- case '8': network_ChannelJoin( 8 ); break;
- case '9': network_ChannelJoin( 9 ); break;
-
- default:
- if( intf_ProcessKey( p_main->p_intf,
- (char )msg.wParam ) )
- {
- intf_DbgMsg( "unhandled key '%c' (%i)",
- (char)msg.wParam, msg.wParam );
- }
- break;
- }
-
- default:
- intf_WarnMsg( 4, "vout: vout_Manage WM Default %i",
- msg.message );
- break;
+ case WM_CLOSE:
+ intf_WarnMsg( 4, "vout: vout_Manage WM_CLOSE" );
+ p_vout->b_die = 1;
+ break;
+
+ case WM_QUIT:
+ intf_WarnMsg( 4, "vout: vout_Manage WM_QUIT" );
+ p_main->p_intf->b_die = 1;
+ break;
+
+ case WM_MOVE:
+ intf_WarnMsg( 3, "vout: vout_Manage WM_MOVE" );
+ if( !p_vout->b_need_render )
+ {
+ p_vout->i_changes |= VOUT_SIZE_CHANGE;
}
-
/* don't create a never ending loop */
- if( b_dispatch_msg )
+ b_dispatch_msg = FALSE;
+ break;
+
+ case WM_APP:
+ intf_WarnMsg( 3, "vout: vout_Manage WM_APP" );
+ if( !p_vout->b_need_render )
{
- TranslateMessage(&msg);
- DispatchMessage(&msg);
+ p_vout->i_changes |= VOUT_SIZE_CHANGE;
+ }
+ /* don't create a never ending loop */
+ b_dispatch_msg = FALSE;
+ break;
+
+#if 0
+ case WM_PAINT:
+ intf_WarnMsg( 4, "vout: vout_Manage WM_PAINT" );
+ break;
+
+ case WM_ERASEBKGND:
+ intf_WarnMsg( 4, "vout: vout_Manage WM_ERASEBKGND" );
+ break;
+#endif
+
+ case WM_MOUSEMOVE:
+ intf_WarnMsg( 4, "vout: vout_Manage WM_MOUSEMOVE" );
+ if( p_vout->p_sys->b_cursor )
+ {
+ if( p_vout->p_sys->b_cursor_autohidden )
+ {
+ p_vout->p_sys->b_cursor_autohidden = 0;
+ p_vout->p_sys->i_lastmoved = mdate();
+ ShowCursor( TRUE );
+ }
+ else
+ {
+ p_vout->p_sys->i_lastmoved = mdate();
+ }
+ }
+ break;
+
+ case WM_KEYDOWN:
+ /* the key events are first processed here. The next
+ * message processed by this main message loop will be the
+ * char translation of the key event */
+ intf_WarnMsg( 3, "vout: vout_Manage WM_KEYDOWN" );
+ switch( msg.wParam )
+ {
+ case VK_ESCAPE:
+ case VK_F12:
+ p_main->p_intf->b_die = 1;
+ break;
+ }
+ TranslateMessage(&msg);
+ b_dispatch_msg = FALSE;
+ break;
+
+ case WM_CHAR:
+ intf_WarnMsg( 3, "vout: vout_Manage WM_CHAR" );
+ switch( msg.wParam )
+ {
+ case 'q':
+ case 'Q':
+ p_main->p_intf->b_die = 1;
+ break;
+
+ case 'f': /* switch to fullscreen */
+ case 'F':
+ p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
+ break;
+
+ case 'y': /* switch to hard YUV */
+ case 'Y':
+ p_vout->i_changes |= VOUT_YUV_CHANGE;
+ break;
+
+ case 'c': /* toggle grayscale */
+ case 'C':
+ p_vout->b_grayscale = ! p_vout->b_grayscale;
+ p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
+ break;
+
+ case 'i': /* toggle info */
+ case 'I':
+ p_vout->b_info = ! p_vout->b_info;
+ p_vout->i_changes |= VOUT_INFO_CHANGE;
+ break;
+
+ case 's': /* toggle scaling */
+ case 'S':
+ p_vout->b_scale = ! p_vout->b_scale;
+ p_vout->i_changes |= VOUT_SCALE_CHANGE;
+ break;
+
+ case ' ': /* toggle interface */
+ p_vout->b_interface = ! p_vout->b_interface;
+ p_vout->i_changes |= VOUT_INTF_CHANGE;
+ break;
+
+ case '0': network_ChannelJoin( 0 ); break;
+ case '1': network_ChannelJoin( 1 ); break;
+ case '2': network_ChannelJoin( 2 ); break;
+ case '3': network_ChannelJoin( 3 ); break;
+ case '4': network_ChannelJoin( 4 ); break;
+ case '5': network_ChannelJoin( 5 ); break;
+ case '6': network_ChannelJoin( 6 ); break;
+ case '7': network_ChannelJoin( 7 ); break;
+ case '8': network_ChannelJoin( 8 ); break;
+ case '9': network_ChannelJoin( 9 ); break;
+
+ default:
+ if( intf_ProcessKey( p_main->p_intf,
+ (char )msg.wParam ) )
+ {
+ intf_DbgMsg( "unhandled key '%c' (%i)",
+ (char)msg.wParam, msg.wParam );
+ }
+ break;
}
- b_dispatch_msg = TRUE;
- }
- else
+#if 0
+ default:
+ intf_WarnMsg( 4, "vout: vout_Manage WM Default %i",
+ msg.message );
+ break;
+#endif
+
+ } /* End Switch */
+
+ /* don't create a never ending loop */
+ if( b_dispatch_msg )
{
- return( 1 );
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
}
+ b_dispatch_msg = TRUE;
- }
+ } /* End While() */
/*
intf_WarnMsg( 3, "vout: vout_Manage Size Change" );
if( DirectXUpdateOverlay( p_vout ) )
/* failed so try again next time */
- PostMessage( p_vout->p_sys->hwnd, WM_APP, 0, 0);
+ PostMessage( p_vout->p_sys->hwnd, WM_APP, 0, 0);
p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
}
int i_image_width;
int i_image_height;
-
- intf_WarnMsg( 5, "vout: vout_Display" );
-
if( (p_vout->p_sys->p_display == NULL) )
{
intf_WarnMsg( 3, "vout error: vout_Display no display!!" );
rect_window.right = point_window.x;
rect_window.bottom = point_window.y;
+ /* We want to keep the aspect ratio of the video */
+ if( p_vout->b_scale )
+ {
+ DirectXKeepAspectRatio( p_vout, &rect_window );
+ }
+
/* Blit video surface to display */
dxresult = IDirectDrawSurface3_Blt(p_vout->p_sys->p_display,
&rect_window,
switch( message )
{
+#if 0
case WM_APP:
intf_WarnMsg( 3, "vout: WinProc WM_APP" );
break;
-#if 0
case WM_ACTIVATE:
intf_WarnMsg( 4, "vout: WinProc WM_ACTIVED" );
break;
intf_WarnMsg( 4, "vout: WinProc WM_MOVING" );
break;
+ case WM_ENTERSIZEMOVE:
+ intf_WarnMsg( 4, "vout: WinProc WM_ENTERSIZEMOVE" );
+ break;
+
case WM_SIZING:
intf_WarnMsg( 4, "vout: WinProc WM_SIZING" );
break;
* comes from the potential dithering (depends on the display depth)
* because we need to know the real RGB value of the chosen colorkey */
hdc = GetDC( GetDesktopWindow() );
- for( colorkey = 1; colorkey < 0xFF /*all shades of red*/; colorkey++ )
+ for( colorkey = 5; colorkey < 0xFF /*all shades of red*/; colorkey++ )
{
if( colorkey == GetNearestColor( hdc, colorkey ) )
break;
DDSD_HEIGHT |
DDSD_WIDTH |
DDSD_PIXELFORMAT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
ddsd.dwHeight = p_vout->p_sys->i_image_height;
ddsd.dwWidth = p_vout->p_sys->i_image_width;
ddsd.dwBackBufferCount = 1; /* One back buffer */
/* We want to keep the aspect ratio of the video */
if( p_vout->b_scale )
{
- switch( p_vout->p_rendered_pic->i_aspect_ratio )
- {
- case AR_16_9_PICTURE:
- if( ((rect_window.right-rect_window.left)*9)
- > ((rect_window.bottom-rect_window.top)*16) )
- {
- int temp;
- temp = (rect_window.bottom-rect_window.top)*16/9;
- temp = (rect_window.right-rect_window.left) - temp;
- rect_window.left += (temp/2);
- rect_window.right -= (temp/2);
- }
- else
- {
- int temp;
- temp = (rect_window.right-rect_window.left)*9/16;
- temp = (rect_window.bottom-rect_window.top) - temp;
- rect_window.top += (temp/2);
- rect_window.bottom -= (temp/2);
- }
- break;
-
- case AR_221_1_PICTURE:
- if( ((rect_window.right-rect_window.left)*100)
- > ((rect_window.bottom-rect_window.top)*221) )
- {
- int temp;
- temp = (rect_window.bottom-rect_window.top)*221/100;
- temp = (rect_window.right-rect_window.left) - temp;
- rect_window.left += (temp/2);
- rect_window.right -= (temp/2);
- }
- else
- {
- int temp;
- temp = (rect_window.right-rect_window.left)*100/221;
- temp = (rect_window.bottom-rect_window.top) - temp;
- rect_window.top += (temp/2);
- rect_window.bottom -= (temp/2);
- }
- break;
-
- case AR_SQUARE_PICTURE:
- if( (rect_window.right-rect_window.left)
- > (rect_window.bottom-rect_window.top) )
- {
- int temp;
- temp = (rect_window.bottom-rect_window.top);
- temp = (rect_window.right-rect_window.left) - temp;
- rect_window.left += (temp/2);
- rect_window.right -= (temp/2);
- }
- else
- {
- int temp;
- temp = (rect_window.right-rect_window.left);
- temp = (rect_window.bottom-rect_window.top) - temp;
- rect_window.top += (temp/2);
- rect_window.bottom -= (temp/2);
- }
- break;
-
- case AR_3_4_PICTURE:
- default:
- if( ((rect_window.right-rect_window.left)*3)
- > ((rect_window.bottom-rect_window.top)*4) )
- {
- int temp;
- temp = (rect_window.bottom-rect_window.top)*4/3;
- temp = (rect_window.right-rect_window.left) - temp;
- rect_window.left += (temp/2);
- rect_window.right -= (temp/2);
- }
- else
- {
- int temp;
- temp = (rect_window.right-rect_window.left)*3/4;
- temp = (rect_window.bottom-rect_window.top) - temp;
- rect_window.top += (temp/2);
- rect_window.bottom -= (temp/2);
- }
- break;
- }
+ DirectXKeepAspectRatio( p_vout, &rect_window );
}
-
/* It seems we can't feed the UpdateOverlay directdraw function with
* negative values so we have to clip the computed rectangles */
memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
rect_window.left, rect_window.top,
rect_window.right, rect_window.bottom);
+ /* the 2 following lines are to fix a bug when click on Windows desktop */
+ if( (rect_window.right-rect_window.left)==0 ||
+ (rect_window.bottom-rect_window.top)==0 ) return 0;
+
/* Clip the source image */
rect_image.left = ( rect_window.left == rect_window_backup.left ) ? 0
: labs(rect_window_backup.left - rect_window.left) *
/* Disable any display */
p_vout->p_sys->b_display_enabled = 0;
}
+
+/*****************************************************************************
+ * DirectXKeepAspectRatio:
+ *****************************************************************************
+ * This function adjusts the coordinates of the video rectangle to keep the
+ * aspect/ratio of the video.
+ *****************************************************************************/
+static void DirectXKeepAspectRatio( vout_thread_t *p_vout, RECT *rect_window )
+{
+
+ if( !p_vout->p_rendered_pic ) return;
+
+ switch( p_vout->p_rendered_pic->i_aspect_ratio )
+ {
+ case AR_16_9_PICTURE:
+ if( ((rect_window->right-rect_window->left)*9)
+ > ((rect_window->bottom-rect_window->top)*16) )
+ {
+ int temp;
+ temp = (rect_window->bottom-rect_window->top)*16/9;
+ temp = (rect_window->right-rect_window->left) - temp;
+ rect_window->left += (temp/2);
+ rect_window->right -= (temp/2);
+ }
+ else
+ {
+ int temp;
+ temp = (rect_window->right-rect_window->left)*9/16;
+ temp = (rect_window->bottom-rect_window->top) - temp;
+ rect_window->top += (temp/2);
+ rect_window->bottom -= (temp/2);
+ }
+ break;
+
+ case AR_221_1_PICTURE:
+ if( ((rect_window->right-rect_window->left)*100)
+ > ((rect_window->bottom-rect_window->top)*221) )
+ {
+ int temp;
+ temp = (rect_window->bottom-rect_window->top)*221/100;
+ temp = (rect_window->right-rect_window->left) - temp;
+ rect_window->left += (temp/2);
+ rect_window->right -= (temp/2);
+ }
+ else
+ {
+ int temp;
+ temp = (rect_window->right-rect_window->left)*100/221;
+ temp = (rect_window->bottom-rect_window->top) - temp;
+ rect_window->top += (temp/2);
+ rect_window->bottom -= (temp/2);
+ }
+ break;
+
+ case AR_3_4_PICTURE:
+ if( ((rect_window->right-rect_window->left)*3)
+ > ((rect_window->bottom-rect_window->top)*4) )
+ {
+ int temp;
+ temp = (rect_window->bottom-rect_window->top)*4/3;
+ temp = (rect_window->right-rect_window->left) - temp;
+ rect_window->left += (temp/2);
+ rect_window->right -= (temp/2);
+ }
+ else
+ {
+ int temp;
+ temp = (rect_window->right-rect_window->left)*3/4;
+ temp = (rect_window->bottom-rect_window->top) - temp;
+ rect_window->top += (temp/2);
+ rect_window->bottom -= (temp/2);
+ }
+ break;
+
+ case AR_SQUARE_PICTURE:
+ default:
+ if( (rect_window->right-rect_window->left)
+ > (rect_window->bottom-rect_window->top) )
+ {
+ int temp;
+ temp = (rect_window->bottom-rect_window->top);
+ temp = (rect_window->right-rect_window->left) - temp;
+ rect_window->left += (temp/2);
+ rect_window->right -= (temp/2);
+ }
+ else
+ {
+ int temp;
+ temp = (rect_window->right-rect_window->left);
+ temp = (rect_window->bottom-rect_window->top) - temp;
+ rect_window->top += (temp/2);
+ rect_window->bottom -= (temp/2);
+ }
+ break;
+
+ }
+
+}
* interface, such as message output. See config.h for output configuration.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: intf_msg.c,v 1.36 2001/06/02 01:09:03 sam Exp $
+ * $Id: intf_msg.c,v 1.37 2001/07/08 17:45:52 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
#include "main.h"
-#ifdef WIN32
-#ifndef snprintf
-#define snprintf _snprintf /* snprintf not defined in mingw32 (bug?) */
-#endif
-#endif
-
/*****************************************************************************
* intf_msg_item_t
*****************************************************************************
static void FlushLockedMsg ( intf_msg_t *p_msg );
#endif
+#if defined( WIN32 )
+static char *ConvertPrintfFormatString ( char *psz_format );
+#endif
/*****************************************************************************
* intf_MsgCreate: initialize messages interface (ok ?)
{
char * psz_str; /* formatted message string */
intf_msg_item_t * p_msg_item; /* pointer to message */
+#ifdef WIN32
+ char * psz_temp;
+#endif
#ifndef INTF_MSG_QUEUE /*................................... instant mode ...*/
intf_msg_item_t msg_item; /* message */
/*
* Convert message to string
*/
+
#ifdef HAVE_VASPRINTF
vasprintf( &psz_str, psz_format, ap );
#else
fprintf(stderr, "\n" );
exit( errno );
}
-#ifdef HAVE_VASPRINTF
+#ifndef HAVE_VASPRINTF
+#ifdef WIN32
+ psz_temp = ConvertPrintfFormatString(psz_format);
+ vsprintf( psz_str, psz_temp, ap );
+ free( psz_temp );
#else
vsprintf( psz_str, psz_format, ap );
-#endif
+#endif /* WIN32 */
+#endif /* HAVE_VASPRINTF */
#ifdef INTF_MSG_QUEUE /*...................................... queue mode ...*/
vlc_mutex_lock( &p_msg->lock ); /* get lock */
{
char * psz_str; /* formatted message string */
intf_msg_item_t * p_msg_item; /* pointer to message */
+#ifdef WIN32
+ char * psz_temp;
+#endif
#ifndef INTF_MSG_QUEUE /*................................... instant mode ...*/
intf_msg_item_t msg_item; /* message */
vasprintf( &psz_str, psz_format, ap );
#else
psz_str = (char*) malloc( INTF_MAX_MSG_SIZE );
- vsprintf( psz_str, psz_format, ap );
#endif
if( psz_str == NULL )
{
fprintf(stderr, "\n" );
exit( errno );
}
+#ifndef HAVE_VASPRINTF
+#ifdef WIN32
+ psz_temp = ConvertPrintfFormatString(psz_format);
+ vsprintf( psz_str, psz_temp, ap );
+ free( psz_temp );
+#else
+ vsprintf( psz_str, psz_format, ap );
+#endif /* WIN32 */
+#endif /* HAVE_VASPRINTF */
#ifdef INTF_MSG_QUEUE /*...................................... queue mode ...*/
vlc_mutex_lock( &p_msg->lock ); /* get lock */
#endif
+
+#if defined( WIN32 )
+/*****************************************************************************
+ * ConvertPrintfFormatString: replace all occurrences of %ll with %I64 in the
+ * printf format string.
+ *****************************************************************************
+ * Win32 doesn't recognize the "%lld" format in a printf string, so we have
+ * to convert this string to something that win32 can handle.
+ * This is a REALLY UGLY HACK which won't even work in every situation,
+ * but hey I don't want to put an ifdef WIN32 each time I use printf with
+ * a "long long" type!!!
+ * By the way, if we don't do this we can sometimes end up with segfaults.
+ *****************************************************************************/
+static char *ConvertPrintfFormatString( char *psz_format )
+{
+ int i, i_counter=0, i_pos=0;
+ char *psz_dest;
+
+ /* We first need to check how many occurences of %ll there are in the
+ * psz_format string. Once we'll know that we'll be able to malloc the
+ * destination string */
+
+ for( i=0; i <= (strlen(psz_format) - 4); i++ )
+ {
+ if( !strncmp( (char *)(psz_format + i), "%ll", 3 ) )
+ i_counter++;
+ }
+
+ /* malloc the destination string */
+ psz_dest = malloc( strlen(psz_format) + i_counter + 1 );
+ if( psz_dest == NULL )
+ {
+ fprintf(stderr, "warning: malloc failed in ConvertPrintfFormatString\n");
+ exit (errno);
+ }
+
+ /* Now build the modified string */
+ i_counter = 0;
+ for( i=0; i <= (strlen(psz_format) - 4); i++ )
+ {
+ if( !strncmp( (char *)(psz_format + i), "%ll", 3 ) )
+ {
+ memcpy( psz_dest+i_pos+i_counter, psz_format+i_pos, i-i_pos+1);
+ *(psz_dest+i+i_counter+1)='I';
+ *(psz_dest+i+i_counter+2)='6';
+ *(psz_dest+i+i_counter+3)='4';
+ i_pos = i+3;
+ i_counter++;
+ }
+ }
+ strcpy( psz_dest+i_pos+i_counter, psz_format+i_pos );
+
+ return psz_dest;
+}
+#endif