iMon Jan 18 23:36:57 1999 Austin Donnelly <austin@gimp.org>

* app/menus.c: include module browser, plus re-instate the 'swap
	     colors' and other options that got killed by mistake.  Clean
	     up the odd extra separator too.

	* app/color_notebook.c: hide newly created colour selectors so we
	     know the GIMP one will be the default page.

	* app/module_db.[ch]: NEW FILEs: module database / browser.
	* app/Makefile.am: add module_db.[ch] stuff
	* app/app_procs.c: initialise the module_db
	* app/commands.[ch]: callback to create a module browser.
	* app/plug_in.c: move module loading out to module_db.c
	* libgimp/gimpmodule.h: API change: module_init() should return
	     additonal info (author, purpose, date, etc.)   Also optional
	     module_unload() function.
	* modules/colorsel_gtk.c: add module info, plus an unload function

	* modules/Makefile.am: build triangle colour selector module
	* modules/colorsel_triangle.c: NEW FILE: colour selector from
	     Simon Budig <Simon.Budig@unix-ag.org>.

	* MAINTAINERS: changed my email address
This commit is contained in:
Austin Donnelly 1999-01-19 00:03:00 +00:00
parent 11068b83dd
commit 43639fa0b3
50 changed files with 2496 additions and 1399 deletions

View File

@ -1,3 +1,28 @@
Mon Jan 18 23:36:57 1999 Austin Donnelly <austin@gimp.org>
* app/menus.c: include module browser, plus re-instate the 'swap
colors' and other options that got killed by mistake. Clean
up the odd extra separator too.
* app/color_notebook.c: hide newly created colour selectors so we
know the GIMP one will be the default page.
* app/module_db.[ch]: NEW FILEs: module database / browser.
* app/Makefile.am: add module_db.[ch] stuff
* app/app_procs.c: initialise the module_db
* app/commands.[ch]: callback to create a module browser.
* app/plug_in.c: move module loading out to module_db.c
* libgimp/gimpmodule.h: API change: module_init() should return
additonal info (author, purpose, date, etc.) Also optional
module_unload() function.
* modules/colorsel_gtk.c: add module info, plus an unload function
* modules/Makefile.am: build triangle colour selector module
* modules/colorsel_triangle.c: NEW FILE: colour selector from
Simon Budig <Simon.Budig@unix-ag.org>.
* MAINTAINERS: changed my email address
Mon Jan 18 22:55:19 GMT 1999 Adam D. Moss <adam@gimp.org>
* app/gimpimage.c app/gimpimage.h:

View File

@ -31,10 +31,10 @@ current work: once the Windows port needs less attention, would love
commit access: no
Name: Austin Donnelly
Email: austin@greenend.org.uk
Email: austin@gimp.org
url: http://www.cl.cam.ac.uk/~and1000/
ircnick: austin
expertise: resolution stuff, fonts
expertise: resolution stuff, modules, colour selectors, fonts
current work: random bug fixes, resolution
commit access: yes

View File

@ -245,6 +245,8 @@ gimp_SOURCES = \
marching_ants.h \
menus.c \
menus.h \
module_db.c \
module_db.h \
move.c \
move.h \
ops_buttons.c \

View File

@ -57,6 +57,7 @@
#include "layers_dialog.h"
#include "layer_select.h"
#include "levels.h"
#include "module_db.h"
#include "palette.h"
#include "patterns.h"
#include "plug_in.h"
@ -1105,6 +1106,16 @@ tips_dialog_cmd_callback (GtkWidget *widget,
tips_dialog_create ();
}
void
dialogs_module_browser_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GtkWidget *w;
w = module_db_browser_new ();
gtk_widget_show (w);
}
/****************************************************/
/** LOCAL FUNCTIONS **/

View File

@ -95,5 +95,6 @@ void dialogs_device_status_cmd_callback (GtkWidget *, gpointer);
void dialogs_error_console_cmd_callback (GtkWidget *, gpointer);
void about_dialog_cmd_callback (GtkWidget *, gpointer);
void tips_dialog_cmd_callback (GtkWidget *, gpointer);
void dialogs_module_browser_cmd_callback (GtkWidget *, gpointer);
#endif /* __COMMANDS_H__ */

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -55,6 +55,7 @@
#include "palette.h"
#include "patterns.h"
#include "plug_in.h"
#include "module_db.h"
#include "procedural_db.h"
#include "session.h"
#include "temp_buf.h"
@ -526,6 +527,7 @@ app_init (void)
app_init_update_status (NULL, NULL, 1.00);
plug_in_init (); /* initialize the plug in structures */
module_db_init (); /* load any modules we need */
RESET_BAR();
file_ops_post_init (); /* post-initialize the file types */

View File

@ -147,6 +147,8 @@ color_notebook_new (int r,
{
label = gtk_label_new (info->name);
gtk_widget_show (label);
/* hide the frame, so it doesn't get selected by mistake */
gtk_widget_hide (csel->frame);
gtk_notebook_append_page (GTK_NOTEBOOK (cnp->notebook),
csel->frame, label);
}

View File

@ -57,6 +57,7 @@
#include "layers_dialog.h"
#include "layer_select.h"
#include "levels.h"
#include "module_db.h"
#include "palette.h"
#include "patterns.h"
#include "plug_in.h"
@ -1105,6 +1106,16 @@ tips_dialog_cmd_callback (GtkWidget *widget,
tips_dialog_create ();
}
void
dialogs_module_browser_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GtkWidget *w;
w = module_db_browser_new ();
gtk_widget_show (w);
}
/****************************************************/
/** LOCAL FUNCTIONS **/

View File

@ -95,5 +95,6 @@ void dialogs_device_status_cmd_callback (GtkWidget *, gpointer);
void dialogs_error_console_cmd_callback (GtkWidget *, gpointer);
void about_dialog_cmd_callback (GtkWidget *, gpointer);
void tips_dialog_cmd_callback (GtkWidget *, gpointer);
void dialogs_module_browser_cmd_callback (GtkWidget *, gpointer);
#endif /* __COMMANDS_H__ */

View File

