#ifndef CODE_APPWINDOW_CXX
#define CODE_APPWINDOW_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: appwindow.cxx,v 1.7 2003/02/26 14:07:46 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include <signal.h>
#include "types.h"
#include "../include/callback.h"
#include <Xclasses/callable.h>
#include <Xclasses/appwindow.h>
#include "include/appwindow_p.h"
#include <Xclasses/gadget.h>
#include <Xclasses/group.h>
#include <Xclasses/menu.h>
#include <Xclasses/tools.h>
#include <Xclasses/dlist.h>
#include "../include/XCprogram_p.h"

#define GOOD_BACKGROUND
#define WAKEUPSTR	"AppWakeUp"		// max 20

extern Window onlywindow; // von Gadget
dlist allapps;
static int inrekursion=0;
static int ID=0;

appwindow::appwindow(void) : Xwindows()
{
	while (!(p=new pappwindow))
	{
		outOfMemory("appwindow");
	}
	p->o=this;
	Name("appwindow");
}
appwindow::appwindow(char *name) : Xwindows()
{
	while (!(p=new pappwindow))
	{
		outOfMemory("appwindow");
	}
	p->o=this;
	if (!prgname) prgname=name;
	Name(name);
}
pappwindow::pappwindow(void) : cb()
{
	closeme=0;
	blocked=0;
	extra_right=0;
	showextra=0;
	x=-1;
	y=-1;
	w=100;
	h=60;
	ps=-1;
	ad=-1;
	amenu=NULL;
	gruppe=NULL;
	extragruppe=NULL;
	mtop=0;
#ifdef EXTRABAR
	menubar=NULL;
	menugroup=NULL;
#endif
}
pappwindow::~pappwindow(void)
{
#ifdef EXTRABAR
	if (menugroup) delete menugroup;
	if (menubar) delete menubar;
#endif
}
appwindow::~appwindow(void)
{
	Close(); // Probleme!
	if (p) delete p;
}
void appwindow::InitSize(int x,int y,int w,int h)
{
	p->x=x;
	p->y=y;
	p->w=w;
	p->h=h;
}
void appwindow::InitSize(int x,int y,int ps)
{
	p->x=x;
	p->y=y;
	if (ps<0) ps=0;
	if (ps>200) ps=200;
	p->ps=100+ps;
}
void appwindow::InitSize(int ps)
{
	if (ps<0) ps=0;
	if (ps>400) ps=400;
	p->ps=100+ps;
}
void appwindow::Adjust(int x,int y,int w,int h,int a)
{
	p->ad_x=x;
	p->ad_y=y;
	p->ad_w=w;
	p->ad_h=h;
	p->ad=a;
}
void appwindow::Adjust(Xwindows *wn, int a)
{
	int x,y,w,h;

	wn->Position(x,y);
	wn->Size(w,h);
	Adjust(x,y,w,h,a);
}
int appwindow::Init(int &argc,char *argv[])
{
	return Init(argc,argv,NULL);
}
static char *allwname=NULL;
int appwindow::Init(int &argc,char *argv[],char *basecolor)
{
	if (!Xcolors::Init(argc,argv,basecolor))
	{
		return 0;
	}
	int i=1;
	char *wname=NULL;
	while (i<argc)
	{
		if (!strcasecmp(argv[i],"-swallow"))
		{
			int c=i+1;
			if (c<argc)
			{
				wname=argv[c];
				remarg(argc,argv,i);
				argc--;
			}
			remarg(argc,argv,i);
			argc--;
		}
		else if (!strcasecmp(argv[i],"-swallowall"))
		{
			int c=i+1;
			if (c<argc)
			{
				allwname=argv[c];
				remarg(argc,argv,i);
				argc--;
			}
			remarg(argc,argv,i);
			argc--;
		}
		else
			i++;
	}

	Xwindows::Create(p->x,p->y,p->w,p->h);
	if (allwname)
	{
		Window wn=FindWindowOnServer(display(),allwname);
		if (wn) XReparentWindow(display(),window(),wn,0,0);
	}
	if (wname)
	{
		Window wn=FindWindowOnServer(display(),wname);
		if (wn) XReparentWindow(display(),window(),wn,0,0);
	}
	Geometry(argc,argv);

#ifdef GOOD_BACKGROUND
	Background(col_background());
#else
	Background(col_black());
#endif
	Title(thisProgram->name->Name());
	IconTitle(thisProgram->name->Name());
	Class(thisProgram->name->Name(),"Xclasses");
	Event(StructureNotifyMask|KeyPressMask|FocusChangeMask);
	return 1;
}
int appwindow::Init(void)
{
	p->closeme=0;
	Xwindows::Create(p->x,p->y,p->w,p->h);
	if (allwname)
	{
		Window wn=FindWindowOnServer(display(),allwname);
		if (wn) XReparentWindow(display(),window(),wn,0,0);
	}
#ifdef GOOD_BACKGROUND
	Background(col_background());
#else
	Background(col_black());
#endif
	Title(thisProgram->name->Name());
	IconTitle(thisProgram->name->Name());
	Class(thisProgram->name->Name(),"Xclasses");
	Event(StructureNotifyMask|KeyPressMask|FocusChangeMask);
	return 1;
}

