/*======== Example Source-Code for an external Icon-Renderer =========

   (C) Copyright 1997 by Georg Steger.
   
       Created with MaxonCPP 4.0 Pro


Description:
ŻŻŻŻŻŻŻŻŻŻŻŻ
The Icons will get a Macintosh-like Look (the one from it's latest OS)


====================================================================*/


/* OS-Includes */

#include <OSIncludes.h>

#pragma header

/* Compiler-Includes */

#include <pragma/intuition_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/exec_lib.h>
#include <string.h>

/* Program-Includes */

#include "/PWDevelopper.h"

#define IMTYP_CLOSE 1
#define IMTYP_DEPTH 2

#define ID_Size sizeof(IconData)
#define NUM_Col (sizeof(ColData)/3)


#define ARG_TEMPLATE "FONTNAME=F/K,FONTSIZE=FS/K/N,FONTSTYLE/K/N,FONTYOFFSET=FY/K/N,FONTXOFFSET=FX/K/N,DEPTHLOOK=D/N,MINBARWIDTH=MBW/K/N,GADGETGAP=GG/K/N,TITLEGAP=TG/K/N,PRECISION=P/N"

enum {ARG_FONTNAME,
	   ARG_FONTSIZE,
	   ARG_FONTSTYLE,
	   ARG_FONTYOFFSET,
	   ARG_FONTXOFFSET,
	   ARG_DEPTHLOOK,
	   ARG_MINBARWIDTH,
	   ARG_GADGETGAP,
	   ARG_TITLEGAP,
	   ARG_PRECISION,
	   NUM_ARGS};


/* Vars */

extern ULONG HookEntry();

struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct UtilityBase *UtilityBase;
struct Library *DiskfontBase;
extern struct Library *DOSBase;

static struct Window *IconWin;
static struct RastPort *rp;
static struct DrawInfo *di;
static struct Gadget *gad,*CloseGad,*DepthGad;
static struct IClass *MyImageClass;
static struct Image *im;
static struct SignalSemaphore MemSem;
static struct RDArgs *MyArgs;
static struct TextFont *MyFont;
static struct TextExtent MyTE;
static struct TextAttr MyTextAttr;

static STRPTR title;
static WORD   a,b,c,d,slen,x1,y1,x2,y2;
static WORD	  FontYSize=13,FontXOffset=0,FontYOffset=0,FontStyle=0;
static WORD	  MinBarWidth=5,TitleGap=5,GadgetGap=4;
static char	  s[257];
LONG	 *Args[NUM_ARGS];

static WORD	  Precision=PRECISION_EXACT;
static WORD	  DepthTyp=0;

static WORD	  ImageCounter;

APTR	 		  MemPool;

/* GRAUTOENE */

#define COL_BACK 0
#define COL_BARSDARK 1
#define COL_HALFDARK 2
#define COL_GADDARK 3
#define COL_GADINNERDARK 4
#define COL_GADINNERSHINE 5
#define COL_SELFRAME 6

UBYTE ColData[][3] =
{
	{206,206,206},			// Background
	{115,115,115},			// Bars dark
	{147,147,147},			// Half dark
	{130,130,130},			// Gad dark
	{189,189,189},			// Gad inner dark
	{222,222,222},			// gad inner shine
	{255,0,0}
};


/*  205,198,199 (RechtEck um Gadget)
  170,170,170 (Gadget-Flaeche)
  51,51,51    (Gadget dunkle Kanten
  102,102,102 (schwarze Linien (=====)
  191,191,191 (InnenRahmen) */
  


struct IconData
{
	struct Window *iwin;
	struct Window *ParentWindow;
	struct ColorMap *cm;
	WORD BarXStart,BarXEnd;
	WORD Grey[NUM_Col][2];
};

struct MyImageData
{
	WORD typ;
	struct IconData *id;
};

static void CleanUp(void)
{
	if (MyImageClass) FreeClass(MyImageClass);
	if (MyFont) CloseFont(MyFont);

	if (MemPool) DeletePool(MemPool);
	if (GfxBase) CloseLibrary((struct Library *)GfxBase);
	if (IntuitionBase)
	{
		if (ImageCounter)
		{
			DisplayBeep(IntuitionBase->ActiveScreen);
		}
		CloseLibrary((struct Library *)IntuitionBase);
	}
	if (UtilityBase) CloseLibrary((struct Library *)UtilityBase);
	if (DiskfontBase) CloseLibrary(DiskfontBase);
	if (DOSBase) CloseLibrary(DOSBase);

}

