]> git.sesse.net Git - vlc/blobdiff - plugins/beos/vout_beos.cpp
* ALL: new module API. Makes a few things a lot simpler, and we gain
[vlc] / plugins / beos / vout_beos.cpp
index 709f8519c7b4623a637bd288223ad8d20c93e19d..bb7724fb266b1e3e2fe1b7161673c5367345717e 100644 (file)
@@ -2,7 +2,7 @@
  * vout_beos.cpp: beos video output display method
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: vout_beos.cpp,v 1.58 2002/05/30 08:17:04 gbazin Exp $
+ * $Id: vout_beos.cpp,v 1.65 2002/07/31 20:56:50 sam Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 #include <Application.h>
 #include <Bitmap.h>
 
-extern "C"
-{
-#include <videolan/vlc.h>
-
-#include "video.h"
-#include "video_output.h"
-
-#include "interface.h"
-
-}
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+#include <vlc/vout.h>
 
 #include "VideoWindow.h"
 #include "DrawingTidbits.h"
+#include "MsgVals.h"
+
 
 /*****************************************************************************
  * vout_sys_t: BeOS video output method descriptor
@@ -56,17 +51,16 @@ extern "C"
  * This structure is part of the video output thread descriptor.
  * It describes the BeOS specific properties of an output thread.
  *****************************************************************************/
-typedef struct vout_sys_s
+struct vout_sys_t
 {
     VideoWindow *  p_window;
 
     s32 i_width;
     s32 i_height;
 
-    u8 *pp_buffer[3];
+    u32 source_chroma;
     int i_index;
-
-} vout_sys_t;
+};
 
 /*****************************************************************************
  * beos_GetAppWindow : retrieve a BWindow pointer from the window name
@@ -114,6 +108,7 @@ VideoWindow::VideoWindow( int v_width, int v_height,
     /* set the VideoWindow variables */
     teardownwindow = false;
     is_zoomed = false;
+    vsync = false;
     i_buffer = 0;
 
     /* call ScreenChanged to set vsync correctly */
@@ -133,31 +128,75 @@ VideoWindow::VideoWindow( int v_width, int v_height,
     } 
     delete screen;
     
+    mode = SelectDrawingMode(v_width, v_height);
+
     // remember current settings
-    i_width = frame.IntegerWidth();
-    i_height = frame.IntegerHeight();
-    FrameResized(frame.IntegerWidth(), frame.IntegerHeight());
+    i_width = v_width;
+    i_height = v_height;
+    FrameResized(v_width, v_height);
 
-    mode = SelectDrawingMode(v_width, v_height);
+    if (mode == OVERLAY)
+    {
+       overlay_restrictions r;
+
+       bitmap[1]->GetOverlayRestrictions(&r);
+       SetSizeLimits((i_width * r.min_width_scale) + 1, i_width * r.max_width_scale,
+                     (i_height * r.min_height_scale) + 1, i_height * r.max_height_scale);
+    }
     Show();
 }
 
 VideoWindow::~VideoWindow()
 {
-    int32 result;
-
     teardownwindow = true;
-    wait_for_thread(fDrawThreadID, &result);
     delete bitmap[0];
     delete bitmap[1];
     delete bitmap[2];
 }
 
-void VideoWindow::drawBuffer(int bufferIndex)
+void VideoWindow::MessageReceived( BMessage *p_message )
 {
-    status_t status;
+    switch( p_message->what )
+    {
+    case TOGGLE_FULL_SCREEN:
+        ((BWindow *)this)->Zoom();
+        break;
+    case RESIZE_100:
+        if (is_zoomed)
+        {
+           ((BWindow *)this)->Zoom();
+        }
+        ResizeTo(i_width, i_height);
+        break;
+    case RESIZE_200:
+        if (is_zoomed)
+        {
+           ((BWindow *)this)->Zoom();
+        }
+        ResizeTo(i_width * 2, i_height * 2);
+        break;
+    case VERT_SYNC:
+        vsync = !vsync;
+        break;
+    case WINDOW_FEEL:
+        {
+            int16 winFeel;
+            if (p_message->FindInt16("WinFeel", &winFeel) == B_OK)
+            {
+                SetFeel((window_feel)winFeel);
+            }
+        }
+        break;
+    default:
+        BWindow::MessageReceived( p_message );
+        break;
+    }
+}
 
