567 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			567 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* LIBPIKA - The PIKA Library
 | 
						|
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
 | 
						|
 *
 | 
						|
 * This library 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 3 of the License, 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
 | 
						|
 * Library 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, see
 | 
						|
 * <https://www.gnu.org/licenses/>.
 | 
						|
 */
 | 
						|
 | 
						|
#include "config.h"
 | 
						|
 | 
						|
#include "pika.h"
 | 
						|
 | 
						|
/* Data bounced back and forth to/from core and libpika,
 | 
						|
 * and here from the temp PDB procedure to the idle func.
 | 
						|
 * But it is opaque to core, passed and returned unaltered.
 | 
						|
 *
 | 
						|
 * Not all fields are meaningful in each direction or transfer.
 | 
						|
 * !!! We don't pass resource to core in this struct,
 | 
						|
 * only from the temp callback to the idle func.
 | 
						|
 *
 | 
						|
 * Lifetime is as long as the remote dialog is open.
 | 
						|
 * Closing the chooser dialog frees the adaption struct.
 | 
						|
 */
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
  /* This portion is passed to and from idle. */
 | 
						|
  guint                idle_id;
 | 
						|
  gint                 resource_id;
 | 
						|
  GType                resource_type;
 | 
						|
  gboolean             closing;
 | 
						|
 | 
						|
  /* This portion is passed to and from core, and to idle. */
 | 
						|
  gchar                       *temp_PDB_callback_name;
 | 
						|
  PikaResourceChoosedCallback  callback;
 | 
						|
  gpointer                     owner_data;
 | 
						|
  GDestroyNotify               data_destroy;
 | 
						|
} PikaResourceAdaption;
 | 
						|
 | 
						|
 | 
						|
/*  local */
 | 
						|
 | 
						|
static void             pika_resource_data_free (PikaResourceAdaption *adaption);
 | 
						|
 | 
						|
static PikaValueArray * pika_temp_resource_run  (PikaProcedure        *procedure,
 | 
						|
                                                 const PikaValueArray *args,
 | 
						|
                                                 gpointer              run_data);
 | 
						|
static gboolean         pika_temp_resource_idle (PikaResourceAdaption *adaption);
 | 
						|
 | 
						|
 | 
						|
/*  public */
 | 
						|
 | 
						|
/* Annotation, which appears in the libpika API doc.
 | 
						|
 * Not a class, only functions.
 | 
						|
 * The functions appear as class methods of PikaResource class.
 | 
						|
 * Formerly, API had separate functions for each resource subclass.
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * SECTION: pikaresourceselect
 | 
						|
 * @title: PikaResourceSelect
 | 
						|
 * @short_description: A resource selection dialog.
 | 
						|
 *
 | 
						|
 * A resource selection dialog.
 | 
						|
 *
 | 
						|
 * An adapter and proxy between libpika and core.
 | 
						|
 * (see Adapter and Proxy patterns in programming literature.)
 | 
						|
 *
 | 
						|
 * Proxy: to a remote dialog in core.
 | 
						|
 * Is a dialog, but the dialog is remote (another process.)
 | 
						|
 * Remote dialog is a chooser dialog of subclass of PikaResource,
 | 
						|
 * e.g. PikaBrush, PikaFont, etc.
 | 
						|
 *
 | 
						|
 * Adapter: gets a callback via PDB procedure from remote dialog
 | 
						|
 * and shuffles parameters to call a owner's callback on libpika side.
 | 
						|
 *
 | 
						|
 * Generic on type of PikaResource subclass.
 | 
						|
 * That is, the type of PikaResource subclass is passed.
 | 
						|
 *
 | 
						|
 * Responsibilities:
 | 
						|
 *
 | 
						|
 *    - implement a proxy  to a chooser widget in core
 | 
						|
 *
 | 
						|
 * Collaborations:
 | 
						|
 *
 | 
						|
 *     - called by PikaResourceSelectButton to popup as a sibling widget
 | 
						|
 *     - PDB procedures to/from core, which implements the remote dialog
 | 
						|
 *       (from via PDB temp callback, to via PDB procs such as pika_fonts_popup)
 | 
						|
 *     - plugins implementing their own GUI
 | 
						|
 **/
 | 
						|
 | 
						|
/* This was extracted from pikabrushselect.c, pikafontselect.c, etc.
 | 
						|
 * and those were deleted.
 | 
						|
 */
 | 
						|
 | 
						|