static void RefreshIFrame(ULONG method,struct Window *win, struct RastPort *rp, struct IconData *id)
{
	struct DrawInfo *dri;

	if ((dri=GetScreenDrawInfo(win->WScreen)))
	{
		SetAPen(rp,method == RI_RENDERFRAME ? dri->dri_Pens[SHADOWPEN] : id->Grey[COL_SELFRAME][0]);
	
		RectFill(rp,0,0,win->Width-1,0);
		RectFill(rp,win->Width-1,0,win->Width-1,win->Height-1);
		RectFill(rp,0,win->Height-1,win->Width-1,win->Height-1);
		RectFill(rp,0,0,0,win->Height-1);

		FreeScreenDrawInfo(win->WScreen,dri);
	}
}

static void RefreshITitle(struct riRefreshITitle *msg)
{
	struct IconData *id;
	struct DrawInfo *di;
	struct Window *IconWin;
	struct RastPort *rp;
	struct TextExtent MyTE;
	STRPTR title;

	WORD a,b,c,d,x1,y1,x2;

	id=msg->UserData;
	IconWin=msg->Icon;
	rp=IconWin->RPort;

	x1=id->BarXStart;
	x2=id->BarXEnd;
	
	if ((di=GetScreenDrawInfo(IconWin->WScreen)))
	{
		for(y1=4;y1<=IconWin->Height-7;y1+=2)
		{
			SetAPen(rp,di->dri_Pens[SHINEPEN]);
			RectFill(rp,x1,y1,x2,y1);
			SetAPen(rp,id->Grey[COL_BARSDARK][0]);
			RectFill(rp,x1+1,y1+1,x2+1,y1+1);
		}
			
		x1+=MinBarWidth;
		x2-=(MinBarWidth+1);
		
		title=id->ParentWindow->Title;
		
		a=TextFit(rp,title,strlen(title),&MyTE,0,1,(x2-x1)+1-(TitleGap*2),IconWin->Height);
		while (a && (title[a-1]==' ')) a--;
	
		b=rp->TxBaseline+(IconWin->Height - rp->TxHeight + 1) / 2;
		d=(TextLength(rp,title,a)+1) & (~1);
		c=x1+(x2-x1+1-d)/2;
		
		SetAPen(rp,id->Grey[COL_BACK][0]);
		y1=d+TitleGap;
		for (y2=4;y2<=IconWin->Height-6;y2++)
		{
			RectFill(rp,c-TitleGap+(y2&1),y2,c+y1+(y2&1)+1,y2);
		}
	
		Move(rp,c+1+FontXOffset,b+FontYOffset);
		SetABPenDrMd(rp,di->dri_Pens[SHADOWPEN],0,JAM1);
		Text(rp,title,a);

		FreeScreenDrawInfo(IconWin->WScreen,di);
	}
}

