mirror of https://github.com/GNOME/gimp.git
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:
parent
11068b83dd
commit
43639fa0b3
25
ChangeLog
25
ChangeLog
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 **/
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 **/
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 **/
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 **/
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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>" },
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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>" },
|
||||
|
|
|
@ -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>" },
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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__ */
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>" },
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue