aboutsummaryrefslogtreecommitdiffstats
/*
 *  ircd-ratbox: A slightly useful ircd.
 *  hash.h: A header for the ircd hashtable code.
 *
 *  Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
 *  Copyright (C) 1996-2002 Hybrid Development Team
 *  Copyright (C) 2002-2004 ircd-ratbox development team
 *
 *  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 INCLUDED_hash_h
#define INCLUDED_hash_h

#include "rb_dictionary.h"
#include "rb_radixtree.h"

extern rb_dictionary *nd_dict;
extern rb_radixtree *resv_tree;
extern rb_radixtree *channel_tree;

/* Magic value for FNV hash functions */
#define FNV1_32_INIT 0x811c9dc5UL

/* Client hash table size, used in hash.c/s_debug.c */
#define U_MAX_BITS 17
#define U_MAX 131072 /* 2^17 */

/* Client connid hash table size, used in hash.c */
#define CLI_CONNID_MAX 4096

/* Channel hash table size, hash.c/s_debug.c */
#define CH_MAX_BITS 16
#define CH_MAX 65536 /* 2^16 */

/* hostname hash table size */
#define HOST_MAX_BITS 17
#define HOST_MAX 131072 /* 2^17 */

/* RESV/XLINE hash table size, used in hash.c */
#define R_MAX_BITS 10
#define R_MAX 1024 /* 2^10 */


#define HASH_WALK(i, max, ptr, table) for (i = 0; i < max; i++) { RB_DLINK_FOREACH(ptr, table[i].head)
#define HASH_WALK_SAFE(i, max, ptr, nptr, table) for (i = 0; i < max; i++) { RB_DLINK_FOREACH_SAFE(ptr, nptr, table[i].head)
#define HASH_WALK_END }

struct Client;
struct Channel;
struct ConfItem;
struct cachefile;
struct nd_entry;

extern uint32_t fnv_hash_upper(const unsigned char *s, int bits);
extern uint32_t fnv_hash(const unsigned char *s, int bits);
extern uint32_t fnv_hash_len(const unsigned char *s, int bits, int len);
extern uint32_t fnv_hash_upper_len(const unsigned char *s, int bits, int len);

extern void init_hash(void);

extern void add_to_client_hash(const char *name, struct Client *client);
extern void del_from_client_hash(const char *name, struct Client *client);
extern struct Client *find_client(const char *name);
extern struct Client *find_named_client(const char *name);
extern struct Client *find_server(struct Client *source_p, const char *name);

extern void add_to_id_hash(const char *, struct Client *);
extern void del_from_id_hash(const char *name, struct Client *client);
extern struct Client *find_id(const char *name);

extern struct Channel *get_or_create_channel(struct Client *client_p, const char *chname, bool *isnew);
extern void del_from_channel_hash(const char *name, struct Channel *chan);
extern struct Channel *find_channel(const char *name);

extern void add_to_hostname_hash(const char *, struct Client *);
extern void del_from_hostname_hash(const char *, struct Client *);
extern rb_dlink_node *find_hostname(const char *);

extern void add_to_resv_hash(const char *name, struct ConfItem *aconf);
extern void del_from_resv_hash(const char *name, struct ConfItem *aconf);
extern struct ConfItem *hash_find_resv(const char *name);
extern void clear_resv_hash(void);

void add_to_cli_connid_hash(struct Client *client_p, uint32_t id);
void del_from_cli_connid_hash(uint32_t id);
struct Client *find_cli_connid_hash(uint32_t connid);

#endif /* INCLUDED_hash_h */
//=============================================================================
//
//   File : KvsObject_pixmap.cpp
//   Creation date : Fri Mar 18 14:30:48 CEST 2005
//   by Tonino Imbesi(Grifisx) and Alessandro Carbone(Noldor)
//
//   This file is part of the KVIrc IRC client distribution
//   Copyright (C) 2005-2008 Alessandro Carbone (elfonol at gmail dot com)
//
//   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 opinion) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================

