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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.