1 /*****************************************************************************
2 * vout_beos.cpp: beos video output display method
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: vout_beos.cpp,v 1.37 2002/01/05 18:25:48 sam Exp $
7 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
9 * Tony Castley <tcastley@mail.powerup.com.au>
10 * Richard Shepherd <richard@rshepherd.demon.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
30 #include <errno.h> /* ENOMEM */
31 #include <stdlib.h> /* free() */
33 #include <string.h> /* strerror() */
34 #include <InterfaceKit.h>
35 #include <DirectWindow.h>
36 #include <Application.h>
41 #include <videolan/vlc.h>
44 #include "video_output.h"
46 #include "interface.h"
49 #include "VideoWindow.h"
51 #define BITS_PER_PLANE 16
52 #define BYTES_PER_PIXEL 2
54 /*****************************************************************************
55 * vout_sys_t: BeOS video output method descriptor
56 *****************************************************************************
57 * This structure is part of the video output thread descriptor.
58 * It describes the BeOS specific properties of an output thread.
59 *****************************************************************************/
60 typedef struct vout_sys_s
62 VideoWindow * p_window;
69 /*****************************************************************************
70 * beos_GetAppWindow : retrieve a BWindow pointer from the window name
71 *****************************************************************************/
72 BWindow *beos_GetAppWindow(char *name)
77 for (index = 0 ; ; index++)
79 window = be_app->WindowAt(index);
82 if (window->LockWithTimeout(20000) == B_OK)
84 if (strcmp(window->Name(), name) == 0)
95 /****************************************************************************
96 * DrawingThread : thread that really does the drawing
97 ****************************************************************************/
98 int32 Draw(void *data)
102 display_mode disp_mode;
103 static uint32 refresh, oldrefresh = 0;
105 screen = new BScreen();
106 screen-> GetMode(&disp_mode);
108 (disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
109 (disp_mode.timing.v_total));
110 if (!(refresh == oldrefresh))
112 printf("\nNew refreshrate is %d:Hz\n",refresh);
113 oldrefresh = refresh;
116 printf("Enabling retrace sync.\n");
120 printf("Disabling retrace sync.\n");
125 p_win = (VideoWindow *) data;
126 if ( p_win-> voutWindow-> LockLooper() )
131 screen-> WaitForRetrace(22000);//set timeout for < 45 Hz...
134 p_win-> view-> DrawBitmap( p_win-> bitmap[p_win-> i_buffer],
135 p_win-> bitmap[p_win-> i_buffer]-> Bounds(),
136 p_win-> voutWindow-> Bounds() );
137 p_win-> voutWindow-> UnlockLooper();
142 /*****************************************************************************
143 * bitmapWindow : This is the bitmap window output
144 *****************************************************************************/
145 bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner)
146 : BWindow( frame, NULL, B_TITLED_WINDOW,
147 B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
152 SetTitle(VOUT_TITLE " (BBitmap output)");
155 bitmapWindow::~bitmapWindow()
159 void bitmapWindow::FrameResized( float width, float height )
168 width_scale = width / origRect.Width();
169 height_scale = height / origRect.Height();
171 /* if the width is proportionally smaller */
172 if (width_scale <= height_scale)
174 ResizeTo(width, origRect.Height() * width_scale);
176 else /* if the height is proportionally smaller */
178 ResizeTo(origRect.Width() * height_scale, height);
182 void bitmapWindow::Zoom(BPoint origin, float width, float height )
186 MoveTo(origRect.left, origRect.top);
187 ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
188 be_app->ShowCursor();
193 screen = new BScreen(this);
194 BRect rect = screen->Frame();
197 ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
198 be_app->HideCursor();
200 is_zoomed = !is_zoomed;
203 /*****************************************************************************
204 * directWindow : This is the bitmap window output
205 *****************************************************************************/
206 directWindow::directWindow(BRect frame, VideoWindow *theOwner)
207 : BDirectWindow( frame, NULL, B_TITLED_WINDOW,
208 B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
213 SetTitle(VOUT_TITLE " (DirectWindow output)");
216 directWindow::~directWindow()
220 void directWindow::DirectConnected(direct_buffer_info *info)
224 void directWindow::FrameResized( float width, float height )
233 width_scale = width / origRect.Width();
234 height_scale = height / origRect.Height();
236 /* if the width is proportionally smaller */
237 if (width_scale <= height_scale)
239 ResizeTo(width, origRect.Height() * width_scale);
241 else /* if the height is proportionally smaller */
243 ResizeTo(origRect.Width() * height_scale, height);
247 void directWindow::Zoom(BPoint origin, float width, float height )
251 SetFullScreen(false);
252 MoveTo(origRect.left, origRect.top);
253 ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
254 be_app->ShowCursor();
260 screen = new BScreen(this);
261 BRect rect = screen->Frame();
264 ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
265 be_app->HideCursor();
267 is_zoomed = !is_zoomed;
270 /*****************************************************************************
271 * VideoWindow constructor and destructor
272 *****************************************************************************/
273 VideoWindow::VideoWindow( int width, int height,
274 vout_thread_t *p_video_output )
276 if ( BDirectWindow::SupportsWindowMode() )
278 voutWindow = new directWindow( BRect( 80, 50,
279 80 + width, 50 + height ), this );
283 voutWindow = new bitmapWindow( BRect( 80, 50,
284 80 + width, 50 + height ), this );
287 /* set the VideoWindow variables */
288 teardownwindow = false;
290 /* create the view to do the display */
291 view = new VLCView( voutWindow->Bounds() );
292 voutWindow->AddChild(view);
294 /* Bitmap mode overlay not available */
295 #if BITS_PER_PLANE == 32
296 bitmap[0] = new BBitmap( voutWindow->Bounds(), B_RGB32);
297 bitmap[1] = new BBitmap( voutWindow->Bounds(), B_RGB32);
299 bitmap[0] = new BBitmap( voutWindow->Bounds(), B_RGB32);
300 bitmap[1] = new BBitmap( voutWindow->Bounds(), B_RGB32);
302 memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
303 memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
305 i_width = bitmap[0]->Bounds().IntegerWidth();
306 i_height = bitmap[0]->Bounds().IntegerHeight();
311 VideoWindow::~VideoWindow()
319 teardownwindow = true;
320 wait_for_thread(fDrawThreadID, &result);
325 void VideoWindow::resizeIfRequired( int newWidth, int newHeight )
327 if (( newWidth != i_width + 1) &&
328 ( newHeight != i_height + 1) &&
331 if ( voutWindow->Lock() )
333 view->ClearViewBitmap();
334 i_width = newWidth - 1;
335 i_height = newHeight -1;
336 voutWindow->ResizeTo((float) i_width, (float) i_height);
337 voutWindow->Unlock();
342 void VideoWindow::drawBuffer(int bufferIndex)
346 i_buffer = bufferIndex;
348 fDrawThreadID = spawn_thread(Draw, "drawing_thread",
349 B_DISPLAY_PRIORITY, (void*) this);
350 wait_for_thread(fDrawThreadID, &status);
353 /*****************************************************************************
355 *****************************************************************************/
356 VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW)
358 #if BITS_PER_PLANE == 32
359 SetViewColor(B_TRANSPARENT_32_BIT);
361 SetViewColor(B_TRANSPARENT_16_BIT);
365 /*****************************************************************************
367 *****************************************************************************/
372 /*****************************************************************************
374 *****************************************************************************/
375 void VLCView::MouseDown(BPoint point)
377 BWindow *win = Window();
384 /*****************************************************************************
386 *****************************************************************************/
387 static int vout_Probe ( probedata_t *p_data );
388 static int vout_Create ( vout_thread_t * );
389 static int vout_Init ( vout_thread_t * );
390 static void vout_End ( vout_thread_t * );
391 static void vout_Destroy ( vout_thread_t * );
392 static int vout_Manage ( vout_thread_t * );
393 static void vout_Display ( vout_thread_t *, picture_t * );
394 static void vout_Render ( vout_thread_t *, picture_t * );
396 static int BeosOpenDisplay ( vout_thread_t *p_vout );
397 static void BeosCloseDisplay( vout_thread_t *p_vout );
399 /*****************************************************************************
400 * Functions exported as capabilities. They are declared as static so that
401 * we don't pollute the namespace too much.
402 *****************************************************************************/
403 void _M( vout_getfunctions )( function_list_t * p_function_list )
405 p_function_list->pf_probe = vout_Probe;
406 p_function_list->functions.vout.pf_create = vout_Create;
407 p_function_list->functions.vout.pf_init = vout_Init;
408 p_function_list->functions.vout.pf_end = vout_End;
409 p_function_list->functions.vout.pf_destroy = vout_Destroy;
410 p_function_list->functions.vout.pf_manage = vout_Manage;
411 p_function_list->functions.vout.pf_display = vout_Display;
412 p_function_list->functions.vout.pf_render = vout_Render;
415 /*****************************************************************************
416 * vout_Probe: probe the video driver and return a score
417 *****************************************************************************
418 * This function tries to initialize SDL and returns a score to the
419 * plugin manager so that it can select the best plugin.
420 *****************************************************************************/
421 static int vout_Probe( probedata_t *p_data )
423 if( TestMethod( VOUT_METHOD_VAR, "beos" ) )
430 /*****************************************************************************
431 * vout_Create: allocates BeOS video thread output method
432 *****************************************************************************
433 * This function allocates and initializes a BeOS vout method.
434 *****************************************************************************/
435 int vout_Create( vout_thread_t *p_vout )
437 /* Allocate structure */
438 p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
439 if( p_vout->p_sys == NULL )
441 intf_ErrMsg( "error: %s", strerror(ENOMEM) );
445 if( p_vout->render.i_height * p_vout->render.i_aspect
446 >= p_vout->render.i_width * VOUT_ASPECT_FACTOR )
448 p_vout->p_sys->i_width = p_vout->render.i_height
449 * p_vout->render.i_aspect / VOUT_ASPECT_FACTOR;
450 p_vout->p_sys->i_height = p_vout->render.i_height;
454 p_vout->p_sys->i_width = p_vout->render.i_width;
455 p_vout->p_sys->i_height = p_vout->render.i_width
456 * VOUT_ASPECT_FACTOR / p_vout->render.i_aspect;
459 /* Open and initialize device */
460 if( BeosOpenDisplay( p_vout ) )
462 intf_ErrMsg("vout error: can't open display");
463 free( p_vout->p_sys );
470 /*****************************************************************************
471 * vout_Init: initialize BeOS video thread output method
472 *****************************************************************************/
473 int vout_Init( vout_thread_t *p_vout )
475 VideoWindow * p_win = p_vout->p_sys->p_window;
477 if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
479 p_vout->pf_setbuffers( p_vout,
480 (byte_t *)p_win->bitmap[0]->Bits(),
481 (byte_t *)p_win->bitmap[1]->Bits());
486 /*****************************************************************************
487 * vout_End: terminate BeOS video thread output method
488 *****************************************************************************/
489 void vout_End( vout_thread_t *p_vout )
491 /* place code here to end the video */
494 /*****************************************************************************
495 * vout_Destroy: destroy BeOS video thread output method
496 *****************************************************************************
497 * Terminate an output method created by DummyCreateOutputMethod
498 *****************************************************************************/
499 void vout_Destroy( vout_thread_t *p_vout )
501 BeosCloseDisplay( p_vout );
502 free( p_vout->p_sys );
505 /*****************************************************************************
506 * vout_Manage: handle BeOS events
507 *****************************************************************************
508 * This function should be called regularly by video output thread. It manages
509 * console events. It returns a non null value on error.
510 *****************************************************************************/
511 int vout_Manage( vout_thread_t *p_vout )
513 VideoWindow * p_win = p_vout->p_sys->p_window;
515 p_win->resizeIfRequired(p_vout->p_buffer[p_vout->i_buffer_index].i_pic_width,
516 p_vout->p_buffer[p_vout->i_buffer_index].i_pic_height);
521 /*****************************************************************************
522 * vout_Render: render previously calculated output
523 *****************************************************************************/
524 void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
529 /*****************************************************************************
530 * vout_Display: displays previously rendered output
531 *****************************************************************************
532 * This function send the currently rendered image to BeOS image, waits until
533 * it is displayed and switch the two rendering buffers, preparing next frame.
534 *****************************************************************************/
535 void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
538 VideoWindow * p_win = p_vout->p_sys->p_window;
539 /* draw buffer if required */
540 if (!p_win->teardownwindow)
542 p_win->drawBuffer(p_vout->i_buffer_index);
545 p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
548 /* following functions are local */
550 /*****************************************************************************
551 * BeosOpenDisplay: open and initialize BeOS device
552 *****************************************************************************/
553 static int BeosOpenDisplay( vout_thread_t *p_vout )
556 VideoWindow * p_win = new VideoWindow( p_vout->i_width - 1,
557 p_vout->i_height - 1,
562 free( p_vout->p_sys );
563 intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
567 p_vout->p_sys->p_window = p_win;
568 /* set the system to 32bits always
569 let BeOS do all the work */
570 p_vout->p_sys->i_width = p_win->i_width + 1;
571 p_vout->p_sys->i_height = p_win->i_height + 1;
573 p_vout->i_screen_depth = BITS_PER_PLANE;
574 p_vout->i_bytes_per_pixel = BYTES_PER_PIXEL;
575 p_vout->i_bytes_per_line = p_vout->p_sys->i_width * BYTES_PER_PIXEL;
577 p_vout->i_red_mask = 0xff0000;
578 p_vout->i_green_mask = 0x00ff00;
579 p_vout->i_blue_mask = 0x0000ff;
585 /*****************************************************************************
586 * BeosDisplay: close and reset BeOS device
587 *****************************************************************************
588 * Returns all resources allocated by BeosOpenDisplay and restore the original
589 * state of the device.
590 *****************************************************************************/
591 static void BeosCloseDisplay( vout_thread_t *p_vout )
593 /* Destroy the video window */
594 delete p_vout->p_sys->p_window;