int usealarm=-1;
static int alarmed=0;
void aw_alarmhandler(int)
{
	pappwindow::alarmhandler();
	alarmed=1;
}
void aw_unalarm(void)
{
	if (usealarm==-1 && thisProgram)
	{
		char *r=thisProgram->o->GetResource("timeoutpointer");
		if (r && !strcasecmp(r,"True"))
			usealarm=2;
		else
			usealarm=0;
	}
	if (usealarm>0)
	{
		signal(SIGALRM,::aw_alarmhandler);
		alarm(0);
		if (alarmed)
		{
			pappwindow::unalarm();
			alarmed=0;
		}
		alarm(usealarm);
	}
}
void pappwindow::alarmhandler(void)
{
	struct node *n=allapps.head;
	while (n->next)
	{
		if (!((appwindow*)n->text)->p->blocked)
			((appwindow*)n->text)->MCursor(XC_gumby); //XC_watch);
		n=n->next;
	}
}
void pappwindow::alarmhandler2(void)
{
	struct node *n=allapps.head;
	while (n->next)
	{
		if (!((appwindow*)n->text)->p->blocked)
			((appwindow*)n->text)->MCursor(XC_watch);
		n=n->next;
	}
}
void pappwindow::unalarm(void)
{
	struct node *n=allapps.head;
	while (n->next)
	{
		if (!((appwindow*)n->text)->p->blocked)
			((appwindow*)n->text)->MCursor(-1);
		n=n->next;
	}
}

