sven

Artifact [9169bbd87f]
Login

Artifact [9169bbd87f]

Artifact 9169bbd87f3b73f147b00fe15cad64fefb61069a:


/* Sven multimedia keyboard deamon
 * plugin.c
 *
 * Copyright (C) 2005 Eugene Morenko(More)
 * mailto: more@irpin.com
 * web: http://sven.linux.kiev.ua/
 * icq:325697438
 *
 * 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 <gtk/gtk.h>
#include <time.h> /* nanosleep() */
#include <string.h> /* strchr() */
#include <unistd.h> /* exit() */
#include <stdlib.h> /* exit() on Solaris */
#include <gmodule.h>

#include "sven.h"
#include "plugin.h"

/**
 * sven_plugin_is_dupe:
 * @name: a #gchar
 *
 * check(verify) here dublicate plugins
 **/
static gboolean sven_plugin_is_dupe(gpointer data,const gchar *name)
{
	Sven *sven = (Sven *)data;
	if((sven==NULL)|| (name==NULL))
		return FALSE;

	if(sven_plugin_find(sven,name)!=NULL)
		return TRUE;
	
	return  FALSE;
}

/**
 * sven_read_plugins:
 *
 *find plugins
 **/
void sven_read_plugins(gpointer data)
{
	Sven *sven = (Sven *)data;
	gint i;
	gchar *dirname=NULL;
	gchar *dirs[] = { 0,0,NULL};
	const gchar *filename=NULL;
	GError *error = NULL;
	GPatternSpec* ps;
	GDir* gd;

	if (sven==NULL)
		return;
	
	dirs[0] = g_strconcat(g_get_home_dir(),"/",".sven/plugins",NULL);
	dirs[1] = LIBDIR;
	for (i = 0; dirs[i] != NULL; ++i) 
	{
		dirname = dirs[i];

		printf("DIR:%s\n",dirname);	   

		if (!g_file_test(dirname, G_FILE_TEST_IS_DIR))
			continue;

		ps = g_pattern_spec_new("*.so");
		gd = g_dir_open(dirname ,0,&error);
		filename = g_dir_read_name(gd);
		while (filename)
		{
			if (g_pattern_match(ps, strlen(filename), filename, NULL))
			{
				if (!sven_plugin_is_dupe(sven,filename))
				{
					int i=0;
					char *temp1=NULL;
					char *temp=g_strdup(filename);
					sven_cfg_read_int(sven->config->all,"plugins",temp,&i);
					temp1=g_strconcat(dirname,"/",filename,NULL);
					sven_plugin_add(sven,temp1,i);
					g_free(temp);temp=NULL;
					g_free(temp1);temp1=NULL;
				}
			     	else
					printf("plugin %s, its already loaded but appears in another location\n",filename);
			}
			filename = g_dir_read_name(gd);
		}
		g_dir_close(gd);
		g_pattern_spec_free(ps);
	}
	g_free(dirs[0]);
	//free(dirname);
}
 
void sven_init_plugin(gpointer data)
{
	Sven *sven = (Sven *)data;
	gchar *temp, *temp2=NULL;
	if(sven==NULL)
		return;

	if (sven->plugin->arg_plugin_file)
	{
		temp = sven->plugin->arg_plugin_file;
		while ((temp2 = strchr(temp, ',')) != NULL)
		{
			(*temp2) = '\0';
			sven_plugin_add(sven,temp,1);
			temp = temp2 + 1;
		}
		sven_plugin_add(sven,temp,1);
		
		free(temp);temp=NULL;
		free(temp2);temp2=NULL;
	}

	
	
	sven_read_plugins(sven);
	
	//sven_plugin_shutdown(sven);
/*	SvenPluginPriv *priv=sven_plugin_find(sven,"time.so");
	printf("Priv:%s\n",priv->name);
	if(priv->func==NULL)
		printf("Priv=NULL:\n");
	sven_plugin_load(sven,"/home/more/.sven/plugins/time.so",0);
	SvenPluginPriv *priv1=sven_plugin_find(sven,"/home/more/.sven/plugins/time.so");
	printf("Priv1:%s\n",priv1->name);
	if(priv1->func==NULL)
		printf("Priv1=NULL:\n");
	sven_plugin_load(sven,"/home/more/.sven/plugins/time.so",1);
	SvenPluginPriv *priv2=sven_plugin_find(sven,"/home/more/.sven/plugins/time.so");
	printf("Priv2:%s\n",priv2->name);
	if(priv2->func==NULL)
		printf("Priv1=NULL:\n");*/
//	sven_plugin_unload (sven,"/home/more/.sven/plugins/time.so");
	/*sven_plugin_unload_free (sven,"/home/more/.sven/plugins/time.so");
	sven_plugin_shutdown (sven);*/

//	sven_plugin_unload(sven,"time.so");
}