#include "KvsObject_pixmap.h"
#include "KvsObject_widget.h"

#include "KvsObject_memoryBuffer.h"
#include "KviAnimatedPixmap.h"

#include "kvi_debug.h"
#include "KviLocale.h"

#include <QFile>

/*
	@doc: pixmap
	@keyterms:
	    pixmap object class
	@title:
		pixmap class
	@type:
		class
	@short:
		This class provide a pixmap.
	@inherits:
		[class]object[/class]
		[class]widget[/class]
	@description:
		The pixmap class is an off-screen, pixel-based paint device.
	@functions:
		!fn: $fill(<colorname, rgb or hsv array value or [<red>,<green>,<blue>][<hue>,<saturation>,<value>],[opacity],[system color:RGB or HSV])
		Fills the pixmap with color and opacity.[br]
		!fn: $resize(<width:integer>,<height:integer>)
		Resizes the pixmap to w width and h height. Set wh or hg to 0, to have a null pixmap.
			!fn: $scale(<width:integer>,<height:integer>,[<aspect_ratio:string>])
			Scales the pixmap or the animation by sx horizontally and sy vertically.
		Aspect_ratio values:
		- IgnoreAspectRatio:the pixmap is scaled ignoring his aspect ratio.
		- KeepAspectRatio: pixmap is scaled to a rectangle as large as possible inside size, preserving the aspect ratio.
		- KeepAspectRatioByExpanding, the pixmap is scaled to a rectangle as small as possible outside size, preserving the aspect ratio.
			Default value is KeepAspectRatio.
			!fn: $load(<file_name:string>)
			Load a pixmap from the file <file_name>.
			!fn: $save(<file_name:string>)
			Save the pixmap or the current animation frame to the file <file_name>.
			!fn: $loadAnimation(<file_name:string>)
			Load an animation from the file <file_name> and start it.
			!fn: $startAnimation()
			Start the animation.
			!fn: $stopAnimation()
			Stop the animation.
		!fn: <integer> $height()
			Return the height of the pixmap or of the animation.
		!fn: <integer> $width()
			Return the width of the pixmap or of the animation.
			!fn: $frameChangedEvent()
			This event is triggered by KVIrc when the current animation frame changes.
		@signals:
			!sg: $frameChanged()
			This signal is emitted by the default implementation of [classfnc]$frameChangedEvent[/classfnc]().[br]

*/


KVSO_BEGIN_REGISTERCLASS(KvsObject_pixmap,"pixmap","object")

	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,fill)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,resize)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,scale)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,load)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,loadAnimation)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,save)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,startAnimation)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,stopAnimation)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,loadFromMemoryBuffer)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,height)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,width)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,rotate)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,mirrored)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,setPixel)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,pixel)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,grabWidget)
	KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_pixmap,frameChangedEvent)


KVSO_END_REGISTERCLASS(KvsObject_pixmap)


KVSO_BEGIN_CONSTRUCTOR(KvsObject_pixmap,KviKvsObject)
	m_pAnimatedPixmap = 0;
	m_currentType = Image;
	m_pPixmap = 0;
	m_pImage = 0;
KVSO_END_CONSTRUCTOR(KvsObject_pixmap)


KVSO_BEGIN_DESTRUCTOR(KvsObject_pixmap)
	emit aboutToDie();
	if (m_pPixmap)
		delete m_pPixmap;
	if (m_pAnimatedPixmap)
		delete m_pAnimatedPixmap;
	if (m_pImage)
		delete m_pImage;
KVSO_END_CONSTRUCTOR(KvsObject_pixmap)


