gimp-pdb.c 20.3 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17
 */
Sven Neumann's avatar
Sven Neumann committed
18

19 20
#include "config.h"

Elliot Lee's avatar
Elliot Lee committed
21 22
#include <stdarg.h>
#include <string.h>
23
#include <sys/types.h>
24

25
#include <glib-object.h>
Sven Neumann's avatar
Sven Neumann committed
26

27 28
#include "libgimpbase/gimpbase.h"

29
#include "pdb-types.h"
Sven Neumann's avatar
Sven Neumann committed
30

31
#include "core/gimp.h"
32
#include "core/gimpcontext.h"
33
#include "core/gimpprogress.h"
34

35
#include "plug-in/plug-in-run.h"
Michael Natterer's avatar
Michael Natterer committed
36

37
#include "internal_procs.h"
Elliot Lee's avatar
Elliot Lee committed
38
#include "procedural_db.h"
39

40
#include "gimp-intl.h"
41

42

Michael Natterer's avatar
Michael Natterer committed
43 44 45 46 47 48 49 50 51 52
typedef struct _PDBData PDBData;

struct _PDBData
{
  gchar  *identifier;
  gint32  bytes;
  guint8 *data;
};


53 54 55 56 57 58 59
/*  local function prototypes  */

gchar * procedural_db_type_name (GimpPDBArgType type);


/*  public functions  */

Elliot Lee's avatar
Elliot Lee committed
60
void
61
procedural_db_init (Gimp *gimp)
Elliot Lee's avatar
Elliot Lee committed
62
{
63
  g_return_if_fail (GIMP_IS_GIMP (gimp));
64

Michael Natterer's avatar
Michael Natterer committed
65
  gimp->procedural_ht           = g_hash_table_new (g_str_hash, g_str_equal);
66
  gimp->procedural_compat_ht    = g_hash_table_new (g_str_hash, g_str_equal);
Michael Natterer's avatar
Michael Natterer committed
67
  gimp->procedural_db_data_list = NULL;
Elliot Lee's avatar
Elliot Lee committed
68 69
}

70
static void
71
procedural_db_free_entry (gpointer key,
Manish Singh's avatar
Manish Singh committed
72 73
                          gpointer value,
                          gpointer user_data)
74 75 76 77 78
{
  if (value)
    g_list_free (value);
}

Elliot Lee's avatar
Elliot Lee committed
79
void
80
procedural_db_free (Gimp *gimp)
Elliot Lee's avatar
Elliot Lee committed
81
{
Michael Natterer's avatar
Michael Natterer committed
82 83
  g_return_if_fail (GIMP_IS_GIMP (gimp));

84
  if (gimp->procedural_ht)
85
    {
86
      g_hash_table_foreach (gimp->procedural_ht,
87
                            procedural_db_free_entry, NULL);
88 89 90
      g_hash_table_destroy (gimp->procedural_ht);
      gimp->procedural_ht = NULL;
    }
Michael Natterer's avatar
Michael Natterer committed
91

92 93 94 95 96 97
  if (gimp->procedural_compat_ht)
    {
      g_hash_table_destroy (gimp->procedural_compat_ht);
      gimp->procedural_compat_ht = NULL;
    }

98
  procedural_db_free_data (gimp);
Elliot Lee's avatar
Elliot Lee committed
99 100
}

