]> git.sesse.net Git - vlc/commitdiff
* Overlay now works under latest QNX release.
authorJon Lech Johansen <jlj@videolan.org>
Fri, 17 Aug 2001 01:26:45 +0000 (01:26 +0000)
committerJon Lech Johansen <jlj@videolan.org>
Fri, 17 Aug 2001 01:26:45 +0000 (01:26 +0000)
plugins/qnx/aout_qnx.c
plugins/qnx/vout_qnx.c

index cabac59fd2b81771a5ce83bc58e0d8ec5a04aed7..67eb022026dba72c3170501a88f1a6d36977ed93 100644 (file)
@@ -1,9 +1,10 @@
 /*****************************************************************************
- * aout_qnx.c : Alsa functions library
+ * aout_qnx.c : QNX audio output 
  *****************************************************************************
- * Copyright (C) 2000 VideoLAN
+ * Copyright (C) 2000, 2001 VideoLAN
  *
  * Authors: Henri Fallon <henri@videolan.org>
+ *          Jon Lech Johansen <jon-vl@nanocrew.net>
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "modules.h"
 #include "modules_export.h"
 
-typedef struct alsa_device_s
-{
-    int i_num;
-} alsa_device_t;
-
-typedef struct alsa_card_s
-{
-    int i_num;
-} alsa_card_t;
-
-/* here we store plugin dependant informations */
-
 typedef struct aout_sys_s
 {
-    snd_pcm_t                * p_alsa_handle;
-    alsa_device_t              s_alsa_device;
-    alsa_card_t                s_alsa_card;
-    snd_pcm_channel_params_t   s_alsa_channel_params;
-    snd_pcm_format_t           s_alsa_format;
+    snd_pcm_t  * p_pcm_handle;
+    int          i_card;
+    int          i_device;
 } aout_sys_t;
 
 /*****************************************************************************
@@ -104,42 +91,33 @@ void _M( aout_getfunctions )( function_list_t * p_function_list )
  *****************************************************************************/
 static int aout_Probe( probedata_t *p_data )
 {
-    int i_open_return, i_close_return;
-    aout_sys_t local_sys;
-    /* This is the same as the beginning of the aout_Open */
-    
-    /* Initialize  */
-    local_sys.s_alsa_device.i_num = 0;
-    local_sys.s_alsa_card.i_num = 0;
-
-    /* Open device */
-    i_open_return = snd_pcm_open( &(local_sys.p_alsa_handle),
-                     local_sys.s_alsa_card.i_num,
-                     local_sys.s_alsa_device.i_num,
-                     SND_PCM_OPEN_PLAYBACK );
-    if( i_open_return )
+    int i_ret;
+    aout_sys_t adev;
+
+    /* open audio device */
+    if( ( i_ret = snd_pcm_open_preferred( &adev.p_pcm_handle,
+                                          &adev.i_card, &adev.i_device,
+                                          SND_PCM_OPEN_PLAYBACK ) ) < 0 )
     {
-        intf_WarnMsg( 2, "aout info: could not probe ALSA device (%s)",
-              snd_strerror( i_open_return ) );
-        return ( 0 );
+        intf_WarnMsg( 2, "aout error: unable to open audio device (%s)",
+                      snd_strerror( i_ret ) );
+        return( 0 );
     }
 
-    /* Close it */
-    i_close_return = snd_pcm_close( local_sys.p_alsa_handle );
-    
-    if( i_close_return )
+    /* close audio device */
+    if( ( i_ret = snd_pcm_close( adev.p_pcm_handle ) ) < 0 )
     {
-        intf_ErrMsg( "aout error: could not close ALSA device (%s)",
-                     snd_strerror( i_close_return ) );
+        intf_WarnMsg( 2, "aout error: unable to close audio device (%s)",
+                      snd_strerror( i_ret ) );
         return( 0 );
     }
-    
+
     if( TestMethod( AOUT_METHOD_VAR, "qnx" ) )
     {
         return( 999 );
     }
 
-    /* And return score */
+    /* return score */
     return( 50 );
 }    
 
@@ -150,125 +128,113 @@ static int aout_Probe( probedata_t *p_data )
  *****************************************************************************/
 static int aout_Open( aout_thread_t *p_aout )
 {
-    int i_open_returns;
-    
-    /* Allocate structures */
+    int i_ret;
+
+    /* allocate structure */
     p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
     if( p_aout->p_sys == NULL )
     {
-        intf_ErrMsg( "aout error: failed allocating memory for ALSA (%s)",
-                     strerror(ENOMEM) );
+        intf_ErrMsg( "aout error: unable to allocate memory (%s)",
+                     strerror( ENOMEM ) );
         return( 1 );
     }
 
-    /* Initialize  */
-    p_aout->p_sys->s_alsa_device.i_num = 0;
-    p_aout->p_sys->s_alsa_card.i_num = 0;
-    /* FIXME : why not other format ? */
-    p_aout->i_format = AOUT_FMT_S16_LE;   
-    /* FIXME : why always 2 channels ?*/
-    p_aout->i_channels = 2;
-    p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
-    
-    /* Open device */
-    if( ( i_open_returns = snd_pcm_open( &(p_aout->p_sys->p_alsa_handle),
-                p_aout->p_sys->s_alsa_card.i_num,
-                p_aout->p_sys->s_alsa_device.i_num,
-                SND_PCM_OPEN_PLAYBACK ) ) )
+    /* initialize  */
+    p_aout->i_format   = AOUT_FORMAT_DEFAULT;
+    p_aout->i_channels = main_GetIntVariable( AOUT_STEREO_VAR,
+                                              AOUT_STEREO_DEFAULT ) + 1;
+    p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR,
+                                              AOUT_RATE_DEFAULT );
+
+    /* open audio device */
+    if( ( i_ret = snd_pcm_open_preferred( &p_aout->p_sys->p_pcm_handle,
+                                          &p_aout->p_sys->i_card,
+                                          &p_aout->p_sys->i_device,
+                                          SND_PCM_OPEN_PLAYBACK ) ) < 0 )
     {
-        intf_ErrMsg( "aout error: could not open ALSA device (%s)",
-             snd_strerror(i_open_returns) );
-        return( -1 );
+        intf_ErrMsg( "aout error: unable to open audio device (%s)",
+                      snd_strerror( i_ret ) );
+        return( 1 );
+    }
+
+    /* disable mmap */
+    if( ( i_ret = snd_pcm_plugin_set_disable( p_aout->p_sys->p_pcm_handle,
+                                              PLUGIN_DISABLE_MMAP ) ) < 0 )
+    {
+        intf_ErrMsg( "aout error: unable to disable mmap (%s)",
+                     snd_strerror( i_ret ) );
+        aout_Close( p_aout );
+        return( 1 );
     }
 
