]> git.sesse.net Git - vlc/blob - modules/gui/skins/src/skin_main.cpp
* modules/gui/skins/*, configure.ac.in: removed the skins plugin depandancy on msimg3...
[vlc] / modules / gui / skins / src / skin_main.cpp
1 /*****************************************************************************
2  * skin-main.cpp: skins plugin for VLC
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: skin_main.cpp,v 1.22 2003/04/29 12:54:57 gbazin Exp $
6  *
7  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8  *          Emmanuel Puig    <karibu@via.ecp.fr>
9  *
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.
14  *
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.
19  *
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,
23  * USA.
24  *****************************************************************************/
25
26 //--- GENERAL ---------------------------------------------------------------
27 #include <wx/wx.h>
28
29 //--- VLC -------------------------------------------------------------------
30 #include <vlc/vlc.h>
31 #include <vlc/intf.h>
32 #include <vlc/aout.h>
33
34 //--- SKIN ------------------------------------------------------------------
35 #include "../os_api.h"
36 #include "event.h"
37 #include "banks.h"
38 #include "window.h"
39 #include "theme.h"
40 #include "../os_theme.h"
41 #include "themeloader.h"
42 #include "vlcproc.h"
43 #include "skin_common.h"
44 #include "wxdialogs.h"
45
46 #ifdef X11_SKINS
47 #include <X11/Xlib.h>
48 #endif
49
50 //---------------------------------------------------------------------------
51 // Interface thread
52 // It is a global variable because we have C code for the parser, and we
53 // need to access C++ objects from there
54 //---------------------------------------------------------------------------
55 intf_thread_t *g_pIntf;
56
57 //---------------------------------------------------------------------------
58 // Exported interface functions.
59 //---------------------------------------------------------------------------
60 #ifdef WIN32
61 extern "C" __declspec( dllexport )
62     int __VLC_SYMBOL( vlc_entry ) ( module_t *p_module );
63 #endif
64
65 //---------------------------------------------------------------------------
66 // Local prototypes.
67 //---------------------------------------------------------------------------
68 static int  Open   ( vlc_object_t * );
69 static void Close  ( vlc_object_t * );
70 static void Run    ( intf_thread_t * );
71
72 int  SkinManage( intf_thread_t *p_intf );
73 void OSRun( intf_thread_t *p_intf );
74
75 //---------------------------------------------------------------------------
76 // Open: initialize interface
77 //---------------------------------------------------------------------------
78 static int Open ( vlc_object_t *p_this )
79 {
80     intf_thread_t *p_intf = (intf_thread_t *)p_this;
81     g_pIntf = p_intf;
82
83     // Allocate instance and initialize some members
84     p_intf->p_sys = (intf_sys_t *) malloc( sizeof( intf_sys_t ) );
85     if( p_intf->p_sys == NULL )
86     {
87         msg_Err( p_intf, "out of memory" );
88         return( 1 );
89     };
90
91     p_intf->pf_run = Run;
92
93
94     // Suscribe to messages bank
95     p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
96
97     // Set no new theme when opening file
98     p_intf->p_sys->p_new_theme_file = NULL;
99
100     // Initialize Win32 thread
101     p_intf->p_sys->i_index        = -1;
102     p_intf->p_sys->i_size         = 0;
103
104
105     p_intf->p_sys->i_close_status = VLC_NOTHING;
106
107     p_intf->p_sys->p_input = NULL;
108     p_intf->p_sys->p_playlist = (playlist_t *)vlc_object_find( p_intf,
109         VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
110
111 #ifdef GTK2_SKINS
112     // Initialize GDK
113     int    i_args   = 3;
114     char  *p_args[] = { "", "", "--sync", NULL };
115     char **pp_args  = p_args;
116
117     gdk_init( &i_args, &pp_args );
118
119 #elif defined X11_SKINS
120     // Initialize X11
121     p_intf->p_sys->display = XOpenDisplay( NULL );
122
123 #elif defined WIN32
124     // We dynamically load msimg32.dll to get a pointer to TransparentBlt()
125     p_intf->p_sys->h_msimg32_dll = LoadLibrary("msimg32.dll");
126     if( !p_intf->p_sys->h_msimg32_dll ||
127         !( p_intf->p_sys->TransparentBlt =
128            (BOOL (WINAPI*)(HDC,int,int,int,int,HDC,
129                            int,int,int,int,unsigned int))
130            GetProcAddress( p_intf->p_sys->h_msimg32_dll, "TransparentBlt" ) ) )
131     {
132         p_intf->p_sys->TransparentBlt = NULL;
133         msg_Dbg( p_intf, "Couldn't find TransparentBlt(), "
134                  "falling back to BitBlt()" );
135     }
136
137     // idem for user32.dll and SetLayeredWindowAttributes()
138     p_intf->p_sys->h_user32_dll = LoadLibrary("user32.dll");
139     if( !p_intf->p_sys->h_user32_dll ||
140         !( p_intf->p_sys->SetLayeredWindowAttributes =
141            (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))
142            GetProcAddress( p_intf->p_sys->h_user32_dll,
143                            "SetLayeredWindowAttributes" ) ) )
144     {
145         p_intf->p_sys->SetLayeredWindowAttributes = NULL;
146         msg_Dbg( p_intf, "Couldn't find SetLayeredWindowAttributes()" );
147     }
148
149 #endif
150
151     // Initialize conditions and mutexes
152     vlc_mutex_init( p_intf, &p_intf->p_sys->init_lock );
153     vlc_cond_init( p_intf, &p_intf->p_sys->init_cond );
154
155     p_intf->p_sys->p_theme = (Theme *)new OSTheme( p_intf );
156
157     return( 0 );
158 }
159
160 //---------------------------------------------------------------------------
161 // Close: destroy interface
162 //---------------------------------------------------------------------------
163 static void Close ( vlc_object_t *p_this )
164 {
165     intf_thread_t *p_intf = (intf_thread_t *)p_this;
166
167
168     if( p_intf->p_sys->p_input )
169     {
170         vlc_object_release( p_intf->p_sys->p_input );
171     }
172
173     if( p_intf->p_sys->p_playlist )
174     {
175         vlc_object_release( p_intf->p_sys->p_playlist );
176     }
177
178     // Delete theme, it's important to do it correctly
179     delete (OSTheme *)p_intf->p_sys->p_theme;
180
181     // Unsuscribe to messages bank
182     msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
183
184     // Destroy conditions and mutexes
185     vlc_cond_destroy( &p_intf->p_sys->init_cond );
186     vlc_mutex_destroy( &p_intf->p_sys->init_lock );
187
188 #ifdef WIN32
189     // Unload msimg32.dll and user32.dll
190     if( p_intf->p_sys->h_msimg32_dll )
191         FreeLibrary( p_intf->p_sys->h_msimg32_dll );
192     if( p_intf->p_sys->h_user32_dll )
193         FreeLibrary( p_intf->p_sys->h_user32_dll );
194 #endif
195
196     // Destroy structure
197     free( p_intf->p_sys );
198 }
199
200
201 //---------------------------------------------------------------------------
202 // Run: main loop
203 //---------------------------------------------------------------------------
204 static void Run( intf_thread_t *p_intf )
205 {
206
207     int a = OSAPI_GetTime();
208
209     // Load a theme
210     char *skin_last = config_GetPsz( p_intf, "skin_last" );
211     ThemeLoader *Loader = new ThemeLoader( p_intf );
212
213     if( skin_last == NULL || ! Loader->Load( skin_last ) )
214     {
215         // Too bad, it failed. Let's try with the default theme
216 #if 0
217         if( ! Loader->Load( DEFAULT_SKIN_FILE ) )
218 #else
219 #ifdef WIN32
220         string default_dir = (string)p_intf->p_libvlc->psz_vlcpath +
221                              DIRECTORY_SEPARATOR + "skins" +
222                              DIRECTORY_SEPARATOR + "default" +
223                              DIRECTORY_SEPARATOR + "theme.xml";
224 #else
225 // FIXME: find VLC directory 
226         string default_dir = (string)"./share" +
227                              DIRECTORY_SEPARATOR + "skins" +
228                              DIRECTORY_SEPARATOR + "default" +
229                              DIRECTORY_SEPARATOR + "theme.xml";
230 #endif
231         if( ! Loader->Load( default_dir ) )
232 #endif
233         {
234             // Last chance: the user can  select a new theme file
235             wxFileDialog dialog( NULL, _("Open a skin file"), "", "",
236                 "Skin files (*.vlt)|*.vlt|Skin files (*.xml)|*.xml|"
237                     "All files|*.*", wxOPEN );
238
239             if( dialog.ShowModal() == wxID_OK )
240             {
241                 // try to load selected file
242                 if( ! Loader->Load( dialog.GetPath().c_str() ) )
243                 {
244                     // He, he, what the hell is he doing ?
245                     delete Loader;
246                     return;
247                 }
248             }
249             else
250             {
251                 delete Loader;
252                 return;
253             }
254         }
255     }
256
257     // Show the theme
258     p_intf->p_sys->p_theme->InitTheme();
259     p_intf->p_sys->p_theme->ShowTheme();
260
261     delete Loader;
262
263     msg_Err( p_intf, "Load theme time : %i ms", OSAPI_GetTime() - a );
264
265     // Refresh the whole interface
266     OSAPI_PostMessage( NULL, VLC_INTF_REFRESH, 0, (int)true );
267
268     OSRun( p_intf );
269 }
270
271 //---------------------------------------------------------------------------
272 // Module descriptor
273 //---------------------------------------------------------------------------
274 #define DEFAULT_SKIN        N_("Last skin actually used")
275 #define DEFAULT_SKIN_LONG   N_("Last skin actually used")
276 #define SKIN_CONFIG         N_("Config of last used skin")
277 #define SKIN_CONFIG_LONG    N_("Config of last used skin")
278 #define SKIN_TRAY           N_("Show application in system tray")
279 #define SKIN_TRAY_LONG      N_("Show application in system tray")
280 #define SKIN_TASKBAR        N_("Show application in taskbar")
281 #define SKIN_TASKBAR_LONG   N_("Show application in taskbar")
282
283 vlc_module_begin();
284     add_string( "skin_last", "", NULL, DEFAULT_SKIN, DEFAULT_SKIN_LONG,
285                 VLC_TRUE );
286     add_string( "skin_config", "", NULL, SKIN_CONFIG, SKIN_CONFIG_LONG,
287                 VLC_TRUE );
288     add_bool( "show_in_tray", VLC_FALSE, NULL, SKIN_TRAY, SKIN_TRAY_LONG,
289               VLC_FALSE );
290     add_bool( "show_in_taskbar", VLC_TRUE, NULL, SKIN_TASKBAR,
291               SKIN_TASKBAR_LONG, VLC_FALSE );
292     set_description( _("Skinnable Interface") );
293     set_capability( "interface", 30 );
294     set_callbacks( Open, Close );
295     add_shortcut( "skins" );
296 vlc_module_end();
297
298
299 //---------------------------------------------------------------------------
300 // Refresh procedure
301 //---------------------------------------------------------------------------
302 int SkinManage( intf_thread_t *p_intf )
303 {
304     vlc_mutex_lock( &p_intf->change_lock );
305
306     // Update the input
307     if( p_intf->p_sys->p_input == NULL )
308     {
309         p_intf->p_sys->p_input = (input_thread_t *)
310                     vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
311     }
312     else if( p_intf->p_sys->p_input->b_dead )
313     {
314         vlc_object_release( p_intf->p_sys->p_input );
315         p_intf->p_sys->p_input = NULL;
316     }
317
318     OSAPI_PostMessage( NULL, VLC_INTF_REFRESH, 0, (long)false );
319
320     // Update the log window
321     p_intf->p_sys->MessagesDlg->UpdateLog();
322
323     // Update the file info window
324     p_intf->p_sys->InfoDlg->UpdateFileInfo();
325
326     //-------------------------------------------------------------------------
327     if( p_intf->p_sys->p_input != NULL && !p_intf->p_sys->p_input->b_die )
328     {
329         input_thread_t  * p_input = p_intf->p_sys->p_input;
330
331         vlc_mutex_lock( &p_input->stream.stream_lock );
332
333         // Refresh sound volume
334         audio_volume_t volume;
335
336         // Get sound volume from VLC
337         aout_VolumeGet( p_intf, &volume);
338
339         // Update sliders
340         OSAPI_PostMessage( NULL, CTRL_SET_SLIDER,
341             (unsigned int)
342             p_intf->p_sys->p_theme->EvtBank->Get( "volume_refresh" ),
343             (long)( volume * SLIDER_RANGE / AOUT_VOLUME_MAX ) );
344
345
346         // Refresh slider
347         // if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )
348         if( p_input->stream.b_seekable )
349         {
350 #define p_area p_input->stream.p_selected_area
351
352             // Set value of sliders
353             long Value = SLIDER_RANGE *
354                 p_input->stream.p_selected_area->i_tell /
355                 p_input->stream.p_selected_area->i_size;
356
357             // Update sliders
358             OSAPI_PostMessage( NULL, CTRL_SET_SLIDER, (unsigned int)
359                 p_intf->p_sys->p_theme->EvtBank->Get( "time" ), (long)Value );
360
361             // Text char * for updating text controls
362             char *text = new char[OFFSETTOTIME_MAX_SIZE];
363
364             // Create end time text
365             input_OffsetToTime( p_intf->p_sys->p_input, &text[1],
366                                 p_area->i_size - p_area->i_tell );
367             text[0] = '-';
368             p_intf->p_sys->p_theme->EvtBank->Get( "left_time" )
369                 ->PostTextMessage( text );
370
371             // Create time text and update
372             input_OffsetToTime( p_intf->p_sys->p_input, text, p_area->i_tell );
373             p_intf->p_sys->p_theme->EvtBank->Get( "time" )
374                 ->PostTextMessage( text );
375
376             // Create total time text
377             input_OffsetToTime( p_intf->p_sys->p_input, text, p_area->i_size );
378             p_intf->p_sys->p_theme->EvtBank->Get( "total_time" )
379                 ->PostTextMessage( text );
380
381             // Free memory
382             delete[] text;
383
384 #undef p_area
385         }
386         vlc_mutex_unlock( &p_input->stream.stream_lock );
387     }
388     //-------------------------------------------------------------------------
389     vlc_mutex_unlock( &p_intf->change_lock );
390
391     return( VLC_TRUE );
392 }