]> git.sesse.net Git - vlc/blobdiff - plugins/beos/vout_beos.cpp
* Fixed the BeOS compile typo.
[vlc] / plugins / beos / vout_beos.cpp
index 6d89bde41df0bc84965dd7968099d657ceddb9a9..44fe4b304f9972ea7c2d6395baf6d87a2da577c7 100644 (file)
@@ -2,9 +2,12 @@
  * vout_beos.cpp: beos video output display method
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
+ * $Id: vout_beos.cpp,v 1.26 2001/05/30 17:03:11 sam Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
+ *          Tony Castley <tcastley@mail.powerup.com.au>
+ *          Richard Shepherd <richard@rshepherd.demon.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +24,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+#define MODULE_NAME beos
+#include "modules_inner.h"
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
@@ -33,8 +39,9 @@
 #include <kernel/OS.h>
 #include <View.h>
 #include <Application.h>
-#include <DirectWindow.h>
+#include <Window.h>
 #include <Locker.h>
+#include <Screen.h>
 #include <malloc.h>
 #include <string.h>
 
@@ -50,13 +57,14 @@ extern "C"
 #include "video.h"
 #include "video_output.h"
 
-#include "interface.h" /* XXX maybe to remove if beos_window.h is splitted */
+#include "interface.h"
 #include "intf_msg.h"
 
 #include "main.h"
 }
 
-#include "beos_window.h"
+#include "VideoWindow.h"
+#include <Screen.h>
 
 #define WIDTH 128
 #define HEIGHT 64
@@ -113,90 +121,45 @@ BWindow *beos_GetAppWindow(char *name)
 
 int32 DrawingThread(void *data)
 {
-    uint32 i, j, y;
-    uint64 *pp, *qq;
-    uint8 *p, *q;
-    uint32 byte_width;
-    uint32 height, bytes_per_line;
-    clipping_rect *clip;
-
-    VideoWindow *w;
-    w = (VideoWindow*) data;
+  VideoWindow *w;
+  w = (VideoWindow*) data;
     
-    while(!w->fConnectionDisabled)
+  while(!w->teardownwindow)
+  {
+    if (w->Lock())
     {
-        w->locker->Lock();
-        if( w->fConnected )
+      if( w->fDirty )
+      {
+        if(w->fUsingOverlay)
         {
-            if( w->fDirty && (!w->fReady || w->i_screen_depth != w->p_vout->i_screen_depth) )
-            {
-                bytes_per_line = w->fRowBytes;
-                for( i=0 ; i < w->fNumClipRects ; i++ )
-                {
-                    clip = &(w->fClipList[i]);
-                    height = clip->bottom - clip->top +1;
-                    byte_width = w->i_bytes_per_pixel * ((clip->right - clip->left)+1);
-                    p = w->fBits + clip->top*w->fRowBytes + clip->left * w->i_bytes_per_pixel;
-                    for( y=0 ; y < height ; )
-                    {
-                        pp = (uint64*) p;
-                        for( j=0 ; j < byte_width/64 ; j++ )
-                        {
-                            *pp++ = 0;
-                            *pp++ = 0; 
-                            *pp++ = 0;
-                            *pp++ = 0; 
-                            *pp++ = 0;
-                            *pp++ = 0; 
-                            *pp++ = 0;
-                            *pp++ = 0; 
-                        }
-                        memset( pp , 0, byte_width & 63 );
-                        y++;
-                        p += bytes_per_line;
-                    }
-                }
-            }
-            else if( w->fDirty )
-            {
-                bytes_per_line = w->fRowBytes;
-                for( i=0 ; i < w->fNumClipRects ; i++ )
-                {
-                    clip = &(w->fClipList[i]);
-                    height = clip->bottom - clip->top +1;
-                    byte_width = w->i_bytes_per_pixel * ((clip->right - clip->left)+1);
-                    p = w->fBits + clip->top * bytes_per_line + clip->left * w->i_bytes_per_pixel;
-                    q = w->p_vout->p_sys->pp_buffer[ !w->p_vout->i_buffer_index ] +
-                        clip->top * w->p_vout->i_bytes_per_line + clip->left *
-                        w->p_vout->i_bytes_per_pixel;
-                    for( y=0 ; y < height ; )
-                    {
-                        pp = (uint64*) p;
-                        qq = (uint64*) q;
-                        for( j=0 ; j < byte_width/64 ; j++ )
-                        {
-                            *pp++ = *qq++;
-                            *pp++ = *qq++; 
-                            *pp++ = *qq++;
-                            *pp++ = *qq++; 
-                            *pp++ = *qq++;
-                            *pp++ = *qq++; 
-                            *pp++ = *qq++;
-                            *pp++ = *qq++; 
-                        }
-                        memcpy( pp , qq, byte_width & 63 );
-                        y++;
-                        p += bytes_per_line;
-                        q += w->p_vout->p_sys->i_width * w->p_vout->i_bytes_per_pixel;
-                    }
-                }
-            }
-            w->fDirty = false;
-        }
-        w->locker->Unlock();
-        snooze( 20000 );
-    }
-    return B_OK;
+          rgb_color key;
+           w->view->SetViewOverlay( w->bitmap[w->i_buffer_index],
+                                    w->bitmap[w->i_buffer_index]->Bounds(),
+                                    w->Bounds(),
+                                    &key,
+                                    B_FOLLOW_ALL,
+                                                   B_OVERLAY_FILTER_HORIZONTAL | B_OVERLAY_FILTER_VERTICAL
+                                                   | B_OVERLAY_TRANSFER_CHANNEL );
+           w->view->SetViewColor(key);
+         }
+         else
+         {
+           w->view->DrawBitmap( w->bitmap[w->i_buffer_index],
+                                w->bitmap[w->i_buffer_index]->Bounds(),
+                                w->Bounds());
+         }
+         
+         w->fDirty = false;
+       }
+     w->Unlock();
+   }
+   else  // we couldn't lock the window, it probably closed.
+     return B_ERROR;
+     
+   snooze (20000);
+ } // while
+
+  return B_OK;
 }
 
 /*****************************************************************************
@@ -204,31 +167,80 @@ int32 DrawingThread(void *data)
  *****************************************************************************/
 
 VideoWindow::VideoWindow(BRect frame, const char *name, vout_thread_t *p_video_output )
