gimpdisplayshell-filter.c 8.07 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* The GIMP -- an image manipulation program
 * Copyright (C) 1999 Manish Singh
 *
 * 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
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
Sven Neumann's avatar
Sven Neumann committed
18

19 20
#include "config.h"

21 22
#include <string.h>

23 24
#include <gmodule.h>

25 26
#include "libgimpbase/gimpbase.h"

Sven Neumann's avatar
Sven Neumann committed
27
#include "apptypes.h"
28
#include "gdisplay_color.h"
29
#include "gdisplay.h"
30
#include "gimpimageP.h"
31
#include "gimpui.h"
32

33
#include <gtk/gtk.h>
34 35 36

typedef struct _ColorDisplayInfo ColorDisplayInfo;

37 38 39
struct _ColorDisplayInfo
 {
  gchar                   *name;
40 41 42 43 44 45
  GimpColorDisplayMethods  methods;
  GSList                  *refs;
};

static GHashTable *color_display_table = NULL;

46 47 48
static void       color_display_foreach_real (gpointer          key,
					      gpointer          value,
					      gpointer          user_data);
49 50 51 52
static void       gdisplay_color_detach_real (GDisplay         *gdisp,
					      ColorDisplayNode *node,
					      gboolean          unref);
static gint       node_name_compare          (ColorDisplayNode *node,
53
					      const gchar      *name);
54

55
void
56
color_display_init (void)
57 58 59
{
}

60
G_MODULE_EXPORT gboolean
61
gimp_color_display_register (const gchar             *name,
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    			     GimpColorDisplayMethods *methods)
{
  ColorDisplayInfo *info;
  
  info = g_new (ColorDisplayInfo, 1);
  
  info->name = g_strdup (name);
  info->methods = *methods;
  info->refs = NULL;
  
  if (!color_display_table)
    color_display_table = g_hash_table_new (g_str_hash, g_str_equal);
  
  if (g_hash_table_lookup (color_display_table, name))
    return FALSE;

  if (!methods->convert)
    return FALSE;

  g_hash_table_insert (color_display_table, info->name, info);
  
  return TRUE;
}

86
G_MODULE_EXPORT gboolean
87
gimp_color_display_unregister (const gchar *name)
88 89
{
  ColorDisplayInfo *info;
90 91
  GDisplay *gdisp;
  GList *node;
92 93 94

  if ((info = g_hash_table_lookup (color_display_table, name)))
    {
95 96 97 98 99 100
      GSList *refs = info->refs;

      while (refs)
	{
	  gdisp = (GDisplay *) refs->data;

101 102 103
	  node = g_list_find_custom (gdisp->cd_list, (gpointer) name,
	      			     (GCompareFunc) node_name_compare);
	  gdisp->cd_list = g_list_remove_link (gdisp->cd_list, node);
104 105 106 107 108 109 110 111 112 113

	  gdisplay_color_detach_real (gdisp, node->data, FALSE);

	  g_list_free_1 (node);

	  refs = refs->next;
	}

      g_slist_free (info->refs);

114 115 116 117 118 119 120 121 122
      g_hash_table_remove (color_display_table, name);

      g_free (info->name);
      g_free (info);
    }
  
  return TRUE;
}

123 124 125 126 127 128 129 130 131
typedef struct _DisplayForeachData DisplayForeachData;

struct _DisplayForeachData
{
  GimpCDFunc func;
  gpointer   user_data;
};

void
132 133
color_display_foreach (GimpCDFunc func,
		       gpointer   user_data)
134 135 136 137 138 139
{
  DisplayForeachData data;

  data.func = func;
  data.user_data = user_data;

140
  g_hash_table_foreach (color_display_table, color_display_foreach_real, &data);
141 142 143
}

static void
144 145 146
color_display_foreach_real (gpointer key,
		            gpointer value,
		            gpointer user_data)
147 148 149 150 151
{
  DisplayForeachData *data = (DisplayForeachData *) user_data;
  data->func (key, data->user_data);
}

152
ColorDisplayNode *
153 154
gdisplay_color_attach (GDisplay    *gdisp,
		       const gchar *name)
155 156
{
  ColorDisplayInfo *info;
157
  ColorDisplayNode *node;
158

159
  g_return_val_if_fail (gdisp != NULL, NULL);
160

161 162
  if ((info = g_hash_table_lookup (color_display_table, name)))
    {
163 164 165 166 167
      node = g_new (ColorDisplayNode, 1);

      node->cd_name = g_strdup (name);
      node->cd_ID = NULL;

168 169 170 171 172 173
      if (!info->refs && info->methods.init)
	info->methods.init ();

      info->refs = g_slist_append (info->refs, gdisp);

      if (info->methods.new)
174
	node->cd_ID = info->methods.new (gdisp->gimage->base_type);
175

176 177
      node->cd_convert = info->methods.convert;

178 179 180
      gdisp->cd_list = g_list_append (gdisp->cd_list, node);

      return node;
181
    }
182 183
  else
    g_warning ("Tried to attach a nonexistant color display");
184 185

  return NULL;
186 187
}