101 102 103 104 105 106 107 108 109 110 111
void
procedural_db_init_procs (Gimp               *gimp,
                          GimpInitStatusFunc  status_callback)
{
  static const struct
  {
    const gchar *old_name;
    const gchar *new_name;
  }
  compat_procs[] =
  {
112
    { "gimp_blend",                      "gimp_edit_blend"                 },
113
    { "gimp_brushes_set_brush",          "gimp_context_set_brush"          },
114 115 116 117
    { "gimp_brushes_get_opacity",        "gimp_context_get_opacity"        },
    { "gimp_brushes_set_opacity",        "gimp_context_set_opacity"        },
    { "gimp_brushes_get_paint_mode",     "gimp_context_get_paint_mode"     },
    { "gimp_brushes_set_paint_mode",     "gimp_context_set_paint_mode"     },
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    { "gimp_brushes_list",               "gimp_brushes_get_list"           },
    { "gimp_bucket_fill",                "gimp_edit_bucket_fill"           },
    { "gimp_channel_delete",             "gimp_drawable_delete"            },
    { "gimp_channel_get_name",           "gimp_drawable_get_name"          },
    { "gimp_channel_get_tattoo",         "gimp_drawable_get_tattoo"        },
    { "gimp_channel_get_visible",        "gimp_drawable_get_visible"       },
    { "gimp_channel_set_name",           "gimp_drawable_set_name"          },
    { "gimp_channel_set_tattoo",         "gimp_drawable_set_tattoo"        },
    { "gimp_channel_set_visible",        "gimp_drawable_set_visible"       },
    { "gimp_color_picker",               "gimp_image_pick_color"           },
    { "gimp_convert_grayscale",          "gimp_image_convert_grayscale"    },
    { "gimp_convert_indexed",            "gimp_image_convert_indexed"      },
    { "gimp_convert_rgb",                "gimp_image_convert_rgb"          },
    { "gimp_crop",                       "gimp_image_crop"                 },
    { "gimp_drawable_bytes",             "gimp_drawable_bpp"               },
    { "gimp_drawable_image",             "gimp_drawable_get_image"         },
134 135 136 137
    { "gimp_gradients_get_active",       "gimp_context_get_gradient"       },
    { "gimp_gradients_set_active",       "gimp_context_set_gradient"       },
    { "gimp_gradients_get_gradient",     "gimp_context_get_gradient"       },
    { "gimp_gradients_set_gradient",     "gimp_context_set_gradient"       },
138 139
    { "gimp_image_active_drawable",      "gimp_image_get_active_drawable"  },
    { "gimp_image_floating_selection",   "gimp_image_get_floating_sel"     },
140 141
    { "gimp_image_get_cmap",             "gimp_image_get_colormap"         },
    { "gimp_image_set_cmap",             "gimp_image_set_colormap"         },
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
    { "gimp_layer_delete",               "gimp_drawable_delete"            },
    { "gimp_layer_get_linked",           "gimp_drawable_get_linked"        },
    { "gimp_layer_get_name",             "gimp_drawable_get_name"          },
    { "gimp_layer_get_tattoo",           "gimp_drawable_get_tattoo"        },
    { "gimp_layer_get_visible",          "gimp_drawable_get_visible"       },
    { "gimp_layer_mask",                 "gimp_layer_get_mask"             },
    { "gimp_layer_set_linked",           "gimp_drawable_set_linked"        },
    { "gimp_layer_set_name",             "gimp_drawable_set_name"          },
    { "gimp_layer_set_tattoo",           "gimp_drawable_set_tattoo"        },
    { "gimp_layer_set_visible",          "gimp_drawable_set_visible"       },
    { "gimp_palette_get_foreground",     "gimp_context_get_foreground"     },
    { "gimp_palette_get_background",     "gimp_context_get_background"     },
    { "gimp_palette_set_foreground",     "gimp_context_set_foreground"     },
    { "gimp_palette_set_background",     "gimp_context_set_background"     },
    { "gimp_palette_set_default_colors", "gimp_context_set_default_colors" },
    { "gimp_palette_swap_colors",        "gimp_context_swap_colors"        },
    { "gimp_palette_refresh",            "gimp_palettes_refresh"           },
159
    { "gimp_palettes_set_palette",       "gimp_context_set_palette"        },
160
    { "gimp_patterns_list",              "gimp_patterns_get_list"          },
161
    { "gimp_patterns_set_pattern",       "gimp_context_set_pattern"        },
162
    { "gimp_selection_clear",            "gimp_selection_none"             },
163 164 165 166
    { "gimp_temp_PDB_name",              "gimp_procedural_db_temp_name"    },
    { "gimp_undo_push_group_start",      "gimp_image_undo_group_start"     },
    { "gimp_undo_push_group_end",        "gimp_image_undo_group_end"       },
    { "gimp_channel_ops_duplicate",      "gimp_image_duplicate"            },
167 168 169 170
    { "gimp_channel_ops_offset",         "gimp_drawable_offset"            },

    { "gimp_layer_get_preserve_trans",   "gimp_drawable_set_lock_alpha"    },
    { "gimp_layer_set_preserve_trans",   "gimp_drawable_set_lock_alpha"    }
171 172 173 174 175 176 177
  };

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (status_callback != NULL);

  internal_procs_init (gimp, status_callback);

178 179 180 181 182 183 184 185 186
  if (gimp->pdb_compat_mode != GIMP_PDB_COMPAT_OFF)
    {
      gint i;

      for (i = 0; i < G_N_ELEMENTS (compat_procs); i++)
        g_hash_table_insert (gimp->procedural_compat_ht,
                             (gpointer) compat_procs[i].old_name,
                             (gpointer) compat_procs[i].new_name);
    }
187 188
}