-    intf_DbgMsg( "aout info: ALSA device successfully opened" );
     return( 0 );
 }
 
 
 /*****************************************************************************
- * aout_SetFormat : sets the alsa output format
+ * aout_SetFormat : set the audio output format 
  *****************************************************************************
  * This function prepares the device, sets the rate, format, the mode
  * ("play as soon as you have data"), and buffer information.
  *****************************************************************************/
 static int aout_SetFormat( aout_thread_t *p_aout )
 {
-    
-    int i_set_param_returns;
-    int i_prepare_playback_returns;
-    int i_playback_go_returns;
-
-    /* Fill with zeros */
-    memset( &p_aout->p_sys->s_alsa_channel_params, 0,
-            sizeof( p_aout->p_sys->s_alsa_channel_params ) );
-    
-    /* Fill the s_alsa_channel_params structure */
-
-    /* Tranfer mode and direction*/    
-    p_aout->p_sys->s_alsa_channel_params.channel = SND_PCM_CHANNEL_PLAYBACK ;
-    p_aout->p_sys->s_alsa_channel_params.mode = SND_PCM_MODE_STREAM;
-    
-    /* Format and rate */
-    p_aout->p_sys->s_alsa_channel_params.format.interleave = 1;
-    if( p_aout->i_format == AOUT_FMT_S16_LE )
+    int i_ret;
+    snd_pcm_channel_info_t pi;
+    snd_pcm_channel_params_t pp;
+
+    memset( &pi, 0, sizeof(pi) );
+    memset( &pp, 0, sizeof(pp) );
+
+    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
+    if( ( i_ret = snd_pcm_plugin_info( p_aout->p_sys->p_pcm_handle,
+                                       &pi ) ) < 0 )
     {
-        p_aout->p_sys->s_alsa_channel_params.format.format = 
-            SND_PCM_SFMT_S16_LE;
+        intf_ErrMsg( "aout error: unable to get plugin info (%s)",
+                     snd_strerror( i_ret ) );
+        return( 1 );
     }
-    else
+
+    pp.mode       = SND_PCM_MODE_STREAM;
+    pp.channel    = SND_PCM_CHANNEL_PLAYBACK;
+    pp.start_mode = SND_PCM_START_DATA;
+    pp.stop_mode  = SND_PCM_STOP_STOP;
+
+    pp.buf.stream.queue_size = pi.max_fragment_size;
+    pp.buf.stream.fill       = SND_PCM_FILL_NONE;
+    pp.buf.stream.max_fill   = 0;
+
+    pp.format.interleave     = 1;
+    pp.format.rate           = p_aout->l_rate;
+    pp.format.voices         = p_aout->i_channels;
+
+    switch( p_aout->i_format )
     {
-        p_aout->p_sys->s_alsa_channel_params.format.format = 
-            SND_PCM_SFMT_S16_BE;
+        case AOUT_FMT_S16_LE:
+            pp.format.format = SND_PCM_SFMT_S16_LE;
+            break;
+
+        default:
+            pp.format.format = SND_PCM_SFMT_S16_BE;
+            break;
     }
-    p_aout->p_sys->s_alsa_channel_params.format.rate = p_aout->l_rate;
-    p_aout->p_sys->s_alsa_channel_params.format.voices = p_aout->i_channels ;
-    
-    /* When to start playing and when to stop */
-    p_aout->p_sys->s_alsa_channel_params.start_mode = SND_PCM_START_DATA;
-    p_aout->p_sys->s_alsa_channel_params.stop_mode = SND_PCM_STOP_STOP;
-
-    /* Buffer information . I have chosen the stream mode here
-     * instead of the block mode. I don't know whether i'm wrong 
-     * but it seemed more logical */
-    /* TODO : find the best value to put here. Probably depending
-     * on many parameters */
-    p_aout->p_sys->s_alsa_channel_params.buf.stream.queue_size = 131072; 
-    
-    p_aout->p_sys->s_alsa_channel_params.buf.stream.fill = SND_PCM_FILL_NONE ;
-    p_aout->p_sys->s_alsa_channel_params.buf.stream.max_fill = 0 ; 
-  
-    /* Now we pass this to the driver */
-    i_set_param_returns = snd_pcm_channel_params( 
-            p_aout->p_sys->p_alsa_handle, 
-            &(p_aout->p_sys->s_alsa_channel_params) );
-    
-    if( i_set_param_returns )
+
+    /* set parameters */
+    if( ( i_ret = snd_pcm_plugin_params( p_aout->p_sys->p_pcm_handle,
+                                         &pp ) ) < 0 )
     {
         intf_ErrMsg( "aout error: unable to set parameters (%s)",
-                     snd_strerror( i_set_param_returns ) );
-        return( -1 );
+                     snd_strerror( i_ret ) );
+        return( 1 );
     }
 
-    /* we shall now prepare the channel */
-    i_prepare_playback_returns = 
-        snd_pcm_playback_prepare( p_aout->p_sys->p_alsa_handle );
-
-    if( i_prepare_playback_returns )
+    /* prepare channel */
+    if( ( i_ret = snd_pcm_plugin_prepare( p_aout->p_sys->p_pcm_handle,
+                                          SND_PCM_CHANNEL_PLAYBACK ) ) < 0 )
     {
         intf_ErrMsg( "aout error: unable to prepare channel (%s)",
-                      snd_strerror( i_set_param_returns ) );
-        return( -1 );
-    }
-    
-   /* then we may go */
-   i_playback_go_returns =
-       snd_pcm_playback_go( p_aout->p_sys->p_alsa_handle );
-    if( i_playback_go_returns )
-    {
-        intf_ErrMsg( "aout error: unable to prepare channel (bis) (%s)",
-                     snd_strerror( i_set_param_returns ) );
-        return( -1 );
+                     snd_strerror( i_ret ) );
+        return( 1 );
     }
 
     p_aout->i_latency = 0;
