session.cc
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:16k
- /* Copyright (C) 1998, 1999 State University of New York at Stony Brook
- Author: Andrew V. Shuvalov ( andrew@ecsl.cs.sunysb.edu )
- Software license is located in file "COPYING"
- */
- #include <gtk--.h>
- #include <fcntl.h>
- #include "gtk_main_win.h"
- #include "gtk_text_win.h"
- #include "gtk_search_win.h"
- #include "gtk_superuser.h"
- #include "db_connection.h"
- #include "word_db.h"
- #include "playback_window.h"
- #include "broadcast_win.h"
- #include "session.h"
- Session::Session( int *pargc, char ***pargv ) : Gtk_Main( pargc, pargv ),
- playbackWindow( 0 ), preferencesWindow( 0 ), searchSystem( 0 ),
- searchWindow( 0 ), suLoginWindow( 0 ), suPrefWindow( 0 ),
- broadcastWindow( NULL ), superuser( false )
- {
- // first init environment
- loadAllConfig();
- mainWindow = new MainWindow( *this );
- mainWindow->set_usize
- ( topWindowInitSizeX, topWindowInitSizeY );
- mainWindow->show();
- dbConnection = new DbConnection();
- wordDb = new WordDb();
- // add the timeout callback
- connect_to_method( Gtk_Main::timeout( 100 ),
- this, &Session::timeout );
- argv0 = *pargv[0];
- }
- void Session::cleanup()
- {
- cerr << "cleanup..." << endl;
- if( playbackWindow )
- {
- playbackWindow->prepare_to_die();
- delete playbackWindow;
- playbackWindow = 0;
- }
- }
- void Session::loadAllConfig()
- {
- string home = getenv( "HOME" );
- if( home.length() == 0 )
- throw GeneralException( "environment HOME must be defined" );
- mkdir( ( home + "/.vclient" ).c_str(), 0750 );
- gdbmMainConfigFile = home + "/.vclient/maincnf";
- GDBM_FILE dbf = gdbm_open( (char *)gdbmMainConfigFile.c_str(), 1024,
- GDBM_WRCREAT, 0750, NULL );
- if( !dbf )
- throw GeneralException( "can't open/create database %s",
- gdbmMainConfigFile.c_str() );
-
- // defaults
- homeLibPath.init( dbf, "Home path to vclient package", "homelib",
- "/usr/local/vclient", this );
- notLoadedPixmap.init
- ( dbf, "Pixmap of movie, not loaded locally", "notloadxpm",
- ( homeLibPath.str() + "/images/g_yellow.xpm" ).c_str(), this );
- loadedPixmap.init
- ( dbf, "Pixmap of movie loaded locally", "loadxpm",
- ( homeLibPath.str() + "/images/g_yellow_on.xpm" ).c_str(), this );
- PlayPixmap.init( dbf, "Play pixmap", "playxpm",
- ( homeLibPath.str() + "/images/play.xpm" ).c_str(), this );
- StopPixmap.init( dbf, "Stop pixmap", "stopxpm",
- ( homeLibPath.str() + "/images/stop.xpm" ).c_str(), this );
- RecPixmap.init( dbf, "Record pixmap", "recxpm",
- ( homeLibPath.str() + "/images/record.xpm" ).c_str(), this );
- movieDbServerName.init(dbf,"The name of movie database server", "dbservname",
- "localhost", this );
- movieDbServerSock.init( dbf, "TCP Socket of movie database server",
- "dbservsock", "7077", this );
- best1PushServIP.init( dbf, "IP of the most preferred push server",
- "best1puship", "127.0.0.1", this );
- best2PushServIP.init( dbf, "IP of the second preferred push server",
- "best2puship", "127.0.0.1", this );
- inputPushSock.init( dbf, "UDP Socket for incoming push-video server packets",
- "pushlocalsock", "7079", this );
- // pushVideoServerName.init(dbf, "The name of push-video server","pushservname",
- // "localhost", this );
- // pushVideoServerSock.init( dbf, "control UDP Socket of push-video server",
- // "pushservsock", "7078", this );
-
- // broadcastChannelNumber.init( dbf, "number of broadcast channels",
- // "channelsnum", "1", this );
- // reserve space in channels prefernces:
- // inputPushBroadcastServer.reserve( broadcastChannelNumber );
- // inputPushBroadcastSock.reserve( broadcastChannelNumber );
- // loop over all channels
- // for( int i = 0; i < broadcastChannelNumber; i++ )
- // {
- // char buf[10];
- // snprintf( buf, sizeof( buf ), "%d", i );
- // inputPushBroadcastServer[i] = new ConfigItemStr();
- // inputPushBroadcastServer[i]->init
- // ( dbf, ( string( "server name for incoming push-video broadcast "
- // "packets( Optional ). Channel " ) + buf ).c_str(),
- // ( string( "pushbroadcastserver" ) + buf ).c_str(),
- // "", this );
- // inputPushBroadcastSock[i] = new ConfigItemInt();
- // inputPushBroadcastSock[i]->init
- // ( dbf, ( string( "UDP Socket for incoming push-video "
- // "broadcast packets. Channel " ) + buf ).c_str(),
- // ( string( "pushbroadcastsock" ) + buf ).c_str(),
- // "7080", this );
- // }
- mtvPlayerName.init( dbf, "MpegTV player executable name",
- "mpegtvexec", "mtvp", this );
- mtvPlayerArguments.init( dbf, "MpegTV player execute arguments ( optional )",
- "mpegtvexargs", "", this );
- sihPlugin.init( dbf, "Video player SII plugin", "sihPlugin",
- "/usr/local/lib/libvclientsih.so", this );
- topWindowInitSizeX.init( dbf, "Initial X size of main window", "topxs",
- "600", this );
- topWindowInitSizeY.init( dbf, "Initial Y size of main window", "topys",
- "500", this );
- verbose.init( dbf, "Verbose level (0,1..)", "verbose",
- "1", this );
- vServVerbose.init(dbf, "Remote server verbose level (0,1..)",
- "verboseRemote", "1", this );
- receiveBufferSize.init( dbf, "Input Mpeg stream buffer size",
- "receiveBufferSize", "1000000", this );
- receiveBufferLowWaterMark.init( dbf, "Input buffer low water mark",
- "receiveBufferSize", "400000", this );
- receiveBufferHighWaterMark.init( dbf, "Input buffer low water mark",
- "receiveBufferSize", "800000", this );
- gdbm_close( dbf );
- }
- void Session::saveAllConfig()
- {
- GDBM_FILE dbf = gdbm_open( (char *)gdbmMainConfigFile.c_str(), 1024,
- GDBM_WRCREAT, 0750, NULL );
- if( !dbf )
- throw GeneralException( "can't open/create database %s",
- gdbmMainConfigFile.c_str() );
-
- for( int i = 0; i < configItems.size(); i++ )
- {
- configItems[i]->store( dbf );
- }
- gdbm_close( dbf );
- }
- void Session::run()
- {
- // default
- mainWindow->display_messagenl( "Start video server client" );
- connect_to_dbserver();
- vector< string > msgs;
- string dbname = dbConnection->get_database_name( msgs );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- // make this database current
- update_movie_list( dbname );
- Gtk_Main::run();
- }
- void Session::connect_to_dbserver()
- {
- if( dbConnection )
- {
- delete dbConnection;
- dbConnection = NULL;
- }
- try {
- dbConnection = new DbConnection();
- dbConnection->connect( movieDbServerName.c_str(),
- movieDbServerSock );
- vector< string > msgs;
- dbConnection->wait_input(); // this means that something is expected,
- // // at least the prompt
- dbConnection->skip_to_prompt( msgs );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- msgs.clear();
- // let's debug
- dbConnection->set_debug( msgs, verbose );
- // display current db name
- string dbname = dbConnection->get_database_name( msgs );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- msgs.clear();
- mainWindow->display_messagenl( "Connected to database " + dbname );
- mainWindow->display_database_name( dbname );
- }
- catch( NetworkException e ) {
- mainWindow->display_messagenl( "Network exception" );
- mainWindow->display_messagenl( e.getText() );
- }
- catch( SyntaxException e ) {
- mainWindow->display_messagenl( "Syntax exception" );
- mainWindow->display_messagenl( e.getText() );
- }
- catch( DatabaseException e ) {
- mainWindow->display_messagenl( "Database exception" );
- mainWindow->display_messagenl( e.getText() );
- delete dbConnection;
- dbConnection = NULL;
- }
- }
- void Session::update_movie_list( const string &dbname )
- {
- vector< string > msgs;
- if( !dbConnection )
- {
- connect_to_dbserver();
- }
- if( !dbConnection ) // still
- {
- put_message( 0, "update movie list: not connected" );
- return; // well, i'm sorry
- }
- try {
- dbConnection->load_new_database( msgs, dbname );
- } catch( DatabaseException e ) {
- mainWindow->display_messagenl( "Database exception" );
- mainWindow->display_messagenl( e.getText() );
- delete dbConnection;
- dbConnection = NULL;
- const map< int, MovieItem > movies;
- // display empty list
- mainWindow->update_movie_list( movies );
- return;
- }
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- msgs.clear();
- const map< int, MovieItem >& movies = dbConnection->get_movies();
- mainWindow->update_movie_list( movies );
- }
- // ----------------------------- called by mainWindow ----------------------
- const MovieItem &Session::get_movie_by_id( int id ) const
- {
- static MovieItem nothing;
- if( !dbConnection )
- return nothing;
-
- return dbConnection->get_movie_by_id( id );
- }
- void Session::display_movie_text_window( int id, time_t timepos )
- {
- if( textWindowsMap.find( id ) == textWindowsMap.end() )
- {
- // create
- TextWindow *win = new TextWindow( id, *this );
- textWindowsMap[ id ] = win;
- win->show();
- if( timepos > 0 )
- win->select_text_line_by_time( timepos );
- }
- else
- {
- textWindowsMap[ id ]->show();
- if( timepos > 0 )
- textWindowsMap[ id ]->select_text_line_by_time( timepos );
- }
- }
- void Session::display_movie_text_window_go_line( int id, unsigned linenum )
- {
- display_movie_text_window( id );
- textWindowsMap[ id ]->select_text_line( linenum );
- }
- void Session::edit_preferences()
- {
- if( !preferencesWindow )
- preferencesWindow = new PrefWindow( *this );
- preferencesWindow->show();
- }
- // ----------------------------- called by textWindow ----------------------
- const TextOfMovieT *Session::get_movie_text( int id )
- {
- if( !dbConnection )
- return NULL;
- {
- const TextOfMovieT *tom = wordDb->get_movie_text( id );
- if( tom )
- return tom;
- }
- // try to load text from database
- TextOfMovieT *tom = new TextOfMovieT();
- vector< string > msgs;
- dbConnection->load_movie_text( msgs, id, tom );
- wordDb->add_new_movie_text( id, tom );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- msgs.clear();
- mainWindow->update_pixmap_by_id( id );
- return tom;
- }
- bool Session::is_movie_text_loaded( int id )
- {
- const TextOfMovieT *tom = wordDb->get_movie_text( id );
- return tom != NULL;
- }
- int Session::close_text_window( GdkEventAny *ev )
- {
- int id = (int) gtk_object_get_user_data( GTK_OBJECT( ev->window ));
- cout << "destroy " << id << endl;
- if( textWindowsMap.find( id ) == textWindowsMap.end() )
- return 0;
- textWindowsMap[ id ] = NULL;
- textWindowsMap.erase( id );
- return 0;
- }
- void Session::menu_close_text_window( int id )
- {
- if( textWindowsMap.find( id ) == textWindowsMap.end() )
- return;
- cout << "destroy menu " << id << endl;
- textWindowsMap[ id ]->hide();
- }
- void Session::notify_text_win_die( int movieId )
- {
- if( textWindowsMap.find( movieId ) == textWindowsMap.end() )
- return;
- cout << "die " << movieId << endl;
- textWindowsMap[ movieId ] = NULL;
- // delete textWindowsMap[ movieId ];
- textWindowsMap.erase( movieId );
- }
- void Session::playVideo( TextWindow &tw, struct tm t, int id )
- {
- if( !dbConnection )
- return;
- vector< string > msgs;
- // stop(); - it's bad idea to close and reopen socket
- MovieFilesT movieFiles;
- dbConnection->getMovieFileListByTime( id, t, movieFiles, *this, msgs );
- if( !movieFiles.size() ) // nothing?
- {
- put_message( 1, "movie is empty, nothing to play" );
- return;
- }
- try {
- if( !playbackWindow )
- playbackWindow = new PlaybackWindow( argv0.c_str(), *this );
- playbackWindow->playback_mode( movieFiles, t, id );
- } catch ( PlayerException e ) {
- mainWindow->display_messagenl( e.getText() );
- delete playbackWindow;
- playbackWindow = 0;
- }
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- }
- void Session::playBroadcast( const string &url )
- {
- try {
- if( !playbackWindow )
- playbackWindow = new PlaybackWindow( argv0.c_str(), *this );
- playbackWindow->broadcast_mode( url );
- } catch ( PlayerException e ) {
- mainWindow->display_messagenl( e.getText() );
- delete playbackWindow;
- playbackWindow = 0;
- return;
- }
- }
- void Session::stop()
- {
- if( !playbackWindow )
- return;
- playbackWindow->stop();
- }
- void Session::start_recording( int channel_id )
- {
- if( !dbConnection )
- {
- put_message( 0, "!start recording: not connected" );
- return; // well, i'm sorry
- }
-
- vector< string > msgs;
- dbConnection->start_recording( channel_id, msgs );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- }
- void Session::stop_recording( int channel_id )
- {
- if( !dbConnection )
- {
- put_message( 0, "!stop recording: not connected" );
- return; // well, i'm sorry
- }
-
- vector< string > msgs;
- dbConnection->stop_recording( channel_id, msgs );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- }
- void Session::select_text_line_by_time( int movieId, time_t t )
- {
- textWindowsMapT::iterator win;
- win = textWindowsMap.find( movieId );
- if( win == textWindowsMap.end() )
- return;
- (*win).second->select_text_line_by_time( t );
- }
- /** called by broadcast window */
- void Session::fill_channellist( channel_infos_mapT &channel_infos_map )
- {
- try {
- if( !dbConnection )
- return;
- vector< string > msgs;
- dbConnection->fill_channellist( msgs, channel_infos_map );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- } catch( SyntaxException e ) {
- channel_infos_map.clear();
- put_message( 0, "fill_channellist: %s", e.getText().c_str() );
- }
- }
- /** this is main destroy application callback. called from main window
- */
- void Session::callback_destroy_session()
- {
- cleanup();
- cerr << "Hasta la vista!" << endl;
- }
- void Session::callback_search()
- {
- if( !searchWindow )
- searchWindow = new SearchWindow( *this );
- searchWindow->show();
- }
- void Session::callback_superuser()
- {
- if( !suLoginWindow )
- suLoginWindow = new SuLoginWindow( *this );
- suLoginWindow->show();
- }
- void Session::callback_server_preferences()
- {
- if( ! suPrefWindow )
- suPrefWindow = new SuperuserPreferenciesWindow( *this );
-
- suPrefWindow->show();
- }
- void Session::callback_broadcast()
- {
- if( !broadcastWindow )
- broadcastWindow = new BroadcastWindow( *this );
- broadcastWindow->show();
- }
- void Session::loadServerProperties( ServerConfigItemVec &props )
- {
- vector< string > msgs;
- if( dbConnection )
- dbConnection->loadServerProperties( msgs, props );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- }
- void Session::saveServerProperties( ServerConfigItemVec &props )
- {
- vector< string > msgs;
- if( dbConnection )
- dbConnection->saveServerProperties( msgs, props );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- }
- void Session::login_superuser( string passwd )
- {
- if( !dbConnection )
- return;
- vector< string > msgs;
- try
- {
- if( dbConnection->login_superuser( passwd, msgs ))
- {
- // success
- mainWindow->show_superuser_status( true );
- if( msgs.size() )
- mainWindow->display_messages( msgs );
- mainWindow->status_changed_to_superuser( true );
- }
- else
- mainWindow->display_messagenl( "Superuser login denied" );
- }
- catch( DatabaseException e )
- {
- delete dbConnection;
- dbConnection = NULL;
- mainWindow->display_messagenl( "Disconnected from database server" );
- }
- }
- // ----------------------------- called by timeout ----------------------
- gint Session::timeout()
- {
- try
- {
- if( playbackWindow )
- playbackWindow->timeout();
- }
- catch( PlayerException e ) {
- mainWindow->display_messagenl( "Player exception" );
- mainWindow->display_messagenl( e.getText() );
- delete playbackWindow;
- playbackWindow = NULL;
- }
- return true;
- }
- // ----------------------------- utils ---------------------------------
- void Session::put_message( int debl, const string &msg )
- {
- if( debl <= verbose )
- mainWindow->display_messagenl( msg );
- }
- void Session::put_message( int debl, const char *format, ... )
- {
- if( debl > verbose )
- return;
- va_list ap;
- va_start( ap, format );
- char buf[1024];
- vsnprintf( buf, sizeof( buf ), format, ap );
- mainWindow->display_messagenl( buf );
- va_end( ap );
- }
- // ----------*******---------- GeneralException ==========================
- GeneralException::GeneralException( const char *format, ... )
- {
- va_list ap;
- va_start( ap, format );
- init( format, ap );
- va_end( ap );
- }