void sven_plugin_add(gpointer data,gchar *filename,int enable)
{
	Sven *sven = (Sven *)data;
	if((sven==NULL)|| (filename==NULL))
		return;
	
	SvenPluginPriv *plug= g_slice_new0(SvenPluginPriv);
	
	printf("Plugin Add[%d]:%s\n",enable,filename);
	if (plug) 
	{
		char *(*get_plugin_name)();
		char *(*get_plugin_info)();
		gboolean test;
		
		plug->module = g_module_open(filename,0);

		if (!plug->module)
		{
			g_print("Could not load plugin: \"%s\" \nDynamic Loader Error: %s\n",filename, g_module_error());
			g_slice_free (SvenPluginPriv, plug);
			return;
		}
	
		test = g_module_symbol(plug->module, "get_plugin_name",(gpointer *)&get_plugin_name);
		if (!test)
		{
			g_print("Dynamic loader error while loading plugin: \"%s\":%s\n",filename,g_module_error());
			g_module_close(plug->module);
			g_slice_free (SvenPluginPriv, plug);
			return;
		}
		plug->filename=g_strdup(filename);
		plug->name=g_strdup((char *)(*get_plugin_name)());

		test = g_module_symbol(plug->module, "get_plugin_info",(gpointer *)&get_plugin_info);
		if (!test)
		{
			plug->info=_("Not information");
		}
		else
			plug->info=g_strdup((char *)(*get_plugin_info)());
		
		printf("File:%s;\n Name:%s;\n Info:%s\n Enable:%d\n",plug->filename,plug->name,plug->info,enable); 	

		
		if(enable)
		{
			SvenPlugin *(*init_plugin)();
			test = g_module_symbol(plug->module, "init_plugin",(gpointer*)&init_plugin);
			if (!test)
			{
				g_print("Dynamic loader error while loading plugin: \"%s\":%s\n",filename,g_module_error());
				g_module_close(plug->module);
				g_slice_free (SvenPluginPriv, plug);
				return;
			}
			plug->func=(*init_plugin)();
			if (plug->func->create!=NULL)
				plug->func->private_data=plug->func->create(sven);
			else
				plug->func->private_data=NULL;
			
			if(plug->func)
				printf("Ok. Module load\n");
			plug->enable=1;
		}
		else
		{
			plug->func=NULL;
			plug->enable=0;
			g_module_close(plug->module);
		}
		
		sven->plugin->list = g_slist_append(sven->plugin->list,(gpointer ) plug);

	//	sven_plugin_find(sven,"test");
		
	}
	else
		printf("Not memory alloc\n");
}

void sven_plugin_load(gpointer data,gchar *filename,int enable)
{
	Sven *sven = (Sven *)data;
	if((sven==NULL)|| (filename==NULL))
		return;
	
	if (enable==0) 
	{
		sven_plugin_unload (sven,filename);
	}
	else if(enable==1)
	{
		SvenPluginPriv *plug=sven_plugin_find(sven,filename);

		gboolean test;
		
		plug->module = g_module_open(filename,0);

		if (!plug->module)
		{
			g_print("Could not load plugin: \"%s\" \nDynamic Loader Error: %s\n",filename, g_module_error());
			g_slice_free (SvenPluginPriv, plug);
		}
	
		{
			SvenPlugin *(*init_plugin)();
			test = g_module_symbol(plug->module, "init_plugin",(gpointer*)&init_plugin);
			if (!test)
			{
				g_print("Dynamic loader error while loading plugin: \"%s\":%s\n",filename,g_module_error());
				g_module_close(plug->module);
				g_slice_free (SvenPluginPriv, plug);
				return;
			}
			plug->func=(*init_plugin)();
			if (plug->func->create!=NULL)
				plug->func->private_data=plug->func->create(sven);
			else
				plug->func->private_data=NULL;

			plug->enable=1;
		}
	}
}

void sven_plugin_unload (gpointer data,gchar *filename)
{
	Sven *sven = (Sven *)data;
	if((sven==NULL)|| (filename==NULL))
		return;
	
	SvenPluginPriv *plug=sven_plugin_find(sven,filename);
	
	if (plug->func->destroy != NULL)
		plug->func->destroy(sven,plug->func->private_data);
	
	plug->func=NULL;
	plug->enable=0;	
	if (plug->module != NULL)
		g_module_close (plug->module);
//	g_slice_free (SvenPluginPriv, plug);	
}
void sven_plugin_unload_free (gpointer data,gchar *filename)
{
	Sven *sven = (Sven *)data;
	if((sven==NULL)|| (filename==NULL))
		return;
	
	SvenPluginPriv *plug=sven_plugin_find(sven,filename);
	
	sven->plugin->list = g_slist_remove (sven->plugin->list, (gpointer ) plug);
	
	if (plug->func->destroy != NULL)
		plug->func->destroy(sven,plug->func->private_data);
	
	plug->enable=0;	
	
	if (plug->module != NULL)
		g_module_close (plug->module);
	
	g_free (plug->name);
	g_free (plug->info);
	g_free (plug->filename);
	
	g_slice_free (SvenPluginPriv, plug);
}

void sven_plugin_shutdown (gpointer data)
{
	Sven *sven = (Sven *)data;
	GSList *l = NULL;

	if(sven==NULL)
		return;
	
	for (l = sven->plugin->list; l; l=l->next)
	{
		SvenPluginPriv *plug = (SvenPluginPriv *)l->data;
		
		if (plug->func->destroy != NULL)
			plug->func->destroy(sven,plug->func->private_data);
			
		if (plug->module != NULL)
			g_module_close (plug->module);
		
		g_free (plug->name);
		g_free (plug->info);
		g_free (plug->filename);

		g_slice_free (SvenPluginPriv, plug);
	}
	
	g_slist_free (sven->plugin->list);
	sven->plugin->list = NULL;
}


SvenPluginPriv *sven_plugin_find(gpointer data,const gchar *name)
{
	Sven *sven = (Sven *)data;
	GSList *l = NULL;

	if((sven==NULL)|| (name==NULL))
		return NULL;

//	printf("Find name:%s\n", name);	

	for (l = sven->plugin->list; l; l=l->next)
	{
		SvenPluginPriv *plug = (SvenPluginPriv *)l->data;
		if(plug==NULL)
			return NULL;
			
//		printf("Find:%s - %s - %s\n",(gchar *)plug->name, (gchar *)plug->filename,g_basename((gchar *)plug->filename));

		if (!g_strcasecmp(g_basename((gchar *)plug->filename),g_basename(name)))
			return plug;	
	}
	
	return NULL;
}