1 /*****************************************************************************
2 * intf_beos.cpp: beos interface
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
5 * $Id: intf_beos.cpp,v 1.14 2001/03/05 13:28:47 richards Exp $
7 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
9 * Tony Castley <tcastley@mail.powerup.com.au>
10 * Richard Shepherd <richard@rshepherd.demon.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
25 *****************************************************************************/
27 #define MODULE_NAME beos
28 #include "modules_inner.h"
30 /*****************************************************************************
32 *****************************************************************************/
36 #include <stdlib.h> /* malloc(), free() */
38 #include <kernel/OS.h>
39 #include <storage/Path.h>
45 #include <StatusBar.h>
46 #include <Application.h>
50 #include <DirectWindow.h>
64 #include "stream_control.h"
65 #include "input_ext-intf.h"
67 #include "interface.h"
68 #include "intf_plst.h"
70 #include "audio_output.h"
77 #include "InterfaceWindow.h"
79 #include "TransportButton.h"
81 /*****************************************************************************
82 * intf_sys_t: description and status of FB interface
83 *****************************************************************************/
84 typedef struct intf_sys_s
86 InterfaceWindow * p_window;
90 /*****************************************************************************
92 *****************************************************************************/
94 InterfaceWindow::InterfaceWindow( BRect frame, const char *name , intf_thread_t *p_interface )
95 : BWindow(frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
96 B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK |B_ASYNCHRONOUS_CONTROLS)
103 SetName( "interface" );
104 SetTitle(VOUT_TITLE " (BeOS interface)");
109 p_view = new BView( Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW );
110 p_view->SetViewColor(216,216,216);
114 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
115 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
116 xStart += kRewindBitmapWidth;
117 TransportButton* p_slow = new TransportButton(ButtonRect, B_EMPTY_STRING,
119 kPressedSkipBackBitmapBits,
120 kDisabledSkipBackBitmapBits,
121 new BMessage(SLOWER_PLAY));
122 p_view->AddChild( p_slow );
125 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
126 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kPlayButtonSize);
127 xStart += kPlayPauseBitmapWidth + 1.0;
128 PlayPauseButton* p_play = new PlayPauseButton(ButtonRect, B_EMPTY_STRING,
129 kPlayButtonBitmapBits,
130 kPressedPlayButtonBitmapBits,
131 kDisabledPlayButtonBitmapBits,
132 kPlayingPlayButtonBitmapBits,
133 kPressedPlayingPlayButtonBitmapBits,
134 kPausedPlayButtonBitmapBits,
135 kPressedPausedPlayButtonBitmapBits,
136 new BMessage(START_PLAYBACK));
138 p_view->AddChild( p_play );
139 p_play->SetPlaying();
142 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
143 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kSkipButtonSize);
144 xStart += kRewindBitmapWidth;
145 TransportButton* p_fast = new TransportButton(ButtonRect, B_EMPTY_STRING,
146 kSkipForwardBitmapBits,
147 kPressedSkipForwardBitmapBits,
148 kDisabledSkipForwardBitmapBits,
149 new BMessage(FASTER_PLAY));
150 p_view->AddChild( p_fast );
153 ButtonRect.SetLeftTop(BPoint(xStart, yStart));
154 ButtonRect.SetRightBottom(ButtonRect.LeftTop() + kStopButtonSize);
155 xStart += kStopBitmapWidth;
156 TransportButton* p_stop = new TransportButton(ButtonRect, B_EMPTY_STRING,
157 kStopButtonBitmapBits,
158 kPressedStopButtonBitmapBits,
159 kDisabledStopButtonBitmapBits,
160 new BMessage(STOP_PLAYBACK));
161 p_view->AddChild( p_stop );
164 p_seek = new SeekSlider(BRect(5,35,355,65), this, 0, 100,
167 p_seek->UseFillColor(TRUE);
168 p_view->AddChild( p_seek );
171 p_vol = new BSlider(BRect(xStart,2,300,20), "vol", "Volume",
172 new BMessage(VOLUME_CHG), 0, VOLUME_MAX);
173 p_vol->SetValue(VOLUME_DEFAULT);
174 p_view->AddChild( p_vol );
177 p_mute = new BCheckBox(BRect(300,10,355,25), "mute", "Mute",
178 new BMessage(VOLUME_MUTE));
179 p_view->AddChild( p_mute );
181 /* Set size and Show */
187 InterfaceWindow::~InterfaceWindow()
191 /*****************************************************************************
192 * InterfaceWindow::MessageReceived
193 *****************************************************************************/
194 void InterfaceWindow::MessageReceived( BMessage * p_message )
196 int vol_val = p_vol->Value(); // remember the current volume
197 static int playback_status; // remember playback state
200 switch( p_message->what )
205 // this currently stops playback not nicely
206 if (p_intf->p_input != NULL )
208 // silence the sound, otherwise very horrible
209 if (p_main->p_aout != NULL)
211 p_main->p_aout->vol = 0;
214 input_SetStatus(p_intf->p_input, INPUT_STATUS_END);
218 // starts playing in normal mode
219 // if (p_intf->p_input != NULL )
221 // if (p_main->p_aout != NULL)
223 // p_main->p_aout->vol = vol_val;
226 // input_SetStatus(p_intf->p_input, INPUT_STATUS_PLAY);
227 // playback_status = PLAYING;
231 // pause the playback
232 if (p_intf->p_input != NULL )
234 // mute the volume if currently playing
235 if (playback_status == PLAYING)
237 if (p_main->p_aout != NULL)
239 p_main->p_aout->vol = 0;
241 playback_status = PAUSED;
244 // restore the volume
246 if (p_main->p_aout != NULL)
248 p_main->p_aout->vol = vol_val;
250 playback_status = PLAYING;
253 input_SetStatus(p_intf->p_input, INPUT_STATUS_PAUSE);
257 // cycle the fast playback modes
258 if (p_intf->p_input != NULL )
260 if (p_main->p_aout != NULL)
262 p_main->p_aout->vol = 0;
265 input_SetStatus(p_intf->p_input, INPUT_STATUS_FASTER);
269 // cycle the slow playback modes
270 if (p_intf->p_input != NULL )
272 if (p_main->p_aout != NULL)
274 p_main->p_aout->vol = 0;
277 input_SetStatus(p_intf->p_input, INPUT_STATUS_SLOWER);
281 // handled by semaphores;
282 /* if( p_intf->p_input != NULL )
285 if (p_message->FindFloat("be:value", &new_position) == B_OK)
287 printf("%e\n", new_position);
288 input_Seek( p_intf->p_input, new_position * 100 );
294 if (p_main->p_aout != NULL)
296 p_main->p_aout->vol = vol_val;
301 if (p_main->p_aout != NULL)
303 if (p_mute->Value() == B_CONTROL_OFF)
305 p_main->p_aout->vol = vol_val;
309 p_main->p_aout->vol = 0;
318 if( p_message->FindRef( "refs", &ref ) == B_OK )
321 char * psz_name = strdup(path.Path());
322 intf_WarnMsg( 1, "intf: dropped text/uri-list data `%s'",
324 intf_PlstAdd( p_main->p_playlist, PLAYLIST_END, psz_name );
330 BWindow::MessageReceived( p_message );
335 /*****************************************************************************
336 * InterfaceWindow::QuitRequested
337 *****************************************************************************/
339 bool InterfaceWindow::QuitRequested()
346 /*****************************************************************************
348 *****************************************************************************/
349 SeekSlider::SeekSlider(BRect frame,
350 InterfaceWindow *owner,
353 thumb_style thumbType = B_TRIANGLE_THUMB)
354 :BSlider(frame, B_EMPTY_STRING, B_EMPTY_STRING,
355 NULL, minValue, maxValue, thumbType)
361 SeekSlider::~SeekSlider()
365 /*****************************************************************************
366 * SeekSlider::MouseDown
367 *****************************************************************************/
368 void SeekSlider::MouseDown(BPoint where)
370 BSlider::MouseDown(where);
371 fOwner->fScrubSem = create_sem(1, "Vlc::fScrubSem");
375 /*****************************************************************************
376 * SeekSlider::MouseUp
377 *****************************************************************************/
378 void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
380 BSlider::MouseMoved(where, code, message);
383 release_sem(fOwner->fScrubSem);
386 /*****************************************************************************
387 * SeekSlider::MouseUp
388 *****************************************************************************/
389 void SeekSlider::MouseUp(BPoint where)
391 BSlider::MouseUp(where);
392 delete_sem(fOwner->fScrubSem);
393 fOwner->fScrubSem = B_ERROR;
401 /*****************************************************************************
403 *****************************************************************************/
404 static int intf_Probe ( probedata_t *p_data );
405 static int intf_Open ( intf_thread_t *p_intf );
406 static void intf_Close ( intf_thread_t *p_intf );
407 static void intf_Run ( intf_thread_t *p_intf );
409 /*****************************************************************************
410 * Functions exported as capabilities. They are declared as static so that
411 * we don't pollute the namespace too much.
412 *****************************************************************************/
413 void _M( intf_getfunctions )( function_list_t * p_function_list )
415 p_function_list->pf_probe = intf_Probe;
416 p_function_list->functions.intf.pf_open = intf_Open;
417 p_function_list->functions.intf.pf_close = intf_Close;
418 p_function_list->functions.intf.pf_run = intf_Run;
421 /*****************************************************************************
422 * intf_Probe: probe the interface and return a score
423 *****************************************************************************
424 * This function tries to initialize Gnome and returns a score to the
425 * plugin manager so that it can select the best plugin.
426 *****************************************************************************/
427 static int intf_Probe( probedata_t *p_data )
429 if( TestMethod( INTF_METHOD_VAR, "beos" ) )
437 /*****************************************************************************
438 * intf_Open: initialize interface
439 *****************************************************************************/
440 static int intf_Open( intf_thread_t *p_intf )
442 /* Allocate instance and initialize some members */
443 p_intf->p_sys = (intf_sys_t*) malloc( sizeof( intf_sys_t ) );
444 if( p_intf->p_sys == NULL )
446 intf_ErrMsg("error: %s", strerror(ENOMEM));
449 p_intf->p_sys->i_key = -1;
451 /* Create the interface window */
452 p_intf->p_sys->p_window =
453 new InterfaceWindow( BRect( 50, 50, 400, 100 ),
454 VOUT_TITLE " (BeOS interface)", p_intf );
455 if( p_intf->p_sys->p_window == 0 )
457 free( p_intf->p_sys );
458 intf_ErrMsg( "error: cannot allocate memory for InterfaceWindow" );
465 /*****************************************************************************
466 * intf_Close: destroy dummy interface
467 *****************************************************************************/
468 static void intf_Close( intf_thread_t *p_intf )
470 /* Destroy the interface window */
471 p_intf->p_sys->p_window->Lock();
472 p_intf->p_sys->p_window->Quit();
474 /* Destroy structure */
475 free( p_intf->p_sys );
479 /*****************************************************************************
480 * intf_Run: event loop
481 *****************************************************************************/
482 static void intf_Run( intf_thread_t *p_intf )
486 bool seekNeeded = false;
488 while( !p_intf->b_die )
491 /* Manage core vlc functions through the callback */
492 p_intf->pf_manage( p_intf );
494 /* Manage the slider */
495 if( p_intf->p_input != NULL && p_intf->p_sys->p_window != NULL)
497 if (acquire_sem(p_intf->p_sys->p_window->fScrubSem) == B_OK)
504 uint32 seekTo = (p_intf->p_sys->p_window->p_seek->Value() *
505 p_intf->p_input->stream.p_selected_area->i_size) / 100;
506 input_Seek( p_intf->p_input, seekTo );
509 else if (p_intf->p_sys->p_window->Lock())
511 progress = (100. * p_intf->p_input->stream.p_selected_area->i_tell) /
512 p_intf->p_input->stream.p_selected_area->i_size;
513 p_intf->p_sys->p_window->p_seek->SetValue(progress);
514 p_intf->p_sys->p_window->Unlock();
519 msleep( INTF_IDLE_SLEEP );