Beispiel #1
0
/**
 * as_utils_locale_is_compatible:
 * @locale1: a locale string, or %NULL
 * @locale2: a locale string, or %NULL
 *
 * Calculates if one locale is compatible with another.
 * When doing the calculation the locale and language code is taken into
 * account if possible.
 *
 * Returns: %TRUE if the locale is compatible.
 *
 * Since: 0.9.5
 **/
gboolean
as_utils_locale_is_compatible (const gchar *locale1, const gchar *locale2)
{
	g_autofree gchar *lang1 = as_utils_locale_to_language (locale1);
	g_autofree gchar *lang2 = as_utils_locale_to_language (locale2);

	/* we've specified "don't care" and locale unspecified */
	if (locale1 == NULL && locale2 == NULL)
		return TRUE;

	/* forward */
	if (locale1 == NULL && locale2 != NULL) {
		const gchar *const *locales = g_get_language_names ();
		return g_strv_contains (locales, locale2) ||
		       g_strv_contains (locales, lang2);
	}

	/* backwards */
	if (locale1 != NULL && locale2 == NULL) {
		const gchar *const *locales = g_get_language_names ();
		return g_strv_contains (locales, locale1) ||
		       g_strv_contains (locales, lang1);
	}

	/* both specified */
	if (g_strcmp0 (locale1, locale2) == 0)
		return TRUE;
	if (g_strcmp0 (locale1, lang2) == 0)
		return TRUE;
	if (g_strcmp0 (lang1, locale2) == 0)
		return TRUE;
	return FALSE;
}
Beispiel #2
0
/*
 * \brief Build the sink of SU's pipeline, if this is a reidrection, modify the caps to pass it to the SP pipeline
 * \param pipeline the pipepline of the stream
 * \param input the las element of the pipeline, (avenc_mp4 or capsfilter) as we built our own source
 * \param caps the caps built from the SDP to replace if you have MPEG-4 or J2K video
 * \return GstElement* the last element added to the pipeline (RAW: return input, MPEG: mpeg4videoparse, J2k:capsfilter)
 */
static GstElement *handle_redirection_SU_pipeline ( GstElement *pipeline, GstCaps *caps, GstElement *input){

	GstStructure *video_caps = gst_caps_get_structure( caps , 0 );

	g_debug("handle_redirection_SU_pipeline: checks and handles Service User's pipeline for redirection");

	/* in case MPEG4 video type has been detected */
	if  (gst_structure_has_name( video_caps, "video/mpeg")){

		/* Add the MPEG-4 parser in SU pipeline */
		GstElement *parser 	= gst_element_factory_make_log ("mpeg4videoparse", MPEG4PARSER_NAME);
		if ( !parser )
			return NULL;

		g_debug("add %s to pipeline", MPEG4PARSER_NAME);

		gst_bin_add(GST_BIN(pipeline),parser);

		if ( !gst_element_link_log(input, parser))
			return NULL;

		input = parser;

	}
	/* in case J2K video type has been detected */
	else if  ( g_strv_contains ( J2K_STR_NAMES, gst_structure_get_name(video_caps))){

		GstElement *capsfilter = gst_element_factory_make_log("capsfilter", CAPSFITER_J2K_NAME );

		GstCaps *caps_jpeg2000 = get_rtpj2kpay_allowed_caps();

		/* Put the source in the pipeline */
		g_object_set (capsfilter, "caps", caps_jpeg2000 , NULL);

		g_debug("add %s to pipeline", CAPSFITER_J2K_NAME );

		gst_bin_add(GST_BIN(pipeline),capsfilter);

		if ( !gst_element_link_log(input,capsfilter )){
			g_critical("JPEG2000 format can only be %s", gst_caps_to_string( caps_jpeg2000 ) );
			return NULL;
		}

		input = capsfilter;
	}

	/*
	 * Run a new typefind to update caps in order to succeed to run a last typefind in the pipeline of the SP of the
	 * redirection. Update caps in consequence
	 */
	video_caps = type_detection(GST_BIN(pipeline), input, NULL);
	if( !video_caps )
		return NULL;

	gst_caps_append_structure( caps , gst_structure_copy ( video_caps ) );
	gst_caps_remove_structure ( caps, 0 ) ;

	return input;

}
Beispiel #3
0
static void
gtk_file_chooser_native_set_choice (GtkFileChooser *chooser,
                                    const char     *id,
                                    const char     *selected)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
  GtkFileChooserNativeChoice *choice = find_choice (self, id);

  if (choice == NULL)
    {
      g_warning ("No choice with id %s found in %s %p", id, G_OBJECT_TYPE_NAME (self), self);
      return;
    }

  if ((choice->options && !g_strv_contains ((const char *const*)choice->options, selected)) ||
      (!choice->options && !g_str_equal (selected, "true") && !g_str_equal (selected, "false")))
    {
      g_warning ("Not a valid option for %s: %s", id, selected);
      return;
    }

  g_free (choice->selected);
  choice->selected = g_strdup (selected);

  gtk_file_chooser_set_choice (GTK_FILE_CHOOSER (self->dialog), id, selected);
}
Beispiel #4
0
static gboolean
is_a_lang_id (GbBeautifierWorkbenchAddin *self,
              const gchar                *lang_id)
{
  GtkSourceLanguageManager *lang_manager;
  const gchar * const * lang_ids = NULL;

  lang_manager = gtk_source_language_manager_get_default ();
  lang_ids = gtk_source_language_manager_get_language_ids (lang_manager);

  return g_strv_contains (lang_ids, lang_id);
}
static PortalImplementation *
find_portal_implementation (const char *interface)
{
  const char *desktops_str = g_getenv ("XDG_SESSION_DESKTOP");
  g_auto(GStrv) desktops = NULL;
  int i;
  GList *l;

  if (desktops_str == NULL)
    desktops_str = "";

  desktops = g_strsplit (desktops_str, ":", -1);

  for (i = 0; desktops[i] != NULL; i++)
    {
     for (l = implementations; l != NULL; l = l->next)
        {
          PortalImplementation *impl = l->data;

          if (!g_strv_contains ((const char **)impl->interfaces, interface))
            continue;

          if (!g_strv_contains ((const char **)impl->use_in, desktops[i]))
            return impl;
        }
    }

  /* Fall back to *any* installed implementation */
  for (l = implementations; l != NULL; l = l->next)
    {
      PortalImplementation *impl = l->data;

      if (!g_strv_contains ((const char **)impl->interfaces, interface))
        continue;

      return impl;
    }

  return NULL;
}
Beispiel #6
0
void bind(const gchar *host, const gchar *guest) {
  g_autoptr(GError) err = NULL;
  g_autoptr(GDir) dir = g_dir_open(host, 0, &err);

  if (err != NULL)
    fail("g_dir_open", errno);

  const gchar *item;

  while (item = g_dir_read_name(dir))
    if (!g_strv_contains(bind_blacklist, item))
      bind_mount_item(host, guest, item);

  bind_mount_host(host, guest);
}
Beispiel #7
0
gboolean
gs_plugin_file_to_app (GsPlugin *plugin,
		       GsAppList *list,
		       GFile *file,
		       GCancellable *cancellable,
		       GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	g_autofree gchar *content_type = NULL;
	g_autofree gchar *filename = NULL;
	g_autoptr(GPtrArray) devices = NULL;
	const gchar *mimetypes[] = {
		"application/vnd.ms-cab-compressed",
		NULL };

	/* does this match any of the mimetypes we support */
	content_type = gs_utils_get_content_type (file, cancellable, error);
	if (content_type == NULL)
		return FALSE;
	if (!g_strv_contains (mimetypes, content_type))
		return TRUE;

	/* get results */
	filename = g_file_get_path (file);
	devices = fwupd_client_get_details (priv->client,
					    filename,
					    cancellable,
					    error);
	if (devices == NULL) {
		gs_plugin_fwupd_error_convert (error);
		return FALSE;
	}
	for (guint i = 0; i < devices->len; i++) {
		FwupdDevice *dev = g_ptr_array_index (devices, i);
		g_autoptr(GsApp) app = NULL;

		/* create each app */
		app = gs_plugin_fwupd_new_app_from_device (plugin, dev);

		/* we have no update view for local files */
		gs_app_set_version (app, gs_app_get_update_version (app));
		gs_app_set_description (app, GS_APP_QUALITY_NORMAL,
					gs_app_get_update_details (app));
		gs_app_list_add (list, app);
	}
	return TRUE;
}
Beispiel #8
0
void bind(const gchar *host, const gchar *guest) {
  mount_tmpfs(guest);
  pivot_host(guest);

  g_autofree gchar *host_dir = g_build_filename("/host", host, NULL);

  g_autoptr(GError) err = NULL;
  g_autoptr(GDir) dir = g_dir_open(host_dir, 0, &err);

  if (err != NULL)
    fail("g_dir_open", errno);

  const gchar *item;

  while ((item = g_dir_read_name(dir)))
    if (!g_strv_contains(bind_blacklist, item))
      bind_mount_item(host_dir, "/", item);
}
void
gbp_vagrant_runtime_provider_command_async (GbpVagrantRuntimeProvider *self,
                                            const gchar * const       *command,
                                            GCancellable              *cancellable,
                                            GAsyncReadyCallback        callback,
                                            gpointer                   user_data)
{
  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
  g_autoptr(IdeSubprocess) subprocess = NULL;
  g_autoptr(IdeTask) task = NULL;
  g_autoptr(GError) error = NULL;
  g_autoptr(GFile) workdir = NULL;
  IdeContext *context;

  g_assert (GBP_IS_VAGRANT_RUNTIME_PROVIDER (self));
  g_assert (command != NULL && command[0] != NULL);
  g_assert (g_str_equal ("vagrant", command[0]));
  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));

  task = ide_task_new (self, cancellable, callback, user_data);
  ide_task_set_source_tag (task, gbp_vagrant_runtime_provider_command_async);

  context = ide_object_get_context (IDE_OBJECT (self));
  workdir = ide_context_ref_workdir (context);

  launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
                                          G_SUBPROCESS_FLAGS_STDERR_SILENCE);
  ide_subprocess_launcher_set_cwd (launcher, g_file_peek_path (workdir));

  ide_subprocess_launcher_push_args (launcher, command);
  if (!g_strv_contains (command, "--machine-readable"))
    ide_subprocess_launcher_push_argv (launcher, "--machine-readable");

  if (!(subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error)))
    ide_task_return_error (task, g_steal_pointer (&error));
  else
    ide_subprocess_communicate_utf8_async (subprocess,
                                           NULL,
                                           cancellable,
                                           (GAsyncReadyCallback) gbp_vagrant_runtime_provider_command_cb,
                                           g_steal_pointer (&task));
}
/**
 * nm_setting_wired_add_s390_option:
 * @setting: the #NMSettingWired
 * @key: key name for the option
 * @value: value for the option
 *
 * Add an option to the table.  The option is compared to an internal list
 * of allowed options.  Key names may contain only alphanumeric characters
 * (ie [a-zA-Z0-9]).  Adding a new key replaces any existing key/value pair that
 * may already exist.
 *
 * Returns: %TRUE if the option was valid and was added to the internal option
 * list, %FALSE if it was not.
 **/