188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
ColorDisplayNode *
gdisplay_color_attach_clone (GDisplay         *gdisp,
			     ColorDisplayNode *node)
{
  ColorDisplayInfo *info;
  ColorDisplayNode *clone;

  g_return_val_if_fail (gdisp != NULL, NULL);
  g_return_val_if_fail (node != NULL, NULL);

  if ((info = g_hash_table_lookup (color_display_table, node->cd_name)))
    {
      clone = g_new (ColorDisplayNode, 1);

      clone->cd_name = g_strdup (node->cd_name);
      clone->cd_ID = NULL;

      info->refs = g_slist_append (info->refs, gdisp);

      if (info->methods.clone)
	node->cd_ID = info->methods.clone (node->cd_ID);

      node->cd_convert = info->methods.convert;

      gdisp->cd_list = g_list_append (gdisp->cd_list, node);

      return node;
    }
  else
    g_warning ("Tried to clone a nonexistant color display");

  return NULL;
}

222
void
223 224
gdisplay_color_detach (GDisplay         *gdisp,
		       ColorDisplayNode *node)
225
{
226 227
  g_return_if_fail (gdisp != NULL);

228 229
  gdisp->cd_list = g_list_remove (gdisp->cd_list, node);
}
230

231 232 233 234
void
gdisplay_color_detach_destroy (GDisplay         *gdisp,
			       ColorDisplayNode *node)
{
235 236
  g_return_if_fail (gdisp != NULL);

237 238
  gdisplay_color_detach_real (gdisp, node, TRUE);
  gdisp->cd_list = g_list_remove (gdisp->cd_list, node);
239 240 241
}

void
242 243
gdisplay_color_detach_all (GDisplay *gdisp)
{
Manish Singh's avatar
Manish Singh committed
244
  GList *list;
245

246 247
  g_return_if_fail (gdisp != NULL);

Manish Singh's avatar
Manish Singh committed
248 249
  list = gdisp->cd_list;

250 251 252 253 254 255 256 257 258 259 260 261 262 263
  while (list)
    {
      gdisplay_color_detach_real (gdisp, list->data, TRUE);
      list = list->next;
    }

  g_list_free (gdisp->cd_list);
  gdisp->cd_list = NULL;
}

static void
gdisplay_color_detach_real (GDisplay         *gdisp,
			    ColorDisplayNode *node,
			    gboolean          unref)
264 265
{
  ColorDisplayInfo *info;
266

267
  g_return_if_fail (gdisp != NULL);
268
  g_return_if_fail (node  != NULL);
269

270
  if ((info = g_hash_table_lookup (color_display_table, node->cd_name)))
271
    {
272 273
      if (info->methods.destroy)
	info->methods.destroy (node->cd_ID);
274

275 276
      if (unref)
        info->refs = g_slist_remove (info->refs, gdisp);
277
      
278 279 280
      if (!info->refs && info->methods.finalize)
	info->methods.finalize ();
    }
281

282 283 284 285
  g_free (node->cd_name);
  g_free (node);
}  

286 287 288
void
gdisplay_color_reorder_up (GDisplay         *gdisp,
			   ColorDisplayNode *node)
289
{
290
  GList *node_list;
291

292
  node_list = g_list_find (gdisp->cd_list, node);
293

294 295 296 297 298
  if (node_list->prev)
    {
      node_list->data = node_list->prev->data;
      node_list->prev->data = node;
    }
299 300
}

301 302 303
void
gdisplay_color_reorder_down (GDisplay         *gdisp,
			     ColorDisplayNode *node)
304
{
305
  GList *node_list;
306

307 308
  g_return_if_fail (gdisp != NULL);

309
  node_list = g_list_find (gdisp->cd_list, node);
310

311 312 313 314 315
  if (node_list->next)
    {
      node_list->data = node_list->next->data;
      node_list->next->data = node;
    }
316 317
}

318 319 320
static gint
node_name_compare (ColorDisplayNode *node,
		   const char       *name)
321
{
322
  return strcmp (node->cd_name, name);
323
}
324

325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
void
gdisplay_color_configure (ColorDisplayNode *node,
			  GFunc             ok_func,
			  gpointer          ok_data,
			  GFunc             cancel_func,
			  gpointer          cancel_data)
{
  ColorDisplayInfo *info;

  g_return_if_fail (node != NULL);

  if ((info = g_hash_table_lookup (color_display_table, node->cd_name)))
    {
      if (info->methods.configure)
	info->methods.configure (node->cd_ID,
	    			 ok_func, ok_data,
				 cancel_func, cancel_data);
    }
  else
    g_warning ("Tried to configure a nonexistant color display");

  return;
}
348

349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
void
gdisplay_color_configure_cancel (ColorDisplayNode *node)
{
  ColorDisplayInfo *info;

  g_return_if_fail (node != NULL);

  if ((info = g_hash_table_lookup (color_display_table, node->cd_name)))
    {
      if (info->methods.cancel)
	info->methods.cancel (node->cd_ID);
    }
  else
    g_warning ("Tried to configure cancel a nonexistant color display");

  return;
}