int appwindow::Create(void)
{
	p->alarmhandler2();
	MCursor(XC_watch);

	int mwidth=0;
	char *w;
	if (p->amenu)
	{
		p->amenu->GSetLimits();
		p->mtop=p->amenu->gg_minheight();
		mwidth=p->amenu->gg_minwidth();
	}
	if (!p->gruppe)
	{
		fprintf(stderr,"Appwindow %s has no group - this will fail\n",FullName());
	}
	p->gruppe->GSetLimits();
	if (p->extragruppe) p->extragruppe->GSetLimits();
	MinSize(p->gruppe->gg_minwidth()>mwidth?p->gruppe->gg_minwidth():mwidth,p->gruppe->gg_minheight()+p->mtop);
	if (p->gruppe->gg_maxwidth()<0xffffff || p->gruppe->gg_maxheight()<0xffffff)
	{
		int w,h;
		DisplaySize(display(),w,h);
		if (p->gruppe->gg_maxwidth()<w) w=p->gruppe->gg_maxwidth();
		if (p->gruppe->gg_maxheight()+p->mtop<h) h=p->gruppe->gg_maxheight()+p->mtop;
		MaxSize(w,h);
	}
	MakeFit();
	if (w=GetResource("percentsize"))
	{
		p->ps=atoi(w);
	}
	if (p->ps>=0 && !UserSized())
	{
		Xwindows::Resize(p->gruppe->gg_minwidth()*p->ps/90,(p->gruppe->gg_minheight()+p->mtop)*p->ps/100);
		XSync(display(),0);

		p->ps=-1;
		Update();
//		MakeFit();
	}
	if (p->ad>=0)
	{
		XWindowAttributes xwa;
		int tx,ty,tw,th;
		GetPositionOnRoot(display(),Xwindows::window(),tx,ty);
		MakeFit();
		XSync(display(),0);
		XGetWindowAttributes(display(),Xwindows::window(),&xwa);
		XGetWindowAttributes(display(),Xwindows::window(),&xwa); // nötig!
		tx+=xwa.x;
		ty+=xwa.y;
		tw=xwa.width;
		th=xwa.height;
		switch (p->ad & (1|2))
		{
			case ADJUST_LEFT:
				tx=p->ad_x;
				break;
			case ADJUST_CENTER:
				tx=p->ad_x+(p->ad_w-tw)/2;
				break;
			case ADJUST_RIGHT:
				tx=p->ad_x+(p->ad_w-tw);
				break;
		}
		switch (p->ad & (4|8))
		{	
			case ADJUST_TOP:
				ty=p->ad_y;
				break;
			case ADJUST_MIDDLE:
				ty=p->ad_y+(p->ad_h-th)/2;
				break;
			case ADJUST_BOTTOM:
				ty=p->ad_y+(p->ad_h-th);
				break;
		}
		if (tx<0) tx=0;
		if (ty<0) ty=0;
		Xwindows::Move(tx,ty);
	}
	XSync(display(),0);
	Update();
	char *res=GetResource("openatonce");
	if (res && !strcasecmp(res,"true"))
		Open();	// optischer Test

	{
		int w,h;
		Size(w,h);
		p->gruppe->Create(window(),0,p->mtop,w,h-p->mtop);
//		XFlush(display());
		Update();
		if (p->extragruppe)
		{
			if (p->extra_right)
				p->extragruppe->Create(window(),w,p->mtop,w,h-p->mtop);
			else
				p->extragruppe->Create(window(),0,h,w,h-p->mtop);
			XUnmapWindow(display(),p->extragruppe->gg_win());
		}
		Size(w,h);
		p->gruppe->Resize(0,p->mtop,w,h-p->mtop);
 		if (p->extragruppe)
 		{
 			if (p->extra_right)
 				p->extragruppe->Resize(w,p->mtop,w,h-p->mtop);
 			else
 				p->extragruppe->Resize(0,h,w,h-p->mtop);
 		}
		if (p->amenu)
		{
			p->amenu->Dimensions(window(),0,0,w,p->mtop);
			p->amenu->Create();
		}
	}
	Open();

#ifdef EXTRABAR
	if (p->menubar)
	{
		int w,h;
		Size(display(),w,h);
//		DisplaySize(display(),w,h);

		p->menubar->InitSize(0,0,w,5);
		p->menubar->Init();
		p->menubar->TransientFor(this);
		p->menubar->Create();
	}
#endif

	p->winnode.text=(char*)this;
	allapps.AddTail(&p->winnode);

	Update();
	MakeFit();
	p->unalarm();
	MCursor(-1);
	return 1;
}
void appwindow::Close(void)
{
	p->alarmhandler2();

#ifdef EXTRABAR
	if (p->menubar) p->menubar->Close();
#endif
	if (window())
	{
		if (p->winnode.text)
		{
			allapps.Remove(&p->winnode);
			p->winnode.text=NULL;
		}
		{
			int x,y;
			int w,h;
			char buf[100];

			if (p->extragruppe && p->showextra)
			{
				HideExtra();
			}
			XFlush(display());

			WMPosition(x,y);
			Size(w,h);
			sprintf(buf,"%dx%d%+d%+d",w,h,x,y);
			SetResource("geometry",buf);
		}
		Xwindows::CloseU();
		if (p->amenu)
		{
			p->amenu->Free(); // slow
			p->amenu=NULL;
		}
		if (p->extragruppe)
		{
			p->extragruppe->Free(); // slow
			p->extragruppe=NULL;
		}
		p->gruppe->Free(); // slow
		p->gruppe=NULL;
		Xwindows::Destroy();
	}
	if (p->blocked) Unblock(0);
	p->unalarm();
}