static LONG MyImageDispatcher(struct IClass *cl,struct Image *im,Msg msg)
{
	struct MyImageData *data;
	struct TagItem *ti;
	struct RastPort *rp;
	struct DrawInfo *di;
	WORD x1,y1,x2,y2,dx,dy;
	LONG rc;

	switch(msg->MethodID)
	{
		case OM_NEW:
			rc=0;
			if ((im=(struct Image *)DoSuperMethodA(cl,(Object *)im,msg)))
			{
				ImageCounter++;
				data=INST_DATA(cl,im);
				if ((ti=FindTagItem(IA_FGPen,((struct opSet *)msg)->ops_AttrList)))
				{
					data->typ=ti->ti_Data;
					ti->ti_Tag=TAG_IGNORE;
				}
				if ((ti=FindTagItem(GA_UserData,((struct opSet *)msg)->ops_AttrList)))
				{
					ti->ti_Tag=TAG_IGNORE;
					data->id=(struct IconData *)ti->ti_Data;
				}
				rc=(LONG)im;
			}
			break;
			
		case OM_DISPOSE:
			ImageCounter--;
			rc=DoSuperMethodA(cl,(Object *)im,msg);
			break;
			
		case IM_DRAW:
		case IM_DRAWFRAME:
			data=INST_DATA(cl,im);
			x1=((struct impDraw *)msg)->imp_Offset.X+im->LeftEdge;
			y1=((struct impDraw *)msg)->imp_Offset.Y+im->TopEdge;
			x2=x1-1+(msg->MethodID==IM_DRAW ? im->Width : ((struct impDraw *)msg)->imp_Dimensions.Width);
			y2=y1-1+(msg->MethodID==IM_DRAW ? im->Height : ((struct impDraw *)msg)->imp_Dimensions.Height);
			rp=((struct impDraw *)msg)->imp_RPort;
			di=((struct impDraw *)msg)->imp_DrInfo;
			dx=x1+(x2-x1+1)/2;
			dy=y1+(y2-y1+1)/2;
			
			/* Frame */
			
			SetAPen(rp,data->id->Grey[COL_GADDARK][0]);
			RectFill(rp,x1,y1,x2-1,y1);
			RectFill(rp,x1,y1,x1,y2-1);
			SetAPen(rp,di->dri_Pens[SHINEPEN]);
			RectFill(rp,x2,y1+1,x2,y2);
			RectFill(rp,x1+1,y2,x2,y2);
			SetAPen(rp,di->dri_Pens[SHADOWPEN]);
			RectFill(rp,x1+1,y1+1,x2-1,y2-1);

			switch (((struct impDraw *)msg)->imp_State)
			{
				case IDS_SELECTED:
					SetAPen(rp,data->id->Grey[COL_GADINNERDARK][0]);
					RectFill(rp,x1+2,y1+2,x2-2,y2-2);
					SetAPen(rp,data->id->Grey[COL_GADDARK][0]);
					RectFill(rp,x1+2,y1+2,x2-3,y1+2);
					RectFill(rp,x1+2,y1+3,x1+2,y2-3);
					SetAPen(rp,data->id->Grey[COL_HALFDARK][0]);
					WritePixel(rp,x1+2,y1+2);

					if (data->typ== IMTYP_DEPTH)
					{
						SetAPen(rp,di->dri_Pens[SHADOWPEN]);
						if (DepthTyp==0)
						{
							RectFill(rp,x1+1,y1+6,x2-1,y1+6);
							RectFill(rp,x1+1,y2-4,x2-1,y2-4);
						} else {
							RectFill(rp,dx+2,y1+1,dx+2,dy+2);
							RectFill(rp,x1+1,dy+2,dx+1,dy+2);
						}
					}

					break;

				default:
					SetAPen(rp,data->id->Grey[COL_BACK][0]);
					RectFill(rp,x1+2,y1+2,x2-2,y2-2);
					SetAPen(rp,data->id->Grey[COL_GADDARK][0]);
					RectFill(rp,x2-2,y1+3,x2-2,y2-2);
					RectFill(rp,x1+3,y2-2,x2-3,y2-2);
					SetAPen(rp,data->id->Grey[COL_GADINNERDARK][0]);
					RectFill(rp,x1+3,y1+3,x2-4,y1+3);
					RectFill(rp,x1+3,y1+4,x1+3,y2-4);
					SetAPen(rp,data->id->Grey[COL_GADINNERSHINE][0]);
					RectFill(rp,x1+3,y2-3,x2-3,y2-3);
					RectFill(rp,x2-3,y1+3,x2-3,y2-4);
					SetAPen(rp,di->dri_Pens[SHINEPEN]);
					WritePixel(rp,x1+2,y1+2);
					SetAPen(rp,data->id->Grey[COL_HALFDARK][0]);
					WritePixel(rp,x2-2,y2-2);

					if (data->typ== IMTYP_DEPTH)
					{
						SetAPen(rp,di->dri_Pens[SHADOWPEN]);
						if (DepthTyp==0)
						{
							RectFill(rp,x1+1,y1+5,x2-1,y1+5);
							RectFill(rp,x1+1,y2-5,x2-1,y2-5);
						} else {
							RectFill(rp,dx+1,y1+1,dx+1,dy+1);
							RectFill(rp,x1+1,dy+1,dx,dy+1);
						}
					}
			}
			
			rc=0;
			break;
			
			
		default: rc=DoSuperMethodA(cl,(Object *)im,msg);
	}
	return rc;
}

