mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-23 22:16:16 +01:00
GApplication: add remote commandline support
This commit is contained in:
parent
2854c373e1
commit
3e6eee806c
@ -139,6 +139,7 @@ application_headers = \
|
||||
gsimpleactiongroup.h \
|
||||
gaction.h \
|
||||
gsimpleaction.h \
|
||||
gapplicationcommandline.h \
|
||||
gapplication.h
|
||||
|
||||
application_sources = \
|
||||
@ -146,6 +147,7 @@ application_sources = \
|
||||
gsimpleactiongroup.c \
|
||||
gaction.c \
|
||||
gsimpleaction.c \
|
||||
gapplicationcommandline.c \
|
||||
gapplicationimpl-dbus.c \
|
||||
gapplication.c
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
/* Prologue {{{1 */
|
||||
#include "gapplication.h"
|
||||
|
||||
#include "gapplicationcommandline.h"
|
||||
#include "gapplicationimpl.h"
|
||||
|
||||
#include "gioenumtypes.h"
|
||||
@ -132,12 +133,30 @@ g_application_real_open (GApplication *application,
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
g_application_real_command_line (GApplication *application,
|
||||
GApplicationCommandLine *cmdline)
|
||||
{
|
||||
static gboolean warned;
|
||||
|
||||
if (warned)
|
||||
return 1;
|
||||
|
||||
g_warning ("Your application claims to support custom command line "
|
||||
"handling but does not implement g_application_command_line() "
|
||||
"and has no handlers connected to the 'command-line' signal.");
|
||||
|
||||
warned = TRUE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_application_real_local_command_line (GApplication *application,
|
||||
GVariant **arguments,
|
||||
int *exit_status)
|
||||
{
|
||||
if (0)
|
||||
if (application->priv->flags & G_APPLICATION_HANDLES_COMMAND_LINE)
|
||||
return FALSE;
|
||||
|
||||
else
|
||||
@ -155,12 +174,12 @@ g_application_real_local_command_line (GApplication *application,
|
||||
|
||||
n_args = g_variant_n_children (*arguments);
|
||||
|
||||
if (application->priv->flags & G_APPLICATION_FLAGS_IS_SERVICE)
|
||||
if (application->priv->flags & G_APPLICATION_IS_SERVICE)
|
||||
{
|
||||
if (n_args > 1)
|
||||
{
|
||||
g_printerr ("GApplication service mode takes no arguments.\n");
|
||||
application->priv->flags &= ~G_APPLICATION_FLAGS_IS_SERVICE;
|
||||
application->priv->flags &= ~G_APPLICATION_IS_SERVICE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -174,7 +193,7 @@ g_application_real_local_command_line (GApplication *application,
|
||||
|
||||
else
|
||||
{
|
||||
if (~application->priv->flags & G_APPLICATION_FLAGS_HANDLES_OPEN)
|
||||
if (~application->priv->flags & G_APPLICATION_HANDLES_OPEN)
|
||||
{
|
||||
g_critical ("This application can not open files.");
|
||||
*exit_status = 1;
|
||||
@ -330,6 +349,17 @@ g_application_init (GApplication *application)
|
||||
GApplicationPrivate);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
first_wins_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer data)
|
||||
{
|
||||
g_value_copy (handler_return, return_accu);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_class_init (GApplicationClass *class)
|
||||
{
|
||||
@ -345,6 +375,7 @@ g_application_class_init (GApplicationClass *class)
|
||||
class->startup = g_application_real_startup;
|
||||
class->activate = g_application_real_activate;
|
||||
class->open = g_application_real_open;
|
||||
class->command_line = g_application_real_command_line;
|
||||
class->local_command_line = g_application_real_local_command_line;
|
||||
class->add_platform_data = g_application_real_add_platform_data;
|
||||
class->quit_mainloop = g_application_real_quit_mainloop;
|
||||
@ -394,6 +425,12 @@ g_application_class_init (GApplicationClass *class)
|
||||
NULL, NULL, _gio_marshal_VOID__POINTER_INT_STRING,
|
||||
G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING);
|
||||
|
||||
g_application_signals[SIGNAL_COMMAND_LINE] =
|
||||
g_signal_new ("command-line", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GApplicationClass, command_line),
|
||||
first_wins_accumulator, NULL, _gio_marshal_INT__OBJECT,
|
||||
G_TYPE_INT, 1, G_TYPE_APPLICATION_COMMAND_LINE);
|
||||
|
||||
g_type_class_add_private (class, sizeof (GApplicationPrivate));
|
||||
}
|
||||
|
||||
@ -729,9 +766,9 @@ g_application_register (GApplication *application,
|
||||
gboolean try;
|
||||
|
||||
/* don't try to be the primary instance if
|
||||
* G_APPLICATION_FLAGS_IS_LAUNCHER was specified.
|
||||
* G_APPLICATION_IS_LAUNCHER was specified.
|
||||
*/
|
||||
try = !(application->priv->flags & G_APPLICATION_FLAGS_IS_LAUNCHER);
|
||||
try = !(application->priv->flags & G_APPLICATION_IS_LAUNCHER);
|
||||
|
||||
application->priv->impl =
|
||||
g_application_impl_register (application, application->priv->id,
|
||||
@ -867,7 +904,7 @@ g_application_activate (GApplication *application)
|
||||
* for this functionality, you should use "".
|
||||
*
|
||||
* The application must be registered before calling this function and
|
||||
* it must have the %G_APPLICATION_FLAGS_CAN_OPEN flag set. The open()
|
||||
* it must have the %G_APPLICATION_CAN_OPEN flag set. The open()
|
||||
* virtual function should also be implemented in order for anything
|
||||
* meaningful to happen.
|
||||
*
|
||||
@ -881,7 +918,7 @@ g_application_open (GApplication *application,
|
||||
{
|
||||
g_return_if_fail (G_IS_APPLICATION (application));
|
||||
g_return_if_fail (application->priv->flags &
|
||||
G_APPLICATION_FLAGS_HANDLES_OPEN);
|
||||
G_APPLICATION_HANDLES_OPEN);
|
||||
g_return_if_fail (application->priv->is_registered);
|
||||
|
||||
if (application->priv->is_remote)
|
||||
@ -913,7 +950,7 @@ g_application_open (GApplication *application,
|
||||
* virtual function is invoked in the primary instance (which may or may
|
||||
* not be this instance).
|
||||
*
|
||||
* If the application has the %G_APPLICATION_FLAGS_REMOTE_COMMAND_LINE
|
||||
* If the application has the %G_APPLICATION_REMOTE_COMMAND_LINE
|
||||
* flag set then the default implementation of handle_command_line()
|
||||
* always returns %FALSE immediately, resulting in the commandline
|
||||
* always being handled in the primary instance.
|
||||
@ -924,7 +961,7 @@ g_application_open (GApplication *application,
|
||||
* to register the application. If that works, then the command line
|
||||
* arguments are inspected. If no commandline arguments are given, then
|
||||
* g_application_activate() is called. If commandline arguments are
|
||||
* given and the %G_APPLICATION_FLAGS_CAN_OPEN flags is set then they
|
||||
* given and the %G_APPLICATION_CAN_OPEN flags is set then they
|
||||
* are assumed to be filenames and g_application_open() is called.
|
||||
*
|
||||
* If you are interested in doing more complicated local handling of the
|
||||
@ -984,12 +1021,39 @@ g_application_run_with_arguments (GApplication *application,
|
||||
if (!G_APPLICATION_GET_CLASS (application)
|
||||
->local_command_line (application, &arguments, &status))
|
||||
{
|
||||
g_assert_not_reached ();
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_application_register (application, NULL, &error))
|
||||
{
|
||||
g_printerr ("%s", error->message);
|
||||
g_error_free (error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (application->priv->is_remote)
|
||||
{
|
||||
GVariant *platform_data;
|
||||
|
||||
platform_data = get_platform_data (application);
|
||||
status = g_application_impl_command_line (application->priv->impl,
|
||||
arguments, platform_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GApplicationCommandLine *cmdline;
|
||||
|
||||
cmdline = g_object_new (G_TYPE_APPLICATION_COMMAND_LINE,
|
||||
"arguments", arguments, NULL);
|
||||
g_signal_emit (application,
|
||||
g_application_signals[SIGNAL_COMMAND_LINE],
|
||||
0, cmdline, &status);
|
||||
g_object_unref (cmdline);
|
||||
}
|
||||
}
|
||||
|
||||
g_variant_unref (arguments);
|
||||
|
||||
if (application->priv->flags & G_APPLICATION_FLAGS_IS_SERVICE &&
|
||||
if (application->priv->flags & G_APPLICATION_IS_SERVICE &&
|
||||
!application->priv->use_count &&
|
||||
!application->priv->inactivity_timeout_id)
|
||||
{
|
||||
|
@ -93,15 +93,14 @@ struct _GApplicationClass
|
||||
gint n_files,
|
||||
const gchar *hint);
|
||||
|
||||
gpointer _reserved_1;
|
||||
int (* command_line) (GApplication *application,
|
||||
GApplicationCommandLine *command_line);
|
||||
|
||||
/* vfuncs */
|
||||
gboolean (* local_command_line) (GApplication *application,
|
||||
GVariant **arguments,
|
||||
int *exit_status);
|
||||
|
||||
gpointer _reserved_2;
|
||||
|
||||
void (* before_emit) (GApplication *application,
|
||||
GVariant *platform_data);
|
||||
void (* after_emit) (GApplication *application,
|
||||
|
273
gio/gapplicationcommandline.c
Normal file
273
gio/gapplicationcommandline.c
Normal file
@ -0,0 +1,273 @@
|
||||
#include "gapplicationcommandline.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_NONE,
|
||||
PROP_ARGUMENTS,
|
||||
PROP_PLATFORM_DATA,
|
||||
PROP_IS_REMOTE
|
||||
};
|
||||
|
||||
struct _GApplicationCommandLinePrivate
|
||||
{
|
||||
GVariant *platform_data;
|
||||
GVariant *arguments;
|
||||
GVariant *cwd;
|
||||
gint exit_status;
|
||||
};
|
||||
|
||||
#define IS_REMOTE(cmdline) ((cmdline)->priv->platform_data != NULL)
|
||||
|
||||
void
|
||||
g_application_command_line_get_argc_argv (GApplicationCommandLine *cmdline,
|
||||
int *argc,
|
||||
char ***argv)
|
||||
{
|
||||
gsize len;
|
||||
|
||||
g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
|
||||
g_return_if_fail (argc != NULL && argv != NULL);
|
||||
|
||||
*argv = g_variant_dup_bytestring_array (cmdline->priv->arguments, &len);
|
||||
*argc = len;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
g_application_command_line_get_arguments (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
return g_variant_ref (cmdline->priv->arguments);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
g_application_command_line_get_cwd (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
if (cmdline->priv->cwd)
|
||||
return g_variant_get_bytestring (cmdline->priv->cwd);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
g_application_command_line_get_cwd_variant (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
if (cmdline->priv->cwd)
|
||||
return g_variant_ref (cmdline->priv->cwd);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_application_command_line_get_is_remote (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
return IS_REMOTE (cmdline);
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_real_print_literal (GApplicationCommandLine *cmdline,
|
||||
const gchar *message)
|
||||
{
|
||||
g_print ("%s\n", message);
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_real_printerr_literal (GApplicationCommandLine *cmdline,
|
||||
const gchar *message)
|
||||
{
|
||||
g_printerr ("%s\n", message);
|
||||
}
|
||||
|
||||
void
|
||||
g_application_command_line_print (GApplicationCommandLine *cmdline,
|
||||
const gchar *format,
|
||||
...)
|
||||
{
|
||||
gchar *message;
|
||||
va_list ap;
|
||||
|
||||
g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
va_start (ap, format);
|
||||
message = g_strdup_vprintf (format, ap);
|
||||
va_end (ap);
|
||||
|
||||
G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
|
||||
->print_literal (cmdline, message);
|
||||
g_free (message);
|
||||
}
|
||||
|
||||
void
|
||||
g_application_command_line_printerr (GApplicationCommandLine *cmdline,
|
||||
const gchar *format,
|
||||
...)
|
||||
{
|
||||
gchar *message;
|
||||
va_list ap;
|
||||
|
||||
g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
|
||||
g_return_if_fail (format != NULL);
|
||||
|
||||
va_start (ap, format);
|
||||
message = g_strdup_vprintf (format, ap);
|
||||
va_end (ap);
|
||||
|
||||
G_APPLICATION_COMMAND_LINE_GET_CLASS (cmdline)
|
||||
->printerr_literal (cmdline, message);
|
||||
g_free (message);
|
||||
}
|
||||
|
||||
void
|
||||
g_application_command_line_set_exit_status (GApplicationCommandLine *cmdline,
|
||||
int exit_status)
|
||||
{
|
||||
g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline));
|
||||
|
||||
cmdline->priv->exit_status = exit_status;
|
||||
}
|
||||
|
||||
int
|
||||
g_application_command_line_get_exit_status (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), -1);
|
||||
|
||||
return cmdline->priv->exit_status;
|
||||
}
|
||||
|
||||
static void
|
||||
grok_platform_data (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
GVariantIter iter;
|
||||
const gchar *key;
|
||||
GVariant *value;
|
||||
|
||||
g_variant_iter_init (&iter, cmdline->priv->platform_data);
|
||||
|
||||
while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
|
||||
if (strcmp (key, "cwd") == 0)
|
||||
{
|
||||
if (!cmdline->priv->cwd)
|
||||
cmdline->priv->cwd = g_variant_ref (value);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ARGUMENTS:
|
||||
g_value_set_variant (value, cmdline->priv->arguments);
|
||||
break;
|
||||
|
||||
case PROP_PLATFORM_DATA:
|
||||
g_value_set_variant (value, cmdline->priv->platform_data);
|
||||
break;
|
||||
|
||||
case PROP_IS_REMOTE:
|
||||
g_value_set_boolean (value, IS_REMOTE (cmdline));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ARGUMENTS:
|
||||
g_assert (cmdline->priv->arguments == NULL);
|
||||
cmdline->priv->arguments = g_value_dup_variant (value);
|
||||
break;
|
||||
|
||||
case PROP_PLATFORM_DATA:
|
||||
g_assert (cmdline->priv->platform_data == NULL);
|
||||
cmdline->priv->platform_data = g_value_dup_variant (value);
|
||||
if (cmdline->priv->platform_data != NULL)
|
||||
grok_platform_data (cmdline);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_finalize (GObject *object)
|
||||
{
|
||||
GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
|
||||
|
||||
if (cmdline->priv->platform_data)
|
||||
g_variant_unref (cmdline->priv->platform_data);
|
||||
if (cmdline->priv->arguments)
|
||||
g_variant_unref (cmdline->priv->arguments);
|
||||
if (cmdline->priv->cwd)
|
||||
g_variant_unref (cmdline->priv->cwd);
|
||||
|
||||
G_OBJECT_CLASS (g_application_command_line_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_init (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
cmdline->priv =
|
||||
G_TYPE_INSTANCE_GET_PRIVATE (cmdline,
|
||||
G_TYPE_APPLICATION_COMMAND_LINE,
|
||||
GApplicationCommandLinePrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_command_line_class_init (GApplicationCommandLineClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->get_property = g_application_command_line_get_property;
|
||||
object_class->set_property = g_application_command_line_set_property;
|
||||
object_class->finalize = g_application_command_line_finalize;
|
||||
class->printerr_literal = g_application_command_line_real_printerr_literal;
|
||||
class->print_literal = g_application_command_line_real_print_literal;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ARGUMENTS,
|
||||
g_param_spec_variant ("arguments", "commandline arguments",
|
||||
"the commandline that caused this cmdline",
|
||||
G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
|
||||
g_param_spec_variant ("platform-data", "platform data",
|
||||
"platform-specific data for the cmdline",
|
||||
G_VARIANT_TYPE ("a{sv}"), NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_IS_REMOTE,
|
||||
g_param_spec_boolean ("is-remote", "is remote",
|
||||
"TRUE if this is a remote cmdline", FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_type_class_add_private (class, sizeof (GApplicationCommandLinePrivate));
|
||||
}
|
||||
|
||||
GVariant *
|
||||
g_application_command_line_get_platform_data (GApplicationCommandLine *cmdline)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (cmdline), NULL);
|
||||
g_return_val_if_fail (IS_REMOTE (cmdline), NULL);
|
||||
|
||||
return g_variant_ref (cmdline->priv->platform_data);
|
||||
}
|
120
gio/gapplicationcommandline.h
Normal file
120
gio/gapplicationcommandline.h
Normal file
@ -0,0 +1,120 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright © 2010 Codethink Limited
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the licence or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Authors: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
|
||||
#error "Only <gio/gio.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __G_APPLICATION_COMMAND_LINE_H__
|
||||
#define __G_APPLICATION_COMMAND_LINE_H__
|
||||
|
||||
#include <gio/giotypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define G_TYPE_APPLICATION_COMMAND_LINE (g_application_command_line_get_type ())
|
||||
#define G_APPLICATION_COMMAND_LINE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
G_TYPE_APPLICATION_COMMAND_LINE, \
|
||||
GApplicationCommandLine))
|
||||
#define G_APPLICATION_COMMAND_LINE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
|
||||
G_TYPE_APPLICATION_COMMAND_LINE, \
|
||||
GApplicationCommandLineClass))
|
||||
#define G_IS_APPLICATION_COMMAND_LINE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
G_TYPE_APPLICATION_COMMAND_LINE))
|
||||
#define G_IS_APPLICATION_COMMAND_LINE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
|
||||
G_TYPE_APPLICATION_COMMAND_LINE))
|
||||
#define G_APPLICATION_COMMAND_LINE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
|
||||
G_TYPE_APPLICATION_COMMAND_LINE, \
|
||||
GApplicationCommandLineClass))
|
||||
|
||||
typedef struct _GApplicationCommandLinePrivate GApplicationCommandLinePrivate;
|
||||
typedef struct _GApplicationCommandLineClass GApplicationCommandLineClass;
|
||||
|
||||
/**
|
||||
* GApplicationCommandLine:
|
||||
*
|
||||
* The <structname>GApplicationCommandLine</structname> structure contains private
|
||||
* data and should only be accessed using the provided API
|
||||
*
|
||||
* Since: 2.26
|
||||
*/
|
||||
struct _GApplicationCommandLine
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
GApplicationCommandLinePrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* GApplicationCommandLineClass:
|
||||
*
|
||||
* The <structname>GApplicationCommandLineClass</structname> structure contains
|
||||
* private data only
|
||||
*
|
||||
* Since: 2.26
|
||||
*/
|
||||
struct _GApplicationCommandLineClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* print_literal) (GApplicationCommandLine *command_line,
|
||||
const gchar *message);
|
||||
void (* printerr_literal) (GApplicationCommandLine *command_line,
|
||||
const gchar *message);
|
||||
|
||||
gpointer padding[12];
|
||||
};
|
||||
|
||||
GType g_application_command_line_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void g_application_command_line_get_argc_argv (GApplicationCommandLine *command_line,
|
||||
int *argc,
|
||||
char ***argv);
|
||||
GVariant * g_application_command_line_get_arguments (GApplicationCommandLine *command_line);
|
||||
|
||||
const gchar * g_application_command_line_get_cwd (GApplicationCommandLine *command_line);
|
||||
GVariant * g_application_command_line_get_cwd_variant (GApplicationCommandLine *command_line);
|
||||
|
||||
gboolean g_application_command_line_get_is_remote (GApplicationCommandLine *command_line);
|
||||
|
||||
void g_application_command_line_output (GApplicationCommandLine *command_line,
|
||||
gint fd,
|
||||
gconstpointer buffer,
|
||||
gssize length);
|
||||
void g_application_command_line_print (GApplicationCommandLine *command_line,
|
||||
const gchar *format,
|
||||
...);
|
||||
void g_application_command_line_printerr (GApplicationCommandLine *command_line,
|
||||
const gchar *format,
|
||||
...);
|
||||
|
||||
int g_application_command_line_get_exit_status (GApplicationCommandLine *command_line);
|
||||
void g_application_command_line_set_exit_status (GApplicationCommandLine *command_line,
|
||||
int exit_status);
|
||||
|
||||
GVariant * g_application_command_line_get_platform_data (GApplicationCommandLine *command_line);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_APPLICATION_COMMAND_LINE_H__ */
|
@ -37,6 +37,9 @@ static const GDBusArgInfo *activate_out[] = { NULL };
|
||||
static const GDBusArgInfo *open_in[] = { &open_uris_arg, &open_hint_arg, &platform_data_arg, NULL };
|
||||
static const GDBusArgInfo *open_out[] = { NULL };
|
||||
|
||||
static const GDBusArgInfo *cmdline_in[] = { &cmdline_path_arg, &cmdline_arguments_arg, &platform_data_arg, NULL };
|
||||
static const GDBusArgInfo *cmdline_out[] = { &cmdline_exit_status_arg, NULL };
|
||||
|
||||
static const GDBusMethodInfo activate_method = {
|
||||
-1, (gchar *) "Activate",
|
||||
(GDBusArgInfo **) activate_in,
|
||||
@ -49,11 +52,42 @@ static const GDBusMethodInfo open_method = {
|
||||
(GDBusArgInfo **) open_out
|
||||
};
|
||||
|
||||
static const GDBusMethodInfo command_line_method = {
|
||||
-1, (gchar *) "CommandLine",
|
||||
(GDBusArgInfo **) cmdline_in,
|
||||
(GDBusArgInfo **) cmdline_out
|
||||
};
|
||||
|
||||
static const GDBusMethodInfo *application_methods[] = {
|
||||
&activate_method, &open_method, NULL
|
||||
&activate_method, &open_method, &command_line_method, NULL
|
||||
};
|
||||
|
||||
const GDBusInterfaceInfo org_gtk_Application = {
|
||||
-1, (gchar *) "org.gtk.Application",
|
||||
(GDBusMethodInfo **) application_methods
|
||||
};
|
||||
|
||||
static const GDBusArgInfo message_arg = { -1, (gchar *) "message", (gchar *) "s" };
|
||||
static const GDBusArgInfo *print_in[] = { &message_arg, NULL };
|
||||
static const GDBusArgInfo *print_out[] = { NULL };
|
||||
|
||||
static const GDBusMethodInfo stdout_method = {
|
||||
-1, (gchar *) "Print",
|
||||
(GDBusArgInfo **) print_in,
|
||||
(GDBusArgInfo **) print_out
|
||||
};
|
||||
|
||||
static const GDBusMethodInfo stderr_method = {
|
||||
-1, (gchar *) "PrintError",
|
||||
(GDBusArgInfo **) print_in,
|
||||
(GDBusArgInfo **) print_out
|
||||
};
|
||||
|
||||
static const GDBusMethodInfo *cmdline_methods[] = {
|
||||
&stdout_method, &stderr_method, NULL
|
||||
};
|
||||
|
||||
const GDBusInterfaceInfo org_gtk_private_Cmdline = {
|
||||
-1, (gchar *) "org.gtk.private.CommandLine",
|
||||
(GDBusMethodInfo **) cmdline_methods
|
||||
};
|
||||
|
@ -28,9 +28,11 @@
|
||||
#include "gdbuserror.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gapplicationimpl-dbus-interface.c"
|
||||
#include "gapplicationcommandline.h"
|
||||
#include "gdbusmethodinvocation.h"
|
||||
|
||||
struct _GApplicationImpl
|
||||
{
|
||||
@ -39,10 +41,13 @@ struct _GApplicationImpl
|
||||
gchar *object_path;
|
||||
guint object_id;
|
||||
gpointer app;
|
||||
|
||||
GMainLoop *cmdline_mainloop;
|
||||
};
|
||||
|
||||
|
||||
static GApplicationCommandLine *
|
||||
g_dbus_command_line_new (GDBusMethodInvocation *invocation);
|
||||
|
||||
|
||||
static void
|
||||
g_application_impl_method_call (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
@ -104,6 +109,22 @@ g_application_impl_method_call (GDBusConnection *connection,
|
||||
g_free (files);
|
||||
}
|
||||
|
||||
else if (strcmp (method_name, "CommandLine") == 0)
|
||||
{
|
||||
GApplicationCommandLine *cmdline;
|
||||
GVariant *platform_data;
|
||||
int status;
|
||||
|
||||
cmdline = g_dbus_command_line_new (invocation);
|
||||
platform_data = g_variant_get_child_value (parameters, 2);
|
||||
class->before_emit (impl->app, platform_data);
|
||||
g_signal_emit_by_name (impl->app, "command-line", cmdline, &status);
|
||||
g_application_command_line_set_exit_status (cmdline, status);
|
||||
class->after_emit (impl->app, platform_data);
|
||||
g_variant_unref (platform_data);
|
||||
g_object_unref (cmdline);
|
||||
}
|
||||
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@ -175,7 +196,7 @@ g_application_impl_register (GApplication *application,
|
||||
|
||||
impl->object_path = application_path_from_appid (appid);
|
||||
|
||||
if (flags & G_APPLICATION_FLAGS_IS_LAUNCHER)
|
||||
if (flags & G_APPLICATION_IS_LAUNCHER)
|
||||
{
|
||||
impl->object_id = 0;
|
||||
*is_remote = TRUE;
|
||||
@ -238,7 +259,7 @@ g_application_impl_register (GApplication *application,
|
||||
impl->object_id);
|
||||
impl->object_id = 0;
|
||||
|
||||
if (flags & G_APPLICATION_FLAGS_IS_SERVICE)
|
||||
if (flags & G_APPLICATION_IS_SERVICE)
|
||||
{
|
||||
g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
|
||||
"Unable to acquire bus name `%s'", appid);
|
||||
@ -297,8 +318,211 @@ g_application_impl_open (GApplicationImpl *impl,
|
||||
NULL, 0, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
g_application_impl_cmdline_method_call (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
const gchar *object_path,
|
||||
const gchar *interface_name,
|
||||
const gchar *method_name,
|
||||
GVariant *parameters,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
const gchar *message;
|
||||
|
||||
g_variant_get_child (parameters, 0, "&s", &message);
|
||||
|
||||
if (strcmp (method_name, "Print") == 0)
|
||||
g_print ("%s", message);
|
||||
else if (strcmp (method_name, "PrintError") == 0)
|
||||
g_printerr ("%s", message);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMainLoop *loop;
|
||||
int status;
|
||||
} CommandLineData;
|
||||
|
||||
static void
|
||||
g_application_impl_cmdline_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
CommandLineData *data = user_data;
|
||||
GError *error = NULL;
|
||||
GVariant *reply;
|
||||
|
||||
reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
|
||||
result, &error);
|
||||
|
||||
if (reply != NULL)
|
||||
{
|
||||
g_variant_get (reply, "(i)", &data->status);
|
||||
g_variant_unref (reply);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
data->status = 1;
|
||||
}
|
||||
|
||||
g_main_loop_quit (data->loop);
|
||||
}
|
||||
|
||||
int
|
||||
g_application_impl_command_line (GApplicationImpl *impl,
|
||||
GVariant *arguments,
|
||||
GVariant *platform_data)
|
||||
{
|
||||
const static GDBusInterfaceVTable vtable = {
|
||||
g_application_impl_cmdline_method_call
|
||||
};
|
||||
const gchar *object_path = "/org/gtk/Application/CommandLine";
|
||||
GMainContext *context;
|
||||
CommandLineData data;
|
||||
guint object_id;
|
||||
|
||||
context = g_main_context_new ();
|
||||
data.loop = g_main_loop_new (context, FALSE);
|
||||
g_main_context_push_thread_default (context);
|
||||
|
||||
object_id = g_dbus_connection_register_object (impl->session_bus,
|
||||
object_path,
|
||||
(GDBusInterfaceInfo *)
|
||||
&org_gtk_private_Cmdline,
|
||||
&vtable, &data, NULL, NULL);
|
||||
/* In theory we should try other paths... */
|
||||
g_assert (object_id != 0);
|
||||
|
||||
g_dbus_connection_call (impl->session_bus,
|
||||
impl->bus_name,
|
||||
impl->object_path,
|
||||
"org.gtk.Application",
|
||||
"CommandLine",
|
||||
g_variant_new ("(o@aay@a{sv})", object_path,
|
||||
arguments, platform_data),
|
||||
G_VARIANT_TYPE ("(i)"), 0, -1, NULL,
|
||||
g_application_impl_cmdline_done, &data);
|
||||
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
g_main_context_pop_thread_default (context);
|
||||
g_main_context_unref (context);
|
||||
g_main_loop_unref (data.loop);
|
||||
|
||||
return data.status;
|
||||
}
|
||||
|
||||
void
|
||||
g_application_impl_flush (GApplicationImpl *impl)
|
||||
{
|
||||
g_dbus_connection_flush_sync (impl->session_bus, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef GApplicationCommandLineClass GDBusCommandLineClass;
|
||||
static GType g_dbus_command_line_get_type (void);
|
||||
typedef struct
|
||||
{
|
||||
GApplicationCommandLine parent_instance;
|
||||
GDBusMethodInvocation *invocation;
|
||||
|
||||
GDBusConnection *connection;
|
||||
const gchar *bus_name;
|
||||
const gchar *object_path;
|
||||
} GDBusCommandLine;
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GDBusCommandLine,
|
||||
g_dbus_command_line,
|
||||
G_TYPE_APPLICATION_COMMAND_LINE)
|
||||
|
||||
static void
|
||||
g_dbus_command_line_print_literal (GApplicationCommandLine *cmdline,
|
||||
const gchar *message)
|
||||
{
|
||||
GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
|
||||
|
||||
g_dbus_connection_call (gdbcl->connection,
|
||||
gdbcl->bus_name,
|
||||
gdbcl->object_path,
|
||||
"org.gtk.private.CommandLine", "Print",
|
||||
g_variant_new ("(s)", message),
|
||||
NULL, 0, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
g_dbus_command_line_printerr_literal (GApplicationCommandLine *cmdline,
|
||||
const gchar *message)
|
||||
{
|
||||
GDBusCommandLine *gdbcl = (GDBusCommandLine *) cmdline;
|
||||
|
||||
g_dbus_connection_call (gdbcl->connection,
|
||||
gdbcl->bus_name,
|
||||
gdbcl->object_path,
|
||||
"org.gtk.private.CommandLine", "PrintError",
|
||||
g_variant_new ("(s)", message),
|
||||
NULL, 0, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
g_dbus_command_line_finalize (GObject *object)
|
||||
{
|
||||
GApplicationCommandLine *cmdline = G_APPLICATION_COMMAND_LINE (object);
|
||||
GDBusCommandLine *gdbcl = (GDBusCommandLine *) object;
|
||||
gint status;
|
||||
|
||||
status = g_application_command_line_get_exit_status (cmdline);
|
||||
|
||||
g_dbus_method_invocation_return_value (gdbcl->invocation,
|
||||
g_variant_new ("(i)", status));
|
||||
g_object_unref (gdbcl->invocation);
|
||||
|
||||
G_OBJECT_CLASS (g_dbus_command_line_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
g_dbus_command_line_init (GDBusCommandLine *gdbcl)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
g_dbus_command_line_class_init (GApplicationCommandLineClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = g_dbus_command_line_finalize;
|
||||
class->printerr_literal = g_dbus_command_line_printerr_literal;
|
||||
class->print_literal = g_dbus_command_line_print_literal;
|
||||
}
|
||||
|
||||
static GApplicationCommandLine *
|
||||
g_dbus_command_line_new (GDBusMethodInvocation *invocation)
|
||||
{
|
||||
GDBusCommandLine *gdbcl;
|
||||
GVariant *args;
|
||||
|
||||
args = g_dbus_method_invocation_get_parameters (invocation);
|
||||
|
||||
gdbcl = g_object_new (g_dbus_command_line_get_type (),
|
||||
"arguments", g_variant_get_child_value (args, 1),
|
||||
"platform-data", g_variant_get_child_value (args, 2),
|
||||
NULL);
|
||||
gdbcl->connection = g_dbus_method_invocation_get_connection (invocation);
|
||||
gdbcl->bus_name = g_dbus_method_invocation_get_sender (invocation);
|
||||
g_variant_get_child (args, 0, "&o", &gdbcl->object_path);
|
||||
gdbcl->invocation = g_object_ref (invocation);
|
||||
|
||||
return G_APPLICATION_COMMAND_LINE (gdbcl);
|
||||
}
|
||||
|
@ -24,5 +24,10 @@ void g_application_impl_open (GApplic
|
||||
const gchar *hint,
|
||||
GVariant *platform_data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
int g_application_impl_command_line (GApplicationImpl *impl,
|
||||
GVariant *arguments,
|
||||
GVariant *platform_data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void g_application_impl_flush (GApplicationImpl *impl);
|
||||
|
@ -23,3 +23,4 @@ VOID:STRING,STRING
|
||||
VOID:STRING,BOOLEAN
|
||||
VOID:POINTER,INT,STRING
|
||||
BOOLEAN:OBJECT
|
||||
INT:OBJECT
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <gio/gactiongroup.h>
|
||||
#include <gio/gsimpleactiongroup.h>
|
||||
#include <gio/gapplication.h>
|
||||
#include <gio/gapplicationcommandline.h>
|
||||
#include <gio/gasyncinitable.h>
|
||||
#include <gio/gasyncresult.h>
|
||||
#include <gio/gbufferedinputstream.h>
|
||||
|
@ -1228,10 +1228,11 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
G_APPLICATION_FLAGS_NONE,
|
||||
G_APPLICATION_FLAGS_IS_SERVICE = (1 << 0),
|
||||
G_APPLICATION_FLAGS_IS_LAUNCHER = (1 << 1),
|
||||
G_APPLICATION_IS_SERVICE = (1 << 0),
|
||||
G_APPLICATION_IS_LAUNCHER = (1 << 1),
|
||||
|
||||
G_APPLICATION_FLAGS_HANDLES_OPEN = (1 << 2)
|
||||
G_APPLICATION_HANDLES_OPEN = (1 << 2),
|
||||
G_APPLICATION_HANDLES_COMMAND_LINE = (1 << 3)
|
||||
} GApplicationFlags;
|
||||
|
||||
G_END_DECLS
|
||||
|
Loading…
Reference in New Issue
Block a user