@@ -286,45 +252,34 @@ static int aout_SetFormat( aout_thread_t *p_aout )
  *****************************************************************************/
 static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
 {
-    snd_pcm_channel_status_t alsa_channel_status;
-    int i_alsa_get_status_returns;
-    
-    memset( &alsa_channel_status, 0, sizeof( alsa_channel_status ) );
-   
-    i_alsa_get_status_returns = snd_pcm_channel_status( 
-            p_aout->p_sys->p_alsa_handle, &alsa_channel_status );
-
-    if( i_alsa_get_status_returns )
+    int i_ret;
+    snd_pcm_channel_status_t status;
+
+    /* get current pcm status */
+    memset( &status, 0, sizeof(status) );
+    if( ( i_ret = snd_pcm_plugin_status( p_aout->p_sys->p_pcm_handle,
+                                         &status ) ) < 0 )
     {
-        intf_ErrMsg( "aout error: failed getting alsa buffer info (%s)",
-                     snd_strerror ( i_alsa_get_status_returns ) );
+        intf_ErrMsg( "aout error: unable to get device status (%s)",
+                     snd_strerror( i_ret ) );
         return( -1 );
     }
 
-    switch( alsa_channel_status.status )
+    /* check for underrun */
+    switch( status.status )
     {
-        case SND_PCM_STATUS_NOTREADY:
-        { 
-            intf_ErrMsg( "aout error: status NOT READY" );
-            break;
-        }
-    
+        case SND_PCM_STATUS_READY:
         case SND_PCM_STATUS_UNDERRUN:
-        {
-            int i_prepare_returns;
-            intf_ErrMsg( "aout error: status UNDERRUN ... resetting queue ");
-            i_prepare_returns = snd_pcm_playback_prepare( 
-                             p_aout->p_sys->p_alsa_handle );
-            if ( i_prepare_returns )
+            if( ( i_ret = snd_pcm_plugin_prepare( p_aout->p_sys->p_pcm_handle,
+                                          SND_PCM_CHANNEL_PLAYBACK ) ) < 0 )
             {
-                intf_ErrMsg( "aout error: could not flush (%s)", 
-                             snd_strerror(i_prepare_returns) );
+                intf_ErrMsg( "aout error: unable to prepare channel (%s)",
+                             snd_strerror( i_ret ) );
             }
             break;
-        }
-    } 
+    }
 
-    return( alsa_channel_status.count );
+    return( status.count );
 }
 
 /*****************************************************************************
@@ -334,34 +289,29 @@ static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
  *****************************************************************************/
 static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
 {
-    int i_write_returns;
+    int i_ret;
 
-    i_write_returns = (int) snd_pcm_write (
-            p_aout->p_sys->p_alsa_handle, (void *) buffer, (size_t) i_size );
-
-    if( i_write_returns <= 0 )
+    if( ( i_ret = snd_pcm_plugin_write( p_aout->p_sys->p_pcm_handle,
+                                        (void *) buffer, 
+                                        (size_t) i_size ) ) <= 0 )
     {
-        intf_ErrMsg( "aout error: writing blocks failed (%s)",
-                     snd_strerror( i_write_returns ) );
+        intf_ErrMsg( "aout error: unable to write data (%s)",
+                     snd_strerror( i_ret ) );
     }
 }
 
 /*****************************************************************************
- * aout_Close : close the Alsa device
+ * aout_Close : close the audio device
  *****************************************************************************/
 static void aout_Close( aout_thread_t *p_aout )
 {
-    int i_close_returns;
-
-    i_close_returns = snd_pcm_close( p_aout->p_sys->p_alsa_handle );
+    int i_ret;
 
-    if( i_close_returns )
+    if( ( i_ret = snd_pcm_close( p_aout->p_sys->p_pcm_handle ) ) < 0 )
     {
-        intf_ErrMsg( "aout error: failed closing ALSA device (%s)",
-                     snd_strerror( i_close_returns ) );
+        intf_ErrMsg( "aout error: unable to close audio device (%s)",
+                     snd_strerror( i_ret ) );
     }
-    free( p_aout->p_sys );
 
-    intf_DbgMsg( "aout: ALSA device closed" );    
+    free( p_aout->p_sys );
 }