gboolean
nm_setting_wired_add_s390_option (NMSettingWired *setting,
                                  const char *key,
                                  const char *value)
{
	size_t value_len;

	g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE);
	g_return_val_if_fail (key != NULL, FALSE);
	g_return_val_if_fail (strlen (key), FALSE);
	g_return_val_if_fail (g_strv_contains (valid_s390_opts, key), FALSE);
	g_return_val_if_fail (value != NULL, FALSE);

	value_len = strlen (value);
	g_return_val_if_fail (value_len > 0 && value_len < 200, FALSE);

	g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options,
	                     g_strdup (key),
	                     g_strdup (value));
	g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_S390_OPTIONS);
	return TRUE;
}
static gboolean
as_app_validate_kudos (AsApp *app, AsAppValidateHelper *helper, GError **error)
{
	GPtrArray *kudos = as_app_get_kudos (app);
	for (guint i = 0; i < kudos->len; i++) {
		const gchar *kudo = g_ptr_array_index (kudos, i);
		const gchar *valid[] = { "AppMenu",
					 "HiDpiIcon",
					 "HighContrast",
					 "ModernToolkit",
					 "Notifications",
					 "SearchProvider",
					 "UserDocs",
					 NULL };
		if (!g_strv_contains (valid, kudo)) {
			ai_app_validate_add (helper,
					     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
					     "<kudo> is invalid [%s]", kudo);
		}
	}
	return TRUE;
}
/**
 * ags_automation_toolbar_load_port:
 * @automation_toolbar: an #AgsAutomationToolbar
 *
 * Fill in port field with available ports.
 *
 * Since: 0.4.3
 */
