* vout_beos.cpp: beos video output display method
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
- * $Id: VideoOutput.cpp,v 1.9 2002/12/07 22:00:36 titer Exp $
+ * $Id: VideoOutput.cpp,v 1.26 2003/11/09 16:00:54 titer Exp $
*
* 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
#include <Application.h>
#include <BitmapStream.h>
#include <Bitmap.h>
+#include <Directory.h>
#include <DirectWindow.h>
#include <File.h>
#include <InterfaceKit.h>
#include <NodeInfo.h>
#include <String.h>
#include <TranslatorRoster.h>
+#include <WindowScreen.h>
/* VLC headers */
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
+#include <vlc_keys.h>
-#include "VideoWindow.h"
+#include "InterfaceWindow.h" // for load/save_settings()
#include "DrawingTidbits.h"
#include "MsgVals.h"
+#include "VideoWindow.h"
+
/*****************************************************************************
* vout_sys_t: BeOS video output method descriptor
*****************************************************************************
{
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;
};
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 int ConvertKey( int key )
+{
+ switch( key )
+ {
+ case B_LEFT_ARROW:
+ return KEY_LEFT;
+ case B_RIGHT_ARROW:
+ return KEY_RIGHT;
+ case B_UP_ARROW:
+ return KEY_UP;
+ case B_DOWN_ARROW:
+ return KEY_DOWN;
+ case B_SPACE:
+ return KEY_SPACE;
+ case B_ENTER:
+ return KEY_ENTER;
+ case B_HOME:
+ return KEY_HOME;
+ case B_END:
+ return KEY_END;
+ case B_ESCAPE:
+ return KEY_ESC;
+ case B_PAGE_UP:
+ return KEY_PAGEUP;
+ case B_PAGE_DOWN:
+ return KEY_PAGEDOWN;
+ case B_TAB:
+ return KEY_TAB;
+ case B_BACKSPACE:
+ return KEY_BACKSPACE;
+ }
+ return key;
}
/*****************************************************************************
BWindow*
get_interface_window()
{
- return beos_GetAppWindow(VOUT_TITLE);
+ return beos_GetAppWindow( "VLC " PACKAGE_VERSION );
}
class BackgroundView : public BView
// let him handle it
fVideoView->MouseDown(where);
}
- virtual void MouseMoved(BPoint where, uint32 transit,
+ virtual void MouseMoved(BPoint where, uint32_t transit,
const BMessage* dragMessage)
{
// convert coordinates
VLCView* fVideoView;
};
+
+/*****************************************************************************
+ * VideoSettings constructor and destructor
+ *****************************************************************************/
+VideoSettings::VideoSettings()
+ : 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);
+ }
+ }
+}
+
+VideoSettings::VideoSettings( const VideoSettings& clone )
+ : 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() );
+ }
+}
+
+/*****************************************************************************
+ * VideoSettings::DefaultSettings
+ *****************************************************************************/
+VideoSettings*
+VideoSettings::DefaultSettings()
+{
+ return &fDefaultSettings;
+}
+
+/*****************************************************************************
+ * VideoSettings::SetVideoSize
+ *****************************************************************************/
+void
+VideoSettings::SetVideoSize( uint32_t mode )
+{
+ fVideoSize = mode;
+}
+
+// static variable initialization
+VideoSettings
+VideoSettings::fDefaultSettings;
+
+
/*****************************************************************************
* VideoWindow constructor and destructor
*****************************************************************************/
: BWindow(frame, NULL, B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_MINIMIZABLE),
i_width(frame.IntegerWidth()),
i_height(frame.IntegerHeight()),
- is_zoomed(false),
- vsync(false),
+ winSize(frame),
i_buffer(0),
teardownwindow(false),
fTrueWidth(v_width),
fTrueHeight(v_height),
- fCorrectAspect(true),
fCachedFeel(B_NORMAL_WINDOW_FEEL),
fInterfaceShowing(false),
- fInitStatus(B_ERROR)
+ 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 );
AddChild(mainView);
mainView->AddChild(view);
- // figure out if we should use vertical sync by default
- BScreen screen(this);
- if (screen.IsValid())
- {
- display_mode mode;
- screen.GetMode(&mode);
- float refresh = (mode.timing.pixel_clock * 1000)
- / ((mode.timing.h_total)* (mode.timing.v_total));
- vsync = (refresh < MIN_AUTO_VSYNC_REFRESH);
- }
-
// allocate bitmap buffers
- for (int32 i = 0; i < 3; i++)
+ for (int32_t i = 0; i < 3; i++)
bitmap[i] = NULL;
fInitStatus = _AllocateBuffers(v_width, v_height, &mode);
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);
}
-
- if( config_GetInt( p_vout, "fullscreen" ) )
- {
- BWindow::Zoom();;
- }
+
+ // 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
+ 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 ) );
+
+ _SetToSettings();
}
VideoWindow::~VideoWindow()
teardownwindow = true;
wait_for_thread(fDrawThreadID, &result);
_FreeBuffers();
+ delete fSettings;
}
/*****************************************************************************
{
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 (is_zoomed)
+ if (IsFullScreen())
BWindow::Zoom();
_SetVideoSize(p_message->what);
break;
case VERT_SYNC:
- vsync = !vsync;
+ SetSyncToRetrace(!IsSyncedToRetrace());
break;
case WINDOW_FEEL:
{
{
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(!fCorrectAspect);
+ SetCorrectAspectRatio(!CorrectAspectRatio());
break;
case SCREEN_SHOT:
// save a screen shot
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++ )
+ 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;
}
- _SaveScreenShot( temp,
- strdup( DEFAULT_SCREEN_SHOT_PATH ),
- DEFAULT_SCREEN_SHOT_FORMAT );
+ 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;
- fprintf( stderr, "error copying bitmaps\n" );
}
}
break;
void
VideoWindow::Zoom(BPoint origin, float width, float height )
{
- if(is_zoomed)
- {
- MoveTo(winSize.left, winSize.top);
- ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
- be_app->ShowCursor();
- fInterfaceShowing = true;
- }
- else
- {
- BScreen screen(this);
- BRect rect = screen.Frame();
- Activate();
- MoveTo(0.0, 0.0);
- ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
- be_app->ObscureCursor();
- fInterfaceShowing = false;
- }
- is_zoomed = !is_zoomed;
+ ToggleFullScreen();
}
/*****************************************************************************
* VideoWindow::FrameMoved
*****************************************************************************/
void
-VideoWindow::FrameMoved(BPoint origin)
+VideoWindow::FrameMoved(BPoint origin)
{
- if (is_zoomed) return ;
- winSize = Frame();
+ if (IsFullScreen())
+ return ;
+ winSize = Frame();
}
/*****************************************************************************
void
VideoWindow::FrameResized( float width, float height )
{
- int32 useWidth = fCorrectAspect ? i_width : fTrueWidth;
- int32 useHeight = fCorrectAspect ? 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 (!is_zoomed)
+ if (!IsFullScreen())
winSize = Frame();
}
VideoWindow::ScreenChanged(BRect frame, color_space format)
{
BScreen screen(this);
- display_mode mode;
- screen.GetMode(&mode);
+ 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)
- vsync = true;
+ / ((mode.timing.h_total) * (mode.timing.v_total));
+ SetSyncToRetrace(refresh < MIN_AUTO_VSYNC_REFRESH);
}
/*****************************************************************************
i_buffer = bufferIndex;
// sync to the screen if required
- if (vsync)
+ if (IsSyncedToRetrace())
{
BScreen screen(this);
screen.WaitForRetrace(22000);
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,
void
VideoWindow::SetCorrectAspectRatio(bool doIt)
{
- if (fCorrectAspect != doIt)
+ if (CorrectAspectRatio() != doIt)
{
- fCorrectAspect = doIt;
+ if (doIt)
+ fSettings->AddFlags(VideoSettings::FLAG_CORRECT_RATIO);
+ else
+ fSettings->ClearFlags(VideoSettings::FLAG_CORRECT_RATIO);
FrameResized(Bounds().Width(), Bounds().Height());
}
}
+/*****************************************************************************
+ * VideoWindow::CorrectAspectRatio
+ *****************************************************************************/
+bool
+VideoWindow::CorrectAspectRatio() const
+{
+ return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO);
+}
+
+/*****************************************************************************
+ * VideoWindow::ToggleFullScreen
+ *****************************************************************************/
+void
+VideoWindow::ToggleFullScreen()
+{
+ SetFullScreen(!IsFullScreen());
+}
+
+/*****************************************************************************
+ * VideoWindow::SetFullScreen
+ *****************************************************************************/
+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);
+ }
+}
+
+/*****************************************************************************
+ * VideoWindow::IsFullScreen
+ *****************************************************************************/
+bool
+VideoWindow::IsFullScreen() const
+{
+ return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN);
+}
+
+/*****************************************************************************
+ * VideoWindow::SetSyncToRetrace
+ *****************************************************************************/
+void
+VideoWindow::SetSyncToRetrace(bool doIt)
+{
+ if (doIt)
+ fSettings->AddFlags(VideoSettings::FLAG_SYNC_RETRACE);
+ else
+ fSettings->ClearFlags(VideoSettings::FLAG_SYNC_RETRACE);
+}
+
+/*****************************************************************************
+ * VideoWindow::IsSyncedToRetrace
+ *****************************************************************************/
+bool
+VideoWindow::IsSyncedToRetrace() const
+{
+ return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE);
+}
+
+
/*****************************************************************************
* VideoWindow::_AllocateBuffers
*****************************************************************************/
for (int i = 0; i < COLOR_COUNT; i++)
{
if (noOverlay) break;
- bitmap[0] = new BBitmap ( bitmapFrame,
+ 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)
+ if(bitmap[0] && bitmap[0]->InitCheck() == B_OK)
{
colspace_index = i;
{
*mode = OVERLAY;
rgb_color key;
- view->SetViewOverlay(bitmap[0],
+ 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(VOUT_TITLE " (Overlay)");
+ SetTitle("VLC " PACKAGE_VERSION " (Overlay)");
break;
}
else
{
// fallback to RGB
colspace_index = DEFAULT_COL; // B_RGB32
- SetTitle( VOUT_TITLE " (Bitmap)" );
+ SetTitle( "VLC " PACKAGE_VERSION " (Bitmap)" );
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 );
}
// see if everything went well
status_t status = B_ERROR;
- for (int32 i = 0; i < 3; i++)
+ for (int32_t i = 0; i < 3; i++)
{
if (bitmap[i])
status = bitmap[i]->InitCheck();
if (status >= B_OK)
{
// clear bitmaps to black
- for (int32 i = 0; i < 3; i++)
+ for (int32_t i = 0; i < 3; i++)
_BlankBitmap(bitmap[i]);
}
return status;
{
// no error checking (we do that earlier on and since it's a private function...
- // YCbCr:
+ // YCbCr:
// Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128)
- // YUV:
+ // 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++) {
+ 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 i = 0; i < bpr; i += 2) {
+ for (int32_t i = 0; i < bpr; i += 2) {
// offset into line
bits[i] = 16;
bits[i + 1] = 128;
// 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) {
+ 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 i = 0; i < bpr; i += 3) {
+ for (int32_t i = 0; i < bpr; i += 3) {
// offset into line
bits[i] = 128;
bits[i + 1] = 16;
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) {
+ 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 i = 0; i < bpr; i += 2) {
+ for (int32_t i = 0; i < bpr; i += 2) {
// offset into line
bits[i] = 128;
bits[i + 1] = 0;
* VideoWindow::_SetVideoSize
*****************************************************************************/
void
-VideoWindow::_SetVideoSize(uint32 mode)
+VideoWindow::_SetVideoSize(uint32_t mode)
{
// let size depend on aspect correction
- int32 width = fCorrectAspect ? i_width : fTrueWidth;
- int32 height = fCorrectAspect ? i_height : fTrueHeight;
+ int32_t width = CorrectAspectRatio() ? i_width : fTrueWidth;
+ int32_t height = CorrectAspectRatio() ? i_height : fTrueHeight;
switch (mode)
{
case RESIZE_50:
default:
break;
}
+ fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN);
ResizeTo(width, height);
- is_zoomed = false;
+}
+
+/*****************************************************************************
+ * VideoWindow::_SetToSettings
+ *****************************************************************************/
+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);
}
/*****************************************************************************
*****************************************************************************/
void
VideoWindow::_SaveScreenShot( BBitmap* bitmap, char* path,
- uint32 translatorID ) const
+ 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 = fCorrectAspect ? i_width : fTrueWidth;
- info->height = fCorrectAspect ? i_height : fTrueHeight;
+ 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",
// 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;
+ int32_t appendedNumber = 0;
if ( entry.Exists() && !entry.IsSymLink() )
{
// we would clobber an existing entry
bool foundUniqueName = false;
appendedNumber = 1;
while ( !foundUniqueName ) {
- BString newName( info->path );
+ BString newName( path.String() );
newName << " " << appendedNumber;
BEntry possiblyClobberedEntry( newName.String() );
if ( possiblyClobberedEntry.Exists()
// make colorspace converted copy of bitmap
BBitmap* converted = new BBitmap( BRect( 0.0, 0.0, info->width, info->height ),
B_RGB32 );
-// if ( converted->IsValid() )
-// memset( converted->Bits(), 0, converted->BitsLength() );
status_t status = convert_bitmap( info->bitmap, converted );
if ( status == B_OK )
{
BTranslatorRoster* roster = BTranslatorRoster::Default();
- uint32 imageFormat = 0;
+ uint32_t imageFormat = 0;
translator_id translator = 0;
bool found = false;
if ( status >= B_OK )
{
for ( int tix = 0; tix < count; tix++ )
- {
- const translation_format *formats = NULL;
- int32 num_formats = 0;
- bool ok = false;
+ {
+ 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;
+ {
+ ok = true;
+ break;
}
}
}
if ( !ok )
- continue;
+ continue;
status = roster->GetOutputFormats( ids[tix],
- &formats, &num_formats);
+ &formats, &num_formats);
if ( status >= B_OK )
{
- for ( int32 oix = 0; oix < num_formats; oix++ )
+ for ( int32_t oix = 0; oix < num_formats; oix++ )
{
if ( formats[oix].type != B_TRANSLATOR_BITMAP )
{
BNodeInfo nodeInfo( &outFile );
if ( nodeInfo.InitCheck() == B_OK )
{
- translation_format* formats;
+ translation_format* formats;
int32 count;
status = roster->GetOutputFormats( translator,
(const translation_format **) &formats,
&count);
if ( status >= B_OK )
{
- const char * mime = NULL;
+ 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 );
}
}
- } else {
- fprintf( stderr, " failed to write bitmap: %s\n",
- strerror( status ) );
}
- } else {
- fprintf( stderr, " failed to create output file: %s\n",
- strerror( status ) );
}
outStream.DetachBitmap( &converted );
outFile.Unset();
}
- else
- fprintf( stderr, " failed to find translator\n");
}
- else
- fprintf( stderr, " failed to convert colorspace: %s\n",
- strerror( status ) );
delete converted;
}
if ( info )
{
delete info->bitmap;
- delete[] info->path;
+ free( info->path );
}
delete info;
return B_OK;
VideoWindow* videoWindow = dynamic_cast<VideoWindow*>(Window());
BMessage* msg = Window()->CurrentMessage();
int32 clicks;
- uint32 buttons;
+ uint32_t buttons;
msg->FindInt32("clicks", &clicks);
msg->FindInt32("buttons", (int32*)&buttons);
{
if (clicks == 2 && !fIgnoreDoubleClick)
Window()->Zoom();
- else
- videoWindow->ToggleInterfaceShowing();
+ /* else
+ videoWindow->ToggleInterfaceShowing(); */
fIgnoreDoubleClick = false;
}
else
{
- if (buttons & B_SECONDARY_MOUSE_BUTTON)
+ if (buttons & B_SECONDARY_MOUSE_BUTTON)
{
// clicks will be 2 next time (if interval short enough)
// even if the first click and the second
// 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));
+ BMenuItem *halfItem = new BMenuItem(_("50%"), new BMessage(RESIZE_50));
menu->AddItem(halfItem);
// Resize to 100%
- BMenuItem *origItem = new BMenuItem("100%", new BMessage(RESIZE_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));
+ 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->is_zoomed);
+ 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->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));
+ BMenuItem *aspectItem = new BMenuItem(_("Correct Aspect Ratio"), new BMessage(ASPECT_CORRECT));
aspectItem->SetMarked(videoWindow->CorrectAspectRatio());
menu->AddItem(aspectItem);
// Windwo Feel Items
/* BMessage *winNormFeel = new BMessage(WINDOW_FEEL);
- winNormFeel->AddInt32("WinFeel", (int32)B_NORMAL_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)B_FLOATING_APP_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)B_FLOATING_ALL_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)feel );
- BMenuItem *windowFeelItem = new BMenuItem( "Stay On Top", windowFeelMsg );
+ 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",
+ 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 );
+ BRect mouseRect( where.x - 5, where.y - 5,
+ where.x + 5, where.y + 5 );
+ menu->Go( where, true, false, mouseRect, true );
}
}
}
* VLCVIew::MouseMoved
*****************************************************************************/
void
-VLCView::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage)
+VLCView::MouseMoved(BPoint point, uint32_t transit, const BMessage* dragMessage)
{
fLastMouseMovedTime = system_time();
fCursorHidden = false;
/*****************************************************************************
* 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
{
be_app->ObscureCursor();
fCursorHidden = true;
- VideoWindow *videoWindow = dynamic_cast<VideoWindow*>(Window());
+
// hide the interface window as well if full screen
- if (videoWindow && videoWindow->is_zoomed)
+ 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::KeyDown
*****************************************************************************/
-void
-VLCView::KeyDown(const char *bytes, int32 numBytes)
+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:
- // 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->is_zoomed)
- 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;
- }
- }
+ if( numBytes < 1 )
+ {
+ return;
+ }
+
+ uint32_t mods = modifiers();
+ vlc_value_t val;
+
+ val.i_int = ConvertKey( *bytes );
+ if( mods & B_SHIFT_KEY )
+ {
+ val.i_int |= KEY_MODIFIER_SHIFT;
+ }
+ if( mods & B_CONTROL_KEY )
+ {
+ val.i_int |= KEY_MODIFIER_CTRL;
+ }
+ if( mods & B_COMMAND_KEY )
+ {
+ val.i_int |= KEY_MODIFIER_ALT;
+ }
+ var_Set( p_vout->p_vlc, "key-pressed", val );
}
/*****************************************************************************
* VLCVIew::Draw
*****************************************************************************/
void
-VLCView::Draw(BRect updateRect)
+VLCView::Draw(BRect updateRect)
{
VideoWindow* window = dynamic_cast<VideoWindow*>( Window() );
if ( window && window->mode == BITMAP )
*****************************************************************************/
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 BeosOpenDisplay ( 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;
{
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_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_pic->p->p_pixels = (uint8_t*)p_vout->p_sys->p_window->bitmap[p_vout->p_sys->i_index]->Bits();
}
/* 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)