+void VideoWindow::drawBuffer(int bufferIndex)
+{
     i_buffer = bufferIndex;
+
     // sync to the screen if required
     if (vsync)
     {
@@ -262,13 +301,6 @@ void VideoWindow::ScreenChanged(BRect frame, color_space mode)
     { 
         vsync = true; 
     } 
-    rgb_color key;
-    view->SetViewOverlay(bitmap[i_buffer], 
-                         bitmap[i_buffer]->Bounds() ,
-                         view->Bounds(),
-                         &key, B_FOLLOW_ALL,
-                         B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
-    view->SetViewColor(key);
 }
 
 void VideoWindow::WindowActivated(bool active)
@@ -278,13 +310,14 @@ void VideoWindow::WindowActivated(bool active)
 int VideoWindow::SelectDrawingMode(int width, int height)
 {
     int drawingMode = BITMAP;
+    int noOverlay = 0;
 
-    int noOverlay = !config_GetIntVariable( "overlay" );
+//    int noOverlay = !config_GetIntVariable( "overlay" );
     for (int i = 0; i < COLOR_COUNT; i++)
     {
         if (noOverlay) break;
         bitmap[0] = new BBitmap ( BRect( 0, 0, width, height ), 
-                                  B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL,
+                                  B_BITMAP_WILL_OVERLAY,
                                   colspace[i].colspace);
 
         if(bitmap[0] && bitmap[0]->InitCheck() == B_OK) 
@@ -323,7 +356,7 @@ int VideoWindow::SelectDrawingMode(int width, int height)
 
     if (drawingMode == BITMAP)
        {
-        // fallback to RGB32
+        // fallback to RGB16
         colspace_index = DEFAULT_COL;
         SetTitle(VOUT_TITLE " (Bitmap)");
         bitmap[0] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
@@ -355,8 +388,66 @@ VLCView::~VLCView()
  *****************************************************************************/
 void VLCView::MouseDown(BPoint point)
 {
-    BWindow *win = Window();
-    win->Zoom();
+    BMessage* msg = Window()->CurrentMessage();
+    int32 clicks = msg->FindInt32("clicks");
+
+    VideoWindow *vWindow = (VideoWindow *)Window();
+    uint32 mouseButtons;
+    BPoint where;
+    GetMouse(&where, &mouseButtons, true);
+
+    if ((mouseButtons & B_PRIMARY_MOUSE_BUTTON) && (clicks == 2))
+    {
+       Window()->Zoom();
+       return;
+    }
+    else
+    {
+       if (mouseButtons & B_SECONDARY_MOUSE_BUTTON) 
+       {
+           BPopUpMenu *menu = new BPopUpMenu("context menu");
+           menu->SetRadioMode(false);
+           // Toggle FullScreen
+           BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN));
+           zoomItem->SetMarked(vWindow->is_zoomed);
+           menu->AddItem(zoomItem);
+           // Resize to 100%
+           BMenuItem *origItem = new BMenuItem("100%", new BMessage(RESIZE_100));
+           menu->AddItem(origItem);
+           // Resize to 200%
+           BMenuItem *doubleItem = new BMenuItem("200%", new BMessage(RESIZE_200));
+           menu->AddItem(doubleItem);
+           menu->AddSeparatorItem();
+           // Toggle vSync
+           BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC));
+           vsyncItem->SetMarked(vWindow->vsync);
+           menu->AddItem(vsyncItem);
+           menu->AddSeparatorItem();
+
+                  // Windwo Feel Items
+                  BMessage *winNormFeel = new BMessage(WINDOW_FEEL);
+                  winNormFeel->AddInt16("WinFeel", (int16)B_NORMAL_WINDOW_FEEL);
+           BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel);
+           normWindItem->SetMarked(vWindow->Feel() == B_NORMAL_WINDOW_FEEL);
+           menu->AddItem(normWindItem);
+           
+                  BMessage *winFloatFeel = new BMessage(WINDOW_FEEL);
+                  winFloatFeel->AddInt16("WinFeel", (int16)B_MODAL_ALL_WINDOW_FEEL);
+           BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel);
+           onTopWindItem->SetMarked(vWindow->Feel() == B_MODAL_ALL_WINDOW_FEEL);
+           menu->AddItem(onTopWindItem);
+           
+                  BMessage *winAllFeel = new BMessage(WINDOW_FEEL);
+                  winAllFeel->AddInt16("WinFeel", (int16)B_FLOATING_ALL_WINDOW_FEEL);
+           BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel);
+           allSpacesWindItem->SetMarked(vWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL);
+           menu->AddItem(allSpacesWindItem);
+                  
+           menu->SetTargetForItems(this);
+           ConvertToScreen(&where);
+           menu->Go(where, true, false, true);
+        }
+       } 
 }
 
 /*****************************************************************************
@@ -369,63 +460,50 @@ void VLCView::Draw(BRect updateRect)
       FillRect(updateRect);
 }
 
-
-extern "C"
-{
-
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int  vout_Create     ( vout_thread_t * );
-static int  vout_Init       ( vout_thread_t * );
-static void vout_End        ( vout_thread_t * );
-static void vout_Destroy    ( vout_thread_t * );
-static int  vout_Manage     ( vout_thread_t * );
-static void vout_Display    ( vout_thread_t *, picture_t * );
-static void vout_Render     ( vout_thread_t *, picture_t * );
+static int  Init       ( vout_thread_t * );
+static void End        ( vout_thread_t * );
+static int  Manage     ( vout_thread_t * );
+static void Display    ( vout_thread_t *, picture_t * );
 
 static int  BeosOpenDisplay ( vout_thread_t *p_vout );
 static void BeosCloseDisplay( vout_thread_t *p_vout );
 
 /*****************************************************************************
- * Functions exported as capabilities. They are declared as static so that
- * we don't pollute the namespace too much.
- *****************************************************************************/
-void _M( vout_getfunctions )( function_list_t * p_function_list )
-{
-    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;
-    p_function_list->functions.vout.pf_destroy    = vout_Destroy;
-    p_function_list->functions.vout.pf_manage     = vout_Manage;
-    p_function_list->functions.vout.pf_display    = vout_Display;
-    p_function_list->functions.vout.pf_render     = vout_Render;
-}
-
-/*****************************************************************************
- * vout_Create: allocates BeOS video thread output method
+ * OpenVideo: allocates BeOS video thread output method
  *****************************************************************************
  * This function allocates and initializes a BeOS vout method.
  *****************************************************************************/