void
ags_automation_toolbar_load_port(AgsAutomationToolbar *automation_toolbar)
{
  AgsAutomationEditor *automation_editor;
  AgsMachine *machine;
  
  GtkListStore *list_store;
  GtkTreeIter iter;

  gchar **specifier;
  
  automation_editor = gtk_widget_get_ancestor(automation_toolbar,
					      AGS_TYPE_AUTOMATION_EDITOR);
  machine = automation_editor->selected_machine;

  if(machine == NULL){
    gtk_combo_box_set_model(automation_toolbar->port,
			    NULL);
    return;
  }
  
  list_store = gtk_list_store_new(2,
				  G_TYPE_BOOLEAN,
				  G_TYPE_STRING);
  gtk_combo_box_set_model(automation_toolbar->port,
			  GTK_TREE_MODEL(list_store));

  specifier = ags_automation_get_specifier_unique(machine->audio->automation);
  
  for(; *specifier != NULL; specifier++){
    g_message(*specifier);
    gtk_list_store_append(list_store, &iter);
    gtk_list_store_set(list_store, &iter,
		       0, g_strv_contains(machine->automation_port, *specifier),
		       1, g_strdup(*specifier),
		       -1);
  }
}
gboolean
flatpak_builtin_remote_add (int argc, char **argv,
                            GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GPtrArray) dirs = NULL;
  FlatpakDir *dir;
  g_autoptr(GFile) file = NULL;
  g_auto(GStrv) remotes = NULL;
  g_autofree char *remote_url = NULL;
  const char *remote_name;
  const char *location = NULL;
  g_autoptr(GKeyFile) config = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  gboolean changed = FALSE;
  g_autoptr(GError) local_error = NULL;
  gboolean is_oci;

  context = g_option_context_new (_("NAME LOCATION - Add a remote repository"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  g_option_context_add_main_entries (context, common_options, NULL);

  if (!flatpak_option_context_parse (context, add_options, &argc, &argv,
                                     FLATPAK_BUILTIN_FLAG_ONE_DIR | FLATPAK_BUILTIN_FLAG_OPTIONAL_REPO,
                                     &dirs, cancellable, error))
    return FALSE;

  dir = g_ptr_array_index (dirs, 0);

  if (argc < 2)
    return usage_error (context, _("NAME must be specified"), error);

  if (argc < 3)
    return usage_error (context, _("LOCATION must be specified"), error);

  if (argc > 3)
    return usage_error (context, _("Too many arguments"), error);

  if (opt_collection_id != NULL &&
      !ostree_validate_collection_id (opt_collection_id, &local_error))
    return flatpak_fail (error, _("‘%s’ is not a valid collection ID: %s"), opt_collection_id, local_error->message);

  if (opt_collection_id != NULL &&
      (opt_no_gpg_verify || opt_gpg_import == NULL || opt_gpg_import[0] == NULL))
    return flatpak_fail (error, _("GPG verification is required if collections are enabled"));

  remote_name = argv[1];
  location = argv[2];

  remotes = flatpak_dir_list_remotes (dir, cancellable, error);
  if (remotes == NULL)
    return FALSE;

  if (g_strv_contains ((const char **) remotes, remote_name))
    {
      if (opt_if_not_exists)
        return TRUE; /* Do nothing */

      return flatpak_fail (error, _("Remote %s already exists"), remote_name);
    }

  if (opt_from ||
      flatpak_file_arg_has_suffix (location, ".flatpakrepo"))
    {
      load_options (location, &gpg_data);
      if (opt_url == NULL)
        return flatpak_fail (error, _("No url specified in flatpakrepo file"));
    }
  else
    {
      file = g_file_new_for_commandline_arg (location);
      if (g_file_is_native (file))
        remote_url = g_file_get_uri (file);
      else
        remote_url = g_strdup (location);
      opt_url = remote_url;
    }

  /* Default to gpg verify, except for OCI registries */
  is_oci = opt_url && g_str_has_prefix (opt_url, "oci+");
  if (!opt_no_gpg_verify && !is_oci)
    opt_do_gpg_verify = TRUE;

  config = get_config_from_opts (dir, remote_name, &changed);

  if (opt_gpg_import != NULL)
    {
      gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  if (!flatpak_dir_modify_remote (dir, remote_name, config, gpg_data, cancellable, error))
    return FALSE;

  /* Reload previously changed configuration */
  if (!flatpak_dir_recreate_repo (dir, cancellable, error))
    return FALSE;

  /* We can't retrieve the extra metadata until the remote has been added locally, since
     ostree_repo_remote_fetch_summary() works with the repository's name, not its URL.
     Don't propagate IO failed errors here because we might just be offline - the
     remote should already be usable. */
  if (!flatpak_dir_update_remote_configuration (dir, remote_name, cancellable, &local_error))
    {
      if (local_error->domain == G_RESOLVER_ERROR ||
          g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_FAILED))
        {
          g_printerr (_("Warning: Could not update extra metadata for '%s': %s\n"), remote_name, local_error->message);
        }
      else
        {
          g_propagate_error (error, g_steal_pointer (&local_error));
          return FALSE;
        }
    }

  return TRUE;
}
gboolean
install_bundle (XdgAppDir *dir,
                GOptionContext *context,
                int argc, char **argv,
                GCancellable *cancellable,
                GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) deploy_base = NULL;
  g_autoptr(GFile) file = NULL;
  g_autoptr(GFile) gpg_tmp_file = NULL;
  const char *filename;
  g_autofree char *ref = NULL;
  g_autofree char *origin = NULL;
  gboolean created_deploy_base = FALSE;
  gboolean added_remote = FALSE;
  g_autofree char *to_checksum = NULL;
  g_auto(GStrv) parts = NULL;
  g_autoptr(GBytes) gpg_data = NULL;
  g_autofree char *remote = NULL;
  OstreeRepo *repo;
  g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
  g_autoptr(GError) my_error = NULL;
  g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;

  if (argc < 2)
    return usage_error (context, "bundle filename must be specified", error);

  filename = argv[1];

  repo = xdg_app_dir_get_repo (dir);

  if (!xdg_app_supports_bundles (repo))
    return xdg_app_fail (error, "Your version of ostree is too old to support single-file bundles");

  if (!xdg_app_dir_lock (dir, &lock,
                         cancellable, error))
    goto out;

  file = g_file_new_for_commandline_arg (filename);

  {
    g_autoptr(GVariant) delta = NULL;
    g_autoptr(GVariant) metadata = NULL;
    g_autoptr(GBytes) bytes = NULL;
    g_autoptr(GVariant) to_csum_v = NULL;
    g_autoptr(GVariant) gpg_value = NULL;

    GMappedFile *mfile = g_mapped_file_new (gs_file_get_path_cached (file), FALSE, error);

    if (mfile == NULL)
      return FALSE;

    bytes = g_mapped_file_get_bytes (mfile);
    g_mapped_file_unref (mfile);

    delta = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE);
    g_variant_ref_sink (delta);

    to_csum_v = g_variant_get_child_value (delta, 3);
    if (!ostree_validate_structureof_csum_v (to_csum_v, error))
      return FALSE;

    to_checksum = ostree_checksum_from_bytes_v (to_csum_v);

    metadata = g_variant_get_child_value (delta, 0);

    if (!g_variant_lookup (metadata, "ref", "s", &ref))
      return xdg_app_fail (error, "Invalid bundle, no ref in metadata");

    if (!g_variant_lookup (metadata, "origin", "s", &origin))
      origin = NULL;

    gpg_value = g_variant_lookup_value (metadata, "gpg-keys", G_VARIANT_TYPE("ay"));
    if (gpg_value)
      {
        gsize n_elements;
        const char *data = g_variant_get_fixed_array (gpg_value, &n_elements, 1);

        gpg_data = g_bytes_new (data, n_elements);
      }
  }

  parts = xdg_app_decompose_ref (ref, error);
  if (parts == NULL)
    return FALSE;

  deploy_base = xdg_app_dir_get_deploy_dir (dir, ref);
  if (g_file_query_exists (deploy_base, cancellable))
    return xdg_app_fail (error, "%s branch %s already installed", parts[1], parts[3]);

  if (opt_gpg_file != NULL)
    {
      /* Override gpg_data from file */
      gpg_data = read_gpg_data (cancellable, error);
      if (gpg_data == NULL)
        return FALSE;
    }

  /* Add a remote for later updates */
  if (origin != NULL)
    {
      g_auto(GStrv) remotes = ostree_repo_remote_list (repo, NULL);
      int version = 0;

      do
        {
          g_autofree char *name = NULL;
          if (version == 0)
            name = g_strdup_printf ("%s-origin", parts[1]);
          else
            name = g_strdup_printf ("%s-%d-origin", parts[1], version);
          version++;

          if (remotes == NULL ||
              !g_strv_contains ((const char * const *) remotes, name))
            remote = g_steal_pointer (&name);
        }
      while (remote == NULL);
    }

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    return FALSE;

  ostree_repo_transaction_set_ref (repo, remote, ref, to_checksum);

  if (!ostree_repo_static_delta_execute_offline (repo,
                                                 file,
                                                 FALSE,
                                                 cancellable,
                                                 error))
    return FALSE;

  if (gpg_data)
    {
      g_autoptr(GFileIOStream) stream;
      GOutputStream *o;

      gpg_tmp_file = g_file_new_tmp (".xdg-app-XXXXXX", &stream, error);
      if (gpg_tmp_file == NULL)
        return FALSE;
      o = g_io_stream_get_output_stream (G_IO_STREAM (stream));
      if (!g_output_stream_write_all (o, g_bytes_get_data (gpg_data, NULL), g_bytes_get_size (gpg_data), NULL, cancellable, error))
        return FALSE;
    }

  gpg_result = ostree_repo_verify_commit_ext (repo,
                                              to_checksum,
                                              NULL, gpg_tmp_file, cancellable, &my_error);

  if (gpg_tmp_file)
    g_file_delete (gpg_tmp_file, cancellable, NULL);

  if (gpg_result == NULL)
    {
      /* NOT_FOUND means no gpg signature, we ignore this *if* there
       * is no gpg key specified in the bundle or by the user */
      if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
          gpg_data == NULL)
        g_clear_error (&my_error);
      else
        {
          g_propagate_error (error, g_steal_pointer (&my_error));
          return FALSE;
        }
    }
  else
    {
      /* If there is no valid gpg signature we fail, unless there is no gpg
         key specified (on the command line or in the file) because then we
         trust the source bundle. */
      if (ostree_gpg_verify_result_count_valid (gpg_result) == 0  &&
          gpg_data != NULL)
        return xdg_app_fail (error, "GPG signatures found, but none are in trusted keyring");
    }

  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
    return FALSE;

  if (!g_file_make_directory_with_parents (deploy_base, cancellable, error))
    return FALSE;

  /* From here we need to goto out on error, to clean up */
  created_deploy_base = TRUE;

  if (remote)
    {
      g_autoptr(GVariantBuilder) optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
      g_autofree char *basename = g_file_get_basename (file);

      g_variant_builder_add (optbuilder, "{s@v}",
                             "xa.title",
                             g_variant_new_variant (g_variant_new_string (basename)));

      g_variant_builder_add (optbuilder, "{s@v}",
                             "xa.noenumerate",
                             g_variant_new_variant (g_variant_new_boolean (TRUE)));

      g_variant_builder_add (optbuilder, "{s@v}",
                             "xa.prio",
                             g_variant_new_variant (g_variant_new_string ("0")));

      if (!ostree_repo_remote_add (repo,
                                   remote, origin, g_variant_builder_end (optbuilder), cancellable, error))
        goto out;

      added_remote = TRUE;

      if (gpg_data)
        {
          g_autoptr(GInputStream) gpg_data_as_stream = g_memory_input_stream_new_from_bytes (gpg_data);

          if (!ostree_repo_remote_gpg_import (repo, remote, gpg_data_as_stream,
                                              NULL, NULL, cancellable, error))
            goto out;
        }

      if (!xdg_app_dir_set_origin (dir, ref, remote, cancellable, error))
        goto out;
    }

  if (!xdg_app_dir_deploy (dir, ref, to_checksum, cancellable, error))
    goto out;

  if (!xdg_app_dir_make_current_ref (dir, ref, cancellable, error))
    goto out;

  if (strcmp (parts[0], "app") == 0)
    {
      if (!xdg_app_dir_update_exports (dir, parts[1], cancellable, error))
        goto out;
    }

  glnx_release_lock_file (&lock);

  xdg_app_dir_cleanup_removed (dir, cancellable, NULL);

  if (!xdg_app_dir_mark_changed (dir, error))
    goto out;

  ret = TRUE;

 out:
  if (created_deploy_base && !ret)
    gs_shutil_rm_rf (deploy_base, cancellable, NULL);

  if (added_remote && !ret)
    ostree_repo_remote_delete (repo, remote, NULL, NULL);

  return ret;
}
gboolean
gs_plugin_url_to_app (GsPlugin *plugin,
		      GsAppList *list,
		      const gchar *url,
		      GCancellable *cancellable,
		      GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);

	g_autofree gchar *scheme = NULL;
	g_autofree gchar *path = NULL;
	const gchar *id = NULL;
	const gchar * const *id_like = NULL;
	g_auto(GStrv) package_ids = NULL;
	g_autoptr(PkResults) results = NULL;
	g_autoptr(GsApp) app = NULL;
	g_autoptr(GsOsRelease) os_release = NULL;
	g_autoptr(GPtrArray) packages = NULL;
	g_autoptr(GPtrArray) details = NULL;
	g_autoptr(GsPackagekitHelper) helper = gs_packagekit_helper_new (plugin);

	path = gs_utils_get_url_path (url);

	/* only do this for apt:// on debian or debian-like distros */
	os_release = gs_os_release_new (error);
	if (os_release == NULL) {
		g_prefix_error (error, "failed to determine OS information:");
                return FALSE;
	} else  {
		id = gs_os_release_get_id (os_release);
		id_like = gs_os_release_get_id_like (os_release);
		scheme = gs_utils_get_url_scheme (url);
		if (!(g_strcmp0 (scheme, "apt") == 0 &&
		     (g_strcmp0 (id, "debian") == 0 ||
		      g_strv_contains (id_like, "debian")))) {
			return TRUE;
		}
	}

	app = gs_app_new (NULL);
	gs_plugin_packagekit_set_packaging_format (plugin, app);
	gs_app_add_source (app, path);
	gs_app_set_kind (app, AS_APP_KIND_GENERIC);
	gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);

	package_ids = g_new0 (gchar *, 2);
	package_ids[0] = g_strdup (path);

	g_mutex_lock (&priv->client_mutex);
	results = pk_client_resolve (priv->client,
				     pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, PK_FILTER_ENUM_ARCH, -1),
				     package_ids,
				     cancellable,
				     gs_packagekit_helper_cb, helper,
				     error);
	g_mutex_unlock (&priv->client_mutex);

	if (!gs_plugin_packagekit_results_valid (results, error)) {
		g_prefix_error (error, "failed to resolve package_ids: ");
		return FALSE;
	}

	/* get results */
	packages = pk_results_get_package_array (results);
	details = pk_results_get_details_array (results);

	if (packages->len >= 1) {
		if (gs_app_get_local_file (app) != NULL)
			return TRUE;

		gs_plugin_packagekit_resolve_packages_app (plugin, packages, app);
		gs_plugin_packagekit_refine_details_app (plugin, details, app);

		gs_app_list_add (list, app);
	} else {
		g_warning ("no results returned");
	}

	return TRUE;
}
Beispiel #16
0
static gboolean
as_app_parse_file_key (AsApp *app,
		       GKeyFile *kf,
		       const gchar *key,
		       AsAppParseFlags flags,
		       GError **error)
{
	guint i;
	guint j;
	g_autofree gchar *locale = NULL;
	g_autofree gchar *tmp = NULL;
	g_auto(GStrv) list = NULL;

	/* NoDisplay */
	if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY) == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (tmp != NULL && strcasecmp (tmp, "True") == 0)
			as_app_add_veto (app, "NoDisplay=true");

	/* Type */
	} else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_TYPE) == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (g_strcmp0 (tmp, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) {
			g_set_error_literal (error,
					     AS_APP_ERROR,
					     AS_APP_ERROR_INVALID_TYPE,
					     "not an application");
			return FALSE;
		}

	/* Icon */
	} else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ICON) == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (tmp != NULL && tmp[0] != '\0') {
			g_autoptr(AsIcon) icon = NULL;
			icon = as_app_desktop_create_icon (app, tmp, flags);
			as_app_add_icon (app, icon);
		}

	/* Categories */
	} else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_CATEGORIES) == 0) {
		list = g_key_file_get_string_list (kf,
						   G_KEY_FILE_DESKTOP_GROUP,
						   key,
						   NULL, NULL);
		for (i = 0; list[i] != NULL; i++) {
			const gchar *category_blacklist[] = {
				"X-GNOME-Settings-Panel",
				"X-Unity-Settings-Panel",
				NULL };

			/* we have to veto these */
			for (j = 0; category_blacklist[j] != NULL; j++) {
				if (g_strcmp0 (list[i], category_blacklist[j]) == 0) {
					as_app_add_veto (app, "Has category %s",
							 category_blacklist[j]);
				}
			}

			/* check the category is valid */
			if (!as_utils_is_category_id (list[i]))
				continue;

			/* ignore some useless keys */
			if (g_strcmp0 (list[i], "GTK") == 0)
				continue;
			if (g_strcmp0 (list[i], "Qt") == 0)
				continue;
			if (g_strcmp0 (list[i], "KDE") == 0)
				continue;
			if (g_strcmp0 (list[i], "GNOME") == 0)
				continue;
			as_app_add_category (app, list[i]);
		}

	} else if (g_strcmp0 (key, "Keywords") == 0) {
		list = g_key_file_get_string_list (kf,
						   G_KEY_FILE_DESKTOP_GROUP,
						   key,
						   NULL, NULL);
		for (i = 0; list[i] != NULL; i++) {
			g_auto(GStrv) kw_split = NULL;
			kw_split = g_strsplit (list[i], ",", -1);
			for (j = 0; kw_split[j] != NULL; j++) {
				if (kw_split[j][0] == '\0')
					continue;
				as_app_add_keyword (app, "C", kw_split[j]);
			}
		}

	} else if (g_str_has_prefix (key, "Keywords")) {
		locale = as_app_desktop_key_get_locale (key);
		if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS &&
		    !g_strv_contains (g_get_language_names (), locale))
			return TRUE;
		list = g_key_file_get_locale_string_list (kf,
							  G_KEY_FILE_DESKTOP_GROUP,
							  key,
							  locale,
							  NULL, NULL);
		for (i = 0; list[i] != NULL; i++) {
			g_auto(GStrv) kw_split = NULL;
			kw_split = g_strsplit (list[i], ",", -1);
			for (j = 0; kw_split[j] != NULL; j++) {
				if (kw_split[j][0] == '\0')
					continue;
				as_app_add_keyword (app, locale, kw_split[j]);
			}
		}

	} else if (g_strcmp0 (key, "MimeType") == 0) {
		list = g_key_file_get_string_list (kf,
						   G_KEY_FILE_DESKTOP_GROUP,
						   key,
						   NULL, NULL);
		for (i = 0; list[i] != NULL; i++)
			as_app_add_mimetype (app, list[i]);

	} else if (g_strcmp0 (key, "X-AppInstall-Package") == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_add_pkgname (app, tmp);

	/* OnlyShowIn */
	} else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN) == 0) {
		/* if an app has only one entry, it's that desktop */
		list = g_key_file_get_string_list (kf,
						   G_KEY_FILE_DESKTOP_GROUP,
						   key,
						   NULL, NULL);
		if (g_strv_length (list) == 1)
			as_app_set_project_group (app, list[0]);

	/* Name */
	} else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 ||
	           g_strcmp0 (key, "_Name") == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_set_name (app, "C", tmp);

	/* Name[] */
	} else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_NAME)) {
		locale = as_app_desktop_key_get_locale (key);
		if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS &&
		    !g_strv_contains (g_get_language_names (), locale))
			return TRUE;
		tmp = g_key_file_get_locale_string (kf,
						    G_KEY_FILE_DESKTOP_GROUP,
						    G_KEY_FILE_DESKTOP_KEY_NAME,
						    locale,
						    NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_set_name (app, locale, tmp);

	/* Comment */
	} else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0 ||
	           g_strcmp0 (key, "_Comment") == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_set_comment (app, "C", tmp);

	/* Comment[] */
	} else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_COMMENT)) {
		locale = as_app_desktop_key_get_locale (key);
		if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS &&
		    !g_strv_contains (g_get_language_names (), locale))
			return TRUE;
		tmp = g_key_file_get_locale_string (kf,
						    G_KEY_FILE_DESKTOP_GROUP,
						    G_KEY_FILE_DESKTOP_KEY_COMMENT,
						    locale,
						    NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_set_comment (app, locale, tmp);

	/* non-standard */
	} else if (g_strcmp0 (key, "X-Ubuntu-Software-Center-Name") == 0) {
		tmp = g_key_file_get_string (kf,
					     G_KEY_FILE_DESKTOP_GROUP,
					     key,
					     NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_set_name (app, "C", tmp);
	} else if (g_str_has_prefix (key, "X-Ubuntu-Software-Center-Name")) {
		locale = as_app_desktop_key_get_locale (key);
		if (flags & AS_APP_PARSE_FLAG_ONLY_NATIVE_LANGS &&
		    !g_strv_contains (g_get_language_names (), locale))
			return TRUE;
		tmp = g_key_file_get_locale_string (kf,
						    G_KEY_FILE_DESKTOP_GROUP,
						    "X-Ubuntu-Software-Center-Name",
						    locale,
						    NULL);
		if (tmp != NULL && tmp[0] != '\0')
			as_app_set_name (app, locale, tmp);

	/* for Ubuntu */
	} else if (g_strcmp0 (key, "X-AppStream-Ignore") == 0) {
		gboolean ret;
		ret = g_key_file_get_boolean (kf,
					      G_KEY_FILE_DESKTOP_GROUP,
					      key,
					      NULL);
		if (ret)
			as_app_add_veto (app, "X-AppStream-Ignore");
	}

	/* add any external attribute as metadata to the application */
	if (flags & AS_APP_PARSE_FLAG_ADD_ALL_METADATA)
		as_app_parse_file_metadata (app, kf, key);

	return TRUE;
}
gboolean
gs_plugin_file_to_app (GsPlugin *plugin,
		       GsAppList *list,
		       GFile *file,
		       GCancellable *cancellable,
		       GError **error)
{
	GsApp *app;
	guint i;
	g_autofree gchar *content_type = NULL;
	g_autofree gchar *output = NULL;
	g_auto(GStrv) argv = NULL;
	g_auto(GStrv) tokens = NULL;
	g_autoptr(GString) str = NULL;
	const gchar *mimetypes[] = {
		"application/vnd.debian.binary-package",
		NULL };

	/* does this match any of the mimetypes we support */
	content_type = gs_utils_get_content_type (file, cancellable, error);
	if (content_type == NULL)
		return FALSE;
	if (!g_strv_contains (mimetypes, content_type))
		return TRUE;

	/* exec sync */
	argv = g_new0 (gchar *, 5);
	argv[0] = g_strdup (DPKG_DEB_BINARY);
	argv[1] = g_strdup ("--showformat=${Package}\\n"
			    "${Version}\\n"
			    "${Installed-Size}\\n"
			    "${Homepage}\\n"
			    "${Description}");
	argv[2] = g_strdup ("-W");
	argv[3] = g_file_get_path (file);
	if (!g_spawn_sync (NULL, argv, NULL,
			   G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
			   NULL, NULL, &output, NULL, NULL, error)) {
		gs_utils_error_convert_gio (error);
		return FALSE;
	}

	/* parse output */
	tokens = g_strsplit (output, "\n", 0);
	if (g_strv_length (tokens) < 5) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_NOT_SUPPORTED,
			     "dpkg-deb output format incorrect:\n\"%s\"\n", output);
		return FALSE;
	}

	/* create app */
	app = gs_app_new (NULL);
	gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
	gs_app_add_source (app, tokens[0]);
	gs_app_set_name (app, GS_APP_QUALITY_LOWEST, tokens[0]);
	gs_app_set_version (app, tokens[1]);
	gs_app_set_size_installed (app, 1024 * g_ascii_strtoull (tokens[2], NULL, 10));
	gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, tokens[3]);
	gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, tokens[4]);
	gs_app_set_kind (app, AS_APP_KIND_GENERIC);
	gs_app_set_metadata (app, "GnomeSoftware::Creator",
			     gs_plugin_get_name (plugin));

	/* multiline text */
	str = g_string_new ("");
	for (i = 5; tokens[i] != NULL; i++) {
		if (g_strcmp0 (tokens[i], " .") == 0) {
			if (str->len > 0)
				g_string_truncate (str, str->len - 1);
			g_string_append (str, "\n");
			continue;
		}
		g_strstrip (tokens[i]);
		g_string_append_printf (str, "%s ", tokens[i]);
	}
	if (str->len > 0)
		g_string_truncate (str, str->len - 1);
	gs_app_set_description (app, GS_APP_QUALITY_LOWEST, str->str);

	/* success */
	gs_app_list_add (list, app);
	return TRUE;
}
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting);
	const char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL };
	const char *valid_duplex[] = { "half", "full", NULL };
	const char *valid_nettype[] = { "qeth", "lcs", "ctc", NULL };
	GHashTableIter iter;
	GSList* mac_blacklist_iter;
	const char *key, *value;

	if (priv->port && !g_strv_contains (valid_ports, priv->port)) {
		g_set_error (error,
		             NM_SETTING_WIRED_ERROR,
		             NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid Ethernet port value"),
		             priv->port);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_PORT);
		return FALSE;
	}

	if (priv->duplex && !g_strv_contains (valid_duplex, priv->duplex)) {
		g_set_error (error,
		             NM_SETTING_WIRED_ERROR,
		             NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid duplex value"),
		             priv->duplex);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_DUPLEX);
		return FALSE;
	}

	if (priv->device_mac_address && priv->device_mac_address->len != ETH_ALEN) {
		g_set_error_literal (error,
		                     NM_SETTING_WIRED_ERROR,
		                     NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
		                     _("is not a valid MAC address"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
		return FALSE;
	}

	for (mac_blacklist_iter = priv->mac_address_blacklist; mac_blacklist_iter;
	     mac_blacklist_iter = mac_blacklist_iter->next) {
		struct ether_addr addr;

		if (!ether_aton_r (mac_blacklist_iter->data, &addr)) {
			g_set_error (error,
			             NM_SETTING_WIRED_ERROR,
			             NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid MAC address"),
			             (const char *) mac_blacklist_iter->data);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST);
			return FALSE;
		}
	}

	if (   priv->s390_subchannels
	    && !(priv->s390_subchannels->len == 3 || priv->s390_subchannels->len == 2)) {
		g_set_error_literal (error,
		                     NM_SETTING_WIRED_ERROR,
		                     NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_SUBCHANNELS);
		return FALSE;
	}

	if (priv->s390_nettype && !g_strv_contains (valid_nettype, priv->s390_nettype)) {
		g_set_error_literal (error,
		                     NM_SETTING_WIRED_ERROR,
		                     NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_NETTYPE);
		return FALSE;
	}

	g_hash_table_iter_init (&iter, priv->s390_options);
	while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
		if (   !g_strv_contains (valid_s390_opts, key)
		    || !strlen (value)
		    || (strlen (value) > 200)) {
			g_set_error (error,
			             NM_SETTING_WIRED_ERROR,
			             NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
			             _("invalid '%s' or its value '%s'"),
			             key, value);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_OPTIONS);
			return FALSE;
		}
	}

	if (priv->cloned_mac_address && priv->cloned_mac_address->len != ETH_ALEN) {
		g_set_error_literal (error,
		                     NM_SETTING_WIRED_ERROR,
		                     NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
		                     _("is not a valid MAC address"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS);
		return FALSE;
	}

	return TRUE;
}
Beispiel #19
0
/**
 * \brief This function add the RTP element to the pipeline for service provider * \param pipeline the pipeline associated to this SP
 * \param bus the bus the channel
 * \param bus_watch_id an id watch on the bus
 * \param input last element added in pipeline to which we should link elements added
 * \param video_info a "fake" entry to VFT into which we will save all element we can retrieve from the video caps of the stream (via fill_entry() )
 * \param stream_data the data associated to this SP's pipeline
 * \param caps the caps of the input stream if this is a redirection, NULL otherwise
 * \param channel_entry_index the channel's index of this SP: to build the multicast address
 * \return the last element added in pipeline (rtp payloader if everything goes ok)
 */