-        : BDirectWindow(frame, name, B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+        : BWindow(frame, name, B_TITLED_WINDOW, NULL)
 {
-    BView * view;
-
-    fReady = false;
-    fConnected = false;
-    fConnectionDisabled = false;
-    locker = new BLocker();
-    fClipList = NULL;
-    fNumClipRects = 0;
-    p_vout = p_video_output;
+       float minWidth, minHeight, maxWidth, maxHeight; 
 
-    view = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
-    view->SetViewColor(B_TRANSPARENT_32_BIT);
+    teardownwindow = false;
+    is_zoomed = false;
+    p_vout = p_video_output;
+       fDrawThreadID = NULL;
+       bitmap[0] = NULL;
+       bitmap[1] = NULL;
+       
+    rect = Frame();
+    view = new VLCView(Bounds());
     AddChild(view);
-/*
-    if(!SupportsWindowMode())
-    {
-        SetFullScreen(true);
-    }
-*/
-    fDirty = false;
-    fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
+       bitmap[0] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL, B_YCbCr422);
+       bitmap[1] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY, B_YCbCr422);
+       fUsingOverlay = true;
+       i_screen_depth = 16;
+       p_vout->b_YCbr = true;
+       
+       if ((bitmap[0]->InitCheck() != B_OK) || (bitmap[1]->InitCheck() != B_OK))
+       {
+               delete bitmap[0];
+               delete bitmap[1];
+               p_vout->b_YCbr = false;
+               fUsingOverlay = false;
+               BScreen *screen;
+               screen = new BScreen();
+               color_space space = screen->ColorSpace();
+               delete screen;
+
+               if(space == B_RGB15)
+                       {
+                       bitmap[0] = new BBitmap(Bounds(), B_RGB15);
+                       bitmap[1] = new BBitmap(Bounds(), B_RGB15);
+               i_screen_depth = 15;
+                   }
+                   else if(space == B_RGB16)
+                       {
+                       bitmap[0] = new BBitmap(Bounds(), B_RGB16);
+                       bitmap[1] = new BBitmap(Bounds(), B_RGB16);
+                       i_screen_depth = 16;
+                       }
+                       else //default to 32bpp
+                       {
+                       bitmap[0] = new BBitmap(Bounds(), B_RGB32);
+                       bitmap[1] = new BBitmap(Bounds(), B_RGB32);
+                       i_screen_depth = 32;
+                       }
+               SetTitle(VOUT_TITLE " (BBitmap output)");
+        }
+
+       if(fUsingOverlay)
+               {
+               rgb_color key;
+               view->SetViewOverlay(bitmap[0], bitmap[0]->Bounds(), Bounds(), &key, B_FOLLOW_ALL,
+                               B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL);
+               view->SetViewColor(key);
+               SetTitle(VOUT_TITLE " (Overlay output)");
+               GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 
+               SetSizeLimits((float) Bounds().IntegerWidth(), maxWidth, (float) Bounds().IntegerHeight(), maxHeight);
+               }
+//     else
+               {
+       fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
                     B_DISPLAY_PRIORITY, (void*) this);
