/******************************************************************************
 jXEventUtil.cc

	Useful functions for dealing with X events.

	Copyright © 1996 John Lindal. All rights reserved.

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

#include <jXEventUtil.h>
#include <JXDisplay.h>
#include <ctype.h>
#include <jAssert.h>

/******************************************************************************
 JXIsPrint

	Returns kTrue if the keysym is between 1 and 255 and isprint() returns
	kTrue.

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

JBoolean
JXIsPrint
	(
	const int keysym
	)
{
	return JConvertToBoolean( 0 < keysym && keysym <= 255 && isprint(keysym) );
}

/******************************************************************************
 JXGetEventTime

	Return the time stamp of the event.  Returns kFalse if the given
	event doesn't contain a time stamp.

	Selection events contain a time field, but this is a timestamp generated
	by clients, not the current server time.

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

JBoolean
JXGetEventTime
	(
	const XEvent&	xEvent,
	Time*			time
	)
{
	*time = 0;

	if (xEvent.type == KeyPress || xEvent.type == KeyRelease)
		{
		*time = xEvent.xkey.time;
		return kTrue;
		}
	else if (xEvent.type == ButtonPress || xEvent.type == ButtonRelease)
		{
		*time = xEvent.xbutton.time;
		return kTrue;
		}
	else if (xEvent.type == MotionNotify)
		{
		*time = xEvent.xmotion.time;
		return kTrue;
		}
	else if (xEvent.type == EnterNotify || xEvent.type == LeaveNotify)
		{
		*time = xEvent.xcrossing.time;
		return kTrue;
		}
	else if (xEvent.type == PropertyNotify)
		{
		*time = xEvent.xproperty.time;
		return kTrue;
		}
	else
		{
		return kFalse;		// event doesn't contain the information
		}
}

/******************************************************************************
 JXGetButtonAndModifierStates

	Return the button and key modifiers states of the event.
	Returns kFalse if the given event doesn't contain the information.

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

JBoolean
JXGetButtonAndModifierStates
	(
	const XEvent&	xEvent,
	JXDisplay*		display,
	unsigned int*	state
	)
{
	*state = 0;

	if (xEvent.type == KeyPress)
		{
		*state = xEvent.xkey.state;
		JIndex modifierIndex;
		if (display->KeycodeToModifier(xEvent.xkey.keycode, &modifierIndex))
			{
			*state = JXKeyModifiers::SetState(*state, modifierIndex, kTrue);
			}
		return kTrue;
		}
	else if (xEvent.type == KeyRelease)
		{
		*state = xEvent.xkey.state;
		JIndex modifierIndex;
		if (display->KeycodeToModifier(xEvent.xkey.keycode, &modifierIndex))
			{
			*state = JXKeyModifiers::SetState(*state, modifierIndex, kFalse);
			}
		return kTrue;
		}
	else if (xEvent.type == ButtonPress)
		{
		const JXMouseButton currButton =
			static_cast<JXMouseButton>(xEvent.xbutton.button);
		*state = JXButtonStates::SetState(xEvent.xbutton.state,
										  currButton, kTrue);
		return kTrue;
		}
	else if (xEvent.type == ButtonRelease)
		{
		const JXMouseButton currButton =
			static_cast<JXMouseButton>(xEvent.xbutton.button);
		*state = JXButtonStates::SetState(xEvent.xbutton.state,
										  currButton, kFalse);
		return kTrue;
		}
	else if (xEvent.type == MotionNotify)
		{
		*state = xEvent.xmotion.state;
		return kTrue;
		}
	else if (xEvent.type == EnterNotify || xEvent.type == LeaveNotify)
		{
		*state = xEvent.xcrossing.state;
		return kTrue;
		}
	else
		{
		return kFalse;		// event doesn't contain the information
		}
}
