1 /*****************************************************************************
2 * vout_beos.cpp: beos video output display method
3 *****************************************************************************
4 * Copyright (C) 2000, 2001 VideoLAN
5 * $Id: vout_beos.cpp,v 1.36 2001/12/30 07:09:54 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 32
52 #define BYTES_PER_PIXEL 4
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;
64 byte_t * pp_buffer[2];
70 /*****************************************************************************
71 * beos_GetAppWindow : retrieve a BWindow pointer from the window name
72 *****************************************************************************/
73 BWindow *beos_GetAppWindow(char *name)
78 for (index = 0 ; ; index++)
80 window = be_app->WindowAt(index);
83 if (window->LockWithTimeout(20000) == B_OK)
85 if (strcmp(window->Name(), name) == 0)
96 /****************************************************************************
98 * DrawingThread : thread that really does the drawing
99 ****************************************************************************
101 int32 Draw(void *data)
105 display_mode disp_mode;
106 static uint32 refresh, oldrefresh = 0;
108 screen = new BScreen();
109 screen-> GetMode(&disp_mode);
111 (disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
112 (disp_mode.timing.v_total));
113 if (!(refresh == oldrefresh))
115 printf("\nNew refreshrate is %d:Hz\n",refresh);
116 oldrefresh = refresh;
119 printf("Enabling retrace sync.\n");
123 printf("Disabling retrace sync.\n");
128 p_win = (VideoWindow *) data;
129 if ( p_win-> voutWindow-> LockLooper() )
134 screen-> WaitForRetrace(22000);//set timeout for < 45 Hz...
137 p_win-> view-> DrawBitmap( p_win-> bitmap[p_win-> i_buffer],
138 p_win-> bitmap[p_win-> i_buffer]-> Bounds(),
139 p_win-> voutWindow-> Bounds() );
140 p_win-> voutWindow-> UnlockLooper();
145 /*****************************************************************************
146 * bitmapWindow : This is the bitmap window output
147 *****************************************************************************/
148 bitmapWindow::bitmapWindow(BRect frame, VideoWindow *theOwner)
149 : BWindow( frame, NULL, B_TITLED_WINDOW,
150 B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
155 SetTitle(VOUT_TITLE " (BBitmap output)");
158 bitmapWindow::~bitmapWindow()
162 void bitmapWindow::FrameResized( float width, float height )
171 width_scale = width / origRect.Width();
172 height_scale = height / origRect.Height();
174 /* if the width is proportionally smaller */
175 if (width_scale <= height_scale)
177 ResizeTo(width, origRect.Height() * width_scale);
179 else /* if the height is proportionally smaller */
181 ResizeTo(origRect.Width() * height_scale, height);
185 void bitmapWindow::Zoom(BPoint origin, float width, float height )
189 MoveTo(origRect.left, origRect.top);
190 ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
191 be_app->ShowCursor();
196 screen = new BScreen(this);
197 BRect rect = screen->Frame();
200 ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
201 be_app->HideCursor();
203 is_zoomed = !is_zoomed;
206 /*****************************************************************************
207 * directWindow : This is the bitmap window output
208 *****************************************************************************/
209 directWindow::directWindow(BRect frame, VideoWindow *theOwner)
210 : BDirectWindow( frame, NULL, B_TITLED_WINDOW,
211 B_OUTLINE_RESIZE | B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
216 SetTitle(VOUT_TITLE " (DirectWindow output)");
219 directWindow::~directWindow()
223 void directWindow::DirectConnected(direct_buffer_info *info)
227 void directWindow::FrameResized( float width, float height )
236 width_scale = width / origRect.Width();
237 height_scale = height / origRect.Height();
239 /* if the width is proportionally smaller */
240 if (width_scale <= height_scale)
242 ResizeTo(width, origRect.Height() * width_scale);
244 else /* if the height is proportionally smaller */
246 ResizeTo(origRect.Width() * height_scale, height);
250 void directWindow::Zoom(BPoint origin, float width, float height )
254 SetFullScreen(false);
255 MoveTo(origRect.left, origRect.top);
256 ResizeTo(origRect.IntegerWidth(), origRect.IntegerHeight());
257 be_app->ShowCursor();
263 screen = new BScreen(this);
264 BRect rect = screen->Frame();
267 ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
268 be_app->HideCursor();
270 is_zoomed = !is_zoomed;
273 /*****************************************************************************
274 * VideoWindow constructor and destructor
275 *****************************************************************************/
276 VideoWindow::VideoWindow( int width, int height,
277 vout_thread_t *p_video_output )
279 if ( BDirectWindow::SupportsWindowMode() )
281 voutWindow = new directWindow( BRect( 80, 50,
282 80 + width, 50 + height ), this );
286 voutWindow = new bitmapWindow( BRect( 80, 50,
287 80 + width, 50 + height ), this );
290 /* set the VideoWindow variables */
291 teardownwindow = false;
293 /* create the view to do the display */
294 view = new VLCView( voutWindow->Bounds() );
295 voutWindow->AddChild(view);
297 /* Bitmap mode overlay not available */
298 bitmap[0] = new BBitmap( voutWindow->Bounds(), B_RGB32);
299 bitmap[1] = new BBitmap( voutWindow->Bounds(), B_RGB32);
300 memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
301 memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
303 i_width = bitmap[0]->Bounds().IntegerWidth();
304 i_height = bitmap[0]->Bounds().IntegerHeight();
309 VideoWindow::~VideoWindow()
317 teardownwindow = true;
318 wait_for_thread(fDrawThreadID, &result);
323 void VideoWindow::resizeIfRequired( int newWidth, int newHeight )
325 if (( newWidth != i_width + 1) &&
326 ( newHeight != i_height + 1) &&
329 if ( voutWindow->Lock() )
331 view->ClearViewBitmap();
332 i_width = newWidth - 1;
333 i_height = newHeight -1;
334 voutWindow->ResizeTo((float) i_width, (float) i_height);
335 voutWindow->Unlock();
340 void VideoWindow::drawBuffer(int bufferIndex)
344 i_buffer = bufferIndex;
346 fDrawThreadID = spawn_thread(Draw, "drawing_thread",
347 B_DISPLAY_PRIORITY, (void*) this);
348 wait_for_thread(fDrawThreadID, &status);
351 /*****************************************************************************
353 *****************************************************************************/
354 VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW)
356 SetViewColor(B_TRANSPARENT_32_BIT);
359 /*****************************************************************************
361 *****************************************************************************/
366 /*****************************************************************************
368 *****************************************************************************/
369 void VLCView::MouseDown(BPoint point)
371 BWindow *win = Window();
378 /*****************************************************************************
380 *****************************************************************************/
381 static int vout_Probe ( probedata_t *p_data );
382 static int vout_Create ( struct vout_thread_s * );
383 static int vout_Init ( struct vout_thread_s * );
384 static void vout_End ( struct vout_thread_s * );
385 static void vout_Destroy ( struct vout_thread_s * );
386 static int vout_Manage ( struct vout_thread_s * );
387 static void vout_Display ( struct vout_thread_s * );
389 static int BeosOpenDisplay ( vout_thread_t *p_vout );
390 static void BeosCloseDisplay( vout_thread_t *p_vout );
392 /*****************************************************************************
393 * Functions exported as capabilities. They are declared as static so that
394 * we don't pollute the namespace too much.
395 *****************************************************************************/
396 void _M( vout_getfunctions )( function_list_t * p_function_list )
398 p_function_list->pf_probe = vout_Probe;
399 p_function_list->functions.vout.pf_create = vout_Create;
400 p_function_list->functions.vout.pf_init = vout_Init;
401 p_function_list->functions.vout.pf_end = vout_End;
402 p_function_list->functions.vout.pf_destroy = vout_Destroy;
403 p_function_list->functions.vout.pf_manage = vout_Manage;
404 p_function_list->functions.vout.pf_display = vout_Display;
405 p_function_list->functions.vout.pf_setpalette = NULL;
408 /*****************************************************************************
409 * vout_Probe: probe the video driver and return a score
410 *****************************************************************************
411 * This function tries to initialize SDL and returns a score to the
412 * plugin manager so that it can select the best plugin.
413 *****************************************************************************/
414 static int vout_Probe( probedata_t *p_data )
416 if( TestMethod( VOUT_METHOD_VAR, "beos" ) )
423 /*****************************************************************************
424 * vout_Create: allocates BeOS video thread output method
425 *****************************************************************************
426 * This function allocates and initializes a BeOS vout method.
427 *****************************************************************************/
428 int vout_Create( vout_thread_t *p_vout )
430 /* Allocate structure */
431 p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
432 if( p_vout->p_sys == NULL )
434 intf_ErrMsg( "error: %s", strerror(ENOMEM) );
438 /* force scaling off */
439 p_vout->b_scale = false;
441 /* Open and initialize device */
442 if( BeosOpenDisplay( p_vout ) )
444 intf_ErrMsg("vout error: can't open display");
445 free( p_vout->p_sys );
452 /*****************************************************************************
453 * vout_Init: initialize BeOS video thread output method
454 *****************************************************************************/
455 int vout_Init( vout_thread_t *p_vout )
457 VideoWindow * p_win = p_vout->p_sys->p_window;
459 if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
461 p_vout->pf_setbuffers( p_vout,
462 (byte_t *)p_win->bitmap[0]->Bits(),
463 (byte_t *)p_win->bitmap[1]->Bits());
468 /*****************************************************************************
469 * vout_End: terminate BeOS video thread output method
470 *****************************************************************************/
471 void vout_End( vout_thread_t *p_vout )
473 /* place code here to end the video */
476 /*****************************************************************************
477 * vout_Destroy: destroy BeOS video thread output method
478 *****************************************************************************
479 * Terminate an output method created by DummyCreateOutputMethod
480 *****************************************************************************/
481 void vout_Destroy( vout_thread_t *p_vout )
483 BeosCloseDisplay( p_vout );
484 free( p_vout->p_sys );
487 /*****************************************************************************
488 * vout_Manage: handle BeOS events
489 *****************************************************************************
490 * This function should be called regularly by video output thread. It manages
491 * console events. It returns a non null value on error.
492 *****************************************************************************/
493 int vout_Manage( vout_thread_t *p_vout )
495 VideoWindow * p_win = p_vout->p_sys->p_window;
497 p_win->resizeIfRequired(p_vout->p_buffer[p_vout->i_buffer_index].i_pic_width,
498 p_vout->p_buffer[p_vout->i_buffer_index].i_pic_height);
503 /*****************************************************************************
504 * vout_Display: displays previously rendered output
505 *****************************************************************************
506 * This function send the currently rendered image to BeOS image, waits until
507 * it is displayed and switch the two rendering buffers, preparing next frame.
508 *****************************************************************************/
509 void vout_Display( vout_thread_t *p_vout )
512 VideoWindow * p_win = p_vout->p_sys->p_window;
513 /* draw buffer if required */
514 if (!p_win->teardownwindow)
516 p_win->drawBuffer(p_vout->i_buffer_index);
519 p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
522 /* following functions are local */
524 /*****************************************************************************
525 * BeosOpenDisplay: open and initialize BeOS device
526 *****************************************************************************/
527 static int BeosOpenDisplay( vout_thread_t *p_vout )
530 VideoWindow * p_win = new VideoWindow( p_vout->i_width - 1,
531 p_vout->i_height - 1,
536 free( p_vout->p_sys );
537 intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
541 p_vout->p_sys->p_window = p_win;
542 /* set the system to 32bits always
543 let BeOS do all the work */
544 p_vout->b_YCbr = false;
545 p_vout->i_screen_depth = BITS_PER_PLANE;
546 p_vout->i_bytes_per_pixel = BYTES_PER_PIXEL;
547 p_vout->i_width = p_win->i_width + 1;
548 p_vout->i_height = p_win->i_height + 1;
549 p_vout->i_bytes_per_line = p_vout->i_width * BYTES_PER_PIXEL;
551 p_vout->i_red_mask = 0xff0000;
552 p_vout->i_green_mask = 0x00ff00;
553 p_vout->i_blue_mask = 0x0000ff;
558 /*****************************************************************************
559 * BeosDisplay: close and reset BeOS device
560 *****************************************************************************
561 * Returns all resources allocated by BeosOpenDisplay and restore the original
562 * state of the device.
563 *****************************************************************************/
564 static void BeosCloseDisplay( vout_thread_t *p_vout )
566 /* Destroy the video window */
567 delete p_vout->p_sys->p_window;