-
index 3b2e479887a8ca281f1d397180aa69b345d7a6c9..f91bbf2672b105299c8db6f16dedbe72effced8e 100644 (file)
@@ -94,8 +94,10 @@ typedef struct vout_sys_s
     /* position & dimensions */
     PhPoint_t               pos;
     PhDim_t                 dim;
+    PhPoint_t               old_pos;
     PhDim_t                 old_dim;
     PhDim_t                 screen_dim;
+    PhRect_t                frame;
 } vout_sys_t;
 
 /*****************************************************************************
@@ -109,9 +111,9 @@ static void vout_Destroy   ( struct vout_thread_s * );
 static int  vout_Manage    ( struct vout_thread_s * );
 static void vout_Display   ( struct vout_thread_s * );
 
+static int  QNXInitDisplay ( struct vout_thread_s * );
 static int  QNXCreateWnd   ( struct vout_thread_s * );
 static int  QNXDestroyWnd  ( struct vout_thread_s * );
-static int  QNXInitDisplay ( struct vout_thread_s * );
 
 /*****************************************************************************
  * Functions exported as capabilities. They are declared as static so that
@@ -176,11 +178,11 @@ static int vout_Create( vout_thread_t *p_vout )
     p_vout->p_sys->i_mode = 
         main_GetIntVariable( VOUT_OVERLAY_VAR, VOUT_OVERLAY_DEFAULT ) ?
         MODE_VIDEO_OVERLAY : MODE_NORMAL_MEM;
-    p_vout->p_sys->dim.w = 
+    p_vout->p_sys->dim.w =
         main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
-    p_vout->p_sys->dim.h = 
+    p_vout->p_sys->dim.h =
         main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
-    
+
     /* init display and create window */
     if( QNXInitDisplay( p_vout ) || QNXCreateWnd( p_vout ) )
     {
@@ -226,7 +228,7 @@ static int vout_Init( vout_thread_t *p_vout )
         /* set bytes per line, set buffers */
         p_vout->i_bytes_per_line = p_vout->p_sys->p_image[0]->bpl;
         p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_image[0]->image,
-                                 p_vout->p_sys->p_image[1]->image );
+                               p_vout->p_sys->p_image[1]->image );
     }
     else if( p_vout->p_sys->i_mode == MODE_VIDEO_MEM )
     {
@@ -265,49 +267,71 @@ static int vout_Init( vout_thread_t *p_vout )
         }
 
         /* set bytes per line, clear buffers, set buffers */