KVSO_CLASS_FUNCTION(pixmap,fill)
{
	kvs_int_t iCol1,iCol2,iCol3,iOpacity;
	QString szColorMode,szColor;
	KviKvsVariant *var1,*var2,*var3;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("Color_1_Or_Colorname",KVS_PT_VARIANT,0,var1)
		KVSO_PARAMETER("Color_2",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var2)
		KVSO_PARAMETER("Colo3_3",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var3)
		KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode)
		KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity)
	KVSO_PARAMETERS_END(c)

	QColor col;
	if (!var1->asInteger(iCol1))
	{
		var1->asString(szColor);
		if (c->paramCount()<2)
			iOpacity=255;
		else {
			if (!var2->asInteger(iOpacity))
			{
				c->warning(__tr2qs_ctx("The opacity parameter didn't evaluate to integer","objects"));
				return true;
			}
		}
		col.setNamedColor(szColor);
		col.setAlpha(iOpacity);
	} else {
		if(c->paramCount()<3)
		{
			c->error(__tr2qs_ctx("Color name or triplette rgb/hsv value required","objects"));
			return true;
		}
		if (!var2->asInteger(iCol2)||!var3->asInteger(iCol3))
		{
			c->error(__tr2qs_ctx("One of the triplette parameters didn't evaluate to an integer","objects"));\
			return true;
		}
		if (c->paramCount()<5)
			iOpacity=255;

		if(KviQString::equalCI(szColorMode, "HSV"))
			col.setHsv(iCol1,iCol2,iCol3,iOpacity);
		else
			col.setRgb(iCol1,iCol2,iCol3,iOpacity);
	}
	if(m_currentType==Image)
	{
		if(m_pImage)
		{
			if(!m_pPixmap)
				m_pPixmap = new QPixmap();
			*m_pPixmap = QPixmap::fromImage(*m_pImage);
			delete m_pImage;
			m_pImage = 0;
		} else {
			m_pPixmap = 0;
		}
	} else if(m_currentType==AnimatedPixmap) {
	      delete m_pAnimatedPixmap;
	      m_pAnimatedPixmap=0;
	}
	m_currentType = Pixmap;
	if(!m_pPixmap)
		m_pPixmap=new QPixmap();
	m_pPixmap->fill(col);
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,resize)
{
	kvs_int_t iWidth,iHeight;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("width",KVS_PT_INTEGER,0,iWidth)
		KVSO_PARAMETER("height",KVS_PT_INTEGER,0,iHeight)
	KVSO_PARAMETERS_END(c)

	if(m_currentType==Image)
	{
		if(m_pImage)
		{
			delete m_pImage;
			m_pImage = 0;
		}
	}
	else if(m_currentType==AnimatedPixmap) {
		if(m_pAnimatedPixmap)
		{
			delete m_pAnimatedPixmap;
			m_pAnimatedPixmap=0;
		}
	} else if(m_pPixmap) {
		delete m_pPixmap;
	}
	m_currentType = Image;
	m_pImage=new QImage(iWidth,iHeight,QImage::Format_ARGB32_Premultiplied);
	m_pImage->fill(Qt::transparent);
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,setPixel)
{
	kvs_int_t iCol1,iCol2,iCol3,iOpacity,iX,iY;
	QString szColorMode,szColor;
	KviKvsVariant *var1,*var2,*var3;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("x",KVS_PT_INTEGER,0,iX)
		KVSO_PARAMETER("y",KVS_PT_INTEGER,0,iY)
		KVSO_PARAMETER("Color_1_Or_Colorname",KVS_PT_VARIANT,0,var1)
		KVSO_PARAMETER("Color_2",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var2)
		KVSO_PARAMETER("Colo3_3",KVS_PT_VARIANT,KVS_PF_OPTIONAL,var3)
		KVSO_PARAMETER("color_mode",KVS_PT_STRING,KVS_PF_OPTIONAL,szColorMode)
		KVSO_PARAMETER("opacity",KVS_PT_INT,KVS_PF_OPTIONAL,iOpacity)
	KVSO_PARAMETERS_END(c)

	QColor col;
	if (!var1->asInteger(iCol1))
	{
		var1->asString(szColor);
		if (c->paramCount()<4)
		{
			iOpacity=255;
		} else {
			if (!var2->asInteger(iOpacity))
			{
				c->warning(__tr2qs_ctx("The opacity parameter didn't evaluate to integer","objects"));
				return true;
			}
		}
		col.setNamedColor(szColor);
		col.setAlpha(iOpacity);
	} else {
		if(c->paramCount()<5)
		{
			c->error(__tr2qs_ctx("Color name or triplette rgb/hsv value required","objects"));
			return true;
		}
		if (!var2->asInteger(iCol2)||!var3->asInteger(iCol3))
		{
			c->error(__tr2qs_ctx("One of the triplette parameters didn't evaluate to an integer","objects"));\
			return true;
		}
		if (c->paramCount()<7)
			iOpacity=255;

		if(KviQString::equalCI(szColorMode, "HSV"))
			col.setHsv(iCol1,iCol2,iCol3,iOpacity);
		else
			col.setRgb(iCol1,iCol2,iCol3,iOpacity);
	}

	if(m_currentType==AnimatedPixmap)
	{
		c->warning(__tr2qs_ctx("AnimatedPixmap not supported","objects"));
		return true;
	} else if((m_currentType==Image && !m_pImage) || (m_currentType==Pixmap && !m_pPixmap)) {
		c->error(__tr2qs_ctx("The pixmap is null","objects"));
		return false;
	} else if(m_currentType==Pixmap) {
		delete m_pImage;
		m_pImage = new QImage();
		*m_pImage = m_pPixmap->toImage();
		delete m_pPixmap;
	}
	m_currentType = Image;
	m_pImage->setPixel(iX,iY,col.rgba());
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,pixel)
{
	kvs_int_t iX,iY;
	QString szFlags;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("x",KVS_PT_INTEGER,0,iX)
		KVSO_PARAMETER("y",KVS_PT_INTEGER,0,iY)
		KVSO_PARAMETER("b",KVS_PT_STRING,KVS_PF_OPTIONAL,szFlags)
	KVSO_PARAMETERS_END(c)

	if(m_currentType==AnimatedPixmap)
	{
		c->warning(__tr2qs_ctx("AnimatedPixmap not supported","objects"));
		return true;
	} else if((m_currentType==Image && !m_pImage) || (m_currentType==Pixmap && !m_pPixmap)) {
		c->error(__tr2qs_ctx("The pixmap is null","objects"));
		return false;
	} else if(m_currentType==Pixmap) {
// 		qDebug("mpimage %i",m_pImage);
// 		qDebug("pixmap %i %i",m_pPixmap->width(),m_pPixmap->height());
		delete m_pImage;
		m_pImage = new QImage();
		*m_pImage = m_pPixmap->toImage();
		delete m_pPixmap;
		m_pPixmap = 0;
	}
	m_currentType = Image;
	QRgb rgb= m_pImage->pixel(iX,iY);
	QColor col(rgb);
	if(szFlags.isEmpty()){
		c->returnValue()->setString(col.name());
		return true;
	}
	KviKvsVariant *pRed = new KviKvsVariant((kvs_int_t)col.red());
	KviKvsVariant *pGreen = new KviKvsVariant((kvs_int_t)col.green());
	KviKvsVariant *pBlue = new KviKvsVariant((kvs_int_t)col.blue());
	if (szFlags.indexOf('a',0,Qt::CaseInsensitive) != -1){
		KviKvsArray *pArray = new KviKvsArray();
		pArray->set(0,pRed);
		pArray->set(1,pGreen);
		pArray->set(2,pBlue);
		c->returnValue()->setArray(pArray);
	} else if (szFlags.indexOf('h',0,Qt::CaseInsensitive) != -1){
		KviKvsHash *pHash = new KviKvsHash();
		pHash->set("red",pRed);
		pHash->set("green",pGreen);
		pHash->set("blue",pBlue);
	}
	return true;
}
KVSO_CLASS_FUNCTION(pixmap,rotate)
{
	kvs_real_t dAngle;
	QString szAxis;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("angle",KVS_PT_DOUBLE,0,dAngle)
		KVSO_PARAMETER("axis",KVS_PT_STRING,KVS_PF_OPTIONAL,szAxis)
	KVSO_PARAMETERS_END(c)

	Qt::Axis axis = Qt::ZAxis;
	if(!szAxis.isEmpty())
	{
		if (KviQString::equalCI(szAxis,"XAxis"))
			axis=Qt::XAxis;
		else if (KviQString::equalCI(szAxis,"YAxis"))
			axis=Qt::YAxis;
		else if (KviQString::equalCI(szAxis,"ZAxis"))
			axis=Qt::ZAxis;
		else
			c->warning(__tr2qs_ctx("Unknown axis '%Q' switching to default ZAxis","objects"),&szAxis);
	}

	if(m_currentType==Pixmap)
	{
		if(m_pPixmap)
		{
			if(!m_pImage)
				m_pImage = new QImage();
			*m_pImage = m_pPixmap->toImage();
		} else {
			c->error(__tr2qs_ctx("The pixmap is null","objects"));
			return false;
		}
	} else if(m_currentType==AnimatedPixmap) {
		c->warning(__tr2qs_ctx("AnimatedPixmap not supported","objects"));
		return true;
	}

	if(!m_pImage)
	{
		c->error(__tr2qs_ctx("The pixmap is null","objects"));
		return false;
	}
	m_currentType = Image;
	QTransform transform;
	transform.rotate(dAngle,axis);
	*m_pImage=m_pImage->transformed(transform);
	return true;
}