void appwindow::Callback(void)
{
	p->cb.set(this,(CALLFUNCTION)&appwindow::Close);
}
void appwindow::Callback(void func(class appwindow*))
{
	p->cb.set((CBCAST) func);
}
void appwindow::Callback(void *c,void func(class appwindow*))
{
	p->cb.set(c,(CBCAST) func);
}
void appwindow::Callback(callable *c,void (callable::*func)(class appwindow*))
{
	p->cb.set(c,(CALLFUNCTION) func);
}
void appwindow::Callback(void *c,...)
{
	cbset(p->cb,c);
}
void appwindow::SetGroup(group *gp)
{
	p->gruppe=gp;
	gp->ParentClass(this);
}
void appwindow::SetGroup(group &gp)
{
	SetGroup(&gp);
}
void appwindow::SetExtraGroup(group *gp)
{
	p->extragruppe=gp;
	gp->ParentClass(this);
}
void appwindow::SetExtraGroup(group &gp)
{
	SetExtraGroup(&gp);
}

void appwindow::SetMenu(menu *mn)
{
#ifdef EXTRABAR
	if (EXTRABAR)
	{
		if (p->menugroup) delete p->menugroup;
		p->menugroup=new group;
		if (p->menubar) delete p->menubar;
		p->menubar=new appwindow;

		p->menugroup->Name(NULL);
		p->menugroup->Add(mn);
		p->menubar->SetGroup(p->menugroup);
		p->menubar->ParentClass(this);
		p->menubar->Name("menubarwindow");
		p->menubar->Name(NULL);
	}
	else
#endif
	{
		p->amenu=mn;
		mn->ParentClass(this);
	}
}
void appwindow::SetMenu(menu &mn)
{
	SetMenu(&mn);
}

void appwindow::ExtraRight(void)
{
	p->extra_right=1;
}
void appwindow::ExtraBottom(void)
{
	p->extra_right=0;
}

static int blockedcount=0;
void appwindow::Block(int b)
{
	if (!p->blocked)
	{
		if (p->amenu) p->amenu->Block(b);
		if (p->gruppe) p->gruppe->Block(b);
		if (p->extragruppe) p->extragruppe->Block(b);
#ifdef EXTRABAR
		if (p->menubar) p->menubar->Block(b);
#endif
		p->blocked=1;
		blockedcount++;
		MCursor(XC_watch);
		XFlush(display());
	}
}
void appwindow::Unblock(int b)
{
	if (p->blocked)
	{
		if (p->amenu) p->amenu->Unblock(b);
		if (p->gruppe) p->gruppe->Unblock(b);
		if (p->extragruppe) p->extragruppe->Unblock(b);
#ifdef EXTRABAR
		if (p->menubar) p->menubar->Unblock(b);
#endif
		p->blocked=0;
		blockedcount--;
		MCursor(-1);
		XFlush(display());
	}
}
void appwindow::BlockExcept(int b)
{
	if (!p->blocked)
	{
		struct node *n=allapps.head;
		while (n->next)
		{
			if (((appwindow*)n->text)!=this && !((appwindow*)n->text)->IsClassType("menubarwindow")) ((appwindow*)n->text)->Block(b);
			n=n->next;
		}
	}
}
void appwindow::UnblockExcept(int b)
{
	struct node *n=allapps.head;
	while (n->next)
	{
		if (((appwindow*)n->text)!=this && !((appwindow*)n->text)->IsClassType("menubarwindow")) ((appwindow*)n->text)->Unblock(b);
		n=n->next;
	}
}

