GNOME Clipboard Manager - Documentation
Creating plugins for GNOME Clipboard Manager
Index
Step1: Setting all includes and preprocessor stuff right
Make a yourplugin.c file that looks like this :
#include "yourplugin.h"
/*
* Add all the .h files of the windows of gcm you want to use
*/
#include "../src/textitemwin.h"
#include "../src/mainwin.h"
#include
#include <string.h>
#include <gnome.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Add code here */
#ifdef __cplusplus
}
#endif
And a yourplugin.h file that looks like this :
/* The plugin.h file of the gcm distrubution*/
#include "../src/plugin.h"
#ifdef __cplusplus
extern "C" {
#endif
void plugin_init (GtkWidget *mainwin);
void plugin_about (GtkWidget *mainwin);
void plugin_configure (GtkWidget *mainwin);
void plugin_cleanup ();
void plugin_on_mainwin_show (GtkWidget *mainwin, gpointer *user_data);
void plugin_on_mainwin_hide (GtkWidget *mainwin, gpointer *user_data);
void plugin_on_plugin_added (GtkWidget *mainwin, GcmPlugin *p);
void plugin_on_firsttime(gpointer *client, gpointer *prefs);
void plugin_on_reload_prefs (GtkWidget *mainwin);
void plugin_on_update_item (GtkWidget *mainwin, gint row, gpointer *user_data);
void plugin_on_add_item (GtkWidget *mainwin, gpointer *item, gint row);
void plugin_on_remove_item (GtkWidget *mainwin, gpointer *item, gint row);
void plugin_on_selection_claimed (GtkWidget *mainwin, GtkClipboard *clipboard,GtkTargetEntry *ttargets, gpointer *item);
void plugin_on_selectiondata_received (GtkWidget *mainwin, gpointer *item, GtkSelectionData *data);
GcmPlugin *plugin_i_will_handle_that_target (GdkAtom target);
gboolean plugin_handle_target_tab (gpointer *mytab, GtkSelectionData *data);
GtkSelectionData *plugin_handle_target_merge (GtkSelectionData *old, GtkSelectionData *in);
#ifdef __cplusplus
}
#endif
Step2: Creating a GcmPlugin struct
Add a GcmPlugin struct in the yourplugin.c file
/* Change the name in two places; the variable-name and in the GcmPlugin struct !*/
GcmPlugin yourplugin =
{
NULL, /* Leave empty */
NULL, /* Leave empty */
"Your plugin", /* Description (change this!) */
"yourplugin", /* The name of your plugin (change this!) */
FALSE, /* Always put false here (this is yourplugin.enabled) */
plugin_init, /* The name of your init function */
plugin_about /* The name of your about function */,
plugin_configure /* The name of your configure function */,
plugin_cleanup /* The name of your cleanup function */,
plugin_on_mainwin_show /* the name of your ... */,
plugin_on_mainwin_hide /* ... */,
plugin_on_plugin_added,
plugin_on_firsttime,
plugin_on_reload_prefs,
plugin_on_update_item,
plugin_on_add_item,
plugin_on_remove_item,
plugin_on_selection_claimed,
plugin_on_selectiondata_received,
plugin_i_will_handle_that_target,
plugin_handle_target_tab,
plugin_handle_target_merge
};
/* Function to return a handle to the plugin */
GcmPlugin *get_gcmplugin_info(void) { return &yourplugin; }
MainWin *themainwin;
void enabled_changed_callback (GConfClient *client,guint cnxn_id,GConfEntry *entry,gpointer user_data);
Step3: Create the functions
Add these functions to the yourplugin.c file
void enabled_changed_callback (GConfClient *client,guint cnxn_id,GConfEntry *entry,gpointer user_data)
{
/* Yes, this is required ! */
gboolean enabled = gconf_value_get_bool (gconf_entry_get_value (entry));
/* You must change this ! */
GcmPlugin *pe = &yourplugin;
if (enabled) {
themainwin->plugin_enable_plugin (themainwin, pe);
} else {
themainwin->plugin_disable_plugin (themainwin, pe);
}
}
void plugin_init (GtkWidget *mainwin)
{
MainWin *mwin = (MainWin*)mainwin;
/* PLUGIN_ENABLED_CONFIG_KEY is a macro defined in plugin.h */
gchar *key = PLUGIN_ENABLED_CONFIG_KEY(sampleplugin);
GError *err=NULL;
GConfClient *client;
themainwin = mwin;
client = gconf_client_get_default();
/* Yes, this is required ! */
gconf_client_notify_add(client, key,
(GConfClientNotifyFunc) enabled_changed_callback,
themainwin->prefswin, /* Give a pointer to the prefswin*/
NULL, NULL);
yourplugin.enabled = gconf_client_get_bool (client, key, &err);
/* You are free to add more code here */
g_free(key);
}
void plugin_about (GtkWidget *mainwin)
{
GtkWidget *thewin;
gchar *comment; void plugin_on_mainwin_show (GtkWidget *mainwin, gpointer *user_data);
const gchar *documenters[] = {
"Documenter",
NULL
};
const gchar *translator_credits = _("translator_credits");
const gchar *authors[] = {
"author",
NULL
};
comment = g_strdup (_("This plugin is a .... plugin for GNOME Clipboard Manager"));
thewin = gnome_about_new ( _("GNOME Clipboard Manager pluginname plugin"), "0.0.1",
"(C) 2000",
_("Released under the GNU General Public License.\n"),
authors,
documenters,
strcmp (translator_credits, "translator_credits") != 0 ? translator_credits : NULL,
NULL);
gtk_widget_show(thewin);
}
void plugin_configure (GtkWidget *mainwin){
GtkWidget *win, *vbox, *bbox, *closeb;
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(GTK_WIDGET(win), 150, 80);
gtk_window_set_title (GTK_WINDOW (win), _("SamplePlugin configuration"));
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER(win), vbox);
gtk_widget_show (vbox);
bbox = gtk_hbutton_box_new ();
gtk_widget_show (bbox);
gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 6);
gtk_container_set_border_width (GTK_CONTAINER (bbox), 6);
closeb = gtk_button_new_from_stock (GNOME_STOCK_BUTTON_CLOSE);
gtk_widget_show (closeb);
gtk_container_add (GTK_CONTAINER (bbox), closeb);
GTK_WIDGET_SET_FLAGS (closeb, GTK_CAN_DEFAULT);
gtk_widget_grab_default (closeb);
g_signal_connect (G_OBJECT (closeb), "clicked",
G_CALLBACK (on_preferencesclose_clicked),
win);
gtk_widget_show(win);
}
void plugin_cleanup ()
{
/*
* Free all memory here !!
*/
}
void plugin_on_mainwin_show (GtkWidget *mainwin, gpointer *user_data);
void plugin_on_mainwin_hide (GtkWidget *mainwin, gpointer *user_data);
void plugin_on_plugin_added (GtkWidget *mainwin, GcmPlugin *p);
void plugin_on_firsttime(gpointer *client, gpointer *prefs);
void plugin_on_reload_prefs (GtkWidget *mainwin);
void plugin_on_update_item (GtkWidget *mainwin, gint row, gpointer *user_data);
void plugin_on_add_item (GtkWidget *mainwin, gpointer *item, gint row);
void plugin_on_remove_item (GtkWidget *mainwin, gpointer *item, gint row);
void plugin_on_selection_claimed (GtkWidget *mainwin, GtkClipboard *clipboard,GtkTargetEntry *ttargets, gpointer *item);
void plugin_on_selectiondata_received (GtkWidget *mainwin, gpointer *item, GtkSelectionData *data);
GcmPlugin *plugin_i_will_handle_that_target (GdkAtom target) {
/* If your plugin is not respos*/
if (yourplugin.enabled) return NULL;
else if (gdk_atom_intern("THE TARGET THAT YOU WANT TO SUPPORT", FALSE) == target) {
return &yourplugin;
} else {
return NULL;
}
}
gboolean plugin_handle_target_tab (gpointer *mytab, GtkSelectionData *data) {
if (yourplugin.enabled) {
TextItemTab *tab = (TextItemTab*) mytab;
GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
GtkWidget *label = gtk_label_new("Hi, I am yourplugin and I am\nresponsible for this target\n");
tab->tabwidget = vbox;
gtk_box_pack_start (GTK_BOX (tab->tabwidget), label, TRUE, FALSE, 0);
gtk_widget_show(label);
gtk_widget_show(tab->tabwidget);
return TRUE;
} else return FALSE;
}
GtkSelectionData
*plugin_handle_target_merge (GtkSelectionData *old, GtkSelectionData *in) {
if (yourplugin.enabled) {
g_print("yourplugin: merging old with new\n");
return old;
}
}
You can use the following casts (if possible: include the correct .h files!)
MainWin *mwin = (MainWin*)mainwin;
TextItemTab *tab = (TextItemTab*) mytab;
Selection *myitem = (Selection*) item;
GConfClient *myclient = (GConfClient*)client;
Prefs *myprefs = (Prefs*) prefs;
...
You can perform the following functions on gcm in your plugins
MainWin *mwin = (MainWin*)mainwin;
void mwin->plugin_update_item (MainWin *mwin, gpointer *user_data);
void mwin->plugin_update_row (MainWin *mwin, gint row);
void mwin->plugin_get_new_item (MainWin *mwin, gpointer *user_data) ;
void mwin->plugin_delete_selected_items (MainWin *mwin, GtkCList *cliplist, gpointer *usr_data);
void mwin->plugin_add_selection (MainWin *mwin, Selection *item);
void mwin->plugin_add_text_selection (MainWin *mwin, gchar *type, gchar *from, gchar *data);
void mwin->plugin_update_menus (MainWin *mwin);
void mwin->plugin_reload_prefs (MainWin *mwin);
void mwin->plugin_claim_selection (MainWin *mwin, Selection *item);
void mwin->plugin_update_text_selection (MainWin *mwin, gint row, gchar *type, gchar *from, gchar *data);
void mwin->plugin_move_selected_up (MainWin *mwin, GList *remaining, gint startrow);
void mwin->plugin_move_selected_down (MainWin *mwin, GList *remaining, gint startrow);
void mwin->plugin_selection_free (Selection *item);
void mwin->plugin_prefs_free (Prefs *p);
void mwin->plugin_targetmanip_free (TargetManip *tz);
void mwin->plugin_try_to_get_text_target (MainWin *mwin, gpointer *user_data);
void mwin->plugin_saveasdata_free (SaveAsData *sa);
void mwin->plugin_show_prefswin (MainWin *mwin, gpointer *user_data);
You can also use libgcm. Just include libgcm.h in your yourplugin.c file. Note that you must
add something special to your Makefile.am file which will be explained later...
Step3: Add your plugin to the Makefile.am file
If you look at the Makefile.am file you will find the gcmlib_LTLIBRARIES variable. You will have to add
your plugin to it :
gcmlib_LTLIBRARIES = \
librtftohtmlplugin.la \
libsampleplugin.la \
libyourplugin.la \
libtoolsplugin.la
You will also have to add the LIBADD, LDFLAGS and SOURCES variables of your plugin :
libyourplugin_la_LDFLAGS = -avoid-version -module
libyourplugin_la_LIBADD = $(GCM_LIBS)
libyourplugin_la_SOURCES = yourplugin.c
If you want to use libgcm in your plugin then pay special attention to the LDFLAGS variable ! You will
have to add the variable like this :
libyourplugin_la_LIBADD = $(GCM_LIBS) $(top_builddir)/libgcm/libgcm.la
If you want to use librtotohtml in your plugin then pay special attention to the LDFLAGS variable ! You will
have to add the variable like this :
librtftohtmlplugin_la_LIBADD = $(GCM_LIBS) $(top_builddir)/librtftohtml/librtftohtml.la -lstdc++
As you can see I also added -lstdc++. This is because the library uses objects and is
written in C++. If your "special library" is also written in C++ then you too must add it to the line.
Step4: Create a patch and send it to the mailinglist
Creating a patch
cvs diff -u > myplugin_by_my_real_name.unified.diff
And send it to the mailinglist of GNOME Clipboard Manager so that I
can include your plugin with the main Gcm distrubution.