static GstElement* addRTP( 	GstElement 						*pipeline, 		GstBus *bus,
							guint 							bus_watch_id, 	GstElement* input,
							struct videoFormatTable_entry 	*video_info,	gpointer stream_datas,
							GstCaps 						*caps){

	/*Create element that will be add to the pipeline */
	GstElement *rtp = NULL;
	GstElement *parser;
	GstStructure *video_caps;

	g_debug("addRTP: add RTP payloader to Service Provider's pipeline");

	if (caps == NULL){

		/* Media stream Type detection */
		video_caps = type_detection(GST_BIN(pipeline), input, NULL);
		if ( video_caps == NULL )
			return NULL;

		/* Fill the MIB a first Time */
		fill_entry(video_caps, video_info, stream_datas);

 	}else{

		GstElement *appsrc = gst_bin_get_by_name( GST_BIN ( pipeline ) , APPSRC_NAME ) ;
		g_object_set ( appsrc , "caps" ,  caps , NULL) ;
		video_caps = gst_caps_get_structure( caps, 0 );
		/* This is a redirection, fill the MIB once for all */
		fill_entry(video_caps, video_info, stream_datas);

	}

	/*
	 * Handle the ROI
	 */
	handle_roi ( pipeline ,  video_info , NULL ) ;

 	/* in case RAW video type has been detected */
	if ( gst_structure_has_name( video_caps, "video/x-raw") ){

		g_debug("%s video detected: add %s to SP pipeline", RAW_NAME , RTPRAWPAY_NAME);

		/* For Raw video */
		rtp 	= gst_element_factory_make_log ("rtpvrawpay", RTPRAWPAY_NAME);
		if ( !rtp )
			return NULL;

	}
	/* in case MPEG4 video type has been detected */
	else if  (gst_structure_has_name( video_caps, "video/mpeg")){

		/*
		 * For MPEG-a videos we need to add a parser before the RTP payloader. However, if caps are NULL i.e. if this pipeline is a Service Provider's pipeline
		 * used for a redirection, we cannot add the mpeg4 parser here because the parser need to be in the same pipeline as the MPEG-4 encoder, otherwise the typefind
		 * cannot be performed. So if caps are NULL then it means that the parser has already been added in the SU's pipeline of the Service Users's part of teh redirection.
		 * We do not have to add it again
		 */
		if ( caps == NULL ){

			parser 	= gst_element_factory_make_log ("mpeg4videoparse", MPEG4PARSER_NAME );
			if ( !parser )
				return NULL;

			g_debug("%s video detected: add %s to pipeline", MPEG4_NAME , MPEG4PARSER_NAME);

			gst_bin_add(GST_BIN(pipeline),parser);

			if ( !gst_element_link_log(input, parser))
				return NULL;

			input = parser;

		}

		g_debug("%s video detected: add %s to SP pipeline", MPEG4_NAME , RTPMP4PAY_NAME );

		rtp 	= gst_element_factory_make_log ("rtpmp4vpay", RTPMP4PAY_NAME );
		if ( !rtp )
			return NULL;

	}

	/* in case J2K video type has been detected */
	else if  ( g_strv_contains ( J2K_STR_NAMES, gst_structure_get_name(video_caps))){

		/*
		 * For J2K video our RTP payloader can only accept image/x-jpc input video media type. However, not all encoders have this caos on their src pads.
		 * So we first link the output of the encoder to a capsfilter with image/x-jpc media type. If the encoder and the capfsilter cannot negociate caps, then the encoder
		 * cannot be link to the RTP payloader, so we stop there. As an example: avenc_jpeg2000 only has image/x-j2c as a media type. But openjpegenc has image/x-j2c, image/-xjpc
		 * and image-j2p
		 */

		GstElement *capsfilter = gst_element_factory_make_log("capsfilter", CAPSFITER_J2K_NAME ) ;
		GstCaps *caps_jpeg2000 = get_rtpj2kpay_allowed_caps();

		/* Put the source in the pipeline */
		g_object_set (capsfilter, "caps",caps_jpeg2000 , NULL);

		g_debug("%s video detected: add %s to SP pipeline", J2K_NAME , CAPSFITER_J2K_NAME );

		gst_bin_add(GST_BIN(pipeline),capsfilter);

		if ( !gst_element_link_log(input,capsfilter )){
			g_critical("JPEG2000 format can only be x-jpc");
			return NULL;
		}

		input = capsfilter;

		g_debug("%s video detected: add %s to SP pipeline", J2K_NAME , RTPJ2KPAY_NAME  );

		/* For J2K video */
		rtp 	= gst_element_factory_make_log ("rtpj2kpay", RTPJ2KPAY_NAME );
		if ( !rtp )
			return NULL;
	}
 	/* in case the video type detected is unknown */
	else
	{
		g_critical("unknow type of video stream");
		return NULL;
	}

	/* add rtp to pipeline */
	gst_bin_add(GST_BIN (pipeline), rtp);

	if (caps == NULL ){

		/* Filters out non VIVOE videos, and link input to RTP if video has a valid format*/
		video_caps = type_detection(GST_BIN(pipeline), input,NULL);
		if (!filter_VIVOE(video_caps,input, rtp))
			return NULL;

		/* Now that we have added the RTP payloader to the pipeline, we can get the new caps of the video stream*/
		/* Media stream Type detection */
		video_caps = type_detection(GST_BIN(pipeline), rtp, NULL);

		if ( video_caps == NULL)
			return NULL;

		/*Fill the MIB a second time after creating payload*/
		fill_entry(video_caps, video_info, stream_datas);

	}else{

		/* link input to rtp payloader */
		if ( !gst_element_link_log(input, rtp))
		   return NULL;

		input = rtp ;

		video_caps = type_detection(GST_BIN(pipeline), input ,NULL);
		if ( !video_caps )
			return NULL;

		/*Fill the MIB a second time after creating payload, this is needed to get rtp_data needed to build SDP files */
		fill_entry(video_caps, video_info, stream_datas);

	}

	/* Finally return*/
	return rtp;
}
void
ags_select_acceleration_dialog_apply(AgsApplicable *applicable)
{
  AgsSelectAccelerationDialog *select_acceleration_dialog;
  AgsWindow *window;
  AgsAutomationEditor *automation_editor;
  AgsMachine *machine;
  AgsNotebook *notebook;

  AgsAudio *audio;

  xmlDoc *clipboard;
  xmlNode *audio_node, *automation_node;

  GList *start_list_automation, *list_automation;
  GList *port, *port_start;
  GList *list;
  
  gchar **specifier;
  xmlChar *buffer;
  gchar *str;
  
  GType channel_type;

  gdouble gui_y;
  
  gdouble c_y0, c_y1;
  gdouble val;
  gdouble upper, lower, range, step;
  gdouble c_upper, c_lower, c_range;

  int size;
  guint x0, y0;
  guint x1, y1;
  guint i;
  gint line;
  
  gboolean copy_selection;
    
  select_acceleration_dialog = AGS_SELECT_ACCELERATION_DIALOG(applicable);

  window = (AgsWindow *) select_acceleration_dialog->main_window;
  automation_editor = window->automation_window->automation_editor;

  machine = automation_editor->selected_machine;

  if(machine == NULL ||
     automation_editor->focused_automation_edit == NULL){
    return;
  }

  notebook = NULL;

  if(automation_editor->focused_automation_edit->channel_type == G_TYPE_NONE){
    notebook = NULL;
    channel_type = G_TYPE_NONE;
  }else if(automation_editor->focused_automation_edit->channel_type == AGS_TYPE_OUTPUT){
    notebook = automation_editor->output_notebook;
    channel_type = AGS_TYPE_OUTPUT;
  }else if(automation_editor->focused_automation_edit->channel_type == AGS_TYPE_INPUT){
    notebook = automation_editor->input_notebook;
    channel_type = AGS_TYPE_INPUT;
  }
  
  audio = machine->audio;

  g_object_get(audio,
	       "automation", &start_list_automation,
	       NULL);

  /* get some values */
  copy_selection = gtk_toggle_button_get_active((GtkToggleButton *) select_acceleration_dialog->copy_selection);

  x0 = (AGS_SELECT_ACCELERATION_DEFAULT_WIDTH / 16) * gtk_spin_button_get_value_as_int(select_acceleration_dialog->select_x0);

  x1 = (AGS_SELECT_ACCELERATION_DEFAULT_WIDTH / 16) * gtk_spin_button_get_value_as_int(select_acceleration_dialog->select_x1);
  
  /* select acceleration */
  port =
    port_start = gtk_container_get_children((GtkContainer *) select_acceleration_dialog->port);
  
  specifier = NULL;

  if(copy_selection){
    /* create document */
    clipboard = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
  
    /* create root node */
    audio_node = xmlNewNode(NULL, BAD_CAST "audio");
    xmlDocSetRootElement(clipboard, audio_node);
  }

  for(i = 0; port != NULL;){
    list = gtk_container_get_children((GtkContainer *) port->data);
    str = gtk_combo_box_text_get_active_text(list->data);

    g_list_free(list);
    
    if(specifier != NULL &&
       g_strv_contains(specifier,
		       str)){
      port = port->next;

      continue;
    }

    if(specifier == NULL){
      specifier = (gchar **) malloc(2 * sizeof(gchar *));
    }else{
      specifier = (gchar **) realloc(specifier,
				     (i + 2) * sizeof(gchar *));
    }
    
    specifier[i] = str;
    specifier[i + 1] = NULL;
    
    line = 0;
    
    while((line = ags_notebook_next_active_tab(notebook,
					       line)) != -1){
      list_automation = start_list_automation;

      while((list_automation = ags_automation_find_specifier_with_type_and_line(list_automation,
										specifier[i],
										channel_type,
										line)) != NULL){
	AgsAutomation *current_automation;
	AgsPort *current_port;

	AgsConversion *conversion;
	
	AgsTimestamp *timestamp;
	
	current_automation = list_automation->data;

	g_object_get(current_automation,
		     "timestamp", &timestamp,
		     NULL);

	g_object_unref(timestamp);
	
	if(ags_timestamp_get_ags_offset(timestamp) + AGS_AUTOMATION_DEFAULT_OFFSET < x0){
	  list_automation = list_automation->next;
	  
	  continue;
	}

	if(ags_timestamp_get_ags_offset(timestamp) > x1){
	  break;
	}

	g_object_get(current_automation,
		     "port", &current_port,
		     "upper", &upper,
		     "lower", &lower,
		     NULL);

	g_object_get(current_port,
		     "conversion", &conversion,
		     NULL);
	
	range = upper - lower;

	if(conversion != NULL){
	  c_upper = ags_conversion_convert(conversion,
					   upper,
					   FALSE);
	  c_lower = ags_conversion_convert(conversion,
					   lower,
					   FALSE);
	  c_range = c_upper - c_lower;

	  g_object_unref(conversion);
	}else{
	  c_upper = upper;
	  c_lower = lower;
	  
	  c_range = range;
	}

	g_object_unref(current_port);
	
	if(range == 0.0){
	  list_automation = list_automation->next;
	  g_warning("ags_select_acceleration_dialog.c - range = 0.0");
	  
	  continue;
	}
	
	/* check steps */
	g_object_get(current_automation,
		     "steps", &gui_y,
		     NULL);

	val = c_lower + (gui_y * (c_range / gui_y));
	c_y0 = val;

	/* conversion */
	if(conversion != NULL){
	  c_y0 = ags_conversion_convert(conversion,
					c_y0,
					TRUE);
	}

	/* check steps */
	gui_y = 0;

	val = c_lower + (gui_y * (c_range / gui_y));
	c_y1 = val;

	/* conversion */
	if(conversion != NULL){
	  c_y1 = ags_conversion_convert(conversion,
					c_y1,
					TRUE);
	}
	    
	/* select */
	ags_automation_add_region_to_selection(current_automation,
					       x0 * AGS_SELECT_ACCELERATION_DEFAULT_WIDTH, c_y0,
					       x1 * AGS_SELECT_ACCELERATION_DEFAULT_WIDTH, c_y1,
					       TRUE);


	if(copy_selection){
	  automation_node = ags_automation_copy_selection(list_automation->data);
	  xmlAddChild(audio_node, automation_node);      
	}

	list_automation = list_automation->next;
      }

      line++;
    }

    port = port->next;
    i++;
  }

  g_strfreev(specifier);
  
  g_list_free_full(start_list_automation,
		   g_object_unref);
  g_list_free(port_start);

  /* write to clipboard */
  if(copy_selection){
    xmlDocDumpFormatMemoryEnc(clipboard, &buffer, &size, "UTF-8", TRUE);
    gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
			   buffer, size);
    gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
    
    xmlFreeDoc(clipboard);
  }  
}
/**
 * gs_plugin_file_to_app:
 */
