1 /*****************************************************************************
2 * vout_qnx.c: QNX RTOS video output display method
3 *****************************************************************************
4 * Copyright (C) 2001 VideoLAN
6 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
26 #include <errno.h> /* ENOMEM */
27 #include <stdlib.h> /* free() */
28 #include <string.h> /* strerror() */
30 #include <photon/PtWidget.h>
31 #include <photon/PtWindow.h>
32 #include <photon/PtLabel.h>
33 #include <photon/PdDirect.h>
35 #include <videolan/vlc.h>
38 #include "video_output.h"
40 #include "interface.h"
42 /*****************************************************************************
43 * vout_sys_t: video output QNX method descriptor
44 *****************************************************************************
45 * This structure is part of the video output thread descriptor.
46 * It describes the QNX specific properties of an output thread. QNX video
47 * output is performed through regular resizable windows. Windows can be
48 * dynamically resized to adapt to the size of the streams.
49 *****************************************************************************/
51 #define MODE_NORMAL_MEM 0
52 #define MODE_SHARED_MEM 1
53 #define MODE_VIDEO_MEM 2
54 #define MODE_VIDEO_OVERLAY 3
56 typedef struct vout_sys_s
62 PtWidget_t * p_window;
64 /* [shared] memory blit */
65 PhImage_t * p_image[2];
68 /* video memory blit */
69 PdOffscreenContext_t * p_ctx[2];
73 PgVideoChannel_t * p_channel;
80 /* position & dimensions */
89 /*****************************************************************************
91 *****************************************************************************/
92 static int vout_Probe ( probedata_t *p_data );
93 static int vout_Create ( struct vout_thread_s * );
94 static int vout_Init ( struct vout_thread_s * );
95 static void vout_End ( struct vout_thread_s * );
96 static void vout_Destroy ( struct vout_thread_s * );
97 static int vout_Manage ( struct vout_thread_s * );
98 static void vout_Display ( struct vout_thread_s * );
100 static int QNXInitDisplay ( struct vout_thread_s * );
101 static int QNXCreateWnd ( struct vout_thread_s * );
102 static int QNXDestroyWnd ( struct vout_thread_s * );
104 /*****************************************************************************
105 * Functions exported as capabilities. They are declared as static so that
106 * we don't pollute the namespace too much.
107 *****************************************************************************/
108 void _M( vout_getfunctions )( function_list_t * p_function_list )
110 p_function_list->pf_probe = vout_Probe;
111 p_function_list->functions.vout.pf_create = vout_Create;
112 p_function_list->functions.vout.pf_init = vout_Init;
113 p_function_list->functions.vout.pf_end = vout_End;
114 p_function_list->functions.vout.pf_destroy = vout_Destroy;
115 p_function_list->functions.vout.pf_manage = vout_Manage;
116 p_function_list->functions.vout.pf_display = vout_Display;
117 p_function_list->functions.vout.pf_setpalette = NULL;
120 /*****************************************************************************
121 * vout_Probe: probe the video driver and return a score
122 *****************************************************************************
123 * This function tries to initialize SDL and returns a score to the
124 * plugin manager so that it can select the best plugin.
125 *****************************************************************************/
126 static int vout_Probe( probedata_t *p_data )
128 if( TestMethod( VOUT_METHOD_VAR, "qnx" ) )
136 /*****************************************************************************
137 * vout_Create: allocate QNX video thread output method
138 *****************************************************************************
139 * This function allocate and initialize a QNX vout method. It uses some of the
140 * vout properties to choose the window size, and change them according to the
141 * actual properties of the display.
142 *****************************************************************************/
143 static int vout_Create( vout_thread_t *p_vout )
145 /* init connection to photon */
146 if( PtInit( "/dev/photon" ) != 0 )
148 intf_ErrMsg( "vout error: unable to connect to photon" );
152 /* allocate structure */
153 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
154 if( p_vout->p_sys == NULL )
156 intf_ErrMsg( "vout error: %s", strerror( ENOMEM ) );
160 memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
162 p_vout->b_fullscreen =
163 main_GetIntVariable( VOUT_FULLSCREEN_VAR, VOUT_FULLSCREEN_DEFAULT );
164 p_vout->p_sys->i_mode =
165 main_GetIntVariable( VOUT_OVERLAY_VAR, VOUT_OVERLAY_DEFAULT ) ?
166 MODE_VIDEO_OVERLAY : MODE_NORMAL_MEM;
167 p_vout->p_sys->dim.w =
168 main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
169 p_vout->p_sys->dim.h =
170 main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
172 /* init display and create window */
173 if( QNXInitDisplay( p_vout ) || QNXCreateWnd( p_vout ) )
175 free( p_vout->p_sys );
182 /*****************************************************************************
183 * vout_Init: initialize QNX video thread output method
184 *****************************************************************************
185 * This function create the buffers needed by the output thread. It is called
186 * at the beginning of the thread, but also each time the window is resized.
187 *****************************************************************************/
188 static int vout_Init( vout_thread_t *p_vout )
190 if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM ||
191 p_vout->p_sys->i_mode == MODE_SHARED_MEM )
193 /* create images for [shared] memory blit */
195 if( !( p_vout->p_sys->p_image[0] = PhCreateImage( NULL,
196 p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
197 p_vout->p_sys->i_img_type, NULL, 0,
198 p_vout->p_sys->i_mode == MODE_SHARED_MEM ) ) ) {
199 intf_ErrMsg( "vout error: cannot create image" );
203 if( !( p_vout->p_sys->p_image[1] = PhCreateImage( NULL,
204 p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
205 p_vout->p_sys->i_img_type, NULL, 0,
206 p_vout->p_sys->i_mode == MODE_SHARED_MEM ) ) ) {
207 intf_ErrMsg( "vout error: cannot create image" );
208 PhReleaseImage( p_vout->p_sys->p_image[0] );
209 free( p_vout->p_sys->p_image[0] );
210 p_vout->p_sys->p_image[0] = NULL;
214 /* set bytes per line, set buffers */
215 p_vout->i_bytes_per_line = p_vout->p_sys->p_image[0]->bpl;
216 p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_image[0]->image,
217 p_vout->p_sys->p_image[1]->image );
219 else if( p_vout->p_sys->i_mode == MODE_VIDEO_MEM )
221 /* create offscreen contexts for video memory blit */
223 if( ( p_vout->p_sys->p_ctx[0] = PdCreateOffscreenContext( 0,
224 p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
225 Pg_OSC_MEM_PAGE_ALIGN ) ) == NULL )
227 intf_ErrMsg( "vout error: unable to create offscreen context" );
231 if( ( p_vout->p_sys->p_ctx[1] = PdCreateOffscreenContext( 0,
232 p_vout->p_sys->dim.w, p_vout->p_sys->dim.h,
233 Pg_OSC_MEM_PAGE_ALIGN ) ) == NULL )
235 intf_ErrMsg( "vout error: unable to create offscreen context" );
236 PhDCRelease ( p_vout->p_sys->p_ctx[0] );
237 p_vout->p_sys->p_ctx[0] = NULL;
241 /* get context pointers */
242 if( ( ( p_vout->p_sys->p_buf[0] =
243 PdGetOffscreenContextPtr ( p_vout->p_sys->p_ctx[0] ) ) == NULL ) ||
244 ( p_vout->p_sys->p_buf[1] =
245 PdGetOffscreenContextPtr ( p_vout->p_sys->p_ctx[1] ) ) == NULL )
247 intf_ErrMsg( "vout error: unable to get offscreen context ptr" );
248 PhDCRelease ( p_vout->p_sys->p_ctx[0] );
249 PhDCRelease ( p_vout->p_sys->p_ctx[1] );
250 p_vout->p_sys->p_ctx[0] = NULL;
251 p_vout->p_sys->p_ctx[1] = NULL;
255 /* set bytes per line, clear buffers, set buffers */
256 p_vout->i_bytes_per_line = p_vout->p_sys->p_ctx[0]->pitch;
257 memset( p_vout->p_sys->p_buf[0], 0,
258 p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
259 memset( p_vout->p_sys->p_buf[1], 0,
260 p_vout->i_bytes_per_line * p_vout->p_sys->dim.h );
261 p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_buf[0],
262 p_vout->p_sys->p_buf[1] );
264 else if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
267 PgScalerProps_t props;
269 props.size = sizeof( props );
270 props.format = p_vout->p_sys->i_vc_format;
271 props.flags = Pg_SCALER_PROP_SCALER_ENABLE |
272 Pg_SCALER_PROP_DOUBLE_BUFFER;
274 /* enable chroma keying if available */
275 if( p_vout->p_sys->i_vc_flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
277 props.flags |= Pg_SCALER_PROP_CHROMA_ENABLE;
280 /* set viewport position */
281 props.viewport.ul.x = p_vout->p_sys->pos.x;
282 props.viewport.ul.y = p_vout->p_sys->pos.y;
283 if( !p_vout->b_fullscreen )
285 props.viewport.ul.x += p_vout->p_sys->frame.ul.x;
286 props.viewport.ul.y += p_vout->p_sys->frame.ul.y;
289 /* set viewport dimension */
290 props.viewport.lr.x = p_vout->p_sys->dim.w + props.viewport.ul.x;
291 props.viewport.lr.y = p_vout->p_sys->dim.h + props.viewport.ul.y;
293 /* set source dimension */
294 props.src_dim.w = p_vout->i_width;
295 props.src_dim.h = p_vout->i_height;
297 /* configure scaler channel */
298 i_ret = PgConfigScalerChannel( p_vout->p_sys->p_channel, &props );
302 intf_ErrMsg( "vout error: unable to configure video channel" );
305 else if( i_ret == 1 )
307 p_vout->p_sys->p_vc_y[0] =
308 PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane1 );
309 p_vout->p_sys->p_vc_y[1] =
310 PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->yplane2 );
312 if( p_vout->p_sys->p_vc_y[0] == NULL ||
313 p_vout->p_sys->p_vc_y[1] == NULL )
315 intf_ErrMsg( "vout error: unable to get video channel ctx ptr" );
320 if( p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_YV12 && i_ret == 1 )
322 p_vout->b_need_render = 0;
324 p_vout->p_sys->p_vc_u[0] =
325 PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->uplane1 );
326 p_vout->p_sys->p_vc_u[1] =
327 PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->uplane2 );
328 p_vout->p_sys->p_vc_v[0] =
329 PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->vplane1 );
330 p_vout->p_sys->p_vc_v[1] =
331 PdGetOffscreenContextPtr( p_vout->p_sys->p_channel->vplane2 );
333 if( p_vout->p_sys->p_vc_u[0] == NULL ||
334 p_vout->p_sys->p_vc_u[1] == NULL ||
335 p_vout->p_sys->p_vc_v[0] == NULL ||
336 p_vout->p_sys->p_vc_v[1] == NULL )
338 intf_ErrMsg( "vout error: unable to get video channel ctx ptr" );
342 else if( p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_RGB8888 )
344 /* set bytes per line, clear buffers, set buffers */
345 p_vout->i_bytes_per_line =
346 p_vout->p_sys->p_channel->yplane1->pitch;
347 memset( p_vout->p_sys->p_vc_y[0], 0,
348 p_vout->i_bytes_per_line * p_vout->i_height );
349 memset( p_vout->p_sys->p_vc_y[1], 0,
350 p_vout->i_bytes_per_line * p_vout->i_height );
351 p_vout->pf_setbuffers( p_vout,
352 p_vout->p_sys->p_vc_y[0], p_vout->p_sys->p_vc_y[1] );
359 /*****************************************************************************
360 * vout_End: terminate QNX video thread output method
361 *****************************************************************************
362 * Destroy the buffers created by vout_Init. It is called at the end of
363 * the thread, but also each time the window is resized.
364 *****************************************************************************/
365 static void vout_End( vout_thread_t *p_vout )
367 if( ( p_vout->p_sys->i_mode == MODE_NORMAL_MEM ||
368 p_vout->p_sys->i_mode == MODE_SHARED_MEM ) &&
369 p_vout->p_sys->p_image[0] )
371 PhReleaseImage( p_vout->p_sys->p_image[0] );
372 PhReleaseImage( p_vout->p_sys->p_image[1] );
373 free( p_vout->p_sys->p_image[0] );
374 free( p_vout->p_sys->p_image[1] );
376 else if( p_vout->p_sys->i_mode == MODE_VIDEO_MEM &&
377 p_vout->p_sys->p_ctx[0] )
379 PhDCRelease( p_vout->p_sys->p_ctx[0] );
380 PhDCRelease( p_vout->p_sys->p_ctx[1] );
384 /*****************************************************************************
385 * vout_Destroy: destroy QNX video thread output method
386 *****************************************************************************
387 * Terminate an output method created by vout_CreateOutputMethod
388 *****************************************************************************/
389 static void vout_Destroy( vout_thread_t *p_vout )
391 /* destroy the window */
392 QNXDestroyWnd( p_vout );
394 /* destroy structure */
395 free( p_vout->p_sys );
398 /*****************************************************************************
399 * vout_Manage: handle QNX events
400 *****************************************************************************
401 * This function should be called regularly by video output thread. It allows
402 * window resizing. It returns a non null value on error.
403 *****************************************************************************/
404 static int vout_Manage( vout_thread_t *p_vout )
408 boolean_t b_repos = 0;
410 /* allocate buffer for event */
411 i_buflen = sizeof( PhEvent_t ) * 4;
412 if( ( p_event = malloc( i_buflen ) ) == NULL )
414 intf_ErrMsg( "vout error: %s", strerror( ENOMEM ) );
421 memset( p_event, 0, i_buflen );
422 i_ev = PhEventPeek( p_event, i_buflen );
424 if( i_ev == Ph_RESIZE_MSG )
426 i_buflen = PhGetMsgSize( p_event );
427 if( ( p_event = realloc( p_event, i_buflen ) ) == NULL )
429 intf_ErrMsg( "vout error: %s", strerror( ENOMEM ) );
433 else if( i_ev == Ph_EVENT_MSG )
435 PtEventHandler( p_event );
437 if( p_event->type == Ph_EV_WM )
439 PhWindowEvent_t *p_ev = PhGetData( p_event );
441 switch( p_ev->event_f )
444 p_main->p_intf->b_die = 1;
448 p_vout->p_sys->pos.x = p_ev->pos.x;
449 p_vout->p_sys->pos.y = p_ev->pos.y;
454 p_vout->p_sys->old_dim.w = p_vout->p_sys->dim.w;
455 p_vout->p_sys->old_dim.h = p_vout->p_sys->dim.h;
456 p_vout->p_sys->dim.w = p_ev->size.w;
457 p_vout->p_sys->dim.h = p_ev->size.h;
458 p_vout->i_changes |= VOUT_SIZE_CHANGE;
462 else if( p_event->type == Ph_EV_KEY )
464 PhKeyEvent_t *p_ev = PhGetData( p_event );
465 long i_key = p_ev->key_sym;
467 if( ( p_ev->key_flags & Pk_KF_Key_Down ) &&
468 ( p_ev->key_flags & Pk_KF_Sym_Valid ) )
474 p_main->p_intf->b_die = 1;
479 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
484 p_vout->b_grayscale = ! p_vout->b_grayscale;
485 p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
489 if( i_key >= Pk_0 && i_key <= Pk_9 )
491 network_ChannelJoin( i_key );
493 else if( intf_ProcessKey( p_main->p_intf,
496 intf_DbgMsg( "vout: unhandled key '%c' (%i)",
497 (char) i_key, i_key );
504 } while( i_ev != -1 && i_ev != 0 );
511 if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
515 intf_DbgMsg( "vout: changing full-screen status" );
517 p_vout->b_fullscreen = !p_vout->b_fullscreen;
518 p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
520 if( p_vout->b_fullscreen )
522 p_vout->p_sys->old_pos.x = p_vout->p_sys->pos.x;
523 p_vout->p_sys->old_pos.y = p_vout->p_sys->pos.y;
524 p_vout->p_sys->pos.x = p_vout->p_sys->pos.y = 0;
525 dim.w = p_vout->p_sys->screen_dim.w + 1;
526 dim.h = p_vout->p_sys->screen_dim.h + 1;
530 p_vout->p_sys->pos.x = p_vout->p_sys->old_pos.x;
531 p_vout->p_sys->pos.y = p_vout->p_sys->old_pos.y;
532 dim.w = p_vout->p_sys->old_dim.w + 1;
533 dim.h = p_vout->p_sys->old_dim.h + 1;
536 /* modify render flags, border */
537 PtSetResource( p_vout->p_sys->p_window,
538 Pt_ARG_WINDOW_RENDER_FLAGS,
539 p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
540 Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
542 /* set position and dimension */
543 PtSetResource( p_vout->p_sys->p_window,
544 Pt_ARG_POS, &p_vout->p_sys->pos, 0 );
545 PtSetResource( p_vout->p_sys->p_window,
546 Pt_ARG_DIM, &dim, 0 );
548 /* mark as damaged to force redraw */
549 PtDamageWidget( p_vout->p_sys->p_window );
555 if( p_vout->i_changes & VOUT_SIZE_CHANGE )
557 intf_DbgMsg( "vout: resizing window" );
558 p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
560 if( p_vout->p_sys->i_mode != MODE_VIDEO_OVERLAY )
562 p_vout->i_width = p_vout->p_sys->dim.w;
563 p_vout->i_height = p_vout->p_sys->dim.h;
564 p_vout->i_changes |= VOUT_YUV_CHANGE;
568 if( vout_Init( p_vout ) )
570 intf_ErrMsg( "vout error: cannot resize display" );
574 intf_Msg( "vout: video display resized (%dx%d)",
575 p_vout->p_sys->dim.w, p_vout->p_sys->dim.h );
579 * position change, move video channel
581 if( b_repos && p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
583 intf_DbgMsg( "vout: moving video channel" );
586 if( vout_Init( p_vout ) )
588 intf_ErrMsg( "vout error: unable to move video channel" );
593 return( i_ev == -1 );
596 /*****************************************************************************
597 * vout_Display: displays previously rendered output
598 *****************************************************************************
599 * This function send the currently rendered image to QNX server, wait until
600 * it is displayed and switch the two rendering buffer, preparing next frame.
601 *****************************************************************************/
602 static void vout_Display( vout_thread_t *p_vout )
604 if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM ||
605 p_vout->p_sys->i_mode == MODE_SHARED_MEM )
607 PhPoint_t pos = { 0, 0 };
609 PgSetRegion( PtWidgetRid( p_vout->p_sys->p_window ) );
610 PgDrawPhImagemx( &pos, p_vout->p_sys->p_image[p_vout->i_buffer_index], 0 );
613 else if( p_vout->p_sys->i_mode == MODE_VIDEO_MEM )
615 PhRect_t rc = { { 0, 0 }, {
616 p_vout->p_sys->dim.w,
620 PgSetRegion( PtWidgetRid ( p_vout->p_sys->p_window ) );
621 PgContextBlit( p_vout->p_sys->p_ctx[p_vout->i_buffer_index], &rc, NULL, &rc );
624 else if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY &&
625 p_vout->p_sys->i_vc_format == Pg_VIDEO_FORMAT_YV12 )
629 /* this code has NOT been tested */
631 i_size = p_vout->p_rendered_pic->i_width *
632 p_vout->p_rendered_pic->i_height;
633 i_index = PgNextVideoFrame( p_vout->p_sys->p_channel );
635 memcpy( p_vout->p_sys->p_vc_y[i_index],
636 p_vout->p_rendered_pic->p_y, i_size );
637 memcpy( p_vout->p_sys->p_vc_v[i_index],
638 p_vout->p_rendered_pic->p_v, i_size / 4 );
639 memcpy( p_vout->p_sys->p_vc_u[i_index],
640 p_vout->p_rendered_pic->p_u, i_size / 4 );
644 /*****************************************************************************
645 * QNXInitDisplay: check screen resolution, depth, amount of video ram, etc
646 *****************************************************************************/
647 static int QNXInitDisplay( p_vout_thread_t p_vout )
650 PgDisplaySettings_t cfg;
651 PgVideoModeInfo_t minfo;
653 /* get graphics card hw capabilities */
654 if( PgGetGraphicsHWCaps( &hwcaps ) != 0 )
656 intf_ErrMsg( "vout error: unable to get gfx card capabilities" );
660 /* get current video mode */
661 if( PgGetVideoMode( &cfg ) != 0 )
663 intf_ErrMsg( "vout error: unable to get current video mode" );
667 /* get video mode info */
668 if( PgGetVideoModeInfo( cfg.mode, &minfo ) != 0 )
670 intf_ErrMsg( "vout error: unable to get info for video mode" );
674 /* switch to normal mode if no overlay support */
675 if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY &&
676 !( minfo.mode_capabilities1 & PgVM_MODE_CAP1_VIDEO_OVERLAY ) )
678 intf_ErrMsg( "vout error: no overlay support detected" );
679 p_vout->p_sys->i_mode = MODE_NORMAL_MEM;
682 /* use video ram if we have enough available */
683 if( p_vout->p_sys->i_mode == MODE_NORMAL_MEM &&
684 hwcaps.currently_available_video_ram >=
685 ( ( minfo.width * minfo.height * minfo.bits_per_pixel ) / 8 ) )
687 intf_DbgMsg( "vout: using video ram" );
688 p_vout->p_sys->i_mode = MODE_VIDEO_MEM;
691 p_vout->p_sys->i_img_type = minfo.type;
692 p_vout->p_sys->screen_dim.w = minfo.width;
693 p_vout->p_sys->screen_dim.h = minfo.height;
694 p_vout->i_screen_depth = minfo.bits_per_pixel;
698 case Pg_IMAGE_PALETTE_BYTE:
699 p_vout->i_bytes_per_pixel = 1;
702 case Pg_IMAGE_DIRECT_555:
703 case Pg_IMAGE_DIRECT_565:
704 p_vout->i_bytes_per_pixel = 2;
707 case Pg_IMAGE_DIRECT_8888:
708 p_vout->i_bytes_per_pixel = 4;
712 switch( p_vout->i_screen_depth )
715 p_vout->i_red_mask = 0x7c00;
716 p_vout->i_green_mask = 0x03e0;
717 p_vout->i_blue_mask = 0x001f;
721 p_vout->i_red_mask = 0xf800;
722 p_vout->i_green_mask = 0x07e0;
723 p_vout->i_blue_mask = 0x001f;
729 p_vout->i_red_mask = 0xff0000;
730 p_vout->i_green_mask = 0x00ff00;
731 p_vout->i_blue_mask = 0x0000ff;
738 /*****************************************************************************
739 * QNXCreateWnd: create and realize the main window
740 *****************************************************************************/
741 static int QNXCreateWnd( p_vout_thread_t p_vout )
744 PhPoint_t pos = { 0, 0 };
745 PgColor_t color = Pg_BLACK;
747 if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
750 PgScalerCaps_t vcaps;
752 if( ( p_vout->p_sys->p_channel =
753 PgCreateVideoChannel( Pg_VIDEO_CHANNEL_SCALER, 0 ) ) == NULL )
755 intf_ErrMsg( "vout error: unable to create video channel" );
759 vcaps.size = sizeof( vcaps );
760 while( PgGetScalerCapabilities( p_vout->p_sys->p_channel,
763 if( vcaps.format == Pg_VIDEO_FORMAT_YV12 ||
764 vcaps.format == Pg_VIDEO_FORMAT_RGB8888 )
766 p_vout->p_sys->i_vc_flags = vcaps.flags;
767 p_vout->p_sys->i_vc_format = vcaps.format;
770 vcaps.size = sizeof( vcaps );
773 if( p_vout->p_sys->i_vc_format == 0 )
775 intf_ErrMsg( "vout error: need YV12 or RGB8888 overlay" );
780 if( p_vout->p_sys->i_vc_flags & Pg_SCALER_CAP_DST_CHROMA_KEY )
782 color = PgGetOverlayChromaColor();
786 /* fullscreen, set dimension */
787 if( p_vout->b_fullscreen )
789 p_vout->p_sys->old_dim.w = p_vout->p_sys->dim.w;
790 p_vout->p_sys->old_dim.h = p_vout->p_sys->dim.h;
791 p_vout->i_width = p_vout->p_sys->dim.w = p_vout->p_sys->screen_dim.w;
792 p_vout->i_height = p_vout->p_sys->dim.h = p_vout->p_sys->screen_dim.h;
795 /* set window parameters */
796 PtSetArg( &args[0], Pt_ARG_POS, &pos, 0 );
797 PtSetArg( &args[1], Pt_ARG_DIM, &p_vout->p_sys->dim, 0 );
798 PtSetArg( &args[2], Pt_ARG_FILL_COLOR, color, 0 );
799 PtSetArg( &args[3], Pt_ARG_WINDOW_TITLE, "VideoLan Client", 0 );
800 PtSetArg( &args[4], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE );
801 PtSetArg( &args[5], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE,
802 Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_CLOSE );
803 PtSetArg( &args[6], Pt_ARG_WINDOW_RENDER_FLAGS,
804 p_vout->b_fullscreen ? Pt_FALSE : Pt_TRUE,
805 Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE );
808 p_vout->p_sys->p_window = PtCreateWidget( PtWindow, Pt_NO_PARENT, 7, args);
809 if( p_vout->p_sys->p_window == NULL )
811 intf_ErrMsg( "vout error: unable to create window" );
815 /* realize the window widget */
816 if( PtRealizeWidget( p_vout->p_sys->p_window ) != 0 )
818 intf_ErrMsg( "vout error: unable to realize window widget" );
819 PtDestroyWidget( p_vout->p_sys->p_window );
823 /* get window frame size */
824 if( PtWindowFrameSize( NULL, p_vout->p_sys->p_window,
825 &p_vout->p_sys->frame ) != 0 )
827 intf_ErrMsg( "vout error: unable to get window frame size" );
828 PtDestroyWidget( p_vout->p_sys->p_window );
835 /*****************************************************************************
836 * QNXDestroyWnd: unrealize and destroy the main window
837 *****************************************************************************/
838 static int QNXDestroyWnd( p_vout_thread_t p_vout )
840 /* destroy the window widget */
841 PtUnrealizeWidget( p_vout->p_sys->p_window );
842 PtDestroyWidget( p_vout->p_sys->p_window );
844 /* destroy video channel */
845 if( p_vout->p_sys->i_mode == MODE_VIDEO_OVERLAY )
847 PgDestroyVideoChannel( p_vout->p_sys->p_channel );