KVSO_CLASS_FUNCTION(pixmap,mirrored)
{
        bool bHorizontal,bVertical;

	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("bHorizontal",KVS_PT_BOOLEAN,0,bHorizontal)
	        KVSO_PARAMETER("bvertical",KVS_PT_BOOLEAN,0,bVertical)
	KVSO_PARAMETERS_END(c)
	if(m_currentType==Pixmap)
	{
		if(m_pPixmap)
		{
			if(!m_pImage) m_pImage = new QImage();
			*m_pImage = m_pPixmap->toImage();
		} else {
			c->error(__tr2qs_ctx("The pixmap is null","objects"));
			return false;
		}
	} else if(m_currentType==AnimatedPixmap) {
		c->warning(__tr2qs_ctx("AnimatedPixmap not supported","objects"));
		return true;
	}

	if(!m_pImage)
	{
		c->error(__tr2qs_ctx("The pixmap is null","objects"));
		return false;
	}
	m_currentType = Image;
	*m_pImage=m_pImage->mirrored(bHorizontal,bVertical);
	return true;
}



KVSO_CLASS_FUNCTION(pixmap,scale)
{
        kvs_int_t iWidth,iHeight;
        QString szAspectRatio;
        KVSO_PARAMETERS_BEGIN(c)
            KVSO_PARAMETER("width",KVS_PT_INTEGER,0,iWidth)
            KVSO_PARAMETER("height",KVS_PT_INTEGER,0,iHeight)
            KVSO_PARAMETER("aspect_ratio",KVS_PT_STRING,KVS_PF_OPTIONAL,szAspectRatio)
        KVSO_PARAMETERS_END(c)
        Qt::AspectRatioMode ratio=Qt::KeepAspectRatio;
        if(!szAspectRatio.isEmpty())
        {
            if(KviQString::equalCI(szAspectRatio,"IgnoreAspectRatio")) ratio=Qt::IgnoreAspectRatio;
            else if (KviQString::equalCI(szAspectRatio,"KeepAspectRatio")) ratio=Qt::KeepAspectRatio;
            else if (KviQString::equalCI(szAspectRatio,"KeepAspectRatioByExpanding")) ratio=Qt::KeepAspectRatioByExpanding;
            else  c->warning(__tr2qs_ctx("Unknown aspect ratio %Q - Switching to KeepAspectRatio ratio","objects"),&szAspectRatio);
        }
        if(m_currentType==Pixmap)
        {
	        if(m_pPixmap)
		*m_pPixmap=m_pPixmap->scaled(iWidth,iHeight,ratio,Qt::SmoothTransformation);
	        else{
		    c->error(__tr2qs_ctx("The pixmap is null","objects"));
		    return false;
	        }
        }
        else if (m_currentType==AnimatedPixmap)
	        m_pAnimatedPixmap->resize(QSize(iWidth,iHeight),ratio);
        else if(m_currentType==Image)
        {
		if(!m_pImage)
		{
			c->error(__tr2qs_ctx("The pixmap is null","objects"));
			return false;
		}
		*m_pImage=m_pImage->scaled(iWidth,iHeight,ratio,Qt::SmoothTransformation);
        }
        return true;
}