-        p_vout->i_bytes_per_line = 
-            p_vout->i_bytes_per_pixel * p_vout->p_sys->dim.w;
+        p_vout->i_bytes_per_line = p_vout->p_sys->p_ctx[0]->pitch; 
         memset( p_vout->p_sys->p_buf[0], 0,
             p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
         memset( p_vout->p_sys->p_buf[1], 0,
             p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
         p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_buf[0],
-                                 p_vout->p_sys->p_buf[1] );
+                               p_vout->p_sys->p_buf[1] );
     }
     else if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
     {
+        int i_ret;
         PgScalerProps_t props;
 
-        props.size = sizeof( props );
+        props.size   = sizeof( props );
         props.format = p_vout->p_sys->i_vc_format; 
-        props.viewport.ul.x = p_vout->p_sys->pos.x + 4;
-        props.viewport.ul.y = p_vout->p_sys->pos.y + 20;
+        props.flags  = Pg_SCALER_PROP_SCALER_ENABLE |
+                       Pg_SCALER_PROP_DOUBLE_BUFFER;
+
+        /* enable chroma keying if available */
+        if( p_vout->p_sys->i_vc_flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
+        {
+            props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
+        }
+
+        /* set viewport position */
+        props.viewport.ul.x = p_vout->p_sys->pos.x;
+        props.viewport.ul.y = p_vout->p_sys->pos.y;
+        if( !p_vout->b_fullscreen )
+        {
+            props.viewport.ul.x += p_vout->p_sys->frame.ul.x;
+            props.viewport.ul.y += p_vout->p_sys->frame.ul.y;
+        }
+
+        /* set viewport dimension */
         props.viewport.lr.x = p_vout->p_sys->dim.w + props.viewport.ul.x;
         props.viewport.lr.y = p_vout->p_sys->dim.h + props.viewport.ul.y;
-        props.src_dim.w = p_vout->p_sys->dim.w;
-        props.src_dim.h    = p_vout->p_sys->dim.h;
-        props.flags = Pg_SCALER_PROP_SCALER_ENABLE |
-                      Pg_SCALER_PROP_DOUBLE_BUFFER;
 
-        if( PgConfigScalerChannel( p_vout->p_sys->p_channel, &props ) == -1 )
+        /* set source dimension */
+        props.src_dim.w = p_vout->i_width;
+        props.src_dim.h = p_vout->i_height;
+
+        /* configure scaler channel */
+        i_ret = PgConfigScalerChannel( p_vout->p_sys->p_channel, &props );
+
+        if( i_ret == -1 )
         {
             intf_ErrMsg( "vout error: unable to configure video channel" );
             return( 1 );
         }
-
-        p_vout->p_sys->p_vc_y[0] =
-            PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane1 );
-        p_vout->p_sys->p_vc_y[1] =
-            PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane2 );
-
-        if( p_vout->p_sys->p_vc_y[0] == NULL ||
-            p_vout->p_sys->p_vc_y[1] == NULL )
+        else if( i_ret == 1 )
         {
-            intf_ErrMsg( "vout error: unable to get video channel ctx ptr" );
-            return( 1 );
+            p_vout->p_sys->p_vc_y[0] =
+                PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane1 );
+            p_vout->p_sys->p_vc_y[1] =
+                PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane2 );
+
+            if( p_vout->p_sys->p_vc_y[0] == NULL ||
+                p_vout->p_sys->p_vc_y[1] == NULL )
+            {
+                intf_ErrMsg( "vout error: unable to get video channel ctx ptr" );
+                return( 1 );
+            }
         }
 
-        if( p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_YV12 )
+        if( p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_YV12 && i_ret == 1 )
         {
             p_vout->b_need_render = 0;
 
@@ -333,11 +357,11 @@ static int vout_Init( vout_thread_t *p_vout )
         {
             /* set bytes per line, clear buffers, set buffers */
             p_vout->i_bytes_per_line =
-                p_vout->i_bytes_per_pixel * p_vout->p_sys->dim.w;
+                p_vout->p_sys->p_channel->yplane1->pitch;
             memset( p_vout->p_sys->p_vc_y[0], 0,
-                p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
+                p_vout->i_bytes_per_line * p_vout->i_height );
             memset( p_vout->p_sys->p_vc_y[1], 0,
-                p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
+                p_vout->i_bytes_per_line * p_vout->i_height );
             p_vout->pf_setbuffers( p_vout,
                 p_vout->p_sys->p_vc_y[0], p_vout->p_sys->p_vc_y[1] );
         }
@@ -435,16 +459,16 @@ static int vout_Manage( vout_thread_t *p_vout )
                     break;
 
                 case Ph_WM_MOVE:
-                    b_repos = 1;
                     p_vout->p_sys->pos.x = p_ev->pos.x;
                     p_vout->p_sys->pos.y = p_ev->pos.y;
+                    b_repos = 1;
                     break;
 
                 case Ph_WM_RESIZE:
                     p_vout->p_sys->old_dim.w = p_vout->p_sys->dim.w;
                     p_vout->p_sys->old_dim.h = p_vout->p_sys->dim.h;
-                    p_vout->p_sys->dim.w = p_vout->i_width = p_ev->size.w;
-                    p_vout->p_sys->dim.h = p_vout->i_height = p_ev->size.h;
+                    p_vout->p_sys->dim.w = p_ev->size.w;
+                    p_vout->p_sys->dim.h = p_ev->size.h;
                     p_vout->i_changes |= VOUT_SIZE_CHANGE;
                     break;
                 }