/* Functions that dispatch on resource type.
 | 
						|
 *
 | 
						|
 * For now, the design is that core callbacks pass
 | 
						|
 * attributes of the resource (not just the resource.)
 | 
						|
 * FUTURE: core will use the same signature for all remote dialogs,
 | 
						|
 * regardless of resource type.
 | 
						|
 * Then all this dispatching code can be deleted.
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
/* Create args for temp PDB callback.
 | 
						|
 * Must match signature that core hardcodes in a subclass of pika_pdb_dialog.
 | 
						|
 *
 | 
						|
 * For example, see app/widgets/paletteselect.c
 | 
						|
 *
 | 
						|
 * When testing, the error "Unable to run callback... temp_proc... wrong type"
 | 
						|
 * means a signature mismatch.
 | 
						|
 *
 | 
						|
 * Note the signature from core might be from an old design where
 | 
						|
 * the core sent all data needed to draw the resource.
 | 
						|
 * In the new design, libpika gets the attributes of the resource
 | 
						|
 * from core in a separate PDB proc call back to core.
 | 
						|
 * While core uses the old design and libpika uses the new design,
 | 
						|
 * libpika simply ignores the extra args (adapts the signature.)
 | 
						|
 */
 | 
						|
static void
 | 
						|
create_callback_PDB_procedure_params (PikaProcedure *procedure,
 | 
						|
                                      GType          resource_type)
 | 
						|
{
 | 
						|
  PIKA_PROC_ARG_STRING (procedure, "resource-name",
 | 
						|
                        "Resource name",
 | 
						|
                        "The resource name",
 | 
						|
                        NULL,
 | 
						|
                        G_PARAM_READWRITE);
 | 
						|
 | 
						|
  /* Create args for the extra, superfluous args that core is passing.*/
 | 
						|
  if (g_type_is_a (resource_type, PIKA_TYPE_FONT))
 | 
						|
    {
 | 
						|
      /* No other args. */
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_GRADIENT))
 | 
						|
    {
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "gradient-width",
 | 
						|
                         "Gradient width",
 | 
						|
                         "The gradient width",
 | 
						|
                         0, G_MAXINT, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_FLOAT_ARRAY (procedure, "gradient-data",
 | 
						|
                                 "Gradient data",
 | 
						|
                                 "The gradient data",
 | 
						|
                                 G_PARAM_READWRITE);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_BRUSH))
 | 
						|
    {
 | 
						|
      PIKA_PROC_ARG_DOUBLE (procedure, "opacity",
 | 
						|
                            "Opacity",
 | 
						|
                            NULL,
 | 
						|
                            0.0, 100.0, 100.0,
 | 
						|
                            G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "spacing",
 | 
						|
                         "Spacing",
 | 
						|
                         NULL,
 | 
						|
                         -1, 1000, 20,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_ENUM (procedure, "paint-mode",
 | 
						|
                          "Paint mode",
 | 
						|
                          NULL,
 | 
						|
                          PIKA_TYPE_LAYER_MODE,
 | 
						|
                          PIKA_LAYER_MODE_NORMAL,
 | 
						|
                          G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "mask-width",
 | 
						|
                         "Brush width",
 | 
						|
                         NULL,
 | 
						|
                         0, 10000, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "mask-height",
 | 
						|
                         "Brush height",
 | 
						|
                         NULL,
 | 
						|
                         0, 10000, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_BYTES (procedure, "mask-data",
 | 
						|
                           "Mask data",
 | 
						|
                           "The brush mask data",
 | 
						|
                           G_PARAM_READWRITE);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PALETTE))
 | 
						|
    {
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "num-colors",
 | 
						|
                         "Num colors",
 | 
						|
                         "Number of colors",
 | 
						|
                         0, G_MAXINT, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PATTERN))
 | 
						|
    {
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "mask-width",
 | 
						|
                         "Mask width",
 | 
						|
                         "Pattern width",
 | 
						|
                         0, 10000, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "mask-height",
 | 
						|
                         "Mask height",
 | 
						|
                         "Pattern height",
 | 
						|
                         0, 10000, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_INT (procedure, "mask-bpp",
 | 
						|
                         "Mask bpp",
 | 
						|
                         "Pattern bytes per pixel",
 | 
						|
                         0, 10000, 0,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
 | 
						|
      PIKA_PROC_ARG_BYTES (procedure, "mask-data",
 | 
						|
                           "Mask data",
 | 
						|
                           "The pattern mask data",
 | 
						|
                           G_PARAM_READWRITE);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_warning ("%s: unhandled resource type", G_STRFUNC);
 | 
						|
    }
 | 
						|
 | 
						|
  PIKA_PROC_ARG_BOOLEAN (procedure, "closing",
 | 
						|
                         "Closing",
 | 
						|
                         "If the dialog was closing",
 | 
						|
                         FALSE,
 | 
						|
                         G_PARAM_READWRITE);
 | 
						|
}
 | 
						|
 | 
						|