/* Program */

LONG RenderIcon(Msg msg)
{
	struct IconData *id;
	struct Gadget *gad;
	struct Image *im;
	WORD i;
	
	switch (msg->MethodID)
	{

 /*==========  RI_INIT  ===========================================*/

		case RI_INIT:
			GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39);
			IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39);
			UtilityBase=(struct UtilityBase *)OpenLibrary("utility.library",39);
			DiskfontBase=OpenLibrary("diskfont.library",39);
			DOSBase=OpenLibrary("dos.library",39);
			
			MyImageClass=MakeClass(0,IMAGECLASS,0,sizeof(MyImageData),0);
			MemPool=CreatePool(MEMF_PUBLIC|MEMF_CLEAR,2000,2000);
			InitSemaphore(&MemSem);

			if ((!GfxBase) || (!IntuitionBase) || (!UtilityBase) || (!DOSBase) || (!MyImageClass) || (!MemPool))
			{
				CleanUp();
				return RIR_FAIL;
			} else {
				MyImageClass->cl_Dispatcher.h_Entry=HookEntry;
				MyImageClass->cl_Dispatcher.h_SubEntry=(HOOKFUNC)MyImageDispatcher;
				
				if (RIINIT_Msg->Parameters && (RIINIT_Msg->PWVersion>=0))
				{
					if ((MyArgs=AllocDosObject(DOS_RDARGS,0)))
					{
						strncpy(s,RIINIT_Msg->Parameters,254);
						strcat(s,"\n");
						MyArgs->RDA_Source.CS_Buffer=s;
						MyArgs->RDA_Source.CS_Length=strlen(s);
						MyArgs->RDA_Source.CS_CurChr=0;
						
						if (ReadArgs(ARG_TEMPLATE,(LONG *)Args,MyArgs))
						{
							if (Args[ARG_FONTSIZE]) FontYSize= *Args[ARG_FONTSIZE];
							if (Args[ARG_FONTSTYLE]) FontStyle= *Args[ARG_FONTSTYLE];
							if (Args[ARG_FONTXOFFSET]) FontXOffset= *Args[ARG_FONTXOFFSET];
							if (Args[ARG_FONTYOFFSET]) FontYOffset= *Args[ARG_FONTYOFFSET];
							if (Args[ARG_MINBARWIDTH]) MinBarWidth= *Args[ARG_MINBARWIDTH];
							if (Args[ARG_GADGETGAP]) GadgetGap= *Args[ARG_GADGETGAP];
							if (Args[ARG_TITLEGAP]) TitleGap= *Args[ARG_TITLEGAP];
							if (Args[ARG_DEPTHLOOK]) DepthTyp= *Args[ARG_DEPTHLOOK];
							if (Args[ARG_PRECISION]) Precision= *Args[ARG_PRECISION];

							if (Args[ARG_FONTNAME])
							{
								MyTextAttr.ta_Name=(STRPTR)Args[ARG_FONTNAME];
								MyTextAttr.ta_YSize=FontYSize;
								
								MyFont=OpenDiskFont(&MyTextAttr);
							}
							FreeArgs(MyArgs);
						}
						FreeDosObject(DOS_RDARGS,MyArgs);
					}
				}
				
			}
			return RIR_OK;

/*==========  RI_EXIT  ===========================================*/

		case RI_EXIT:
			CleanUp();
			return RIR_OK;

/*==========  RI_INITICON  =======================================*/

		case RI_INITICON:
			ObtainSemaphore(&MemSem);
			if ((RIINITICON_Msg->UserData=AllocPooled(MemPool,ID_Size)))
			{
				id=(struct IconData *)RIINITICON_Msg->UserData;
				id->cm=ViewPortAddress(RIINITICON_Msg->ParentWin)->ColorMap;

				for (i=0;i<NUM_Col;i++)
				{
					id->Grey[i][1]=ObtainBestPen(id->cm,
										ColData[i][0]<<24,
										ColData[i][1]<<24,
										ColData[i][2]<<24,
										OBP_Precision,Precision,
										OBP_FailIfBad,FALSE,
										TAG_DONE);
					if (id->Grey[i][1]>=0)
					{
						id->Grey[i][0]=id->Grey[i][1];
					} else {
						id->Grey[i][0]=FindColor(id->cm,
										ColData[i][0]<<24,
										ColData[i][1]<<24,
										ColData[i][2]<<24,
										~0);
					}
				}
				if (MyFont)
				{
					RIINITICON_Msg->IconHeight=8+MyFont->tf_YSize;
				} else {
					RIINITICON_Msg->IconHeight=8+RIINITICON_Msg->ParentWin->WScreen->RastPort.TxHeight;
				}
				if (RIINITICON_Msg->IconHeight<21) (RIINITICON_Msg->IconHeight=21);
				
			}
			ReleaseSemaphore(&MemSem);
			return RIR_OK;