KVSO_CLASS_FUNCTION(pixmap,loadAnimation)
{
	QString szFile;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile)
	KVSO_PARAMETERS_END(c)

	if(!QFile::exists(szFile))
	{
		c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile);
		return true;
	}
	if (m_pAnimatedPixmap) {
		delete m_pAnimatedPixmap;
		m_pAnimatedPixmap = 0;
	}
	if (m_pPixmap)
	{
		delete m_pPixmap;
		m_pPixmap=0;
	}
	m_pAnimatedPixmap= new KviAnimatedPixmap(szFile);
	connect(m_pAnimatedPixmap,SIGNAL(frameChanged()),this,SLOT(frameChanged()));
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,startAnimation)
{
	Q_UNUSED(c);
	if (m_pAnimatedPixmap)
		m_pAnimatedPixmap->start();
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,stopAnimation)
{
	Q_UNUSED(c);
	if (m_pAnimatedPixmap)
		m_pAnimatedPixmap->stop();
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,load)
{
	QString szFile;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile)
	KVSO_PARAMETERS_END(c)

	if(!QFile::exists(szFile))
	{
		c->warning(__tr2qs_ctx("I can't find the specified file '%Q'.","objects"),&szFile);
		return true;
	}
	if(!m_pImage)
		m_pImage=new QImage();
	m_currentType = Image;
	m_pImage->load(szFile);
	return true;
