]> git.sesse.net Git - vlc/blob - src/vlc.c
36cf1f322cd6f97c23901a65a3767805d7273d3b
[vlc] / src / vlc.c
1 /*****************************************************************************
2  * vlc.c: the vlc player
3  *****************************************************************************
4  * Copyright (C) 1998-2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Vincent Seguin <seguin@via.ecp.fr>
8  *          Samuel Hocevar <sam@zoy.org>
9  *          Gildas Bazin <gbazin@netcourrier.com>
10  *          Derk-Jan Hartman <hartman at videolan dot org>
11  *          Lots of other people, see the libvlc AUTHORS file
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
26  *****************************************************************************/
27
28 #include "config.h"
29
30 #include <stdio.h>                                              /* fprintf() */
31 #include <stdlib.h>                                  /* putenv(), strtol(),  */
32 #ifdef HAVE_SIGNAL_H
33 #   include <signal.h>                            /* SIGHUP, SIGINT, SIGKILL */
34 #endif
35 #ifdef HAVE_TIME_H
36 #   include <time.h>                                               /* time() */
37 #endif
38 #ifdef HAVE_STRINGS_H
39 #   include <strings.h>                                         /* strncmp() */
40 #endif
41
42 #include <vlc/vlc.h>
43
44 #ifdef SYS_DARWIN
45 #include <Cocoa/Cocoa.h>
46 #endif
47
48 /*****************************************************************************
49  * Local prototypes.
50  *****************************************************************************/
51 #ifndef WIN32
52 static void SigHandler  ( int i_signal );
53 #endif
54
55 #ifdef SYS_DARWIN
56 /*****************************************************************************
57  * VLCApplication interface
58  *****************************************************************************/
59 @interface VLCApplication : NSApplication
60 {
61 }
62
63 @end
64
65 /*****************************************************************************
66  * VLCApplication implementation 
67  *****************************************************************************/
68 @implementation VLCApplication 
69
70 - (void)stop: (id)sender
71 {
72     NSEvent *o_event;
73     [super stop:sender];
74
75     /* send a dummy event to break out of the event loop */
76     o_event = [NSEvent mouseEventWithType: NSLeftMouseDown
77                 location: NSMakePoint( 1, 1 ) modifierFlags: 0
78                 timestamp: 1 windowNumber: [[NSApp mainWindow] windowNumber]
79                 context: [NSGraphicsContext currentContext] eventNumber: 1
80                 clickCount: 1 pressure: 0.0];
81     [NSApp postEvent: o_event atStart: YES];
82 }
83
84 - (void)terminate: (id)sender
85 {
86     if( [NSApp isRunning] )
87         [NSApp stop:sender];
88     [super terminate: sender];
89 }
90
91 @end
92
93 #endif /* SYS_DARWIN */
94
95 /*****************************************************************************
96  * main: parse command line, start interface and spawn threads.
97  *****************************************************************************/
98 int main( int i_argc, char *ppsz_argv[] )
99 {
100     int i_ret;
101     int b_cli = VLC_FALSE ;
102
103 #ifndef SYS_DARWIN
104     /* This clutters OSX GUI error logs */
105     fprintf( stderr, "VLC media player %s\n", VLC_Version() );
106 #endif
107
108 #ifdef HAVE_PUTENV
109 #   ifdef DEBUG
110     /* Activate malloc checking routines to detect heap corruptions. */
111     putenv( "MALLOC_CHECK_=2" );
112
113     /* Disable the ugly Gnome crash dialog so that we properly segfault */
114     putenv( "GNOME_DISABLE_CRASH_DIALOG=1" );
115 #   endif
116
117     /* If the user isn't using VLC_VERBOSE, set it to 0 by default */
118     if( getenv( "VLC_VERBOSE" ) == NULL )
119     {
120         putenv( "VLC_VERBOSE=0" );
121     }
122 #endif
123
124     /* Create a libvlc structure */
125     i_ret = VLC_Create();
126     if( i_ret < 0 )
127     {
128         return i_ret;
129     }
130
131 #ifndef WIN32
132     /* Set the signal handlers. SIGTERM is not intercepted, because we need at
133      * least one method to kill the program when all other methods failed, and
134      * when we don't want to use SIGKILL.
135      * Note that we set the signals after the vlc_create call. */
136     signal( SIGINT,  SigHandler );
137     signal( SIGHUP,  SigHandler );
138     signal( SIGQUIT, SigHandler );
139
140     /* Other signals */
141     signal( SIGALRM, SIG_IGN );
142     signal( SIGPIPE, SIG_IGN );
143 #endif
144
145     /* Initialize libvlc */
146     i_ret = VLC_Init( 0, i_argc, ppsz_argv );
147     if( i_ret < 0 )
148     {
149         VLC_Destroy( 0 );
150         return i_ret;
151     }
152
153 #ifdef HAVE_STRINGS_H
154     /* if first 3 chars of argv[0] are cli, then this is clivlc
155      * We detect this specifically for Mac OS X, so you can launch vlc
156      * from the commandline even if you are not logged in on the GUI */
157     if( i_argc > 0 )
158     {
159         char *psz_temp;
160         char *psz_program = psz_temp = ppsz_argv[0];
161         while( *psz_temp )
162         {
163             if( *psz_temp == '/' ) psz_program = ++psz_temp;
164             else ++psz_temp;
165         }
166         b_cli = !strncmp( psz_program, "cli", 3 );
167     }
168 #endif
169
170 #ifdef SYS_DARWIN
171     if( !b_cli )
172     {
173         [VLCApplication sharedApplication];
174     }
175
176     i_ret = VLC_AddIntf( 0, NULL, VLC_TRUE, VLC_TRUE );
177     
178     if( !b_cli )
179     {
180         /* This is a blocking call */
181         [NSApp run];
182     }
183 #else
184     i_ret = VLC_AddIntf( 0, NULL, VLC_TRUE, VLC_TRUE );
185 #endif /* SYS_DARWIN */
186
187     /* Finish the threads */
188     VLC_CleanUp( 0 );
189
190     /* Destroy the libvlc structure */
191     VLC_Destroy( 0 );
192
193 #ifdef SYS_DARWIN
194     if( !b_cli )
195     {
196         [NSApp terminate:NULL];
197     }
198 #endif /* SYS_DARWIN */
199
200     return i_ret;
201 }
202
203 #ifndef WIN32
204 /*****************************************************************************
205  * SigHandler: system signal handler
206  *****************************************************************************
207  * This function is called when a fatal signal is received by the program.
208  * It tries to end the program in a clean way.
209  *****************************************************************************/
210 static void SigHandler( int i_signal )
211 {
212     static time_t abort_time = 0;
213     static volatile vlc_bool_t b_die = VLC_FALSE;
214
215     /* Once a signal has been trapped, the termination sequence will be
216      * armed and subsequent signals will be ignored to avoid sending signals
217      * to a libvlc structure having been destroyed */
218
219     if( !b_die )
220     {
221         b_die = VLC_TRUE;
222         abort_time = time( NULL );
223
224         fprintf( stderr, "signal %d received, terminating vlc - do it "
225                          "again in case it gets stuck\n", i_signal );
226
227         /* Acknowledge the signal received */
228         VLC_Die( 0 );
229     }
230     else if( time( NULL ) > abort_time + 2 )
231     {
232         /* If user asks again 1 or 2 seconds later, die badly */
233         signal( SIGINT,  SIG_DFL );
234         signal( SIGHUP,  SIG_DFL );
235         signal( SIGQUIT, SIG_DFL );
236         signal( SIGALRM, SIG_DFL );
237         signal( SIGPIPE, SIG_DFL );
238
239         fprintf( stderr, "user insisted too much, dying badly\n" );
240
241         abort();
242     }
243 }
244 #endif
245