]> git.sesse.net Git - vlc/blobdiff - plugins/qnx/vout_qnx.c
* Fixed a problem in the MacOS X aout which caused the previously
[vlc] / plugins / qnx / vout_qnx.c
index 3b2e479887a8ca281f1d397180aa69b345d7a6c9..6dcee12f2a8f8cdd97271103ca86334c38a50c03 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
-#define MODULE_NAME qnx 
-#include "modules_inner.h"
-
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include "defs.h"
-
 #include <errno.h>                                                 /* ENOMEM */
 #include <stdlib.h>                                                /* free() */
 #include <string.h>                                            /* strerror() */
 #include <photon/PtLabel.h>
 #include <photon/PdDirect.h>
 
-#include "config.h"
-#include "common.h"
-#include "threads.h"
-#include "mtime.h"
-#include "tests.h"
+#include <videolan/vlc.h>
 
 #include "video.h"
 #include "video_output.h"
 
 #include "interface.h"
-#include "intf_msg.h"
-#include "main.h"
-
-#include "modules.h"
-#include "modules_export.h"
 
 /*****************************************************************************
  * vout_sys_t: video output QNX method descriptor
@@ -94,14 +80,15 @@ 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;
 
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int  vout_Probe     ( probedata_t *p_data );
 static int  vout_Create    ( struct vout_thread_s * );
 static int  vout_Init      ( struct vout_thread_s * );
 static void vout_End       ( struct vout_thread_s * );
@@ -109,9 +96,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
@@ -119,7 +106,6 @@ static int  QNXInitDisplay ( struct vout_thread_s * );
  *****************************************************************************/
 void _M( vout_getfunctions )( function_list_t * p_function_list )
 {
-    p_function_list->pf_probe = vout_Probe;
     p_function_list->functions.vout.pf_create     = vout_Create;
     p_function_list->functions.vout.pf_init       = vout_Init;
     p_function_list->functions.vout.pf_end        = vout_End;
@@ -129,22 +115,6 @@ void _M( vout_getfunctions )( function_list_t * p_function_list )
     p_function_list->functions.vout.pf_setpalette = NULL;
 }
 
-/*****************************************************************************
- * vout_Probe: probe the video driver and return a score
- *****************************************************************************
- * This function tries to initialize SDL and returns a score to the
- * plugin manager so that it can select the best plugin.
- *****************************************************************************/
-static int vout_Probe( probedata_t *p_data )
-{
-    if( TestMethod( VOUT_METHOD_VAR, "qnx" ) )
-    {
-        return( 999 );
-    }
-
-    return( 100 );
-}
-
 /*****************************************************************************
  * vout_Create: allocate QNX video thread output method
  *****************************************************************************
@@ -172,15 +142,13 @@ static int vout_Create( vout_thread_t *p_vout )
     memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
 
     p_vout->b_fullscreen = 
-        main_GetIntVariable( VOUT_FULLSCREEN_VAR, VOUT_FULLSCREEN_DEFAULT );
+        config_GetIntVariable( "fullscreen" );
     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 = 
-        main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
-    p_vout->p_sys->dim.h = 
-        main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
-    
+        config_GetIntVariable( "nooverlay" ) ?
+        MODE_NORMAL_MEM : MODE_VIDEO_OVERLAY;
+    p_vout->p_sys->dim.w = p_vout->i_window_width;
+    p_vout->p_sys->dim.h = p_vout->i_window_height;
+
     /* init display and create window */
     if( QNXInitDisplay( p_vout ) || QNXCreateWnd( p_vout ) )
     {
@@ -199,11 +167,15 @@ static int vout_Create( vout_thread_t *p_vout )
  *****************************************************************************/
 static int vout_Init( vout_thread_t *p_vout )
 {
-    if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM ||
-        p_vout->p_sys->i_mode == MODE_SHARED_MEM )
+    /* These variables are only used if we are in overlay mode */
+    int i_ret;
+    PgScalerProps_t props;
+
+    switch( p_vout->p_sys->i_mode )
     {
+    case MODE_NORMAL_MEM:
+    case MODE_SHARED_MEM:
         /* create images for [shared] memory blit */
-
         if( !( p_vout->p_sys->p_image[0] = PhCreateImage( NULL,
                     p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
                     p_vout->p_sys->i_img_type, NULL, 0,
@@ -226,12 +198,11 @@ 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 );
-    }
-    else if( p_vout->p_sys->i_mode == MODE_VIDEO_MEM )
-    {
-        /* create offscreen contexts for video memory blit */
+                               p_vout->p_sys->p_image[1]->image );
+        break;
 
+    case MODE_VIDEO_MEM:
+        /* create offscreen contexts for video memory blit */
         if( ( p_vout->p_sys->p_ctx[0] = PdCreateOffscreenContext( 0,
                         p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
                         Pg_OSC_MEM_PAGE_ALIGN ) ) == NULL )
@@ -265,49 +236,67 @@ 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] );
-    }
-    else if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
-    {
-        PgScalerProps_t props;
+                               p_vout->p_sys->p_buf[1] );
 
