5997ee561f614b6efd3c6fe88fbd55a7f2349c63
[vlc.git] / modules / misc / gtk_main.c
1 /*****************************************************************************
2  * gtk_main.c : Gtk+ wrapper for gtk_main
3  *****************************************************************************
4  * Copyright (C) 2002 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28
29
30 #include <gtk/gtk.h>
31
32 #if defined(MODULE_NAME_IS_gtk2_main)
33 #   include <glib.h>
34 #endif
35
36 #if defined(MODULE_NAME_IS_gnome_main) || defined(MODULE_NAME_IS_gnome2_main)
37 #   include <gnome.h>
38 #endif
39
40 /*****************************************************************************
41  * Local prototypes.
42  *****************************************************************************/
43 static int  Open    ( vlc_object_t * );
44 static void Close   ( vlc_object_t * );
45
46 static void GtkMain ( vlc_object_t * );
47
48 /*****************************************************************************
49  * Local variables (mutex-protected).
50  *****************************************************************************/
51 static int            i_refcount = 0;
52 static vlc_object_t * p_gtk_main = NULL;
53
54 /*****************************************************************************
55  * Module descriptor
56  *****************************************************************************/
57 vlc_module_begin();
58     int i_cap;
59     set_description( _("Gtk+ GUI helper") );
60 #if defined(MODULE_NAME_IS_gtk_main)
61     i_cap = 90;
62     add_shortcut( "gtk" );
63 #elif defined(MODULE_NAME_IS_gnome_main)
64     i_cap = 100;
65     add_shortcut( "gtk" );
66     add_shortcut( "gnome" );
67 #elif defined(MODULE_NAME_IS_gtk2_main)
68     i_cap = 95;
69     add_shortcut( "gtk2" );
70 #elif defined(MODULE_NAME_IS_gnome2_main)
71     i_cap = 105;
72     add_shortcut( "gtk2" );
73     add_shortcut( "gnome2" );
74 #endif
75     set_capability( "gui-helper", i_cap );
76     set_callbacks( Open, Close );
77     linked_with_a_crap_library_which_uses_atexit();
78 vlc_module_end();
79
80 /*****************************************************************************
81  * Open: initialize and create window
82  *****************************************************************************/
83 static int Open( vlc_object_t *p_this )
84 {
85     vlc_mutex_t *lock;
86
87     lock = var_AcquireMutex( "gtk" );
88
89     if( i_refcount > 0 )
90     {
91         i_refcount++;
92         vlc_mutex_unlock( lock );
93
94         return VLC_SUCCESS;
95     }
96
97     p_gtk_main = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
98
99     /* Only initialize gthreads if it's the first time we do it */
100     if( !g_thread_supported() )
101     {
102         g_thread_init( NULL );
103     }
104
105     /* Launch the gtk_main() thread. It will not return until it has
106      * called gdk_threads_enter(), which ensures us thread safety. */
107     if( vlc_thread_create( p_gtk_main, "gtk_main", GtkMain,
108                            VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
109     {
110         vlc_object_destroy( p_gtk_main );
111         i_refcount--;
112         vlc_mutex_unlock( lock );
113         return VLC_ETHREAD;
114     }
115
116     i_refcount++;
117     vlc_mutex_unlock( lock );
118
119     return VLC_SUCCESS;
120 }
121
122 /*****************************************************************************
123  * Close: destroy interface window
124  *****************************************************************************/
125 static void Close( vlc_object_t *p_this )
126 {
127     vlc_mutex_t *lock;
128
129     lock = var_AcquireMutex( "gtk" );
130
131     i_refcount--;
132
133     if( i_refcount > 0 )
134     {
135         vlc_mutex_unlock( lock );
136         return;
137     }
138
139     gtk_main_quit();
140     vlc_thread_join( p_gtk_main );
141
142     vlc_object_destroy( p_gtk_main );
143     p_gtk_main = NULL;
144
145     vlc_mutex_unlock( lock );
146 }
147
148 static gint foo( gpointer bar ) { return TRUE; }
149
150 /*****************************************************************************
151  * GtkMain: Gtk+ thread
152  *****************************************************************************
153  * this part of the interface is in a separate thread so that we can call
154  * gtk_main() from within it without annoying the rest of the program.
155  *****************************************************************************/
156 static void GtkMain( vlc_object_t *p_this )
157 {
158     /* gtk_init needs to know the command line. We don't care, so we
159      * give it an empty one */
160     static char  *p_args[] = { "", NULL };
161 #if defined(MODULE_NAME_IS_gtk_main) || defined(MODULE_NAME_IS_gtk2_main)
162     static char **pp_args  = p_args;
163 #endif
164     static int    i_args   = 1;
165
166     /* FIXME: deprecated ? */
167 #if defined(MODULE_NAME_IS_gtk2_main) || defined(MODULE_NAME_IS_gnome2_main)
168     gdk_threads_init();
169 #endif
170
171 #if defined(MODULE_NAME_IS_gnome_main)
172     gnome_init( p_this->p_libvlc->psz_object_name, VERSION, i_args, p_args );
173 #elif defined(MODULE_NAME_IS_gnome2_main)
174     gnome_program_init( PACKAGE, VERSION, LIBGNOMEUI_MODULE,
175                         i_args, p_args,
176                         GNOME_PARAM_APP_DATADIR, "",//PACKAGE_DATA_DIR,
177                         NULL );
178 #else
179     gtk_set_locale();
180     gtk_init( &i_args, &pp_args );
181 #endif
182
183     gdk_threads_enter();
184
185     vlc_thread_ready( p_this );
186
187     /* If we don't add this simple timeout, gtk_main remains stuck if
188      * we try to close the window without having sent any gtk event. */
189     gtk_timeout_add( INTF_IDLE_SLEEP / 1000, foo, p_this );
190
191     /* Enter Gtk mode */
192     gtk_main();
193
194     gdk_threads_leave();
195 }
196