/*****************************************************************************
* vout_beos.cpp: beos video output display method
*****************************************************************************
- * Copyright (C) 2000, 2001 VideoLAN
- * $Id: VideoOutput.cpp,v 1.18 2003/05/07 14:49:19 titer Exp $
+ * Copyright (C) 2000, 2001 the VideoLAN team
+ * $Id$
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* 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
*
* 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.
*****************************************************************************/
/*****************************************************************************
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
+#include <vlc_keys.h>
-#include "InterfaceWindow.h" // for load/save_settings()
+#include "InterfaceWindow.h" // for load/save_settings()
#include "DrawingTidbits.h"
#include "MsgVals.h"
{
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
BWindow*
beos_GetAppWindow(char *name)
{
- int32 index;
+ int32_t index;
BWindow *window;
-
+
for (index = 0 ; ; index++)
{
window = be_app->WindowAt(index);
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;
}
/*****************************************************************************
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;
};
* 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() );
+ }
}
/*****************************************************************************
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
*****************************************************************************/
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);
-
- // add a few useful shortcuts
- AddShortcut( 'f', 0, new BMessage( TOGGLE_FULL_SCREEN ) );
- AddShortcut( '1', 0, new BMessage( RESIZE_50 ) );
- AddShortcut( '2', 0, new BMessage( RESIZE_100 ) );
- AddShortcut( '3', 0, new BMessage( RESIZE_200 ) );
-
- // workaround for french keyboards
- fprintf( stderr, "%x\n", '&' );
- AddShortcut( '&', 0, new BMessage( RESIZE_50 ) );
- AddShortcut( 'é', 0, new BMessage( RESIZE_100 ) );
- // FIXME - this one doesn't work because 'é' is a multi-byte character
- AddShortcut( '"', 0, new BMessage( RESIZE_200 ) );
-
+
+ // vlc settings override settings from disk
+ if (config_GetInt(p_vout, "fullscreen"))
+ fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN);
+
_SetToSettings();
}
teardownwindow = true;
wait_for_thread(fDrawThreadID, &result);
_FreeBuffers();
- delete fSettings;
+ delete fSettings;
}
/*****************************************************************************
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-screenshotpath" );
- if ( !path )
- path = strdup( DEFAULT_SCREEN_SHOT_PATH );
- /* config_GetPsz( p_vout, "beos-screenshotformat" ); */
- int32 format = DEFAULT_SCREEN_SHOT_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_vlc, "key-pressed", val );
+
+ free( keys );
+ free( chars );
+ break;
+ }
+
+ default:
+ BWindow::MessageReceived( p_message );
+ break;
+ }
}
/*****************************************************************************
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();
}
/*****************************************************************************
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;
{
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 */
view->MoveTo(out_left,out_top);
view->ResizeTo(out_width, out_height);
- if (!IsFullScreen())
+ if (!IsFullScreen())
winSize = Frame();
}
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);
}
/*****************************************************************************
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
void
VideoWindow::ToggleInterfaceShowing()
{
- SetInterfaceShowing(!fInterfaceShowing);
+ SetInterfaceShowing(!fInterfaceShowing);
}
/*****************************************************************************
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;
+ }
}
/*****************************************************************************
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());
+ }
}
/*****************************************************************************
bool
VideoWindow::CorrectAspectRatio() const
{
- return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO);
+ return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO);
}
/*****************************************************************************
void
VideoWindow::ToggleFullScreen()
{
- SetFullScreen(!IsFullScreen());
+ SetFullScreen(!IsFullScreen());
}
/*****************************************************************************
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);
+ }
}
/*****************************************************************************
bool
VideoWindow::IsFullScreen() const
{
- return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN);
+ return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN);
}
/*****************************************************************************
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);
}
/*****************************************************************************
bool
VideoWindow::IsSyncedToRetrace() const
{
- return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE);
+ return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE);
}
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;
}
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;
}
/*****************************************************************************
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);
}
/*****************************************************************************
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 );
- create_directory( folder.String(), 0777 );
- path << "/vlc screenshot";
- 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);
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);
}
/*****************************************************************************
void
VLCView::MouseDown(BPoint where)
{
- VideoWindow* videoWindow = dynamic_cast<VideoWindow*>(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<VideoWindow*>(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;
}
/*****************************************************************************
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<VideoWindow*>(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<VideoWindow*>(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<VideoWindow*>(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<VideoWindow*>( Window() );
- if ( window && window->mode == BITMAP )
- FillRect( updateRect );
+ VideoWindow* window = dynamic_cast<VideoWindow*>( Window() );
+ if ( window && window->mode == BITMAP )
+ FillRect( 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 );
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 );
}
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 */
{
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++;
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
*****************************************************************************
{
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 */
* 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 )
{
p_vout->p_sys->p_window->Show();
}
-
+
return( 0 );
}
* 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)