4ab65248ead3a84e5a9f265effe1b96cd8237038
[vlc.git] / src / misc / darwin_specific.c
1
2 /*****************************************************************************
3  * darwin_specific.m: Darwin specific features
4  *****************************************************************************
5  * Copyright (C) 2001-2009 the VideoLAN team
6  * $Id$
7  *
8  * Authors: Sam Hocevar <sam@zoy.org>
9  *          Christophe Massiot <massiot@via.ecp.fr>
10  *          Pierre d'Herbemont <pdherbemont@free.fr>
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 #include <vlc_common.h>
32 #include "../libvlc.h"
33 #include <dirent.h>                                                /* *dir() */
34 #include <libgen.h>
35 #include <dlfcn.h>
36 #include <CoreFoundation/CoreFoundation.h>
37 #include <mach-o/dyld.h>
38
39 #ifdef HAVE_LOCALE_H
40 #   include <locale.h>
41 #endif
42
43 #ifndef MAXPATHLEN
44 # define MAXPATHLEN 1024
45 #endif
46
47 /*****************************************************************************
48  * system_Init: fill in program path & retrieve language
49  *****************************************************************************/
50 void system_Init( libvlc_int_t *p_this, int *pi_argc, const char *ppsz_argv[] )
51 {
52     VLC_UNUSED(p_this);
53     char i_dummy;
54     char *p_char = NULL;
55     char *p_oldchar = &i_dummy;
56     unsigned int i;
57     (void)pi_argc;
58
59     /* Get the full program path and name */
60     /* First try to see if we are linked to the framework */
61     for (i = 0; i < _dyld_image_count(); i++)
62     {
63         const char * psz_img_name = _dyld_get_image_name(i);
64         /* Check for "VLCKit.framework/Versions/Current/VLCKit",
65          * as well as "VLCKit.framework/Versions/A/VLCKit" and
66          * "VLC.framework/Versions/B/VLCKit" */
67         if( (p_char = strstr( psz_img_name, "VLCKit.framework/Versions/" )) )
68         {
69             /* Look for the next forward slash */
70             p_char += 26; /* p_char += strlen(" VLCKit.framework/Versions/" ) */
71             while( *p_char != '\0' && *p_char != '/')
72                 p_char++;
73
74             /* If the string ends with VLC then we've found a winner */
75             if ( !strcmp( p_char, "/VLCKit" ) )
76             {
77                 p_char = strdup( psz_img_name );
78                 break;
79             }
80             else
81                 p_char = NULL;
82         }
83         else
84         {
85             size_t len = strlen(psz_img_name);
86             /* Do we end by "VLC"? If so we are the legacy VLC.app that doesn't
87              * link to VLCKit. */
88             if( !strcmp( psz_img_name + len - 3, "VLC") )
89             {
90                 p_char = strdup( psz_img_name );
91                 break;
92             }
93         }
94     }
95     if ( !p_char )
96     {
97         /* We are not linked to the VLC.framework, let's use dladdr to figure
98          * libvlc path */
99         Dl_info info;
100         if( dladdr(system_Init, &info) )
101             p_char = strdup(dirname( info.dli_fname ));
102     }
103     if( !p_char )
104     {
105         char path[MAXPATHLEN+1];
106         uint32_t path_len = MAXPATHLEN;
107         if ( !_NSGetExecutablePath(path, &path_len) )
108             p_char = strdup(path);
109     }
110     if( !p_char )
111     {
112         /* We are not linked to the VLC.framework, return the executable path */
113         p_char = strdup( ppsz_argv[ 0 ] );
114     }
115
116     free(psz_vlcpath);
117     psz_vlcpath = p_char;
118
119     /* Remove trailing program name */
120     for( ; *p_char ; )
121     {
122         if( *p_char == '/' )
123         {
124             *p_oldchar = '/';
125             *p_char = '\0';
126             p_oldchar = p_char;
127         }
128         p_char++;
129     }
130
131 #ifdef ENABLE_NLS
132     /* Check if $LANG is set. */
133     if( NULL == getenv("LANG") )
134     {
135         /*
136            Retrieve the preferred language as chosen in  System Preferences.app
137            (note that CFLocaleCopyCurrent() is not used because it returns the
138             preferred locale not language)
139         */
140         CFArrayRef all_locales, preferred_locales;
141         char psz_locale[50];
142
143         all_locales = CFLocaleCopyAvailableLocaleIdentifiers();
144
145         preferred_locales = CFBundleCopyLocalizationsForPreferences( all_locales, NULL );
146
147         if ( preferred_locales )
148         {
149             if ( CFArrayGetCount( preferred_locales ) )
150             {
151                 CFStringRef user_language_string_ref = CFArrayGetValueAtIndex( preferred_locales, 0 );
152                 CFStringGetCString( user_language_string_ref, psz_locale, sizeof(psz_locale), kCFStringEncodingUTF8 );
153                 setenv( "LANG", psz_locale, 1 );
154             }
155             CFRelease( preferred_locales );
156         }
157         CFRelease( all_locales );
158     }
159 #endif
160 }
161
162 /*****************************************************************************
163  * system_Configure: check for system specific configuration options.
164  *****************************************************************************/
165 void system_Configure( libvlc_int_t *p_this, int *pi_argc, const char *ppsz_argv[] )
166 {
167     (void)p_this;
168     (void)pi_argc;
169     (void)ppsz_argv;
170 }
171
172 /*****************************************************************************
173  * system_End: free the program path.
174  *****************************************************************************/
175 void system_End( libvlc_int_t *p_this )
176 {
177     (void)p_this;
178     free( psz_vlcpath );
179     psz_vlcpath = NULL;
180 }
181