/*==========  RI_EXITICON  =======================================*/

		case RI_EXITICON:
			if (RIEXITICON_Msg->UserData)
			{
				id=(struct IconData *)RIEXITICON_Msg->UserData;
				gad=id->iwin->FirstGadget;
				while (gad)
				{
					if (gad->Flags&GFLG_GADGIMAGE)
					{
						if ((im=(struct Image *)gad->GadgetRender))
						{
							if (im->Depth==CUSTOMIMAGEDEPTH)
							{
								if (OCLASS(im)==MyImageClass)
								{
									SetGadgetAttrs(gad,id->iwin,0,
										GA_Image,0,
										TAG_DONE);
									DisposeObject(im);
								}
							}
						}
					}
					gad=gad->NextGadget;
				}
				for (i=0;i<NUM_Col;i++)
				{
					if (id->Grey[i][1]>=0)
					{
						ReleasePen(id->cm,id->Grey[i][0]);
					}
				}
				ObtainSemaphore(&MemSem);
				FreePooled(MemPool,RIEXITICON_Msg->UserData,ID_Size);
				ReleaseSemaphore(&MemSem);
			}
			return RIR_OK;
			
/*==========  RI_RENDERICON  =====================================*/

		case RI_RENDERICON:
			id=(struct IconData *)RIRENDERICON_Msg->UserData;
			if (!id) return RIR_FAIL;

			IconWin=RIRENDERICON_Msg->Icon;
			id->iwin=IconWin;
			rp=IconWin->RPort;

			if (MyFont)
			{
				SetFont(rp,MyFont);
			} else {
				SetFont(rp,IconWin->WScreen->RastPort.Font);
			}

			if (FontStyle) SetSoftStyle(rp,FontStyle,AskSoftStyle(rp));

			di=GetScreenDrawInfo(IconWin->WScreen);
			if (!di) return RIR_FAIL;

			gad=IconWin->FirstGadget;
			CloseGad=0;DepthGad=0;
			while (gad)
			{
				if ((gad->GadgetType&GTYP_SYSTYPEMASK)==GTYP_WDEPTH)
				{
					DepthGad=gad;
				} else if ((gad->GadgetType&GTYP_SYSTYPEMASK)==GTYP_CLOSE)
				{
					CloseGad=gad;
				} else if (gad->GadgetID==GID_WDEPTH)
				{
					DepthGad=gad;
				}

				gad=gad->NextGadget;
			}

			SetAPen(rp,di->dri_Pens[SHADOWPEN]);
			RectFill(rp,0,0,IconWin->Width-1,IconWin->Height-1);
			SetAPen(rp,di->dri_Pens[SHINEPEN]);
			RectFill(rp,1,1,IconWin->Width-2,1);
			RectFill(rp,1,1,1,IconWin->Height-2);
			SetAPen(rp,id->Grey[COL_HALFDARK][0]);
			RectFill(rp,IconWin->Width-2,2,IconWin->Width-2,IconWin->Height-2);
			RectFill(rp,2,IconWin->Height-2,IconWin->Width-3,IconWin->Height-2);
			SetAPen(rp,id->Grey[COL_BACK][0]);
			RectFill(rp,2,2,IconWin->Width-3,IconWin->Height-3);

			x1=CloseGad ? 4+13+GadgetGap : 4;
			x2=IconWin->Width - (DepthGad ? 6+13+GadgetGap : 6);

			id->BarXStart=x1;
			id->BarXEnd=x2;
			id->ParentWindow=RIRENDERICON_Msg->ParentWin;

			for(y1=4;y1<=IconWin->Height-7;y1+=2)
			{
				SetAPen(rp,di->dri_Pens[SHINEPEN]);
				RectFill(rp,x1,y1,x2,y1);
				SetAPen(rp,id->Grey[COL_BARSDARK][0]);
				RectFill(rp,x1+1,y1+1,x2+1,y1+1);
			}
