X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fbeos%2FVideoOutput.cpp;h=24a30010345e48f2d550c031d9a83c428b6f3a8e;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=9b90ef1b811af73604b42a4ee411014a113c78f5;hpb=5b9ea47e111632c29aab62f8d0a0105186d3d782;p=vlc diff --git a/modules/gui/beos/VideoOutput.cpp b/modules/gui/beos/VideoOutput.cpp index 9b90ef1b81..24a3001034 100644 --- a/modules/gui/beos/VideoOutput.cpp +++ b/modules/gui/beos/VideoOutput.cpp @@ -1,8 +1,8 @@ /***************************************************************************** * vout_beos.cpp: beos video output display method ***************************************************************************** - * Copyright (C) 2000, 2001 VideoLAN - * $Id: VideoOutput.cpp,v 1.15 2003/04/18 16:38:58 titer Exp $ + * Copyright (C) 2000, 2001 the VideoLAN team + * $Id$ * * Authors: Jean-Marc Dressler * Samuel Hocevar @@ -14,7 +14,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -22,16 +22,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ #include /* ENOMEM */ -#include /* free() */ -#include -#include /* strerror() */ #include #include @@ -47,10 +44,11 @@ /* VLC headers */ #include -#include -#include +#include +#include +#include -#include "InterfaceWindow.h" // for load/save_settings() +#include "InterfaceWindow.h" // for load/save_settings() #include "DrawingTidbits.h" #include "MsgVals.h" @@ -66,19 +64,17 @@ struct vout_sys_t { VideoWindow * p_window; - s32 i_width; - s32 i_height; + int32_t i_width; + int32_t i_height; -// u8 *pp_buffer[3]; - u32 source_chroma; +// uint8_t *pp_buffer[3]; + uint32_t source_chroma; int i_index; }; -#define MOUSE_IDLE_TIMEOUT 2000000 // two seconds -#define MIN_AUTO_VSYNC_REFRESH 61 // Hz -#define DEFAULT_SCREEN_SHOT_FORMAT 'PNG ' -#define DEFAULT_SCREEN_SHOT_PATH "/boot/home/vlc screenshot" +#define MOUSE_IDLE_TIMEOUT 2000000 // two seconds +#define MIN_AUTO_VSYNC_REFRESH 61 // Hz /***************************************************************************** * beos_GetAppWindow : retrieve a BWindow pointer from the window name @@ -86,9 +82,9 @@ struct vout_sys_t BWindow* beos_GetAppWindow(char *name) { - int32 index; + int32_t index; BWindow *window; - + for (index = 0 ; ; index++) { window = be_app->WindowAt(index); @@ -104,7 +100,60 @@ beos_GetAppWindow(char *name) window->Unlock(); } } - return window; + return window; +} + +static const int beos_keys[][2] = +{ + { B_LEFT_ARROW, KEY_LEFT }, + { B_RIGHT_ARROW, KEY_RIGHT }, + { B_UP_ARROW, KEY_UP }, + { B_DOWN_ARROW, KEY_DOWN }, + { B_SPACE, KEY_SPACE }, + { B_ENTER, KEY_ENTER }, + { B_F1_KEY, KEY_F1 }, + { B_F2_KEY, KEY_F2 }, + { B_F3_KEY, KEY_F3 }, + { B_F4_KEY, KEY_F4 }, + { B_F5_KEY, KEY_F5 }, + { B_F6_KEY, KEY_F6 }, + { B_F7_KEY, KEY_F7 }, + { B_F8_KEY, KEY_F8 }, + { B_F9_KEY, KEY_F9 }, + { B_F10_KEY, KEY_F10 }, + { B_F11_KEY, KEY_F11 }, + { B_F12_KEY, KEY_F12 }, + { B_HOME, KEY_HOME }, + { B_END, KEY_END }, + { B_ESCAPE, KEY_ESC }, + { B_PAGE_UP, KEY_PAGEUP }, + { B_PAGE_DOWN, KEY_PAGEDOWN }, + { B_TAB, KEY_TAB }, + { B_BACKSPACE, KEY_BACKSPACE } +}; + +static int ConvertKeyFromVLC( int key ) +{ + for( unsigned i = 0; i < sizeof( beos_keys ) / sizeof( int ) / 2; i++ ) + { + if( beos_keys[i][1] == key ) + { + return beos_keys[i][0]; + } + } + return key; +} + +static int ConvertKeyToVLC( int key ) +{ + for( unsigned i = 0; i < sizeof( beos_keys ) / sizeof( int ) / 2; i++ ) + { + if( beos_keys[i][0] == key ) + { + return beos_keys[i][1]; + } + } + return key; } /***************************************************************************** @@ -113,42 +162,42 @@ beos_GetAppWindow(char *name) BWindow* get_interface_window() { - return beos_GetAppWindow( "VLC " PACKAGE_VERSION ); + return beos_GetAppWindow( "VLC " PACKAGE_VERSION ); } class BackgroundView : public BView { public: - BackgroundView(BRect frame, VLCView* view) - : BView(frame, "background", - B_FOLLOW_ALL, B_FULL_UPDATE_ON_RESIZE), - fVideoView(view) - { - SetViewColor(kBlack); - } - virtual ~BackgroundView() {} - - virtual void MouseDown(BPoint where) - { - // convert coordinates - where = fVideoView->ConvertFromParent(where); - // let him handle it - fVideoView->MouseDown(where); - } - virtual void MouseMoved(BPoint where, uint32 transit, - const BMessage* dragMessage) - { - // convert coordinates - where = fVideoView->ConvertFromParent(where); - // let him handle it - fVideoView->MouseMoved(where, transit, dragMessage); - // notice: It might look like transit should be - // B_OUTSIDE_VIEW regardless, but leave it like this, - // otherwise, unwanted things will happen! - } + BackgroundView(BRect frame, VLCView* view) + : BView(frame, "background", + B_FOLLOW_ALL, B_FULL_UPDATE_ON_RESIZE), + fVideoView(view) + { + SetViewColor(kBlack); + } + virtual ~BackgroundView() {} + + virtual void MouseDown(BPoint where) + { + // convert coordinates + where = fVideoView->ConvertFromParent(where); + // let him handle it + fVideoView->MouseDown(where); + } + virtual void MouseMoved(BPoint where, uint32_t transit, + const BMessage* dragMessage) + { + // convert coordinates + where = fVideoView->ConvertFromParent(where); + // let him handle it + fVideoView->MouseMoved(where, transit, dragMessage); + // notice: It might look like transit should be + // B_OUTSIDE_VIEW regardless, but leave it like this, + // otherwise, unwanted things will happen! + } private: - VLCView* fVideoView; + VLCView* fVideoView; }; @@ -156,69 +205,65 @@ class BackgroundView : public BView * VideoSettings constructor and destructor *****************************************************************************/ VideoSettings::VideoSettings() - : fVideoSize( SIZE_100 ), - fFlags( FLAG_CORRECT_RATIO ), - fSettings( new BMessage( 'sett' ) ) + : fVideoSize( SIZE_100 ), + fFlags( FLAG_CORRECT_RATIO ), + fSettings( new BMessage( 'sett' ) ) { - // read settings from disk - status_t ret = load_settings( fSettings, "video_settings", "VideoLAN Client" ); - if ( ret == B_OK ) - { - uint32 flags; - if ( fSettings->FindInt32( "flags", (int32*)&flags ) == B_OK ) - SetFlags( flags ); - uint32 size; - if ( fSettings->FindInt32( "video size", (int32*)&size ) == B_OK ) - SetVideoSize( size ); - } - else - { - fprintf( stderr, "error loading video settings: %s\n", strerror( ret ) ); - - // figure out if we should use vertical sync by default - BScreen screen(B_MAIN_SCREEN_ID); - if (screen.IsValid()) - { - display_mode mode; - screen.GetMode(&mode); - float refresh = (mode.timing.pixel_clock * 1000) - / ((mode.timing.h_total)* (mode.timing.v_total)); - if (refresh < MIN_AUTO_VSYNC_REFRESH) - AddFlags(FLAG_SYNC_RETRACE); - } - } + // read settings from disk + status_t ret = load_settings( fSettings, "video_settings", "VideoLAN Client" ); + if ( ret == B_OK ) + { + uint32_t flags; + if ( fSettings->FindInt32( "flags", (int32*)&flags ) == B_OK ) + SetFlags( flags ); + uint32_t size; + if ( fSettings->FindInt32( "video size", (int32*)&size ) == B_OK ) + SetVideoSize( size ); + } + else + { + // figure out if we should use vertical sync by default + BScreen screen(B_MAIN_SCREEN_ID); + if (screen.IsValid()) + { + display_mode mode; + screen.GetMode(&mode); + float refresh = (mode.timing.pixel_clock * 1000) + / ((mode.timing.h_total)* (mode.timing.v_total)); + if (refresh < MIN_AUTO_VSYNC_REFRESH) + AddFlags(FLAG_SYNC_RETRACE); + } + } } VideoSettings::VideoSettings( const VideoSettings& clone ) - : fVideoSize( clone.VideoSize() ), - fFlags( clone.Flags() ), - fSettings( NULL ) + : fVideoSize( clone.VideoSize() ), + fFlags( clone.Flags() ), + fSettings( NULL ) { } VideoSettings::~VideoSettings() { - if ( fSettings ) - { - // we are the default settings - // and write our settings to disk - if (fSettings->ReplaceInt32( "video size", VideoSize() ) != B_OK) - fSettings->AddInt32( "video size", VideoSize() ); - if (fSettings->ReplaceInt32( "flags", Flags() ) != B_OK) - fSettings->AddInt32( "flags", Flags() ); - - status_t ret = save_settings( fSettings, "video_settings", "VideoLAN Client" ); - if ( ret != B_OK ) - fprintf( stderr, "error saving video settings: %s\n", strerror( ret ) ); - delete fSettings; - } - else - { - // we are just a clone of the default settings - fDefaultSettings.SetVideoSize( VideoSize() ); - fDefaultSettings.SetFlags( Flags() ); - } + if ( fSettings ) + { + // we are the default settings + // and write our settings to disk + if (fSettings->ReplaceInt32( "video size", VideoSize() ) != B_OK) + fSettings->AddInt32( "video size", VideoSize() ); + if (fSettings->ReplaceInt32( "flags", Flags() ) != B_OK) + fSettings->AddInt32( "flags", Flags() ); + + save_settings( fSettings, "video_settings", "VideoLAN Client" ); + delete fSettings; + } + else + { + // we are just a clone of the default settings + fDefaultSettings.SetVideoSize( VideoSize() ); + fDefaultSettings.SetFlags( Flags() ); + } } /***************************************************************************** @@ -227,16 +272,16 @@ VideoSettings::~VideoSettings() VideoSettings* VideoSettings::DefaultSettings() { - return &fDefaultSettings; + return &fDefaultSettings; } /***************************************************************************** * VideoSettings::SetVideoSize *****************************************************************************/ void -VideoSettings::SetVideoSize( uint32 mode ) +VideoSettings::SetVideoSize( uint32_t mode ) { - fVideoSize = mode; + fVideoSize = mode; } // static variable initialization @@ -249,49 +294,49 @@ VideoSettings::fDefaultSettings; *****************************************************************************/ VideoWindow::VideoWindow(int v_width, int v_height, BRect frame, vout_thread_t *p_videoout) - : BWindow(frame, NULL, B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_MINIMIZABLE), - i_width(frame.IntegerWidth()), - i_height(frame.IntegerHeight()), - winSize(frame), - i_buffer(0), - teardownwindow(false), - fTrueWidth(v_width), - fTrueHeight(v_height), - fCachedFeel(B_NORMAL_WINDOW_FEEL), - fInterfaceShowing(false), - fInitStatus(B_ERROR), - fSettings(new VideoSettings(*VideoSettings::DefaultSettings())) + : BWindow(frame, NULL, B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_MINIMIZABLE), + i_width(frame.IntegerWidth()), + i_height(frame.IntegerHeight()), + winSize(frame), + i_buffer(0), + teardownwindow(false), + fTrueWidth(v_width), + fTrueHeight(v_height), + fCachedFeel(B_NORMAL_WINDOW_FEEL), + fInterfaceShowing(false), + fInitStatus(B_ERROR), + fSettings(new VideoSettings(*VideoSettings::DefaultSettings())) { p_vout = p_videoout; - + // create the view to do the display view = new VLCView( Bounds(), p_vout ); - // create background view + // create background view BView *mainView = new BackgroundView( Bounds(), view ); AddChild(mainView); mainView->AddChild(view); - // allocate bitmap buffers - for (int32 i = 0; i < 3; i++) - bitmap[i] = NULL; - fInitStatus = _AllocateBuffers(v_width, v_height, &mode); + // allocate bitmap buffers + for (int32_t i = 0; i < 3; i++) + bitmap[i] = NULL; + fInitStatus = _AllocateBuffers(v_width, v_height, &mode); - // make sure we layout the view correctly + // make sure we layout the view correctly FrameResized(i_width, i_height); if (fInitStatus >= B_OK && mode == OVERLAY) { overlay_restrictions r; - bitmap[1]->GetOverlayRestrictions(&r); + bitmap[0]->GetOverlayRestrictions(&r); SetSizeLimits((i_width * r.min_width_scale), i_width * r.max_width_scale, (i_height * r.min_height_scale), i_height * r.max_height_scale); } - - // vlc settings override settings from disk - if (config_GetInt(p_vout, "fullscreen")) - fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN); + + // vlc settings override settings from disk + if (config_GetInt(p_vout, "fullscreen")) + fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN); _SetToSettings(); } @@ -303,7 +348,7 @@ VideoWindow::~VideoWindow() teardownwindow = true; wait_for_thread(fDrawThreadID, &result); _FreeBuffers(); - delete fSettings; + delete fSettings; } /***************************************************************************** @@ -312,78 +357,121 @@ VideoWindow::~VideoWindow() void VideoWindow::MessageReceived( BMessage *p_message ) { - switch( p_message->what ) - { - case TOGGLE_FULL_SCREEN: - BWindow::Zoom(); - break; - case RESIZE_50: - case RESIZE_100: - case RESIZE_200: - if (IsFullScreen()) - BWindow::Zoom(); - _SetVideoSize(p_message->what); - break; - case VERT_SYNC: - SetSyncToRetrace(!IsSyncedToRetrace()); - break; - case WINDOW_FEEL: - { - window_feel winFeel; - if (p_message->FindInt32("WinFeel", (int32*)&winFeel) == B_OK) - { - SetFeel(winFeel); - fCachedFeel = winFeel; - if (winFeel == B_FLOATING_ALL_WINDOW_FEEL) - fSettings->AddFlags(VideoSettings::FLAG_ON_TOP_ALL); - else - fSettings->ClearFlags(VideoSettings::FLAG_ON_TOP_ALL); - } - } - break; - case ASPECT_CORRECT: - SetCorrectAspectRatio(!CorrectAspectRatio()); - break; - case SCREEN_SHOT: - // save a screen shot - if ( BBitmap* current = bitmap[i_buffer] ) - { -// the following line might be tempting, but does not work for some overlay bitmaps!!! -// BBitmap* temp = new BBitmap( current ); -// so we clone the bitmap ourselves -// however, we need to take care of potentially different padding! -// memcpy() is slow when reading from grafix memory, but what the heck... - BBitmap* temp = new BBitmap( current->Bounds(), current->ColorSpace() ); - if ( temp && temp->IsValid() ) - { - int32 height = (int32)current->Bounds().Height(); - uint8* dst = (uint8*)temp->Bits(); - uint8* src = (uint8*)current->Bits(); - int32 dstBpr = temp->BytesPerRow(); - int32 srcBpr = current->BytesPerRow(); - int32 validBytes = dstBpr > srcBpr ? srcBpr : dstBpr; - for ( int32 y = 0; y < height; y++ ) - { - memcpy( dst, src, validBytes ); - dst += dstBpr; - src += srcBpr; - } - char* path = config_GetPsz( p_vout, "beos-screenshot-path" ); - if ( !path ) - path = strdup( DEFAULT_SCREEN_SHOT_PATH ); - int32 format = config_GetInt( p_vout, "beos-screenshot-format" ); - _SaveScreenShot( temp, path, format ); - } - else - { - delete temp; - } - } - break; - default: - BWindow::MessageReceived( p_message ); - break; - } + switch( p_message->what ) + { + case SHOW_INTERFACE: + SetInterfaceShowing( true ); + break; + case TOGGLE_FULL_SCREEN: + BWindow::Zoom(); + break; + case RESIZE_50: + case RESIZE_100: + case RESIZE_200: + if (IsFullScreen()) + BWindow::Zoom(); + _SetVideoSize(p_message->what); + break; + case VERT_SYNC: + SetSyncToRetrace(!IsSyncedToRetrace()); + break; + case WINDOW_FEEL: + { + window_feel winFeel; + if (p_message->FindInt32("WinFeel", (int32*)&winFeel) == B_OK) + { + SetFeel(winFeel); + fCachedFeel = winFeel; + if (winFeel == B_FLOATING_ALL_WINDOW_FEEL) + fSettings->AddFlags(VideoSettings::FLAG_ON_TOP_ALL); + else + fSettings->ClearFlags(VideoSettings::FLAG_ON_TOP_ALL); + } + } + break; + case ASPECT_CORRECT: + SetCorrectAspectRatio(!CorrectAspectRatio()); + break; + + case B_KEY_DOWN: + case B_UNMAPPED_KEY_DOWN: + case B_KEY_UP: + case B_UNMAPPED_KEY_UP: + { + key_map * keys; + char * chars; + int32 key, modifiers; + + if( p_message->FindInt32( "key", &key ) != B_OK || + p_message->FindInt32( "modifiers", &modifiers ) != B_OK ) + { + /* Shouldn't happen */ + break; + } + + if( ( p_message->what == B_KEY_UP || + p_message->what == B_UNMAPPED_KEY_UP ) && + !( modifiers & B_COMMAND_KEY ) ) + { + /* We only use the KEY_UP messages to detect Alt+X + shortcuts (because the KEY_DOWN messages aren't + sent when Alt is pressed) */ + break; + } + + /* Special case for Alt+1, Alt+2 and Alt+3 shortcuts: since + the character depends on the keymap, we use the key codes + directly (18, 19, 20) */ + if( ( modifiers & B_COMMAND_KEY ) && + key >= 18 && key <= 20 ) + { + if( key == 18 ) + PostMessage( RESIZE_50 ); + else if( key == 19 ) + PostMessage( RESIZE_100 ); + else + PostMessage( RESIZE_200 ); + + break; + } + + /* Get the current keymap */ + get_key_map( &keys, &chars ); + + if( key >= 128 || chars[keys->normal_map[key]] != 1 ) + { + /* Weird key or Unicode character */ + free( keys ); + free( chars ); + break; + } + + vlc_value_t val; + val.i_int = ConvertKeyToVLC( chars[keys->normal_map[key]+1] ); + + if( modifiers & B_COMMAND_KEY ) + { + val.i_int |= KEY_MODIFIER_ALT; + } + if( modifiers & B_SHIFT_KEY ) + { + val.i_int |= KEY_MODIFIER_SHIFT; + } + if( modifiers & B_CONTROL_KEY ) + { + val.i_int |= KEY_MODIFIER_CTRL; + } + var_Set( p_vout->p_libvlc, "key-pressed", val ); + + free( keys ); + free( chars ); + break; + } + + default: + BWindow::MessageReceived( p_message ); + break; + } } /***************************************************************************** @@ -392,18 +480,18 @@ VideoWindow::MessageReceived( BMessage *p_message ) void VideoWindow::Zoom(BPoint origin, float width, float height ) { - ToggleFullScreen(); + ToggleFullScreen(); } /***************************************************************************** * VideoWindow::FrameMoved *****************************************************************************/ void -VideoWindow::FrameMoved(BPoint origin) +VideoWindow::FrameMoved(BPoint origin) { - if (IsFullScreen()) - return ; - winSize = Frame(); + if (IsFullScreen()) + return ; + winSize = Frame(); } /***************************************************************************** @@ -412,8 +500,8 @@ VideoWindow::FrameMoved(BPoint origin) void VideoWindow::FrameResized( float width, float height ) { - int32 useWidth = CorrectAspectRatio() ? i_width : fTrueWidth; - int32 useHeight = CorrectAspectRatio() ? i_height : fTrueHeight; + int32_t useWidth = CorrectAspectRatio() ? i_width : fTrueWidth; + int32_t useHeight = CorrectAspectRatio() ? i_height : fTrueHeight; float out_width, out_height; float out_left, out_top; float width_scale = width / useWidth; @@ -423,7 +511,7 @@ VideoWindow::FrameResized( float width, float height ) { out_width = (useWidth * width_scale); out_height = (useHeight * width_scale); - out_left = 0; + out_left = 0; out_top = (height - out_height) / 2; } else /* if the height is proportionally smaller */ @@ -436,7 +524,7 @@ VideoWindow::FrameResized( float width, float height ) view->MoveTo(out_left,out_top); view->ResizeTo(out_width, out_height); - if (!IsFullScreen()) + if (!IsFullScreen()) winSize = Frame(); } @@ -446,12 +534,12 @@ VideoWindow::FrameResized( float width, float height ) void VideoWindow::ScreenChanged(BRect frame, color_space format) { - BScreen screen(this); - display_mode mode; - screen.GetMode(&mode); - float refresh = (mode.timing.pixel_clock * 1000) - / ((mode.timing.h_total) * (mode.timing.v_total)); - SetSyncToRetrace(refresh < MIN_AUTO_VSYNC_REFRESH); + BScreen screen(this); + display_mode mode; + screen.GetMode(&mode); + float refresh = (mode.timing.pixel_clock * 1000) + / ((mode.timing.h_total) * (mode.timing.v_total)); + SetSyncToRetrace(refresh < MIN_AUTO_VSYNC_REFRESH); } /***************************************************************************** @@ -482,14 +570,14 @@ VideoWindow::drawBuffer(int bufferIndex) if (mode == OVERLAY) { rgb_color key; - view->SetViewOverlay(bitmap[i_buffer], + view->SetViewOverlay(bitmap[i_buffer], bitmap[i_buffer]->Bounds() , view->Bounds(), &key, B_FOLLOW_ALL, - B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL| - B_OVERLAY_TRANSFER_CHANNEL); - view->SetViewColor(key); - } + B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL| + B_OVERLAY_TRANSFER_CHANNEL); + view->SetViewColor(key); + } else { // switch the bitmap @@ -505,7 +593,7 @@ VideoWindow::drawBuffer(int bufferIndex) void VideoWindow::ToggleInterfaceShowing() { - SetInterfaceShowing(!fInterfaceShowing); + SetInterfaceShowing(!fInterfaceShowing); } /***************************************************************************** @@ -514,24 +602,24 @@ VideoWindow::ToggleInterfaceShowing() void VideoWindow::SetInterfaceShowing(bool showIt) { - BWindow* window = get_interface_window(); - if (window) - { - if (showIt) - { - if (fCachedFeel != B_NORMAL_WINDOW_FEEL) - SetFeel(B_NORMAL_WINDOW_FEEL); - window->Activate(true); - SendBehind(window); - } - else - { - SetFeel(fCachedFeel); - Activate(true); - window->SendBehind(this); - } - fInterfaceShowing = showIt; - } + BWindow* window = get_interface_window(); + if (window) + { + if (showIt) + { + if (fCachedFeel != B_NORMAL_WINDOW_FEEL) + SetFeel(B_NORMAL_WINDOW_FEEL); + window->Activate(true); + SendBehind(window); + } + else + { + SetFeel(fCachedFeel); + Activate(true); + window->SendBehind(this); + } + fInterfaceShowing = showIt; + } } /***************************************************************************** @@ -540,14 +628,14 @@ VideoWindow::SetInterfaceShowing(bool showIt) void VideoWindow::SetCorrectAspectRatio(bool doIt) { - if (CorrectAspectRatio() != doIt) - { - if (doIt) - fSettings->AddFlags(VideoSettings::FLAG_CORRECT_RATIO); - else - fSettings->ClearFlags(VideoSettings::FLAG_CORRECT_RATIO); - FrameResized(Bounds().Width(), Bounds().Height()); - } + if (CorrectAspectRatio() != doIt) + { + if (doIt) + fSettings->AddFlags(VideoSettings::FLAG_CORRECT_RATIO); + else + fSettings->ClearFlags(VideoSettings::FLAG_CORRECT_RATIO); + FrameResized(Bounds().Width(), Bounds().Height()); + } } /***************************************************************************** @@ -556,7 +644,7 @@ VideoWindow::SetCorrectAspectRatio(bool doIt) bool VideoWindow::CorrectAspectRatio() const { - return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO); + return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO); } /***************************************************************************** @@ -565,7 +653,7 @@ VideoWindow::CorrectAspectRatio() const void VideoWindow::ToggleFullScreen() { - SetFullScreen(!IsFullScreen()); + SetFullScreen(!IsFullScreen()); } /***************************************************************************** @@ -574,25 +662,27 @@ VideoWindow::ToggleFullScreen() void VideoWindow::SetFullScreen(bool doIt) { - if (doIt) - { - BScreen screen(this); - BRect rect = screen.Frame(); - Activate(); - MoveTo(0.0, 0.0); - ResizeTo(rect.IntegerWidth(), rect.IntegerHeight()); - be_app->ObscureCursor(); - fInterfaceShowing = false; - fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN); - } - else - { - MoveTo(winSize.left, winSize.top); - ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight()); - be_app->ShowCursor(); - fInterfaceShowing = true; - fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN); - } + if (doIt) + { + SetLook( B_NO_BORDER_WINDOW_LOOK ); + BScreen screen( this ); + BRect rect = screen.Frame(); + Activate(); + MoveTo(0.0, 0.0); + ResizeTo(rect.IntegerWidth(), rect.IntegerHeight()); + be_app->ObscureCursor(); + fInterfaceShowing = false; + fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN); + } + else + { + SetLook( B_TITLED_WINDOW_LOOK ); + MoveTo(winSize.left, winSize.top); + ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight()); + be_app->ShowCursor(); + fInterfaceShowing = true; + fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN); + } } /***************************************************************************** @@ -601,7 +691,7 @@ VideoWindow::SetFullScreen(bool doIt) bool VideoWindow::IsFullScreen() const { - return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN); + return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN); } /***************************************************************************** @@ -610,10 +700,10 @@ VideoWindow::IsFullScreen() const void VideoWindow::SetSyncToRetrace(bool doIt) { - if (doIt) - fSettings->AddFlags(VideoSettings::FLAG_SYNC_RETRACE); - else - fSettings->ClearFlags(VideoSettings::FLAG_SYNC_RETRACE); + if (doIt) + fSettings->AddFlags(VideoSettings::FLAG_SYNC_RETRACE); + else + fSettings->ClearFlags(VideoSettings::FLAG_SYNC_RETRACE); } /***************************************************************************** @@ -622,7 +712,7 @@ VideoWindow::SetSyncToRetrace(bool doIt) bool VideoWindow::IsSyncedToRetrace() const { - return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE); + return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE); } @@ -632,77 +722,99 @@ VideoWindow::IsSyncedToRetrace() const status_t VideoWindow::_AllocateBuffers(int width, int height, int* mode) { - // clear any old buffers - _FreeBuffers(); - // set default mode - *mode = BITMAP; + // clear any old buffers + _FreeBuffers(); + // set default mode + *mode = BITMAP; + bitmap_count = 3; - BRect bitmapFrame( 0, 0, width, height ); - // read from config, if we are supposed to use overlay at all + BRect bitmapFrame( 0, 0, width, height ); + // read from config, if we are supposed to use overlay at all int noOverlay = !config_GetInt( p_vout, "overlay" ); - // test for overlay capability - for (int i = 0; i < COLOR_COUNT; i++) + + /* Test for overlay capability: for every chroma in colspace, + we try to do double-buffered overlay, single-buffered overlay + or basic overlay. If nothing worked, we then have to work with + a non-overlay BBitmap. */ + for( int i = 0; i < COLOR_COUNT; i++ ) { - if (noOverlay) break; - bitmap[0] = new BBitmap ( bitmapFrame, - B_BITMAP_WILL_OVERLAY | - B_BITMAP_RESERVE_OVERLAY_CHANNEL, - colspace[i].colspace); + if( noOverlay ) + break; - if(bitmap[0] && bitmap[0]->InitCheck() == B_OK) + bitmap[0] = new BBitmap( bitmapFrame, + B_BITMAP_WILL_OVERLAY | + B_BITMAP_RESERVE_OVERLAY_CHANNEL, + colspace[i].colspace ); + if( bitmap[0] && bitmap[0]->InitCheck() == B_OK ) { colspace_index = i; + *mode = OVERLAY; + rgb_color key; + view->SetViewOverlay( bitmap[0], bitmap[0]->Bounds(), + view->Bounds(), &key, B_FOLLOW_ALL, + B_OVERLAY_FILTER_HORIZONTAL | + B_OVERLAY_FILTER_VERTICAL ); + view->SetViewColor( key ); + SetTitle( "VLC " PACKAGE_VERSION " (Overlay)" ); + bitmap[1] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY, colspace[colspace_index].colspace); - bitmap[2] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY, - colspace[colspace_index].colspace); - if ( (bitmap[2] && bitmap[2]->InitCheck() == B_OK) ) + if( bitmap[1] && bitmap[1]->InitCheck() == B_OK ) { - *mode = OVERLAY; - rgb_color key; - view->SetViewOverlay(bitmap[0], - bitmap[0]->Bounds() , - view->Bounds(), - &key, B_FOLLOW_ALL, - B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL); - view->SetViewColor(key); - SetTitle("VLC " PACKAGE_VERSION " (Overlay)"); - break; + + bitmap[2] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY, + colspace[colspace_index].colspace); + if( bitmap[2] && bitmap[2]->InitCheck() == B_OK ) + { + msg_Dbg( p_vout, "using double-buffered overlay" ); + } + else + { + msg_Dbg( p_vout, "using single-buffered overlay" ); + bitmap_count = 2; + if( bitmap[2] ) { delete bitmap[2]; bitmap[2] = NULL; } + } } else { - _FreeBuffers(); - *mode = BITMAP; // might want to try again with normal bitmaps + msg_Dbg( p_vout, "using simple overlay" ); + bitmap_count = 1; + if( bitmap[1] ) { delete bitmap[1]; bitmap[1] = NULL; } } + break; } else - delete bitmap[0]; - } + { + if( bitmap[0] ) { delete bitmap[0]; bitmap[0] = NULL; } + } + } if (*mode == BITMAP) - { + { + msg_Warn( p_vout, "no possible overlay" ); + // fallback to RGB - colspace_index = DEFAULT_COL; // B_RGB32 - SetTitle( "VLC " PACKAGE_VERSION " (Bitmap)" ); + colspace_index = DEFAULT_COL; // B_RGB32 bitmap[0] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace ); bitmap[1] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace ); bitmap[2] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace ); + SetTitle( "VLC " PACKAGE_VERSION " (Bitmap)" ); } // see if everything went well status_t status = B_ERROR; - for (int32 i = 0; i < 3; i++) + for (int32_t i = 0; i < bitmap_count; i++) { - if (bitmap[i]) - status = bitmap[i]->InitCheck(); - if (status < B_OK) - break; + if (bitmap[i]) + status = bitmap[i]->InitCheck(); + if (status < B_OK) + break; } if (status >= B_OK) { - // clear bitmaps to black - for (int32 i = 0; i < 3; i++) - _BlankBitmap(bitmap[i]); + // clear bitmaps to black + for (int32_t i = 0; i < bitmap_count; i++) + _BlankBitmap(bitmap[i]); } return status; } @@ -713,13 +825,10 @@ VideoWindow::_AllocateBuffers(int width, int height, int* mode) void VideoWindow::_FreeBuffers() { - delete bitmap[0]; - bitmap[0] = NULL; - delete bitmap[1]; - bitmap[1] = NULL; - delete bitmap[2]; - bitmap[2] = NULL; - fInitStatus = B_ERROR; + if( bitmap[0] ) { delete bitmap[0]; bitmap[0] = NULL; } + if( bitmap[1] ) { delete bitmap[1]; bitmap[1] = NULL; } + if( bitmap[2] ) { delete bitmap[2]; bitmap[2] = NULL; } + fInitStatus = B_ERROR; } /***************************************************************************** @@ -728,102 +837,102 @@ VideoWindow::_FreeBuffers() void VideoWindow::_BlankBitmap(BBitmap* bitmap) const { - // no error checking (we do that earlier on and since it's a private function... - - // YCbCr: - // Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128) - - // YUV: - // Extrema points are Y 0 - 207 (absolute) U -91 - 91 (offset 128) V -127 - 127 (offset 128) - - // we only handle weird colorspaces with special care - switch (bitmap->ColorSpace()) { - case B_YCbCr422: { - // Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0] Y2[7:0] Cb2[7:0] Y3[7:0] Cr2[7:0] - int32 height = bitmap->Bounds().IntegerHeight() + 1; - uint8* bits = (uint8*)bitmap->Bits(); - int32 bpr = bitmap->BytesPerRow(); - for (int32 y = 0; y < height; y++) { - // handle 2 bytes at a time - for (int32 i = 0; i < bpr; i += 2) { - // offset into line - bits[i] = 16; - bits[i + 1] = 128; - } - // next line - bits += bpr; - } - break; - } - case B_YCbCr420: { + // no error checking (we do that earlier on and since it's a private function... + + // YCbCr: + // Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128) + + // YUV: + // Extrema points are Y 0 - 207 (absolute) U -91 - 91 (offset 128) V -127 - 127 (offset 128) + + // we only handle weird colorspaces with special care + switch (bitmap->ColorSpace()) { + case B_YCbCr422: { + // Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0] Y2[7:0] Cb2[7:0] Y3[7:0] Cr2[7:0] + int32_t height = bitmap->Bounds().IntegerHeight() + 1; + uint8_t* bits = (uint8_t*)bitmap->Bits(); + int32_t bpr = bitmap->BytesPerRow(); + for (int32_t y = 0; y < height; y++) { + // handle 2 bytes at a time + for (int32_t i = 0; i < bpr; i += 2) { + // offset into line + bits[i] = 16; + bits[i + 1] = 128; + } + // next line + bits += bpr; + } + break; + } + case B_YCbCr420: { // TODO: untested!! - // Non-interlaced only, Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ... - // Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines - int32 height = bitmap->Bounds().IntegerHeight() + 1; - uint8* bits = (uint8*)bitmap->Bits(); - int32 bpr = bitmap->BytesPerRow(); - for (int32 y = 0; y < height; y += 1) { - // handle 3 bytes at a time - for (int32 i = 0; i < bpr; i += 3) { - // offset into line - bits[i] = 128; - bits[i + 1] = 16; - bits[i + 2] = 16; - } - // next line - bits += bpr; - } - break; - } - case B_YUV422: { + // Non-interlaced only, Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ... + // Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines + int32_t height = bitmap->Bounds().IntegerHeight() + 1; + uint8_t* bits = (uint8_t*)bitmap->Bits(); + int32_t bpr = bitmap->BytesPerRow(); + for (int32_t y = 0; y < height; y += 1) { + // handle 3 bytes at a time + for (int32_t i = 0; i < bpr; i += 3) { + // offset into line + bits[i] = 128; + bits[i + 1] = 16; + bits[i + 2] = 16; + } + // next line + bits += bpr; + } + break; + } + case B_YUV422: { // TODO: untested!! - // U0[7:0] Y0[7:0] V0[7:0] Y1[7:0] U2[7:0] Y2[7:0] V2[7:0] Y3[7:0] - int32 height = bitmap->Bounds().IntegerHeight() + 1; - uint8* bits = (uint8*)bitmap->Bits(); - int32 bpr = bitmap->BytesPerRow(); - for (int32 y = 0; y < height; y += 1) { - // handle 2 bytes at a time - for (int32 i = 0; i < bpr; i += 2) { - // offset into line - bits[i] = 128; - bits[i + 1] = 0; - } - // next line - bits += bpr; - } - break; - } - default: - memset(bitmap->Bits(), 0, bitmap->BitsLength()); - break; - } + // U0[7:0] Y0[7:0] V0[7:0] Y1[7:0] U2[7:0] Y2[7:0] V2[7:0] Y3[7:0] + int32_t height = bitmap->Bounds().IntegerHeight() + 1; + uint8_t* bits = (uint8_t*)bitmap->Bits(); + int32_t bpr = bitmap->BytesPerRow(); + for (int32_t y = 0; y < height; y += 1) { + // handle 2 bytes at a time + for (int32_t i = 0; i < bpr; i += 2) { + // offset into line + bits[i] = 128; + bits[i + 1] = 0; + } + // next line + bits += bpr; + } + break; + } + default: + memset(bitmap->Bits(), 0, bitmap->BitsLength()); + break; + } } /***************************************************************************** * VideoWindow::_SetVideoSize *****************************************************************************/ void -VideoWindow::_SetVideoSize(uint32 mode) +VideoWindow::_SetVideoSize(uint32_t mode) { - // let size depend on aspect correction - int32 width = CorrectAspectRatio() ? i_width : fTrueWidth; - int32 height = CorrectAspectRatio() ? i_height : fTrueHeight; - switch (mode) - { - case RESIZE_50: - width /= 2; - height /= 2; - break; - case RESIZE_200: - width *= 2; - height *= 2; - break; - case RESIZE_100: - default: - break; - } - fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN); - ResizeTo(width, height); + // let size depend on aspect correction + int32_t width = CorrectAspectRatio() ? i_width : fTrueWidth; + int32_t height = CorrectAspectRatio() ? i_height : fTrueHeight; + switch (mode) + { + case RESIZE_50: + width /= 2; + height /= 2; + break; + case RESIZE_200: + width *= 2; + height *= 2; + break; + case RESIZE_100: + default: + break; + } + fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN); + ResizeTo(width, height); } /***************************************************************************** @@ -832,228 +941,43 @@ VideoWindow::_SetVideoSize(uint32 mode) void VideoWindow::_SetToSettings() { - // adjust dimensions - uint32 mode = RESIZE_100; - switch (fSettings->VideoSize()) - { - case VideoSettings::SIZE_50: - mode = RESIZE_50; - break; - case VideoSettings::SIZE_200: - mode = RESIZE_200; - break; - case VideoSettings::SIZE_100: - case VideoSettings::SIZE_OTHER: - default: - break; - } - bool fullscreen = IsFullScreen(); // remember settings - _SetVideoSize(mode); // because this will reset settings - // the fullscreen status is reflected in the settings, - // but not yet in the windows state - if (fullscreen) - SetFullScreen(true); - if (fSettings->HasFlags(VideoSettings::FLAG_ON_TOP_ALL)) - fCachedFeel = B_FLOATING_ALL_WINDOW_FEEL; - else - fCachedFeel = B_NORMAL_WINDOW_FEEL; - SetFeel(fCachedFeel); -} - -/***************************************************************************** - * VideoWindow::_SaveScreenShot - *****************************************************************************/ -void -VideoWindow::_SaveScreenShot( BBitmap* bitmap, char* path, - uint32 translatorID ) const -{ - // make the info object from the parameters - screen_shot_info* info = new screen_shot_info; - info->bitmap = bitmap; - info->path = path; - info->translatorID = translatorID; - info->width = CorrectAspectRatio() ? i_width : fTrueWidth; - info->height = CorrectAspectRatio() ? i_height : fTrueHeight; - // spawn a new thread to take care of the actual saving to disk - thread_id thread = spawn_thread( _save_screen_shot, - "screen shot saver", - B_LOW_PRIORITY, (void*)info ); - // start thread or do the job ourself if something went wrong - if ( thread < B_OK || resume_thread( thread ) < B_OK ) - _save_screen_shot( (void*)info ); -} - -/***************************************************************************** - * VideoWindow::_save_screen_shot - *****************************************************************************/ -int32 -VideoWindow::_save_screen_shot( void* cookie ) -{ - screen_shot_info* info = (screen_shot_info*)cookie; - if ( info && info->bitmap && info->bitmap->IsValid() && info->path ) - { - // try to be as quick as possible creating the file (the user might have - // taken the next screen shot already!) - // make sure we have a unique name for the screen shot - BString path( info->path ); - // create the folder if it doesn't exist - BString folder( info->path ); - int32 pos = folder.FindLast("/"); - if ( pos > 0 ) - { - pos++; // leave the last '/' in the string - if ( pos == path.Length() ) - path << "vlc screenshot"; - else - { - int32 removeChars = folder.Length() - pos; - folder.Remove( pos, removeChars ); - } - create_directory( folder.String(), 0777 ); - } - BEntry entry( path.String() ); - int32 appendedNumber = 0; - if ( entry.Exists() && !entry.IsSymLink() ) - { - // we would clobber an existing entry - bool foundUniqueName = false; - appendedNumber = 1; - while ( !foundUniqueName ) { - BString newName( path.String() ); - newName << " " << appendedNumber; - BEntry possiblyClobberedEntry( newName.String() ); - if ( possiblyClobberedEntry.Exists() - && !possiblyClobberedEntry.IsSymLink() ) - appendedNumber++; - else - foundUniqueName = true; - } - } - if ( appendedNumber > 0 ) - path << " " << appendedNumber; - // there is still a slight chance to clobber an existing - // file (if it was created in the "meantime"), but we take it... - BFile outFile( path.String(), - B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE ); - - // make colorspace converted copy of bitmap - BBitmap* converted = new BBitmap( BRect( 0.0, 0.0, info->width, info->height ), - B_RGB32 ); - status_t status = convert_bitmap( info->bitmap, converted ); - if ( status == B_OK ) - { - BTranslatorRoster* roster = BTranslatorRoster::Default(); - uint32 imageFormat = 0; - translator_id translator = 0; - bool found = false; - - // find suitable translator - translator_id* ids = NULL; - int32 count = 0; - - status = roster->GetAllTranslators( &ids, &count ); - if ( status >= B_OK ) - { - for ( int tix = 0; tix < count; tix++ ) - { - const translation_format *formats = NULL; - int32 num_formats = 0; - bool ok = false; - status = roster->GetInputFormats( ids[tix], - &formats, &num_formats ); - if (status >= B_OK) - { - for ( int iix = 0; iix < num_formats; iix++ ) - { - if ( formats[iix].type == B_TRANSLATOR_BITMAP ) - { - ok = true; - break; - } - } - } - if ( !ok ) - continue; - status = roster->GetOutputFormats( ids[tix], - &formats, &num_formats); - if ( status >= B_OK ) - { - for ( int32 oix = 0; oix < num_formats; oix++ ) - { - if ( formats[oix].type != B_TRANSLATOR_BITMAP ) - { - if ( formats[oix].type == info->translatorID ) - { - found = true; - imageFormat = formats[oix].type; - translator = ids[tix]; - break; - } - } - } - } - } - } - delete[] ids; - if ( found ) - { - // make bitmap stream - BBitmapStream outStream( converted ); - - status = outFile.InitCheck(); - if (status == B_OK) { - status = roster->Translate( &outStream, NULL, NULL, - &outFile, imageFormat ); - if ( status == B_OK ) - { - BNodeInfo nodeInfo( &outFile ); - if ( nodeInfo.InitCheck() == B_OK ) - { - translation_format* formats; - int32 count; - status = roster->GetOutputFormats( translator, - (const translation_format **) &formats, - &count); - if ( status >= B_OK ) - { - const char * mime = NULL; - for ( int ix = 0; ix < count; ix++ ) { - if ( formats[ix].type == imageFormat ) { - mime = formats[ix].MIME; - break; - } - } - if ( mime ) - nodeInfo.SetType( mime ); - } - } - } - } - outStream.DetachBitmap( &converted ); - outFile.Unset(); - } - } - delete converted; - } - if ( info ) - { - delete info->bitmap; - free( info->path ); - } - delete info; - return B_OK; + // adjust dimensions + uint32_t mode = RESIZE_100; + switch (fSettings->VideoSize()) + { + case VideoSettings::SIZE_50: + mode = RESIZE_50; + break; + case VideoSettings::SIZE_200: + mode = RESIZE_200; + break; + case VideoSettings::SIZE_100: + case VideoSettings::SIZE_OTHER: + default: + break; + } + bool fullscreen = IsFullScreen(); // remember settings + _SetVideoSize(mode); // because this will reset settings + // the fullscreen status is reflected in the settings, + // but not yet in the windows state + if (fullscreen) + SetFullScreen(true); + if (fSettings->HasFlags(VideoSettings::FLAG_ON_TOP_ALL)) + fCachedFeel = B_FLOATING_ALL_WINDOW_FEEL; + else + fCachedFeel = B_NORMAL_WINDOW_FEEL; + SetFeel(fCachedFeel); } - /***************************************************************************** * VLCView::VLCView *****************************************************************************/ VLCView::VLCView(BRect bounds, vout_thread_t *p_vout_instance ) - : BView(bounds, "video view", B_FOLLOW_NONE, B_WILL_DRAW | B_PULSE_NEEDED), - fLastMouseMovedTime(system_time()), - fCursorHidden(false), - fCursorInside(false), - fIgnoreDoubleClick(false) + : BView(bounds, "video view", B_FOLLOW_NONE, B_WILL_DRAW | B_PULSE_NEEDED), + fLastMouseMovedTime(mdate()), + fCursorHidden(false), + fCursorInside(false), + fIgnoreDoubleClick(false) { p_vout = p_vout_instance; SetViewColor(B_TRANSPARENT_32_BIT); @@ -1072,10 +996,8 @@ VLCView::~VLCView() void VLCView::AttachedToWindow() { - // in order to get keyboard events - MakeFocus(true); - // periodically check if we want to hide the pointer - Window()->SetPulseRate(1000000); + // periodically check if we want to hide the pointer + Window()->SetPulseRate(1000000); } /***************************************************************************** @@ -1084,102 +1006,111 @@ VLCView::AttachedToWindow() void VLCView::MouseDown(BPoint where) { - VideoWindow* videoWindow = dynamic_cast(Window()); - BMessage* msg = Window()->CurrentMessage(); - int32 clicks; - uint32 buttons; - msg->FindInt32("clicks", &clicks); - msg->FindInt32("buttons", (int32*)&buttons); - - if (videoWindow) - { - if (buttons & B_PRIMARY_MOUSE_BUTTON) - { - if (clicks == 2 && !fIgnoreDoubleClick) - Window()->Zoom(); - /* else - videoWindow->ToggleInterfaceShowing(); */ - fIgnoreDoubleClick = false; - } - else - { - if (buttons & B_SECONDARY_MOUSE_BUTTON) - { - // clicks will be 2 next time (if interval short enough) - // even if the first click and the second - // have not been made with the same mouse button - fIgnoreDoubleClick = true; - // launch popup menu - BPopUpMenu *menu = new BPopUpMenu("context menu"); - menu->SetRadioMode(false); - // Resize to 50% - BMenuItem *halfItem = new BMenuItem("50%", new BMessage(RESIZE_50)); - menu->AddItem(halfItem); - // 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); - // Toggle FullScreen - BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN)); - zoomItem->SetMarked(videoWindow->IsFullScreen()); - menu->AddItem(zoomItem); - - menu->AddSeparatorItem(); - - // Toggle vSync - BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC)); - vsyncItem->SetMarked(videoWindow->IsSyncedToRetrace()); - menu->AddItem(vsyncItem); - // Correct Aspect Ratio - BMenuItem *aspectItem = new BMenuItem("Correct Aspect Ratio", new BMessage(ASPECT_CORRECT)); - aspectItem->SetMarked(videoWindow->CorrectAspectRatio()); - menu->AddItem(aspectItem); - - menu->AddSeparatorItem(); - - // Windwo Feel Items -/* BMessage *winNormFeel = new BMessage(WINDOW_FEEL); - winNormFeel->AddInt32("WinFeel", (int32)B_NORMAL_WINDOW_FEEL); - BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel); - normWindItem->SetMarked(videoWindow->Feel() == B_NORMAL_WINDOW_FEEL); - menu->AddItem(normWindItem); - - BMessage *winFloatFeel = new BMessage(WINDOW_FEEL); - winFloatFeel->AddInt32("WinFeel", (int32)B_FLOATING_APP_WINDOW_FEEL); - BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel); - onTopWindItem->SetMarked(videoWindow->Feel() == B_FLOATING_APP_WINDOW_FEEL); - menu->AddItem(onTopWindItem); - - BMessage *winAllFeel = new BMessage(WINDOW_FEEL); - winAllFeel->AddInt32("WinFeel", (int32)B_FLOATING_ALL_WINDOW_FEEL); - BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel); - allSpacesWindItem->SetMarked(videoWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL); - menu->AddItem(allSpacesWindItem);*/ - - BMessage *windowFeelMsg = new BMessage( WINDOW_FEEL ); - bool onTop = videoWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL; - window_feel feel = onTop ? B_NORMAL_WINDOW_FEEL : B_FLOATING_ALL_WINDOW_FEEL; - windowFeelMsg->AddInt32( "WinFeel", (int32)feel ); - BMenuItem *windowFeelItem = new BMenuItem( "Stay On Top", windowFeelMsg ); - windowFeelItem->SetMarked( onTop ); - menu->AddItem( windowFeelItem ); - - menu->AddSeparatorItem(); - - BMenuItem* screenShotItem = new BMenuItem( "Take Screen Shot", - new BMessage( SCREEN_SHOT ) ); - menu->AddItem( screenShotItem ); - - menu->SetTargetForItems( this ); - ConvertToScreen( &where ); - menu->Go( where, true, false, true ); - } - } - } - fLastMouseMovedTime = system_time(); - fCursorHidden = false; + VideoWindow* videoWindow = dynamic_cast(Window()); + BMessage* msg = Window()->CurrentMessage(); + int32 clicks; + uint32_t buttons; + msg->FindInt32("clicks", &clicks); + msg->FindInt32("buttons", (int32*)&buttons); + + if (videoWindow) + { + if (buttons & B_PRIMARY_MOUSE_BUTTON) + { + if (clicks == 2 && !fIgnoreDoubleClick) + Window()->Zoom(); + /* else + videoWindow->ToggleInterfaceShowing(); */ + fIgnoreDoubleClick = false; + } + else + { + if (buttons & B_SECONDARY_MOUSE_BUTTON) + { + // clicks will be 2 next time (if interval short enough) + // even if the first click and the second + // have not been made with the same mouse button + fIgnoreDoubleClick = true; + // launch popup menu + BPopUpMenu *menu = new BPopUpMenu("context menu"); + menu->SetRadioMode(false); + // In full screen, add an item to show/hide the interface + if( videoWindow->IsFullScreen() ) + { + BMenuItem *intfItem = + new BMenuItem( _("Show Interface"), new BMessage(SHOW_INTERFACE) ); + menu->AddItem( intfItem ); + } + // Resize to 50% + BMenuItem *halfItem = new BMenuItem(_("50%"), new BMessage(RESIZE_50)); + menu->AddItem(halfItem); + // 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); + // Toggle FullScreen + BMenuItem *zoomItem = new BMenuItem(_("Fullscreen"), new BMessage(TOGGLE_FULL_SCREEN)); + zoomItem->SetMarked(videoWindow->IsFullScreen()); + menu->AddItem(zoomItem); + + menu->AddSeparatorItem(); + + // Toggle vSync + BMenuItem *vsyncItem = new BMenuItem(_("Vertical Sync"), new BMessage(VERT_SYNC)); + vsyncItem->SetMarked(videoWindow->IsSyncedToRetrace()); + menu->AddItem(vsyncItem); + // Correct Aspect Ratio + BMenuItem *aspectItem = new BMenuItem(_("Correct Aspect Ratio"), new BMessage(ASPECT_CORRECT)); + aspectItem->SetMarked(videoWindow->CorrectAspectRatio()); + menu->AddItem(aspectItem); + + menu->AddSeparatorItem(); + + // Window Feel Items +/* BMessage *winNormFeel = new BMessage(WINDOW_FEEL); + winNormFeel->AddInt32("WinFeel", (int32_t)B_NORMAL_WINDOW_FEEL); + BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel); + normWindItem->SetMarked(videoWindow->Feel() == B_NORMAL_WINDOW_FEEL); + menu->AddItem(normWindItem); + + BMessage *winFloatFeel = new BMessage(WINDOW_FEEL); + winFloatFeel->AddInt32("WinFeel", (int32_t)B_FLOATING_APP_WINDOW_FEEL); + BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel); + onTopWindItem->SetMarked(videoWindow->Feel() == B_FLOATING_APP_WINDOW_FEEL); + menu->AddItem(onTopWindItem); + + BMessage *winAllFeel = new BMessage(WINDOW_FEEL); + winAllFeel->AddInt32("WinFeel", (int32_t)B_FLOATING_ALL_WINDOW_FEEL); + BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel); + allSpacesWindItem->SetMarked(videoWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL); + menu->AddItem(allSpacesWindItem);*/ + + BMessage *windowFeelMsg = new BMessage( WINDOW_FEEL ); + bool onTop = videoWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL; + window_feel feel = onTop ? B_NORMAL_WINDOW_FEEL : B_FLOATING_ALL_WINDOW_FEEL; + windowFeelMsg->AddInt32( "WinFeel", (int32_t)feel ); + BMenuItem *windowFeelItem = new BMenuItem( _("Stay On Top"), windowFeelMsg ); + windowFeelItem->SetMarked( onTop ); + menu->AddItem( windowFeelItem ); + + menu->AddSeparatorItem(); + + BMenuItem* screenShotItem = new BMenuItem( _("Take Screen Shot"), + new BMessage( SCREEN_SHOT ) ); + menu->AddItem( screenShotItem ); + + menu->SetTargetForItems( this ); + ConvertToScreen( &where ); + BRect mouseRect( where.x - 5, where.y - 5, + where.x + 5, where.y + 5 ); + menu->Go( where, true, false, mouseRect, true ); + } + } + } + fLastMouseMovedTime = mdate(); + fCursorHidden = false; } /***************************************************************************** @@ -1199,140 +1130,74 @@ VLCView::MouseUp( BPoint where ) void VLCView::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage) { - fLastMouseMovedTime = system_time(); - fCursorHidden = false; - fCursorInside = (transit == B_INSIDE_VIEW || transit == B_ENTERED_VIEW); - /* DVD navigation */ - unsigned int i_width, i_height, i_x, i_y; + fLastMouseMovedTime = mdate(); + fCursorHidden = false; + fCursorInside = ( transit == B_INSIDE_VIEW || transit == B_ENTERED_VIEW ); + + if( !fCursorInside ) + { + return; + } + + vlc_value_t val; + unsigned int i_width, i_height, i_x, i_y; vout_PlacePicture( p_vout, (unsigned int)Bounds().Width(), (unsigned int)Bounds().Height(), &i_x, &i_y, &i_width, &i_height ); - vlc_value_t val; - val.i_int = ( (int)point.x - i_x ) * p_vout->render.i_width / i_width; - var_Set( p_vout, "mouse-x", val ); - val.i_int = ( (int)point.y - i_y ) * p_vout->render.i_height / i_height; - var_Set( p_vout, "mouse-y", val ); - val.b_bool = VLC_TRUE; + val.i_int = ( (int)point.x - i_x ) * p_vout->render.i_width / i_width; + var_Set( p_vout, "mouse-x", val ); + val.i_int = ( (int)point.y - i_y ) * p_vout->render.i_height / i_height; + var_Set( p_vout, "mouse-y", val ); + val.b_bool = VLC_TRUE; var_Set( p_vout, "mouse-moved", val ); } /***************************************************************************** * VLCVIew::Pulse *****************************************************************************/ -void +void VLCView::Pulse() { - // We are getting the pulse messages no matter if the mouse is over - // this view. If we are in full screen mode, we want to hide the cursor - // even if it is not. - VideoWindow *videoWindow = dynamic_cast(Window()); - if (!fCursorHidden) - { - if (fCursorInside - && system_time() - fLastMouseMovedTime > MOUSE_IDLE_TIMEOUT) - { - be_app->ObscureCursor(); - fCursorHidden = true; - - // hide the interface window as well if full screen - if (videoWindow && videoWindow->IsFullScreen()) - videoWindow->SetInterfaceShowing(false); - } - } + // We are getting the pulse messages no matter if the mouse is over + // this view. If we are in full screen mode, we want to hide the cursor + // even if it is not. + VideoWindow *videoWindow = dynamic_cast(Window()); + if (!fCursorHidden) + { + if (fCursorInside + && mdate() - fLastMouseMovedTime > MOUSE_IDLE_TIMEOUT) + { + be_app->ObscureCursor(); + fCursorHidden = true; + + // hide the interface window as well if full screen + if (videoWindow && videoWindow->IsFullScreen()) + videoWindow->SetInterfaceShowing(false); + } + } // Workaround to disable the screensaver in full screen: - // we simulate an activity every 29 seconds - if( videoWindow && videoWindow->IsFullScreen() && - system_time() - fLastMouseMovedTime > 29000000 ) - { - BPoint where; - uint32 buttons; - GetMouse(&where, &buttons, false); - ConvertToScreen(&where); - set_mouse_position((int32) where.x, (int32) where.y); - } -} - -/***************************************************************************** - * VLCVIew::KeyDown - *****************************************************************************/ -void -VLCView::KeyDown(const char *bytes, int32 numBytes) -{ - VideoWindow *videoWindow = dynamic_cast(Window()); - BWindow* interfaceWindow = get_interface_window(); - if (videoWindow && numBytes > 0) { - uint32 mods = modifiers(); - switch (*bytes) { - case B_TAB: - case 'f': - case 'F': - // toggle window and full screen mode - // not passing on the tab key to the default KeyDown() - // implementation also avoids loosing the keyboard focus - videoWindow->PostMessage(TOGGLE_FULL_SCREEN); - break; - case B_ESCAPE: - // go back to window mode - if (videoWindow->IsFullScreen()) - videoWindow->PostMessage(TOGGLE_FULL_SCREEN); - break; - case B_SPACE: - // toggle playback - if (interfaceWindow) - interfaceWindow->PostMessage(PAUSE_PLAYBACK); - break; - case B_RIGHT_ARROW: - if (interfaceWindow) - { - if (mods & B_SHIFT_KEY) - // next title - interfaceWindow->PostMessage(NEXT_TITLE); - else - // next chapter - interfaceWindow->PostMessage(NEXT_CHAPTER); - } - break; - case B_LEFT_ARROW: - if (interfaceWindow) - { - if (mods & B_SHIFT_KEY) - // previous title - interfaceWindow->PostMessage(PREV_TITLE); - else - // previous chapter - interfaceWindow->PostMessage(PREV_CHAPTER); - } - break; - case B_UP_ARROW: - // previous file in playlist - interfaceWindow->PostMessage(PREV_FILE); - break; - case B_DOWN_ARROW: - // next file in playlist - interfaceWindow->PostMessage(NEXT_FILE); - break; - case B_PRINT_KEY: - case 's': - case 'S': - videoWindow->PostMessage( SCREEN_SHOT ); - break; - default: - BView::KeyDown(bytes, numBytes); - break; - } - } + // we simulate an activity every 29 seconds + if( videoWindow && videoWindow->IsFullScreen() && + mdate() - fLastMouseMovedTime > 29000000 ) + { + BPoint where; + uint32 buttons; + GetMouse(&where, &buttons, false); + ConvertToScreen(&where); + set_mouse_position((int32_t) where.x, (int32_t) where.y); + } } /***************************************************************************** * VLCVIew::Draw *****************************************************************************/ void -VLCView::Draw(BRect updateRect) +VLCView::Draw(BRect updateRect) { - VideoWindow* window = dynamic_cast( Window() ); - if ( window && window->mode == BITMAP ) - FillRect( updateRect ); + VideoWindow* window = dynamic_cast( Window() ); + if ( window && window->mode == BITMAP ) + FillRect( updateRect ); } /***************************************************************************** @@ -1340,8 +1205,9 @@ VLCView::Draw(BRect updateRect) *****************************************************************************/ static int Init ( vout_thread_t * ); static void End ( vout_thread_t * ); -// static int Manage ( vout_thread_t * ); +static int Manage ( vout_thread_t * ); static void Display ( vout_thread_t *, picture_t * ); +static int Control ( vout_thread_t *, int, va_list ); static int BeosOpenDisplay ( vout_thread_t *p_vout ); static void BeosCloseDisplay( vout_thread_t *p_vout ); @@ -1368,9 +1234,10 @@ int E_(OpenVideo) ( vlc_object_t *p_this ) p_vout->pf_init = Init; p_vout->pf_end = End; - p_vout->pf_manage = NULL; + p_vout->pf_manage = Manage; p_vout->pf_render = NULL; p_vout->pf_display = Display; + p_vout->pf_control = Control; return( 0 ); } @@ -1406,7 +1273,9 @@ int Init( vout_thread_t *p_vout ) p_vout->output.i_gmask = 0x0000ff00; p_vout->output.i_bmask = 0x000000ff; - for (int buffer_index = 0 ; buffer_index < 3; buffer_index++) + for( int buffer_index = 0 ; + buffer_index < p_vout->p_sys->p_window->bitmap_count; + buffer_index++ ) { p_pic = NULL; /* Find an empty picture slot */ @@ -1424,17 +1293,18 @@ int Init( vout_thread_t *p_vout ) { return 0; } - p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[buffer_index]->Bits(); + p_pic->p->p_pixels = (uint8_t*)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_visible_lines = p_vout->p_sys->i_height; 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[buffer_index]->BytesPerRow(); + 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; - + PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; I_OUTPUTPICTURES++; @@ -1451,6 +1321,20 @@ void End( vout_thread_t *p_vout ) BeosCloseDisplay( p_vout ); } +/***************************************************************************** + * Manage + *****************************************************************************/ +static int Manage( vout_thread_t * p_vout ) +{ + if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE ) + { + p_vout->p_sys->p_window->PostMessage( TOGGLE_FULL_SCREEN ); + p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; + } + + return 0; +} + /***************************************************************************** * CloseVideo: destroy BeOS video thread output method ***************************************************************************** @@ -1473,14 +1357,20 @@ void Display( vout_thread_t *p_vout, picture_t *p_pic ) { VideoWindow * p_win = p_vout->p_sys->p_window; - /* draw buffer if required */ + /* draw buffer if required */ if (!p_win->teardownwindow) - { + { p_win->drawBuffer(p_vout->p_sys->i_index); } /* change buffer */ - p_vout->p_sys->i_index = ++p_vout->p_sys->i_index % 3; - p_pic->p->p_pixels = (u8*)p_vout->p_sys->p_window->bitmap[p_vout->p_sys->i_index]->Bits(); + p_vout->p_sys->i_index = ++p_vout->p_sys->i_index % + p_vout->p_sys->p_window->bitmap_count; + p_pic->p->p_pixels = (uint8_t*)p_vout->p_sys->p_window->bitmap[p_vout->p_sys->i_index]->Bits(); +} + +static int Control( vout_thread_t * p_vout, int i_query, va_list args ) +{ + return vout_vaControlDefault( p_vout, i_query, args ); } /* following functions are local */ @@ -1489,12 +1379,12 @@ void Display( vout_thread_t *p_vout, picture_t *p_pic ) * BeosOpenDisplay: open and initialize BeOS device *****************************************************************************/ 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, + 20 + p_vout->i_window_width - 1, 50 + p_vout->i_window_height - 1 ), p_vout ); if( p_vout->p_sys->p_window == NULL ) @@ -1506,7 +1396,7 @@ static int BeosOpenDisplay( vout_thread_t *p_vout ) { p_vout->p_sys->p_window->Show(); } - + return( 0 ); } @@ -1517,7 +1407,7 @@ static int BeosOpenDisplay( vout_thread_t *p_vout ) * state of the device. *****************************************************************************/ static void BeosCloseDisplay( vout_thread_t *p_vout ) -{ +{ VideoWindow * p_win = p_vout->p_sys->p_window; /* Destroy the video window */ if( p_win != NULL && !p_win->teardownwindow)