@@ -501,7 +525,6 @@ static int vout_Manage( vout_thread_t *p_vout )
     if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
     {
         PhDim_t dim;
-        PhPoint_t pos;
 
         intf_DbgMsg( "vout: changing full-screen status" );
 
@@ -510,42 +533,34 @@ static int vout_Manage( vout_thread_t *p_vout )
 
         if( p_vout->b_fullscreen )
         {
-            pos.x = pos.y = 0;
+            p_vout->p_sys->old_pos.x = p_vout->p_sys->pos.x;
+            p_vout->p_sys->old_pos.y = p_vout->p_sys->pos.y;
+            p_vout->p_sys->pos.x = p_vout->p_sys->pos.y = 0;
             dim.w = p_vout->p_sys->screen_dim.w + 1;
             dim.h = p_vout->p_sys->screen_dim.h + 1;
         }
         else
         {
-            pos.x = p_vout->p_sys->pos.x;
-            pos.y = p_vout->p_sys->pos.y;
+            p_vout->p_sys->pos.x = p_vout->p_sys->old_pos.x;
+            p_vout->p_sys->pos.y = p_vout->p_sys->old_pos.y;
             dim.w = p_vout->p_sys->old_dim.w + 1;
             dim.h = p_vout->p_sys->old_dim.h + 1;
         }
 
+        /* modify render flags, border */
         PtSetResource( p_vout->p_sys->p_window,
             Pt_ARG_WINDOW_RENDER_FLAGS,
             p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
             Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
+
+        /* set position and dimension */
         PtSetResource( p_vout->p_sys->p_window,
-            Pt_ARG_POS, &pos, 0 );
+                       Pt_ARG_POS, &p_vout->p_sys->pos, 0 );
         PtSetResource( p_vout->p_sys->p_window,
-            Pt_ARG_DIM, &dim, 0 );
-    }
+                       Pt_ARG_DIM, &dim, 0 );
 
-    /*
-     * vout window resizing
-     */
-    if( ( p_vout->i_width  != p_vout->p_sys->dim.w ) ||
-             ( p_vout->i_height != p_vout->p_sys->dim.h ) )
-    {
-        intf_DbgMsg( "vout: resizing output window" );
-
-        p_vout->p_sys->dim.w = p_vout->i_width;
-        p_vout->p_sys->dim.h = p_vout->i_height;
-
-        /* set new dimension */
-        PtSetResource( p_vout->p_sys->p_window,
-            Pt_ARG_DIM, &p_vout->p_sys->dim, 0 );
+        /* mark as damaged to force redraw */
+        PtDamageWidget( p_vout->p_sys->p_window );
     }
 
     /*
@@ -556,6 +571,13 @@ static int vout_Manage( vout_thread_t *p_vout )
         intf_DbgMsg( "vout: resizing window" );
         p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
 
+        if( p_vout->p_sys->i_mode != MODE_VIDEO_OVERLAY )
+        {
+            p_vout->i_width = p_vout->p_sys->dim.w;
+            p_vout->i_height = p_vout->p_sys->dim.h;
+            p_vout->i_changes |= VOUT_YUV_CHANGE;
+        }
+
         vout_End( p_vout );
         if( vout_Init( p_vout ) )
         {
@@ -563,9 +585,8 @@ static int vout_Manage( vout_thread_t *p_vout )
             return( 1 );
         }
 
-        p_vout->i_changes |= VOUT_YUV_CHANGE;
         intf_Msg( "vout: video display resized (%dx%d)",
-                    p_vout->i_width, p_vout->i_height );
+                  p_vout->p_sys->dim.w, p_vout->p_sys->dim.h );
     }
 
     /*
@@ -664,6 +685,14 @@ static int QNXInitDisplay( p_vout_thread_t p_vout )
         return( 1 );
     }
 
+    /* switch to normal mode if no overlay support */
+    if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY &&
+        !( minfo.mode_capabilities1 & PgVM_MODE_CAP1_VIDEO_OVERLAY ) )
+    {
+        intf_ErrMsg( "vout error: no overlay support detected" );
+        p_vout->p_sys->i_mode = MODE_NORMAL_MEM;
+    }
+
     /* use video ram if we have enough available */
     if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM &&
         hwcaps.currently_available_video_ram >= 
@@ -729,60 +758,42 @@ static int QNXCreateWnd( p_vout_thread_t p_vout )
     PhPoint_t pos = { 0, 0 };
     PgColor_t color = Pg_BLACK;
 