/* Open (create) a remote chooser dialog of resource.
 | 
						|
 *
 | 
						|
 * Dispatch on subclass of PikaResource.
 | 
						|
 * Call a PDB procedure that communicates with core to create remote dialog.
 | 
						|
 */
 | 
						|
static gboolean
 | 
						|
popup_remote_chooser (const gchar   *title,
 | 
						|
                      PikaResource  *resource,
 | 
						|
                      gchar         *temp_PDB_callback_name,
 | 
						|
                      GType          resource_type)
 | 
						|
{
 | 
						|
  gboolean result = FALSE;
 | 
						|
  gchar   *resource_name;
 | 
						|
 | 
						|
  /* The PDB procedure still takes a name  */
 | 
						|
  resource_name = pika_resource_get_name (resource);
 | 
						|
 | 
						|
  if (g_type_is_a (resource_type, PIKA_TYPE_BRUSH))
 | 
						|
    {
 | 
						|
      result = pika_brushes_popup (temp_PDB_callback_name, title, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_FONT))
 | 
						|
    {
 | 
						|
      result = pika_fonts_popup (temp_PDB_callback_name, title, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_GRADIENT))
 | 
						|
    {
 | 
						|
      result = pika_gradients_popup (temp_PDB_callback_name, title, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PALETTE))
 | 
						|
    {
 | 
						|
      result = pika_palettes_popup (temp_PDB_callback_name, title, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PATTERN))
 | 
						|
    {
 | 
						|
      result = pika_patterns_popup (temp_PDB_callback_name, title, resource_name);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_warning ("%s: unhandled resource type", G_STRFUNC);
 | 
						|
    }
 | 
						|
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
/*Does nothing, quietly, when the remote dialog is not open. */
 | 
						|
static void
 | 
						|
close_remote_chooser (gchar *temp_PDB_callback_name,
 | 
						|
                      GType  resource_type)
 | 
						|
{
 | 
						|
  if (g_type_is_a (resource_type, PIKA_TYPE_FONT))
 | 
						|
    {
 | 
						|
      pika_fonts_close_popup (temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_GRADIENT))
 | 
						|
    {
 | 
						|
      pika_gradients_close_popup (temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_BRUSH))
 | 
						|
    {
 | 
						|
      pika_brushes_close_popup (temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PALETTE))
 | 
						|
    {
 | 
						|
      pika_palettes_close_popup (temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PATTERN))
 | 
						|
    {
 | 
						|
      pika_patterns_close_popup (temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_warning ("%s: unhandled resource type", G_STRFUNC);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* Get the index of the is_closing arg in a PikaValueArray of the tempPDBproc.
 | 
						|
 * Count the extra args above, and add that to 1.
 | 
						|
 */
 | 
						|
static gint
 | 
						|
index_of_is_closing_arg (GType  resource_type)
 | 
						|
{
 | 
						|
  if (g_type_is_a (resource_type, PIKA_TYPE_FONT))
 | 
						|
    {
 | 
						|
      return 1;
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_GRADIENT))
 | 
						|
    {
 | 
						|
      return 3;
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_BRUSH))
 | 
						|
    {
 | 
						|
      return 7;
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PALETTE))
 | 
						|
    {
 | 
						|
      return 2;
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PATTERN))
 | 
						|
    {
 | 
						|
      return 5;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_warning ("%s: unhandled resource type", G_STRFUNC);
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * pika_resource_select_new:
 | 
						|
 * @title:      Title of the resource selection dialog.
 | 
						|
 * @resource:   The resource to set as the initial choice.
 | 
						|
 * @resource_type: The type of the subclass of resource.
 | 
						|
 * @callback: (scope notified): The callback function to call when a user chooses a resource.
 | 
						|
 * @owner_data: (closure callback): The run_data given to @callback.
 | 
						|
 * @data_destroy: (destroy owner_data): The destroy function for @owner_data.
 | 
						|
 *
 | 
						|
 * Invoke a resource chooser dialog which may call @callback with the chosen
 | 
						|
 * resource and owner's @data.
 | 
						|
 *
 | 
						|
 * A proxy to a remote dialog in core, which knows the model i.e. installed resources.
 | 
						|
 *
 | 
						|
 * Generic on type of #PikaResource subclass passed in @resource_type.
 | 
						|
 *
 | 
						|
 * Returns: (transfer none): the name of a temporary PDB procedure. The
 | 
						|
 *          string belongs to the resource selection dialog and will be
 | 
						|
 *          freed automatically when the dialog is closed.
 | 
						|
 **/
 | 
						|
const gchar *
 | 
						|
pika_resource_select_new (const gchar                 *title,
 | 
						|
                          PikaResource                *resource,
 | 
						|
                          GType                        resource_type,
 | 
						|
                          PikaResourceChoosedCallback  callback,
 | 
						|
                          gpointer                     owner_data,
 | 
						|
                          GDestroyNotify               data_destroy)
 | 
						|
{
 | 
						|
  PikaPlugIn    *plug_in = pika_get_plug_in ();
 | 
						|
  PikaProcedure *procedure;
 | 
						|
  gchar         *temp_PDB_callback_name;
 | 
						|
  PikaResourceAdaption  *adaption;
 | 
						|
 | 
						|
  g_debug ("%s", G_STRFUNC);
 | 
						|
 | 
						|
  g_return_val_if_fail (resource != NULL, NULL);
 | 
						|
  g_return_val_if_fail (callback != NULL, NULL);
 | 
						|
  g_return_val_if_fail (resource_type != 0, NULL);
 | 
						|
 | 
						|
  temp_PDB_callback_name = pika_pdb_temp_procedure_name (pika_get_pdb ());
 | 
						|
 | 
						|
  adaption = g_slice_new0 (PikaResourceAdaption);
 | 
						|
 | 
						|
  adaption->temp_PDB_callback_name  = temp_PDB_callback_name;
 | 
						|
  adaption->callback                = callback;
 | 
						|
  adaption->owner_data              = owner_data;
 | 
						|
  adaption->data_destroy            = data_destroy;
 | 
						|
  adaption->resource_type           = resource_type;
 | 
						|
 | 
						|
  /* !!! Only part of the adaption has been initialized. */
 | 
						|
 | 
						|
  procedure = pika_procedure_new (plug_in,
 | 
						|
                                  temp_PDB_callback_name,
 | 
						|
                                  PIKA_PDB_PROC_TYPE_TEMPORARY,
 | 
						|
                                  pika_temp_resource_run,
 | 
						|
                                  adaption,
 | 
						|
                                  (GDestroyNotify) pika_resource_data_free);
 | 
						|
 | 
						|
  create_callback_PDB_procedure_params (procedure, resource_type);
 | 
						|
 | 
						|
  pika_plug_in_add_temp_procedure (plug_in, procedure);
 | 
						|
  g_object_unref (procedure);
 | 
						|
 | 
						|
  if (popup_remote_chooser (title, resource, temp_PDB_callback_name,
 | 
						|
                            resource_type))
 | 
						|
    {
 | 
						|
      /* Allow callbacks to be watched */
 | 
						|
      pika_plug_in_extension_enable (plug_in);
 | 
						|
 | 
						|
      return temp_PDB_callback_name;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_warning ("Failed to open remote resource select dialog.");
 | 
						|
      pika_plug_in_remove_temp_procedure (plug_in, temp_PDB_callback_name);
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
pika_resource_select_destroy (const gchar *temp_PDB_callback_name)
 | 
						|
{
 | 
						|
  PikaPlugIn *plug_in = pika_get_plug_in ();
 | 
						|
 | 
						|
  g_return_if_fail (temp_PDB_callback_name != NULL);
 | 
						|
 | 
						|
  pika_plug_in_remove_temp_procedure (plug_in, temp_PDB_callback_name);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Set currently selected resource in remote chooser.
 | 
						|
 *
 | 
						|
 * Calls a PDB procedure.
 | 
						|
 *
 | 
						|
 * Note core is still using string name of resource,
 | 
						|
 * so pdb/groups/<foo>_select.pdb, <foo>_set_popup must have type string.
 | 
						|
 */
 | 
						|
void
 | 
						|
pika_resource_select_set (const gchar  *temp_pdb_callback,
 | 
						|
                          PikaResource *resource,
 | 
						|
                          GType         resource_type)
 | 
						|
{
 | 
						|
  gchar *resource_name;
 | 
						|
 | 
						|
  /* The remote setter is e.g. pika_fonts_set_popup, a PDB procedure.
 | 
						|
   * It still takes a name aka ID instead of a resource object.
 | 
						|
   */
 | 
						|
  resource_name = pika_resource_get_name (resource);
 | 
						|
 | 
						|
  if (g_type_is_a (resource_type, PIKA_TYPE_FONT))
 | 
						|
    {
 | 
						|
      pika_fonts_set_popup (temp_pdb_callback, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_GRADIENT))
 | 
						|
    {
 | 
						|
      pika_gradients_set_popup (temp_pdb_callback, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_BRUSH))
 | 
						|
    {
 | 
						|
      pika_brushes_set_popup (temp_pdb_callback, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PALETTE))
 | 
						|
    {
 | 
						|
      pika_palettes_set_popup (temp_pdb_callback, resource_name);
 | 
						|
    }
 | 
						|
  else if (g_type_is_a (resource_type, PIKA_TYPE_PATTERN))
 | 
						|
    {
 | 
						|
      pika_patterns_set_popup (temp_pdb_callback, resource_name);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_warning ("%s: unhandled resource type", G_STRFUNC);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*  private functions  */
 | 
						|
 | 
						|
/* Free a PikaResourceAdaption struct.
 | 
						|
 * A PikaResourceAdaption and this func are passed to a PikaProcedure
 | 
						|
 * and this func is called back when the procedure is removed.
 | 
						|
 *
 | 
						|
 * This can be called for the exception: failed to open remote dialog.
 | 
						|
 *
 | 
						|
 * Each allocated field must be safely freed (not assuming it is valid pointer.)
 | 
						|
 */
 | 
						|
static void
 | 
						|
pika_resource_data_free (PikaResourceAdaption *adaption)
 | 
						|
{
 | 
						|
  if (adaption->idle_id)
 | 
						|
    g_source_remove (adaption->idle_id);
 | 
						|
 | 
						|
  if (adaption->temp_PDB_callback_name)
 | 
						|
    {
 | 
						|
      close_remote_chooser (adaption->temp_PDB_callback_name,
 | 
						|
                            adaption->resource_type);
 | 
						|
      g_free (adaption->temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
 | 
						|
  if (adaption->data_destroy)
 | 
						|
    adaption->data_destroy (adaption->owner_data);
 | 
						|
 | 
						|
  g_slice_free (PikaResourceAdaption, adaption);
 | 
						|
}
 | 
						|
 | 
						|
/* Run func for the temporary PDB procedure.
 | 
						|
 * Called when user chooses a resource in remote dialog.
 | 
						|
 */
 | 
						|
static PikaValueArray *
 | 
						|
pika_temp_resource_run (PikaProcedure        *procedure,
 | 
						|
                        const PikaValueArray *args,
 | 
						|
                        gpointer              run_data)
 | 
						|
{
 | 
						|
  PikaResourceAdaption *adaption = run_data;
 | 
						|
  const gchar          *resource_name;
 | 
						|
  PikaResource         *resource;
 | 
						|
 | 
						|
  resource_name = PIKA_VALUES_GET_STRING (args, 0);
 | 
						|
 | 
						|
  resource = pika_resource_get_by_name (adaption->resource_type,
 | 
						|
                                        resource_name);
 | 
						|
 | 
						|
  adaption->resource_id = pika_resource_get_id (resource);
 | 
						|
 | 
						|
  adaption->closing = PIKA_VALUES_GET_BOOLEAN (args, index_of_is_closing_arg (adaption->resource_type));
 | 
						|
 | 
						|
  if (! adaption->idle_id)
 | 
						|
    adaption->idle_id = g_idle_add ((GSourceFunc) pika_temp_resource_idle,
 | 
						|
                                    adaption);
 | 
						|
 | 
						|
  return pika_procedure_new_return_values (procedure, PIKA_PDB_SUCCESS, NULL);
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
pika_temp_resource_idle (PikaResourceAdaption *adaption)
 | 
						|
{
 | 
						|
  adaption->idle_id = 0;
 | 
						|
 | 
						|
  if (adaption->callback)
 | 
						|
    adaption->callback (pika_resource_get_by_id (adaption->resource_id),
 | 
						|
                        adaption->closing,
 | 
						|
                        adaption->owner_data);
 | 
						|
 | 
						|
  adaption->resource_id = 0;
 | 
						|
 | 
						|
  if (adaption->closing)
 | 
						|
    {
 | 
						|
      gchar *temp_PDB_callback_name = adaption->temp_PDB_callback_name;
 | 
						|
 | 
						|
      adaption->temp_PDB_callback_name = NULL;
 | 
						|
      pika_resource_select_destroy (temp_PDB_callback_name);
 | 
						|
      g_free (temp_PDB_callback_name);
 | 
						|
    }
 | 
						|
 | 
						|
  return G_SOURCE_REMOVE;
 | 
						|
}
 |