/* $Id: Accelerator.c,v 1.1 1997/04/17 13:20:38 archer Exp $
 *	ACCELERATOR.C - Handle hotkeys
 *
 * Mostly called by Shell widget, but separate for clarity's sake.
 */
#include <Widget/ShellP.h>
#include <Widget/Manage.h>
#include <X11/keysym.h>


/**
 ** X11_ACCELERATOR_CANCEL
 **	Remove accelerators from the shell
 **/
void X11_AcceleratorCancel(X11_widget wdg)
{
x11__shell	*s;
x11__key	*p, *n;
/*
 * Any shell ?
 */
	if ((s = (x11__shell *)(wdg->shell)) == 0)
		return;
	p = 0;
	n = s->accelerators;
/*
 * Loop on all accelerators
 */
	while (n)
		if (n->requester == wdg) {
/*
 * Drop accelerator for this widget
 */
			if (p) {
				p->next = n->next;
				free(n);
				n = p->next;
			} else {
				s->accelerators = n->next;
				free(n);
				n = s->accelerators;
			}
/*
 * Scan next accelerator
 */
		} else {
			p = n;
			n = n->next;
		}
}


/**
 ** X11_ACCELERATOR
 **	Declare an accelerator to the shell
 **/
void X11_Accelerator(X11_widget wdg, KeySym key, int modifiers,
					X11_callback c, void *data)
{
x11__shell	*s;
x11__key	*p, *k;
/*
 * On which shell?
 */
	s = (x11__shell *)wdg->shell;
/*
 * Accelerator registered
 */
	p = 0;
	for (k = s->accelerators; k; k = k->next)
		if (k->requester == wdg &&
		    k->key == key &&
		    k->modifiers == modifiers)
			break;
		else
			p = k;
/*
 * Pre-registered?
 */
	if (k) {
		if (c) {
			k->requester = wdg;
			k->data      = data;
			k->call      = c;
			return;
		}
/*
 * Drop
 */
		if (p)
			p->next = k->next;
		else
			s->accelerators = k->next;
		free(k);
		return;
	}
/*
 * Nothing to do?
 */
	if (!c)
		return;
	k = allocator(x11__key);
	k->key       = key;
	k->modifiers = modifiers;
	k->call      = c;
	k->requester = wdg;
	k->data      = data;
	k->next      = s->accelerators;
	s->accelerators = k;
}
