/*
 * AT-SPI - Assistive Technology Service Provider Interface
 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
 *
 * Copyright 2001, 2002 Sun Microsystems Inc.,
 * Copyright 2001, 2002 Ximian, Inc.
 *
 * 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 <stdio.h>
#include "../cspi/spi-private.h" /* A hack for now */

#define XK_MISCELLANY
#include <X11/keysymdef.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>

#include <X11/XKBlib.h>

static void report_focus_event    		(const AccessibleEvent *event, void *user_data);
static void report_window_event  		(const AccessibleEvent *event, void *user_data);
static SPIBoolean ke_report_layer_key_event 	(const AccessibleKeystroke *key, gpointer user_data);

static AccessibleEventListener 		*focus_listener;
static AccessibleEventListener 		*window_listener;
static AccessibleKeystrokeListener 	*ke_layer_listener;

static AccessibleKeySet *ke_layer_keyset  = NULL;

static short*
ke_get_keypad_keycodes (void)
{
    Display *display;
    short *keycodes = (short *) g_new0 (short *, 17);	

    display = GDK_DISPLAY ();

    if (!display)
	g_print ("\nInvalid display");
    
    keycodes [0] = XKeysymToKeycode (display, XK_KP_0);
    keycodes [1] = XKeysymToKeycode (display, XK_KP_1);
    keycodes [2] = XKeysymToKeycode (display, XK_KP_2);
    keycodes [3] = XKeysymToKeycode (display, XK_KP_3);
    keycodes [4] = XKeysymToKeycode (display, XK_KP_4);
    keycodes [5] = XKeysymToKeycode (display, XK_KP_5);
    keycodes [6] = XKeysymToKeycode (display, XK_KP_6);
    keycodes [7] = XKeysymToKeycode (display, XK_KP_7);
    keycodes [8] = XKeysymToKeycode (display, XK_KP_8);
    keycodes [9] = XKeysymToKeycode (display, XK_KP_9);
    keycodes [10] = XKeysymToKeycode (display, XK_KP_Decimal);
    keycodes [11] = XKeysymToKeycode (display, XK_KP_Enter);
    keycodes [12] = XKeysymToKeycode (display, XK_KP_Add);
    keycodes [13] = XKeysymToKeycode (display, XK_KP_Subtract);
    keycodes [14] = XKeysymToKeycode (display, XK_KP_Multiply);
    keycodes [15] = XKeysymToKeycode (display, XK_KP_Divide);
    keycodes [16] = XKeysymToKeycode (display, XK_KP_Separator);
    	
    return keycodes;
}

static gboolean
ke_layer_register_events (AccessibleKeystrokeListener *ke_layer_listener,
			  AccessibleKeySet 	      *ke_layer_keyset)
{
    gboolean retval = TRUE;
  
    retval = SPI_registerAccessibleKeystrokeListener (ke_layer_listener,
				      (AccessibleKeySet *) ke_layer_keyset,
				      SPI_KEYMASK_NUMLOCK,
				      (gulong) ( SPI_KEY_PRESSED | SPI_KEY_RELEASED ),
				      SPI_KEYLISTENER_ALL_WINDOWS);

    return retval;
}

int
main (int argc, char **argv)
{
    SPI_init ();
    gdk_init (&argc, &argv);

    focus_listener = SPI_createAccessibleEventListener (report_focus_event, NULL);
    window_listener = SPI_createAccessibleEventListener (report_window_event, NULL); 
    ke_layer_listener = SPI_createAccessibleKeystrokeListener (ke_report_layer_key_event, NULL);

    ke_layer_keyset = SPI_createAccessibleKeySet (17, NULL, ke_get_keypad_keycodes (), NULL);    
    
    SPI_registerGlobalEventListener (focus_listener, "focus:");  
    SPI_registerGlobalEventListener (window_listener, "window:activate");      
    ke_layer_register_events (ke_layer_listener,(AccessibleKeySet *) ke_layer_keyset);
  
    SPI_event_main ();

    return SPI_exit ();
}

static void
report_focus_event (const AccessibleEvent *event, void *user_data)
{
    g_print ("\nFOCUS EVENT!!!");   
}


static void
report_window_event (const AccessibleEvent *event, void *user_data)
{
    g_print ("\nWINDOW ACTIVATE!!!");
}


static SPIBoolean 
ke_report_layer_key_event (const AccessibleKeystroke *key, gpointer user_data)
{
    g_print ("\nLAYER EVENT!!!");
    return TRUE;
}
