X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fbeos%2FVideoOutput.cpp;h=62a4ec676d6ae8467fbdb6fb2b45213878d0dfd3;hb=1405cf748a267b5e7ad21b606172a27d688eda56;hp=4fae241ea9f2d9e00b914804acf9f4b4a57aabda;hpb=6f8690b5a1404de11a2b1f2cc27d0565bb0ca226;p=vlc diff --git a/modules/gui/beos/VideoOutput.cpp b/modules/gui/beos/VideoOutput.cpp index 4fae241ea9..62a4ec676d 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.29 2003/12/28 01:49:12 titer Exp $ + * Copyright (C) 2000, 2001 the VideoLAN team + * $Id$ * * Authors: Jean-Marc Dressler * Samuel Hocevar @@ -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 @@ -46,12 +43,16 @@ #include /* VLC headers */ -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include #include -#include "InterfaceWindow.h" // for load/save_settings() +#include "InterfaceWindow.h" // for load/save_settings() #include "DrawingTidbits.h" #include "MsgVals.h" @@ -76,10 +77,7 @@ struct vout_sys_t }; -#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 MIN_AUTO_VSYNC_REFRESH 61 // Hz /***************************************************************************** * beos_GetAppWindow : retrieve a BWindow pointer from the window name @@ -167,42 +165,42 @@ static int ConvertKeyToVLC( int key ) 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_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! - } + 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; }; @@ -210,65 +208,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_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); - } - } + // 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() ); - - 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() ); - } + 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() ); + } } /***************************************************************************** @@ -277,7 +275,7 @@ VideoSettings::~VideoSettings() VideoSettings* VideoSettings::DefaultSettings() { - return &fDefaultSettings; + return &fDefaultSettings; } /***************************************************************************** @@ -286,7 +284,7 @@ VideoSettings::DefaultSettings() void VideoSettings::SetVideoSize( uint32_t mode ) { - fVideoSize = mode; + fVideoSize = mode; } // static variable initialization @@ -299,55 +297,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_t 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); - - // add a few useful shortcuts - // XXX works only with US keymap - AddShortcut( '1', 0, new BMessage( RESIZE_50 ) ); - AddShortcut( '2', 0, new BMessage( RESIZE_100 ) ); - AddShortcut( '3', 0, new BMessage( RESIZE_200 ) ); + // vlc settings override settings from disk + if (config_GetInt(p_vout, "fullscreen")) + fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN); _SetToSettings(); } @@ -359,7 +351,7 @@ VideoWindow::~VideoWindow() teardownwindow = true; wait_for_thread(fDrawThreadID, &result); _FreeBuffers(); - delete fSettings; + delete fSettings; } /***************************************************************************** @@ -368,101 +360,121 @@ VideoWindow::~VideoWindow() void VideoWindow::MessageReceived( BMessage *p_message ) { - 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 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_t height = (int32_t)current->Bounds().Height(); - uint8_t* dst = (uint8_t*)temp->Bits(); - uint8_t* src = (uint8_t*)current->Bits(); - int32_t dstBpr = temp->BytesPerRow(); - int32_t srcBpr = current->BytesPerRow(); - int32_t validBytes = dstBpr > srcBpr ? srcBpr : dstBpr; - for ( int32_t y = 0; y < height; y++ ) - { - memcpy( dst, src, validBytes ); - dst += dstBpr; - src += srcBpr; - } - char * path = config_GetPsz( p_vout, "beos-screenshotpath" ); - if ( !path ) - path = strdup( DEFAULT_SCREEN_SHOT_PATH ); - - /* FIXME - we should check which translators are - actually available */ - char * psz_format = config_GetPsz( p_vout, "beos-screenshotformat" ); - int32_t format = DEFAULT_SCREEN_SHOT_FORMAT; - if( !strcmp( psz_format, "TGA" ) ) - format = 'TGA '; - else if( !strcmp( psz_format, "PPM" ) ) - format = 'PPM '; - else if( !strcmp( psz_format, "JPEG" ) ) - format = 'JPEG'; - else if( !strcmp( psz_format, "BMP" ) ) - format = 'BMP '; - - _SaveScreenShot( temp, path, format ); - } - else - { - delete temp; - } - } - break; - case SHORTCUT: + 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; - p_message->FindInt32( "key", (int32*) &val.i_int ); - var_Set( p_vout->p_vlc, "key-pressed", 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; - } + + default: + BWindow::MessageReceived( p_message ); + break; + } } /***************************************************************************** @@ -471,7 +483,7 @@ VideoWindow::MessageReceived( BMessage *p_message ) void VideoWindow::Zoom(BPoint origin, float width, float height ) { - ToggleFullScreen(); + ToggleFullScreen(); } /***************************************************************************** @@ -480,9 +492,9 @@ VideoWindow::Zoom(BPoint origin, float width, float height ) void VideoWindow::FrameMoved(BPoint origin) { - if (IsFullScreen()) - return ; - winSize = Frame(); + if (IsFullScreen()) + return ; + winSize = Frame(); } /***************************************************************************** @@ -515,7 +527,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(); } @@ -525,12 +537,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); } /***************************************************************************** @@ -565,10 +577,10 @@ VideoWindow::drawBuffer(int bufferIndex) 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 @@ -584,7 +596,7 @@ VideoWindow::drawBuffer(int bufferIndex) void VideoWindow::ToggleInterfaceShowing() { - SetInterfaceShowing(!fInterfaceShowing); + SetInterfaceShowing(!fInterfaceShowing); } /***************************************************************************** @@ -593,24 +605,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; + } } /***************************************************************************** @@ -619,14 +631,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()); + } } /***************************************************************************** @@ -635,7 +647,7 @@ VideoWindow::SetCorrectAspectRatio(bool doIt) bool VideoWindow::CorrectAspectRatio() const { - return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO); + return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO); } /***************************************************************************** @@ -644,7 +656,7 @@ VideoWindow::CorrectAspectRatio() const void VideoWindow::ToggleFullScreen() { - SetFullScreen(!IsFullScreen()); + SetFullScreen(!IsFullScreen()); } /***************************************************************************** @@ -653,27 +665,27 @@ VideoWindow::ToggleFullScreen() void VideoWindow::SetFullScreen(bool doIt) { - 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); - } + 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); + } } /***************************************************************************** @@ -682,7 +694,7 @@ VideoWindow::SetFullScreen(bool doIt) bool VideoWindow::IsFullScreen() const { - return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN); + return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN); } /***************************************************************************** @@ -691,10 +703,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); } /***************************************************************************** @@ -703,7 +715,7 @@ VideoWindow::SetSyncToRetrace(bool doIt) bool VideoWindow::IsSyncedToRetrace() const { - return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE); + return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE); } @@ -713,77 +725,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; + 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; + delete bitmap[1]; bitmap[1] = NULL; } + break; } else - delete 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_t 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_t 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; } @@ -794,13 +828,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; + delete bitmap[0]; bitmap[0] = NULL; + delete bitmap[1]; bitmap[1] = NULL; + delete bitmap[2]; bitmap[2] = NULL; + fInitStatus = B_ERROR; } /***************************************************************************** @@ -809,75 +840,75 @@ 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_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: { + // 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_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: { + // 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_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; - } + // 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; + } } /***************************************************************************** @@ -886,25 +917,25 @@ VideoWindow::_BlankBitmap(BBitmap* bitmap) const void VideoWindow::_SetVideoSize(uint32_t mode) { - // 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); + // 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); } /***************************************************************************** @@ -913,219 +944,46 @@ VideoWindow::_SetVideoSize(uint32_t mode) void VideoWindow::_SetToSettings() { - // 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); -} - -/***************************************************************************** - * VideoWindow::_SaveScreenShot - *****************************************************************************/ -void -VideoWindow::_SaveScreenShot( BBitmap* bitmap, char* path, - uint32_t 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 ); - create_directory( folder.String(), 0777 ); - path << "/vlc screenshot"; - BEntry entry( path.String() ); - int32_t 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_t 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_t 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; + fMouseHideTimeout = var_GetInteger(p_vout, "mouse-hide-timeout") * 1000; SetViewColor(B_TRANSPARENT_32_BIT); } @@ -1142,10 +1000,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); } /***************************************************************************** @@ -1154,111 +1010,111 @@ VLCView::AttachedToWindow() void VLCView::MouseDown(BPoint where) { - 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 = 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; } /***************************************************************************** @@ -1268,7 +1124,7 @@ void VLCView::MouseUp( BPoint where ) { vlc_value_t val; - val.b_bool = VLC_TRUE; + val.b_bool = true; var_Set( p_vout, "mouse-clicked", val ); } @@ -1278,20 +1134,25 @@ 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 = true; var_Set( p_vout, "mouse-moved", val ); } @@ -1301,64 +1162,35 @@ VLCView::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage) 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); - } - } - - // 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_t) where.x, (int32_t) where.y); - } -} - -/***************************************************************************** - * VLCVIew::KeyUp - *****************************************************************************/ -void VLCView::KeyUp( const char *bytes, int32 numBytes ) -{ - if( numBytes < 1 ) + // 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) { - return; + if (fCursorInside + && mdate() - fLastMouseMovedTime > fMouseHideTimeout) + { + be_app->ObscureCursor(); + fCursorHidden = true; + + // hide the interface window as well if full screen + if (videoWindow && videoWindow->IsFullScreen()) + videoWindow->SetInterfaceShowing(false); + } } - uint32_t mods = modifiers(); - - vlc_value_t val; - val.i_int = ConvertKeyToVLC( *bytes ); - if( mods & B_COMMAND_KEY ) - { - val.i_int |= KEY_MODIFIER_ALT; - } - if( mods & B_SHIFT_KEY ) - { - val.i_int |= KEY_MODIFIER_SHIFT; - } - if( mods & B_CONTROL_KEY ) + // Workaround to disable the screensaver in full screen: + // we simulate an activity every 29 seconds + if( videoWindow && videoWindow->IsFullScreen() && + mdate() - fLastMouseMovedTime > 29000000 ) { - val.i_int |= KEY_MODIFIER_CTRL; + BPoint where; + uint32 buttons; + GetMouse(&where, &buttons, false); + ConvertToScreen(&where); + set_mouse_position((int32_t) where.x, (int32_t) where.y); } - var_Set( p_vout->p_vlc, "key-pressed", val ); } /***************************************************************************** @@ -1367,9 +1199,9 @@ void VLCView::KeyUp( const char *bytes, int32 numBytes ) void 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 ); } /***************************************************************************** @@ -1379,6 +1211,7 @@ static int Init ( vout_thread_t * ); static void End ( vout_thread_t * ); static int Manage ( vout_thread_t * ); static void Display ( vout_thread_t *, picture_t * ); +static int Control ( vout_thread_t *, int, va_list ); static int BeosOpenDisplay ( vout_thread_t *p_vout ); static void BeosCloseDisplay( vout_thread_t *p_vout ); @@ -1388,7 +1221,7 @@ static void BeosCloseDisplay( vout_thread_t *p_vout ); ***************************************************************************** * This function allocates and initializes a BeOS vout method. *****************************************************************************/ -int E_(OpenVideo) ( vlc_object_t *p_this ) +int OpenVideo ( vlc_object_t *p_this ) { vout_thread_t * p_vout = (vout_thread_t *)p_this; @@ -1408,6 +1241,7 @@ int E_(OpenVideo) ( vlc_object_t *p_this ) p_vout->pf_manage = Manage; p_vout->pf_render = NULL; p_vout->pf_display = Display; + p_vout->pf_control = Control; return( 0 ); } @@ -1443,7 +1277,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 */ @@ -1463,6 +1299,7 @@ int Init( vout_thread_t *p_vout ) } 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; @@ -1507,7 +1344,7 @@ static int Manage( vout_thread_t * p_vout ) ***************************************************************************** * Terminate an output method created by DummyCreateOutputMethod *****************************************************************************/ -void E_(CloseVideo) ( vlc_object_t *p_this ) +void CloseVideo ( vlc_object_t *p_this ) { vout_thread_t * p_vout = (vout_thread_t *)p_this; @@ -1530,10 +1367,16 @@ void Display( vout_thread_t *p_vout, picture_t *p_pic ) 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_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 */ /*****************************************************************************