]> git.sesse.net Git - vlc/blob - src/winvlc.c
Separate and refactor the win32 main code
[vlc] / src / winvlc.c
1 /*****************************************************************************
2  * winvlc.c: the Windows VLC player
3  *****************************************************************************
4  * Copyright (C) 1998-2008 the VideoLAN team
5  *
6  * Authors: Vincent Seguin <seguin@via.ecp.fr>
7  *          Samuel Hocevar <sam@zoy.org>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Derk-Jan Hartman <hartman at videolan dot org>
10  *          Lots of other people, see the libvlc AUTHORS file
11  *
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.
16  *
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.
21  *
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #define UNICODE
32 #include <vlc/vlc.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <windows.h>
37
38 static void find_end_quote( char **s, char **ppsz_parser, int i_quote )
39 {
40     int i_bcount = 0;
41
42     while( **s )
43     {
44         if( **s == '\\' )
45         {
46             **ppsz_parser = **s;
47             (*ppsz_parser)++; (*s)++;
48             i_bcount++;
49         }
50         else if( **s == '"' || **s == '\'' )
51         {
52             /* Preceeded by a number of '\' which we erase. */
53             *ppsz_parser -= i_bcount / 2;
54             if( i_bcount & 1 )
55             {
56                 /* '\\' followed by a '"' or '\'' */
57                 *ppsz_parser -= 1;
58                 **ppsz_parser = **s;
59                 (*ppsz_parser)++; (*s)++;
60                 i_bcount = 0;
61                 continue;
62             }
63
64             if( **s == i_quote )
65             {
66                 /* End */
67                 return;
68             }
69             else
70             {
71                 /* Different quoting */
72                 int i_quote = **s;
73                 **ppsz_parser = **s;
74                 (*ppsz_parser)++; (*s)++;
75                 find_end_quote( s, ppsz_parser, i_quote );
76                 **ppsz_parser = **s;
77                 (*ppsz_parser)++; (*s)++;
78             }
79
80             i_bcount = 0;
81         }
82         else
83         {
84             /* A regular character */
85             **ppsz_parser = **s;
86             (*ppsz_parser)++; (*s)++;
87             i_bcount = 0;
88         }
89     }
90 }
91
92 /*************************************************************************
93  * vlc_parse_cmdline: Command line parsing into elements.
94  *
95  * The command line is composed of space/tab separated arguments.
96  * Quotes can be used as argument delimiters and a backslash can be used to
97  * escape a quote.
98  *************************************************************************/
99 static char **vlc_parse_cmdline( const char *psz_cmdline, int *i_args )
100 {
101     char **argv = NULL;
102     char *s, *psz_parser, *psz_arg, *psz_orig;
103     int i_bcount = 0, argc = 0;
104
105     psz_orig = strdup( psz_cmdline );
106     psz_arg = psz_parser = s = psz_orig;
107
108     while( *s )
109     {
110         if( *s == '\t' || *s == ' ' )
111         {
112             /* We have a complete argument */
113             *psz_parser = 0;
114             argv = realloc( argv, (argc + 1) * sizeof (char *) );
115             argv[argc] = psz_arg;
116
117             /* Skip trailing spaces/tabs */
118             do{ s++; } while( *s == '\t' || *s == ' ' );
119
120             /* New argument */
121             psz_arg = psz_parser = s;
122             i_bcount = 0;
123         }
124         else if( *s == '\\' )
125         {
126             *psz_parser++ = *s++;
127             i_bcount++;
128         }
129         else if( *s == '"' || *s == '\'' )
130         {
131             if( ( i_bcount & 1 ) == 0 )
132             {
133                 /* Preceeded by an even number of '\', this is half that
134                  * number of '\', plus a quote which we erase. */
135                 int i_quote = *s;
136                 psz_parser -= i_bcount / 2;
137                 s++;
138                 find_end_quote( &s, &psz_parser, i_quote );
139                 s++;
140             }
141             else
142             {
143                 /* Preceeded by an odd number of '\', this is half that
144                  * number of '\' followed by a '"' */
145                 psz_parser = psz_parser - i_bcount/2 - 1;
146                 *psz_parser++ = '"';
147                 s++;
148             }
149             i_bcount = 0;
150         }
151         else
152         {
153             /* A regular character */
154             *psz_parser++ = *s++;
155             i_bcount = 0;
156         }
157     }
158
159     /* Take care of the last arg */
160     if( *psz_arg )
161     {
162         *psz_parser = '\0';
163         argv = realloc( argv, (argc + 1) * sizeof (char *) );
164         argv[argc] = psz_arg;
165     }
166
167     *i_args = argc;
168     return argv;
169 }
170
171
172 #ifdef UNDER_CE
173 # define wWinMain WinMain
174 #endif
175
176 /*****************************************************************************
177  * wWinMain: parse command line, start interface and spawn threads.
178  *****************************************************************************/
179 int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
180                     LPWSTR lpCmdLine, int nCmdShow )
181 {
182     char **argv, psz_cmdline[wcslen(lpCmdLine) * 4];
183     int argc, ret;
184
185     (void)hInstance; (void)hPrevInstance; (void)nCmdShow;
186     /* This clutters OSX GUI error logs */
187     fprintf( stderr, "VLC media player %s\n", libvlc_get_version() );
188
189     WideCharToMultiByte( CP_UTF8, 0, lpCmdLine, -1,
190                          psz_cmdline, MAX_PATH, NULL, NULL );
191     argv = vlc_parse_cmdline( psz_cmdline, &argc );
192
193     libvlc_exception_t ex;
194     libvlc_exception_init (&ex);
195
196     /* Initialize libvlc */
197     libvlc_instance_t *vlc = libvlc_new (argc, (const char **)argv, &ex);
198     if (vlc != NULL)
199     {
200         libvlc_run_interface (vlc, NULL, &ex);
201         libvlc_release (vlc);
202     }
203
204     ret = libvlc_exception_raised (&ex);
205     libvlc_exception_clear (&ex);
206     return ret;
207 }