1 /*****************************************************************************
2 * intf_beos.cpp: beos interface
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
5 * $Id: intf_beos.cpp,v 1.13 2001/03/05 01:29:25 sam Exp $
7 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 #define MODULE_NAME beos
26 #include "modules_inner.h"
28 /*****************************************************************************
30 *****************************************************************************/
34 #include <stdlib.h> /* malloc(), free() */
36 #include <kernel/OS.h>
37 #include <storage/Path.h>
43 #include <StatusBar.h>
44 #include <Application.h>
48 #include <DirectWindow.h>
62 #include "stream_control.h"
63 #include "input_ext-intf.h"
65 #include "interface.h"
66 #include "intf_plst.h"
68 #include "audio_output.h"
75 #include "InterfaceWindow.h"
77 #include "TransportButton.h"
79 /*****************************************************************************
80 * intf_sys_t: description and status of FB interface
81 *****************************************************************************/
82 typedef struct intf_sys_s
84 InterfaceWindow * p_window;
88 /*****************************************************************************
90 *****************************************************************************/
92 InterfaceWindow::InterfaceWindow( BRect frame, const char *name , intf_thread_t *p_interface )
93 : BWindow(frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
94 B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK |B_ASYNCHRONOUS_CONTROLS)
101 SetName( "interface" );
102 SetTitle(VOUT_TITLE " (BeOS interface)");
107 p_view = new BView( Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW );
108 p_view->SetViewColor(216,216,216);
112 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
113 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
114 xStart += kRewindBitmapWidth;
115 TransportButton* p_slow = new TransportButton(ButtonRect, B_EMPTY_STRING,
117 kPressedSkipBackBitmapBits,
118 kDisabledSkipBackBitmapBits,
119 new BMessage(SLOWER_PLAY));
120 p_view->AddChild( p_slow );
123 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
124 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kPlayButtonSize);
125 xStart += kPlayPauseBitmapWidth + 1.0;
126 PlayPauseButton* p_play = new PlayPauseButton(ButtonRect, B_EMPTY_STRING,
127 kPlayButtonBitmapBits,
128 kPressedPlayButtonBitmapBits,
129 kDisabledPlayButtonBitmapBits,
130 kPlayingPlayButtonBitmapBits,
131 kPressedPlayingPlayButtonBitmapBits,
132 kPausedPlayButtonBitmapBits,
133 kPressedPausedPlayButtonBitmapBits,
134 new BMessage(START_PLAYBACK));
136 p_view->AddChild( p_play );
137 p_play->SetPlaying();
140 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
141 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
142 xStart += kRewindBitmapWidth;
143 TransportButton* p_fast = new TransportButton(ButtonRect, B_EMPTY_STRING,
144 kSkipForwardBitmapBits,
145 kPressedSkipForwardBitmapBits,
146 kDisabledSkipForwardBitmapBits,
147 new BMessage(FASTER_PLAY));
148 p_view->AddChild( p_fast );
151 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
152 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kStopButtonSize);
153 xStart += kStopBitmapWidth;
154 TransportButton* p_stop = new TransportButton(ButtonRect, B_EMPTY_STRING,
155 kStopButtonBitmapBits,
156 kPressedStopButtonBitmapBits,
157 kDisabledStopButtonBitmapBits,
158 new BMessage(STOP_PLAYBACK));
159 p_view->AddChild( p_stop );
162 p_seek = new SeekSlider(BRect(5,35,355,65), this, 0, 100,
165 p_seek->UseFillColor(TRUE);
166 p_view->AddChild( p_seek );
169 p_vol = new BSlider(BRect(xStart,2,300,20), "vol", "Volume",
170 new BMessage(VOLUME_CHG), 0, VOLUME_MAX);
171 p_vol->SetValue(VOLUME_DEFAULT);
172 p_view->AddChild( p_vol );
175 p_mute = new BCheckBox(BRect(300,10,355,25), "mute", "Mute",
176 new BMessage(VOLUME_MUTE));
177 p_view->AddChild( p_mute );
179 /* Set size and Show */
185 InterfaceWindow::~InterfaceWindow()
189 /*****************************************************************************
190 * InterfaceWindow::MessageReceived
191 *****************************************************************************/
192 void InterfaceWindow::MessageReceived( BMessage * p_message )
194 int vol_val = p_vol->Value(); // remember the current volume
195 static int playback_status; // remember playback state
198 switch( p_message->what )
203 // this currently stops playback not nicely
204 if (p_intf->p_input != NULL )
206 // silence the sound, otherwise very horrible
207 if (p_main->p_aout != NULL)
209 p_main->p_aout->vol = 0;
212 input_SetStatus(p_intf->p_input, INPUT_STATUS_END);
216 // starts playing in normal mode
217 // if (p_intf->p_input != NULL )
219 // if (p_main->p_aout != NULL)
221 // p_main->p_aout->vol = vol_val;
224 // input_SetStatus(p_intf->p_input, INPUT_STATUS_PLAY);
225 // playback_status = PLAYING;
229 // pause the playback
230 if (p_intf->p_input != NULL )
232 // mute the volume if currently playing
233 if (playback_status == PLAYING)
235 if (p_main->p_aout != NULL)
237 p_main->p_aout->vol = 0;
239 playback_status = PAUSED;
242 // restore the volume
244 if (p_main->p_aout != NULL)
246 p_main->p_aout->vol = vol_val;
248 playback_status = PLAYING;
251 input_SetStatus(p_intf->p_input, INPUT_STATUS_PAUSE);
255 // cycle the fast playback modes
256 if (p_intf->p_input != NULL )
258 if (p_main->p_aout != NULL)
260 p_main->p_aout->vol = 0;
263 input_SetStatus(p_intf->p_input, INPUT_STATUS_FASTER);
267 // cycle the slow playback modes
268 if (p_intf->p_input != NULL )
270 if (p_main->p_aout != NULL)
272 p_main->p_aout->vol = 0;
275 input_SetStatus(p_intf->p_input, INPUT_STATUS_SLOWER);
279 // handled by semaphores;
280 /* if( p_intf->p_input != NULL )
283 if (p_message->FindFloat("be:value", &new_position) == B_OK)
285 printf("%e\n", new_position);
286 input_Seek( p_intf->p_input, new_position * 100 );
292 if (p_main->p_aout != NULL)
294 p_main->p_aout->vol = vol_val;
299 if (p_main->p_aout != NULL)
301 if (p_mute->Value() == B_CONTROL_OFF)
303 p_main->p_aout->vol = vol_val;
307 p_main->p_aout->vol = 0;
316 if( p_message->FindRef( "refs", &ref ) == B_OK )
319 char * psz_name = strdup(path.Path());
320 intf_WarnMsg( 1, "intf: dropped text/uri-list data `%s'",
322 intf_PlstAdd( p_main->p_playlist, PLAYLIST_END, psz_name );
328 BWindow::MessageReceived( p_message );
333 /*****************************************************************************
334 * InterfaceWindow::QuitRequested
335 *****************************************************************************/
337 bool InterfaceWindow::QuitRequested()
344 /*****************************************************************************
346 *****************************************************************************/
347 SeekSlider::SeekSlider(BRect frame,
348 InterfaceWindow *owner,
351 thumb_style thumbType = B_TRIANGLE_THUMB)
352 :BSlider(frame, B_EMPTY_STRING, B_EMPTY_STRING,
353 NULL, minValue, maxValue, thumbType)
359 SeekSlider::~SeekSlider()
363 /*****************************************************************************
364 * SeekSlider::MouseDown
365 *****************************************************************************/
366 void SeekSlider::MouseDown(BPoint where)
368 BSlider::MouseDown(where);
369 fOwner->fScrubSem = create_sem(1, "Vlc::fScrubSem");
373 /*****************************************************************************
374 * SeekSlider::MouseUp
375 *****************************************************************************/
376 void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
378 BSlider::MouseMoved(where, code, message);
381 release_sem(fOwner->fScrubSem);
384 /*****************************************************************************
385 * SeekSlider::MouseUp
386 *****************************************************************************/
387 void SeekSlider::MouseUp(BPoint where)
389 BSlider::MouseUp(where);
390 delete_sem(fOwner->fScrubSem);
391 fOwner->fScrubSem = B_ERROR;
399 /*****************************************************************************
401 *****************************************************************************/
402 static int intf_Probe ( probedata_t *p_data );
403 static int intf_Open ( intf_thread_t *p_intf );
404 static void intf_Close ( intf_thread_t *p_intf );
405 static void intf_Run ( intf_thread_t *p_intf );
407 /*****************************************************************************
408 * Functions exported as capabilities. They are declared as static so that
409 * we don't pollute the namespace too much.
410 *****************************************************************************/
411 void _M( intf_getfunctions )( function_list_t * p_function_list )
413 p_function_list->pf_probe = intf_Probe;
414 p_function_list->functions.intf.pf_open = intf_Open;
415 p_function_list->functions.intf.pf_close = intf_Close;
416 p_function_list->functions.intf.pf_run = intf_Run;
419 /*****************************************************************************
420 * intf_Probe: probe the interface and return a score
421 *****************************************************************************
422 * This function tries to initialize Gnome and returns a score to the
423 * plugin manager so that it can select the best plugin.
424 *****************************************************************************/
425 static int intf_Probe( probedata_t *p_data )
427 if( TestMethod( INTF_METHOD_VAR, "beos" ) )
435 /*****************************************************************************
436 * intf_Open: initialize interface
437 *****************************************************************************/
438 static int intf_Open( intf_thread_t *p_intf )
440 /* Allocate instance and initialize some members */
441 p_intf->p_sys = (intf_sys_t*) malloc( sizeof( intf_sys_t ) );
442 if( p_intf->p_sys == NULL )
444 intf_ErrMsg("error: %s", strerror(ENOMEM));
447 p_intf->p_sys->i_key = -1;
449 /* Create the interface window */
450 p_intf->p_sys->p_window =
451 new InterfaceWindow( BRect( 50, 50, 400, 100 ),
452 VOUT_TITLE " (BeOS interface)", p_intf );
453 if( p_intf->p_sys->p_window == 0 )
455 free( p_intf->p_sys );
456 intf_ErrMsg( "error: cannot allocate memory for InterfaceWindow" );
463 /*****************************************************************************
464 * intf_Close: destroy dummy interface
465 *****************************************************************************/
466 static void intf_Close( intf_thread_t *p_intf )
468 /* Destroy the interface window */
469 p_intf->p_sys->p_window->Lock();
470 p_intf->p_sys->p_window->Quit();
472 /* Destroy structure */
473 free( p_intf->p_sys );
477 /*****************************************************************************
478 * intf_Run: event loop
479 *****************************************************************************/
480 static void intf_Run( intf_thread_t *p_intf )
484 bool seekNeeded = false;
486 while( !p_intf->b_die )
489 /* Manage core vlc functions through the callback */
490 p_intf->pf_manage( p_intf );
492 /* Manage the slider */
493 if( p_intf->p_input != NULL && p_intf->p_sys->p_window != NULL)
495 if (acquire_sem(p_intf->p_sys->p_window->fScrubSem) == B_OK)
502 uint32 seekTo = (p_intf->p_sys->p_window->p_seek->Value() *
503 p_intf->p_input->stream.p_selected_area->i_size) / 100;
504 input_Seek( p_intf->p_input, seekTo );
507 else if (p_intf->p_sys->p_window->Lock())
509 progress = (100. * p_intf->p_input->stream.p_selected_area->i_tell) /
510 p_intf->p_input->stream.p_selected_area->i_size;
511 p_intf->p_sys->p_window->p_seek->SetValue(progress);
512 p_intf->p_sys->p_window->Unlock();
517 msleep( INTF_IDLE_SLEEP );