]> git.sesse.net Git - vlc/blobdiff - plugins/beos/vout_beos.cpp
Commited BeOS changes by Richard Shepherd and Tony Castley.
[vlc] / plugins / beos / vout_beos.cpp
index 0bcb58f1f9aa8edbfc19539bc090c7999ff82f62..1dd7c9b6c4d2ef4eb90ffde9be304bcc42e3d241 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
+ *          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
@@ -36,8 +37,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>
 
@@ -53,13 +55,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
@@ -116,88 +119,20 @@ 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;
     
-    while(!w->fConnectionDisabled)
+    while(!w->teardownwindow)
     {
-        w->locker->Lock();
-        if( w->fConnected )
-        {
-            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 )
+    w->Lock();
+       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;
-                    }
-                }
+              if(!w->fUsingOverlay)
+               w->view->DrawBitmap(w->bitmap[w->i_buffer_index], w->bitmap[w->i_buffer_index]->Bounds(), w->Bounds());
+              w->fDirty = false;
             }
-            w->fDirty = false;
-        }
-        w->locker->Unlock();
-        snooze( 20000 );
+    w->Unlock();
+       snooze(20000);
     }
     return B_OK;
 }
@@ -207,27 +142,69 @@ 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;
+       float minWidth, minHeight, maxWidth, maxHeight; 
+
+    teardownwindow = false;
+    is_zoomed = false;
     p_vout = p_video_output;
 
-    view = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
-    view->SetViewColor(B_TRANSPARENT_32_BIT);
+    rect = Frame();
+    view = new VLCView(Bounds());
     AddChild(view);
-/*
-    if(!SupportsWindowMode())
-    {
-        SetFullScreen(true);
-    }
-*/
+       bitmap[0] = new BBitmap(Bounds(), B_BITMAP_WILL_OVERLAY|B_BITMAP_RESERVE_OVERLAY_CHANNEL, B_YCbCr422);
+       fUsingOverlay = true;
+       i_screen_depth = 32;
+       p_vout->b_YCbr = true;
+       
+       if (bitmap[0]->InitCheck() != B_OK)
+       {
+               delete bitmap[0];
+               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;
+                       }
+               memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
+               memset(bitmap[1]->Bits(), 0, bitmap[1]->BitsLength());
+               SetTitle("VideoLAN (BBitmap)");
+        }
+
+       if(fUsingOverlay)
+               {
+               memset(bitmap[0]->Bits(), 0, bitmap[0]->BitsLength());
+               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("VideoLAN (Overlay)");
+               GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); 
+               SetSizeLimits((float) Bounds().IntegerWidth(), maxWidth, (float) Bounds().IntegerHeight(), maxHeight);
+               }
+
+       i_bytes_per_pixel = bitmap[0]->BytesPerRow()/bitmap[0]->Bounds().IntegerWidth();
+    fRowBytes = bitmap[0]->BytesPerRow();
     fDirty = false;
     fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
                     B_DISPLAY_PRIORITY, (void*) this);
@@ -239,74 +216,46 @@ VideoWindow::~VideoWindow()
 {
     int32 result;
 
-    fConnectionDisabled = true;
     Hide();
     Sync();
     wait_for_thread(fDrawThreadID, &result);
-    free(fClipList);
-    delete locker;
-}
+    delete bitmap[0];
+    if(!fUsingOverlay)
+       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;
 }
 
 /*****************************************************************************
@@ -343,10 +292,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"
 {
 
@@ -436,30 +414,22 @@ 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)
+       {
+           vout_SetBuffers( p_vout, (byte_t *)p_win->bitmap[0]->Bits(),
+                        (byte_t *)p_win->bitmap[0]->Bits());
+       }
+    else
+               {
+           vout_SetBuffers( p_vout, (byte_t *)p_win->bitmap[0]->Bits(),
+                        (byte_t *)p_win->bitmap[1]->Bits());
+       }
     return( 0 );
 }
 
@@ -468,15 +438,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();   
 }
 
 /*****************************************************************************
@@ -499,39 +460,7 @@ 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;
-    }
-
-    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
-    {
-        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 );
+   return( 0 );
 }
 
 /*****************************************************************************
@@ -544,11 +473,9 @@ 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;
+       p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
     p_win->fDirty = true;
-    p_win->locker->Unlock();
 }
 
 /* following functions are local */
@@ -564,9 +491,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( 50, 150, 50+p_vout->i_width-1, 150+p_vout->i_height-1 ), NULL, p_vout );
     if( p_vout->p_sys->p_window == 0 )
     {
         free( p_vout->p_sys );
@@ -575,10 +501,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;
@@ -606,7 +528,6 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
         p_vout->i_blue_mask =       0x0000ff;
         break;
     }
-
     return( 0 );
 }