-    resume_thread(fDrawThreadID);
+       resume_thread(fDrawThreadID);
+       }
+
+       memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
+       memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
+       i_bytes_per_pixel = bitmap[0]->BytesPerRow()/bitmap[0]->Bounds().IntegerWidth();
+    fRowBytes = bitmap[0]->BytesPerRow();
+    fDirty = false;
     Show();
 }
 
@@ -236,74 +248,49 @@ VideoWindow::~VideoWindow()
 {
     int32 result;
 
-    fConnectionDisabled = true;
     Hide();
     Sync();
-    wait_for_thread(fDrawThreadID, &result);
-    free(fClipList);
-    delete locker;
-}
+//    if(!fUsingOverlay)
+//     {
+           teardownwindow = true;
+           wait_for_thread(fDrawThreadID, &result);
+       delete bitmap[0];
+       delete bitmap[1];
+//     }
+ }
+
 
 /*****************************************************************************
- * VideoWindow::DirectConnected
+ * VideoWindow::FrameResized
  *****************************************************************************/
-
-void VideoWindow::DirectConnected(direct_buffer_info *info)
+void VideoWindow::FrameResized( float width, float height )
 {
-    unsigned int i;
-
-    if(!fConnected && fConnectionDisabled)
-    {
-        return;
-    }
-    locker->Lock();
-
-    switch(info->buffer_state & B_DIRECT_MODE_MASK)
-    {
-    case B_DIRECT_START:
-        fConnected = true;
-    case B_DIRECT_MODIFY:
-        fBits = (uint8*)((char*)info->bits +
-        (info->window_bounds.top) * info->bytes_per_row +
-        (info->window_bounds.left) * (info->bits_per_pixel>>3));;
-        
-        i_bytes_per_pixel = info->bits_per_pixel >> 3;
-        i_screen_depth = info->bits_per_pixel;
-        
-        fRowBytes = info->bytes_per_row;
-        fFormat = info->pixel_format;
-        fBounds = info->window_bounds;
-        fDirty = true;
-
-        if(fClipList)
-        {
-            free(fClipList);
-            fClipList = NULL;
-        }
-        fNumClipRects = info->clip_list_count;
-        fClipList = (clipping_rect*) malloc(fNumClipRects*sizeof(clipping_rect));
-        for( i=0 ; i<info->clip_list_count ; i++ )
-        {
-            fClipList[i].top = info->clip_list[i].top - info->window_bounds.top;
-            fClipList[i].left = info->clip_list[i].left - info->window_bounds.left;
-            fClipList[i].bottom = info->clip_list[i].bottom - info->window_bounds.top;
-            fClipList[i].right = info->clip_list[i].right - info->window_bounds.left;
-        }
-        break;
-    case B_DIRECT_STOP:
-        fConnected = false;
-        break;
-    }
-    locker->Unlock();
 }
 
 /*****************************************************************************
- * VideoWindow::FrameResized
+ * VideoWindow::Zoom
  *****************************************************************************/
 
-void VideoWindow::FrameResized( float width, float height )
+void VideoWindow::Zoom(BPoint origin, float width, float height )
 {
-    b_resized = 1;
+if(is_zoomed)
+       {
+       MoveTo(rect.left, rect.top);
+       ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
+       be_app->ShowCursor();
+       }
+else
+       {
+       rect = Frame();
+       BScreen *screen;
+       screen = new BScreen(this);
+       BRect rect = screen->Frame();
+       delete screen;
+       MoveTo(0,0);
+       ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
+       be_app->HideCursor();
+       }
+is_zoomed = !is_zoomed;
 }
 
 /*****************************************************************************
@@ -340,10 +327,39 @@ bool VideoWindow::QuitRequested()
 {
     /* FIXME: send a message ! */
     p_main->p_intf->b_die = 1;
-
+    teardownwindow = true;
     return( false );
 }
 