//			SetAPen(rp,id->Grey[COL_BACK][0]);
			x1+=MinBarWidth;
			x2-=(MinBarWidth+1);

			if (CloseGad)
			{
				SetGadgetAttrs(CloseGad,IconWin,0,
					GA_Left,4,
					GA_Top,4,
					GA_Width,13,
					GA_Height,IconWin->Height-8,
					TAG_DONE);
				if ((im=NewObject(MyImageClass,0,
					IA_FGPen,IMTYP_CLOSE,
					GA_UserData,id,
					IA_Width,13,
					IA_Height,IconWin->Height-8,
					TAG_DONE)))
				{
					SetGadgetAttrs(CloseGad,IconWin,0,
						GA_Image,im,
						TAG_DONE);
					RefreshGList(CloseGad,IconWin,0,1);
				}
					
			}
			if (DepthGad)
			{
				SetGadgetAttrs(DepthGad,IconWin,0,
					GA_RelRight,-16,
					GA_Top,4,
					GA_Width,13,
					GA_Height,IconWin->Height-8,
					TAG_DONE);
				if ((im=NewObject(MyImageClass,0,
					IA_FGPen,IMTYP_DEPTH,
					GA_UserData,id,
					IA_Width,13,
					IA_Height,IconWin->Height-8,
					TAG_DONE)))
				{
					SetGadgetAttrs(DepthGad,IconWin,0,
						GA_Image,im,
						TAG_DONE);
					RefreshGList(DepthGad,IconWin,0,1);
				}

			}
			title=RIRENDERICON_Msg->ParentWin->Title;
			a=TextFit(rp,title,strlen(title),&MyTE,0,1,(x2-x1)+1-(TitleGap*2),IconWin->Height);
			while (a && (title[a-1]==' ')) a--;

			b=rp->TxBaseline+(IconWin->Height - rp->TxHeight + 1) / 2;
			d=(TextLength(rp,title,a)+1) & (~1);
			c=x1+(x2-x1+1-d)/2;
			
			SetAPen(rp,id->Grey[COL_BACK][0]);
			y1=d+TitleGap;
			for (y2=4;y2<=IconWin->Height-6;y2++)
			{
				RectFill(rp,c-TitleGap+(y2&1),y2,c+y1+(y2&1)+1,y2);
			}

			Move(rp,c+1+FontXOffset,b+FontYOffset);
			SetABPenDrMd(rp,di->dri_Pens[SHADOWPEN],0,JAM1);
			Text(rp,title,a);

			FreeScreenDrawInfo(IconWin->WScreen,di);
			
			return RIR_OK;

/*==========  RI_REFRESHIFRAME ===================================*/

		case RI_REFRESHIFRAME:
			RefreshIFrame(RI_RENDERFRAME,
							  RIREFRESHIFRAME_Msg->Icon,
							  RIREFRESHIFRAME_Msg->Icon->RPort,
							  (struct IconData *)RIREFRESHIFRAME_Msg->UserData);
			return RIR_OK;

/*==========  RI_REFRESHIFRAME ===================================*/

		case RI_REFRESHITITLE:
			RefreshITitle((struct riRefreshITitle *)msg);
			return RIR_OK;

/*==========  RI_RENDERFRAME    ==================================*/

		case RI_RENDERFRAME:
			RefreshIFrame(RI_RENDERFRAME,
							  RIRENDERFRAME_Msg->Icon,
							  RIRENDERFRAME_Msg->rp,
							  (struct IconData *)RIRENDERFRAME_Msg->UserData);
			break;

/*==========  RI_RENDERFRAMESEL ==================================*/

		case RI_RENDERFRAMESEL:
			RefreshIFrame(RI_RENDERFRAMESEL,
								RIRENDERFRAMESEL_Msg->Icon,
								RIRENDERFRAMESEL_Msg->rp,
								(struct IconData *)RIRENDERFRAMESEL_Msg->UserData);
			break;

		default:
			return RIR_FAIL;
	}
}