Elliot Lee's avatar
Elliot Lee committed
189
void
190
procedural_db_register (Gimp       *gimp,
Manish Singh's avatar
Manish Singh committed
191
                        ProcRecord *procedure)
Elliot Lee's avatar
Elliot Lee committed
192 193 194
{
  GList *list;

Michael Natterer's avatar
Michael Natterer committed
195 196 197
  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (procedure != NULL);

198
  list = g_hash_table_lookup (gimp->procedural_ht, procedure->name);
Elliot Lee's avatar
Elliot Lee committed
199 200
  list = g_list_prepend (list, (gpointer) procedure);

201
  g_hash_table_insert (gimp->procedural_ht,
Manish Singh's avatar
Manish Singh committed
202 203
                       (gpointer) procedure->name,
                       (gpointer) list);
Elliot Lee's avatar
Elliot Lee committed
204 205 206
}

void
207
procedural_db_unregister (Gimp        *gimp,
Manish Singh's avatar
Manish Singh committed
208
                          const gchar *name)
Elliot Lee's avatar
Elliot Lee committed
209 210 211
{
  GList *list;

Michael Natterer's avatar
Michael Natterer committed
212 213 214
  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (name != NULL);

215
  list = g_hash_table_lookup (gimp->procedural_ht, name);
216

Elliot Lee's avatar
Elliot Lee committed
217 218 219 220 221
  if (list)
    {
      list = g_list_remove (list, list->data);

      if (list)
Manish Singh's avatar
Manish Singh committed
222
        g_hash_table_insert (gimp->procedural_ht, (gpointer) name, list);
223
      else
Manish Singh's avatar
Manish Singh committed
224
        g_hash_table_remove (gimp->procedural_ht, name);
Elliot Lee's avatar
Elliot Lee committed
225 226 227 228
    }
}

ProcRecord *
229
procedural_db_lookup (Gimp        *gimp,
Manish Singh's avatar
Manish Singh committed
230
                      const gchar *name)
Elliot Lee's avatar
Elliot Lee committed
231
{
232
  GList *list;
Elliot Lee's avatar
Elliot Lee committed
233

Michael Natterer's avatar
Michael Natterer committed
234 235 236
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (name != NULL, NULL);

237
  list = g_hash_table_lookup (gimp->procedural_ht, name);
Elliot Lee's avatar
Elliot Lee committed
238

239 240 241 242
  if (list)
    return (ProcRecord *) list->data;
  else
    return NULL;
Elliot Lee's avatar
Elliot Lee committed
243 244 245
}

Argument *
246 247 248 249 250
procedural_db_execute (Gimp         *gimp,
                       GimpContext  *context,
                       GimpProgress *progress,
                       const gchar  *name,
                       Argument     *args)
