GApplication: add remote commandline support
[platform/upstream/glib.git] / gio / gapplicationcommandline.c
1 #include "gapplicationcommandline.h"
2
3 #include <string.h>
4 #include <stdio.h>
5
6 G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
7
8 enum
9 {
10   PROP_NONE,
11   PROP_ARGUMENTS,
12   PROP_PLATFORM_DATA,
13   PROP_IS_REMOTE
14 };
15
16 struct _GApplicationCommandLinePrivate
17 {
18   GVariant *platform_data;
19   GVariant *arguments;
20   GVariant *cwd;
21   gint exit_status;
22 };
23
24 #define IS_REMOTE(cmdline) ((cmdline)->priv->platform_data != NULL)
25
26 void
27 g_application_command_line_get_argc_argv (GApplicationCommandLine   *cmdline,
28                                           int                       *argc,
29                                           char                    ***argv)
30 {
31   gsize len;
32
33   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
34   g_return_if_fail (argc != NULL && argv != NULL);
35
36   *argv = g_variant_dup_bytestring_array (cmdline->priv->arguments, &len);
37   *argc = len;
38 }
39
40 GVariant *
41 g_application_command_line_get_arguments (GApplicationCommandLine *cmdline)
42 {
43   return g_variant_ref (cmdline->priv->arguments);
44 }
45
46 const gchar *
47 g_application_command_line_get_cwd (GApplicationCommandLine *cmdline)
48 {
49   if (cmdline->priv->cwd)
50     return g_variant_get_bytestring (cmdline->priv->cwd);
51   else
52     return NULL;
53 }
54
55 GVariant *
56 g_application_command_line_get_cwd_variant (GApplicationCommandLine *cmdline)
57 {
58   if (cmdline->priv->cwd)
59     return g_variant_ref (cmdline->priv->cwd);
60   else
61     return NULL;
62 }
63
64 gboolean
65 g_application_command_line_get_is_remote (GApplicationCommandLine *cmdline)
66 {
67   return IS_REMOTE (cmdline);
68 }
69
70 static void
71 g_application_command_line_real_print_literal (GApplicationCommandLine *cmdline,
72                                                const gchar             *message)
73 {
74   g_print ("%s\n", message);
75 }
76
77 static void
78 g_application_command_line_real_printerr_literal (GApplicationCommandLine *cmdline,
79                                                   const gchar             *message)
80 {
81   g_printerr ("%s\n", message);
82 }
83
84 void
85 g_application_command_line_print (GApplicationCommandLine *cmdline,
86                                   const gchar             *format,
87                                   ...)
88 {
89   gchar *message;
90   va_list ap;
91
92   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
93   g_return_if_fail (format != NULL);
94
95   va_start (ap, format);
96   message = g_strdup_vprintf (format, ap);
97   va_end (ap);
98
99   G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
100     ->print_literal (cmdline, message);
101   g_free (message);
102 }
103
104 void
105 g_application_command_line_printerr (GApplicationCommandLine *cmdline,
106                                      const gchar             *format,
107                                      ...)
108 {
109   gchar *message;
110   va_list ap;
111
112   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
113   g_return_if_fail (format != NULL);
114
115   va_start (ap, format);
116   message = g_strdup_vprintf (format, ap);
117   va_end (ap);
118
119   G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
120     ->printerr_literal (cmdline, message);
121   g_free (message);
122 }
123
124 void
125 g_application_command_line_set_exit_status (GApplicationCommandLine *cmdline,
126                                             int                      exit_status)
127 {
128   g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
129
130   cmdline->priv->exit_status = exit_status;
131 }
132
133 int
134 g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline)
135 {
136   g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), -1);
137
138   return cmdline->priv->exit_status;
139 }
140
141 static void
142 grok_platform_data (GApplicationCommandLine *cmdline)
143 {
144   GVariantIter iter;
145   const gchar *key;
146   GVariant *value;
147
148   g_variant_iter_init (&iter, cmdline->priv->platform_data);
149
150   while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
151     if (strcmp (key, "cwd") == 0)
152       {
153         if (!cmdline->priv->cwd)
154           cmdline->priv->cwd = g_variant_ref (value);
155       }
156 }
157
158 static void
159 g_application_command_line_get_property (GObject *object, guint prop_id,
160                                          GValue *value, GParamSpec *pspec)
161 {
162   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
163
164   switch (prop_id)
165     {
166     case PROP_ARGUMENTS:
167       g_value_set_variant (value, cmdline->priv->arguments);
168       break;
169
170     case PROP_PLATFORM_DATA:
171       g_value_set_variant (value, cmdline->priv->platform_data);
172       break;
173
174     case PROP_IS_REMOTE:
175       g_value_set_boolean (value, IS_REMOTE (cmdline));
176       break;
177
178     default:
179       g_assert_not_reached ();
180     }
181 }
182
183 static void
184 g_application_command_line_set_property (GObject *object, guint prop_id,
185                                          const GValue *value, GParamSpec *pspec)
186 {
187   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
188
189   switch (prop_id)
190     {
191     case PROP_ARGUMENTS:
192       g_assert (cmdline->priv->arguments == NULL);
193       cmdline->priv->arguments = g_value_dup_variant (value);
194       break;
195
196     case PROP_PLATFORM_DATA:
197       g_assert (cmdline->priv->platform_data == NULL);
198       cmdline->priv->platform_data = g_value_dup_variant (value);
199       if (cmdline->priv->platform_data != NULL)
200         grok_platform_data (cmdline);
201       break;
202
203     default:
204       g_assert_not_reached ();
205     }
206 }
207
208 static void
209 g_application_command_line_finalize (GObject *object)
210 {
211   GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
212
213   if (cmdline->priv->platform_data)
214     g_variant_unref (cmdline->priv->platform_data);
215   if (cmdline->priv->arguments)
216     g_variant_unref (cmdline->priv->arguments);
217   if (cmdline->priv->cwd)
218     g_variant_unref (cmdline->priv->cwd);
219
220   G_OBJECT_CLASS (g_application_command_line_parent_class)
221     ->finalize (object);
222 }
223
224 static void
225 g_application_command_line_init (GApplicationCommandLine *cmdline)
226 {
227   cmdline->priv =
228     G_TYPE_INSTANCE_GET_PRIVATE (cmdline,
229                                  G_TYPE_APPLICATION_COMMAND_LINE,
230                                  GApplicationCommandLinePrivate);
231 }
232
233 static void
234 g_application_command_line_class_init (GApplicationCommandLineClass *class)
235 {
236   GObjectClass *object_class = G_OBJECT_CLASS (class);
237
238   object_class->get_property = g_application_command_line_get_property;
239   object_class->set_property = g_application_command_line_set_property;
240   object_class->finalize = g_application_command_line_finalize;
241   class->printerr_literal = g_application_command_line_real_printerr_literal;
242   class->print_literal = g_application_command_line_real_print_literal;
243
244   g_object_class_install_property (object_class, PROP_ARGUMENTS,
245     g_param_spec_variant ("arguments", "commandline arguments",
246                           "the commandline that caused this cmdline",
247                           G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL,
248                           G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
249                           G_PARAM_STATIC_STRINGS));
250
251   g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
252     g_param_spec_variant ("platform-data", "platform data",
253                           "platform-specific data for the cmdline",
254                           G_VARIANT_TYPE ("a{sv}"), NULL,
255                           G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
256                           G_PARAM_STATIC_STRINGS));
257
258   g_object_class_install_property (object_class, PROP_IS_REMOTE,
259     g_param_spec_boolean ("is-remote", "is remote",
260                           "TRUE if this is a remote cmdline", FALSE,
261                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
262
263   g_type_class_add_private (class, sizeof (GApplicationCommandLinePrivate));
264 }
265
266 GVariant *
267 g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline)
268 {
269   g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
270   g_return_val_if_fail (IS_REMOTE (cmdline), NULL);
271
272   return g_variant_ref (cmdline->priv->platform_data);
273 }