void appwindow::ShowExtra(void)
{
	if (!p->showextra)
	{
		p->showextra=1;

		if (p->extragruppe)
		{
			int w1=p->gruppe->gg_width(),w2=p->extragruppe->gg_width(),h1=p->gruppe->gg_height()+p->mtop,h2=p->extragruppe->gg_height();
			int gw=w1+w2,gh=h1+h2;
			int x,y,w,h,dw,dh;
			int mwidth=0;

			if (p->amenu)
				mwidth=p->amenu->gg_minwidth();

			Position(x,y);
			Size(w,h);
			DisplaySize(display(),dw,dh);

			XMapRaised(display(),p->extragruppe->gg_win());
			if (p->extra_right)
			{
				Resize(gw,h);
				if (p->amenu) p->amenu->Resize(gw,p->mtop);
				MinSize(p->gruppe->gg_minwidth()+p->extragruppe->gg_minwidth()>mwidth?p->gruppe->gg_minwidth()+p->extragruppe->gg_minwidth():mwidth,p->gruppe->gg_minheight()+p->mtop);
				if (x+gw>dw)
				{
					x=dw-gw;
					if (x<0) x=0;
					Move(x,y);
				}
			}
			else
			{
				Resize(w,gh);
				MinSize(p->gruppe->gg_minwidth()>mwidth?p->gruppe->gg_minwidth():mwidth,p->gruppe->gg_minheight()+p->mtop+p->extragruppe->gg_minheight());
				if (y+gh>dh)
				{
					y=dh-gh;
					if (y<0) y=0;
					Move(x,y);
				}
			}
		}
	}
}
void appwindow::HideExtra(void)
{
	if (p->showextra)
	{
		p->showextra=0;

		if (p->extragruppe)
		{
			int w1=p->gruppe->gg_width(),h1=p->gruppe->gg_height();
			int w,h;
			int mwidth=0;

			if (p->amenu)
				mwidth=p->amenu->gg_minwidth();

			Size(w,h);

			XUnmapWindow(display(),p->extragruppe->gg_win());
			MinSize(p->gruppe->gg_minwidth()>mwidth?p->gruppe->gg_minwidth():mwidth,p->gruppe->gg_minheight()+p->mtop);
			if (p->gruppe->gg_maxwidth()<0xffffff || p->gruppe->gg_maxheight()<0xffffff)
			{
				int w,h;
				DisplaySize(display(),w,h);
				if (p->gruppe->gg_maxwidth()<w) w=p->gruppe->gg_maxwidth();
				if (p->gruppe->gg_maxheight()+p->mtop<h) h=p->gruppe->gg_maxheight()+p->mtop;
				MaxSize(w,h);
			}
			if (p->extra_right)
			{
				Resize(w1,h);
				if (p->amenu) p->amenu->Resize(w1,p->mtop);
			}
			else
			{
				Resize(w,h1+p->mtop);
			}
		}
	}
}