-int vout_Create( vout_thread_t *p_vout )
+int E_(OpenVideo) ( vlc_object_t *p_this )
 {
+    vout_thread_t * p_vout = (vout_thread_t *)p_this;
+
     /* Allocate structure */
     p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
     if( p_vout->p_sys == NULL )
     {
-        intf_ErrMsg( "error: %s", strerror(ENOMEM) );
+        msg_Err( p_vout, "out of memory" );
         return( 1 );
     }
     p_vout->p_sys->i_width = p_vout->render.i_width;
     p_vout->p_sys->i_height = p_vout->render.i_height;
+    p_vout->p_sys->source_chroma = p_vout->render.i_chroma;
+
+    p_vout->pf_init = Init;
+    p_vout->pf_end = End;
+    p_vout->pf_manage = NULL;
+    p_vout->pf_render = NULL;
+    p_vout->pf_display = Display;
 
     return( 0 );
 }
 
 /*****************************************************************************
- * vout_Init: initialize BeOS video thread output method
+ * Init: initialize BeOS video thread output method
  *****************************************************************************/
-int vout_Init( vout_thread_t *p_vout )
+int Init( vout_thread_t *p_vout )
 {
     int i_index;
     picture_t *p_pic;
@@ -435,13 +513,9 @@ int vout_Init( vout_thread_t *p_vout )
     /* Open and initialize device */
     if( BeosOpenDisplay( p_vout ) )
     {
-        intf_ErrMsg("vout error: can't open display");
+        msg_Err(p_vout, "vout error: can't open display");
         return 0;
     }
-    /* Set the buffers */
-    p_vout->p_sys->pp_buffer[0] = (u8*)p_vout->p_sys->p_window->bitmap[0]->Bits();
-    p_vout->p_sys->pp_buffer[1] = (u8*)p_vout->p_sys->p_window->bitmap[1]->Bits();
-    p_vout->p_sys->pp_buffer[2] = (u8*)p_vout->p_sys->p_window->bitmap[2]->Bits();
     p_vout->output.i_width  = p_vout->render.i_width;
     p_vout->output.i_height = p_vout->render.i_height;
 
@@ -451,6 +525,8 @@ int vout_Init( vout_thread_t *p_vout )
     p_vout->output.i_chroma = colspace[p_vout->p_sys->p_window->colspace_index].chroma;
     p_vout->p_sys->i_index = 0;
 
+    p_vout->b_direct = 1;
+
     p_vout->output.i_rmask  = 0x00ff0000;
     p_vout->output.i_gmask  = 0x0000ff00;
     p_vout->output.i_bmask  = 0x000000ff;
@@ -473,25 +549,13 @@ int vout_Init( vout_thread_t *p_vout )
        {
            return 0;
        }
-       p_pic->p->p_pixels = p_vout->p_sys->pp_buffer[0];
+       p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[buffer_index]->Bits();
        p_pic->p->i_lines = p_vout->p_sys->i_height;
 
-       p_pic->p->i_pixel_bytes = colspace[p_vout->p_sys->p_window->colspace_index].pixel_bytes;
+       p_pic->p->i_pixel_pitch = colspace[p_vout->p_sys->p_window->colspace_index].pixel_bytes;
        p_pic->i_planes = colspace[p_vout->p_sys->p_window->colspace_index].planes;
-       p_pic->p->i_pitch = p_vout->p_sys->p_window->bitmap[0]->BytesPerRow(); 
-
-       if (p_vout->p_sys->p_window->mode == OVERLAY)
-       {
-          p_pic->p->i_visible_bytes = (p_vout->p_sys->p_window->bitmap[0]->Bounds().IntegerWidth()+1) 
-                                     * p_pic->p->i_pixel_bytes; 
-          p_pic->p->b_margin = 1;
-          p_pic->p->b_hidden = 0;
-       }
-       else
-       {
-          p_pic->p->b_margin = 0;
-          p_pic->p->i_visible_bytes = p_pic->p->i_pitch;
-       }
+       p_pic->p->i_pitch = p_vout->p_sys->p_window->bitmap[buffer_index]->BytesPerRow(); 
+       p_pic->p->i_visible_pitch = p_pic->p->i_pixel_pitch * ( p_vout->p_sys->p_window->bitmap[buffer_index]->Bounds().IntegerWidth() + 1 );
 
        p_pic->i_status = DESTROYED_PICTURE;
        p_pic->i_type   = DIRECT_PICTURE;
@@ -505,50 +569,32 @@ int vout_Init( vout_thread_t *p_vout )
 }
 
 /*****************************************************************************
- * vout_End: terminate BeOS video thread output method
+ * End: terminate BeOS video thread output method
  *****************************************************************************/