Elliot Lee's avatar
Elliot Lee committed
251
{
252 253
  Argument *return_args = NULL;
  GList    *list;
Elliot Lee's avatar
Elliot Lee committed
254

Michael Natterer's avatar
Michael Natterer committed
255
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
256
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
257
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
Michael Natterer's avatar
Michael Natterer committed
258 259
  g_return_val_if_fail (name != NULL, NULL);

260
  list = g_hash_table_lookup (gimp->procedural_ht, name);
Elliot Lee's avatar
Elliot Lee committed
261

262 263
  if (list == NULL)
    {
264
      g_message (_("PDB calling error:\nprocedure '%s' not found"), name);
265

266
      return_args = g_new (Argument, 1);
267
      return_args->arg_type      = GIMP_PDB_STATUS;
268
      return_args->value.pdb_int = GIMP_PDB_CALLING_ERROR;
269

270 271
      return return_args;
    }
272

273
  for (; list; list = g_list_next (list))
Elliot Lee's avatar
Elliot Lee committed
274
    {
275
      ProcRecord *procedure = list->data;
276 277 278
      gint        i;

      g_return_val_if_fail (procedure != NULL, NULL);
Elliot Lee's avatar
Elliot Lee committed
279 280 281

      /*  check the arguments  */
      for (i = 0; i < procedure->num_args; i++)
Manish Singh's avatar
Manish Singh committed
282 283 284
        {
          if (args[i].arg_type != procedure->args[i].arg_type)
            {
285 286 287 288 289 290
              gchar *expected;
              gchar *got;

              expected = procedural_db_type_name (procedure->args[i].arg_type);
              got      = procedural_db_type_name (args[i].arg_type);

Manish Singh's avatar
Manish Singh committed
291
              g_message (_("PDB calling error for procedure '%s':\n"
292
                           "Argument #%d type mismatch (expected %s, got %s)"),
293 294 295 296
                         procedure->name, i + 1, expected, got);

              g_free (expected);
              g_free (got);
297

Manish Singh's avatar
Manish Singh committed
298 299 300
              return_args = g_new (Argument, 1);
              return_args->arg_type      = GIMP_PDB_STATUS;
              return_args->value.pdb_int = GIMP_PDB_CALLING_ERROR;
Elliot Lee's avatar
Elliot Lee committed
301

Manish Singh's avatar
Manish Singh committed
302 303 304
              return return_args;
            }
        }
Elliot Lee's avatar
Elliot Lee committed
305 306 307

      /*  call the procedure  */
      switch (procedure->proc_type)
Manish Singh's avatar
Manish Singh committed
308 309 310
        {
        case GIMP_INTERNAL:
          return_args =
311
            (* procedure->exec_method.internal.marshal_func) (gimp, context,
312
                                                              progress,
313
                                                              args);
Manish Singh's avatar
Manish Singh committed
314
          break;
Elliot Lee's avatar
Elliot Lee committed
315

Manish Singh's avatar
Manish Singh committed
316 317 318
        case GIMP_PLUGIN:
        case GIMP_EXTENSION:
        case GIMP_TEMPORARY:
319
          return_args = plug_in_run (gimp, context, progress, procedure,
320
                                     args, procedure->num_args,
321
                                     TRUE, FALSE, -1);
322 323 324 325 326 327

          /*  If there are no return arguments, assume
           *  an execution error and fall through.
           */
          if (return_args)
            break;
Elliot Lee's avatar
Elliot Lee committed
328

Manish Singh's avatar
Manish Singh committed
329 330 331 332
        default:
          return_args = g_new (Argument, 1);
          return_args->arg_type      = GIMP_PDB_STATUS;
          return_args->value.pdb_int = GIMP_PDB_EXECUTION_ERROR;
333 334

          return return_args;
Manish Singh's avatar
Manish Singh committed
335
        }
Elliot Lee's avatar
Elliot Lee committed
336

337 338
      if (return_args[0].value.pdb_int != GIMP_PDB_SUCCESS      &&
          return_args[0].value.pdb_int != GIMP_PDB_PASS_THROUGH &&
Manish Singh's avatar
Manish Singh committed
339
          procedure->num_values > 0)
340 341 342
        {
          memset (&return_args[1], 0, sizeof (Argument) * procedure->num_values);
        }
Elliot Lee's avatar
Elliot Lee committed
343

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
      if (return_args[0].value.pdb_int == GIMP_PDB_PASS_THROUGH)
        {
          /*  If the return value is GIMP_PDB_PASS_THROUGH and there is
           *  a next procedure in the list, destroy the return values
           *  and run the next procedure.
           */
          if (g_list_next (list))
            procedural_db_destroy_args (return_args, procedure->num_values);
        }
      else
        {
          /*  No GIMP_PDB_PASS_THROUGH, break out of the list of
           *  procedures and return the current return values.
           */
          break;
        }
Elliot Lee's avatar
Elliot Lee committed
360 361 362 363 364 365
    }

  return return_args;
}