int appwindow::HandleEvent(XEvent *event)
{
	int r=0;
	if (event->xexpose.window==window())
	{
		if ((!onlywindow || onlywindow==window()) && IsCloseEvent(event) && !p->blocked)
		{
			p->closeme=1;
			if (p->cb.iscallback())
			{
				p->cb.call((void*)this);
			}
			else
			{
				r=1;
			}
		}
		else if (IsDestroyEvent(event))
		{
//printf("Destroy - Save yourself\n");
// 			p->closeme=1;
// 			if (p->cb.iscallback())
// 			{
// 				p->cb.call((int)this);
// 			}
// 			else
// 			{
// 				r=1;
// 			}
			DestroyContinue();
		}
		else
		{
			switch (event->type)
			{
				case ClientMessage:
					if (!strcmp(event->xclient.data.b,WAKEUPSTR))
					{
						r=2;
					}
					break;
				case ConfigureNotify:
				{
					if (p->extragruppe)
					{
						int w1=p->gruppe->gg_width(),w2=p->extragruppe->gg_width(),h1=p->gruppe->gg_height()+p->mtop,h2=p->extragruppe->gg_height();
						int gw=w1+w2,gh=h1+h2;
						int w,h;

						Size(w,h);

						if (p->extra_right)
						{
							h1=h;
							h2=h;
							if (p->showextra)
							{
								w2=(w*(1000*w2/gw))/1000;
								if (abs(w-w2-w1)<2)
									w2=w-w1;
								else
									w1=w-w2;
							}
							else
								w1=w;
							p->gruppe->Resize(w1,h1-p->mtop);
							p->extragruppe->Resize(w1,p->mtop,w2,h2-p->mtop);
						}
						else
						{
							w1=w;
							w2=w;
							if (p->showextra)
							{
								h2=(h*(1000*h2/gh))/1000;
								if (abs(h-h2-h1)<2)
									h2=h-h1;
								else
									h1=h-h2;
							}
							else
								h1=h;
							p->gruppe->Resize(w1,h1-p->mtop);
							p->extragruppe->Resize(0,h1,w2,h2);
						}
					}
					else
						p->gruppe->Resize(window(),p->mtop,0);
					if (p->amenu)
					{
						int w,h;
						Size(w,h);
						p->amenu->Resize(w,p->mtop);
					}
				}
				break;
			}
		}
	}
	else
	{ // andere appwindows prüfen
		if (event->type==ConfigureNotify || event->type==ClientMessage)
		{
			struct node *n;
			if (inrekursion)
			{
				n=p->winnode.next;
				if (n && n->next) r=((appwindow*)n->text)->HandleEvent(event);
			}
			else
			{
				inrekursion=1;
				n=allapps.head;
				if (n->next)
				{
					r=((appwindow*)n->text)->HandleEvent(event);
				}
				inrekursion=0;
			}
		}
	}
	return r;
}

