]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkspawn-x11.c
daa25aad5a0fd1e48e55bb08e19e383abca9b994
[~andy/gtk] / gdk / x11 / gdkspawn-x11.c
1 /*
2  * Copyright (C) 2003 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Mark McLoughlin <mark@skynet.ie>
20  */
21
22 #include <config.h>
23 #include <string.h>
24
25 #include "gdkalias.h"
26 #include "gdkspawn.h"
27
28 #include <glib.h>
29 #include <gdk/gdk.h>
30
31 extern char **environ;
32
33 /**
34  * gdk_make_spawn_environment_for_screen:
35  * @screen: A #GdkScreen
36  * @envp: program environment to copy, or %NULL to use current environment.
37  *
38  * Returns a modified copy of the program environment @envp (or the current
39  * environment if @envp is %NULL) with <envar>DISPLAY</envar> set such that 
40  * a launched application (which calls gdk_display_open()) inheriting this 
41  * environment would have @screen as its default screen..
42  *
43  * Returns: a newly-allocated %NULL-terminated array of strings.
44  *          Use g_strfreev() to free it.
45  *
46  * Since: 2.4
47  **/
48 static gchar **
49 gdk_spawn_make_environment_for_screen (GdkScreen  *screen,
50                                        gchar     **envp)
51 {
52   gchar **retval = NULL;
53   gchar  *display_name;
54   gint    display_index = -1;
55   gint    i, env_len;
56
57   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
58
59   if (envp == NULL)
60     envp = environ;
61
62   for (env_len = 0; envp[env_len]; env_len++)
63     if (strncmp (envp[env_len], "DISPLAY", strlen ("DISPLAY")) == 0)
64       display_index = env_len;
65
66   retval = g_new (char *, env_len + 1);
67   retval[env_len] = NULL;
68
69   display_name = gdk_screen_make_display_name (screen);
70
71   for (i = 0; i < env_len; i++)
72     if (i == display_index)
73       retval[i] = g_strconcat ("DISPLAY=", display_name, NULL);
74     else
75       retval[i] = g_strdup (envp[i]);
76
77   g_assert (i == env_len);
78
79   g_free (display_name);
80
81   return retval;
82 }
83
84 /**
85  * gdk_spawn_on_screen:
86  * @screen: a #GdkScreen
87  * @working_directory: child's current working directory, or %NULL to 
88  *   inherit parent's
89  * @argv: child's argument vector
90  * @envp: child's environment, or %NULL to inherit parent's
91  * @flags: flags from #GSpawnFlags
92  * @child_setup: function to run in the child just before exec()
93  * @user_data: user data for @child_setup
94  * @child_pid: return location for child process ID, or %NULL
95  * @error: return location for error
96  *
97  * Like g_spawn_async(), except the child process is spawned in such
98  * an environment that on calling gdk_display_open() it would be
99  * returned a #GdkDisplay with @screen as the default screen.
100  *
101  * This is useful for applications which wish to launch an application
102  * on a specific screen.
103  *
104  * Return value: %TRUE on success, %FALSE if error is set
105  *
106  * Since: 2.4
107  **/
108 gboolean
109 gdk_spawn_on_screen (GdkScreen             *screen,
110                      const gchar           *working_directory,
111                      gchar                **argv,
112                      gchar                **envp,
113                      GSpawnFlags            flags,
114                      GSpawnChildSetupFunc   child_setup,
115                      gpointer               user_data,
116                      gint                  *child_pid,
117                      GError               **error)
118 {
119   gchar    **new_envp;
120   gboolean   retval;
121
122   g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
123
124   new_envp = gdk_spawn_make_environment_for_screen (screen, envp);
125
126   retval = g_spawn_async (working_directory,
127                           argv,
128                           new_envp,
129                           flags,
130                           child_setup,
131                           user_data,
132                           child_pid,
133                           error);
134
135   g_strfreev (new_envp);
136
137   return retval;
138 }
139
140 /**
141  * gdk_spawn_on_screen_with_pipes:
142  * @screen: a #GdkScreen
143  * @working_directory: child's current working directory, or %NULL to 
144  *   inherit parent's
145  * @argv: child's argument vector
146  * @envp: child's environment, or %NULL to inherit parent's
147  * @flags: flags from #GSpawnFlags
148  * @child_setup: function to run in the child just before exec()
149  * @user_data: user data for @child_setup
150  * @child_pid: return location for child process ID, or %NULL
151  * @standard_input: return location for file descriptor to write to 
152  *   child's stdin, or %NULL
153  * @standard_output: return location for file descriptor to read child's 
154  *   stdout, or %NULL
155  * @standard_error: return location for file descriptor to read child's 
156  *   stderr, or %NULL
157  * @error: return location for error
158  *
159  * Like g_spawn_async_with_pipes(), except the child process is
160  * spawned in such an environment that on calling gdk_display_open()
161  * it would be returned a #GdkDisplay with @screen as the default
162  * screen.
163  *
164  * This is useful for applications which wish to launch an application
165  * on a specific screen.
166  *
167  * Return value: %TRUE on success, %FALSE if an error was set
168  *
169  * Since: 2.4
170  **/
171 gboolean
172 gdk_spawn_on_screen_with_pipes (GdkScreen            *screen,
173                                 const gchar          *working_directory,
174                                 gchar               **argv,
175                                 gchar               **envp,
176                                 GSpawnFlags           flags,
177                                 GSpawnChildSetupFunc  child_setup,
178                                 gpointer              user_data,
179                                 gint                 *child_pid,
180                                 gint                 *standard_input,
181                                 gint                 *standard_output,
182                                 gint                 *standard_error,
183                                 GError              **error)
184 {
185   gchar    **new_envp;
186   gboolean   retval;
187
188   g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
189
190   new_envp = gdk_spawn_make_environment_for_screen (screen, envp);
191
192   retval = g_spawn_async_with_pipes (working_directory,
193                                      argv,
194                                      new_envp,
195                                      flags,
196                                      child_setup,
197                                      user_data,
198                                      child_pid,
199                                      standard_input,
200                                      standard_output,
201                                      standard_error,
202                                      error);
203
204   g_strfreev (new_envp);
205
206   return retval;
207 }
208
209 /**
210  * gdk_spawn_command_line_on_screen:
211  * @screen: a #GdkScreen
212  * @command_line: a command line
213  * @error: return location for errors
214  *
215  * Like g_spawn_command_line_async(), except the child process is
216  * spawned in such an environment that on calling gdk_display_open()
217  * it would be returned a #GdkDisplay with @screen as the default
218  * screen.
219  *
220  * This is useful for applications which wish to launch an application
221  * on a specific screen.
222  *
223  * Return value: %TRUE on success, %FALSE if error is set.
224  *
225  * Since: 2.4
226  **/
227 gboolean
228 gdk_spawn_command_line_on_screen (GdkScreen    *screen,
229                                   const gchar  *command_line,
230                                   GError      **error)
231 {
232   gchar    **argv = NULL;
233   gboolean   retval;
234
235   g_return_val_if_fail (command_line != NULL, FALSE);
236
237   if (!g_shell_parse_argv (command_line,
238                            NULL, &argv,
239                            error))
240     return FALSE;
241
242   retval = gdk_spawn_on_screen (screen,
243                                 NULL, argv, NULL,
244                                 G_SPAWN_SEARCH_PATH,
245                                 NULL, NULL, NULL,
246                                 error);
247   g_strfreev (argv);
248
249   return retval;
250 }