+/*****************************************************************************
+ * VLCView::VLCView
+ *****************************************************************************/
+VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW)
+{
+SetViewColor(B_TRANSPARENT_32_BIT);
+}
+
+/*****************************************************************************
+ * VLCView::~VLCView
+ *****************************************************************************/
+VLCView::~VLCView()
+{
+
+}
+
+/*****************************************************************************
+ * VLCVIew::~VLCView
+ *****************************************************************************/
+void VLCView::MouseDown(BPoint point)
+{
+VideoWindow *w = (VideoWindow *) Window();
+if(w->is_zoomed)
+       {
+       BWindow *win = Window();
+       win->Zoom();
+       }
+}
+
 extern "C"
 {
 
@@ -365,7 +381,7 @@ 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 vout_getfunctions( function_list_t * p_function_list )
+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;
@@ -433,30 +449,39 @@ int vout_Init( vout_thread_t *p_vout )
     VideoWindow * p_win = p_vout->p_sys->p_window;
     u32 i_page_size;
 
-    p_win->locker->Lock();
 
     i_page_size =   p_vout->i_width * p_vout->i_height * p_vout->i_bytes_per_pixel;
     
     p_vout->p_sys->i_width =         p_vout->i_width;
     p_vout->p_sys->i_height =        p_vout->i_height;    
 
-    /* Allocate memory for the 2 display buffers */
-    p_vout->p_sys->pp_buffer[0] = (byte_t*) malloc( i_page_size );
-    p_vout->p_sys->pp_buffer[1] = (byte_t*) malloc( i_page_size );
-    if( p_vout->p_sys->pp_buffer[0] == NULL  || p_vout->p_sys->pp_buffer[0] == NULL )
-    {
-        intf_ErrMsg("vout error: can't allocate video memory (%s)", strerror(errno) );
-        if( p_vout->p_sys->pp_buffer[0] != NULL ) free( p_vout->p_sys->pp_buffer[0] );
-        if( p_vout->p_sys->pp_buffer[1] != NULL ) free( p_vout->p_sys->pp_buffer[1] );
-        p_win->locker->Unlock();
-        return( 1 );
-    }
-
-    /* Set and initialize buffers */
-    vout_SetBuffers( p_vout, p_vout->p_sys->pp_buffer[0],
-                     p_vout->p_sys->pp_buffer[1] );
-
-    p_win->locker->Unlock();
+/*    if(p_win->fUsingOverlay)
+       {
+           if(p_win->bitmap[0] != NULL)
+               {
+                   p_vout->pf_setbuffers( p_vout,
+                         (byte_t *)p_win->bitmap[0]->Bits(),
+                        (byte_t *)p_win->bitmap[0]->Bits());
+               delete p_win->bitmap[0];
+               p_win->bitmap[0] = NULL;
+               }
+       }
+    else
+               {
+           if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
+               {
+               p_vout->pf_setbuffers( p_vout,
+                         (byte_t *)p_win->bitmap[0]->Bits(),
+                        (byte_t *)p_win->bitmap[1]->Bits());
+               }
+       }*/
+           if((p_win->bitmap[0] != NULL) && (p_win->bitmap[1] != NULL))
+               {
+               p_vout->pf_setbuffers( p_vout,
+                         (byte_t *)p_win->bitmap[0]->Bits(),
+                        (byte_t *)p_win->bitmap[1]->Bits());
+               }
+    
     return( 0 );
 }
 