int appwindow::NextEvent(void)
{
	XEvent event;
	int r;
	while (1)
	{
		switch(r=gadget::NextEvent(&event))
		{
			case -1: 
				return EV_TICK;
				break;
			case 0:
				{
					struct node *n=allapps.head;
					if (n->next && (r=((appwindow*)n->text)->HandleEvent(&event)))
					{
						if (r==1)
							return EV_WINDOWCLOSE;
						else
							return EV_WAKEUP;
					}
				}
				break;
			default:
				::ID=r;
				return EV_GADGET;
				break;
		}
		// noch appwindows da?
		if (allapps.Count()==0)
		{
			return EV_FINISH;
			// Warum das hier klappt:
			// beim Schliessen des Window wird ein Event gesendet,
			// gadget::NextEvent() -> 0, appwindow aber nicht mehr
			// in allapps Liste, allapps.Count()==0 -> Ende
		}
// 		if (onlywindow && onlywindow==event.xexpose.window)
// 		{
// 			// Warum:
// 			// Wenn das einzig freigegebene Fenster geschlossen
// 			// wird FINISH melden, so kann man Dialoge sowohl
// 			// sperrent und parallel machen.
// 			return EV_FINISH;
// 		}
		if (blockedcount>=allapps.Count())
		{
			// Warum:
			// Wenn das einzig freigegebene Fenster geschlossen
			// wird FINISH melden, so kann man Dialoge sowohl
			// sperrent und parallel machen.
			return EV_FINISH;
		}
	}
}
int appwindow::UpdateEvent(void)
{
	XEvent event;
	int r;
	switch(r=gadget::UpdateEvent(&event))
	{
		case -1: 
			return EV_TICK;
			break;
		case 0:
			{
				struct node *n=allapps.head;
				if (n->next && (r=((appwindow*)n->text)->HandleEvent(&event)))
				{
					if (r==1)
						return EV_WINDOWCLOSE;
					else
						return EV_WAKEUP;
				}
			}
			break;
		default:
			::ID=r;
			return EV_GADGET;
			break;
	}
	// noch appwindows da?
	if (allapps.Count()==0)
	{
		return EV_FINISH;
	}
// 	if (onlywindow && onlywindow==event.xexpose.window)
// 	{
// 		// Warum:
// 		// Wenn das einzig freigegebene Fenster geschlossen
// 		// wird FINISH melden, so kann man Dialoge sowohl
// 		// sperrent und parallel machen.
// 		return EV_FINISH;
// 	}
	if (blockedcount>=allapps.Count())
	{
		// Warum:
		// Wenn das einzig freigegebene Fenster geschlossen
		// wird FINISH melden, so kann man Dialoge sowohl
		// sperrent und parallel machen.
		return EV_FINISH;
	}
	return EV_NOTHING;
}
int appwindow::TickEvent(void)
{
	XEvent event;
	int r;
	while (1)
	{
		switch(r=gadget::TickEvent(&event))
		{
			case -1: 
				return EV_TICK;
				break;
			case 0:
				{
					struct node *n=allapps.head;
					if (n->next && (r=((appwindow*)n->text)->HandleEvent(&event)))
					{
						if (r==1)
							return EV_WINDOWCLOSE;
						else
							return EV_WAKEUP;
					}
				}
				break;
			default:
				::ID=r;
				return EV_GADGET;
				break;
		}
		// noch appwindows da?
		if (allapps.Count()==0)
		{
			return EV_FINISH;
		}
// 		if (onlywindow && onlywindow==event.xexpose.window)
// 		{
// 			// Warum:
// 			// Wenn das einzig freigegebene Fenster geschlossen
// 			// wird FINISH melden, so kann man Dialoge sowohl
// 			// sperrent und parallel machen.
// 			return EV_FINISH;
// 		}
		if (blockedcount>=allapps.Count())
		{
			// Warum:
			// Wenn das einzig freigegebene Fenster geschlossen
			// wird FINISH melden, so kann man Dialoge sowohl
			// sperrent und parallel machen.
			return EV_FINISH;
		}
	}
}
int appwindow::DoubleClick(void)
{
	return gadget::DoubleClick();
}
int appwindow::ID(void)
{
	return ::ID;
}
int appwindow::CloseMe(void)
{
	return p->closeme;
}

void appwindow::CloseAll(void)
{
	XClientMessageEvent xce;
	struct node *n;
	appwindow *aw;
	n=allapps.head;
	while (n->next)
	{
		aw=(appwindow*)n->text;
		xce.type=ClientMessage;
		xce.serial=0;
		xce.display=aw->display();
		xce.window=aw->window();
		xce.message_type=XInternAtom(aw->display(),"WM_DELETE_WINDOW",False);
		xce.format=32;
		xce.data.l[0]=XInternAtom(aw->display(),"WM_DELETE_WINDOW",False);
		XSendEvent(aw->display(),aw->window(),False,ClientMessage,(XEvent*)&xce);
		n=n->next;
	}
}
void appwindow::WakeUp(void)
{
	XClientMessageEvent xce;
	struct node *n;
	appwindow *aw;
	n=allapps.head;
	if (n->next)
	{
		aw=(appwindow*)n->text;
		xce.type=ClientMessage;
		xce.serial=0;
		xce.display=aw->display();
		xce.window=aw->window();
		xce.message_type=0;
		xce.format=8;
		strcpy(xce.data.b,WAKEUPSTR);
		XSendEvent(aw->display(),aw->window(),False,ClientMessage,(XEvent*)&xce);
	}
}

#endif