/*
 *	FIXME UNUSED CODE
	if (m_currentType==Image && m_pImage)
		delete m_pImage;
	else if (m_currentType==AnimatedPixmap && m_pAnimatedPixmap)
		delete m_pAnimatedPixmap;
	if(!m_pPixmap) m_pPixmap=new QPixmap();
	m_currentType=Pixmap;
	m_pPixmap->load(szFile);
	qDebug("alpha %i",m_pPixmap->hasAlpha());
	return true;
*/
}

KVSO_CLASS_FUNCTION(pixmap,save)
{
	QString szFile;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("file",KVS_PT_STRING,0,szFile)
	KVSO_PARAMETERS_END(c)

	if(m_currentType==Pixmap)
	{
		if(m_pPixmap)
		{
			m_pPixmap->save(szFile);
		} else {
			c->error(__tr2qs_ctx("The pixmap is null","objects"));
			return false;
		}
	} else if(m_currentType==Image) {
		if(m_pImage)
		{
			m_pImage->save(szFile);
		} else {
			c->error(__tr2qs_ctx("The pixmap is null","objects"));
			return false;
		}
	} else {
		m_pAnimatedPixmap->pixmap()->save(szFile);
	}
	return true;
}

void KvsObject_pixmap::setInternalPixmap(QPixmap *pPixmap)
{
	if(m_currentType==Image && m_pImage)
		delete m_pImage;
	else if(m_currentType==Pixmap && m_pPixmap)
		delete m_pPixmap;
	m_currentType=Pixmap;
	m_pPixmap=pPixmap;
}
void KvsObject_pixmap::setInternalImage(QImage *pImage)
{
	if(m_currentType==Image && m_pImage)
		delete m_pImage;
	else if(m_currentType==Pixmap && m_pPixmap)
		delete m_pPixmap;
	m_currentType=Image;
	m_pImage=pImage;
}
KVSO_CLASS_FUNCTION(pixmap,loadFromMemoryBuffer)
{
	KviKvsObject * pObject;
	kvs_hobject_t hObject;
	KVSO_PARAMETERS_BEGIN(c)
		KVSO_PARAMETER("hobject",KVS_PT_HOBJECT,0,hObject)
	KVSO_PARAMETERS_END(c)

	pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
	if (!pObject)
	{
		c->warning(__tr2qs_ctx("Buffer parameter is not an object","objects"));
		return true;
	}
	if (!pObject->inheritsClass("memorybuffer"))
	{
		c->warning(__tr2qs_ctx("Buffer parameter is not a memorybuffer object","objects"));
		return true;
	}
	if (m_pAnimatedPixmap)
	{
		delete m_pAnimatedPixmap;
		m_pAnimatedPixmap=0;
	}
	if (!m_pPixmap)
		m_pPixmap=new QPixmap();
	m_pPixmap->loadFromData(((KvsObject_memoryBuffer *)pObject)->dataBuffer());
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,grabWidget)
{
	CHECK_INTERNAL_POINTER(m_pPixmap)
	KviKvsObject * pObject;
	kvs_hobject_t hObject;
	KVSO_PARAMETERS_BEGIN(c)
	       KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject)
	KVSO_PARAMETERS_END(c)

	pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject);
	CHECK_HOBJECT_IS_WIDGET(pObject)
	if (m_pAnimatedPixmap)
	{
		delete m_pAnimatedPixmap;
		m_pAnimatedPixmap=0;
	}
	if (!m_pPixmap)
		m_pPixmap=new QPixmap();
	*m_pPixmap=QPixmap::grabWidget(((KvsObject_widget *)pObject)->widget());
	return true;

