00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031
00032 #include <vlc/vlc.h>
00033 #include <vlc/intf.h>
00034
00035 #ifdef HAVE_LOCALE_H
00036 # include <locale.h>
00037 #endif
00038
00039 #include "wxwidgets.h"
00040
00041
00042 #if defined(WIN32) && defined(_WX_INIT_H_)
00043 #if (wxMAJOR_VERSION <= 2) && (wxMINOR_VERSION <= 5) && (wxRELEASE_NUMBER < 3)
00044
00045 extern int wxEntry( HINSTANCE hInstance, HINSTANCE hPrevInstance = NULL,
00046 char *pCmdLine = NULL, int nCmdShow = SW_NORMAL );
00047 #endif
00048 #endif
00049
00050
00051
00052
00053 static int Open ( vlc_object_t * );
00054 static void Close ( vlc_object_t * );
00055 static int OpenDialogs ( vlc_object_t * );
00056
00057 static void Run ( intf_thread_t * );
00058 static void Init ( intf_thread_t * );
00059
00060 static void ShowDialog ( intf_thread_t *, int, int, intf_dialog_args_t * );
00061
00062 #if (wxCHECK_VERSION(2,5,0))
00063 void *wxClassInfo_sm_classTable_BUGGY = 0;
00064 #endif
00065
00066
00067
00068
00069 class Instance: public wxApp
00070 {
00071 public:
00072 Instance();
00073 Instance( intf_thread_t *_p_intf );
00074
00075 bool OnInit();
00076 int OnExit();
00077
00078 private:
00079 intf_thread_t *p_intf;
00080 wxLocale locale;
00081 };
00082
00083
00084
00085
00086 #define EMBED_TEXT N_("Embed video in interface")
00087 #define EMBED_LONGTEXT N_("Embed the video inside the interface instead " \
00088 "of having it in a separate window.")
00089 #define BOOKMARKS_TEXT N_("Show bookmarks dialog")
00090 #define BOOKMARKS_LONGTEXT N_("Show bookmarks dialog when the interface " \
00091 "starts.")
00092 #define EXTENDED_TEXT N_("Show extended GUI")
00093 #define EXTENDED_LONGTEXT N_("Show extended GUI")
00094 #define TASKBAR_TEXT N_("Show taskbar entry")
00095 #define TASKBAR_LONGTEXT N_("Show taskbar entry")
00096 #define MINIMAL_TEXT N_("Minimal interface")
00097 #define MINIMAL_LONGTEXT N_("Use minimal interface, no toolbar, few menus")
00098 #define SIZE_TO_VIDEO_TEXT N_("Size to video")
00099 #define SIZE_TO_VIDEO_LONGTEXT N_("Resize VLC to match the video resolution")
00100 #define SYSTRAY_TEXT N_("Show systray icon")
00101 #define SYSTRAY_LONGTEXT N_("Show systray icon")
00102
00103 vlc_module_begin();
00104 #ifdef WIN32
00105 int i_score = 150;
00106 #else
00107 int i_score = getenv( "DISPLAY" ) == NULL ? 15 : 150;
00108 #endif
00109 set_shortname( (char*) "wxWidgets" );
00110 set_description( (char *) _("wxWidgets interface module") );
00111 set_category( CAT_INTERFACE );
00112 set_subcategory( SUBCAT_INTERFACE_GENERAL );
00113 set_capability( "interface", i_score );
00114 set_callbacks( Open, Close );
00115 add_shortcut( "wxwindows" );
00116 add_shortcut( "wxwin" );
00117 add_shortcut( "wx" );
00118 add_shortcut( "wxwidgets" );
00119 set_program( "wxvlc" );
00120
00121 add_bool( "wx-embed", 1, NULL,
00122 EMBED_TEXT, EMBED_LONGTEXT, VLC_FALSE );
00123 add_deprecated( "wxwin-enbed", VLC_FALSE);
00124 add_bool( "wx-bookmarks", 0, NULL,
00125 BOOKMARKS_TEXT, BOOKMARKS_LONGTEXT, VLC_FALSE );
00126 add_deprecated( "wxwin-bookmarks", VLC_FALSE);
00127 add_bool( "wx-taskbar", 1, NULL,
00128 TASKBAR_TEXT, TASKBAR_LONGTEXT, VLC_FALSE );
00129 add_deprecated( "wxwin-taskbar", VLC_FALSE);
00130 add_bool( "wx-extended", 0, NULL,
00131 EXTENDED_TEXT, EXTENDED_LONGTEXT, VLC_FALSE );
00132 add_bool( "wx-minimal", 0, NULL,
00133 MINIMAL_TEXT, MINIMAL_LONGTEXT, VLC_TRUE );
00134 add_deprecated( "wxwin-minimal", VLC_FALSE);
00135 add_bool( "wx-autosize", 1, NULL,
00136 SIZE_TO_VIDEO_TEXT, SIZE_TO_VIDEO_LONGTEXT, VLC_TRUE );
00137 add_deprecated( "wxwin-autosize", VLC_FALSE);
00138 #ifdef wxHAS_TASK_BAR_ICON
00139 add_bool( "wx-systray", 0, NULL,
00140 SYSTRAY_TEXT, SYSTRAY_LONGTEXT, VLC_FALSE );
00141 add_deprecated( "wxwin-systray", VLC_FALSE);
00142 #endif
00143 add_string( "wx-config-last", NULL, NULL,
00144 "last config", "last config", VLC_TRUE );
00145 change_autosave();
00146 add_deprecated( "wxwin-config-last", VLC_FALSE);
00147
00148 add_submodule();
00149 set_description( _("wxWidgets dialogs provider") );
00150 set_capability( "dialogs provider", 50 );
00151 set_callbacks( OpenDialogs, Close );
00152
00153 #if !defined(WIN32)
00154 linked_with_a_crap_library_which_uses_atexit();
00155 #endif
00156 vlc_module_end();
00157
00158
00159
00160
00161 static int Open( vlc_object_t *p_this )
00162 {
00163 intf_thread_t *p_intf = (intf_thread_t *)p_this;
00164
00165
00166 p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
00167 if( p_intf->p_sys == NULL )
00168 {
00169 msg_Err( p_intf, "out of memory" );
00170 return VLC_ENOMEM;
00171 }
00172 memset( p_intf->p_sys, 0, sizeof( intf_sys_t ) );
00173
00174 p_intf->pf_run = Run;
00175
00176 p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
00177
00178
00179 p_intf->p_sys->b_playing = 0;
00180
00181 p_intf->p_sys->p_input = NULL;
00182 p_intf->p_sys->i_playing = -1;
00183 p_intf->p_sys->b_slider_free = 1;
00184 p_intf->p_sys->i_slider_pos = p_intf->p_sys->i_slider_oldpos = 0;
00185
00186 p_intf->p_sys->p_popup_menu = NULL;
00187 p_intf->p_sys->p_video_window = NULL;
00188
00189 p_intf->pf_show_dialog = NULL;
00190
00191
00192 p_intf->b_play = VLC_TRUE;
00193
00194 p_intf->p_sys->b_video_autosize =
00195 config_GetInt( p_intf, "wx-autosize" );
00196
00197 return VLC_SUCCESS;
00198 }
00199
00200 static int OpenDialogs( vlc_object_t *p_this )
00201 {
00202 intf_thread_t *p_intf = (intf_thread_t *)p_this;
00203 int i_ret = Open( p_this );
00204
00205 p_intf->pf_show_dialog = ShowDialog;
00206
00207 return i_ret;
00208 }
00209
00210
00211
00212
00213 static void Close( vlc_object_t *p_this )
00214 {
00215 intf_thread_t *p_intf = (intf_thread_t *)p_this;
00216
00217 vlc_mutex_lock( &p_intf->object_lock );
00218 p_intf->b_dead = VLC_TRUE;
00219 vlc_mutex_unlock( &p_intf->object_lock );
00220
00221 if( p_intf->pf_show_dialog )
00222 {
00223
00224 wxCommandEvent event( wxEVT_DIALOG, INTF_DIALOG_EXIT );
00225 p_intf->p_sys->p_wxwindow->AddPendingEvent( event );
00226 vlc_thread_join( p_intf );
00227 }
00228
00229 msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
00230
00231
00232 delete p_intf->p_sys->p_window_settings;
00233
00234 #if (wxCHECK_VERSION(2,5,0))
00235 wxClassInfo::sm_classTable = (wxHashTable*)wxClassInfo_sm_classTable_BUGGY;
00236 #endif
00237
00238
00239 free( p_intf->p_sys );
00240 }
00241
00242
00243
00244
00245
00246
00247 #if !defined(__BUILTIN__) && defined( WIN32 )
00248 HINSTANCE hInstance = 0;
00249 extern "C" BOOL WINAPI
00250 DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
00251 {
00252 hInstance = (HINSTANCE)hModule;
00253 return TRUE;
00254 }
00255 #endif
00256
00257 static void Run( intf_thread_t *p_intf )
00258 {
00259 if( p_intf->pf_show_dialog )
00260 {
00261
00262
00263
00264 if( vlc_thread_create( p_intf, "Skins Dialogs Thread",
00265 Init, 0, VLC_TRUE ) )
00266 {
00267 msg_Err( p_intf, "cannot create Skins Dialogs Thread" );
00268 p_intf->pf_show_dialog = NULL;
00269 }
00270 }
00271 else
00272 {
00273
00274 Init( p_intf );
00275 }
00276 }
00277
00278 static void Init( intf_thread_t *p_intf )
00279 {
00280 #if !defined( WIN32 )
00281 static char *p_args[] = { "" };
00282 int i_args = 1;
00283 #endif
00284
00285
00286 #ifdef wxTheApp
00287 wxApp::SetInstance( new Instance( p_intf ) );
00288 #else
00289 wxTheApp = new Instance( p_intf );
00290 #endif
00291
00292 #if defined( WIN32 )
00293 #if !defined(__BUILTIN__)
00294
00295
00296 if (hInstance == NULL)
00297 hInstance = GetModuleHandle(NULL);
00298
00299 wxEntry( hInstance, NULL, NULL, SW_SHOW );
00300 #else
00301 wxEntry( GetModuleHandle(NULL), NULL, NULL, SW_SHOW );
00302 #endif
00303 #else
00304 wxEntry( i_args, p_args );
00305 #endif
00306 setlocale( LC_NUMERIC, "C" );
00307 }
00308
00309
00310
00311
00312
00313
00314 Instance::Instance( )
00315 {
00316 }
00317
00318 Instance::Instance( intf_thread_t *_p_intf )
00319 {
00320
00321 p_intf = _p_intf;
00322 }
00323
00324 IMPLEMENT_APP_NO_MAIN(Instance)
00325
00326
00327
00328
00329
00330
00331
00332 bool Instance::OnInit()
00333 {
00334
00335
00336
00337 locale.Init( wxLANGUAGE_DEFAULT, wxLOCALE_LOAD_DEFAULT );
00338 setlocale( LC_NUMERIC, "C" );
00339
00340
00341 p_intf->p_sys->p_window_settings = new WindowSettings( p_intf );
00342
00343
00344
00345
00346
00347 if( !p_intf->pf_show_dialog )
00348 {
00349
00350 long style = wxDEFAULT_FRAME_STYLE;
00351 if ( ! config_GetInt( p_intf, "wx-taskbar" ) )
00352 {
00353 style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR;
00354 }
00355
00356 Interface *MainInterface = new Interface( p_intf, style );
00357 p_intf->p_sys->p_wxwindow = MainInterface;
00358
00359
00360 MainInterface->Show( TRUE );
00361 SetTopWindow( MainInterface );
00362 MainInterface->Raise();
00363 }
00364
00365
00366 p_intf->p_sys->p_wxwindow =
00367 CreateDialogsProvider( p_intf, p_intf->pf_show_dialog ?
00368 NULL : p_intf->p_sys->p_wxwindow );
00369
00370 p_intf->p_sys->pf_show_dialog = ShowDialog;
00371
00372
00373 vlc_thread_ready( p_intf );
00374
00375
00376 if( !p_intf->pf_show_dialog && p_intf->b_play )
00377 {
00378 playlist_t *p_playlist =
00379 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00380 FIND_ANYWHERE );
00381 if( p_playlist )
00382 {
00383 playlist_LockControl( p_playlist, PLAYLIST_AUTOPLAY );
00384 vlc_object_release( p_playlist );
00385 }
00386 }
00387
00388
00389 return TRUE;
00390 }
00391
00392
00393
00394
00395 int Instance::OnExit()
00396 {
00397 if( p_intf->pf_show_dialog )
00398 {
00399
00400 if( p_intf->p_sys->p_wxwindow ) delete p_intf->p_sys->p_wxwindow;
00401 }
00402
00403 #if (wxCHECK_VERSION(2,5,0))
00404 wxClassInfo_sm_classTable_BUGGY = wxClassInfo::sm_classTable;
00405 wxClassInfo::sm_classTable = 0;
00406 #endif
00407
00408 return 0;
00409 }
00410
00411 static void ShowDialog( intf_thread_t *p_intf, int i_dialog_event, int i_arg,
00412 intf_dialog_args_t *p_arg )
00413 {
00414 wxCommandEvent event( wxEVT_DIALOG, i_dialog_event );
00415 event.SetInt( i_arg );
00416 event.SetClientData( p_arg );
00417
00418 #ifdef WIN32
00419 SendMessage( (HWND)p_intf->p_sys->p_wxwindow->GetHandle(),
00420 WM_CANCELMODE, 0, 0 );
00421 #endif
00422 if( i_dialog_event == INTF_DIALOG_POPUPMENU && i_arg == 0 ) return;
00423
00424
00425
00426 if( i_dialog_event != INTF_DIALOG_POPUPMENU ||
00427 !p_intf->p_sys->p_popup_menu )
00428 {
00429 p_intf->p_sys->p_wxwindow->AddPendingEvent( event );
00430 }
00431 }
00432
00433
00434
00435
00436 WindowSettings::WindowSettings( intf_thread_t *_p_intf )
00437 {
00438 char *psz_org = NULL;
00439 char *psz;
00440 int i;
00441
00442
00443 p_intf = _p_intf;
00444
00445
00446 for( i = 0; i < ID_MAX; i++ )
00447 {
00448 b_valid[i] = false;
00449 b_shown[i] = false;
00450 position[i] = wxDefaultPosition;
00451 size[i] = wxDefaultSize;
00452 }
00453 b_shown[ID_MAIN] = true;
00454
00455 if( p_intf->pf_show_dialog ) return;
00456
00457
00458 psz_org = psz = config_GetPsz( p_intf, "wx-config-last" );
00459 if( !psz || *psz == '\0' ) return;
00460
00461 msg_Dbg( p_intf, "Using last windows config '%s'", psz );
00462
00463 i_screen_w = 0;
00464 i_screen_h = 0;
00465 while( psz && *psz )
00466 {
00467 int id, v[4];
00468
00469 psz = strchr( psz, '(' );
00470
00471 if( !psz )
00472 break;
00473 psz++;
00474
00475 id = strtol( psz, &psz, 0 );
00476 if( *psz != ',' )
00477 goto invalid;
00478 psz++;
00479
00480 for( i = 0; i < 4; i++ )
00481 {
00482 v[i] = strtol( psz, &psz, 0 );
00483
00484 if( i < 3 )
00485 {
00486 if( *psz != ',' )
00487 goto invalid;
00488 psz++;
00489 }
00490 else
00491 {
00492 if( *psz != ')' )
00493 goto invalid;
00494 }
00495 }
00496 if( id == ID_SCREEN )
00497 {
00498 i_screen_w = v[2];
00499 i_screen_h = v[3];
00500 }
00501 else if( id >= 0 && id < ID_MAX )
00502 {
00503 b_valid[id] = true;
00504 b_shown[id] = true;
00505 position[id] = wxPoint( v[0], v[1] );
00506 size[id] = wxSize( v[2], v[3] );
00507
00508 msg_Dbg( p_intf, "id=%d p=(%d,%d) s=(%d,%d)",
00509 id, position[id].x, position[id].y,
00510 size[id].x, size[id].y );
00511 }
00512
00513 psz = strchr( psz, ')' );
00514 if( psz ) psz++;
00515 }
00516
00517 if( i_screen_w <= 0 || i_screen_h <= 0 )
00518 goto invalid;
00519
00520 for( i = 0; i < ID_MAX; i++ )
00521 {
00522 if( !b_valid[i] )
00523 continue;
00524 if( position[i].x < 0 || position[i].y < 0 )
00525 goto invalid;
00526 if( size[i].x <= 0 || size[i].y <= 0 )
00527 goto invalid;
00528 }
00529
00530 if( psz_org ) free( psz_org );
00531 return;
00532
00533 invalid:
00534 msg_Dbg( p_intf, "last windows config is invalid (ignored)" );
00535 for( i = 0; i < ID_MAX; i++ )
00536 {
00537 b_valid[i] = false;
00538 b_shown[i] = false;
00539 position[i] = wxDefaultPosition;
00540 size[i] = wxDefaultSize;
00541 }
00542 if( psz_org ) free( psz_org );
00543 }
00544
00545
00546 WindowSettings::~WindowSettings( )
00547 {
00548 wxString sCfg;
00549
00550 if( p_intf->pf_show_dialog ) return;
00551
00552 sCfg = wxString::Format( wxT("(%d,0,0,%d,%d)"), ID_SCREEN,
00553 wxSystemSettings::GetMetric( wxSYS_SCREEN_X ),
00554 wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ) );
00555 for( int i = 0; i < ID_MAX; i++ )
00556 {
00557 if( !b_valid[i] || !b_shown[i] )
00558 continue;
00559
00560 sCfg += wxString::Format( wxT("(%d,%d,%d,%d,%d)"),
00561 i, position[i].x, position[i].y,
00562 size[i].x, size[i].y );
00563 }
00564
00565 config_PutPsz( p_intf, "wx-config-last", sCfg.mb_str() );
00566 }
00567
00568 void WindowSettings::SetScreen( int i_screen_w, int i_screen_h )
00569 {
00570 int i;
00571
00572 for( i = 0; i < ID_MAX; i++ )
00573 {
00574 if( !b_valid[i] )
00575 continue;
00576 if( position[i].x >= i_screen_w || position[i].y >= i_screen_h )
00577 goto invalid;
00578 }
00579 return;
00580
00581 invalid:
00582 for( i = 0; i < ID_MAX; i++ )
00583 {
00584 b_valid[i] = false;
00585 b_shown[i] = false;
00586 position[i] = wxDefaultPosition;
00587 size[i] = wxDefaultSize;
00588 }
00589 }
00590
00591 void WindowSettings::SetSettings( int id, bool _b_shown, wxPoint p, wxSize s )
00592 {
00593 if( id < 0 || id >= ID_MAX )
00594 return;
00595
00596 b_valid[id] = true;
00597 b_shown[id] = _b_shown;
00598
00599 position[id] = p;
00600 size[id] = s;
00601 }
00602
00603 bool WindowSettings::GetSettings( int id, bool& _b_shown, wxPoint& p, wxSize& s)
00604 {
00605 if( id < 0 || id >= ID_MAX )
00606 return false;
00607
00608 if( !b_valid[id] )
00609 return false;
00610
00611 _b_shown = b_shown[id];
00612 p = position[id];
00613 s = size[id];
00614
00615 return true;
00616 }