@@ -465,15 +490,6 @@ int vout_Init( vout_thread_t *p_vout )
  *****************************************************************************/
 void vout_End( vout_thread_t *p_vout )
 {
-   VideoWindow * p_win = p_vout->p_sys->p_window;
-   
-   p_win->Lock();
-   
-   free( p_vout->p_sys->pp_buffer[0] );
-   free( p_vout->p_sys->pp_buffer[1] );
-
-   p_win->fReady = false;
-   p_win->Unlock();   
 }
 
 /*****************************************************************************
@@ -496,39 +512,44 @@ void vout_Destroy( vout_thread_t *p_vout )
  *****************************************************************************/
 int vout_Manage( vout_thread_t *p_vout )
 {
-    if( p_vout->p_sys->p_window->b_resized )
-    {
-        p_vout->p_sys->p_window->b_resized = 0;
-        p_vout->i_changes |= VOUT_SIZE_CHANGE;
-    }
+VideoWindow * p_win = p_vout->p_sys->p_window;
+rgb_color key;
+float minWidth, minHeight, maxWidth, maxHeight; 
 
-    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+if( (p_vout->i_width  != p_vout->p_sys->i_width) ||
+             (p_vout->i_height != p_vout->p_sys->i_height) )
     {
-        intf_WarnMsg( 1, "resizing window" );
-        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
-
-        /* Resize window */
-        p_vout->p_sys->p_window->ResizeTo( p_vout->i_width, p_vout->i_height );
-
-        /* Destroy XImages to change their size */
-        vout_End( p_vout );
-
-        /* Recreate XImages. If SysInit failed, the thread can't go on. */
-        if( vout_Init( p_vout ) )
-        {
-            intf_ErrMsg( "error: can't resize display" );
-            return( 1 );
-        }
-
-        /* Tell the video output thread that it will need to rebuild YUV
-         * tables. This is needed since convertion buffer size may have
-         * changed */
-        p_vout->i_changes |= VOUT_YUV_CHANGE;
-        intf_Msg( "vout: video display resized (%dx%d)",
-                  p_vout->i_width, p_vout->i_height );
-    }
-
-    return( 0 );
+        /* If video output size has changed, change interface window size */
+        intf_DbgMsg( "resizing output window" );
+        if(p_win->fUsingOverlay)
+               {
+               p_win->Lock();
+               p_win->view->ClearViewOverlay();
+               delete p_win->bitmap[0];
+               delete p_win->bitmap[1];
+               p_vout->p_sys->i_width =    p_vout->i_width;
+               p_vout->p_sys->i_height =   p_vout->i_height;;
+                       p_win->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 
+                       p_win->SetSizeLimits((float) p_vout->p_sys->i_width, maxWidth, (float) p_vout->p_sys->i_height, maxHeight);       
+               p_win->ResizeTo(p_vout->p_sys->i_width, p_vout->p_sys->i_height);
+               p_win->bitmap[0] = new BBitmap(p_win->Bounds(),
+                                               B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL,
+                                               B_YCbCr422);
+               p_win->bitmap[0] = new BBitmap(p_win->Bounds(),
+                                               B_BITMAP_WILL_OVERLAY, B_YCbCr422);
+                       memset(p_win->bitmap[0]->Bits(), 0, p_win->bitmap[0]->BitsLength());
+                       memset(p_win->bitmap[1]->Bits(), 0, p_win->bitmap[1]->BitsLength());
+                       p_win->view->SetViewOverlay(p_win->bitmap[0], p_win->bitmap[0]->Bounds(), p_win->Bounds(), &key, B_FOLLOW_ALL,
+                                       B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL|B_OVERLAY_TRANSFER_CHANNEL);
+                       p_win->view->SetViewColor(key);
+                       p_win->Unlock();
+                   p_vout->pf_setbuffers( p_vout,
+                                 (byte_t *)p_win->bitmap[0]->Bits(),
+                                (byte_t *)p_win->bitmap[0]->Bits());
+                   delete p_win->bitmap[0];
+                   }
+           }
+return( 0 );
 }
 
 /*****************************************************************************
@@ -541,11 +562,12 @@ void vout_Display( vout_thread_t *p_vout )
 {
     VideoWindow * p_win = p_vout->p_sys->p_window;
     
-    p_win->locker->Lock();
-    p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
-    p_win->fReady = true;
+       p_win->i_buffer_index = p_vout->i_buffer_index;
+       if(p_win->fUsingOverlay)
+               p_vout->i_buffer_index = p_vout->i_buffer_index & 1;
+       else
+               p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
     p_win->fDirty = true;
-    p_win->locker->Unlock();
 }
 
 /* following functions are local */
@@ -561,9 +583,8 @@ void vout_Display( vout_thread_t *p_vout )
 
 static int BeosOpenDisplay( vout_thread_t *p_vout )
 { 
-    /* Create the DirectDraw video window */
     p_vout->p_sys->p_window =
-        new VideoWindow(  BRect( 50, 150, 50+p_vout->i_width-1, 150+p_vout->i_height-1 ), VOUT_TITLE " (BeOS output) - drop a file here to play it !", p_vout );
+        new VideoWindow(  BRect( 80, 50, 80+p_vout->i_width-1, 50+p_vout->i_height-1 ), NULL, p_vout );
     if( p_vout->p_sys->p_window == 0 )
     {
         free( p_vout->p_sys );
@@ -572,10 +593,6 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
     }   
     VideoWindow * p_win = p_vout->p_sys->p_window;
     
-    /* Wait until DirectConnected has been called */
-    while( !p_win->fConnected )
-        snooze( 50000 );
-
     p_vout->i_screen_depth =         p_win->i_screen_depth;
     p_vout->i_bytes_per_pixel =      p_win->i_bytes_per_pixel;
     p_vout->i_bytes_per_line =       p_vout->i_width*p_win->i_bytes_per_pixel;
@@ -603,7 +620,6 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
         p_vout->i_blue_mask =       0x0000ff;
         break;
     }
-
     return( 0 );
 }