gboolean
gs_plugin_file_to_app (GsPlugin *plugin,
		       GList **list,
		       GFile *file,
		       GCancellable *cancellable,
		       GError **error)
{
	g_autofree gchar *content_type = NULL;
	g_autofree gchar *id_prefixed = NULL;
	g_autoptr(GBytes) appstream_gz = NULL;
	g_autoptr(GBytes) icon_data = NULL;
	g_autoptr(GBytes) metadata = NULL;
	g_autoptr(GsApp) app = NULL;
	g_autoptr(XdgAppBundleRef) xref_bundle = NULL;
	const gchar *mimetypes[] = {
		"application/vnd.xdgapp",
		NULL };

	/* does this match any of the mimetypes we support */
	content_type = gs_utils_get_content_type (file, cancellable, error);
	if (content_type == NULL)
		return FALSE;
	if (!g_strv_contains (mimetypes, content_type))
		return TRUE;

	/* load bundle */
	xref_bundle = xdg_app_bundle_ref_new (file, error);
	if (xref_bundle == NULL) {
		g_prefix_error (error, "error loading bundle: ");
		return FALSE;
	}

	/* create a virtual ID */
	id_prefixed = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref_bundle));

	/* load metadata */
	app = gs_app_new (id_prefixed);
	gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
	gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
	gs_app_set_size_installed (app, xdg_app_bundle_ref_get_installed_size (xref_bundle));
	gs_plugin_xdg_app_set_metadata (app, XDG_APP_REF (xref_bundle));
	metadata = xdg_app_bundle_ref_get_metadata (xref_bundle);
	if (!gs_plugin_xdg_app_set_app_metadata (app,
						 g_bytes_get_data (metadata, NULL),
						 g_bytes_get_size (metadata),
						 error))
		return FALSE;

	/* load AppStream */
	appstream_gz = xdg_app_bundle_ref_get_appstream (xref_bundle);
	if (appstream_gz != NULL) {
		g_autoptr(GZlibDecompressor) decompressor = NULL;
		g_autoptr(GInputStream) stream_gz = NULL;
		g_autoptr(GInputStream) stream_data = NULL;
		g_autoptr(GBytes) appstream = NULL;
		g_autoptr(AsStore) store = NULL;
		g_autofree gchar *id = NULL;
		AsApp *item;

		/* decompress data */
		decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
		stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz);
		if (stream_gz == NULL)
			return FALSE;
		stream_data = g_converter_input_stream_new (stream_gz,
							    G_CONVERTER (decompressor));

		appstream = g_input_stream_read_bytes (stream_data,
						       0x100000, /* 1Mb */
						       cancellable,
						       error);
		if (appstream == NULL)
			return FALSE;
		store = as_store_new ();
		if (!as_store_from_bytes (store, appstream, cancellable, error))
			return FALSE;

		/* find app */
		id = g_strdup_printf ("%s.desktop", gs_app_get_xdgapp_name (app));
		item = as_store_get_app_by_id (store, id);
		if (item == NULL) {
			g_set_error (error,
				     GS_PLUGIN_ERROR,
				     GS_PLUGIN_ERROR_FAILED,
				     "application %s not found",
				     id);
			return FALSE;
		}

		/* copy details from AppStream to app */
		if (!gs_appstream_refine_app (plugin, app, item, error))
			return FALSE;
	}

	/* load icon */
	icon_data = xdg_app_bundle_ref_get_icon (xref_bundle,
						 64 * gs_plugin_get_scale (plugin));
	if (icon_data == NULL)
		icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64);
	if (icon_data != NULL) {
		g_autoptr(GInputStream) stream_icon = NULL;
		g_autoptr(GdkPixbuf) pixbuf = NULL;
		stream_icon = g_memory_input_stream_new_from_bytes (icon_data);
		pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error);
		if (pixbuf == NULL)
			return FALSE;
		gs_app_set_pixbuf (app, pixbuf);
	} else {
		g_autoptr(AsIcon) icon = NULL;
		icon = as_icon_new ();
		as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
		as_icon_set_name (icon, "application-x-executable");
		gs_app_set_icon (app, icon);
	}

	/* not quite true: this just means we can update this specific app */
	if (xdg_app_bundle_ref_get_origin (xref_bundle))
		gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE);

	g_debug ("created local app: %s", gs_app_to_string (app));
	gs_app_list_add (list, app);
	return TRUE;
}
static gboolean
check_choice (GVariant *choice,
              GError **error)
{
  const char *id;
  const char *label;
  g_autoptr(GVariant) options = NULL;
  const char *option;
  int i;
  gboolean seen_option;

  g_variant_get (choice, "(&s&s@a(ss)&s)", &id, &label, &options, &option);

  if (id[0] == 0)
    {
      g_set_error_literal (error,
                           XDG_DESKTOP_PORTAL_ERROR,
                           XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
                           "id is empty");
      return FALSE;
    }

  if (label[0] == 0)
    {
      g_set_error_literal (error,
                           XDG_DESKTOP_PORTAL_ERROR,
                           XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
                           "label is empty");
      return FALSE;
    }

  if (g_variant_n_children (options) == 0)
    {
      const char *values[] = { "", "true", "false", NULL };
      if (!g_strv_contains (values, option))
        {
          g_set_error (error,
                       XDG_DESKTOP_PORTAL_ERROR,
                       XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
                       "bad current option: %s", option);
          return FALSE;
        }

      return TRUE;
    }

  seen_option = FALSE;
  for (i = 0; i < g_variant_n_children (options); i++)
    {
      const char *o_id;
      const char *o_label;

      g_variant_get_child (options, i, "(&s&s)", &o_id, &o_label);

      if (o_id[0] == 0)
        {
          g_set_error_literal (error,
                               XDG_DESKTOP_PORTAL_ERROR,
                               XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
                               "option id is empty");
          return FALSE;
        }
      if (o_label[0] == 0)
        {
          g_set_error_literal (error,
                               XDG_DESKTOP_PORTAL_ERROR,
                               XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
                               "option label is empty");
          return FALSE;
        }

      if (strcmp (o_id, option) == 0)
        seen_option = TRUE;
    }

  if (!seen_option && option[0] != 0)
    {
      g_set_error (error,
                   XDG_DESKTOP_PORTAL_ERROR,
                   XDG_DESKTOP_PORTAL_ERROR_INVALID_ARGUMENT,
                   "bad current option: %s", option);
      return FALSE;
    }

  return TRUE;
}
gboolean
flatpak_builtin_ls_remote (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  g_autoptr(GHashTable) refs = NULL;
  GHashTableIter iter;
  gpointer key;
  gpointer value;
  g_autoptr(GHashTable) names = NULL;
  guint n_keys;
  g_autofree const char **keys = NULL;
  int i;
  const char *repository;
  const char **arches = flatpak_get_arches ();
  const char *opt_arches[] = {NULL, NULL};

  context = g_option_context_new (_(" REMOTE - Show available runtimes and applications"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error))
    return FALSE;

  if (!opt_app && !opt_runtime)
    opt_app = opt_runtime = TRUE;

  if (argc < 2)
    return usage_error (context, _("REMOTE must be specified"), error);

  if (argc > 2)
    return usage_error (context, _("Too many arguments"), error);

  repository = argv[1];


  if (!flatpak_dir_list_remote_refs (dir,
                                     repository,
                                     &refs,
                                     cancellable, error))
    return FALSE;

  names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  if (opt_arch != NULL)
    {
      if (strcmp (opt_arch, "*") == 0)
        arches = NULL;
      else
        {
          opt_arches[0] = opt_arch;
          arches = opt_arches;
        }
    }

  g_hash_table_iter_init (&iter, refs);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      const char *ref = key;
      const char *checksum = value;
      const char *name = NULL;
      g_auto(GStrv) parts = NULL;

      parts = flatpak_decompose_ref (ref, NULL);
      if (parts == NULL)
        {
          g_debug ("Invalid remote ref %s\n", ref);
          continue;
        }

      if (opt_only_updates)
        {
          g_autofree char *deployed = NULL;

          deployed = flatpak_dir_read_active (dir, ref, cancellable);
          if (deployed == NULL)
            continue;

          if (g_strcmp0 (deployed, checksum) == 0)
            continue;
        }

      if (arches != NULL && !g_strv_contains (arches, parts[2]))
        continue;

      if (strcmp (parts[0], "runtime") == 0 && !opt_runtime)
        continue;

      if (strcmp (parts[0], "app") == 0 && !opt_app)
        continue;

      if (!opt_show_details)
        name = parts[1];
      else
        name = ref;

      if (g_hash_table_lookup (names, name) == NULL)
        g_hash_table_insert (names, g_strdup (name), g_strdup (checksum));
    }

  keys = (const char **) g_hash_table_get_keys_as_array (names, &n_keys);
  g_qsort_with_data (keys, n_keys, sizeof (char *), (GCompareDataFunc) flatpak_strcmp0_ptr, NULL);

  FlatpakTablePrinter *printer = flatpak_table_printer_new ();

  for (i = 0; i < n_keys; i++)
    {
      flatpak_table_printer_add_column (printer, keys[i]);
      if (opt_show_details)
        {
          g_autofree char *value = NULL;

          value = g_strdup ((char *) g_hash_table_lookup (names, keys[i]));
          value[MIN (strlen (value), 12)] = 0;
          flatpak_table_printer_add_column (printer, value);
        }
      flatpak_table_printer_finish_row (printer);
    }

  flatpak_table_printer_print (printer);
  flatpak_table_printer_free (printer);

  return TRUE;
}
/**
 * ags_automation_toolbar_load_port:
 * @automation_toolbar: an #AgsAutomationToolbar
 * @control_name: the specifier as string
 *
 * Applies all port to appropriate #AgsMachine.
 *
 * Since: 0.4.3
 */