-void vout_End( vout_thread_t *p_vout )
+void End( vout_thread_t *p_vout )
 {
     BeosCloseDisplay( p_vout );
 }
 
 /*****************************************************************************
- * vout_Destroy: destroy BeOS video thread output method
+ * CloseVideo: destroy BeOS video thread output method
  *****************************************************************************
  * Terminate an output method created by DummyCreateOutputMethod
  *****************************************************************************/
-void vout_Destroy( vout_thread_t *p_vout )
+void E_(CloseVideo) ( vlc_object_t *p_this )
 {
-    free( p_vout->p_sys );
-}
+    vout_thread_t * p_vout = (vout_thread_t *)p_this;
 
-/*****************************************************************************
- * vout_Manage: handle BeOS events
- *****************************************************************************
- * This function should be called regularly by video output thread. It manages
- * console events. It returns a non null value on error.
- *****************************************************************************/
-int vout_Manage( vout_thread_t *p_vout )
-{
-                          
-    return( 0 );
-}
-
-/*****************************************************************************
- * vout_Render: render previously calculated output
- *****************************************************************************/
-void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    ;
+    free( p_vout->p_sys );
 }
 
 /*****************************************************************************
- * vout_Display: displays previously rendered output
+ * Display: displays previously rendered output
  *****************************************************************************
  * This function send the currently rendered image to BeOS image, waits until
  * it is displayed and switch the two rendering buffers, preparing next frame.
  *****************************************************************************/
-void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
+void Display( vout_thread_t *p_vout, picture_t *p_pic )
 {
     VideoWindow * p_win = p_vout->p_sys->p_window;
 
@@ -559,7 +605,7 @@ void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
     }
     /* change buffer */
     p_vout->p_sys->i_index = ++p_vout->p_sys->i_index % 3;
-    p_pic->p->p_pixels = p_vout->p_sys->pp_buffer[p_vout->p_sys->i_index];
+    p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[p_vout->p_sys->i_index]->Bits();
 }
 
 /* following functions are local */
@@ -573,12 +619,12 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
     p_vout->p_sys->p_window = new VideoWindow( p_vout->p_sys->i_width - 1,
                                                p_vout->p_sys->i_height - 1,
                                                BRect( 20, 50,
-                                                      20 + p_vout->i_window_width -1, 
-                                                      50 + p_vout->i_window_height ));
+                                                      20 + p_vout->i_window_width - 1, 
+                                                      50 + p_vout->i_window_height - 1 ));
 
     if( p_vout->p_sys->p_window == NULL )
     {
-        intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
+        msg_Err( p_vout, "cannot allocate VideoWindow" );
         return( 1 );
     }   
     
@@ -602,8 +648,6 @@ static void BeosCloseDisplay( vout_thread_t *p_vout )
         p_win->Hide();
         p_win->Quit();
     }
+    p_win = NULL;
 }
 
-
-
-} /* extern "C" */