need help in plugin development....xfce4-mount-plugin
jean-baptiste dulong <[email protected]>
| Newsgroups | gmane.comp.desktop.xfce.goodies.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi,
I'm working on the xfce4-mount-plugin and would like to add a new
functionality. I'd like the plugin to launch a command upon a
successfull mount (eg: a terminal). The command won't depend on a
specific device but will be a general options for the plugin.
Therefore I added an element in the structure that hold the plugin
(Control->data) to store that command :
typedef struct
{
/* added string to hold command value */
char * on_mount_cmd ;
GtkWidget * button ;
GtkWidget * menu ;
GPtrArray * pdisks ;
GPtrArray * pdisk_display ;
} t_mounter ;
I also added a mounter_read_config and a mounter_write_config function
to store and restore the option value.
My next step (before implementing a graphical interface for the user to
change the options) is to actually use the value in on_mount_cmd when
mounting a device.
For mounting a device, I catch an event from a menu item with this
simple function :
static void on_activate_disk_display(GtkWidget * widget,t_disk * disk)
{
if (disk != NULL)
{
if (disk->mount_info != NULL)
{
disk_umount(disk);
}
else
{
disk_mount(disk);
/*exec_cmd_silent(g_strconcat(mt->on_mount_cmd,disk->mount_point,NULL),FALSE,TRUE);*/
}
}
}
And this function would love to use mt->on_mount_cmd to launch
something, but we don't have access to it and the gpointer element in
the callback function is already used, we need a pointer on the t_disk *
disk element.
So is there a way to access the Control->data from some function like
this one ?? Is it possible to add argument to the function with a
pointer to Control->data ?? Is there a magic spell ??
If all this doesn't sound clear at all, leave it, I'll spend my
desperate nights on it... :-))
If the answer is trivial, it will help anyway...
--
---------------------------------------------------
Jean-Baptiste Dulong
---------------------------------------------------
mount-plugin.c
(text/plain, 11.2 KB)
/* mount-plugin.c */ /* Copyright (C) 2005 Jean-Baptiste [email protected] 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "devices.h" #include <gtk/gtk.h> /* for debugging */ #include <libxfce4util/debug.h> #include <panel/xfce.h> #include <panel/plugins.h> #include <libxfcegui4/libxfcegui4.h> #include "icons.h" /*--------- graphical interface ----------*/ typedef struct { char * on_mount_cmd ; GtkWidget * button ; GtkWidget * menu ; GPtrArray * pdisks ; /* contains pointers to struct t_disk */ GPtrArray * pdisk_display ; /*contains pointers to t_disk_display */ } t_mounter ; /*---------------------------------*/ typedef struct { GtkWidget * menu_item ; GtkWidget * hbox ; GtkWidget * label_disk ; GtkWidget * label_mount_info ; GtkWidget * progress_bar ; } t_disk_display ; /*------------------------------------------------*/ /*---------------- on_activate_disk_display ---------------*/ static void on_activate_disk_display(GtkWidget * widget,t_disk * disk) { if (disk != NULL) { if (disk->mount_info != NULL) {/*disk is mounted*/ disk_umount(disk); /* disk->mount_info is freed by disk_mount */ } else {/*disk is not mounted*/ disk_mount(disk); /* needs a refresh, a global refresh is done whe the window becomes visible*/ //exec_cmd_silent(g_strconcat(mt->on_mount_cmd,disk->mount_point,NULL),FALSE,TRUE); } } } /*---------------------------------------------------------*/ /*-------------------- disk_display_new -----------------*/ /*create a new t_disk_display from t_disk infos */ static t_disk_display * disk_display_new(t_disk * disk) { if (disk != NULL) { t_disk_display * dd ; dd = g_new0(t_disk_display,1) ; dd->menu_item = gtk_menu_item_new(); g_signal_connect(G_OBJECT(dd->menu_item),"activate",G_CALLBACK(on_activate_disk_display),disk); dd->hbox = gtk_hbox_new(FALSE,10); gtk_container_add(GTK_CONTAINER(dd->menu_item), dd->hbox); dd->label_disk = gtk_label_new(g_strconcat(disk->device," -> ",disk->mount_point,NULL)); /*change to uniform label size*/ gtk_label_set_width_chars(GTK_LABEL(dd->label_disk),28); gtk_label_set_justify(GTK_LABEL(dd->label_disk),GTK_JUSTIFY_LEFT); gtk_box_pack_start(GTK_BOX(dd->hbox),dd->label_disk,FALSE,TRUE,0); dd->label_mount_info = gtk_label_new(""); /*change to uniform label size*/ gtk_label_set_width_chars(GTK_LABEL(dd->label_mount_info),25); gtk_label_set_use_markup(GTK_LABEL(dd->label_mount_info),TRUE); gtk_label_set_justify(GTK_LABEL(dd->label_mount_info),GTK_JUSTIFY_RIGHT); gtk_box_pack_start(GTK_BOX(dd->hbox),dd->label_mount_info,TRUE,TRUE,0); dd->progress_bar = gtk_progress_bar_new(); gtk_box_pack_start(GTK_BOX(dd->hbox),dd->progress_bar,TRUE,TRUE,0); return dd ; } return NULL ; } /*-----------------------------------------------------------*/ /*-------------------- disk_display_refresh -----------------*/ static void disk_display_refresh(t_disk_display * disk_display, t_mount_info * mount_info) { TRACE("enters disk_display_refresh"); if (disk_display != NULL) { if (mount_info != NULL) { /* device is mounted */ char * text ; char * used = get_size_human_readable(mount_info->used); //DBG("used is now : %s",used); char * size = get_size_human_readable(mount_info->size); //DBG("size is now : %s",size); char * avail = get_size_human_readable(mount_info->avail); //DBG("avail is now : %s",size); text = g_strdup_printf("[%s/%s] %s free", used ,size,avail ); //DBG("text is now : %s",text); g_free(used); g_free(size); g_free(avail); //text = g_strdup_printf("mounted on : %s\t[%g Mb/%g Mb] %g Mb free",mount_info->mounted_on, mount_info->used, mount_info->size, mount_info->avail); gtk_label_set_text(GTK_LABEL(disk_display->label_mount_info),text); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(disk_display->progress_bar),((gdouble)mount_info->percent / 100) ); gtk_widget_show(GTK_WIDGET(disk_display->progress_bar)); } else /* mount_info == NULL */ { /*remove mount info */ gtk_label_set_markup(GTK_LABEL(disk_display->label_mount_info),"<span foreground=\"#FF0000\">not mounted</span>"); gtk_widget_hide(GTK_WIDGET(disk_display->progress_bar)); } } TRACE("leaves disk_display_refresh"); } /*----------------------------------------------*/ /*--------------- mounter_data_free -----------------*/ static void mounter_data_free(t_mounter * mt) { TRACE ("enters mounter_data_free"); disks_free(&(mt->pdisks)); g_ptr_array_free(mt->pdisk_display,TRUE); mt->pdisk_display = NULL; gtk_widget_destroy(GTK_WIDGET(mt->menu)); mt->menu = NULL ; TRACE ("leaves mounter_data_free"); } /*----------------------------------------------*/ /*--------------- mounter_free -----------------*/ static void mounter_free(Control * control) { TRACE ("enters mounter_free"); t_mounter * mt = (t_mounter*) control->data ; mounter_data_free(mt); g_free(mt->on_mount_cmd); g_free(mt); TRACE ("leaves mounter_free"); } /*----------------------------------------------*/ /*---------------- mounter_data_new --------------------------*/ static void mounter_data_new(t_mounter * mt) { int i ; t_disk * disk ; t_disk_display * disk_display ; /*get static infos from /etc/fstab */ mt->pdisks = disks_new(); /* get dynamic infos on mounts */ disks_refresh(mt->pdisks); /* menu with menu_item */ mt->menu = gtk_menu_new(); /* gtk_menu_shell_append(GTK_MENU_SHELL(mt->menu),gtk_menu_item_new_with_label("devices")); */ /* gtk_menu_shell_append(GTK_MENU_SHELL(mt->menu),gtk_separator_menu_item_new());*/ mt->pdisk_display = g_ptr_array_sized_new(mt->pdisks->len) ; for(i=0;i < mt->pdisks->len;i++) { disk = g_ptr_array_index(mt->pdisks,i); //get the disk disk_display = disk_display_new(disk) ;// creates a disk_display disk_display_refresh(disk_display,disk->mount_info) ;//fill in mount infos gtk_menu_shell_append(GTK_MENU_SHELL(mt->menu),disk_display->menu_item);//add the mnu_item to the menu g_ptr_array_add(mt->pdisk_display,disk_display); //add to the array } gtk_widget_show_all(mt->menu); return ; } /*------------------------------------------------------*/ /*---------------------- mounter_refresh ---------------*/ static void mounter_refresh(t_mounter * mt) { TRACE ("enters mounter_refresh"); mounter_data_free(mt); mounter_data_new(mt); TRACE ("leaves mounter_refresh"); } /*---------------------------------------------------------*/ /* --------------plugin event --------------------------------*/ static gboolean on_button_press(GtkWidget * widget , GdkEventButton * event,t_mounter * mounter) { TRACE("enters on_button_pressed"); if (mounter != NULL && event->button == 1) { mounter_refresh(mounter); // refreshs infos regarding mounts data gtk_menu_popup(GTK_MENU(mounter->menu),NULL,NULL,NULL,NULL,0,event->time); return TRUE; } TRACE("leaves on_button_pressed"); return FALSE ; } /*------------------------------------------------------*/ /*---------------------- mounter_read_config --------------------*/ static void mounter_read_config (Control * control, xmlNodePtr node) { xmlChar *value; t_mounter *mt; if (!node || !node->children) return; mt = (t_mounter *) control->data; /* on_mount_cmd */ value = xmlGetProp (node, (const xmlChar *) "on_mount_cmd"); if (value) { g_free (mt->on_mount_cmd); mt->on_mount_cmd = (char *) value; } } /*-------------------------------------------------------*/ /*------------------- mounter_write_config -----------------------*/ static void mounter_write_config (Control * control, xmlNodePtr parent) { char value[5]; t_mounter * mt; mt = (t_mounter *) control->data; xmlSetProp (parent, "on_mount_cmd", mt->on_mount_cmd); } /*----------------------------------------------------------*/ /*--------------- mounter_attach_callback -----*/ void mounter_attach_callback(Control * control, const char *signal, GCallback callback, gpointer data) { TRACE ("enters mounter_attach_callback"); t_mounter * mounter = (t_mounter*)control->data ; g_signal_connect(G_OBJECT(mounter->button),signal,callback,data); TRACE ("leaves mounter_attach_callback"); } /*--------------------------------------------*/ /*------------------- create_mounter -------------------*/ static gboolean create_mounter_control (Control * control) { TRACE ("enters create_mounter_control"); t_mounter * mounter ; mounter = g_new0(t_mounter,1); /* default mount command */ mounter->on_mount_cmd = ""; /*plugin button */ GdkPixbuf * pb ; pb = gdk_pixbuf_new_from_inline (sizeof(icon_plugin), icon_plugin, FALSE, NULL); mounter->button = xfce_iconbutton_new_from_pixbuf (pb); gtk_button_set_relief(GTK_BUTTON(mounter->button),GTK_RELIEF_NONE); add_tooltip(GTK_WIDGET(mounter->button),"devices"); /*-------------------------------------------------------------*/ g_signal_connect(G_OBJECT(mounter->button),"button_press_event",G_CALLBACK(on_button_press),mounter); gtk_widget_show(mounter->button); /*get the data*/ mounter_data_new(mounter); gtk_container_add(GTK_CONTAINER(control->base), mounter->button); control->data = mounter ; TRACE ("leaves create_mounter_control"); return TRUE; } /*--------------------------------------------------------*/ G_MODULE_EXPORT void xfce_control_class_init (ControlClass * cc) { TRACE ("enters xfce_control_class_init"); xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8"); cc->name = "mount-plugin"; cc->caption = "mount/display devices"; cc->create_control = (CreateControlFunc) create_mounter_control; cc->attach_callback = mounter_attach_callback; cc->free = mounter_free; cc->read_config = mounter_read_config; cc->write_config = mounter_write_config; cc->create_options = NULL; cc->set_theme = NULL; /* cc->set_size = NULL; * cc->set_orientation = NULL; * cc->about = NULL; */ /* Additional API calls */ /* use if there should be only one instance per screen */ control_class_set_unique (cc, TRUE); /* use if the gmodule should not be unloaded * * (usually because of library issues) */ /*control_class_set_unloadable (cc, FALSE);*/ /* use to set an icon to represent the module * * (you could even update it when the theme changes) */ /* if (1) { GdkPixbuf *pixbuf; pixbuf = xfce_icon_theme_load (xfce_icon_theme_get_for_screen (NULL), "sampleicon.png", 48); if (pixbuf) { control_class_set_icon (cc, pixbuf); g_object_unref (pixbuf); } } */ TRACE ("leaves xfce_control_class_init"); } /* Macro that checks panel API version */ XFCE_PLUGIN_CHECK_INIT