Argument *
366 367 368 369 370
procedural_db_run_proc (Gimp         *gimp,
                        GimpContext  *context,
                        GimpProgress *progress,
                        const gchar  *name,
                        gint         *nreturn_vals,
Manish Singh's avatar
Manish Singh committed
371
                        ...)
Elliot Lee's avatar
Elliot Lee committed
372 373
{
  ProcRecord *proc;
374 375 376 377
  Argument   *params;
  Argument   *return_vals;
  va_list     args;
  gint        i;
Elliot Lee's avatar
Elliot Lee committed
378

Michael Natterer's avatar
Michael Natterer committed
379
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
380
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
381
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL);
Michael Natterer's avatar
Michael Natterer committed
382
  g_return_val_if_fail (name != NULL, NULL);
Sven Neumann's avatar
Sven Neumann committed
383
  g_return_val_if_fail (nreturn_vals != NULL, NULL);
Michael Natterer's avatar
Michael Natterer committed
384

385 386 387
  proc = procedural_db_lookup (gimp, name);

  if (proc == NULL)
Elliot Lee's avatar
Elliot Lee committed
388
    {
Sven Neumann's avatar
Sven Neumann committed
389 390
      *nreturn_vals = 1;

391
      return_vals = g_new (Argument, 1);
392
      return_vals->arg_type      = GIMP_PDB_STATUS;
393
      return_vals->value.pdb_int = GIMP_PDB_CALLING_ERROR;
394

Elliot Lee's avatar
Elliot Lee committed
395 396 397 398 399 400 401 402 403 404
      return return_vals;
    }

  /*  allocate the parameter array  */
  params = g_new (Argument, proc->num_args);

  va_start (args, nreturn_vals);

  for (i = 0; i < proc->num_args; i++)
    {
405 406 407
      params[i].arg_type = va_arg (args, GimpPDBArgType);

      if (proc->args[i].arg_type != params[i].arg_type)
Manish Singh's avatar
Manish Singh committed
408
        {
409 410 411 412 413 414
          gchar *expected;
          gchar *got;

          expected = procedural_db_type_name (proc->args[i].arg_type);
          got      = procedural_db_type_name (params[i].arg_type);

Manish Singh's avatar
Manish Singh committed
415
          g_free (params);
Sven Neumann's avatar
Sven Neumann committed
416

417 418 419 420 421 422 423
         g_message (_("PDB calling error for procedure '%s':\n"
                       "Argument #%d type mismatch (expected %s, got %s)"),
                    proc->name, i + 1, expected, got);

          g_free (expected);
          g_free (got);

Sven Neumann's avatar
Sven Neumann committed
424
          *nreturn_vals = 0;
Manish Singh's avatar
Manish Singh committed
425 426
          return NULL;
        }
Elliot Lee's avatar
Elliot Lee committed
427 428

      switch (proc->args[i].arg_type)
Manish Singh's avatar
Manish Singh committed
429 430 431 432
        {
        case GIMP_PDB_INT32:
        case GIMP_PDB_INT16:
        case GIMP_PDB_INT8:
433
        case GIMP_PDB_DISPLAY:
Manish Singh's avatar
Manish Singh committed
434 435
          params[i].value.pdb_int = (gint32) va_arg (args, gint);
          break;
436

437
        case GIMP_PDB_FLOAT:
438
          params[i].value.pdb_float = (gdouble) va_arg (args, gdouble);
Elliot Lee's avatar
Elliot Lee committed
439
          break;
440

441 442 443 444 445 446
        case GIMP_PDB_STRING:
        case GIMP_PDB_INT32ARRAY:
        case GIMP_PDB_INT16ARRAY:
        case GIMP_PDB_INT8ARRAY:
        case GIMP_PDB_FLOATARRAY:
        case GIMP_PDB_STRINGARRAY:
447 448
          params[i].value.pdb_pointer = va_arg (args, gpointer);
          break;
449

450
        case GIMP_PDB_COLOR:
Manish Singh's avatar
Manish Singh committed
451
          params[i].value.pdb_color = va_arg (args, GimpRGB);
Elliot Lee's avatar
Elliot Lee committed
452
          break;
453

454
        case GIMP_PDB_REGION:
Elliot Lee's avatar
Elliot Lee committed
455
          break;
456

457 458 459 460 461 462 463
        case GIMP_PDB_IMAGE:
        case GIMP_PDB_LAYER:
        case GIMP_PDB_CHANNEL:
        case GIMP_PDB_DRAWABLE:
        case GIMP_PDB_SELECTION:
        case GIMP_PDB_BOUNDARY:
        case GIMP_PDB_PATH:
Manish Singh's avatar
Manish Singh committed
464 465
          params[i].value.pdb_int = (gint32) va_arg (args, gint);
          break;
466

467
        case GIMP_PDB_PARASITE:
468
          params[i].value.pdb_pointer = va_arg (args, gpointer);
469
          break;
470

471
        case GIMP_PDB_STATUS:
Manish Singh's avatar
Manish Singh committed
472 473
          params[i].value.pdb_int = (gint32) va_arg (args, gint);
          break;
474

Manish Singh's avatar
Manish Singh committed
475 476 477
        case GIMP_PDB_END:
          break;
        }
Elliot Lee's avatar
Elliot Lee committed
478 479 480 481 482 483
    }

  va_end (args);

  *nreturn_vals = proc->num_values;