@ -147,6 +147,8 @@ color_notebook_new (int r,
{
label = gtk_label_new (info->name);
gtk_widget_show (label);
/* hide the frame, so it doesn't get selected by mistake */
gtk_widget_hide (csel->frame);
gtk_notebook_append_page (GTK_NOTEBOOK (cnp->notebook),
csel->frame, label);
}

518
app/dialogs/module-dialog.c Normal file
View File

@ -0,0 +1,518 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* module_db.c (C) 1999 Austin Donnelly <austin@gimp.org>
*
* 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.
*/
#include <stdio.h>
#include <string.h>
#include "appenv.h"
#include "module_db.h"
#include "gimprc.h"
#include "datafiles.h"
#include "actionarea.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmodule.h"
typedef enum {
ST_MODULE_ERROR, /* missing module_load function or other error */
ST_LOADED_OK, /* happy and running (normal state of affairs) */
ST_LOAD_FAILED, /* module_load returned GIMP_MODULE_UNLOAD */
ST_UNLOAD_REQUESTED, /* sent unload request, waiting for callback */
ST_UNLOADED_OK /* callback arrived, module not in memory anymore */
} module_state;
static const char * const statename[] = {
"ST_MODULE_ERROR",
"ST_LOADED_OK",
"ST_LOAD_FAILED",
"ST_UNLOAD_REQUESTED",
"ST_UNLOADED_OK"
};
/* one of these is kept per-module */
typedef struct {
gchar *fullpath; /* path to the module */
module_state state; /* what's happened to the module */
/* stuff from now on may be NULL depending on the state the module is in */
GimpModuleInfo *info; /* returned values from module_init */
GModule *module; /* handle on the module */
gchar *last_module_error;
GimpModuleInitFunc *init;
GimpModuleUnloadFunc *unload;
} module_info;
#define NUM_INFO_LINES 6
typedef struct {
GtkWidget *table;
GtkWidget *label[NUM_INFO_LINES];
GtkWidget *button_label;
module_info *last_update;
GtkWidget *button;
} browser_st;
/* global list of module_info */
static GSList *modules = NULL;
/*#define DUMP_DB*/
/* prototypes */
static void module_initialize (char *filename);
static void mod_load (module_info *mod, gboolean verbose);
static void mod_unload (module_info *mod, gboolean verbose);
#ifdef DUMP_DB
static void print_module_info (gpointer data, gpointer user_data);
#endif
static void browser_popdown_callback (GtkWidget *w, gpointer client_data);
static void browser_info_update (browser_st *st, module_info *mod);
static void browser_info_init (GtkWidget *table);
static void browser_select_callback (GtkWidget *widget, GtkWidget *child);
static void browser_load_unload_callback (GtkWidget *widget, gpointer data);
/**************************************************************/
/* Exported functions */
void
module_db_init (void)
{
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
#ifdef DUMP_DB
g_slist_foreach (modules, print_module_info, NULL);
#endif
}
GtkWidget *
module_db_browser_new (void)
{
GtkWidget *shell;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *listbox;
GtkWidget *list;
GtkWidget *list_item;
GSList *here;
module_info *info;
browser_st *st;
ActionAreaItem action_items[] =
{
{ N_("OK"), browser_popdown_callback, NULL, NULL }
};
shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (shell), "module_db_dialog", "Gimp");
gtk_window_set_title (GTK_WINDOW (shell), _("Module DB"));
hbox = gtk_hbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 1);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shell)->vbox), hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
listbox = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (hbox), listbox, TRUE, TRUE, 0);
gtk_widget_set_usize (listbox, 125, 100);
gtk_widget_show (listbox);
list = gtk_list_new ();
gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (listbox), list);
st = g_new0 (browser_st, 1);
here = modules;
while (here)
{
info = here->data;
here = g_slist_next (here);
if (!st->last_update)
st->last_update = info;
list_item = gtk_list_item_new_with_label (info->fullpath);
gtk_container_add (GTK_CONTAINER (list), list_item);
gtk_widget_show (list_item);
gtk_object_set_user_data (GTK_OBJECT (list_item), info);
}
gtk_widget_show (list);
vbox = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
st->table = gtk_table_new (2, NUM_INFO_LINES, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), st->table, TRUE, TRUE, 0);
gtk_widget_show (st->table);
st->button = gtk_button_new ();
gtk_box_pack_start (GTK_BOX (vbox), st->button, TRUE, TRUE, 0);
gtk_widget_show (st->button);
gtk_signal_connect (GTK_OBJECT (st->button), "clicked",
browser_load_unload_callback, st);
browser_info_init (st->table);
browser_info_update (st, modules->data);
gtk_object_set_user_data (GTK_OBJECT (list), st);
gtk_signal_connect (GTK_OBJECT (list), "select_child",
browser_select_callback, NULL);
action_items[0].user_data = shell;
build_action_area (GTK_DIALOG (shell),
action_items,
sizeof( action_items)/sizeof( ActionAreaItem),
0);
return shell;
}
/**************************************************************/
/* helper functions */
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
module_info *mod;
if (!valid_module_name (filename))
return;
mod = g_new0 (module_info, 1);
modules = g_slist_append (modules, mod);
mod->fullpath = g_strdup (filename);
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod_load (mod, TRUE);
}
static void
mod_load (module_info *mod, gboolean verbose)
{
gpointer symbol;
g_return_if_fail (mod->module == NULL);
mod->module = g_module_open (mod->fullpath, G_MODULE_BIND_LAZY);
if (!mod->module)
{
mod->state = ST_MODULE_ERROR;
if (mod->last_module_error)
g_free (mod->last_module_error);
mod->last_module_error = g_strdup (g_module_error ());
if (verbose)
g_warning (_("module load error: %s: %s"),
mod->fullpath, mod->last_module_error);
return;
}
/* find the module_init symbol */
if (!g_module_symbol (mod->module, "module_init", &symbol))
{
mod->state = ST_MODULE_ERROR;
if (mod->last_module_error)
g_free (mod->last_module_error);
mod->last_module_error = g_strdup (_("missing module_init() symbol"));
if (verbose)
g_warning (_("%s: module_init() symbol not found"), mod->fullpath);
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
return;
}
/* run module's initialisation */
mod->init = symbol;
mod->info = NULL;
if (mod->init (&mod->info) == GIMP_MODULE_UNLOAD)
{
mod->state = ST_LOAD_FAILED;
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
return;
}
/* module is now happy */
mod->state = ST_LOADED_OK;
/* do we have an unload function? */
if (g_module_symbol (mod->module, "module_unload", &symbol))
mod->unload = symbol;
else
mod->unload = NULL;
}
static void
mod_unload_completed_callback (void *data)
{
module_info *mod = data;
g_return_if_fail (mod->state == ST_UNLOAD_REQUESTED);
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
mod->state = ST_UNLOADED_OK;
}
static void
mod_unload (module_info *mod, gboolean verbose)
{
g_return_if_fail (mod->module != NULL);
g_return_if_fail (mod->unload != NULL);
if (mod->state == ST_UNLOAD_REQUESTED)
return;
mod->state = ST_UNLOAD_REQUESTED;
/* send the unload request */
mod->unload (mod->info->shutdown_data, mod_unload_completed_callback, mod);
}
#ifdef DUMP_DB
static void
print_module_info (gpointer data, gpointer user_data)
{
module_info *i = data;
printf ("\n%s: %s\n",
i->fullpath, statename[i->state]);
printf (" module:%p lasterr:%s init:%p unload:%p\n",
i->module, i->last_module_error? i->last_module_error : "NONE",
i->init, i->unload);
if (i->info)
{
printf (" shutdown_data: %p\n"
" purpose: %s\n"
" author: %s\n"
" version: %s\n"
" copyright: %s\n"
" date: %s\n",
i->info->shutdown_data,
i->info->purpose, i->info->author, i->info->version,
i->info->copyright, i->info->date);
}
}
#endif
/**************************************************************/
/* UI functions */
static void
browser_popdown_callback (GtkWidget *w, gpointer client_data)
{
gtk_widget_destroy (GTK_WIDGET (client_data));
}
static void
browser_info_update (browser_st *st, module_info *mod)
{
int i;
const char *text[NUM_INFO_LINES];
if (mod->info)
{
text[0] = mod->info->purpose;
text[1] = mod->info->author;
text[2] = mod->info->version;
text[3] = mod->info->copyright;
text[4] = mod->info->date;
}
else
{
text[0] = "--";
text[1] = "--";
text[2] = "--";
text[3] = "--";
text[4] = "--";
}
if (mod->state == ST_MODULE_ERROR && mod->last_module_error)
{
text[5] = g_malloc (strlen (statename[mod->state]) + 2 +
strlen (mod->last_module_error) + 2);
sprintf(text[5], "%s (%s)", statename[mod->state], mod->last_module_error);
}
else
{
text[5] = g_strdup (statename[mod->state]);
}
for (i=0; i < NUM_INFO_LINES; i++)
{
if (st->label[i])
gtk_container_remove (GTK_CONTAINER (st->table), st->label[i]);
st->label[i] = gtk_label_new (text[i]);
gtk_misc_set_alignment (GTK_MISC (st->label[i]), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (st->table), st->label[i], 1, 2, i, i+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
gtk_widget_show (st->label[i]);
}
g_free (text[5]);
/* work out what the button should do (if anything) */
switch (mod->state) {
case ST_MODULE_ERROR:
case ST_LOAD_FAILED:
case ST_UNLOADED_OK:
if (st->button_label)
gtk_container_remove (GTK_CONTAINER (st->button), st->button_label);
st->button_label = gtk_label_new (_("Load"));
gtk_widget_show (st->button_label);
gtk_container_add (GTK_CONTAINER (st->button), st->button_label);
gtk_widget_set_sensitive (GTK_WIDGET (st->button), TRUE);
break;
case ST_UNLOAD_REQUESTED:
gtk_widget_set_sensitive (GTK_WIDGET (st->button), FALSE);
break;
case ST_LOADED_OK:
if (st->button_label)
gtk_container_remove (GTK_CONTAINER (st->button), st->button_label);
st->button_label = gtk_label_new (_("Unload"));
gtk_widget_show (st->button_label);
gtk_container_add (GTK_CONTAINER (st->button), st->button_label);
gtk_widget_set_sensitive (GTK_WIDGET (st->button),
mod->unload? TRUE : FALSE);
break;
}
}
static void
browser_info_init (GtkWidget *table)
{
GtkWidget *label;
int i;
char *text[] = {
N_("Purpose: "),
N_("Author: "),
N_("Verson: "),
N_("Copyright: "),
N_("Date: "),
N_("State: ")
};
for (i=0; i < sizeof(text) / sizeof(char *); i++)
{
label = gtk_label_new (gettext (text[i]));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
gtk_widget_show (label);
}
}
static void
browser_select_callback (GtkWidget *widget, GtkWidget *child)
{
module_info *i;
browser_st *st;
i = gtk_object_get_user_data (GTK_OBJECT (child));
st = gtk_object_get_user_data (GTK_OBJECT (widget));
if (st->last_update == i)
return;
st->last_update = i;
browser_info_update (st, i);
}
static void
browser_load_unload_callback (GtkWidget *widget, gpointer data)
{
browser_st *st = data;
if (st->last_update->state == ST_LOADED_OK)
mod_unload (st->last_update, FALSE);
else
mod_load (st->last_update, FALSE);
browser_info_update (st, st->last_update);
}

View File

@ -0,0 +1,29 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* module_db.h (C) 1999 Austin Donnelly <austin@gimp.org>
*
* 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.
*/
#ifndef __MODULE_DB_H__
/* Load any modules we find on the module-path set in the gimprc */
void module_db_init (void);
GtkWidget *module_db_browser_new (void);
#endif /* __MODULE_DB_H__ */

View File

@ -147,6 +147,8 @@ color_notebook_new (int r,
{
label = gtk_label_new (info->name);
gtk_widget_show (label);
/* hide the frame, so it doesn't get selected by mistake */
gtk_widget_hide (csel->frame);
gtk_notebook_append_page (GTK_NOTEBOOK (cnp->notebook),
csel->frame, label);
}

View File

@ -57,6 +57,7 @@
#include "layers_dialog.h"
#include "layer_select.h"
#include "levels.h"
#include "module_db.h"
#include "palette.h"
#include "patterns.h"
#include "plug_in.h"
@ -1105,6 +1106,16 @@ tips_dialog_cmd_callback (GtkWidget *widget,
tips_dialog_create ();
}
void
dialogs_module_browser_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GtkWidget *w;
w = module_db_browser_new ();
gtk_widget_show (w);
}
/****************************************************/
/** LOCAL FUNCTIONS **/

View File

@ -95,5 +95,6 @@ void dialogs_device_status_cmd_callback (GtkWidget *, gpointer);
void dialogs_error_console_cmd_callback (GtkWidget *, gpointer);
void about_dialog_cmd_callback (GtkWidget *, gpointer);
void tips_dialog_cmd_callback (GtkWidget *, gpointer);
void dialogs_module_browser_cmd_callback (GtkWidget *, gpointer);
#endif /* __COMMANDS_H__ */

View File

@ -57,6 +57,7 @@
#include "layers_dialog.h"
#include "layer_select.h"
#include "levels.h"
#include "module_db.h"
#include "palette.h"
#include "patterns.h"
#include "plug_in.h"
@ -1105,6 +1106,16 @@ tips_dialog_cmd_callback (GtkWidget *widget,
tips_dialog_create ();
}
void
dialogs_module_browser_cmd_callback (GtkWidget *widget,
gpointer client_data)
{
GtkWidget *w;
w = module_db_browser_new ();
gtk_widget_show (w);
}
/****************************************************/
/** LOCAL FUNCTIONS **/

View File

@ -95,5 +95,6 @@ void dialogs_device_status_cmd_callback (GtkWidget *, gpointer);
void dialogs_error_console_cmd_callback (GtkWidget *, gpointer);
void about_dialog_cmd_callback (GtkWidget *, gpointer);
void tips_dialog_cmd_callback (GtkWidget *, gpointer);
void dialogs_module_browser_cmd_callback (GtkWidget *, gpointer);
#endif /* __COMMANDS_H__ */

View File

@ -62,6 +62,7 @@ static const GtkItemFactoryEntry toolbox_entries[] =
{ N_("/File/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
{ N_("/File/Dialogs/Document Index..."), NULL, raise_idea_callback, 0 },
{ N_("/File/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
{ N_("/File/Dialogs/Module Browser..."), NULL, dialogs_module_browser_cmd_callback, 0 },
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" },
};
static guint n_toolbox_entries = sizeof (toolbox_entries) / sizeof (toolbox_entries[0]);
@ -148,7 +149,6 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Image/Resize"), NULL, image_resize_cmd_callback, 0 },
{ N_("/Image/Scale"), NULL, image_scale_cmd_callback, 0 },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Layers/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
{ N_("/Layers/Raise Layer"), "<control>F", layers_raise_cmd_callback, 0 },
@ -191,7 +191,11 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
*/
{ N_("/Filters/"), NULL, NULL, 0 },
{ N_("/Tools/Toolbox"), NULL, toolbox_raise_callback, 0 },
{ N_("/Tools/Default Colors"), "D", tools_default_colors_cmd_callback, 0 },
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
{ N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Filters/Repeat last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
{ N_("/Filters/Re-show last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
{ N_("/Filters/---"), NULL, NULL, 0, "<Separator>" },

518
app/gui/module-browser.c Normal file
View File

@ -0,0 +1,518 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* module_db.c (C) 1999 Austin Donnelly <austin@gimp.org>
*
* 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.
*/
#include <stdio.h>
#include <string.h>
#include "appenv.h"
#include "module_db.h"
#include "gimprc.h"
#include "datafiles.h"
#include "actionarea.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmodule.h"
typedef enum {
ST_MODULE_ERROR, /* missing module_load function or other error */
ST_LOADED_OK, /* happy and running (normal state of affairs) */
ST_LOAD_FAILED, /* module_load returned GIMP_MODULE_UNLOAD */
ST_UNLOAD_REQUESTED, /* sent unload request, waiting for callback */
ST_UNLOADED_OK /* callback arrived, module not in memory anymore */
} module_state;
static const char * const statename[] = {
"ST_MODULE_ERROR",
"ST_LOADED_OK",
"ST_LOAD_FAILED",
"ST_UNLOAD_REQUESTED",
"ST_UNLOADED_OK"
};
/* one of these is kept per-module */
typedef struct {
gchar *fullpath; /* path to the module */
module_state state; /* what's happened to the module */
/* stuff from now on may be NULL depending on the state the module is in */
GimpModuleInfo *info; /* returned values from module_init */
GModule *module; /* handle on the module */
gchar *last_module_error;
GimpModuleInitFunc *init;
GimpModuleUnloadFunc *unload;
} module_info;
#define NUM_INFO_LINES 6
typedef struct {
GtkWidget *table;
GtkWidget *label[NUM_INFO_LINES];
GtkWidget *button_label;
module_info *last_update;
GtkWidget *button;
} browser_st;
/* global list of module_info */
static GSList *modules = NULL;
/*#define DUMP_DB*/
/* prototypes */
static void module_initialize (char *filename);
static void mod_load (module_info *mod, gboolean verbose);
static void mod_unload (module_info *mod, gboolean verbose);
#ifdef DUMP_DB
static void print_module_info (gpointer data, gpointer user_data);
#endif
static void browser_popdown_callback (GtkWidget *w, gpointer client_data);
static void browser_info_update (browser_st *st, module_info *mod);
static void browser_info_init (GtkWidget *table);
static void browser_select_callback (GtkWidget *widget, GtkWidget *child);
static void browser_load_unload_callback (GtkWidget *widget, gpointer data);
/**************************************************************/
/* Exported functions */
void
module_db_init (void)
{
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
#ifdef DUMP_DB
g_slist_foreach (modules, print_module_info, NULL);
#endif
}
GtkWidget *
module_db_browser_new (void)
{
GtkWidget *shell;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *listbox;
GtkWidget *list;
GtkWidget *list_item;
GSList *here;
module_info *info;
browser_st *st;
ActionAreaItem action_items[] =
{
{ N_("OK"), browser_popdown_callback, NULL, NULL }
};
shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (shell), "module_db_dialog", "Gimp");
gtk_window_set_title (GTK_WINDOW (shell), _("Module DB"));
hbox = gtk_hbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 1);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shell)->vbox), hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
listbox = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (hbox), listbox, TRUE, TRUE, 0);
gtk_widget_set_usize (listbox, 125, 100);
gtk_widget_show (listbox);
list = gtk_list_new ();
gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (listbox), list);
st = g_new0 (browser_st, 1);
here = modules;
while (here)
{
info = here->data;
here = g_slist_next (here);
if (!st->last_update)
st->last_update = info;
list_item = gtk_list_item_new_with_label (info->fullpath);
gtk_container_add (GTK_CONTAINER (list), list_item);
gtk_widget_show (list_item);
gtk_object_set_user_data (GTK_OBJECT (list_item), info);
}
gtk_widget_show (list);
vbox = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
st->table = gtk_table_new (2, NUM_INFO_LINES, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), st->table, TRUE, TRUE, 0);
gtk_widget_show (st->table);
st->button = gtk_button_new ();
gtk_box_pack_start (GTK_BOX (vbox), st->button, TRUE, TRUE, 0);
gtk_widget_show (st->button);
gtk_signal_connect (GTK_OBJECT (st->button), "clicked",
browser_load_unload_callback, st);
browser_info_init (st->table);
browser_info_update (st, modules->data);
gtk_object_set_user_data (GTK_OBJECT (list), st);
gtk_signal_connect (GTK_OBJECT (list), "select_child",
browser_select_callback, NULL);
action_items[0].user_data = shell;
build_action_area (GTK_DIALOG (shell),
action_items,
sizeof( action_items)/sizeof( ActionAreaItem),
0);
return shell;
}
/**************************************************************/
/* helper functions */
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
module_info *mod;
if (!valid_module_name (filename))
return;
mod = g_new0 (module_info, 1);
modules = g_slist_append (modules, mod);
mod->fullpath = g_strdup (filename);
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod_load (mod, TRUE);
}
static void
mod_load (module_info *mod, gboolean verbose)
{
gpointer symbol;
g_return_if_fail (mod->module == NULL);
mod->module = g_module_open (mod->fullpath, G_MODULE_BIND_LAZY);
if (!mod->module)
{
mod->state = ST_MODULE_ERROR;
if (mod->last_module_error)
g_free (mod->last_module_error);
mod->last_module_error = g_strdup (g_module_error ());
if (verbose)
g_warning (_("module load error: %s: %s"),
mod->fullpath, mod->last_module_error);
return;
}
/* find the module_init symbol */
if (!g_module_symbol (mod->module, "module_init", &symbol))
{
mod->state = ST_MODULE_ERROR;
if (mod->last_module_error)
g_free (mod->last_module_error);
mod->last_module_error = g_strdup (_("missing module_init() symbol"));
if (verbose)
g_warning (_("%s: module_init() symbol not found"), mod->fullpath);
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
return;
}
/* run module's initialisation */
mod->init = symbol;
mod->info = NULL;
if (mod->init (&mod->info) == GIMP_MODULE_UNLOAD)
{
mod->state = ST_LOAD_FAILED;
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
return;
}
/* module is now happy */
mod->state = ST_LOADED_OK;
/* do we have an unload function? */
if (g_module_symbol (mod->module, "module_unload", &symbol))
mod->unload = symbol;
else
mod->unload = NULL;
}
static void
mod_unload_completed_callback (void *data)
{
module_info *mod = data;
g_return_if_fail (mod->state == ST_UNLOAD_REQUESTED);
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
mod->state = ST_UNLOADED_OK;
}
static void
mod_unload (module_info *mod, gboolean verbose)
{
g_return_if_fail (mod->module != NULL);
g_return_if_fail (mod->unload != NULL);
if (mod->state == ST_UNLOAD_REQUESTED)
return;
mod->state = ST_UNLOAD_REQUESTED;
/* send the unload request */
mod->unload (mod->info->shutdown_data, mod_unload_completed_callback, mod);
}
#ifdef DUMP_DB
static void
print_module_info (gpointer data, gpointer user_data)
{
module_info *i = data;
printf ("\n%s: %s\n",
i->fullpath, statename[i->state]);
printf (" module:%p lasterr:%s init:%p unload:%p\n",
i->module, i->last_module_error? i->last_module_error : "NONE",
i->init, i->unload);
if (i->info)
{
printf (" shutdown_data: %p\n"
" purpose: %s\n"
" author: %s\n"
" version: %s\n"
" copyright: %s\n"
" date: %s\n",
i->info->shutdown_data,
i->info->purpose, i->info->author, i->info->version,
i->info->copyright, i->info->date);
}
}
#endif
/**************************************************************/
/* UI functions */
static void
browser_popdown_callback (GtkWidget *w, gpointer client_data)
{
gtk_widget_destroy (GTK_WIDGET (client_data));
}
static void
browser_info_update (browser_st *st, module_info *mod)
{
int i;
const char *text[NUM_INFO_LINES];
if (mod->info)
{
text[0] = mod->info->purpose;
text[1] = mod->info->author;
text[2] = mod->info->version;
text[3] = mod->info->copyright;
text[4] = mod->info->date;
}
else
{
text[0] = "--";
text[1] = "--";
text[2] = "--";
text[3] = "--";
text[4] = "--";
}
if (mod->state == ST_MODULE_ERROR && mod->last_module_error)
{
text[5] = g_malloc (strlen (statename[mod->state]) + 2 +
strlen (mod->last_module_error) + 2);
sprintf(text[5], "%s (%s)", statename[mod->state], mod->last_module_error);
}
else
{
text[5] = g_strdup (statename[mod->state]);
}
for (i=0; i < NUM_INFO_LINES; i++)
{
if (st->label[i])
gtk_container_remove (GTK_CONTAINER (st->table), st->label[i]);
st->label[i] = gtk_label_new (text[i]);
gtk_misc_set_alignment (GTK_MISC (st->label[i]), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (st->table), st->label[i], 1, 2, i, i+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
gtk_widget_show (st->label[i]);
}
g_free (text[5]);
/* work out what the button should do (if anything) */
switch (mod->state) {
case ST_MODULE_ERROR:
case ST_LOAD_FAILED:
case ST_UNLOADED_OK:
if (st->button_label)
gtk_container_remove (GTK_CONTAINER (st->button), st->button_label);
st->button_label = gtk_label_new (_("Load"));
gtk_widget_show (st->button_label);
gtk_container_add (GTK_CONTAINER (st->button), st->button_label);
gtk_widget_set_sensitive (GTK_WIDGET (st->button), TRUE);
break;
case ST_UNLOAD_REQUESTED:
gtk_widget_set_sensitive (GTK_WIDGET (st->button), FALSE);
break;
case ST_LOADED_OK:
if (st->button_label)
gtk_container_remove (GTK_CONTAINER (st->button), st->button_label);
st->button_label = gtk_label_new (_("Unload"));
gtk_widget_show (st->button_label);
gtk_container_add (GTK_CONTAINER (st->button), st->button_label);
gtk_widget_set_sensitive (GTK_WIDGET (st->button),
mod->unload? TRUE : FALSE);
break;
}
}
static void
browser_info_init (GtkWidget *table)
{
GtkWidget *label;
int i;
char *text[] = {
N_("Purpose: "),
N_("Author: "),
N_("Verson: "),
N_("Copyright: "),
N_("Date: "),
N_("State: ")
};
for (i=0; i < sizeof(text) / sizeof(char *); i++)
{
label = gtk_label_new (gettext (text[i]));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
gtk_widget_show (label);
}
}
static void
browser_select_callback (GtkWidget *widget, GtkWidget *child)
{
module_info *i;
browser_st *st;
i = gtk_object_get_user_data (GTK_OBJECT (child));
st = gtk_object_get_user_data (GTK_OBJECT (widget));
if (st->last_update == i)
return;
st->last_update = i;
browser_info_update (st, i);
}
static void
browser_load_unload_callback (GtkWidget *widget, gpointer data)
{
browser_st *st = data;
if (st->last_update->state == ST_LOADED_OK)
mod_unload (st->last_update, FALSE);
else
mod_load (st->last_update, FALSE);
browser_info_update (st, st->last_update);
}

29
app/gui/module-browser.h Normal file
View File

@ -0,0 +1,29 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* module_db.h (C) 1999 Austin Donnelly <austin@gimp.org>
*
* 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.
*/
#ifndef __MODULE_DB_H__
/* Load any modules we find on the module-path set in the gimprc */
void module_db_init (void);
GtkWidget *module_db_browser_new (void);
#endif /* __MODULE_DB_H__ */

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -62,6 +62,7 @@ static const GtkItemFactoryEntry toolbox_entries[] =
{ N_("/File/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
{ N_("/File/Dialogs/Document Index..."), NULL, raise_idea_callback, 0 },
{ N_("/File/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
{ N_("/File/Dialogs/Module Browser..."), NULL, dialogs_module_browser_cmd_callback, 0 },
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" },
};
static guint n_toolbox_entries = sizeof (toolbox_entries) / sizeof (toolbox_entries[0]);
@ -148,7 +149,6 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Image/Resize"), NULL, image_resize_cmd_callback, 0 },
{ N_("/Image/Scale"), NULL, image_scale_cmd_callback, 0 },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Layers/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
{ N_("/Layers/Raise Layer"), "<control>F", layers_raise_cmd_callback, 0 },
@ -191,7 +191,11 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
*/
{ N_("/Filters/"), NULL, NULL, 0 },
{ N_("/Tools/Toolbox"), NULL, toolbox_raise_callback, 0 },
{ N_("/Tools/Default Colors"), "D", tools_default_colors_cmd_callback, 0 },
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
{ N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Filters/Repeat last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
{ N_("/Filters/Re-show last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
{ N_("/Filters/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -62,6 +62,7 @@ static const GtkItemFactoryEntry toolbox_entries[] =
{ N_("/File/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
{ N_("/File/Dialogs/Document Index..."), NULL, raise_idea_callback, 0 },
{ N_("/File/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
{ N_("/File/Dialogs/Module Browser..."), NULL, dialogs_module_browser_cmd_callback, 0 },
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" },
};
static guint n_toolbox_entries = sizeof (toolbox_entries) / sizeof (toolbox_entries[0]);
@ -148,7 +149,6 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Image/Resize"), NULL, image_resize_cmd_callback, 0 },
{ N_("/Image/Scale"), NULL, image_scale_cmd_callback, 0 },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Layers/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
{ N_("/Layers/Raise Layer"), "<control>F", layers_raise_cmd_callback, 0 },
@ -191,7 +191,11 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
*/
{ N_("/Filters/"), NULL, NULL, 0 },
{ N_("/Tools/Toolbox"), NULL, toolbox_raise_callback, 0 },
{ N_("/Tools/Default Colors"), "D", tools_default_colors_cmd_callback, 0 },
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
{ N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Filters/Repeat last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
{ N_("/Filters/Re-show last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
{ N_("/Filters/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

518
app/module_db.c Normal file
View File

@ -0,0 +1,518 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* module_db.c (C) 1999 Austin Donnelly <austin@gimp.org>
*
* 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.
*/
#include <stdio.h>
#include <string.h>
#include "appenv.h"
#include "module_db.h"
#include "gimprc.h"
#include "datafiles.h"
#include "actionarea.h"
#include "libgimp/gimpintl.h"
#include "libgimp/gimpmodule.h"
typedef enum {
ST_MODULE_ERROR, /* missing module_load function or other error */
ST_LOADED_OK, /* happy and running (normal state of affairs) */
ST_LOAD_FAILED, /* module_load returned GIMP_MODULE_UNLOAD */
ST_UNLOAD_REQUESTED, /* sent unload request, waiting for callback */
ST_UNLOADED_OK /* callback arrived, module not in memory anymore */
} module_state;
static const char * const statename[] = {
"ST_MODULE_ERROR",
"ST_LOADED_OK",
"ST_LOAD_FAILED",
"ST_UNLOAD_REQUESTED",
"ST_UNLOADED_OK"
};
/* one of these is kept per-module */
typedef struct {
gchar *fullpath; /* path to the module */
module_state state; /* what's happened to the module */
/* stuff from now on may be NULL depending on the state the module is in */
GimpModuleInfo *info; /* returned values from module_init */
GModule *module; /* handle on the module */
gchar *last_module_error;
GimpModuleInitFunc *init;
GimpModuleUnloadFunc *unload;
} module_info;
#define NUM_INFO_LINES 6
typedef struct {
GtkWidget *table;
GtkWidget *label[NUM_INFO_LINES];
GtkWidget *button_label;
module_info *last_update;
GtkWidget *button;
} browser_st;
/* global list of module_info */
static GSList *modules = NULL;
/*#define DUMP_DB*/
/* prototypes */
static void module_initialize (char *filename);
static void mod_load (module_info *mod, gboolean verbose);
static void mod_unload (module_info *mod, gboolean verbose);
#ifdef DUMP_DB
static void print_module_info (gpointer data, gpointer user_data);
#endif
static void browser_popdown_callback (GtkWidget *w, gpointer client_data);
static void browser_info_update (browser_st *st, module_info *mod);
static void browser_info_init (GtkWidget *table);
static void browser_select_callback (GtkWidget *widget, GtkWidget *child);
static void browser_load_unload_callback (GtkWidget *widget, gpointer data);
/**************************************************************/
/* Exported functions */
void
module_db_init (void)
{
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
#ifdef DUMP_DB
g_slist_foreach (modules, print_module_info, NULL);
#endif
}
GtkWidget *
module_db_browser_new (void)
{
GtkWidget *shell;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *listbox;
GtkWidget *list;
GtkWidget *list_item;
GSList *here;
module_info *info;
browser_st *st;
ActionAreaItem action_items[] =
{
{ N_("OK"), browser_popdown_callback, NULL, NULL }
};
shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (shell), "module_db_dialog", "Gimp");
gtk_window_set_title (GTK_WINDOW (shell), _("Module DB"));
hbox = gtk_hbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 1);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shell)->vbox), hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
listbox = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (hbox), listbox, TRUE, TRUE, 0);
gtk_widget_set_usize (listbox, 125, 100);
gtk_widget_show (listbox);
list = gtk_list_new ();
gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (listbox), list);
st = g_new0 (browser_st, 1);
here = modules;
while (here)
{
info = here->data;
here = g_slist_next (here);
if (!st->last_update)
st->last_update = info;
list_item = gtk_list_item_new_with_label (info->fullpath);
gtk_container_add (GTK_CONTAINER (list), list_item);
gtk_widget_show (list_item);
gtk_object_set_user_data (GTK_OBJECT (list_item), info);
}
gtk_widget_show (list);
vbox = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
st->table = gtk_table_new (2, NUM_INFO_LINES, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), st->table, TRUE, TRUE, 0);
gtk_widget_show (st->table);
st->button = gtk_button_new ();
gtk_box_pack_start (GTK_BOX (vbox), st->button, TRUE, TRUE, 0);
gtk_widget_show (st->button);
gtk_signal_connect (GTK_OBJECT (st->button), "clicked",
browser_load_unload_callback, st);
browser_info_init (st->table);
browser_info_update (st, modules->data);
gtk_object_set_user_data (GTK_OBJECT (list), st);
gtk_signal_connect (GTK_OBJECT (list), "select_child",
browser_select_callback, NULL);
action_items[0].user_data = shell;
build_action_area (GTK_DIALOG (shell),
action_items,
sizeof( action_items)/sizeof( ActionAreaItem),
0);
return shell;
}
/**************************************************************/
/* helper functions */
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
module_info *mod;
if (!valid_module_name (filename))
return;
mod = g_new0 (module_info, 1);
modules = g_slist_append (modules, mod);
mod->fullpath = g_strdup (filename);
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod_load (mod, TRUE);
}
static void
mod_load (module_info *mod, gboolean verbose)
{
gpointer symbol;
g_return_if_fail (mod->module == NULL);
mod->module = g_module_open (mod->fullpath, G_MODULE_BIND_LAZY);
if (!mod->module)
{
mod->state = ST_MODULE_ERROR;
if (mod->last_module_error)
g_free (mod->last_module_error);
mod->last_module_error = g_strdup (g_module_error ());
if (verbose)
g_warning (_("module load error: %s: %s"),
mod->fullpath, mod->last_module_error);
return;
}
/* find the module_init symbol */
if (!g_module_symbol (mod->module, "module_init", &symbol))
{
mod->state = ST_MODULE_ERROR;
if (mod->last_module_error)
g_free (mod->last_module_error);
mod->last_module_error = g_strdup (_("missing module_init() symbol"));
if (verbose)
g_warning (_("%s: module_init() symbol not found"), mod->fullpath);
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
return;
}
/* run module's initialisation */
mod->init = symbol;
mod->info = NULL;
if (mod->init (&mod->info) == GIMP_MODULE_UNLOAD)
{
mod->state = ST_LOAD_FAILED;
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
return;
}
/* module is now happy */
mod->state = ST_LOADED_OK;
/* do we have an unload function? */
if (g_module_symbol (mod->module, "module_unload", &symbol))
mod->unload = symbol;
else
mod->unload = NULL;
}
static void
mod_unload_completed_callback (void *data)
{
module_info *mod = data;
g_return_if_fail (mod->state == ST_UNLOAD_REQUESTED);
g_module_close (mod->module);
mod->module = NULL;
mod->info = NULL;
mod->state = ST_UNLOADED_OK;
}
static void
mod_unload (module_info *mod, gboolean verbose)
{
g_return_if_fail (mod->module != NULL);
g_return_if_fail (mod->unload != NULL);
if (mod->state == ST_UNLOAD_REQUESTED)
return;
mod->state = ST_UNLOAD_REQUESTED;
/* send the unload request */
mod->unload (mod->info->shutdown_data, mod_unload_completed_callback, mod);
}
#ifdef DUMP_DB
static void
print_module_info (gpointer data, gpointer user_data)
{
module_info *i = data;
printf ("\n%s: %s\n",
i->fullpath, statename[i->state]);
printf (" module:%p lasterr:%s init:%p unload:%p\n",
i->module, i->last_module_error? i->last_module_error : "NONE",
i->init, i->unload);
if (i->info)
{
printf (" shutdown_data: %p\n"
" purpose: %s\n"
" author: %s\n"
" version: %s\n"
" copyright: %s\n"
" date: %s\n",
i->info->shutdown_data,
i->info->purpose, i->info->author, i->info->version,
i->info->copyright, i->info->date);
}
}
#endif
/**************************************************************/
/* UI functions */
static void
browser_popdown_callback (GtkWidget *w, gpointer client_data)
{
gtk_widget_destroy (GTK_WIDGET (client_data));
}
static void
browser_info_update (browser_st *st, module_info *mod)
{
int i;
const char *text[NUM_INFO_LINES];
if (mod->info)
{
text[0] = mod->info->purpose;
text[1] = mod->info->author;
text[2] = mod->info->version;
text[3] = mod->info->copyright;
text[4] = mod->info->date;
}
else
{
text[0] = "--";
text[1] = "--";
text[2] = "--";
text[3] = "--";
text[4] = "--";
}
if (mod->state == ST_MODULE_ERROR && mod->last_module_error)
{
text[5] = g_malloc (strlen (statename[mod->state]) + 2 +
strlen (mod->last_module_error) + 2);
sprintf(text[5], "%s (%s)", statename[mod->state], mod->last_module_error);
}
else
{
text[5] = g_strdup (statename[mod->state]);
}
for (i=0; i < NUM_INFO_LINES; i++)
{
if (st->label[i])
gtk_container_remove (GTK_CONTAINER (st->table), st->label[i]);
st->label[i] = gtk_label_new (text[i]);
gtk_misc_set_alignment (GTK_MISC (st->label[i]), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (st->table), st->label[i], 1, 2, i, i+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
gtk_widget_show (st->label[i]);
}
g_free (text[5]);
/* work out what the button should do (if anything) */
switch (mod->state) {
case ST_MODULE_ERROR:
case ST_LOAD_FAILED:
case ST_UNLOADED_OK:
if (st->button_label)
gtk_container_remove (GTK_CONTAINER (st->button), st->button_label);
st->button_label = gtk_label_new (_("Load"));
gtk_widget_show (st->button_label);
gtk_container_add (GTK_CONTAINER (st->button), st->button_label);
gtk_widget_set_sensitive (GTK_WIDGET (st->button), TRUE);
break;
case ST_UNLOAD_REQUESTED:
gtk_widget_set_sensitive (GTK_WIDGET (st->button), FALSE);
break;
case ST_LOADED_OK:
if (st->button_label)
gtk_container_remove (GTK_CONTAINER (st->button), st->button_label);
st->button_label = gtk_label_new (_("Unload"));
gtk_widget_show (st->button_label);
gtk_container_add (GTK_CONTAINER (st->button), st->button_label);
gtk_widget_set_sensitive (GTK_WIDGET (st->button),
mod->unload? TRUE : FALSE);
break;
}
}
static void
browser_info_init (GtkWidget *table)
{
GtkWidget *label;
int i;
char *text[] = {
N_("Purpose: "),
N_("Author: "),
N_("Verson: "),
N_("Copyright: "),
N_("Date: "),
N_("State: ")
};
for (i=0; i < sizeof(text) / sizeof(char *); i++)
{
label = gtk_label_new (gettext (text[i]));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i+1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
gtk_widget_show (label);
}
}
static void
browser_select_callback (GtkWidget *widget, GtkWidget *child)
{
module_info *i;
browser_st *st;
i = gtk_object_get_user_data (GTK_OBJECT (child));
st = gtk_object_get_user_data (GTK_OBJECT (widget));
if (st->last_update == i)
return;
st->last_update = i;
browser_info_update (st, i);
}
static void
browser_load_unload_callback (GtkWidget *widget, gpointer data)
{
browser_st *st = data;
if (st->last_update->state == ST_LOADED_OK)
mod_unload (st->last_update, FALSE);
else
mod_load (st->last_update, FALSE);
browser_info_update (st, st->last_update);
}

29
app/module_db.h Normal file
View File

@ -0,0 +1,29 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* module_db.h (C) 1999 Austin Donnelly <austin@gimp.org>
*
* 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.
*/
#ifndef __MODULE_DB_H__
/* Load any modules we find on the module-path set in the gimprc */
void module_db_init (void);
GtkWidget *module_db_browser_new (void);
#endif /* __MODULE_DB_H__ */

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -30,7 +30,6 @@
#include <unistd.h>
#include "libgimp/parasite.h"
#include "libgimp/parasiteP.h" /* ick */
#include "libgimp/gimpmodule.h"
#ifdef HAVE_IPC_H
#include <sys/ipc.h>
@ -137,7 +136,6 @@ static Argument* message_handler_set_invoker (Argument *args);
static Argument* plugin_temp_PDB_name_invoker (Argument *args);
static void module_initialize (char *filename);
static GSList *plug_in_defs = NULL;
@ -484,76 +482,9 @@ plug_in_init ()
g_slist_free (plug_in_defs);
/* Load and initialize gimp modules */
if (g_module_supported ())
datafiles_read_directories (module_path,
module_initialize, 0 /* no flags */);
}
/* name must be of the form lib*.so */
/* TODO: need support for WIN32-style dll names. Maybe this function
* should live in libgmodule? */
static gboolean
valid_module_name (const char *filename)
{
const char *basename;
int len;
basename = strrchr (filename, '/');
if (basename)
basename++;
else
basename = filename;
len = strlen (basename);
if (len < 3 + 1 + 3)
return FALSE;
if (strncmp (basename, "lib", 3))
return FALSE;
if (strcmp (basename + len - 3, ".so"))
return FALSE;
return TRUE;
}
static void
module_initialize (char *filename)
{
GModule *mod;
GimpModuleInitFunc init;
gpointer symbol;
if (!valid_module_name (filename))
return;
if ((be_verbose == TRUE) || (no_splash == TRUE))
g_print (_("load module: \"%s\"\n"), filename);
mod = g_module_open (filename, G_MODULE_BIND_LAZY);
if (!mod)
{
g_warning (_("module load error: %s: %s"), filename, g_module_error ());
return;
}
if (g_module_symbol (mod, "module_init", &symbol))
{
init = symbol;
if (init () == GIMP_MODULE_UNLOAD)
g_module_close (mod);
}
else
{
g_warning (_("%s: module_init() symbol not found"), filename);
g_module_close (mod);
}
}
void
plug_in_kill ()

View File

@ -147,6 +147,8 @@ color_notebook_new (int r,
{
label = gtk_label_new (info->name);
gtk_widget_show (label);
/* hide the frame, so it doesn't get selected by mistake */
gtk_widget_hide (csel->frame);
gtk_notebook_append_page (GTK_NOTEBOOK (cnp->notebook),
csel->frame, label);
}

View File

@ -62,6 +62,7 @@ static const GtkItemFactoryEntry toolbox_entries[] =
{ N_("/File/Dialogs/Device Status..."), NULL, dialogs_device_status_cmd_callback, 0 },
{ N_("/File/Dialogs/Document Index..."), NULL, raise_idea_callback, 0 },
{ N_("/File/Dialogs/Error Console..."), NULL, dialogs_error_console_cmd_callback, 0 },
{ N_("/File/Dialogs/Module Browser..."), NULL, dialogs_module_browser_cmd_callback, 0 },
{ N_("/File/---"), NULL, NULL, 0, "<Separator>" },
};
static guint n_toolbox_entries = sizeof (toolbox_entries) / sizeof (toolbox_entries[0]);
@ -148,7 +149,6 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Image/Resize"), NULL, image_resize_cmd_callback, 0 },
{ N_("/Image/Scale"), NULL, image_scale_cmd_callback, 0 },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Image/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Layers/Layers & Channels..."), "<control>L", dialogs_lc_cmd_callback, 0 },
{ N_("/Layers/Raise Layer"), "<control>F", layers_raise_cmd_callback, 0 },
@ -191,7 +191,11 @@ static const GtkItemFactoryEntry image_entries[] =
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
*/
{ N_("/Filters/"), NULL, NULL, 0 },
{ N_("/Tools/Toolbox"), NULL, toolbox_raise_callback, 0 },
{ N_("/Tools/Default Colors"), "D", tools_default_colors_cmd_callback, 0 },
{ N_("/Tools/Swap Colors"), "X", tools_swap_colors_cmd_callback, 0 },
{ N_("/Tools/---"), NULL, NULL, 0, "<Separator>" },
{ N_("/Filters/Repeat last"), "<alt>F", filters_repeat_cmd_callback, 0x0 },
{ N_("/Filters/Re-show last"), "<alt><shift>F", filters_repeat_cmd_callback, 0x1 },
{ N_("/Filters/---"), NULL, NULL, 0, "<Separator>" },

View File

@ -30,15 +30,54 @@ typedef enum {
} GimpModuleStatus;
typedef struct {
void *shutdown_data;
const char *purpose;
const char *author;
const char *version;
const char *copyright;
const char *date;
} GimpModuleInfo;
/* GIMP modules should G_MODULE_EXPORT a function named "module_init"
* of the following type: */
typedef GimpModuleStatus (*GimpModuleInitFunc) (void);
typedef GimpModuleStatus (GimpModuleInitFunc) (GimpModuleInfo **);
GimpModuleInitFunc module_init;
/* This function is called by the GIMP at startup, and should return
* either GIMP_MODULE_OK if it sucessfully initialised or
* GIMP_MODULE_UNLOAD if the module failed to hook whatever functions
* it wanted. GIMP_MODULE_UNLOAD causes the module to be closed, so
* the module must not have registered any internal functions or given
* out pointers to its data to anyone. */
* out pointers to its data to anyone.
*
* If the module returns GIMP_MODULE_OK, it should also return a
* GimpModuleInfo structure describing itself.
*/
/* If GIMP modules want to allow themselves to be unloaded, they
* should G_MODULE_EXPORT a function named "module_unload" with the
* following type: */
typedef void (GimpModuleUnloadFunc) (void *shutdown_data,
void (*completed_cb)(void *),
void *completed_data);
GimpModuleUnloadFunc module_unload;
/* GIMP calls this unload request function to ask a module to
* prepare itself to be unloaded. It is called with the value of
* shutdown_data supplied in the GimpModuleInfo struct. The module
* should ensure that none of its code or data are being used, and
* then call the supplied "completed_cb" callback function with the
* data provided. Typically the shutdown request function will queue
* de-registration activities then return. Only when the
* de-registration has finished should the completed_cb be invoked. */
#endif /* __GIMPMODULE_H__ */

View File

@ -8,7 +8,9 @@ INCLUDES = \
$(GTK_CFLAGS) \
-I$(includedir)
module_LTLIBRARIES = libcolorsel_gtk.la
module_LTLIBRARIES = libcolorsel_gtk.la libcolorsel_triangle.la
libcolorsel_gtk_la_SOURCES = colorsel_gtk.c
libcolorsel_triangle_la_SOURCES = colorsel_triangle.c

View File

@ -40,18 +40,47 @@ static GimpColorSelectorMethods methods =
colorsel_gtk_setcolor
};
static GimpModuleInfo info = {
NULL,
"GTK colour selector as a pluggable colour selector",
"Austin Donnelly <austin@gimp.org>",
"v0.02",
"(c) 1999, released under the GPL",
"17 Jan 1999"
};
/* globaly exported init function */
G_MODULE_EXPORT GimpModuleStatus
module_init (void)
module_init (GimpModuleInfo **inforet)
{
if (gimp_color_selector_register ("GTK", &methods))
GimpColorSelectorID id;
id = gimp_color_selector_register ("GTK", &methods);
if (id)
{
info.shutdown_data = id;
*inforet = &info;
return GIMP_MODULE_OK;
}
else
{
return GIMP_MODULE_UNLOAD;
}
}
G_MODULE_EXPORT void
module_unload (void *shutdown_data,
void (*completed_cb)(void *),
void *completed_data)
{
gimp_color_selector_unregister (shutdown_data, completed_cb, completed_data);
}
/**************************************************************/
/* GTK colour selector methods */

665
modules/colorsel_triangle.c Normal file
View File

@ -0,0 +1,665 @@
/*
* colorsel_triangle module (C) 1999 Simon Budig <Simon.Budig@unix-ag.org>
* http://www.home.unix-ag.org/simon/gimp/colorsel.html
*
* 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.
*
* Ported to loadable colour selector interface by Austin Donnelly
* <austin@gimp.org>
*
*/
#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <libgimp/color_selector.h>
#include <libgimp/gimpmodule.h>
#include <math.h>
/* prototypes */
static GtkWidget * colorsel_triangle_new (int, int, int,
GimpColorSelector_Callback, void *,
void **);
static void colorsel_triangle_free (void *);
static void colorsel_triangle_setcolor (void *, int, int, int, int);
/* local methods */
static GimpColorSelectorMethods methods =
{
colorsel_triangle_new,
colorsel_triangle_free,
colorsel_triangle_setcolor
};
static GimpModuleInfo info = {
NULL /* no shutdown data needed */,
"Painter-style colour selector as a pluggable colour selector",
"Simon Budig <Simon.Budig@unix-ag.org>",
"v0.01",
"(c) 1999, released under the GPL",
"17 Jan 1999"
};
#define COLORWHEELRADIUS 100
#define COLORTRIANGLERADIUS 80
#define PREVIEWSIZE (2*COLORWHEELRADIUS+1)
#define INTENSITY(r,g,b) (r * 0.30 + g * 0.59 + b * 0.11 + 0.001)
#define BGCOLOR 180
#define PREVIEW_MASK GDK_EXPOSURE_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON_MOTION_MASK
typedef enum {
HUE = 0,
SATURATION,
VALUE,
RED,
GREEN,
BLUE,
HUE_SATURATION,
HUE_VALUE,
SATURATION_VALUE,
RED_GREEN,
RED_BLUE,
GREEN_BLUE
} ColorSelectFillType;
typedef struct _ColorSelect _ColorSelect, *ColorSelectP;
struct _ColorSelect {
gint values[6];
gfloat oldsat;
gfloat oldval;
gint mode;
GtkWidget *preview;
GimpColorSelector_Callback callback;
void *data;
};
static GtkWidget * create_color_preview (ColorSelectP);
static void color_select_update_rgb_values (ColorSelectP);
static void update_color_preview (ColorSelectP, GtkWidget *, gint);
static void color_select_update_hsv_values (ColorSelectP);
/*************************************************************/
/* globaly exported init function */
G_MODULE_EXPORT GimpModuleStatus
module_init (GimpModuleInfo **inforet)
{
if (gimp_color_selector_register ("Triangle", &methods))
{
*inforet = &info;
return GIMP_MODULE_OK;
}
else
{
return GIMP_MODULE_UNLOAD;
}
}
/*************************************************************/
/* methods */
static GtkWidget * colorsel_triangle_new (int r, int g, int b,
GimpColorSelector_Callback callback,
void *callback_data,
/* RETURNS: */
void **selector_data)
{
ColorSelectP coldata;
GtkWidget *frame;
coldata = g_malloc (sizeof (_ColorSelect));
coldata->values[RED] = r;
coldata->values[GREEN] = g;
coldata->values[BLUE] = b;
color_select_update_hsv_values(coldata);
coldata->oldsat = 0;
coldata->oldval = 0;
coldata->mode = 0;
coldata->callback = callback;
coldata->data = callback_data;
/* gtk_rc_parse ("colorselrc"); */
frame = create_color_preview (coldata);
coldata->preview = frame;
*selector_data = coldata;
return frame;
}
static void
colorsel_triangle_free (void *selector_data)
{
/* anything else needed to go? */
g_free (selector_data);
}
static void
colorsel_triangle_setcolor (void *selector_data, int r, int g, int b,
int set_current)
{
ColorSelectP coldata;
coldata = selector_data;
coldata->values[RED] = r;
coldata->values[GREEN] = g;
coldata->values[BLUE] = b;
color_select_update_hsv_values(coldata);
update_color_preview(coldata, coldata->preview, 1);
}
/*************************************************************/
/* helper functions */
/* Conversion hsv->rgb */
static void color_hsv_to_rgb (gfloat hue, gfloat sat, gfloat val, guchar* red, guchar *green, guchar *blue) {
gfloat f, p, q, t;
if (sat == 0) {
*red = val * 255;
*green = val * 255;
*blue = val * 255;
} else {
while (hue < 0)
hue += 360;
while (hue >= 360)
hue -= 360;
hue /= 60;
f = hue - (int) hue;
p = val * (1 - sat);
q = val * (1 - (sat * f));
t = val * (1 - (sat * (1 - f)));
switch ((int) hue) {
case 0:
*red = val * 255;
*green = t * 255;
*blue = p * 255;
break;
case 1:
*red = q * 255;
*green = val * 255;
*blue = p * 255;
break;
case 2:
*red = p * 255;
*green = val * 255;
*blue = t * 255;
break;
case 3:
*red = p * 255;
*green = q * 255;
*blue = val * 255;
break;
case 4:
*red = t * 255;
*green = p * 255;
*blue = val * 255;
break;
case 5:
*red = val * 255;
*green = p * 255;
*blue = q * 255;
break;
default:
break;
}
}
}
static void color_select_update_rgb_values (ColorSelectP csp) {
gfloat h, s, v;
gfloat f, p, q, t;
if (csp)
{
h = csp->values[HUE];
s = csp->values[SATURATION] / 100.0;
v = csp->values[VALUE] / 100.0;
if (s == 0)
{
csp->values[RED] = v * 255;
csp->values[GREEN] = v * 255;
csp->values[BLUE] = v * 255;
}
else
{
if (h == 360)
h = 0;
h /= 60;
f = h - (int) h;
p = v * (1 - s);
q = v * (1 - (s * f));
t = v * (1 - (s * (1 - f)));
switch ((int) h)
{
case 0:
csp->values[RED] = v * 255;
csp->values[GREEN] = t * 255;
csp->values[BLUE] = p * 255;
break;
case 1:
csp->values[RED] = q * 255;
csp->values[GREEN] = v * 255;
csp->values[BLUE] = p * 255;
break;
case 2:
csp->values[RED] = p * 255;
csp->values[GREEN] = v * 255;
csp->values[BLUE] = t * 255;
break;
case 3:
csp->values[RED] = p * 255;
csp->values[GREEN] = q * 255;
csp->values[BLUE] = v * 255;
break;
case 4:
csp->values[RED] = t * 255;
csp->values[GREEN] = p * 255;
csp->values[BLUE] = v * 255;
break;
case 5:
csp->values[RED] = v * 255;
csp->values[GREEN] = p * 255;
csp->values[BLUE] = q * 255;
break;
}
}
}
}
static void
color_select_update_hsv_values (ColorSelectP csp)
{
int r, g, b;
float h, s, v;
int min, max;
int delta;
if (csp)
{
r = csp->values[RED];
g = csp->values[GREEN];
b = csp->values[BLUE];
if (r > g)
{
if (r > b)
max = r;
else
max = b;
if (g < b)
min = g;
else
min = b;
}
else
{
if (g > b)
max = g;
else
max = b;
if (r < b)
min = r;
else
min = b;
}
v = max;
if (max != 0)
s = (max - min) / (float) max;
else
s = 0;
if (s == 0)
h = 0;
else
{
h = 0;
delta = max - min;
if (r == max)
h = (g - b) / (float) delta;
else if (g == max)
h = 2 + (b - r) / (float) delta;
else if (b == max)
h = 4 + (r - g) / (float) delta;
h *= 60;
if (h < 0)
h += 360;
}
csp->values[HUE] = h;
csp->values[SATURATION] = s * 100;
csp->values[VALUE] = v * 100 / 255;
}
}
static void update_color_preview (ColorSelectP coldata,
GtkWidget *preview, gint hue_changed) {
guchar buf[3*PREVIEWSIZE];
gint x, y, k, r2, dx, col;
gint x0, y0;
gfloat hue, sat, val, s, v;
gint hx,hy, sx,sy, vx,vy;
hue = (float) coldata->values[HUE] * M_PI / 180;
hx = sin(hue) * COLORTRIANGLERADIUS;
hy = cos(hue) * COLORTRIANGLERADIUS;
sx = sin(hue - 2*M_PI/3) * COLORTRIANGLERADIUS;
sy = cos(hue - 2*M_PI/3) * COLORTRIANGLERADIUS;
vx = sin(hue + 2*M_PI/3) * COLORTRIANGLERADIUS;
vy = cos(hue + 2*M_PI/3) * COLORTRIANGLERADIUS;
hue = (float) coldata->values[HUE];
if (hue_changed) {
for (y = COLORWHEELRADIUS; y > -COLORWHEELRADIUS; y--) {
dx = (int) sqrt((float) abs((COLORWHEELRADIUS)*(COLORWHEELRADIUS)-y*y));
for (x = -dx, k=0; x <= dx; x++) {
buf[k]=buf[k+1]=buf[k+2]=BGCOLOR;
r2 = (x*x)+(y*y);
if ( r2 <= COLORWHEELRADIUS * COLORWHEELRADIUS) {
if (r2 > COLORTRIANGLERADIUS * COLORTRIANGLERADIUS) {
color_hsv_to_rgb (atan2 (x,y) / M_PI * 180, 1, 1, &buf[k], &buf[k+1], &buf[k+2]);
} else {
val = (float) ((x-sx)*(hy-vy)-(y-sy)*(hx-vx)) / (float) ((vx-sx)*(hy-vy)-(vy-sy)*(hx-vx));
if (val>0 && val<=1) { // eigentlich val>=0, aber dann Grafikfehler...
sat = (val==0?0: ((float) (y-sy-val*(vy-sy)) / (val * (float) (hy-vy))));
if (sat >= 0 && sat <= 1)
color_hsv_to_rgb (hue, sat, val, &buf[k], &buf[k+1], &buf[k+2]);
}
}
}
k += 3;
}
/* gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, COLORWHEELRADIUS - y - 1, PREVIEWSIZE); */
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, COLORWHEELRADIUS - dx, COLORWHEELRADIUS - y - 1, 2*dx+1);
}
// Marker im aeusseren Ring
x0 = (gint) (sin(hue*M_PI/180) * ((float) (COLORWHEELRADIUS - COLORTRIANGLERADIUS + 1)/2 + COLORTRIANGLERADIUS) + 0.5);
y0 = (gint) (cos(hue*M_PI/180) * ((float) (COLORWHEELRADIUS - COLORTRIANGLERADIUS + 1)/2 + COLORTRIANGLERADIUS) + 0.5);
color_hsv_to_rgb (atan2 (x0,y0) / M_PI * 180, 1, 1, &buf[0], &buf[1], &buf[2]);
col = INTENSITY(buf[0], buf[1], buf[2]) > 127 ? 0 : 255 ;
for (y = y0 - 4 ; y <= y0 + 4 ; y++) {
for (x = x0 - 4, k=0 ; x <= x0 + 4 ; x++) {
r2 = (x-x0)*(x-x0)+(y-y0)*(y-y0);
if (r2 <= 20 && r2 >= 6)
buf[k]=buf[k+1]=buf[k+2]=col;
else
color_hsv_to_rgb (atan2 (x,y) / M_PI * 180, 1, 1, &buf[k], &buf[k+1], &buf[k+2]);
k += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, COLORWHEELRADIUS + x0-4, COLORWHEELRADIUS - 1 - y, 9);
}
} else {
// Marker im Dreieck loeschen
s = coldata->oldsat;
v = coldata->oldval;
x0 = (gint) (sx + (vx - sx)*v + (hx - vx) * s * v);
y0 = (gint) (sy + (vy - sy)*v + (hy - vy) * s * v);
for (y = y0 - 4 ; y <= y0 + 4 ; y++) {
for (x = x0 - 4, k=0 ; x <= x0 + 4 ; x++) {
buf[k]=buf[k+1]=buf[k+2]=BGCOLOR;
r2 = (x-x0)*(x-x0)+(y-y0)*(y-y0);
if (x*x+y*y > COLORTRIANGLERADIUS * COLORTRIANGLERADIUS) {
color_hsv_to_rgb (atan2 (x,y) / M_PI * 180, 1, 1, &buf[k], &buf[k+1], &buf[k+2]);
} else {
val = (float) ((x-sx)*(hy-vy)-(y-sy)*(hx-vx)) / (float) ((vx-sx)*(hy-vy)-(vy-sy)*(hx-vx));
if (val>0 && val<=1) { // eigentlich val>=0, aber dann Grafikfehler...
sat = (val==0?0: ((float) (y-sy-val*(vy-sy)) / (val * (float) (hy-vy))));
if (sat >= 0 && sat <= 1)
color_hsv_to_rgb (hue, sat, val, &buf[k], &buf[k+1], &buf[k+2]);
}
}
k += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, COLORWHEELRADIUS + x0-4, COLORWHEELRADIUS - 1 - y, 9);
}
coldata->oldsat = coldata->values[SATURATION] / 100.0;
coldata->oldval = coldata->values[VALUE] / 100.0;
}
// Marker im Dreieck
col = INTENSITY(coldata->values[RED], coldata->values[GREEN],
coldata->values[BLUE]) > 127 ? 0 : 255 ;
s = coldata->values[SATURATION] / 100.0;
v = coldata->values[VALUE] / 100.0;
coldata->oldsat=s;
coldata->oldval=v;
x0 = (gint) (sx + (vx - sx)*v + (hx - vx) * s * v);
y0 = (gint) (sy + (vy - sy)*v + (hy - vy) * s * v);
for (y = y0 - 4 ; y <= y0 + 4 ; y++) {
for (x = x0 - 4, k=0 ; x <= x0 + 4 ; x++) {
buf[k]=buf[k+1]=buf[k+2]=BGCOLOR;
r2 = (x-x0)*(x-x0)+(y-y0)*(y-y0);
if (r2 <= 20 && r2 >= 6)
buf[k]=buf[k+1]=buf[k+2]=col;
else {
if (x*x+y*y > COLORTRIANGLERADIUS * COLORTRIANGLERADIUS) {
color_hsv_to_rgb (atan2 (x,y) / M_PI * 180, 1, 1, &buf[k], &buf[k+1], &buf[k+2]);
} else {
val = (float) ((x-sx)*(hy-vy)-(y-sy)*(hx-vx)) / (float) ((vx-sx)*(hy-vy)-(vy-sy)*(hx-vx));
if (val>0 && val<=1) { // eigentlich val>=0, aber dann Grafikfehler...
sat = (val==0?0: ((float) (y-sy-val*(vy-sy)) / (val * (float) (hy-vy))));
if (sat >= 0 && sat <= 1)
color_hsv_to_rgb (hue, sat, val, &buf[k], &buf[k+1], &buf[k+2]);
}
}
}
k += 3;
}
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, COLORWHEELRADIUS + x0-4, COLORWHEELRADIUS - 1 - y, 9);
}
for (k=0; k < (PREVIEWSIZE * 3); k+=3) {
buf[k]=coldata->values[RED];
buf[k+1]=coldata->values[GREEN];
buf[k+2]=coldata->values[BLUE];
}
for (y=0; y < 30; y++) {
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, y+PREVIEWSIZE, PREVIEWSIZE);
}
gtk_widget_draw (preview, NULL);
}
static void
init_color_preview (GtkWidget *preview)
{
guchar buf[3*PREVIEWSIZE];
gint i;
for (i=0; i < 3*PREVIEWSIZE; i+=3)
buf[i]=buf[i+1]=buf[i+2]=BGCOLOR;
for (i=0; i < PREVIEWSIZE; i++)
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, PREVIEWSIZE);
gtk_widget_draw (preview, NULL);
}
/*
* Color Preview
*/
static gint
color_selection_callback(GtkWidget *widget, GdkEvent *event)
{
ColorSelectP coldata;
gint x,y, mousex, mousey;
gfloat r;
gfloat hue, sat, val;
gint hx,hy, sx,sy, vx,vy;
coldata = gtk_object_get_user_data (GTK_OBJECT (widget));
switch (event->type) {
case GDK_BUTTON_PRESS:
x = event->button.x - COLORWHEELRADIUS - 1;
y = - event->button.y + COLORWHEELRADIUS + 1;
r = sqrt((float) (x*x+y*y));
if ( /* r <= COLORWHEELRADIUS && */ r > COLORTRIANGLERADIUS)
coldata->mode = 1; // Dragging in the Ring
else
coldata->mode = 2; // Dragging in the Triangle
break;
case GDK_MOTION_NOTIFY:
x = event->motion.x - COLORWHEELRADIUS - 1;
y = - event->motion.y + COLORWHEELRADIUS + 1;
break;
case GDK_BUTTON_RELEASE:
coldata->mode = 0;
break;
default:
gtk_widget_get_pointer(widget, &x, &y);
x = x - COLORWHEELRADIUS - 1;
y = - y + COLORWHEELRADIUS + 1;
break;
}
gtk_widget_get_pointer(widget, &mousex, &mousey);
if ((event->type == GDK_MOTION_NOTIFY &&
(mousex != event->motion.x || mousey != event->motion.y)))
return FALSE;
if (coldata->mode == 1) {
coldata->values[HUE] = ( (int) (atan2 (x, y) / M_PI * 180) + 360 ) %360;
color_select_update_rgb_values(coldata);
update_color_preview(coldata, widget, 1);
}
if (coldata->mode == 2) {
hue = (float) coldata->values[HUE] * M_PI / 180;
hx = sin(hue) * COLORTRIANGLERADIUS;
hy = cos(hue) * COLORTRIANGLERADIUS;
sx = sin(hue - 2*M_PI/3) * COLORTRIANGLERADIUS;
sy = cos(hue - 2*M_PI/3) * COLORTRIANGLERADIUS;
vx = sin(hue + 2*M_PI/3) * COLORTRIANGLERADIUS;
vy = cos(hue + 2*M_PI/3) * COLORTRIANGLERADIUS;
hue = (float) coldata->values[HUE];
if ((x-sx)*vx+(y-sy)*vy < 0) {
sat = 1;
val = ((float) ((x-sx)*(hx-sx)+(y-sy)*(hy-sy)))/((hx-sx)*(hx-sx)+(hy-sy)*(hy-sy));
if (val<0) val=0; else if (val>1) val=1;
} else if ((x-sx)*hx+(y-sy)*hy < 0) {
sat = 0;
val = ((float) ((x-sx)*(vx-sx)+(y-sy)*(vy-sy)))/((vx-sx)*(vx-sx)+(vy-sy)*(vy-sy));
if (val<0) val=0; else if (val>1) val=1;
} else if ((x-hx)*sx+(y-hy)*sy < 0) {
val = 1;
sat = ((float) ((x-vx)*(hx-vx)+(y-vy)*(hy-vy)))/((hx-vx)*(hx-vx)+(hy-vy)*(hy-vy));
if (sat<0) sat=0; else if (sat>1) sat=1;
} else {
val = (float) ((x-sx)*(hy-vy)-(y-sy)*(hx-vx)) / (float) ((vx-sx)*(hy-vy)-(vy-sy)*(hx-vx));
if (val<=0) {
val=0;
sat=0;
} else {
if (val>1) val=1;
sat = (float) (y-sy-val*(vy-sy)) / (val * (float) (hy-vy));
if (sat<0) sat=0; else if (sat>1) sat=1;
}
}
coldata->values[SATURATION]=100*sat+0.5;
coldata->values[VALUE]=100*val+0.5;
color_select_update_rgb_values(coldata);
update_color_preview(coldata, widget, 0);
}
/* callback the user */
(*coldata->callback) (coldata->data,
coldata->values[RED],
coldata->values[GREEN],
coldata->values[BLUE]);
return FALSE;
}
static GtkWidget *
create_color_preview (ColorSelectP coldata)
{
GtkWidget *preview;
preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_widget_set_events( GTK_WIDGET(preview), PREVIEW_MASK );
gtk_preview_size (GTK_PREVIEW (preview), PREVIEWSIZE, PREVIEWSIZE + 30 /* BAD! */);
gtk_object_set_user_data (GTK_OBJECT (preview), coldata);
gtk_signal_connect (GTK_OBJECT(preview), "motion_notify_event",
GTK_SIGNAL_FUNC(color_selection_callback), NULL);
gtk_signal_connect (GTK_OBJECT(preview), "button_press_event",
GTK_SIGNAL_FUNC(color_selection_callback), NULL);
gtk_signal_connect (GTK_OBJECT(preview), "button_release_event",
GTK_SIGNAL_FUNC(color_selection_callback), NULL);
init_color_preview (preview);
update_color_preview (coldata, preview, 1);
return preview;
}