-    /* correct way to check for overlay support:
-
-        1. call PgGetGraphicsHWCaps and check
-           the results for Pg_VIDEO_OVERLAY
-        2. check if the current graphics mode
-           has PgVM_MODE_CAP1_VIDEO_OVERLAY set
-        3. call PgGetScalerCapabilities for info
-
-        problems:
-
-        1. Pg_VIDEO_OVERLAY is not defined in any
-           header files :)
-        2. PgVM_MODE_CAP1_VIDEO_OVERLAY is not set
-           even if the current mode supports overlay
-        3. the flags (chroma, etc) do not reflect
-           the actual capabilities 
-    */
-    
     if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
     {
+        int i = 0;
+        PgScalerCaps_t vcaps;
+
         if( ( p_vout->p_sys->p_channel = 
             PgCreateVideoChannel( Pg_VIDEO_CHANNEL_SCALER, 0 ) ) == NULL )
         {
             intf_ErrMsg( "vout error: unable to create video channel" );
             return( 1 );
         }
-        else
-        {
-            int i = 0;
-            PgScalerCaps_t vcaps;
-
-            vcaps.size = sizeof( vcaps );
-            while( PgGetScalerCapabilities( p_vout->p_sys->p_channel, 
-                                            i++, &vcaps ) == 0 )
-            {    
-                if( vcaps.format == Pg_VIDEO_FORMAT_YV12 ||
-                    vcaps.format == Pg_VIDEO_FORMAT_RGB8888 )
-                {
-                    p_vout->p_sys->i_vc_flags  = vcaps.flags;
-                    p_vout->p_sys->i_vc_format = vcaps.format;
-                }
-                
-                vcaps.size = sizeof( vcaps );
-            }
 
-            if( p_vout->p_sys->i_vc_format == 0 )
+        vcaps.size = sizeof( vcaps );
+        while( PgGetScalerCapabilities( p_vout->p_sys->p_channel, 
+                                        i++, &vcaps ) == 0 )
+        {    
+            if( vcaps.format == Pg_VIDEO_FORMAT_YV12 ||
+                vcaps.format == Pg_VIDEO_FORMAT_RGB8888 )
             {
-                intf_ErrMsg( "vout error: need YV12 or RGB8888 overlay" );
-                return( 1 );
-            }
-            else if( vcaps.flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
-            {
-                color = PgGetOverlayChromaColor();
+                p_vout->p_sys->i_vc_flags  = vcaps.flags;
+                p_vout->p_sys->i_vc_format = vcaps.format;
             }
+                
+            vcaps.size = sizeof( vcaps );
+        }
+
+        if( p_vout->p_sys->i_vc_format == 0 )
+        {
+            intf_ErrMsg( "vout error: need YV12 or RGB8888 overlay" );
+            
+            return( 1 );
+        }
+        
+        if( p_vout->p_sys->i_vc_flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
+        {
+            color = PgGetOverlayChromaColor();
         }
     }
 
@@ -802,10 +813,10 @@ static int QNXCreateWnd( p_vout_thread_t p_vout )
     PtSetArg( &args[3], Pt_ARG_WINDOW_TITLE, "VideoLan Client", 0 );
     PtSetArg( &args[4], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE );
     PtSetArg( &args[5], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, 
-                Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_CLOSE );
+              Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_CLOSE );
     PtSetArg( &args[6], Pt_ARG_WINDOW_RENDER_FLAGS,
-        p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
-        Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
+              p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
+              Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
 
     /* create window */
     p_vout->p_sys->p_window = PtCreateWidget( PtWindow, Pt_NO_PARENT, 7, args);
@@ -823,6 +834,15 @@ static int QNXCreateWnd( p_vout_thread_t p_vout )
         return( 1 );
     }
 
+    /* get window frame size */
+    if( PtWindowFrameSize( NULL, p_vout->p_sys->p_window, 
+                           &p_vout->p_sys->frame ) != 0 )
+    {
+        intf_ErrMsg( "vout error: unable to get window frame size" );
+        PtDestroyWidget( p_vout->p_sys->p_window );
+        return( 1 );
+    }
+
     return( 0 );
 }