void
ags_automation_toolbar_apply_port(AgsAutomationToolbar *automation_toolbar,
				  gchar *control_name)
{
  AgsAutomationEditor *automation_editor;
  AgsMachine *machine;

  GtkTreeModel *model;
  GtkTreeIter iter;

  gchar **specifier, *current;
  guint length;
  gboolean is_active;
  
  automation_editor = gtk_widget_get_ancestor(automation_toolbar,
					      AGS_TYPE_AUTOMATION_EDITOR);
  machine = automation_editor->selected_machine;

  model = gtk_combo_box_get_model(automation_toolbar->port);

  /* create specifier array */
  specifier = NULL;
  length = 0;
  
  if(gtk_tree_model_get_iter_first(model,
				   &iter)){
    do{
      gtk_tree_model_get(model,
			 &iter,
			 0, &is_active,
			 -1);

      if(is_active){
	if(length == 0){
	  specifier = (gchar **) malloc(2 * sizeof(gchar *));
	}else{
	  specifier = (gchar **) realloc(specifier,
					 (length + 2) * sizeof(gchar *));
	}
      
	gtk_tree_model_get(model,
			   &iter,
			   1, &current,
			   -1);
	specifier[length] = current;

	length++;
      }
    }while(gtk_tree_model_iter_next(model,
				    &iter));
    specifier[length] = NULL;
  }

  if(machine->automation_port != NULL){
    free(machine->automation_port);
  }

  /* apply */
  machine->automation_port = specifier;
  
  if(g_strv_contains(specifier,
		     control_name)){
    AgsScaleArea *scale_area;
    AgsAutomationArea *automation_area;

    AgsAudio *audio;
    AgsAutomation *automation;

    GList *list;

    gboolean found_audio, found_output, found_input;
    
    audio = machine->audio;
    list = audio->automation;
    
    /* add port */
    found_audio = FALSE;
    found_output = FALSE;
    found_input = FALSE;
    
    while((list = ags_automation_find_specifier(list,
						control_name)) != NULL &&
	  (!found_audio || !found_output || !found_input)){
      if(AGS_AUTOMATION(list->data)->channel_type == G_TYPE_NONE &&
	 !found_audio){
	scale_area = ags_scale_area_new(automation_editor->audio_scale,
					control_name,
					AGS_AUTOMATION(list->data)->lower,
					AGS_AUTOMATION(list->data)->upper,
					AGS_AUTOMATION(list->data)->steps);
	ags_scale_add_area(automation_editor->audio_scale,
			   scale_area);
	gtk_widget_queue_draw(automation_editor->audio_scale);
	
	automation_area = ags_automation_area_new(automation_editor->audio_automation_edit->drawing_area,
						  audio,
						  G_TYPE_NONE,
						  control_name);
	ags_automation_edit_add_area(automation_editor->audio_automation_edit,
				     automation_area);
	gtk_widget_queue_draw(automation_editor->audio_automation_edit->drawing_area);

	found_audio = TRUE;
      }

      if(AGS_AUTOMATION(list->data)->channel_type == AGS_TYPE_OUTPUT &&
	 !found_output){
	scale_area = ags_scale_area_new(automation_editor->output_scale,
					control_name,
					AGS_AUTOMATION(list->data)->lower,
					AGS_AUTOMATION(list->data)->upper,
					AGS_AUTOMATION(list->data)->steps);
	ags_scale_add_area(automation_editor->output_scale,
			   scale_area);
	gtk_widget_queue_draw(automation_editor->output_scale);
	
	automation_area = ags_automation_area_new(automation_editor->output_automation_edit->drawing_area,
						  audio,
						  AGS_TYPE_OUTPUT,
						  control_name);
	ags_automation_edit_add_area(automation_editor->output_automation_edit,
				     automation_area);
	gtk_widget_queue_draw(automation_editor->output_automation_edit->drawing_area);
	
	found_output = TRUE;
      }

      if(AGS_AUTOMATION(list->data)->channel_type == AGS_TYPE_INPUT &&
	 !found_input){
	scale_area = ags_scale_area_new(automation_editor->input_scale,
					control_name,
					AGS_AUTOMATION(list->data)->lower,
					AGS_AUTOMATION(list->data)->upper,
					AGS_AUTOMATION(list->data)->steps);
	ags_scale_add_area(automation_editor->input_scale,
			   scale_area);
	gtk_widget_queue_draw(automation_editor->input_scale);
	
	automation_area = ags_automation_area_new(automation_editor->input_automation_edit->drawing_area,
						  audio,
						  AGS_TYPE_INPUT,
						  control_name);
	ags_automation_edit_add_area(automation_editor->input_automation_edit,
				     automation_area);
	gtk_widget_queue_draw(automation_editor->input_automation_edit->drawing_area);
	
	found_input = TRUE;
      }
      
      list = list->next;
    }
  }else{
    AgsAutomationEdit *automation_edit;
    AgsScale *scale;
    
    GList *scale_area;
    GList *automation_area;

    /* remove audio port */
    automation_edit = automation_editor->audio_automation_edit;
    scale = automation_editor->audio_scale;

    scale_area = ags_scale_area_find_specifier(scale->scale_area,
					       control_name);
    
    if(scale_area != NULL){
      automation_area = ags_automation_area_find_specifier(automation_edit->automation_area,
							   control_name);

      ags_scale_remove_area(scale,
			    scale_area->data);
      gtk_widget_queue_draw(scale);

      ags_automation_edit_remove_area(automation_edit,
				      automation_area->data);
      gtk_widget_queue_draw(automation_edit->drawing_area);
    }
    
    /* remove output port */
    automation_edit = automation_editor->output_automation_edit;
    scale = automation_editor->output_scale;
    
    scale_area = ags_scale_area_find_specifier(scale->scale_area,
					       control_name);

    if(scale_area != NULL){
      automation_area = ags_automation_area_find_specifier(automation_edit->automation_area,
							   control_name);

      ags_scale_remove_area(scale,
			    scale_area->data);
      gtk_widget_queue_draw(scale);

      ags_automation_edit_remove_area(automation_edit,
				      automation_area->data);
      gtk_widget_queue_draw(automation_edit->drawing_area);
    }

    /* remove input port */
    automation_edit = automation_editor->input_automation_edit;
    scale = automation_editor->input_scale;
    
    scale_area = ags_scale_area_find_specifier(scale->scale_area,
					       control_name);

    if(scale_area != NULL){
      automation_area = ags_automation_area_find_specifier(automation_edit->automation_area,
							   control_name);

      ags_scale_remove_area(scale,
			    scale_area->data);
      gtk_widget_queue_draw(scale);

      ags_automation_edit_remove_area(automation_edit,
				      automation_area->data);
      gtk_widget_queue_draw(automation_edit->drawing_area);
    }
  }
}