484
  return_vals = procedural_db_execute (gimp, context, progress, name, params);
Elliot Lee's avatar
Elliot Lee committed
485 486 487 488 489 490 491 492

  g_free (params);

  return return_vals;
}

Argument *
procedural_db_return_args (ProcRecord *procedure,
Manish Singh's avatar
Manish Singh committed
493
                           gboolean    success)
Elliot Lee's avatar
Elliot Lee committed
494 495
{
  Argument *return_args;
496
  gint      i;
Elliot Lee's avatar
Elliot Lee committed
497

Michael Natterer's avatar
Michael Natterer committed
498 499
  g_return_val_if_fail (procedure != NULL, NULL);

500 501 502
  return_args = g_new0 (Argument, procedure->num_values + 1);

  return_args[0].arg_type = GIMP_PDB_STATUS;
Elliot Lee's avatar
Elliot Lee committed
503 504

  if (success)
505
    return_args[0].value.pdb_int = GIMP_PDB_SUCCESS;
Elliot Lee's avatar
Elliot Lee committed
506
  else
507
    return_args[0].value.pdb_int = GIMP_PDB_EXECUTION_ERROR;
Elliot Lee's avatar
Elliot Lee committed
508 509 510

  /*  Set the arg types for the return values  */
  for (i = 0; i < procedure->num_values; i++)
511
    return_args[i + 1].arg_type = procedure->values[i].arg_type;
Elliot Lee's avatar
Elliot Lee committed
512 513 514 515 516 517

  return return_args;
}

void
procedural_db_destroy_args (Argument *args,
Manish Singh's avatar
Manish Singh committed
518
                            gint      nargs)
Elliot Lee's avatar
Elliot Lee committed
519
{
520
  gint i;
Elliot Lee's avatar
Elliot Lee committed
521

522
  if (! args)
523
    return;
524

Elliot Lee's avatar
Elliot Lee committed
525 526 527
  for (i = 0; i < nargs; i++)
    {
      switch (args[i].arg_type)
Manish Singh's avatar
Manish Singh committed
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
        {
        case GIMP_PDB_INT32:
        case GIMP_PDB_INT16:
        case GIMP_PDB_INT8:
        case GIMP_PDB_FLOAT:
          break;

        case GIMP_PDB_STRING:
        case GIMP_PDB_INT32ARRAY:
        case GIMP_PDB_INT16ARRAY:
        case GIMP_PDB_INT8ARRAY:
        case GIMP_PDB_FLOATARRAY:
          g_free (args[i].value.pdb_pointer);
          break;

        case GIMP_PDB_STRINGARRAY:
544 545 546 547
          {
            gchar **stringarray;
            gint    count;
            gint    j;
548

549 550 551 552 553 554 555 556 557 558
            count       = args[i - 1].value.pdb_int;
            stringarray = args[i].value.pdb_pointer;

            for (j = 0; j < count; j++)
              g_free (stringarray[j]);

            g_free (args[i].value.pdb_pointer);
          }
          break;

Manish Singh's avatar
Manish Singh committed
559 560 561 562 563 564 565 566 567 568 569 570 571
        case GIMP_PDB_COLOR:
        case GIMP_PDB_REGION:
        case GIMP_PDB_DISPLAY:
        case GIMP_PDB_IMAGE:
        case GIMP_PDB_LAYER:
        case GIMP_PDB_CHANNEL:
        case GIMP_PDB_DRAWABLE:
        case GIMP_PDB_SELECTION:
        case GIMP_PDB_BOUNDARY:
        case GIMP_PDB_PATH:
          break;

        case GIMP_PDB_PARASITE:
572 573 574
          gimp_parasite_free ((GimpParasite *) (args[i].value.pdb_pointer));
          break;

Manish Singh's avatar
Manish Singh committed
575 576 577 578
        case GIMP_PDB_STATUS:
        case GIMP_PDB_END:
          break;
        }
Elliot Lee's avatar
Elliot Lee committed
579 580 581 582
    }

  g_free (args);
}
Michael Natterer's avatar
Michael Natterer committed
583