-        props.size = sizeof( props );
+    case MODE_VIDEO_OVERLAY:
+        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,14 +322,19 @@ 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] );
         }
+        break;
+
+    default:
+        /* This shouldn't happen ! */
+        break;
     }
 
     return( 0 );
@@ -435,16 +429,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;
                 }
@@ -480,12 +474,6 @@ static int vout_Manage( vout_thread_t *p_vout )
                         {
                             network_ChannelJoin( i_key );
                         }
-                        else if( intf_ProcessKey( p_main->p_intf,
-                                                    (char) i_key ) )
-                        {
-                            intf_DbgMsg( "vout: unhandled key '%c' (%i)",
-                                         (char) i_key, i_key );
-                        }
                         break;
                     }
                 }
@@ -501,51 +489,40 @@ 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" );
 
         p_vout->b_fullscreen = !p_vout->b_fullscreen;
         p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
 
         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 );
-    }
-
-    /*
-     * 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;
+                       Pt_ARG_DIM, &dim, 0 );
 
-        /* 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 );
     }
 
     /*
@@ -553,9 +530,15 @@ static int vout_Manage( vout_thread_t *p_vout )
      */
     if( p_vout->i_changes & VOUT_SIZE_CHANGE )
     {
-        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 +546,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 );
     }
 
     /*
@@ -573,8 +555,6 @@ static int vout_Manage( vout_thread_t *p_vout )
      */
     if( b_repos && p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
     {
-        intf_DbgMsg( "vout: moving video channel" );
-
         vout_End( p_vout );
         if( vout_Init( p_vout ) )
         {
@@ -664,12 +644,19 @@ 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 >= 
         ( ( minfo.width * minfo.height * minfo.bits_per_pixel ) / 8 ) )
     {
-        intf_DbgMsg( "vout: using video ram" );
         p_vout->p_sys->i_mode = MODE_VIDEO_MEM;
     }
 
@@ -697,23 +684,23 @@ static int QNXInitDisplay( p_vout_thread_t p_vout )
     switch( p_vout->i_screen_depth )
     {
         case 15:
-            p_vout->i_red_mask   = 0x7c00;
-            p_vout->i_green_mask = 0x03e0;
-            p_vout->i_blue_mask  = 0x001f;
+            p_vout->output.i_rmask = 0x7c00;
+            p_vout->output.i_gmask = 0x03e0;
+            p_vout->output.i_bmask = 0x001f;
             break;
 
         case 16:
-            p_vout->i_red_mask   = 0xf800;
-            p_vout->i_green_mask = 0x07e0;
-            p_vout->i_blue_mask  = 0x001f;
+            p_vout->output.i_rmask = 0xf800;
+            p_vout->output.i_gmask = 0x07e0;
+            p_vout->output.i_bmask = 0x001f;
             break;
 
         case 24:
         case 32:
         default:
-            p_vout->i_red_mask   = 0xff0000;
-            p_vout->i_green_mask = 0x00ff00;
-            p_vout->i_blue_mask  = 0x0000ff;
+            p_vout->output.i_rmask = 0xff0000;
+            p_vout->output.i_gmask = 0x00ff00;
+            p_vout->output.i_bmask = 0x0000ff;
             break;
     }
 
@@ -729,60 +716,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 +771,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 +792,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 );
 }