/*	FIXME UNUSED CODE
	QString szFileName;
	KVSO_PARAMETERS_BEGIN(c)
			KVSO_PARAMETER("file_name",KVS_PT_STRING,0,szFileName)
	KVSO_PARAMETERS_END(c)
	QPrinter printer;//(QPrinter::HighResolution);
	printer.setOutputFormat(QPrinter::PdfFormat);
	printer.setPaperSize(QPrinter::A4);
	printer.setOutputFileName(szFileName);

	QPixmap pixmap=QPixmap::grabWidget(((QTableWidget *)widget()));
	QPainter painter(&printer);
	painter.drawPixmap(QPoint(0,0), pixmap, pixmap.rect());
*/
}

KVSO_CLASS_FUNCTION(pixmap,height)
{
	if (m_currentType==Image && m_pImage)
		 c->returnValue()->setInteger(m_pImage->height());
	else if(m_currentType==Pixmap && m_pPixmap)
		c->returnValue()->setInteger(m_pPixmap->height());
	else
		c->returnValue()->setInteger(0);
	//else if(m_pAnimatedPixmap) c->returnValue()->setInteger(m_pAnimatedPixmap->size().height());
	//else c->returnValue()->setInteger(m_pPixmap->height());
	return true;
}

KVSO_CLASS_FUNCTION(pixmap,width)
{
	if (m_currentType==Image && m_pImage)
		c->returnValue()->setInteger(m_pImage->width());
	else if(m_currentType==Pixmap && m_pPixmap)
		c->returnValue()->setInteger(m_pPixmap->width());
	else
		c->returnValue()->setInteger(0);
	//else if(m_pAnimatedPixmap) c->returnValue()->setInteger(m_pAnimatedPixmap->size().height());
	//else c->returnValue()->setInteger(m_pPixmap->height());
	 return true;
}

/*QPixmap * KvsObject_pixmap::getPixmap()
{
	if (!m_pAnimatedPixmap && !m_pPixmap) return new QPixmap();
	else if(m_pAnimatedPixmap) return m_pAnimatedPixmap->pixmap();
	else return m_pPixmap;
}*/
KVSO_CLASS_FUNCTION(pixmap,frameChangedEvent)
{
	emitSignal("frameChanged",c);
	return true;
}

// slots
void KvsObject_pixmap::frameChanged()
{
	KviKvsVariantList *params=0;
	callFunction(this,"frameChangedEvent",params);
}