584 585 586 587 588 589 590
void
procedural_db_free_data (Gimp *gimp)
{
  g_return_if_fail (GIMP_IS_GIMP (gimp));

  if (gimp->procedural_db_data_list)
    {
591
      GList *list;
592 593 594 595 596

      for (list = gimp->procedural_db_data_list;
           list;
           list = g_list_next (list))
        {
597
          PDBData *data = list->data;
598 599 600 601 602 603 604 605 606 607 608

          g_free (data->identifier);
          g_free (data->data);
          g_free (data);
        }

      g_list_free (gimp->procedural_db_data_list);
      gimp->procedural_db_data_list = NULL;
    }
}

Michael Natterer's avatar
Michael Natterer committed
609
void
610
procedural_db_set_data (Gimp         *gimp,
Michael Natterer's avatar
Michael Natterer committed
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
                        const gchar  *identifier,
                        gint32        bytes,
                        const guint8 *data)
{
  GList   *list;
  PDBData *pdb_data;

  g_return_if_fail (GIMP_IS_GIMP (gimp));
  g_return_if_fail (identifier != NULL);
  g_return_if_fail (bytes > 0);
  g_return_if_fail (data != NULL);

  for (list = gimp->procedural_db_data_list; list; list = g_list_next (list))
    {
      pdb_data = (PDBData *) list->data;

      if (! strcmp (pdb_data->identifier, identifier))
        break;
    }

  /* If there isn't already data with the specified identifier, create one */
  if (list == NULL)
    {
      pdb_data = g_new0 (PDBData, 1);
      pdb_data->identifier = g_strdup (identifier);

      gimp->procedural_db_data_list =
        g_list_prepend (gimp->procedural_db_data_list, pdb_data);
    }
  else
    {
      g_free (pdb_data->data);
    }

  pdb_data->bytes = bytes;
  pdb_data->data  = g_memdup (data, bytes);
}

const guint8 *
procedural_db_get_data (Gimp        *gimp,
                        const gchar *identifier,
                        gint32      *bytes)
{
654
  GList *list;
Michael Natterer's avatar
Michael Natterer committed
655 656 657 658 659 660 661 662 663

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (identifier != NULL, NULL);
  g_return_val_if_fail (bytes != NULL, NULL);

  *bytes = 0;

  for (list = gimp->procedural_db_data_list; list; list = g_list_next (list))
    {
664
      PDBData *pdb_data = list->data;
Michael Natterer's avatar
Michael Natterer committed
665 666 667 668 669 670 671 672 673 674

      if (! strcmp (pdb_data->identifier, identifier))
        {
          *bytes = pdb_data->bytes;
          return pdb_data->data;
        }
    }

  return NULL;
}
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691


/*  private functions  */

gchar *
procedural_db_type_name (GimpPDBArgType type)
{
  const gchar *name;

  if (! gimp_enum_get_value (GIMP_TYPE_PDB_ARG_TYPE, type,
                             &name, NULL, NULL, NULL))
    {
      return  g_strdup_printf ("(PDB type %d unknown)", type);
    }

  return g_strdup (name);
}