/******************************************************************************
 JXAssert.cc

	We insure that all keyboard and mouse grabs are released.

	BASE CLASS = JAssertBase

	Copyright © 1997 by John Lindal. All rights reserved.

 *****************************************************************************/

#include <JXAssert.h>
#include <JXApplication.h>
#include <JXDisplay.h>
#include <X11/Xlib.h>
#include <stdio.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

 ******************************************************************************/

JXAssert::JXAssert()
	:
	JAssertBase()
{
	itsIsOperatingFlag = kTrue;

	itsDisplayList = new JPtrArray<JXDisplay>;
	assert( itsDisplayList != NULL );

	itsIsOperatingFlag = kFalse;
}

/******************************************************************************
 Destructor

 ******************************************************************************/

JXAssert::~JXAssert()
{
	itsIsOperatingFlag = kTrue;

	JPtrArray<JXDisplay>* list = itsDisplayList;
	itsDisplayList = NULL;
	delete list;

	itsIsOperatingFlag = kFalse;
}

/******************************************************************************
 Assert (virtual)

 ******************************************************************************/

int
JXAssert::Assert
	(
	const JCharacter*	expr,
	const JCharacter*	file,
	const int			line
	)
{
	const JBoolean wasOperating = itsIsOperatingFlag;
	itsIsOperatingFlag = kTrue;

	if (wasOperating || itsDisplayList == NULL)		// prevents infinite recursion
		{
		fprintf(stderr, "\nError inside fatal error handler!\n\n");
		}
	else
		{
		UnlockDisplays();
		}

	const int result = JAssertBase::DefaultAssert(expr, file, line);

	itsIsOperatingFlag = wasOperating;
	return result;
}

/******************************************************************************
 Abort (virtual)

	We call JXApplication::Abort().

 ******************************************************************************/

void
JXAssert::Abort()
{
	JXApplication::Abort(JXDocumentManager::kAssertFired, kTrue);
}

/******************************************************************************
 UnlockDisplays

 ******************************************************************************/

void
JXAssert::UnlockDisplays()
{
	const JSize count = itsDisplayList->GetElementCount();
	for (JIndex i=1; i<=count; i++)
		{
		JXDisplay* display = itsDisplayList->NthElement(i);
		Display* xDisplay  = display->GetXDisplay();
		XUngrabServer(xDisplay);
		XUngrabPointer(xDisplay, CurrentTime);
		XUngrabKeyboard(xDisplay, CurrentTime);
		display->Flush();
		}
}
