changeset 934:c925bacdda60

[xemacs-hg @ 2002-07-29 09:21:12 by michaels] 2002-07-17 Marcus Crestani <crestani@informatik.uni-tuebingen.de> Markus Kaltenbach <makalten@informatik.uni-tuebingen.de> Mike Sperber <mike@xemacs.org> configure flag to turn these changes on: --use-kkcc First we added a dumpable flag to lrecord_implementation. It shows, if the object is dumpable and should be processed by the dumper. * lrecord.h (struct lrecord_implementation): added dumpable flag (MAKE_LRECORD_IMPLEMENTATION): fitted the different makro definitions to the new lrecord_implementation and their calls. Then we changed mark_object, that it no longer needs a mark method for those types that have pdump descritions. * alloc.c: (mark_object): If the object has a description, the new mark algorithm is called, and the object is marked according to its description. Otherwise it uses the mark method like before. These procedures mark objects according to their descriptions. They are modeled on the corresponding pdumper procedures. (mark_with_description): (get_indirect_count): (structure_size): (mark_struct_contents): These procedures still call mark_object, this is needed while there are Lisp_Objects without descriptions left. We added pdump descriptions for many Lisp_Objects: * extents.c: extent_auxiliary_description * database.c: database_description * gui.c: gui_item_description * scrollbar.c: scrollbar_instance_description * toolbar.c: toolbar_button_description * event-stream.c: command_builder_description * mule-charset.c: charset_description * device-msw.c: devmode_description * dialog-msw.c: mswindows_dialog_id_description * eldap.c: ldap_description * postgresql.c: pgconn_description pgresult_description * tooltalk.c: tooltalk_message_description tooltalk_pattern_description * ui-gtk.c: emacs_ffi_description emacs_gtk_object_description * events.c: * events.h: * event-stream.c: * event-Xt.c: * event-gtk.c: * event-tty.c: To write a pdump description for Lisp_Event, we converted every struct in the union event to a Lisp_Object. So we created nine new Lisp_Objects: Lisp_Key_Data, Lisp_Button_Data, Lisp_Motion_Data, Lisp_Process_Data, Lisp_Timeout_Data, Lisp_Eval_Data, Lisp_Misc_User_Data, Lisp_Magic_Data, Lisp_Magic_Eval_Data. We also wrote makro selectors and mutators for the fields of the new designed Lisp_Event and added everywhere these new abstractions. We implemented XD_UNION support in (mark_with_description), so we can describe exspecially console/device specific data with XD_UNION. To describe with XD_UNION, we added a field to these objects, which holds the variant type of the object. This field is initialized in the appendant constructor. The variant is an integer, it has also to be described in an description, if XD_UNION is used. XD_UNION is used in following descriptions: * console.c: console_description (get_console_variant): returns the variant (create_console): added variant initialization * console.h (console_variant): the different console types * console-impl.h (struct console): added enum console_variant contype * device.c: device_description (Fmake_device): added variant initialization * device-impl.h (struct device): added enum console_variant devtype * objects.c: image_instance_description font_instance_description (Fmake_color_instance): added variant initialization (Fmake_font_instance): added variant initialization * objects-impl.h (struct Lisp_Color_Instance): added color_instance_type * objects-impl.h (struct Lisp_Font_Instance): added font_instance_type * process.c: process_description (make_process_internal): added variant initialization * process.h (process_variant): the different process types
author michaels
date Mon, 29 Jul 2002 09:21:25 +0000
parents f6bc42928b34
children 7ddc4c0b471d
files src/ChangeLog src/alloc.c src/buffer.c src/bytecode.c src/casetab.c src/chartab.c src/console-impl.h src/console.c src/console.h src/data.c src/database.c src/device-impl.h src/device-msw.c src/device.c src/dialog-msw.c src/dumper.c src/eldap.c src/elhash.c src/event-Xt.c src/event-stream.c src/event-tty.c src/events.c src/events.h src/extents.c src/faces.c src/file-coding.c src/floatfns.c src/fns.c src/frame.c src/glyphs.c src/gpmevent.c src/gui-x.c src/gui.c src/keymap.c src/lisp.h src/lrecord.h src/lstream.c src/marker.c src/menubar-x.c src/mule-charset.c src/objects-impl.h src/objects.c src/opaque.c src/postgresql.c src/process.c src/process.h src/procimpl.h src/rangetab.c src/scrollbar.c src/specifier.c src/symbols.c src/toolbar.c src/tooltalk.c src/ui-gtk.c src/window.c
diffstat 55 files changed, 4259 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/ChangeLog	Mon Jul 29 09:21:25 2002 +0000
@@ -1,3 +1,93 @@
+2002-07-17  Marcus Crestani  <crestani@informatik.uni-tuebingen.de>
+	    Markus Kaltenbach  <makalten@informatik.uni-tuebingen.de>
+	    Mike Sperber <mike@xemacs.org>
+
+	configure flag to turn these changes on: --use-kkcc
+	
+	First we added a dumpable flag to lrecord_implementation. It shows,
+	if the object is dumpable and should be processed by the dumper.
+	* lrecord.h (struct lrecord_implementation): added dumpable flag
+	(MAKE_LRECORD_IMPLEMENTATION): fitted the different makro definitions
+	to the new lrecord_implementation and their calls.
+
+	Then we changed mark_object, that it no longer needs a mark method for
+	those types that have pdump descritions.
+	* alloc.c: 
+	(mark_object): If the object has a description, the new mark algorithm
+	is called, and the object is marked according to its description. 
+	Otherwise it uses the mark method like before.
+	
+	These procedures mark objects according to their descriptions. They 
+	are modeled on the corresponding pdumper procedures.
+	(mark_with_description): 
+	(get_indirect_count): 
+	(structure_size): 
+	(mark_struct_contents): 
+	These procedures still call mark_object, this is needed while there are
+	Lisp_Objects without descriptions left.
+
+	We added pdump descriptions for many Lisp_Objects:
+	* extents.c: extent_auxiliary_description
+	* database.c: database_description
+	* gui.c: gui_item_description
+	* scrollbar.c: scrollbar_instance_description
+	* toolbar.c: toolbar_button_description
+	* event-stream.c: command_builder_description
+	* mule-charset.c: charset_description
+	* device-msw.c: devmode_description
+	* dialog-msw.c: mswindows_dialog_id_description
+	* eldap.c: ldap_description
+	* postgresql.c: pgconn_description
+			pgresult_description
+	* tooltalk.c: tooltalk_message_description
+		      tooltalk_pattern_description
+	* ui-gtk.c: emacs_ffi_description
+	            emacs_gtk_object_description
+
+	* events.c:
+	* events.h:
+	* event-stream.c:
+	* event-Xt.c:
+	* event-gtk.c:
+	* event-tty.c:
+	To write a pdump description for Lisp_Event, we converted every struct
+	in the union event to a Lisp_Object. So we created nine new 
+	Lisp_Objects: Lisp_Key_Data, Lisp_Button_Data, Lisp_Motion_Data,
+	Lisp_Process_Data, Lisp_Timeout_Data, Lisp_Eval_Data, 
+	Lisp_Misc_User_Data, Lisp_Magic_Data, Lisp_Magic_Eval_Data.
+	We also wrote makro selectors and mutators for the fields of the new 
+	designed Lisp_Event and added everywhere these new abstractions.
+
+
+	We implemented XD_UNION support in (mark_with_description), so
+	we can describe exspecially console/device specific data with XD_UNION.
+	To describe with XD_UNION, we added a field to these objects, which 
+	holds the variant type of the object. This field is initialized in 
+	the appendant constructor. The variant is an integer, it has also to 
+	be described in an description, if XD_UNION is used.
+
+	XD_UNION is used in following descriptions:	
+	* console.c: console_description
+	(get_console_variant): returns the variant
+	(create_console): added variant initialization
+	* console.h (console_variant): the different console types
+	* console-impl.h (struct console): added enum console_variant contype
+
+	* device.c: device_description
+	(Fmake_device): added variant initialization
+	* device-impl.h (struct device): added enum console_variant devtype
+
+	* objects.c: image_instance_description
+	             font_instance_description
+	(Fmake_color_instance): added variant initialization
+	(Fmake_font_instance): added variant initialization
+	* objects-impl.h (struct Lisp_Color_Instance): added color_instance_type
+	* objects-impl.h (struct Lisp_Font_Instance): added font_instance_type
+
+	* process.c: process_description
+	(make_process_internal): added variant initialization
+	* process.h (process_variant): the different process types
+
 2002-07-27  Steve Youngs  <youngs@xemacs.org>
 
 	* XEmacs 21.5.8 "broccoli" is released.
--- a/src/alloc.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/alloc.c	Mon Jul 29 09:21:25 2002 +0000
@@ -61,6 +61,10 @@
 #include "window.h"
 #include "console-stream.h"
 
+#ifdef USE_KKCC
+#include "file-coding.h"
+#endif /* USE_KKCC */
+
 #ifdef DOUG_LEA_MALLOC
 #include <malloc.h>
 #endif
@@ -937,6 +941,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons,
+				     1, /*dumpable-flag*/
+				     mark_cons, print_cons, 0,
+				     cons_equal,
+				     /*
+				      * No `hash' method needed.
+				      * internal_hash knows how to
+				      * handle conses.
+				      */
+				     0,
+				     cons_description,
+				     Lisp_Cons);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons,
 				     mark_cons, print_cons, 0,
 				     cons_equal,
@@ -948,6 +966,7 @@
 				     0,
 				     cons_description,
 				     Lisp_Cons);
+#endif /* not USE_KKCC */
 
 DEFUN ("cons", Fcons, 2, 2, 0, /*
 Create a new cons, give it CAR and CDR as components, and return it.
@@ -1155,13 +1174,22 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector,
+				       1, /*dumpable-flag*/
+				       mark_vector, print_vector, 0,
+				       vector_equal,
+				       vector_hash,
+				       vector_description,
+				       size_vector, Lisp_Vector);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector,
 				       mark_vector, print_vector, 0,
 				       vector_equal,
 				       vector_hash,
 				       vector_description,
 				       size_vector, Lisp_Vector);
-
+#endif /* not USE_KKCC */
 /* #### should allocate `small' vectors from a frob-block */
 static Lisp_Vector *
 make_vector_internal (Elemcount sizei)
@@ -1661,6 +1689,133 @@
   return wrap_event (e);
 }
 
+#ifdef USE_KKCC
+DECLARE_FIXED_TYPE_ALLOC (key_data, Lisp_Key_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_key_data 1000
+
+Lisp_Object
+allocate_key_data (void)
+{
+  Lisp_Key_Data *d;
+
+  ALLOCATE_FIXED_TYPE (key_data, Lisp_Key_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_key_data);
+
+  return wrap_key_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (button_data, Lisp_Button_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_button_data 1000
+
+Lisp_Object
+allocate_button_data (void)
+{
+  Lisp_Button_Data *d;
+
+  ALLOCATE_FIXED_TYPE (button_data, Lisp_Button_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_button_data);
+
+  return wrap_button_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (motion_data, Lisp_Motion_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_motion_data 1000
+
+Lisp_Object
+allocate_motion_data (void)
+{
+  Lisp_Motion_Data *d;
+
+  ALLOCATE_FIXED_TYPE (motion_data, Lisp_Motion_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_motion_data);
+
+  return wrap_motion_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (process_data, Lisp_Process_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_process_data 1000
+
+Lisp_Object
+allocate_process_data (void)
+{
+  Lisp_Process_Data *d;
+
+  ALLOCATE_FIXED_TYPE (process_data, Lisp_Process_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_process_data);
+
+  return wrap_process_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (timeout_data, Lisp_Timeout_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_timeout_data 1000
+
+Lisp_Object
+allocate_timeout_data (void)
+{
+  Lisp_Timeout_Data *d;
+
+  ALLOCATE_FIXED_TYPE (timeout_data, Lisp_Timeout_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_timeout_data);
+
+  return wrap_timeout_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (magic_data, Lisp_Magic_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_magic_data 1000
+
+Lisp_Object
+allocate_magic_data (void)
+{
+  Lisp_Magic_Data *d;
+
+  ALLOCATE_FIXED_TYPE (magic_data, Lisp_Magic_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_magic_data);
+
+  return wrap_magic_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (magic_eval_data, Lisp_Magic_Eval_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_magic_eval_data 1000
+
+Lisp_Object
+allocate_magic_eval_data (void)
+{
+  Lisp_Magic_Eval_Data *d;
+
+  ALLOCATE_FIXED_TYPE (magic_eval_data, Lisp_Magic_Eval_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_magic_eval_data);
+
+  return wrap_magic_eval_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (eval_data, Lisp_Eval_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_eval_data 1000
+
+Lisp_Object
+allocate_eval_data (void)
+{
+  Lisp_Eval_Data *d;
+
+  ALLOCATE_FIXED_TYPE (eval_data, Lisp_Eval_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_eval_data);
+
+  return wrap_eval_data(d);
+}
+
+DECLARE_FIXED_TYPE_ALLOC (misc_user_data, Lisp_Misc_User_Data);
+#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_misc_user_data 1000
+
+Lisp_Object
+allocate_misc_user_data (void)
+{
+  Lisp_Misc_User_Data *d;
+
+  ALLOCATE_FIXED_TYPE (misc_user_data, Lisp_Misc_User_Data, d);
+  set_lheader_implementation (&d->lheader, &lrecord_misc_user_data);
+
+  return wrap_misc_user_data(d);
+}
+#endif /* USE_KKCC */
 
 /************************************************************************/
 /*			 Marker allocation				*/
@@ -1799,6 +1954,18 @@
    is done with the ADDITIONAL_FREE_string macro, which is the
    standard way to do finalization when using
    SWEEP_FIXED_TYPE_BLOCK(). */
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string,
+						1, /*dumpable-flag*/
+						mark_string, print_string,
+						0, string_equal, 0,
+						string_description,
+						string_getprop,
+						string_putprop,
+						string_remprop,
+						string_plist,
+						Lisp_String);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string,
 						mark_string, print_string,
 						0, string_equal, 0,
@@ -1808,7 +1975,7 @@
 						string_remprop,
 						string_plist,
 						Lisp_String);
-
+#endif /* not USE_KKCC */
 /* String blocks contain this many useful bytes. */
 #define STRING_CHARS_BLOCK_SIZE					\
   ((Bytecount) (8192 - MALLOC_OVERHEAD -			\
@@ -2380,9 +2547,17 @@
   return Qnil;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list,
+			       0, /*dumpable-flag*/
+			       mark_lcrecord_list, internal_object_printer,
+			       0, 0, 0, 0, struct lcrecord_list);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list,
 			       mark_lcrecord_list, internal_object_printer,
 			       0, 0, 0, 0, struct lcrecord_list);
+#endif /* not USE_KKCC */
+
 Lisp_Object
 make_lcrecord_list (Elemcount size,
 		    const struct lrecord_implementation *implementation)
@@ -2663,7 +2838,342 @@
 #define GC_CHECK_LHEADER_INVARIANTS(lheader)
 #endif
 
-
+
+
+#ifdef USE_KKCC
+/* The following functions implement the new mark algorithm. 
+   They mark objects according to their descriptions. They 
+   are modeled on the corresponding pdumper procedures. */
+
+static void mark_struct_contents (const void *data,
+						   const struct struct_description *
+						   sdesc,
+						   int count);
+
+/* This function extracts the value of a count variable described somewhere 
+   else in the description. It is converted corresponding to the type */ 
+static EMACS_INT
+get_indirect_count (EMACS_INT code,
+			  const struct lrecord_description *idesc,
+			  const void *idata)
+{
+  EMACS_INT count;
+  const void *irdata;
+
+  int line = XD_INDIRECT_VAL (code);
+  int delta = XD_INDIRECT_DELTA (code);
+
+  irdata = ((char *)idata) + idesc[line].offset;
+  switch (idesc[line].type)
+    {
+    case XD_BYTECOUNT:
+      count = *(Bytecount *)irdata;
+      break;
+    case XD_ELEMCOUNT:
+      count = *(Elemcount *)irdata;
+      break;
+    case XD_HASHCODE:
+      count = *(Hashcode *)irdata;
+      break;
+    case XD_INT:
+      count = *(int *)irdata;
+      break;
+    case XD_LONG:
+      count = *(long *)irdata;
+      break;
+    default:
+      stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n",
+		  idesc[line].type, line, (long)code);
+      count = 0; /* warning suppression */
+      abort ();
+    }
+  count += delta;
+  return count;
+}
+
+/* This function is called to mark the elements of an object. It processes
+   the description of the object and calls mark object with every described
+   object. */
+static void
+mark_with_description (const void *lheader, const struct lrecord_description *desc)
+{
+  int pos;
+
+  static const Lisp_Object *last_occured_object = (Lisp_Object *) 0;
+  static int mark_last_occured_object = 0;
+
+ reprocess_desc:
+  for (pos=0; desc[pos].type != XD_END; pos++)
+    {
+      const void *rdata = (const char *)lheader + desc[pos].offset;
+      switch (desc[pos].type) {
+      case XD_LISP_OBJECT: 
+	{
+	  const Lisp_Object *stored_obj = (const Lisp_Object *)rdata;
+	  if (!(*stored_obj)){
+	    break;
+	  }
+
+	  if (desc[pos+1].type == XD_END)
+	    {
+	      mark_last_occured_object = 1;
+	      last_occured_object = stored_obj;
+	      break;
+	    }
+	  else
+	    {
+	      mark_object (*stored_obj);
+	    }
+	  
+	  
+	  break;
+	}
+      case XD_LISP_OBJECT_ARRAY:
+	{
+	  int i;
+	  EMACS_INT count = desc[pos].data1;
+	  if (XD_IS_INDIRECT (count))
+	    count = get_indirect_count (count, desc, lheader);
+	
+	  for (i = 0; i < count; i++)
+	    {
+	      const Lisp_Object *stored_obj = ((const Lisp_Object *)rdata) + i;
+	      if (!(*stored_obj))
+		{
+		  break;
+		}
+
+	      mark_object (*stored_obj);
+	    }
+	  break;
+	}
+      case XD_SPECIFIER_END:
+	desc = ((const Lisp_Specifier *)lheader)->methods->extra_description;
+	goto reprocess_desc;
+	break;
+      case XD_CODING_SYSTEM_END:
+	desc = ((const Lisp_Coding_System *)lheader)->methods->extra_description;
+	goto reprocess_desc;
+	break;
+      case XD_BYTECOUNT:
+	break;
+      case XD_ELEMCOUNT:
+	break;
+      case XD_HASHCODE:
+	break;
+      case XD_INT:
+	break;
+      case XD_LONG:
+	break;
+      case XD_INT_RESET:
+	break;
+      case XD_LO_LINK:
+	break;
+      case XD_OPAQUE_PTR:
+	break;
+      case XD_OPAQUE_DATA_PTR:
+	break;
+      case XD_C_STRING:
+	break;
+      case XD_DOC_STRING:
+	break;
+      case XD_STRUCT_PTR:
+	{
+	  EMACS_INT count = desc[pos].data1;
+	  const struct struct_description *sdesc = desc[pos].data2;
+	  const char *dobj = *(const char **)rdata;
+	  if (dobj)
+	    {
+	      if (XD_IS_INDIRECT (count))
+		count = get_indirect_count (count, desc, lheader);
+	      mark_struct_contents (dobj, sdesc, count);
+	    }
+	  break;
+	}
+      case XD_STRUCT_ARRAY:
+	{
+	  EMACS_INT count = desc[pos].data1;
+	  const struct struct_description *sdesc = desc[pos].data2;
+		      
+	  if (XD_IS_INDIRECT (count))
+	    count = get_indirect_count (count, desc, lheader);
+		      
+	  mark_struct_contents (rdata, sdesc, count);
+	  break;
+	}
+      case XD_UNION:
+	{
+	  int count = 0;
+	  int variant = desc[pos].data1;
+	  const struct struct_description *sdesc = desc[pos].data2;
+	  const char *dobj = *(const char **)rdata;
+	  if (XD_IS_INDIRECT (variant))
+	    variant = get_indirect_count (variant, desc, lheader);
+	  
+	  for (count=0; sdesc[count].size != XD_END; count++)
+	    {
+	      if (sdesc[count].size == variant)
+		{
+		  mark_with_description(dobj, sdesc[count].description);
+		  break;
+		}
+	    }
+	  break;
+	}
+		    
+      default:
+	stderr_out ("Unsupported description type : %d\n", desc[pos].type);
+	abort ();
+      }
+    }
+
+  if (mark_last_occured_object)
+    {
+      mark_object(*last_occured_object);
+      mark_last_occured_object = 0;
+    }
+}
+
+
+/* This function calculates the size of a described struct. */
+static Bytecount
+structure_size (const void *obj, const struct struct_description *sdesc)
+{
+  int max_offset = -1;
+  int max_offset_pos = -1;
+  int size_at_max = 0;
+  int pos;
+  const struct lrecord_description *desc;
+  void *rdata;
+
+  if (sdesc->size)
+    return sdesc->size;
+
+  desc = sdesc->description;
+
+  for (pos = 0; desc[pos].type != XD_END; pos++)
+    {
+      if (desc[pos].offset == max_offset)
+	{
+	  stderr_out ("Two relocatable elements at same offset?\n");
+	  abort ();
+	}
+      else if (desc[pos].offset > max_offset)
+	{
+	  max_offset = desc[pos].offset;
+	  max_offset_pos = pos;
+	}
+    }
+
+  if (max_offset_pos < 0)
+    return 0;
+
+  pos = max_offset_pos;
+  rdata = (char *) obj + desc[pos].offset;
+
+  switch (desc[pos].type)
+    {
+    case XD_LISP_OBJECT_ARRAY:
+      {
+	EMACS_INT val = desc[pos].data1;
+	if (XD_IS_INDIRECT (val))
+	  val = get_indirect_count (val, desc, obj);
+	size_at_max = val * sizeof (Lisp_Object);
+	break;
+      }
+    case XD_LISP_OBJECT:
+    case XD_LO_LINK:
+      size_at_max = sizeof (Lisp_Object);
+      break;
+    case XD_OPAQUE_PTR:
+      size_at_max = sizeof (void *);
+      break;
+    case XD_STRUCT_PTR:
+      {
+	EMACS_INT val = desc[pos].data1;
+	if (XD_IS_INDIRECT (val))
+	  val = get_indirect_count (val, desc, obj);
+	size_at_max = val * sizeof (void *);
+	break;
+      }
+      break;
+    case XD_STRUCT_ARRAY:
+      {
+	EMACS_INT val = desc[pos].data1;
+
+	if (XD_IS_INDIRECT (val))
+	  val = get_indirect_count (val, desc, obj);
+	    
+	size_at_max = val * structure_size (rdata, desc[pos].data2);
+	break;
+      }
+      break;
+    case XD_OPAQUE_DATA_PTR:
+      size_at_max = sizeof (void *);
+      break;
+    case XD_UNION:
+      abort ();
+      break;
+    case XD_C_STRING:
+      size_at_max = sizeof (void *);
+      break;
+    case XD_DOC_STRING:
+      size_at_max = sizeof (void *);
+      break;
+    case XD_INT_RESET:
+      size_at_max = sizeof (int);
+      break;
+    case XD_BYTECOUNT:
+      size_at_max = sizeof (Bytecount);
+      break;
+    case XD_ELEMCOUNT:
+      size_at_max = sizeof (Elemcount);
+      break;
+    case XD_HASHCODE:
+      size_at_max = sizeof (Hashcode);
+      break;
+    case XD_INT:
+      size_at_max = sizeof (int);
+      break;
+    case XD_LONG:
+      size_at_max = sizeof (long);
+      break;
+    case XD_SPECIFIER_END:
+    case XD_CODING_SYSTEM_END:
+      stderr_out
+	("Should not be seeing XD_SPECIFIER_END or\n"
+	 "XD_CODING_SYSTEM_END outside of struct Lisp_Specifier\n"
+	 "and struct Lisp_Coding_System.\n");
+      abort ();
+    default:
+      stderr_out ("Unsupported dump type : %d\n", desc[pos].type);
+      abort ();
+    }
+
+  return ALIGN_SIZE (max_offset + size_at_max, ALIGNOF (max_align_t));
+}
+
+
+/* This function loops all elements of a struct pointer and calls 
+   mark_with_description with each element. */
+static void
+mark_struct_contents (const void *data,
+				const struct struct_description *sdesc,
+				int count)
+{
+  int i;
+  Bytecount elsize;
+  elsize = structure_size (data, sdesc);
+
+  for (i = 0; i < count; i++)
+    {
+      mark_with_description (((char *) data) + elsize * i,
+					  sdesc->description);
+    }
+}
+
+#endif /* USE_KKCC */  
+
 /* Mark reference to a Lisp_Object.  If the object referred to has not been
    seen yet, recursively mark all the references contained in it. */
 
@@ -2680,6 +3190,10 @@
   if (XTYPE (obj) == Lisp_Type_Record)
     {
       struct lrecord_header *lheader = XRECORD_LHEADER (obj);
+#ifdef USE_KKCC
+      const struct lrecord_implementation *imp;
+      const struct lrecord_description *desc;
+#endif /* USE_KKCC */      
 
       GC_CHECK_LHEADER_INVARIANTS (lheader);
 
@@ -2692,11 +3206,30 @@
 	{
 	  MARK_RECORD_HEADER (lheader);
 
-	  if (RECORD_MARKER (lheader))
+#ifdef USE_KKCC
+	  imp = LHEADER_IMPLEMENTATION (lheader);
+	  desc = imp->description;
+	  
+	  if (desc) /* && !CONSP(obj))*/  /* KKCC cons special case */
+	    {
+	      mark_with_description (lheader, desc);
+	    }
+	  
+	  else 
 	    {
-	      obj = RECORD_MARKER (lheader) (obj);
-	      if (!NILP (obj)) goto tail_recurse;
+
+#endif /* USE_KKCC */
+
+
+	      if (RECORD_MARKER (lheader))
+		{
+		  obj = RECORD_MARKER (lheader) (obj);
+		  if (!NILP (obj)) goto tail_recurse;
+		}
+
+#ifdef USE_KKCC
 	    }
+#endif /* USE_KKCC */
 	}
     }
 }
@@ -3133,6 +3666,91 @@
   SWEEP_FIXED_TYPE_BLOCK (event, Lisp_Event);
 }
 
+#ifdef USE_KKCC
+
+static void
+sweep_key_data (void)
+{
+#define UNMARK_key_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_key_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (key_data, Lisp_Key_Data);
+}
+
+static void
+sweep_button_data (void)
+{
+#define UNMARK_button_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_button_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (button_data, Lisp_Button_Data);
+}
+
+static void
+sweep_motion_data (void)
+{
+#define UNMARK_motion_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_motion_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (motion_data, Lisp_Motion_Data);
+}
+
+static void
+sweep_process_data (void)
+{
+#define UNMARK_process_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_process_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (process_data, Lisp_Process_Data);
+}
+
+static void
+sweep_timeout_data (void)
+{
+#define UNMARK_timeout_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_timeout_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (timeout_data, Lisp_Timeout_Data);
+}
+
+static void
+sweep_magic_data (void)
+{
+#define UNMARK_magic_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_magic_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (magic_data, Lisp_Magic_Data);
+}
+
+static void
+sweep_magic_eval_data (void)
+{
+#define UNMARK_magic_eval_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_magic_eval_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (magic_eval_data, Lisp_Magic_Eval_Data);
+}
+
+static void
+sweep_eval_data (void)
+{
+#define UNMARK_eval_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_eval_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (eval_data, Lisp_Eval_Data);
+}
+
+static void
+sweep_misc_user_data (void)
+{
+#define UNMARK_misc_user_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
+#define ADDITIONAL_FREE_misc_user_data(ptr)
+
+  SWEEP_FIXED_TYPE_BLOCK (misc_user_data, Lisp_Misc_User_Data);
+}
+
+#endif /* USE_KKCC */
+
 static void
 sweep_markers (void)
 {
@@ -3443,6 +4061,18 @@
 
   sweep_events ();
 
+#ifdef USE_KKCC
+  sweep_key_data ();
+  sweep_button_data ();
+  sweep_motion_data ();
+  sweep_process_data ();
+  sweep_timeout_data ();
+  sweep_magic_data ();
+  sweep_magic_eval_data ();
+  sweep_eval_data ();
+  sweep_misc_user_data ();
+#endif /* USE_KKCC */
+
 #ifdef PDUMP
   pdump_objects_unmark ();
 #endif
@@ -3880,7 +4510,6 @@
   Lisp_Object pl = Qnil;
   int i;
   int gc_count_vector_total_size = 0;
-
   garbage_collect_1 ();
 
   for (i = 0; i < lrecord_type_count; i++)
@@ -4229,6 +4858,17 @@
   init_marker_alloc ();
   init_extent_alloc ();
   init_event_alloc ();
+#ifdef USE_KKCC
+  init_key_data_alloc ();
+  init_button_data_alloc ();
+  init_motion_data_alloc ();
+  init_process_data_alloc ();
+  init_timeout_data_alloc ();
+  init_magic_data_alloc ();
+  init_magic_eval_data_alloc ();
+  init_eval_data_alloc ();
+  init_misc_user_data_alloc ();
+#endif /* USE_KKCC */
 
   ignore_malloc_warnings = 0;
 
--- a/src/buffer.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/buffer.c	Mon Jul 29 09:21:25 2002 +0000
@@ -277,9 +277,16 @@
 /* We do not need a finalize method to handle a buffer's children list
    because all buffers have `kill-buffer' applied to them before
    they disappear, and the children removal happens then. */
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer,
+			       0, /*dumpable-flag*/
+                               mark_buffer, print_buffer, 0, 0, 0, 0,
+			       struct buffer);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("buffer", buffer,
                                mark_buffer, print_buffer, 0, 0, 0, 0,
 			       struct buffer);
+#endif /* not USE_KKCC */
 
 DEFUN ("bufferp", Fbufferp, 1, 1, 0, /*
 Return t if OBJECT is an editor buffer.
@@ -2073,7 +2080,6 @@
       = intern (lname);							      \
   }									      \
 } while (0)
-
 #define DEFVAR_BUFFER_LOCAL_MAGIC(lname, field_name, magicfun)		\
 	DEFVAR_BUFFER_LOCAL_1 (lname, field_name,			\
 			       SYMVAL_CURRENT_BUFFER_FORWARD, magicfun)
--- a/src/bytecode.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/bytecode.c	Mon Jul 29 09:21:25 2002 +0000
@@ -1959,6 +1959,16 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION ("compiled-function", compiled_function,
+				     1, /*dumpable_flag*/
+				     mark_compiled_function,
+				     print_compiled_function, 0,
+				     compiled_function_equal,
+				     compiled_function_hash,
+				     compiled_function_description,
+				     Lisp_Compiled_Function);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("compiled-function", compiled_function,
 				     mark_compiled_function,
 				     print_compiled_function, 0,
@@ -1966,6 +1976,7 @@
 				     compiled_function_hash,
 				     compiled_function_description,
 				     Lisp_Compiled_Function);
+#endif /* not USE_KKCC */
 
 DEFUN ("compiled-function-p", Fcompiled_function_p, 1, 1, 0, /*
 Return t if OBJECT is a byte-compiled function object.
--- a/src/casetab.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/casetab.c	Mon Jul 29 09:21:25 2002 +0000
@@ -105,9 +105,17 @@
   { XD_END }
 };
 
+
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION("case-table", case_table,
+			      1, /*dumpable-flag*/
+			      mark_case_table, print_case_table, 0,
+			      0, 0, case_table_description, Lisp_Case_Table);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("case-table", case_table,
 			      mark_case_table, print_case_table, 0,
 			      0, 0, case_table_description, Lisp_Case_Table);
+#endif /* not USE_KKCC */
 
 static Lisp_Object
 allocate_case_table (int init_tables)
--- a/src/chartab.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/chartab.c	Mon Jul 29 09:21:25 2002 +0000
@@ -138,12 +138,23 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
+			       1, /* dumpable flag */
+                               mark_char_table_entry, internal_object_printer,
+			       0, char_table_entry_equal,
+			       char_table_entry_hash,
+			       char_table_entry_description,
+			       Lisp_Char_Table_Entry);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("char-table-entry", char_table_entry,
                                mark_char_table_entry, internal_object_printer,
 			       0, char_table_entry_equal,
 			       char_table_entry_hash,
 			       char_table_entry_description,
 			       Lisp_Char_Table_Entry);
+#endif /* not USE_KKCC */
+
 #endif /* MULE */
 
 static Lisp_Object
@@ -389,11 +400,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
+			       1, /*dumpable-flag*/
+                               mark_char_table, print_char_table, 0,
+			       char_table_equal, char_table_hash,
+			       char_table_description,
+			       Lisp_Char_Table);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("char-table", char_table,
                                mark_char_table, print_char_table, 0,
 			       char_table_equal, char_table_hash,
 			       char_table_description,
 			       Lisp_Char_Table);
+#endif /* not USE_KKCC */
 
 DEFUN ("char-table-p", Fchar_table_p, 1, 1, 0, /*
 Return non-nil if OBJECT is a char table.
--- a/src/console-impl.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/console-impl.h	Mon Jul 29 09:21:25 2002 +0000
@@ -407,6 +407,10 @@
   /* Description of this console's methods.  */
   struct console_methods *conmeths;
 
+#ifdef USE_KKCC
+  enum console_variant contype;
+#endif /* USE_KKCC */  
+
   /* A structure of auxiliary data specific to the console type.
      struct x_console is used for X window frames; defined in console-x.h
      struct tty_console is used to TTY's; defined in console-tty.h */
--- a/src/console.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/console.c	Mon Jul 29 09:21:25 2002 +0000
@@ -105,6 +105,70 @@
 console_type_entry_dynarr *the_console_type_entry_dynarr;
 
 
+
+#ifdef USE_KKCC
+
+static const struct lrecord_description empty_condata_description [] = {
+  { XD_END }
+};
+
+static const struct lrecord_description tty_condata_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct tty_console, terminal_type) },
+  { XD_LISP_OBJECT, offsetof (struct tty_console, instream) },
+  { XD_LISP_OBJECT, offsetof (struct tty_console, outstream) },
+  { XD_END }
+};
+
+static const struct struct_description condata_description []= {
+  { dead_console, empty_condata_description },
+  { tty_console, tty_condata_description },
+  { gtk_console, empty_condata_description },
+  { x_console, empty_condata_description },
+  { mswindows_console, empty_condata_description },
+  { stream_console, empty_condata_description },
+  { XD_END }
+};
+
+static const struct lrecord_description conmeths_description_1 [] = {
+  { XD_LISP_OBJECT, offsetof (struct console_methods, symbol) },
+  /*{ XD_LISP_OBJECT, offsetof (struct console_methods, predicate_symbol) },
+    { XD_LISP_OBJECT, offsetof (struct console_methods, image_conversion_list) },*/
+  { XD_END }
+};
+
+static const struct struct_description conmeths_description = {
+  sizeof (struct console_methods),
+  conmeths_description_1
+};
+
+static const struct lrecord_description console_description [] = {
+  { XD_INT, offsetof (struct console, contype) },
+  { XD_LISP_OBJECT, offsetof (struct console, name) },
+  { XD_LISP_OBJECT, offsetof (struct console, connection) },
+  { XD_LISP_OBJECT, offsetof (struct console, canon_connection) },
+  { XD_LISP_OBJECT, offsetof (struct console, device_list) },
+  { XD_LISP_OBJECT, offsetof (struct console, selected_device) },
+  { XD_LISP_OBJECT, offsetof (struct console, last_nonminibuf_frame) },
+  { XD_LISP_OBJECT, offsetof (struct console, overriding_terminal_local_map) },
+  { XD_LISP_OBJECT, offsetof (struct console, last_command) },
+  { XD_LISP_OBJECT, offsetof (struct console, prefix_arg) },
+  { XD_LISP_OBJECT, offsetof (struct console, command_builder) },
+  { XD_LISP_OBJECT, offsetof (struct console, defining_kbd_macro) },
+  { XD_LISP_OBJECT, offsetof (struct console, kbd_macro_builder) },
+  { XD_LISP_OBJECT, offsetof (struct console, last_kbd_macro) },
+#ifdef HAVE_TTY
+  { XD_LISP_OBJECT, offsetof (struct console, tty_erase_char) },
+#endif
+  { XD_LISP_OBJECT, offsetof (struct console, default_minibuffer_frame) },
+  { XD_LISP_OBJECT, offsetof (struct console, function_key_map) },
+  { XD_STRUCT_PTR, offsetof (struct console, conmeths), 1, &conmeths_description },
+  { XD_UNION, offsetof (struct console, console_data), 
+    XD_INDIRECT (0, 0), condata_description },
+  { XD_END }
+};
+
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_console (Lisp_Object obj)
 {
@@ -140,9 +204,17 @@
   write_fmt_string (printcharfun, " 0x%x>", con->header.uid);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("console", console,
+			       0, /*dumpable-flag*/
+			       mark_console, print_console, 0, 0, 0, 
+			       console_description,
+			       struct console);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("console", console,
 			       mark_console, print_console, 0, 0, 0, 0,
 			       struct console);
+#endif /* not USE_KKCC */
 
 static struct console *
 allocate_console (void)
@@ -191,6 +263,40 @@
   return 0;
 }
 
+#ifdef USE_KKCC
+enum console_variant
+get_console_variant (Lisp_Object type)
+{
+  if (EQ (type, Qtty)) 
+    {
+      return tty_console;
+    }
+
+  if (EQ (type, Qgtk)) 
+    {
+      return gtk_console;
+    }
+
+  if (EQ (type, Qx)) 
+    {
+      return x_console;
+    }
+
+  if (EQ (type, Qmswindows)) 
+    {
+      return mswindows_console;
+    }
+
+  if (EQ (type, Qstream)) 
+    {
+      return stream_console;
+    }
+
+  abort (); /* should never happen */
+  return dead_console; 
+}
+#endif /* USE_KKCC */
+
 int
 valid_console_type_p (Lisp_Object type)
 {
@@ -493,6 +599,9 @@
   GCPRO1 (console);
 
   con->conmeths = decode_console_type (type, ERROR_ME);
+#ifdef USE_KKCC
+  con->contype = get_console_variant (type);
+#endif /* USE_KKCC */
 
   CONSOLE_NAME (con) = name;
   CONSOLE_CONNECTION (con) =
--- a/src/console.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/console.h	Mon Jul 29 09:21:25 2002 +0000
@@ -46,6 +46,19 @@
 /* GCC does not like forward enum declaration. This needs to be
    defined here. What a disgust! */
 
+#ifdef USE_KKCC
+enum console_variant
+{
+  dead_console,
+  tty_console,
+  gtk_console,
+  x_console,
+  mswindows_console,
+  stream_console
+};
+
+#endif /* USE_KKCC */
+
 enum device_metrics
 {
   DM_color_default, DM_color_select, DM_color_balloon, DM_color_3d_face,
@@ -120,6 +133,11 @@
 				     struct console_methods *type);
 struct console_methods *decode_console_type (Lisp_Object type,
 					     Error_Behavior errb);
+
+#ifdef USE_KKCC
+enum console_variant get_console_variant (Lisp_Object type);
+#endif /* USE_KKCC */
+
 void delete_console_internal (struct console *con, int force,
 			      int from_kill_emacs, int from_io_error);
 void io_error_delete_console (Lisp_Object console);
--- a/src/data.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/data.c	Mon Jul 29 09:21:25 2002 +0000
@@ -1635,11 +1635,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
+			       1, /*dumpable-flag*/
+			       mark_weak_list, print_weak_list,
+			       0, weak_list_equal, weak_list_hash,
+			       weak_list_description,
+			       struct weak_list);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
 			       mark_weak_list, print_weak_list,
 			       0, weak_list_equal, weak_list_hash,
 			       weak_list_description,
 			       struct weak_list);
+#endif /* not USE_KKCC */
 /*
    -- we do not mark the list elements (either the elements themselves
       or the cons cells that hold them) in the normal marking phase.
@@ -2096,11 +2105,20 @@
   { XD_END}
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("weak_box", weak_box,
+			       0, /*dumpable-flag*/
+			       mark_weak_box, print_weak_box,
+			       0, weak_box_equal, weak_box_hash,
+			       weak_box_description,
+			       struct weak_box);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("weak_box", weak_box,
 			       mark_weak_box, print_weak_box,
 			       0, weak_box_equal, weak_box_hash,
 			       weak_box_description,
 			       struct weak_box);
+#endif /* not USE_KKCC */
 
 DEFUN ("make-weak-box", Fmake_weak_box, 1, 1, 0, /*
 Return a new weak box from value CONTENTS.
@@ -2275,11 +2293,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("ephemeron", ephemeron,
+			       0, /*dumpable-flag*/
+			       mark_ephemeron, print_ephemeron,
+			       0, ephemeron_equal, ephemeron_hash,
+			       ephemeron_description,
+			       struct ephemeron);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("ephemeron", ephemeron,
 			       mark_ephemeron, print_ephemeron,
 			       0, ephemeron_equal, ephemeron_hash,
 			       ephemeron_description,
 			       struct ephemeron);
+#endif /* not USE_KKCC */
 
 DEFUN ("make-ephemeron", Fmake_ephemeron, 2, 3, 0, /*
 Return a new ephemeron with key KEY, value CONTENTS, and finalizer FINALIZER.
--- a/src/database.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/database.c	Mon Jul 29 09:21:25 2002 +0000
@@ -139,6 +139,13 @@
   return db;
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description database_description[] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Database, fname) },
+  { XD_END}
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_database (Lisp_Object object)
 {
@@ -179,10 +186,19 @@
   db->funcs->close (db);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("database", database,
+			       0, /*dumpable-flag*/
+                               mark_database, print_database,
+			       finalize_database, 0, 0, 
+			       database_description,
+			       Lisp_Database);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("database", database,
                                mark_database, print_database,
 			       finalize_database, 0, 0, 0,
 			       Lisp_Database);
+#endif /* not USE_KKCC */
 
 DEFUN ("close-database", Fclose_database, 1, 1, 0, /*
 Close database DATABASE.
--- a/src/device-impl.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/device-impl.h	Mon Jul 29 09:21:25 2002 +0000
@@ -77,6 +77,10 @@
      through device->console, but it's faster this way. */
   struct console_methods *devmeths;
 
+#ifdef USE_KKCC
+  enum console_variant devtype;
+#endif /* USE_KKCC */  
+
   /* A structure of auxiliary data specific to the device type.
      struct x_device is used for X window frames; defined in console-x.h
      struct tty_device is used to TTY's; defined in console-tty.h */
--- a/src/device-msw.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/device-msw.c	Mon Jul 29 09:21:25 2002 +0000
@@ -1074,6 +1074,14 @@
 /*                                devmode                               */
 /************************************************************************/
 
+#ifdef USE_KKCC
+static const struct lrecord_description devmode_description[] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Devmode, printer_name) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Devmode, device) }
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_devmode (Lisp_Object obj)
 {
@@ -1143,10 +1151,19 @@
 		internal_hash (dm->printer_name, depth + 1));
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("msprinter-settings", devmode,
+			       mark_devmode, print_devmode, finalize_devmode,
+			       equal_devmode, hash_devmode, 
+			       devmode_description,
+			       Lisp_Devmode);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("msprinter-settings", devmode,
 			       mark_devmode, print_devmode, finalize_devmode,
 			       equal_devmode, hash_devmode, 0/*description*/,
 			       Lisp_Devmode);
+#endif /* not USE_KKCC */
+
 static Lisp_Object
 allocate_devmode (DEVMODEW* src_devmode, int do_copy,
 		  Lisp_Object src_name, struct device *d)
--- a/src/device.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/device.c	Mon Jul 29 09:21:25 2002 +0000
@@ -45,6 +45,19 @@
 #include "toolbar.h"
 #include "window.h"
 
+#ifdef USE_KKCC
+#include "console-tty-impl.h"
+#ifdef HAVE_MS_WINDOWS
+#include "console-msw-impl.h"
+#endif
+#ifdef HAVE_X_WINDOWS
+#include "console-x-impl.h"
+#endif
+#ifdef HAVE_GTK
+#include "console-gtk-impl.h"
+#endif
+#endif /* USE_KKCC */
+
 #ifdef HAVE_SCROLLBARS
 #include "scrollbar.h"
 #endif
@@ -84,6 +97,84 @@
 Lisp_Object Vdevice_class_list;
 
 
+
+#ifdef USE_KKCC
+
+static const struct lrecord_description empty_devdata_description [] = {
+  { XD_END }
+};
+
+static const struct lrecord_description mswindows_devdata_description [] = {
+#ifdef HAVE_MS_WINDOWS
+  { XD_LISP_OBJECT, offsetof (struct mswindows_device, fontlist) },
+#endif
+  { XD_END }
+};
+
+static const struct lrecord_description gtk_devdata_description [] = {
+#ifdef HAVE_GTK
+  { XD_LISP_OBJECT, offsetof (struct gtk_device, x_keysym_map_hash_table) },
+  { XD_LISP_OBJECT, offsetof (struct gtk_device, WM_COMMAND_frame) },
+#endif
+  { XD_END }
+};
+
+static const struct lrecord_description x_devdata_description [] = {
+#ifdef HAVE_X_WINDOWS
+  { XD_LISP_OBJECT, offsetof (struct x_device, x_keysym_map_hash_table) },
+  { XD_LISP_OBJECT, offsetof (struct x_device, WM_COMMAND_frame) },
+#endif
+  { XD_END }
+};
+
+static const struct struct_description devdata_description []= {
+  { dead_console, empty_devdata_description},
+  { tty_console, empty_devdata_description},
+  { gtk_console, gtk_devdata_description},
+  { x_console, x_devdata_description},
+  { mswindows_console, mswindows_devdata_description},
+  { stream_console, empty_devdata_description},
+  { XD_END }
+};
+
+static const struct lrecord_description conmeths_description_1 [] = {
+  { XD_LISP_OBJECT, offsetof (struct console_methods, symbol) },
+  { XD_END }
+};
+
+static const struct struct_description conmeths_description = {
+  sizeof (struct console_methods),
+  conmeths_description_1
+};
+
+static const struct lrecord_description device_description [] = {
+  { XD_INT, offsetof (struct device, devtype) },
+  { XD_LISP_OBJECT, offsetof (struct device, name) },
+  { XD_LISP_OBJECT, offsetof (struct device, connection) },
+  { XD_LISP_OBJECT, offsetof (struct device, canon_connection) },
+  { XD_LISP_OBJECT, offsetof (struct device, frame_list) },
+  { XD_LISP_OBJECT, offsetof (struct device, console) },
+  { XD_LISP_OBJECT, offsetof (struct device, selected_frame) },
+  { XD_LISP_OBJECT, offsetof (struct device, frame_with_focus_real) },
+  { XD_LISP_OBJECT, offsetof (struct device, frame_with_focus_for_hooks) },
+  { XD_LISP_OBJECT, offsetof (struct device, frame_that_ought_to_have_focus) },
+  { XD_LISP_OBJECT, offsetof (struct device, device_class) },
+  { XD_LISP_OBJECT, offsetof (struct device, user_defined_tags) },
+  { XD_LISP_OBJECT, offsetof (struct device, color_instance_cache) },
+  { XD_LISP_OBJECT, offsetof (struct device, font_instance_cache) },
+#ifdef MULE
+  { XD_LISP_OBJECT, offsetof (struct device, charset_font_cache_stage_1) },
+  { XD_LISP_OBJECT, offsetof (struct device, charset_font_cache_stage_2) },
+#endif
+  { XD_LISP_OBJECT, offsetof (struct device, image_instance_cache) },
+  { XD_LISP_OBJECT, offsetof (struct device, frame_list) },
+  { XD_STRUCT_PTR, offsetof (struct device, devmeths), 1, &conmeths_description },
+  { XD_UNION, offsetof (struct device, device_data), 
+    XD_INDIRECT (0, 0), devdata_description },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_device (Lisp_Object obj)
 {
@@ -117,9 +208,17 @@
   write_fmt_string (printcharfun, " 0x%x>", d->header.uid);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("device", device,
+			       0, /*dumpable-flag*/
+			       mark_device, print_device, 0, 0, 0, 
+			       device_description,
+			       struct device);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("device", device,
 			       mark_device, print_device, 0, 0, 0, 0,
 			       struct device);
+#endif /* not USE_KKCC */
 
 int
 valid_device_class_p (Lisp_Object class)
@@ -603,6 +702,9 @@
   device = wrap_device (d);
 
   d->devmeths = con->conmeths;
+#ifdef USE_KKCC
+  d->devtype = get_console_variant (type);
+#endif /* USE_KKCC */
 
   DEVICE_NAME (d) = name;
   DEVICE_CONNECTION (d) =
--- a/src/dialog-msw.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/dialog-msw.c	Mon Jul 29 09:21:25 2002 +0000
@@ -169,6 +169,14 @@
   return 0;
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description mswindows_dialog_id_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct mswindows_dialog_id, frame) },
+  { XD_LISP_OBJECT, offsetof (struct mswindows_dialog_id, callbacks) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_mswindows_dialog_id (Lisp_Object obj)
 {
@@ -177,10 +185,18 @@
   return data->callbacks;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("mswindows-dialog-id", mswindows_dialog_id,
+			       mark_mswindows_dialog_id,
+			       internal_object_printer, 0, 0, 0, 
+			       mswindows_dialog_id_description,
+			       struct mswindows_dialog_id);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("mswindows-dialog-id", mswindows_dialog_id,
 			       mark_mswindows_dialog_id,
 			       internal_object_printer, 0, 0, 0, 0,
 			       struct mswindows_dialog_id);
+#endif /* not USE_KKCC */
 
 /* Dialog procedure */
 static BOOL CALLBACK 
--- a/src/dumper.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/dumper.c	Mon Jul 29 09:21:25 2002 +0000
@@ -591,7 +591,12 @@
 
   imp = LHEADER_IMPLEMENTATION (objh);
 
+#ifdef USE_KKCC
+  if (imp->description
+      && RECORD_DUMPABLE(objh))
+#else /* not USE_KKCC */
   if (imp->description)
+#endif /* not USE_KKCC */    
     {
       int me = depth++;
       if (me > 65536)
--- a/src/eldap.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/eldap.c	Mon Jul 29 09:21:25 2002 +0000
@@ -98,6 +98,13 @@
   return wrap_ldap (ldap);
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description ldap_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_LDAP, host) },
+  { XD_END }
+};
+#endif USE_KKCC
+
 static Lisp_Object
 mark_ldap (Lisp_Object obj)
 {
@@ -142,10 +149,15 @@
   ldap->ld = NULL;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap,
+                               mark_ldap, print_ldap, finalize_ldap,
+                               NULL, NULL, ldap_description, Lisp_LDAP);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("ldap", ldap,
                                mark_ldap, print_ldap, finalize_ldap,
                                NULL, NULL, 0, Lisp_LDAP);
-
+#endif /* not USE_KKCC */
 
 
 
--- a/src/elhash.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/elhash.c	Mon Jul 29 09:21:25 2002 +0000
@@ -429,12 +429,22 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
+			       1, /*dumpable-flag*/
+                               mark_hash_table, print_hash_table,
+			       finalize_hash_table,
+			       hash_table_equal, hash_table_hash,
+			       hash_table_description,
+			       Lisp_Hash_Table);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
                                mark_hash_table, print_hash_table,
 			       finalize_hash_table,
 			       hash_table_equal, hash_table_hash,
 			       hash_table_description,
 			       Lisp_Hash_Table);
+#endif /* not USE_KKCC */
 
 static Lisp_Hash_Table *
 xhash_table (Lisp_Object hash_table)
--- a/src/event-Xt.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/event-Xt.c	Mon Jul 29 09:21:25 2002 +0000
@@ -1130,9 +1130,10 @@
   switch (x_event->type)
     {
     case KeyRelease:
-      x_handle_sticky_modifiers (x_event, d);
-      return 0;
-
+      {
+	x_handle_sticky_modifiers (x_event, d);
+	return 0;
+      }
     case KeyPress:
     case ButtonPress:
     case ButtonRelease:
@@ -1208,7 +1209,11 @@
 	    XKeyEvent *ev = &x_event->xkey;
 	    /* This used to compute the frame from the given X window and
 	       store it here, but we really don't care about the frame. */
+#ifdef USE_KKCC
+	    SET_EVENT_CHANNEL (emacs_event, DEVICE_CONSOLE (d));
+#else /* not USE_KKCC */
 	    emacs_event->channel = DEVICE_CONSOLE (d);
+#endif /* not USE_KKCC */
 	    keysym = x_to_emacs_keysym (&x_event->xkey, 0);
 
 	    /* If the emacs keysym is nil, then that means that the X
@@ -1252,10 +1257,17 @@
 		if (top && bot && top != bot)
 		  modifiers &= ~XEMACS_MOD_SHIFT;
 	      }
+#ifdef USE_KKCC
+	    set_event_type (emacs_event, key_press_event);
+	    SET_EVENT_TIMESTAMP (emacs_event, ev->time);
+	    XSET_KEY_DATA_MODIFIERS (EVENT_DATA (emacs_event), modifiers);
+	    XSET_KEY_DATA_KEYSYM (EVENT_DATA (emacs_event), keysym);
+#else /* not USE_KKCC */
 	    emacs_event->event_type	     = key_press_event;
 	    emacs_event->timestamp	     = ev->time;
 	    emacs_event->event.key.modifiers = modifiers;
 	    emacs_event->event.key.keysym    = keysym;
+#endif /* not USE_KKCC */
 	  }
 	else                    /* Mouse press/release event */
 	  {
@@ -1264,8 +1276,18 @@
 
 	    if (! frame)
 	      return 0;	/* not for us */
+#ifdef USE_KKCC
+	    set_event_type (emacs_event, (x_event->type == ButtonPress) ?
+                        button_press_event : button_release_event);
+            SET_EVENT_CHANNEL (emacs_event, wrap_frame(frame));
+
+	    XSET_BUTTON_DATA_MODIFIERS (EVENT_DATA (emacs_event), modifiers);
+	    SET_EVENT_TIMESTAMP (emacs_event, ev->time);
+	    XSET_BUTTON_DATA_BUTTON (EVENT_DATA (emacs_event), ev->button);
+	    XSET_BUTTON_DATA_X (EVENT_DATA (emacs_event), ev->x);
+	    XSET_BUTTON_DATA_Y (EVENT_DATA (emacs_event), ev->y);
+#else /* not USE_KKCC */
 	    emacs_event->channel = wrap_frame (frame);
-
 	    emacs_event->event_type = (x_event->type == ButtonPress) ?
 	      button_press_event : button_release_event;
 
@@ -1274,6 +1296,7 @@
 	    emacs_event->event.button.button	= ev->button;
 	    emacs_event->event.button.x		= ev->x;
 	    emacs_event->event.button.y		= ev->y;
+#endif /* not USE_KKCC */
 	    /* because we don't seem to get a FocusIn event for button clicks
 	       when a widget-glyph is selected we will assume that we want the
 	       focus if a button gets pressed. */
@@ -1310,12 +1333,19 @@
           ev = &event2; /* only one structure copy */
 
         DEVICE_X_MOUSE_TIMESTAMP (d) = ev->time;
-
+#ifdef USE_KKCC
+        SET_EVENT_CHANNEL (emacs_event, wrap_frame(frame));
+        set_event_type (emacs_event, pointer_motion_event);
+        SET_EVENT_TIMESTAMP (emacs_event, ev->time);
+        XSET_MOTION_DATA_X (EVENT_DATA (emacs_event), ev->x);
+        XSET_MOTION_DATA_Y (EVENT_DATA (emacs_event), ev->y);
+#else /* not USE_KKCC */
         emacs_event->channel = wrap_frame (frame);
         emacs_event->event_type	    = pointer_motion_event;
         emacs_event->timestamp      = ev->time;
         emacs_event->event.motion.x = ev->x;
         emacs_event->event.motion.y = ev->y;
+#endif /* not USE_KKCC */
         if (ev->state & ShiftMask)	modifiers |= XEMACS_MOD_SHIFT;
         if (ev->state & ControlMask)	modifiers |= XEMACS_MOD_CONTROL;
         if (ev->state & xd->MetaMask)	modifiers |= XEMACS_MOD_META;
@@ -1329,7 +1359,11 @@
         if (ev->state & Button5Mask)	modifiers |= XEMACS_MOD_BUTTON5;
         /* Currently ignores Shift_Lock but probably shouldn't
            (but it definitely should ignore Caps_Lock). */
+#ifdef USE_KKCC
+        XSET_MOTION_DATA_MODIFIERS (EVENT_DATA (emacs_event), modifiers);
+#else /* not USE_KKCC */
         emacs_event->event.motion.modifiers = modifiers;
+#endif /* not USE_KKCC */
       }
     break;
 
@@ -1356,11 +1390,15 @@
 	      return 0;	/* not for us */
 
 	    GCPRO4 (l_type, l_data, l_dndlist, l_item);
+#ifdef USE_KKCC
+	    set_event_type (emacs_event, misc_user_event);
+	    SET_EVENT_CHANNEL (emacs_event, wrap_frame(frame));
+	    SET_EVENT_TIMESTAMP (emacs_event, DEVICE_X_LAST_SERVER_TIMESTAMP (d));
+#else /* not USE_KKCC */
 	    emacs_event->channel = wrap_frame (frame);
-
 	    emacs_event->event_type = misc_user_event;
 	    emacs_event->timestamp  = DEVICE_X_LAST_SERVER_TIMESTAMP (d);
-
+#endif /* not USE_KKCC */
 	    state=DndDragButtons(x_event);
 
 	    if (state & ShiftMask)	modifiers |= XEMACS_MOD_SHIFT;
@@ -1381,13 +1419,21 @@
 	    if (state & Button2Mask)    button = Button2;
 	    if (state & Button1Mask)    button = Button1;
 
+#ifdef USE_KKCC
+	    XSET_MISC_USER_DATA_MODIFIERS (EVENT_DATA (emacs_event), modifiers);
+	    XSET_MISC_USER_DATA_BUTTON (EVENT_DATA (emacs_event), button);
+
+	    DndDropCoordinates(FRAME_X_TEXT_WIDGET(frame), x_event,
+			       &(XMISC_USER_DATA_X (EVENT_DATA (emacs_event))),
+			       &(XMISC_USER_DATA_Y (EVENT_DATA (emacs_event))) );
+#else /* not USE_KKCC */
 	    emacs_event->event.misc.modifiers = modifiers;
 	    emacs_event->event.misc.button    = button;
 
 	    DndDropCoordinates(FRAME_X_TEXT_WIDGET(frame), x_event,
 			       &(emacs_event->event.misc.x),
 			       &(emacs_event->event.misc.y) );
-
+#endif /* not USE_KKCC */
 	    DndGetData(x_event,&data,&size);
 
 	    dtype=DndDataType(x_event);
@@ -1463,8 +1509,13 @@
 		break;
 	      }
 
+#ifdef USE_KKCC
+	    XSET_MISC_USER_DATA_FUNCTION (EVENT_DATA (emacs_event), Qdragdrop_drop_dispatch);
+	    XSET_MISC_USER_DATA_OBJECT (EVENT_DATA (emacs_event), Fcons (l_type, l_dndlist));
+#else /* not USE_KKCC */
 	    emacs_event->event.misc.function = Qdragdrop_drop_dispatch;
 	    emacs_event->event.misc.object = Fcons (l_type, l_dndlist);
+#endif /* not USE_KKCC */
 
 	    UNGCPRO;
 
@@ -1484,7 +1535,13 @@
       {
         struct frame *frame;
         Window w;
+#ifdef USE_KKCC
+	XEvent *x_event_copy;
+	SET_EVENT_TYPE (emacs_event, magic_event);
+        x_event_copy = &XMAGIC_DATA_X_EVENT (EVENT_DATA (emacs_event));
+#else /* not USE_KKCC */
 	XEvent *x_event_copy = &emacs_event->event.magic.underlying_x_event;
+#endif /* not USE_KKCC */
 
 #define FROB(event_member, window_member) \
 	x_event_copy->event_member = x_event->event_member; \
@@ -1519,9 +1576,14 @@
         if (!frame)
           return 0;
 
+#ifdef USE_KKCC
+	SET_EVENT_TYPE (emacs_event, magic_event);
+	SET_EVENT_CHANNEL (emacs_event, wrap_frame(frame));
+	XSET_MAGIC_DATA_X_EVENT (EVENT_DATA(emacs_event), *x_event_copy);
+#else /* not USE_KKCC */
         emacs_event->event_type = magic_event;
         emacs_event->channel = wrap_frame (frame);
-
+#endif /* not USE_KKCC */
         break;
       }
     }
@@ -1617,13 +1679,22 @@
 {
   Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
   Lisp_Event *ev          = XEVENT (emacs_event);
+#ifdef USE_KKCC
+  XEvent *x_event = &XMAGIC_DATA_X_EVENT(EVENT_DATA(ev));
+#else /* not USE_KKCC */
   XEvent *x_event = &ev->event.magic.underlying_x_event;
+#endif /* not USE_KKCC */
 
   x_event->type = in_p ? FocusIn : FocusOut;
   x_event->xfocus.window = XtWindow (wants_it);
 
+#ifdef USE_KKCC
+  SET_EVENT_CHANNEL(ev, frame);
+  /*  SET_EVENT_TYPE(ev, magic_event); */
+#else /* not USE_KKCC */
   ev->channel	            = frame;
   ev->event_type	    = magic_event;
+#endif /* not USE_KKCC */
 
   enqueue_Xt_dispatch_event (emacs_event);
 }
@@ -1904,7 +1975,11 @@
   Lisp_Object console = CDFW_CONSOLE (EVENT_CHANNEL (event));
   if (CONSOLE_X_P (XCONSOLE (console)))
     write_c_string
+#ifdef USE_KKCC
+      (pstream, x_event_name ((XMAGIC_DATA_X_EVENT (EVENT_DATA(event))).type));
+#else /* not USE_KKCC */
       (pstream, x_event_name (event->event.magic.underlying_x_event.type));
+#endif /* not USE_KKCC */
 }
 
 static int
@@ -1912,8 +1987,13 @@
 {
   if (CONSOLE_X_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e1)))) &&
       CONSOLE_X_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e2)))))
+#ifdef USE_KKCC
+    return ((XMAGIC_DATA_X_EVENT (EVENT_DATA(e1))).xany.serial ==
+	    (XMAGIC_DATA_X_EVENT (EVENT_DATA(e2))).xany.serial);
+#else /* not USE_KKCC */
     return (e1->event.magic.underlying_x_event.xany.serial ==
 	    e2->event.magic.underlying_x_event.xany.serial);
+#endif /* not USE_KKCC */
   if (CONSOLE_X_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e1)))) ||
       CONSOLE_X_P (XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e2)))))
     return 0;
@@ -1925,7 +2005,11 @@
 {
   Lisp_Object console = CDFW_CONSOLE (EVENT_CHANNEL (e));
   if (CONSOLE_X_P (XCONSOLE (console)))
+#ifdef USE_KKCC
+    return (XMAGIC_DATA_X_EVENT (EVENT_DATA(e))).xany.serial;
+#else /* not USE_KKCC */
     return e->event.magic.underlying_x_event.xany.serial;
+#endif /* not USE_KKCC */
   return 0;
 }
 
@@ -1933,7 +2017,11 @@
 emacs_Xt_handle_magic_event (Lisp_Event *emacs_event)
 {
   /* This function can GC */
+#ifdef USE_KKCC
+  XEvent *event = &XMAGIC_DATA_X_EVENT (EVENT_DATA(emacs_event));
+#else /* not USE_KKCC */
   XEvent *event = &emacs_event->event.magic.underlying_x_event;
+#endif /* not USE_KKCC */
   struct frame *f = XFRAME (EVENT_CHANNEL (emacs_event));
 
   if (!FRAME_LIVE_P (f) || DEVICE_X_BEING_DELETED (XDEVICE (FRAME_DEVICE (f))))
@@ -1944,19 +2032,19 @@
     case SelectionRequest:
       x_handle_selection_request (&event->xselectionrequest);
       break;
-
+      
     case SelectionClear:
       x_handle_selection_clear (&event->xselectionclear);
       break;
-
+      
     case SelectionNotify:
       x_handle_selection_notify (&event->xselection);
       break;
-
+      
     case PropertyNotify:
       x_handle_property_notify (&event->xproperty);
       break;
-
+	
     case Expose:
       if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
 				     event->xexpose.width, event->xexpose.height)
@@ -2182,12 +2270,20 @@
   struct Xt_timeout *timeout = completed_timeouts;
   assert (timeout);
   completed_timeouts = completed_timeouts->next;
+  /* timeout events have nil as channel */
+#ifdef USE_KKCC
+  set_event_type(emacs_event, timeout_event);
+  SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### wrong!! */
+  XSET_TIMEOUT_DATA_INTERVAL_ID (EVENT_DATA (emacs_event), timeout->id);
+  XSET_TIMEOUT_DATA_FUNCTION (EVENT_DATA (emacs_event), Qnil);
+  XSET_TIMEOUT_DATA_OBJECT (EVENT_DATA (emacs_event), Qnil);
+#else /* not USE_KKCC */
   emacs_event->event_type = timeout_event;
-  /* timeout events have nil as channel */
   emacs_event->timestamp  = 0; /* #### wrong!! */
   emacs_event->event.timeout.interval_id = timeout->id;
   emacs_event->event.timeout.function = Qnil;
   emacs_event->event.timeout.object = Qnil;
+#endif /* not USE_KKCC */
   Blocktype_free (the_Xt_timeout_blocktype, timeout);
 }
 
@@ -2441,9 +2537,15 @@
 	  filedesc_with_input[i] = Qnil;
 	  process_events_occurred--;
 	  /* process events have nil as channel */
+#ifdef USE_KKCC
+	  set_event_type (emacs_event, process_event);
+	  SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### */
+	  XSET_PROCESS_DATA_PROCESS (EVENT_DATA (emacs_event), process);
+#else /* not USE_KKCC */
 	  emacs_event->event_type = process_event;
 	  emacs_event->timestamp  = 0; /* #### */
 	  emacs_event->event.process.process = process;
+#endif /* not USE_KKCC */
 	  return;
 	}
     }
@@ -2769,11 +2871,17 @@
 {
   Lisp_Object event = Fmake_event (Qnil, Qnil);
 
+#ifdef USE_KKCC
+  XSET_EVENT_TYPE (event, misc_user_event);
+  XSET_EVENT_CHANNEL (event, channel);
+  XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), function);
+  XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), object);
+#else /* not USE_KKCC */
   XEVENT (event)->event_type = misc_user_event;
   XEVENT (event)->channel = channel;
   XEVENT (event)->event.eval.function = function;
   XEVENT (event)->event.eval.object = object;
-
+#endif /* not USE_KKCC */
   enqueue_Xt_dispatch_event (event);
 }
 
@@ -2844,9 +2952,15 @@
       /* A dummy event, so that a cycle of the command loop will occur. */
       fake_event_occurred = 0;
       /* eval events have nil as channel */
+#ifdef USE_KKCC
+      set_event_type (emacs_event, eval_event);
+      XSET_EVAL_DATA_FUNCTION (EVENT_DATA (emacs_event), Qidentity);
+      XSET_EVAL_DATA_OBJECT (EVENT_DATA (emacs_event), Qnil);
+#else /* not USE_KKCC */
       emacs_event->event_type = eval_event;
       emacs_event->event.eval.function = Qidentity;
       emacs_event->event.eval.object = Qnil;
+#endif /* not USE_KKCC */
     }
   else /* if (process_events_occurred) */
     Xt_process_to_emacs_event (emacs_event);
--- a/src/event-stream.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/event-stream.c	Mon Jul 29 09:21:25 2002 +0000
@@ -318,6 +318,27 @@
 
 static Lisp_Object Vcommand_builder_free_list;
 
+#ifdef USE_KKCC
+static const struct lrecord_description munging_key_translation_description_1 [] = {
+  { XD_LISP_OBJECT, offsetof (struct munging_key_translation, first_mungeable_event) },
+  { XD_END }
+};
+
+static const struct struct_description munging_key_translation_description = {
+  sizeof (Lisp_Object),
+  munging_key_translation_description_1
+};
+
+static const struct lrecord_description command_builder_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct command_builder, current_events) },
+  { XD_LISP_OBJECT, offsetof (struct command_builder, most_current_event) },
+  { XD_LISP_OBJECT, offsetof (struct command_builder, last_non_munged_event) },
+  { XD_LISP_OBJECT, offsetof (struct command_builder, console) },
+  { XD_STRUCT_ARRAY, offsetof (struct command_builder, munge_me), 2, &munging_key_translation_description },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_command_builder (Lisp_Object obj)
 {
@@ -344,10 +365,19 @@
     }
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("command-builder", command_builder,
+			       0, /*dumpable-flag*/
+                               mark_command_builder, internal_object_printer,
+			       finalize_command_builder, 0, 0, 
+			       command_builder_description,
+			       struct command_builder);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("command-builder", command_builder,
                                mark_command_builder, internal_object_printer,
 			       finalize_command_builder, 0, 0, 0,
 			       struct command_builder);
+#endif /* not USE_KKCC */
 
 static void
 reset_command_builder_event_chain (struct command_builder *builder)
@@ -761,7 +791,11 @@
       clear_echo_area (selected_frame (), Qnil, 0);
     }
 
-  format_event_object (buf, XEVENT (event), 1);
+#ifdef USE_KKCC
+  format_event_object (buf, event, 1);
+#else /* not USE_KKCC */
+  format_event_object (buf, XEVENT(event), 1);
+#endif /* not USE_KKCC */
   len = eilen (buf);
 
   if (len + buf_index + 4 > command_builder->echo_buf_length)
@@ -876,44 +910,89 @@
 				      Qnil);
       if (!NILP (traduit) && SYMBOLP (traduit))
 	{
+#ifdef USE_KKCC
+	  XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), traduit);
+	  XSET_KEY_DATA_MODIFIERS (XEVENT_DATA (event), 0);
+#else /* not USE_KKCC */
 	  XEVENT (event)->event.key.keysym = traduit;
 	  XEVENT (event)->event.key.modifiers = 0;
+#endif /* not USE_KKCC */
 	  did_translate = 1;
 	}
       else if (CHARP (traduit))
 	{
+#ifdef USE_KKCC
+	  Lisp_Object ev2 = Fmake_event(Qnil, Qnil);
+#else /* not USE_KKCC */
 	  Lisp_Event ev2;
 
 	  /* This used to call Fcharacter_to_event() directly into EVENT,
 	     but that can eradicate timestamps and other such stuff.
 	     This way is safer. */
 	  zero_event (&ev2);
+#endif /* not USE_KKCC */
+
+#ifdef USE_KKCC
+	  character_to_event (XCHAR (traduit), XEVENT (ev2),
+			      XCONSOLE (XEVENT_CHANNEL (event)), 1, 1);
+	  XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), XKEY_DATA_KEYSYM (XEVENT_DATA (ev2)));
+	  XSET_KEY_DATA_MODIFIERS (XEVENT_DATA (event), 
+                               XKEY_DATA_MODIFIERS (XEVENT_DATA (ev2)));
+#else /* not USE_KKCC */
 	  character_to_event (XCHAR (traduit), &ev2,
 			      XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 1, 1);
 	  XEVENT (event)->event.key.keysym = ev2.event.key.keysym;
 	  XEVENT (event)->event.key.modifiers = ev2.event.key.modifiers;
+#endif /* not USE_KKCC */
 	  did_translate = 1;
 	}
     }
 
   if (!did_translate)
     {
+#ifdef USE_KKCC
+      Lisp_Object traduit = Fgethash (XKEY_DATA_KEYSYM (XEVENT_DATA (event)),
+				      Vkeyboard_translate_table, Qnil);
+#else /* not USE_KKCC */
       Lisp_Object traduit = Fgethash (XEVENT (event)->event.key.keysym,
 				      Vkeyboard_translate_table, Qnil);
+#endif /* not USE_KKCC */
       if (!NILP (traduit) && SYMBOLP (traduit))
 	{
+#ifdef USE_KKCC
+	  XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), traduit);
+#else /* not USE_KKCC */
 	  XEVENT (event)->event.key.keysym = traduit;
+#endif /* not USE_KKCC */
 	  did_translate = 1;
 	}
       else if (CHARP (traduit))
 	{
+#ifdef USE_KKCC
+	  Lisp_Object ev2 = Fmake_event(Qnil, Qnil);
+#else /* not USE_KKCC */
 	  Lisp_Event ev2;
 
+	  /* This used to call Fcharacter_to_event() directly into EVENT,
+	     but that can eradicate timestamps and other such stuff.
+	     This way is safer. */
 	  zero_event (&ev2);
+#endif /* not USE_KKCC */
+
+#ifdef USE_KKCC
+	  character_to_event (XCHAR (traduit), XEVENT (ev2),
+			      XCONSOLE (XEVENT_CHANNEL (event)), 1, 1);
+	  XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), XKEY_DATA_KEYSYM (XEVENT_DATA (ev2)));
+	  XSET_KEY_DATA_MODIFIERS (XEVENT_DATA (event),
+                               XKEY_DATA_MODIFIERS (XEVENT_DATA (event)) |
+                               XKEY_DATA_MODIFIERS (XEVENT_DATA (ev2)));
+#else /* not USE_KKCC */
 	  character_to_event (XCHAR (traduit), &ev2,
 			      XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 1, 1);
 	  XEVENT (event)->event.key.keysym = ev2.event.key.keysym;
 	  XEVENT (event)->event.key.modifiers |= ev2.event.key.modifiers;
+#endif /* not USE_KKCC */
+
 	  did_translate = 1;
 	}
     }
@@ -1230,9 +1309,16 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("timeout", timeout,
+			       1, /*dumpable-flag*/
+			       mark_timeout, internal_object_printer,
+			       0, 0, 0, timeout_description, Lisp_Timeout);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("timeout", timeout,
 			       mark_timeout, internal_object_printer,
 			       0, 0, 0, timeout_description, Lisp_Timeout);
+#endif /* not USE_KKCC */
 
 /* Generate a timeout and return its ID. */
 
@@ -1628,11 +1714,17 @@
 enqueue_magic_eval_event (void (*fun) (Lisp_Object), Lisp_Object object)
 {
   Lisp_Object event = Fmake_event (Qnil, Qnil);
-
+#ifdef USE_KKCC
+  XSET_EVENT_TYPE (event, magic_eval_event);
+  /* channel for magic_eval events is nil */
+  XSET_MAGIC_EVAL_DATA_INTERNAL_FUNCTION (XEVENT_DATA (event), fun);
+  XSET_MAGIC_EVAL_DATA_OBJECT (XEVENT_DATA (event), object);
+#else /* not USE_KKCC */
   XEVENT (event)->event_type = magic_eval_event;
   /* channel for magic_eval events is nil */
   XEVENT (event)->event.magic_eval.internal_function = fun;
   XEVENT (event)->event.magic_eval.object = object;
+#endif /* not USE_KKCC */
   enqueue_command_event (event);
 }
 
@@ -1647,10 +1739,17 @@
 {
   Lisp_Object event = Fmake_event (Qnil, Qnil);
 
+#ifdef USE_KKCC
+  XSET_EVENT_TYPE (event, eval_event);
+  /* channel for eval events is nil */
+  XSET_EVAL_DATA_FUNCTION (XEVENT_DATA (event), function);
+  XSET_EVAL_DATA_OBJECT (XEVENT_DATA (event), object);
+#else /* not USE_KKCC */
   XEVENT (event)->event_type = eval_event;
   /* channel for eval events is nil */
   XEVENT (event)->event.eval.function = function;
   XEVENT (event)->event.eval.object = object;
+#endif /* not USE_KKCC */
   enqueue_command_event (event);
 
   return event;
@@ -1661,7 +1760,16 @@
 			 Lisp_Object object)
 {
   Lisp_Object event = Fmake_event (Qnil, Qnil);
-
+#ifdef USE_KKCC
+  XSET_EVENT_TYPE (event, misc_user_event);
+  XSET_EVENT_CHANNEL (event, channel);
+  XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), function);
+  XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), object);
+  XSET_MISC_USER_DATA_BUTTON (XEVENT_DATA (event), 0);
+  XSET_MISC_USER_DATA_MODIFIERS (XEVENT_DATA (event), 0);
+  XSET_MISC_USER_DATA_X (XEVENT_DATA (event), -1);
+  XSET_MISC_USER_DATA_Y (XEVENT_DATA (event), -1);
+#else /* not USE_KKCC */
   XEVENT (event)->event_type = misc_user_event;
   XEVENT (event)->channel = channel;
   XEVENT (event)->event.misc.function  = function;
@@ -1670,6 +1778,7 @@
   XEVENT (event)->event.misc.modifiers = 0;
   XEVENT (event)->event.misc.x         = -1;
   XEVENT (event)->event.misc.y         = -1;
+#endif /* not USE_KKCC */
   enqueue_command_event (event);
 
   return event;
@@ -1682,6 +1791,16 @@
 {
   Lisp_Object event = Fmake_event (Qnil, Qnil);
 
+#ifdef USE_KKCC
+  XSET_EVENT_TYPE (event, misc_user_event);
+  XSET_EVENT_CHANNEL (event, channel);
+  XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), function);
+  XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), object);
+  XSET_MISC_USER_DATA_BUTTON (XEVENT_DATA (event), button);
+  XSET_MISC_USER_DATA_MODIFIERS (XEVENT_DATA (event), modifiers);
+  XSET_MISC_USER_DATA_X (XEVENT_DATA (event), x);
+  XSET_MISC_USER_DATA_Y (XEVENT_DATA (event), y);
+#else /* not USE_KKCC */
   XEVENT (event)->event_type = misc_user_event;
   XEVENT (event)->channel = channel;
   XEVENT (event)->event.misc.function  = function;
@@ -1690,6 +1809,7 @@
   XEVENT (event)->event.misc.modifiers = modifiers;
   XEVENT (event)->event.misc.x         = x;
   XEVENT (event)->event.misc.y         = y;
+#endif /* not USE_KKCC */
   enqueue_command_event (event);
 
   return event;
@@ -2074,10 +2194,23 @@
       /* If this was a timeout, then we need to extract some data
 	 out of the returned closure and might need to resignal
 	 it. */
+#ifdef USE_KKCC
+      if (EVENT_TYPE (e) == timeout_event)
+#else /* not USE_KKCC */
       if (e->event_type == timeout_event)
+#endif /* not USE_KKCC */
 	{
 	  Lisp_Object tristan, isolde;
 
+#ifdef USE_KKCC
+	  XSET_TIMEOUT_DATA_ID_NUMBER (EVENT_DATA (e), 
+                          event_stream_resignal_wakeup (XTIMEOUT_DATA_INTERVAL_ID (EVENT_DATA (e)), 0, &tristan, &isolde));
+
+          XSET_TIMEOUT_DATA_FUNCTION (EVENT_DATA (e), tristan);
+          XSET_TIMEOUT_DATA_OBJECT (EVENT_DATA (e), isolde);
+	  /* next_event_internal() doesn't print out timeout events
+	     because of the extra info we just set. */
+#else /* not USE_KKCC */
 	  e->event.timeout.id_number =
 	    event_stream_resignal_wakeup (e->event.timeout.interval_id, 0,
 					  &tristan, &isolde);
@@ -2086,13 +2219,18 @@
 	  e->event.timeout.object = isolde;
 	  /* next_event_internal() doesn't print out timeout events
 	     because of the extra info we just set. */
+#endif /* not USE_KKCC */
 	  DEBUG_PRINT_EMACS_EVENT ("real, timeout", target_event);
 	}
 
       /* If we read a ^G, then set quit-flag and try to QUIT.
 	 This may be blocked (see above).
        */
+#ifdef USE_KKCC
+      if (EVENT_TYPE (e) == key_press_event &&
+#else /* not USE_KKCC */
       if (e->event_type == key_press_event &&
+#endif /* not USE_KKCC */
 	  event_matches_key_specifier_p
 	  (e, make_char (CONSOLE_QUIT_CHAR (XCONSOLE (EVENT_CHANNEL (e))))))
 	{
@@ -2453,7 +2591,7 @@
   /* This function can GC */
   struct gcpro gcpro1;
   GCPRO1 (event);
-
+   
   maybe_echo_keys (XCOMMAND_BUILDER
 		   (XCONSOLE (Vselected_console)->
 		    command_builder), 0); /* #### This sucks bigtime */
@@ -2741,7 +2879,11 @@
 	case process_event:
 	  {
 	    if (NILP (process) ||
+#ifdef USE_KKCC
+                EQ (XPROCESS_DATA_PROCESS (XEVENT_DATA (event)), process))
+#else /* not USE_KKCC */
                 EQ (XEVENT (event)->event.process.process, process))
+#endif /* not USE_KKCC */
 	      {
                 done = 1;
 		/* RMS's version always returns nil when proc is nil,
@@ -3023,15 +3165,25 @@
 
     case eval_event:
       {
+#ifdef USE_KKCC
+	call1 (XEVAL_DATA_FUNCTION (XEVENT_DATA (event)),
+	       XEVAL_DATA_OBJECT (XEVENT_DATA (event)));
+#else /* not USE_KKCC */
 	call1 (XEVENT (event)->event.eval.function,
 	       XEVENT (event)->event.eval.object);
+#endif /* not USE_KKCC */
 	return;
       }
 
     case magic_eval_event:
       {
+#ifdef USE_KKCC
+	XMAGIC_EVAL_DATA_INTERNAL_FUNCTION (XEVENT_DATA (event))
+	  XMAGIC_EVAL_DATA_OBJECT (XEVENT_DATA (event));
+#else /* not USE_KKCC */
 	(XEVENT (event)->event.magic_eval.internal_function)
 	  (XEVENT (event)->event.magic_eval.object);
+#endif /* not USE_KKCC */
 	return;
       }
 
@@ -3044,7 +3196,11 @@
 
     case process_event:
       {
+#ifdef USE_KKCC
+	Lisp_Object p = XPROCESS_DATA_PROCESS (XEVENT_DATA (event));
+#else /* not USE_KKCC */
 	Lisp_Object p = XEVENT (event)->event.process.process;
+#endif /* not USE_KKCC */
 	Charcount readstatus;
 	int iter;
 
@@ -3137,16 +3293,21 @@
     case timeout_event:
       {
 	Lisp_Event *e = XEVENT (event);
+
+#ifdef USE_KKCC
+	if (!NILP (XTIMEOUT_DATA_FUNCTION (EVENT_DATA (e))))
+	  call1 (XTIMEOUT_DATA_FUNCTION (EVENT_DATA (e)),
+                 XTIMEOUT_DATA_OBJECT (EVENT_DATA (e)));
+#else /* not USE_KKCC */
 	if (!NILP (e->event.timeout.function))
 	  call1 (e->event.timeout.function,
 		 e->event.timeout.object);
+#endif /* not USE_KKCC */
 	return;
       }
     case magic_event:
-      {
 	event_stream_handle_magic_event (XEVENT (event));
 	return;
-      }
     default:
       abort ();
     }
@@ -3297,8 +3458,13 @@
   if (XEVENT_TYPE (evee) == misc_user_event)
     {
       if (allow_misc_user_events_p && (NILP (XEVENT_NEXT (evee))))
+#ifdef USE_KKCC
+	return list2  (XEVAL_DATA_FUNCTION (XEVENT_DATA (evee)),
+		       XEVAL_DATA_OBJECT (XEVENT_DATA (evee)));
+#else /* not USE_KKCC */
 	return list2 (XEVENT (evee)->event.eval.function,
 		      XEVENT (evee)->event.eval.object);
+#endif /* not USE_KKCC */
       else
 	return Qnil;
     }
@@ -3355,12 +3521,23 @@
       && !NILP (Vretry_undefined_key_binding_unshifted))
     {
       Lisp_Object terminal = builder->most_current_event;
+#ifdef USE_KKCC
+      Lisp_Key_Data* key = XKEY_DATA (XEVENT_DATA (terminal));
+#else /* not USE_KKCC */
       struct key_data *key = &XEVENT (terminal)->event.key;
+#endif /* not USE_KKCC */
       Ichar c = 0;
+#ifdef USE_KKCC
+      if ((KEY_DATA_MODIFIERS (key) & XEMACS_MOD_SHIFT)
+          || (CHAR_OR_CHAR_INTP (KEY_DATA_KEYSYM(key))
+              && ((c = XCHAR_OR_CHAR_INT (KEY_DATA_KEYSYM(key))),
+		  c >= 'A' && c <= 'Z')))
+#else /* not USE_KKCC */
       if ((key->modifiers & XEMACS_MOD_SHIFT)
           || (CHAR_OR_CHAR_INTP (key->keysym)
               && ((c = XCHAR_OR_CHAR_INT (key->keysym)),
 		  c >= 'A' && c <= 'Z')))
+#endif /* not USE_KKCC */
         {
 	  Lisp_Object neubauten = copy_command_builder (builder, 0);
 	  struct command_builder *neub = XCOMMAND_BUILDER (neubauten);
@@ -3368,12 +3545,21 @@
 
 	  GCPRO1 (neubauten);
           terminal = event_chain_tail (neub->current_events);
+#ifdef USE_KKCC
+	  key = XKEY_DATA (XEVENT_DATA (terminal));
+
+          if (KEY_DATA_MODIFIERS (key) & XEMACS_MOD_SHIFT)
+            SET_KEY_DATA_MODIFIERS (key, (KEY_DATA_MODIFIERS (key) & (~ XEMACS_MOD_SHIFT)));
+          else
+            SET_KEY_DATA_KEYSYM (key, make_char (c + 'a' - 'A'));
+#else /* not USE_KKCC */
 	  key = &XEVENT (terminal)->event.key;
 
           if (key->modifiers & XEMACS_MOD_SHIFT)
             key->modifiers &= (~ XEMACS_MOD_SHIFT);
           else
             key->keysym = make_char (c + 'a' - 'A');
+#endif /* not USE_KKCC */
 
           result =
 	    command_builder_find_leaf_no_mule_processing
@@ -3443,8 +3629,13 @@
   if (XEVENT_TYPE (builder->most_current_event) == key_press_event
       && !NILP (Vcomposed_character_default_binding))
     {
+#ifdef USE_KKCC
+      Lisp_Object keysym =
+	XKEY_DATA_KEYSYM(XEVENT (builder->most_current_event));
+#else /* not USE_KKCC */
       Lisp_Object keysym =
 	XEVENT (builder->most_current_event)->event.key.keysym;
+#endif /* not USE_KKCC */
       if (CHARP (keysym) && !ichar_ascii_p (XCHAR (keysym)))
         return Vcomposed_character_default_binding;
     }
@@ -3867,11 +4058,23 @@
 	   */
 	Fcopy_event (event, recent);
 	e = XEVENT (recent);
+#ifdef USE_KKCC
+	if (EVENT_TYPE (e) == key_press_event)
+          XSET_KEY_DATA_MODIFIERS (EVENT_DATA (e), 
+                          XKEY_DATA_MODIFIERS (EVENT_DATA (e)) | 
+                          XEMACS_MOD_META);
+	else if (EVENT_TYPE (e) == button_press_event
+		 || EVENT_TYPE (e) == button_release_event)
+          XSET_BUTTON_DATA_MODIFIERS (EVENT_DATA (e), 
+                              XBUTTON_DATA_MODIFIERS (EVENT_DATA (e)) |
+                              XEMACS_MOD_META);
+#else /* not USE_KKCC */
 	if (e->event_type == key_press_event)
 	  e->event.key.modifiers |= XEMACS_MOD_META;
 	else if (e->event_type == button_press_event
 		 || e->event_type == button_release_event)
 	  e->event.button.modifiers |= XEMACS_MOD_META;
+#endif /* not USE_KKCC */
 	else
 	  abort ();
 
@@ -3965,9 +4168,15 @@
 #ifdef HAVE_SCROLLBARS
   Lisp_Object fun;
 
+#ifdef USE_KKCC
+  if (XEVENT_TYPE (event) != misc_user_event)
+    return 0;
+  fun = XMISC_USER_DATA_FUNCTION(XEVENT_DATA (event));
+#else /* not USE_KKCC */
   if (XEVENT (event)->event_type != misc_user_event)
     return 0;
   fun = XEVENT (event)->event.misc.function;
+#endif /* not USE_KKCC */
 
   return (EQ (fun, Qscrollbar_line_up) ||
 	  EQ (fun, Qscrollbar_line_down) ||
@@ -4104,11 +4313,19 @@
 
     pre_command_hook ();
 
+#ifdef USE_KKCC
+    if (XEVENT_TYPE (event) == misc_user_event)
+      {
+	call1 (XMISC_USER_DATA_FUNCTION (XEVENT_DATA (event)),
+	       XMISC_USER_DATA_OBJECT (XEVENT_DATA (event)));
+      }
+#else /* not USE_KKCC */
     if (XEVENT (event)->event_type == misc_user_event)
       {
 	call1 (XEVENT (event)->event.eval.function,
 	       XEVENT (event)->event.eval.object);
       }
+#endif /* not USE_KKCC */
     else
       {
 	Fcommand_execute (Vthis_command, Qnil, Qnil);
@@ -4292,7 +4509,11 @@
     Fselect_console (console);
 
   command_builder = XCOMMAND_BUILDER (XCONSOLE (console)->command_builder);
+#ifdef USE_KKCC
+  switch (XEVENT_TYPE (event))
+#else /* not USE_KKCC */
   switch (XEVENT (event)->event_type)
+#endif /* not USE_KKCC */
     {
     case button_press_event:
     case button_release_event:
@@ -4454,6 +4675,17 @@
 	   (a lambda expression).  So in the `eval' case I'll just
 	   convert it into a lambda expression.
 	   */
+#ifdef USE_KKCC
+	if (EQ (XMISC_USER_DATA_FUNCTION (XEVENT_DATA (event)), Qcall_interactively)
+	    && SYMBOLP (XMISC_USER_DATA_OBJECT (XEVENT_DATA (event))))
+	  Vthis_command = XMISC_USER_DATA_OBJECT (XEVENT_DATA (event));
+	else if (EQ (XMISC_USER_DATA_FUNCTION (XEVENT_DATA (event)), Qeval))
+	  Vthis_command =
+	    Fcons (Qlambda, Fcons (Qnil, XMISC_USER_DATA_OBJECT (XEVENT_DATA (event))));
+	else if (SYMBOLP (XMISC_USER_DATA_FUNCTION (XEVENT_DATA (event))))
+	  /* A scrollbar command or the like. */
+	  Vthis_command = XMISC_USER_DATA_FUNCTION (XEVENT_DATA (event));
+#else /* not USE_KKCC */
 	if (EQ (XEVENT (event)->event.eval.function, Qcall_interactively)
 	    && SYMBOLP (XEVENT (event)->event.eval.object))
 	  Vthis_command = XEVENT (event)->event.eval.object;
@@ -4463,6 +4695,7 @@
 	else if (SYMBOLP (XEVENT (event)->event.eval.function))
 	  /* A scrollbar command or the like. */
 	  Vthis_command = XEVENT (event)->event.eval.function;
+#endif /* not USE_KKCC */
 	else
 	  /* Huh? */
 	  Vthis_command = Qnil;
@@ -4479,10 +4712,8 @@
 	break;
       }
     default:
-      {
 	execute_internal_event (event);
 	break;
-      }
     }
   return Qnil;
 }
@@ -4556,7 +4787,11 @@
 	execute_internal_event (event);
       else
 	{
+#ifdef USE_KKCC
+	  if (XEVENT_TYPE (event) == misc_user_event)
+#else /* not USE_KKCC */
 	  if (XEVENT (event)->event_type == misc_user_event)
+#endif /* not USE_KKCC */
 	    reset_current_events (command_builder);
 	  result = lookup_command_event (command_builder, event, 1);
 	  if (!KEYMAPP (result))
@@ -4623,11 +4858,19 @@
   if (NILP (Vdribble_file))
     return;
 
+#ifdef USE_KKCC
+  if (XEVENT_TYPE (event) == key_press_event &&
+      !XKEY_DATA_MODIFIERS (XEVENT_DATA (event)))
+    {
+      Lisp_Object keysym = XKEY_DATA_KEYSYM (XEVENT_DATA (event));
+      if (CHARP (XKEY_DATA_KEYSYM (XEVENT_DATA (event))))
+#else /* not USE_KKCC */
   if (XEVENT (event)->event_type == key_press_event &&
       !XEVENT (event)->event.key.modifiers)
     {
       Lisp_Object keysym = XEVENT (event)->event.key.keysym;
       if (CHARP (XEVENT (event)->event.key.keysym))
+#endif /* not USE_KKCC */
 	{
 	  Ichar ch = XCHAR (keysym);
 	  Ibyte str[MAX_ICHAR_LEN];
--- a/src/event-tty.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/event-tty.c	Mon Jul 29 09:21:25 2002 +0000
@@ -66,13 +66,21 @@
 static void
 tty_timeout_to_emacs_event (Lisp_Event *emacs_event)
 {
+  /* timeout events have nil as channel */
+#ifdef USE_KKCC
+  SET_EVENT_TYPE (emacs_event, timeout_event);
+  SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### */
+  XSET_TIMEOUT_DATA_INTERVAL_ID (EVENT_DATA (emacs_event), pop_low_level_timeout (&tty_timer_queue, 0));
+  XSET_TIMEOUT_DATA_FUNCTION (EVENT_DATA (emacs_event), Qnil);
+  XSET_TIMEOUT_DATA_OBJECT (EVENT_DATA (emacs_event), Qnil);
+#else /* not USE_KKCC */
   emacs_event->event_type = timeout_event;
-  /* timeout events have nil as channel */
   emacs_event->timestamp  = 0; /* #### */
   emacs_event->event.timeout.interval_id =
     pop_low_level_timeout (&tty_timer_queue, 0);
   emacs_event->event.timeout.function = Qnil;
   emacs_event->event.timeout.object = Qnil;
+#endif /* not USE_KKCC */
 }
 
 
@@ -160,10 +168,17 @@
 
 		  assert (p);
 		  process = wrap_process (p);
+#ifdef USE_KKCC
+		  set_event_type (emacs_event, process_event);
+		  /* process events have nil as channel */
+		  SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### */
+		  XSET_PROCESS_DATA_PROCESS (EVENT_DATA (emacs_event), process);
+#else /* not USE_KKCC */
 		  emacs_event->event_type = process_event;
 		  /* process events have nil as channel */
 		  emacs_event->timestamp  = 0; /* #### */
 		  emacs_event->event.process.process = process;
+#endif /* not USE_KKCC */
 		  return;
 		}
 	    }
@@ -172,10 +187,17 @@
 	  /* Return a dummy event, so that a cycle of the command loop will
 	     occur. */
 	  drain_signal_event_pipe ();
+#ifdef USE_KKCC
+	  set_event_type (emacs_event, eval_event);
+	  /* eval events have nil as channel */
+	  XSET_EVAL_DATA_FUNCTION (EVENT_DATA (emacs_event), Qidentity);
+	  XSET_EVAL_DATA_OBJECT (EVENT_DATA (emacs_event), Qnil);
+#else /* not USE_KKCC */
 	  emacs_event->event_type = eval_event;
 	  /* eval events have nil as channel */
 	  emacs_event->event.eval.function = Qidentity;
 	  emacs_event->event.eval.object = Qnil;
+#endif /* not USE_KKCC */
 	  return;
 	}
       else if (ndesc == 0) /* timeout fired */
--- a/src/events.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/events.c	Mon Jul 29 09:21:25 2002 +0000
@@ -41,6 +41,10 @@
 
 #include "console-tty-impl.h" /* for stuff in character_to_event */
 
+#ifdef USE_KKCC
+#include "console-x.h"
+#endif /* USE_KKCC */
+
 /* Where old events go when they are explicitly deallocated.
    The event chain here is cut loose before GC, so these will be freed
    eventually.
@@ -69,6 +73,634 @@
   Vevent_resource = Qnil;
 }
 
+#ifdef USE_KKCC
+/* Make sure we lose quickly if we try to use this event */
+static void
+deinitialize_event (Lisp_Object ev)
+{
+  Lisp_Event *event = XEVENT (ev);
+
+  set_event_type (event, dead_event);
+  SET_EVENT_CHANNEL (event, Qnil);
+  set_lheader_implementation (&event->lheader, &lrecord_event);
+  XSET_EVENT_NEXT (ev, Qnil);
+  XSET_EVENT_DATA (ev, Qnil);
+}
+
+/* Set everything to zero or nil so that it's predictable. */
+void
+zero_event (Lisp_Event *e)
+{
+  SET_EVENT_DATA (e, Qnil);
+  set_event_type (e, empty_event);
+  SET_EVENT_NEXT (e, Qnil);
+  SET_EVENT_CHANNEL (e, Qnil);
+  SET_EVENT_TIMESTAMP_ZERO (e);
+}
+
+static const struct lrecord_description event_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Event, next) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Event, channel) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Event, event_data) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_event (Lisp_Object obj)
+{
+  mark_object (XEVENT_DATA(obj));
+  mark_object (XEVENT_CHANNEL(obj));
+  return (XEVENT_NEXT(obj));
+}
+
+
+static const struct lrecord_description key_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Key_Data, keysym) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_key_data (Lisp_Object obj)
+{
+  return (XKEY_DATA_KEYSYM(obj));
+}
+
+
+static const struct lrecord_description button_data_description [] = {
+  { XD_END }
+};
+
+static Lisp_Object
+mark_button_data (Lisp_Object obj)
+{
+  return Qnil;
+}
+
+
+static const struct lrecord_description motion_data_description [] = {
+  { XD_END }
+};
+
+static Lisp_Object
+mark_motion_data (Lisp_Object obj)
+{
+  return Qnil;
+}
+
+
+static const struct lrecord_description process_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Process_Data, process) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_process_data (Lisp_Object obj)
+{
+  return (XPROCESS_DATA_PROCESS(obj));
+}
+
+
+static const struct lrecord_description timeout_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Timeout_Data, function) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Timeout_Data, object) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_timeout_data (Lisp_Object obj)
+{
+  mark_object (XTIMEOUT_DATA_FUNCTION(obj));
+  return (XTIMEOUT_DATA_OBJECT(obj));
+}
+
+
+static const struct lrecord_description eval_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Eval_Data, function) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Eval_Data, object) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_eval_data (Lisp_Object obj)
+{
+  mark_object (XEVAL_DATA_FUNCTION(obj));
+  return (XEVAL_DATA_OBJECT(obj));
+}
+
+
+static const struct lrecord_description misc_user_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Misc_User_Data, function) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Misc_User_Data, object) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_misc_user_data (Lisp_Object obj)
+{
+  mark_object (XMISC_USER_DATA_FUNCTION(obj));
+  return (XMISC_USER_DATA_OBJECT(obj));
+}
+
+
+static const struct lrecord_description magic_eval_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Magic_Eval_Data, object) },
+  { XD_END }
+};
+
+static Lisp_Object
+mark_magic_eval_data (Lisp_Object obj)
+{
+  return (XMAGIC_EVAL_DATA_OBJECT(obj));
+}
+
+
+static const struct lrecord_description magic_data_description [] = {
+  { XD_END }
+};
+
+static Lisp_Object
+mark_magic_data (Lisp_Object obj)
+{
+  return Qnil;
+}
+
+
+
+static void
+print_event (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  if (print_readably)
+    printing_unreadable_object ("#<event>");
+
+  switch (XEVENT_TYPE (obj))
+    {
+    case key_press_event:
+      write_c_string (printcharfun, "#<keypress-event ");
+      break;
+    case button_press_event:
+      write_c_string (printcharfun, "#<buttondown-event ");
+      break;
+    case button_release_event:
+      write_c_string (printcharfun, "#<buttonup-event ");
+      break;
+    case magic_eval_event:
+      write_c_string (printcharfun, "#<magic-eval-event ");
+      break;
+    case magic_event:
+      write_c_string (printcharfun, "#<magic-event ");         
+      break;
+    case pointer_motion_event:
+      write_c_string (printcharfun, "#<motion-event ");
+      break;
+    case process_event:
+	write_c_string (printcharfun, "#<process-event ");
+	break;
+    case timeout_event:
+	write_c_string (printcharfun, "#<timeout-event ");
+	break;
+    case misc_user_event:
+	write_c_string (printcharfun, "#<misc-user-event ");
+	break;
+    case eval_event:
+	write_c_string (printcharfun, "#<eval-event ");
+	break;
+    case empty_event:
+	write_c_string (printcharfun, "#<empty-event>");
+        return;
+    case dead_event:
+	write_c_string (printcharfun, "#<DEALLOCATED-EVENT>");
+        return;
+    default:
+	write_c_string (printcharfun, "#<UNKNOWN-EVENT-TYPE>");
+        return;
+      }
+  
+  print_internal (XEVENT_DATA (obj), printcharfun, 1);
+  write_c_string (printcharfun, ">");
+}
+
+
+static void
+print_key_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  char buf[128];
+  if (print_readably)
+    printing_unreadable_object ("#<key_data>");
+
+  sprintf (buf, "#<key_data ");
+  /*  format_event_data_object (buf + 11, obj, 0);
+  sprintf (buf + strlen (buf), ">");
+  write_c_string (printcharfun, buf);*/
+}
+
+static void
+print_button_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  char buf[128];
+  if (print_readably)
+    printing_unreadable_object ("#<button_data>");
+
+  sprintf (buf, "#<button_data ");
+  /*  format_event_data_object (buf + 14, obj, 0);
+  sprintf (buf + strlen (buf), ">");
+  write_c_string (printcharfun, buf);*/
+}
+
+
+static void
+print_motion_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  char buf[64];
+  Lisp_Object Vx, Vy;
+
+  if (print_readably)
+    printing_unreadable_object ("#<motion_data>");
+
+  Vx = XMOTION_DATA_X (obj);
+  Vy = XMOTION_DATA_Y (obj);
+  sprintf (buf, "#<motion-data %ld, %ld>", (long) XINT (Vx), (long) XINT (Vy));
+  write_c_string (printcharfun, buf);
+}
+
+
+static void
+print_process_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  if (print_readably)
+    printing_unreadable_object ("#<process_data>");
+
+  write_c_string (print_readably, "#<process-data ");
+  print_internal (XPROCESS_DATA_PROCESS (obj), printcharfun, 1);
+  write_c_string (printcharfun, ">");
+}
+
+
+static void
+print_timeout_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  if (print_readably)
+    printing_unreadable_object ("#<timeout_data>");
+
+  write_c_string (printcharfun, "#<timeout-data ");
+  print_internal (XTIMEOUT_DATA_OBJECT (obj), printcharfun, 1);
+  write_c_string (printcharfun, ">");
+}
+
+
+static void
+print_eval_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  if (print_readably)
+    printing_unreadable_object ("#<eval_data>");
+
+  write_c_string (printcharfun, "#<eval-data ");
+  print_internal (XEVAL_DATA_FUNCTION (obj), printcharfun, 1);
+  write_c_string (printcharfun, " ");
+  print_internal (XEVAL_DATA_OBJECT (obj), printcharfun, 1);
+  write_c_string (printcharfun, ">");
+}
+
+
+static void
+print_misc_user_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  if (print_readably)
+    printing_unreadable_object ("#<misc_user_data>");
+
+  write_c_string (printcharfun, "#<misc-user-data ");
+  print_internal (XMISC_USER_DATA_FUNCTION (obj), printcharfun, 1);
+  write_c_string (printcharfun, " ");
+  print_internal (XMISC_USER_DATA_OBJECT (obj), printcharfun, 1);
+  write_c_string (printcharfun, ">");
+}
+
+
+static void
+print_magic_eval_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  //  char buf[128];
+
+  if (print_readably)
+    printing_unreadable_object ("#<magic_eval_data>");
+
+  /*  format_event_data_object (buf + 18, obj, 0);*/
+}
+
+
+static void
+print_magic_data (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+  char buf[128];
+
+  if (print_readably)
+    printing_unreadable_object ("#<magic_data>");
+
+  sprintf (buf, "#<magic-data ");
+  /*  format_event_data_object (buf + 13, obj, 0);
+  sprintf (buf + strlen (buf), ">");
+  write_c_string (print_readably, buf);*/
+}
+
+
+static int
+event_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  Lisp_Event *e1 = XEVENT (obj1);
+  Lisp_Event *e2 = XEVENT (obj2);
+
+  if (EVENT_TYPE (e1) != EVENT_TYPE (e2)) return 0;
+  if (!EQ (EVENT_CHANNEL (e1), EVENT_CHANNEL (e2))) return 0;
+/*  if (EVENT_TIMESTAMP (e1) != EVENT_TIMESTAMP (e2)) return 0; */
+  switch (EVENT_TYPE (e1))
+    {
+    default: abort ();
+
+    case process_event:
+    case timeout_event:
+    case pointer_motion_event:
+    case key_press_event:
+    case button_press_event:
+    case button_release_event:
+    case misc_user_event:
+    case eval_event:
+    case magic_eval_event:
+      return internal_equal (EVENT_DATA (e1), EVENT_DATA (e2), 0);
+
+    case magic_event:
+      {
+	struct console *con = XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e1)));
+
+#ifdef HAVE_X_WINDOWS
+	if (CONSOLE_X_P (con))
+	  return (XMAGIC_DATA_X_EVENT (EVENT_DATA (e1)).xany.serial ==
+		  XMAGIC_DATA_X_EVENT (EVENT_DATA (e2)).xany.serial);
+#endif
+#ifdef HAVE_GTK
+	if (CONSOLE_GTK_P (con))
+	  return (XMAGIC_DATA_GTK_EVENT (EVENT_DATA (e1)) ==
+		  XMAGIC_DATA_GTK_EVENT (EVENT_DATA (e2)));
+#endif
+#ifdef HAVE_MS_WINDOWS
+	if (CONSOLE_MSWINDOWS_P (con))
+	  return (!memcmp(&XMAGIC_DATA_MSWINDOWS_EVENT (EVENT_DATA (e1)),
+			  &XMAGIC_DATA_MSWINDOWS_EVENT (EVENT_DATA (e2)),
+			  sizeof (union magic_data)));
+#endif
+	abort ();
+	return 1; /* not reached */
+      }
+
+    case empty_event:      /* Empty and deallocated events are equal. */
+    case dead_event:
+      return 1;
+    }
+}
+
+static int
+key_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (EQ (XKEY_DATA_KEYSYM (obj1), XKEY_DATA_KEYSYM (obj2)) &&
+          (XKEY_DATA_MODIFIERS (obj1) == XKEY_DATA_MODIFIERS (obj2)));
+}
+
+static int
+button_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (XBUTTON_DATA_BUTTON (obj1) == XBUTTON_DATA_BUTTON (obj2) &&
+          XBUTTON_DATA_MODIFIERS (obj1) == XBUTTON_DATA_MODIFIERS (obj2));
+}
+
+static int
+motion_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (XMOTION_DATA_X (obj1) == XMOTION_DATA_X (obj2) &&
+          XMOTION_DATA_Y (obj1) == XMOTION_DATA_Y (obj2));
+}
+
+static int
+process_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return EQ (XPROCESS_DATA_PROCESS (obj1), XPROCESS_DATA_PROCESS (obj2));
+}
+
+static int
+timeout_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (internal_equal (XTIMEOUT_DATA_FUNCTION (obj1),
+                          XTIMEOUT_DATA_FUNCTION (obj2), 0) &&
+          internal_equal (XTIMEOUT_DATA_OBJECT (obj1),
+                          XTIMEOUT_DATA_OBJECT (obj2), 0));
+}
+
+static int
+eval_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (internal_equal (XEVAL_DATA_FUNCTION (obj1),
+                          XEVAL_DATA_FUNCTION (obj2), 0) &&
+          internal_equal (XEVAL_DATA_OBJECT (obj1),
+                          XEVAL_DATA_OBJECT (obj2), 0));
+}
+
+static int
+misc_user_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (internal_equal (XMISC_USER_DATA_FUNCTION (obj1), 
+                          XMISC_USER_DATA_FUNCTION (obj2), 0) &&
+          internal_equal (XMISC_USER_DATA_OBJECT (obj1), 
+                          XMISC_USER_DATA_OBJECT (obj2), 0) &&
+	      /* is this really needed for equality
+	         or is x and y also important? */
+          XMISC_USER_DATA_BUTTON (obj1) == XMISC_USER_DATA_BUTTON (obj2) &&
+          XMISC_USER_DATA_MODIFIERS (obj1) == 
+          XMISC_USER_DATA_MODIFIERS (obj2));
+}
+
+static int
+magic_eval_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{
+  return (XMAGIC_EVAL_DATA_INTERNAL_FUNCTION (obj1) ==
+          XMAGIC_EVAL_DATA_INTERNAL_FUNCTION (obj2) &&
+          internal_equal (XMAGIC_EVAL_DATA_OBJECT (obj1),
+                          XMAGIC_EVAL_DATA_OBJECT (obj2), 0));
+}
+
+static int
+magic_data_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
+{assert (0); return 0;}
+
+static unsigned long
+event_hash (Lisp_Object obj, int depth)
+{
+  Lisp_Event *e = XEVENT (obj);
+  unsigned long hash;
+
+  hash = HASH2 (EVENT_TYPE (e), LISP_HASH (EVENT_CHANNEL (e)));
+  switch (EVENT_TYPE (e))
+    {
+    case process_event:
+    case timeout_event:
+    case key_press_event:
+    case button_press_event:
+    case button_release_event:
+    case pointer_motion_event:
+    case misc_user_event:
+    case eval_event:
+    case magic_eval_event:
+      return HASH2 (hash, internal_hash (EVENT_DATA (e), depth + 1));
+
+    case magic_event:
+      {
+	struct console *con = XCONSOLE (CDFW_CONSOLE (EVENT_CHANNEL (e)));
+#ifdef HAVE_X_WINDOWS
+	if (CONSOLE_X_P (con))
+	  return HASH2 (hash, XMAGIC_DATA_X_EVENT (EVENT_DATA (e)).xany.serial);
+#endif
+#ifdef HAVE_GTK
+	if (CONSOLE_GTK_P (con))
+	  return HASH2 (hash, XMAGIC_DATA_GTK_EVENT (EVENT_DATA (e)));
+#endif
+#ifdef HAVE_MS_WINDOWS
+	if (CONSOLE_MSWINDOWS_P (con))
+	  return HASH2 (hash, XMAGIC_DATA_MSWINDOWS_EVENT (EVENT_DATA (e)));
+#endif
+	abort ();
+	return 0;
+      }
+
+    case empty_event:
+    case dead_event:
+      return hash;
+
+    default:
+      abort ();
+    }
+
+  return 0; /* unreached */
+}
+
+static unsigned long
+key_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH2 (LISP_HASH (XKEY_DATA_KEYSYM (obj)),
+                XKEY_DATA_MODIFIERS (obj));
+}
+
+static unsigned long
+button_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH2 (XBUTTON_DATA_BUTTON (obj), XBUTTON_DATA_MODIFIERS (obj));
+}
+
+static unsigned long
+motion_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH2 (XMOTION_DATA_X (obj), XMOTION_DATA_Y (obj));
+}
+
+static unsigned long
+process_data_hash (Lisp_Object obj, int depth)
+{
+  return LISP_HASH (XPROCESS_DATA_PROCESS (obj));
+}
+
+static unsigned long
+timeout_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH2 (internal_hash (XTIMEOUT_DATA_FUNCTION (obj), depth + 1),
+                internal_hash (XTIMEOUT_DATA_OBJECT (obj), depth + 1));
+}
+
+static unsigned long
+eval_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH2 (internal_hash (XEVAL_DATA_FUNCTION (obj), depth + 1),
+                internal_hash (XEVAL_DATA_OBJECT (obj), depth + 1));
+}
+
+static unsigned long
+misc_user_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH4 (internal_hash (XMISC_USER_DATA_FUNCTION (obj), depth + 1),
+                internal_hash (XMISC_USER_DATA_OBJECT (obj), depth + 1),
+                XMISC_USER_DATA_BUTTON (obj), XMISC_USER_DATA_MODIFIERS (obj));
+}
+
+static unsigned long
+magic_eval_data_hash (Lisp_Object obj, int depth)
+{
+  return HASH2 ((unsigned long) XMAGIC_EVAL_DATA_INTERNAL_FUNCTION (obj),
+                internal_hash (XMAGIC_EVAL_DATA_OBJECT (obj), depth + 1));
+}
+
+static unsigned long
+magic_data_hash (Lisp_Object obj, int depth)
+{assert(0); return 1;}
+
+DEFINE_LRECORD_IMPLEMENTATION ("key-data", key_data,
+			       0, /*dumpable-flag*/
+                               mark_key_data, 
+                               print_key_data, 0, 
+                               key_data_equal, key_data_hash, key_data_description, 
+                               Lisp_Key_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("button-data", button_data,
+			       0, /*dumpable-flag*/
+                               mark_button_data, print_button_data, 0, 
+                               button_data_equal, button_data_hash, button_data_description, 
+                               Lisp_Button_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("motion-data", motion_data,
+			       0, /*dumpable-flag*/
+                               mark_motion_data, print_motion_data, 0, 
+                               motion_data_equal, motion_data_hash, motion_data_description,
+                               Lisp_Motion_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("process-data", process_data,
+			       0, /*dumpable-flag*/
+                               mark_process_data, 
+                               print_process_data, 0,
+                               process_data_equal, process_data_hash, process_data_description,
+                               Lisp_Process_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("timeout-data", timeout_data,
+			       0, /*dumpable-flag*/
+                               mark_timeout_data,
+                               print_timeout_data, 0,
+                               timeout_data_equal, timeout_data_hash, timeout_data_description,
+                               Lisp_Timeout_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("eval-data", eval_data,
+			       0, /*dumpable-flag*/
+                               mark_eval_data, 
+                               print_eval_data, 0, 
+                               eval_data_equal, eval_data_hash, eval_data_description,
+                               Lisp_Eval_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("misc-user-data", misc_user_data,
+			       0, /*dumpable-flag*/
+                               mark_misc_user_data,
+                               print_misc_user_data,
+                               0, misc_user_data_equal, 
+                               misc_user_data_hash, misc_user_data_description, 
+                               Lisp_Misc_User_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("magic-eval-data", magic_eval_data,
+			       0, /*dumpable-flag*/
+                               mark_magic_eval_data, 
+                               print_magic_eval_data, 0, 
+                               magic_eval_data_equal,
+                               magic_eval_data_hash, magic_eval_data_description, 
+                               Lisp_Magic_Eval_Data);
+
+DEFINE_LRECORD_IMPLEMENTATION ("magic-data", magic_data,
+			       0, /*dumpable-flag*/
+                               mark_magic_data, print_magic_data, 0,
+                               magic_data_equal, magic_data_hash, magic_data_description,
+                               Lisp_Magic_Data);
+
+
+
+#else /* not USE_KKCC */
 /* Make sure we lose quickly if we try to use this event */
 static void
 deinitialize_event (Lisp_Object ev)
@@ -323,10 +955,19 @@
 
   return 0; /* unreached */
 }
-
+#endif /* not USE_KKCC */
+
+
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION ("event", event,
+				     0, /*dumpable-flag*/
+				     mark_event, print_event, 0, event_equal,
+				     event_hash, 0/*event_description*/, Lisp_Event);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("event", event,
 				     mark_event, print_event, 0, event_equal,
 				     event_hash, 0, Lisp_Event);
+#endif /* not USE_KKCC */
 
 DEFUN ("make-event", Fmake_event, 0, 2, 0, /*
 Return a new event of type TYPE, with properties described by PLIST.
@@ -404,7 +1045,11 @@
          PLIST.  In fact, processing PLIST would be wrong, because the
          sanitizing process would fill in the properties
          (e.g. CHANNEL), which we don't want in empty events.  */
+#ifdef USE_KKCC
+      set_event_type (e, empty_event);
+#else /* not USE_KKCC */
       e->event_type = empty_event;
+#endif /* not USE_KKCC */
       if (!NILP (plist))
 	invalid_operation ("Cannot set properties of empty event", plist);
       UNGCPRO;
@@ -412,19 +1057,42 @@
     }
   else if (EQ (type, Qkey_press))
     {
+#ifdef USE_KKCC
+      set_event_type (e, key_press_event);
+      XSET_KEY_DATA_KEYSYM (EVENT_DATA (e), Qunbound);
+#else /* not USE_KKCC */
       e->event_type = key_press_event;
       e->event.key.keysym = Qunbound;
+#endif /* not USE_KKCC */
     }
   else if (EQ (type, Qbutton_press))
+#ifdef USE_KKCC
+    set_event_type (e, button_press_event);
+#else /* not USE_KKCC */
     e->event_type = button_press_event;
+#endif /* not USE_KKCC */
   else if (EQ (type, Qbutton_release))
+#ifdef USE_KKCC
+    set_event_type (e, button_release_event);
+#else /* not USE_KKCC */
     e->event_type = button_release_event;
+#endif /* not USE_KKCC */
   else if (EQ (type, Qmotion))
+#ifdef USE_KKCC
+    set_event_type (e, pointer_motion_event);
+#else /* not USE_KKCC */
     e->event_type = pointer_motion_event;
+#endif /* not USE_KKCC */
   else if (EQ (type, Qmisc_user))
     {
+#ifdef USE_KKCC
+      set_event_type (e, misc_user_event);
+      XSET_MISC_USER_DATA_FUNCTION (EVENT_DATA (e), Qnil); 
+      XSET_MISC_USER_DATA_OBJECT (EVENT_DATA (e), Qnil);
+#else /* not USE_KKCC */
       e->event_type = misc_user_event;
       e->event.eval.function = e->event.eval.object = Qnil;
+#endif /* not USE_KKCC */
     }
   else
     {
@@ -445,7 +1113,11 @@
       {
 	if (EQ (keyword, Qchannel))
 	  {
+#ifdef USE_KKCC
+	    if (EVENT_TYPE(e) == key_press_event)
+#else /* not USE_KKCC */
 	    if (e->event_type == key_press_event)
+#endif /* not USE_KKCC */
 	      {
 		if (!CONSOLEP (value))
 		  value = wrong_type_argument (Qconsolep, value);
@@ -459,12 +1131,20 @@
 	  }
 	else if (EQ (keyword, Qkey))
 	  {
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case key_press_event:
 		if (!SYMBOLP (value) && !CHARP (value))
 		  invalid_argument ("Invalid event key", value);
+#ifdef USE_KKCC
+		XSET_KEY_DATA_KEYSYM (EVENT_DATA(e), value);
+#else /* not USE_KKCC */
 		e->event.key.keysym = value;
+#endif /* not USE_KKCC */
 		break;
 	      default:
 		WRONG_EVENT_TYPE_FOR_PROPERTY (type, keyword);
@@ -476,14 +1156,26 @@
 	    CHECK_NATNUM (value);
 	    check_int_range (XINT (value), 0, 7);
 
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case button_press_event:
 	      case button_release_event:
+#ifdef USE_KKCC
+		XSET_BUTTON_DATA_BUTTON (EVENT_DATA (e), XINT (value));
+#else /* not USE_KKCC */
 		e->event.button.button = XINT (value);
+#endif /* not USE_KKCC */
 		break;
 	      case misc_user_event:
+#ifdef USE_KKCC
+		XSET_MISC_USER_DATA_BUTTON (EVENT_DATA (e), XINT (value));
+#else /* not USE_KKCC */
 		e->event.misc.button = XINT (value);
+#endif /* not USE_KKCC */
 		break;
 	      default:
 		WRONG_EVENT_TYPE_FOR_PROPERTY (type, keyword);
@@ -512,20 +1204,40 @@
 		  invalid_constant ("Invalid key modifier", sym);
 	      }
 
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case key_press_event:
+#ifdef USE_KKCC
+                XSET_KEY_DATA_MODIFIERS (EVENT_DATA (e), modifiers);
+#else /* not USE_KKCC */
 		e->event.key.modifiers = modifiers;
+#endif /* not USE_KKCC */
 		break;
 	      case button_press_event:
 	      case button_release_event:
+#ifdef USE_KKCC
+                XSET_BUTTON_DATA_MODIFIERS (EVENT_DATA (e), modifiers);
+#else /* not USE_KKCC */
 		e->event.button.modifiers = modifiers;
+#endif /* not USE_KKCC */
 		break;
 	      case pointer_motion_event:
+#ifdef USE_KKCC
+                XSET_MOTION_DATA_MODIFIERS (EVENT_DATA (e), modifiers);
+#else /* not USE_KKCC */
 		e->event.motion.modifiers = modifiers;
+#endif /* not USE_KKCC */
 		break;
 	      case misc_user_event:
+#ifdef USE_KKCC
+                XSET_MISC_USER_DATA_MODIFIERS (EVENT_DATA (e), modifiers);
+#else /* not USE_KKCC */
 		e->event.misc.modifiers = modifiers;
+#endif /* not USE_KKCC */
 		break;
 	      default:
 		WRONG_EVENT_TYPE_FOR_PROPERTY (type, keyword);
@@ -534,7 +1246,11 @@
 	  }
 	else if (EQ (keyword, Qx))
 	  {
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case pointer_motion_event:
 	      case button_press_event:
@@ -552,7 +1268,11 @@
 	  }
 	else if (EQ (keyword, Qy))
 	  {
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case pointer_motion_event:
 	      case button_press_event:
@@ -570,14 +1290,26 @@
 	else if (EQ (keyword, Qtimestamp))
 	  {
 	    CHECK_NATNUM (value);
+#ifdef USE_KKCC
+	    SET_EVENT_TIMESTAMP (e, XINT (value));
+#else /* not USE_KKCC */
 	    e->timestamp = XINT (value);
+#endif /* not USE_KKCC */
 	  }
 	else if (EQ (keyword, Qfunction))
 	  {
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case misc_user_event:
+#ifdef USE_KKCC
+                XSET_MISC_USER_DATA_FUNCTION (EVENT_DATA (e), value);
+#else /* not USE_KKCC */
 		e->event.eval.function = value;
+#endif /* not USE_KKCC */
 		break;
 	      default:
 		WRONG_EVENT_TYPE_FOR_PROPERTY (type, keyword);
@@ -586,10 +1318,18 @@
 	  }
 	else if (EQ (keyword, Qobject))
 	  {
+#ifdef USE_KKCC
+	    switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
 	    switch (e->event_type)
+#endif /* not USE_KKCC */
 	      {
 	      case misc_user_event:
+#ifdef USE_KKCC
+                XSET_MISC_USER_DATA_OBJECT (EVENT_DATA (e), value);
+#else /* not USE_KKCC */
 		e->event.eval.object = value;
+#endif /* not USE_KKCC */
 		break;
 	      default:
 		WRONG_EVENT_TYPE_FOR_PROPERTY (type, keyword);
@@ -604,7 +1344,11 @@
   /* Insert the channel, if missing. */
   if (NILP (EVENT_CHANNEL (e)))
     {
+#ifdef USE_KKCC
+      if (EVENT_TYPE (e) == key_press_event)
+#else /* not USE_KKCC */
       if (e->event_type == key_press_event)
+#endif /* not USE_KKCC */
 	EVENT_CHANNEL (e) = Vselected_console;
       else
 	EVENT_CHANNEL (e) = Fselected_frame (Qnil);
@@ -620,17 +1364,32 @@
       switch (e->event_type)
 	{
 	case pointer_motion_event:
+#ifdef USE_KKCC
+	  XSET_MOTION_DATA_X (EVENT_DATA (e), coord_x);
+	  XSET_MOTION_DATA_Y (EVENT_DATA (e), coord_y);
+#else /* not USE_KKCC */
 	  e->event.motion.x = coord_x;
 	  e->event.motion.y = coord_y;
+#endif /* not USE_KKCC */
 	  break;
 	case button_press_event:
 	case button_release_event:
+#ifdef USE_KKCC
+	  XSET_BUTTON_DATA_X (EVENT_DATA (e), coord_x);
+	  XSET_BUTTON_DATA_Y (EVENT_DATA (e), coord_y);
+#else /* not USE_KKCC */
 	  e->event.button.x = coord_x;
 	  e->event.button.y = coord_y;
+#endif /* not USE_KKCC */
 	  break;
 	case misc_user_event:
+#ifdef USE_KKCC
+	  XSET_MISC_USER_DATA_X (EVENT_DATA (e), coord_x);
+	  XSET_MISC_USER_DATA_Y (EVENT_DATA (e), coord_y);
+#else /* not USE_KKCC */
 	  e->event.misc.x = coord_x;
 	  e->event.misc.y = coord_y;
+#endif /* not USE_KKCC */
 	  break;
 	default:
 	  abort();
@@ -638,27 +1397,47 @@
     }
 
   /* Finally, do some more validation.  */
+#ifdef USE_KKCC
+  switch (EVENT_TYPE(e))
+#else /* not USE_KKCC */
   switch (e->event_type)
+#endif /* not USE_KKCC */
     {
     case key_press_event:
+#ifdef USE_KKCC
+      if (UNBOUNDP (XKEY_DATA_KEYSYM (EVENT_DATA (e))))
+#else /* not USE_KKCC */
       if (UNBOUNDP (e->event.key.keysym))
+#endif /* not USE_KKCC */
 	sferror ("A key must be specified to make a keypress event",
 		      plist);
       break;
     case button_press_event:
+#ifdef USE_KKCC
+      if (!XBUTTON_DATA_BUTTON (EVENT_DATA (e)))
+#else /* not USE_KKCC */
       if (!e->event.button.button)
+#endif /* not USE_KKCC */
 	sferror
 	  ("A button must be specified to make a button-press event",
 	   plist);
       break;
     case button_release_event:
+#ifdef USE_KKCC
+      if (!XBUTTON_DATA_BUTTON (EVENT_DATA (e)))
+#else /* not USE_KKCC */
       if (!e->event.button.button)
+#endif /* not USE_KKCC */
 	sferror
 	  ("A button must be specified to make a button-release event",
 	   plist);
       break;
     case misc_user_event:
+#ifdef USE_KKCC
+      if (NILP (XMISC_USER_DATA_FUNCTION (EVENT_DATA (e))))
+#else /* not USE_KKCC */
       if (NILP (e->event.misc.function))
+#endif /* not USE_KKCC */
 	sferror ("A function must be specified to make a misc-user event",
 		      plist);
       break;
@@ -670,6 +1449,114 @@
   return event;
 }
 
+
+#ifdef USE_KKCC
+
+Lisp_Object 
+make_key_data (void)
+{
+  Lisp_Object data = allocate_key_data ();
+
+  XSET_KEY_DATA_KEYSYM (data, Qnil);
+  XSET_KEY_DATA_MODIFIERS (data, 0);  
+  
+  return data;
+}
+
+Lisp_Object
+make_button_data (void)
+{
+  Lisp_Object data = allocate_button_data ();
+
+  XSET_BUTTON_DATA_BUTTON (data, 0);
+  XSET_BUTTON_DATA_MODIFIERS (data, 0);
+  XSET_BUTTON_DATA_X (data, 0);
+  XSET_BUTTON_DATA_Y (data, 0);
+  
+  return data;
+}
+
+Lisp_Object
+make_motion_data (void)
+{
+  Lisp_Object data = allocate_motion_data ();
+
+  XSET_MOTION_DATA_X (data, 0);
+  XSET_MOTION_DATA_Y (data, 0);
+  XSET_MOTION_DATA_MODIFIERS (data, 0);
+  
+  return data;
+}
+
+Lisp_Object
+make_process_data (void)
+{
+  Lisp_Object data = allocate_process_data ();
+
+  XSET_PROCESS_DATA_PROCESS (data, Qnil);
+  
+  return data;
+}
+
+Lisp_Object
+make_timeout_data (void)
+{
+  Lisp_Object data = allocate_timeout_data ();
+
+  XSET_TIMEOUT_DATA_INTERVAL_ID (data, 0);
+  XSET_TIMEOUT_DATA_ID_NUMBER(data, 0);
+  XSET_TIMEOUT_DATA_FUNCTION(data, Qnil);
+  XSET_TIMEOUT_DATA_OBJECT (data, Qnil);
+  
+  return data;
+}
+
+Lisp_Object
+make_magic_eval_data (void)
+{
+  Lisp_Object data = allocate_magic_eval_data ();
+
+  XSET_MAGIC_EVAL_DATA_OBJECT (data, Qnil);
+  XSET_MAGIC_EVAL_DATA_INTERNAL_FUNOBJ (data, 0);
+  
+  return data;
+}
+
+Lisp_Object
+make_eval_data (void)
+{
+  Lisp_Object data = allocate_eval_data ();
+
+  XSET_EVAL_DATA_FUNCTION (data, Qnil);
+  XSET_EVAL_DATA_OBJECT (data, Qnil);  
+
+  return data;
+}
+
+Lisp_Object
+make_magic_data (void)
+{
+  return allocate_magic_data ();
+}
+
+Lisp_Object
+make_misc_user_data (void)
+{
+  Lisp_Object data = allocate_misc_user_data ();
+
+  XSET_MISC_USER_DATA_FUNCTION (data, Qnil);
+  XSET_MISC_USER_DATA_OBJECT (data, Qnil);
+  XSET_MISC_USER_DATA_BUTTON (data, Qnil);
+  XSET_MISC_USER_DATA_MODIFIERS (data, 0);
+  XSET_MISC_USER_DATA_X (data, 0);
+  XSET_MISC_USER_DATA_Y (data, 0);
+
+  return data;
+}
+#endif /* USE_KKCC */
+
+
+
 DEFUN ("deallocate-event", Fdeallocate_event, 1, 1, 0, /*
 Allow the given event structure to be reused.
 You MUST NOT use this event object after calling this function with it.
@@ -719,6 +1606,60 @@
   return Qnil;
 }
 
+#ifdef USE_KKCC
+void
+copy_event_data (Lisp_Object dest, Lisp_Object src)
+{
+  switch (XRECORD_LHEADER (dest)->type) {
+  case lrecord_type_key_data:
+    XSET_KEY_DATA_KEYSYM (dest, XKEY_DATA_KEYSYM (src));
+    XSET_KEY_DATA_MODIFIERS (dest, XKEY_DATA_MODIFIERS (src));
+    break;
+  case lrecord_type_button_data:
+    XSET_BUTTON_DATA_BUTTON (dest, XBUTTON_DATA_BUTTON (src));
+    XSET_BUTTON_DATA_MODIFIERS (dest, XBUTTON_DATA_MODIFIERS (src));
+    XSET_BUTTON_DATA_X (dest, XBUTTON_DATA_X (src));
+    XSET_BUTTON_DATA_Y (dest, XBUTTON_DATA_Y (src));
+    break;
+  case lrecord_type_motion_data:
+    XSET_MOTION_DATA_X (dest, XMOTION_DATA_X (src));
+    XSET_MOTION_DATA_Y (dest, XMOTION_DATA_Y (src));
+    XSET_MOTION_DATA_MODIFIERS (dest, XMOTION_DATA_MODIFIERS (src));
+    break;
+  case lrecord_type_process_data:
+    XSET_PROCESS_DATA_PROCESS (dest, XPROCESS_DATA_PROCESS (src));
+    break;
+  case lrecord_type_timeout_data:
+    XSET_TIMEOUT_DATA_INTERVAL_ID (dest, XTIMEOUT_DATA_INTERVAL_ID (src));
+    XSET_TIMEOUT_DATA_ID_NUMBER (dest, XTIMEOUT_DATA_ID_NUMBER (src));
+    XSET_TIMEOUT_DATA_FUNCTION (dest, XTIMEOUT_DATA_FUNCTION (src));
+    XSET_TIMEOUT_DATA_OBJECT (dest, XTIMEOUT_DATA_OBJECT (src));
+    break;
+  case lrecord_type_eval_data:
+    XSET_EVAL_DATA_FUNCTION (dest, XEVAL_DATA_FUNCTION (src));
+    XSET_EVAL_DATA_OBJECT (dest, XEVAL_DATA_OBJECT (src));
+    break;    
+  case lrecord_type_misc_user_data:
+    XSET_MISC_USER_DATA_FUNCTION (dest, XMISC_USER_DATA_FUNCTION (src));
+    XSET_MISC_USER_DATA_OBJECT (dest, XMISC_USER_DATA_OBJECT (src));
+    XSET_MISC_USER_DATA_BUTTON (dest, XMISC_USER_DATA_BUTTON (src));
+    XSET_MISC_USER_DATA_MODIFIERS (dest, XMISC_USER_DATA_MODIFIERS (src));
+    XSET_MISC_USER_DATA_X (dest, XMISC_USER_DATA_X (src));
+    XSET_MISC_USER_DATA_Y (dest, XMISC_USER_DATA_Y (src));
+    break;
+  case lrecord_type_magic_eval_data:
+    XSET_MAGIC_EVAL_DATA_INTERNAL_FUNCTION (dest, XMAGIC_EVAL_DATA_INTERNAL_FUNCTION (src));
+    XSET_MAGIC_EVAL_DATA_OBJECT (dest, XMAGIC_EVAL_DATA_OBJECT (src));
+    break;
+  case lrecord_type_magic_data:
+    XSET_MAGIC_DATA_UNDERLYING (dest, XMAGIC_DATA_UNDERLYING (src));
+    break;
+  default:
+    break;
+  }
+}
+#endif /* USE_KKCC */
+
 DEFUN ("copy-event", Fcopy_event, 1, 2, 0, /*
 Make a copy of the event object EVENT1.
 If a second event argument EVENT2 is given, EVENT1 is copied into
@@ -743,6 +1684,14 @@
   assert (XEVENT_TYPE (event1) <= last_event_type);
   assert (XEVENT_TYPE (event2) <= last_event_type);
 
+#ifdef USE_KKCC
+  XSET_EVENT_TYPE (event2, XEVENT_TYPE (event1));
+  XSET_EVENT_CHANNEL (event2, XEVENT_CHANNEL (event1));
+  XSET_EVENT_TIMESTAMP (event2, XEVENT_TIMESTAMP (event1));
+  copy_event_data (XEVENT_DATA (event2), XEVENT_DATA (event1));
+
+  return event2;
+#else /* not USE_KKCC */
   {
     Lisp_Event *ev2 = XEVENT (event2);
     Lisp_Event *ev1 = XEVENT (event1);
@@ -754,6 +1703,7 @@
 
     return event2;
   }
+#endif /* not USE_KKCC */
 }
 
 
@@ -964,7 +1914,11 @@
 {
   Lisp_Object k = Qnil;
   int m = 0;
+#ifdef USE_KKCC
+  if (EVENT_TYPE (event) == dead_event)
+#else /* not USE_KKCC */
   if (event->event_type == dead_event)
+#endif /* not USE_KKCC */
     invalid_argument ("character-to-event called with a deallocated event!", Qunbound);
 
 #ifndef MULE
@@ -1021,11 +1975,19 @@
   else if (c == ' ')
     k = QKspace;
 
+#ifdef USE_KKCC
+  set_event_type (event, key_press_event);
+  SET_EVENT_TIMESTAMP_ZERO (event); /* #### */
+  SET_EVENT_CHANNEL (event, wrap_console (con));
+  XSET_KEY_DATA_KEYSYM (EVENT_DATA (event), (!NILP (k) ? k : make_char (c)));
+  XSET_KEY_DATA_MODIFIERS (EVENT_DATA (event), m);
+#else /* not USE_KKCC */
   event->event_type	     = key_press_event;
   event->timestamp	     = 0; /* #### */
   event->channel	     = wrap_console (con);
   event->event.key.keysym    = (!NILP (k) ? k : make_char (c));
   event->event.key.modifiers = m;
+#endif /* not USE_KKCC */
 }
 
 /* This variable controls what character name -> character code mapping
@@ -1047,32 +2009,65 @@
   Ichar c = 0;
   Lisp_Object code;
 
+#ifdef USE_KKCC
+  if (EVENT_TYPE (event) != key_press_event)
+#else /* not USE_KKCC */
   if (event->event_type != key_press_event)
+#endif /* not USE_KKCC */
     {
+#ifdef USE_KKCC
+      assert (EVENT_TYPE (event) != dead_event);
+#else /* not USE_KKCC */
       assert (event->event_type != dead_event);
+#endif /* not USE_KKCC */
       return -1;
     }
   if (!allow_extra_modifiers &&
+#ifdef USE_KKCC
+      XKEY_DATA_MODIFIERS (EVENT_DATA (event)) & (XEMACS_MOD_SUPER|XEMACS_MOD_HYPER|XEMACS_MOD_ALT))
+#else /* not USE_KKCC */
       event->event.key.modifiers & (XEMACS_MOD_SUPER|XEMACS_MOD_HYPER|XEMACS_MOD_ALT))
+#endif /* not USE_KKCC */
     return -1;
+#ifdef USE_KKCC
+  if (CHAR_OR_CHAR_INTP (XKEY_DATA_KEYSYM (EVENT_DATA (event))))
+    c = XCHAR_OR_CHAR_INT (XKEY_DATA_KEYSYM (EVENT_DATA (event)));
+  else if (!SYMBOLP (XKEY_DATA_KEYSYM (EVENT_DATA (event))))
+#else /* not USE_KKCC */
   if (CHAR_OR_CHAR_INTP (event->event.key.keysym))
     c = XCHAR_OR_CHAR_INT (event->event.key.keysym);
   else if (!SYMBOLP (event->event.key.keysym))
+#endif /* not USE_KKCC */
     abort ();
   else if (allow_non_ascii && !NILP (Vcharacter_set_property)
 	   /* Allow window-system-specific extensibility of
 	      keysym->code mapping */
+#ifdef USE_KKCC
+	   && CHAR_OR_CHAR_INTP (code = Fget (XKEY_DATA_KEYSYM (EVENT_DATA (event)),
+					      Vcharacter_set_property,
+					      Qnil)))
+#else /* not USE_KKCC */
 	   && CHAR_OR_CHAR_INTP (code = Fget (event->event.key.keysym,
 					      Vcharacter_set_property,
 					      Qnil)))
+#endif /* not USE_KKCC */
     c = XCHAR_OR_CHAR_INT (code);
+#ifdef USE_KKCC
+  else if (CHAR_OR_CHAR_INTP (code = Fget (XKEY_DATA_KEYSYM (EVENT_DATA (event)),
+					   Qascii_character, Qnil)))
+#else /* not USE_KKCC */
   else if (CHAR_OR_CHAR_INTP (code = Fget (event->event.key.keysym,
 					   Qascii_character, Qnil)))
+#endif /* not USE_KKCC */
     c = XCHAR_OR_CHAR_INT (code);
   else
     return -1;
 
+#ifdef USE_KKCC
+  if (XKEY_DATA_MODIFIERS (EVENT_DATA (event)) & XEMACS_MOD_CONTROL)
+#else /* not USE_KKCC */
   if (event->event.key.modifiers & XEMACS_MOD_CONTROL)
+#endif /* not USE_KKCC */
     {
       if (c >= 'a' && c <= 'z')
 	c -= ('a' - 'A');
@@ -1090,7 +2085,11 @@
 	if (! allow_extra_modifiers) return -1;
     }
 
+#ifdef USE_KKCC
+  if (XKEY_DATA_MODIFIERS (EVENT_DATA (event)) & XEMACS_MOD_META)
+#else /* not USE_KKCC */
   if (event->event.key.modifiers & XEMACS_MOD_META)
+#endif /* not USE_KKCC */
     {
       if (! allow_meta) return -1;
       if (c & 0200) return -1;		/* don't allow M-oslash (overlap) */
@@ -1217,22 +2216,37 @@
   return head;
 }
 
+
 /* Concatenate a string description of EVENT onto the end of BUF.  If
    BRIEF, use short forms for keys, e.g. C- instead of control-. */
 
+#ifdef USE_KKCC
+void
+format_event_object (Eistring *buf, Lisp_Object event, int brief)
+#else /* not USE_KKCC */
 void
 format_event_object (Eistring *buf, Lisp_Event *event, int brief)
+#endif /* not USE_KKCC */
 {
   int mouse_p = 0;
   int mod = 0;
   Lisp_Object key;
 
+#ifdef USE_KKCC
+  switch (EVENT_TYPE (XEVENT(event)))
+#else /* not USE_KKCC */
   switch (event->event_type)
+#endif /* not USE_KKCC */
     {
     case key_press_event:
       {
+#ifdef USE_KKCC
+	mod = XKEY_DATA_MODIFIERS (XEVENT_DATA(event));
+	key = XKEY_DATA_KEYSYM (XEVENT_DATA(event));
+#else /* not USE_KKCC */
         mod = event->event.key.modifiers;
         key = event->event.key.keysym;
+#endif /* not USE_KKCC */
         /* Hack. */
         if (! brief && CHARP (key) &&
             mod & (XEMACS_MOD_CONTROL | XEMACS_MOD_META | XEMACS_MOD_SUPER |
@@ -1252,8 +2266,13 @@
     case button_press_event:
       {
         mouse_p++;
+#ifdef USE_KKCC
+	mod = XBUTTON_DATA_MODIFIERS (XEVENT_DATA(event));
+	key = make_char (XBUTTON_DATA_BUTTON (XEVENT_DATA(event)) + '0');
+#else /* not USE_KKCC */
         mod = event->event.button.modifiers;
         key = make_char (event->event.button.button + '0');
+#endif /* not USE_KKCC */
         break;
       }
     case magic_event:
@@ -1263,7 +2282,11 @@
 	GCPRO1 (stream);
 
 	stream = make_resizing_buffer_output_stream ();
+#ifdef USE_KKCC
+	event_stream_format_magic_event (XEVENT(event), stream);
+#else /* not USE_KKCC */
 	event_stream_format_magic_event (event, stream);
+#endif /* not USE_KKCC */
 	Lstream_flush (XLSTREAM (stream));
 	eicat_raw (buf, resizing_buffer_stream_ptr (XLSTREAM (stream)),
 		   Lstream_byte_count (XLSTREAM (stream)));
@@ -1325,6 +2348,7 @@
     eicat_c (buf, "up");
 }
 
+
 DEFUN ("eventp", Feventp, 1, 1, 0, /*
 True if OBJECT is an event object.
 */
@@ -1338,8 +2362,13 @@
 */
        (object))
 {
+#ifdef USE_KKCC
+  return EVENTP (object) && XEVENT_TYPE (object) != dead_event ?
+    Qt : Qnil;
+#else /* not USE_KKCC */
   return EVENTP (object) && XEVENT (object)->event_type != dead_event ?
     Qt : Qnil;
+#endif /* not USE_KKCC */
 }
 
 #if 0 /* debugging functions */
@@ -1405,7 +2434,11 @@
        (event))
 {
   CHECK_LIVE_EVENT (event);
+#ifdef USE_KKCC
+  switch (XEVENT_TYPE (event))
+#else /* not USE_KKCC */
   switch (XEVENT (event)->event_type)
+#endif /* not USE_KKCC */
     {
     case key_press_event:	return Qkey_press;
     case button_press_event:	return Qbutton_press;
@@ -1441,8 +2474,13 @@
   /* This junk is so that timestamps don't get to be negative, but contain
      as many bits as this particular emacs will allow.
    */
+#ifdef USE_KKCC
+  return make_int (((1L << (VALBITS - 1)) - 1) &
+		      XEVENT_TIMESTAMP (event));
+#else /* not USE_KKCC */
   return make_int (((1L << (VALBITS - 1)) - 1) &
 		      XEVENT (event)->timestamp);
+#endif /* not USE_KKCC */
 }
 
 #define TIMESTAMP_HALFSPACE (1L << (VALBITS - 2))
@@ -1467,12 +2505,31 @@
     return t1 - t2 < TIMESTAMP_HALFSPACE ? Qnil : Qt;
 }
 
+#ifdef USE_KKCC
+#define CHECK_EVENT_TYPE(e,t1,sym) do {		\
+  CHECK_LIVE_EVENT (e);				\
+  if (XEVENT_TYPE (e) != (t1))	        	\
+    e = wrong_type_argument (sym,e);		\
+} while (0)
+#else /* not USE_KKCC */
 #define CHECK_EVENT_TYPE(e,t1,sym) do {		\
   CHECK_LIVE_EVENT (e);				\
   if (XEVENT(e)->event_type != (t1))		\
     e = wrong_type_argument (sym,e);		\
 } while (0)
-
+#endif /* not USE_KKCC */
+
+#ifdef USE_KKCC
+#define CHECK_EVENT_TYPE2(e,t1,t2,sym) do {		\
+  CHECK_LIVE_EVENT (e);					\
+  {							\
+    emacs_event_type CET_type = XEVENT_TYPE (e);	\
+    if (CET_type != (t1) &&				\
+	CET_type != (t2))				\
+      e = wrong_type_argument (sym,e);			\
+  }							\
+} while (0)
+#else /* not USE_KKCC */
 #define CHECK_EVENT_TYPE2(e,t1,t2,sym) do {		\
   CHECK_LIVE_EVENT (e);					\
   {							\
@@ -1482,7 +2539,20 @@
       e = wrong_type_argument (sym,e);			\
   }							\
 } while (0)
-
+#endif /* not USE_KKCC */
+
+#ifdef USE_KKCC
+#define CHECK_EVENT_TYPE3(e,t1,t2,t3,sym) do {		\
+  CHECK_LIVE_EVENT (e);					\
+  {							\
+    emacs_event_type CET_type = XEVENT_TYPE (e);	\
+    if (CET_type != (t1) &&				\
+	CET_type != (t2) &&				\
+	CET_type != (t3))				\
+      e = wrong_type_argument (sym,e);			\
+  }							\
+} while (0)
+#else /* not USE_KKCC */
 #define CHECK_EVENT_TYPE3(e,t1,t2,t3,sym) do {		\
   CHECK_LIVE_EVENT (e);					\
   {							\
@@ -1493,6 +2563,7 @@
       e = wrong_type_argument (sym,e);			\
   }							\
 } while (0)
+#endif /* not USE_KKCC */
 
 DEFUN ("event-key", Fevent_key, 1, 1, 0, /*
 Return the Keysym of the key-press event EVENT.
@@ -1501,7 +2572,11 @@
        (event))
 {
   CHECK_EVENT_TYPE (event, key_press_event, Qkey_press_event_p);
+#ifdef USE_KKCC
+  return XKEY_DATA_KEYSYM (XEVENT_DATA (event));
+#else /* not USE_KKCC */
   return XEVENT (event)->event.key.keysym;
+#endif /* not USE_KKCC */
 }
 
 DEFUN ("event-button", Fevent_button, 1, 1, 0, /*
@@ -1513,10 +2588,17 @@
   CHECK_EVENT_TYPE3 (event, button_press_event, button_release_event,
 		     misc_user_event, Qbutton_event_p);
 #ifdef HAVE_WINDOW_SYSTEM
+#ifdef USE_KKCC
+  if ( XEVENT_TYPE (event) == misc_user_event)
+    return make_int (XMISC_USER_DATA_BUTTON (XEVENT_DATA (event)));
+  else
+    return make_int (XBUTTON_DATA_BUTTON (XEVENT_DATA (event)));
+#else /* not USE_KKCC */
   if ( XEVENT (event)->event_type == misc_user_event)
     return make_int (XEVENT (event)->event.misc.button);
   else
     return make_int (XEVENT (event)->event.button.button);
+#endif /* not USE_KKCC */
 #else /* !HAVE_WINDOW_SYSTEM */
   return Qzero;
 #endif /* !HAVE_WINDOW_SYSTEM */
@@ -1532,6 +2614,23 @@
 {
  again:
   CHECK_LIVE_EVENT (event);
+#ifdef USE_KKCC
+  switch (XEVENT_TYPE (event))
+    {
+    case key_press_event:
+      return make_int (XKEY_DATA_MODIFIERS (XEVENT_DATA (event)));
+    case button_press_event:
+    case button_release_event:
+      return make_int (XBUTTON_DATA_MODIFIERS (XEVENT_DATA (event)));
+    case pointer_motion_event:
+      return make_int (XMOTION_DATA_MODIFIERS (XEVENT_DATA (event)));
+    case misc_user_event:
+      return make_int (XMISC_USER_DATA_MODIFIERS (XEVENT_DATA (event)));
+    default:
+      event = wrong_type_argument (intern ("key-or-mouse-event-p"), event);
+      goto again;
+    }
+#else /* not USE_KKCC */
   switch (XEVENT (event)->event_type)
     {
     case key_press_event:
@@ -1547,6 +2646,7 @@
       event = wrong_type_argument (intern ("key-or-mouse-event-p"), event);
       goto again;
     }
+#endif /* not USE_KKCC */
 }
 
 DEFUN ("event-modifiers", Fevent_modifiers, 1, 1, 0, /*
@@ -1619,6 +2719,26 @@
   struct window *w;
   struct frame *f;
 
+#ifdef USE_KKCC
+  if (XEVENT_TYPE (event) == pointer_motion_event)
+    {
+      *x = XMOTION_DATA_X (XEVENT_DATA (event));
+      *y = XMOTION_DATA_Y (XEVENT_DATA (event));
+    }
+  else if (XEVENT_TYPE (event) == button_press_event ||
+	   XEVENT_TYPE (event) == button_release_event)
+    {
+      *x = XBUTTON_DATA_X (XEVENT_DATA (event));
+      *y = XBUTTON_DATA_Y (XEVENT_DATA (event));
+    }
+  else if (XEVENT_TYPE (event) == misc_user_event)
+    {
+      *x = XMISC_USER_DATA_X (XEVENT_DATA (event));
+      *y = XMISC_USER_DATA_Y (XEVENT_DATA (event));
+    }
+  else
+    return 0;
+#else /* not USE_KKCC */
   if (XEVENT (event)->event_type == pointer_motion_event)
     {
       *x = XEVENT (event)->event.motion.x;
@@ -1637,7 +2757,7 @@
     }
   else
     return 0;
-
+#endif /* not USE_KKCC */
   f = XFRAME (EVENT_CHANNEL (XEVENT (event)));
 
   if (relative)
@@ -1774,6 +2894,27 @@
   Lisp_Object ret_obj1, ret_obj2;
 
   CHECK_LIVE_EVENT (event);
+#ifdef USE_KKCC
+  frame = XEVENT_CHANNEL (event);
+  switch (XEVENT_TYPE (event))
+    {
+    case pointer_motion_event :
+      pix_x = XMOTION_DATA_X (XEVENT_DATA (event));
+      pix_y = XMOTION_DATA_Y (XEVENT_DATA (event));
+      break;
+    case button_press_event :
+    case button_release_event :
+      pix_x = XBUTTON_DATA_X (XEVENT_DATA (event));
+      pix_y = XBUTTON_DATA_Y (XEVENT_DATA (event));
+      break;
+    case misc_user_event :
+      pix_x = XMISC_USER_DATA_X (XEVENT_DATA (event));
+      pix_y = XMISC_USER_DATA_Y (XEVENT_DATA (event));
+      break;
+    default:
+      dead_wrong_type_argument (Qmouse_event_p, event);
+    }
+#else /* not USE_KKCC */
   frame = XEVENT (event)->channel;
   switch (XEVENT (event)->event_type)
     {
@@ -1793,6 +2934,7 @@
     default:
       dead_wrong_type_argument (Qmouse_event_p, event);
     }
+#endif /* not USE_KKCC */
 
   result = pixel_to_glyph_translation (XFRAME (frame), pix_x, pix_y,
 				       &ret_x, &ret_y, &ret_obj_x, &ret_obj_y,
@@ -2101,8 +3243,13 @@
 */
        (event))
 {
+#ifdef USE_KKCC
+  CHECK_EVENT_TYPE (event, process_event, Qprocess_event_p);
+  return XPROCESS_DATA_PROCESS (XEVENT_DATA (event));
+#else /* not USE_KKCC */
   CHECK_EVENT_TYPE (event, process_event, Qprocess_event_p);
   return XEVENT (event)->event.process.process;
+#endif /* not USE_KKCC */
 }
 
 DEFUN ("event-function", Fevent_function, 1, 1, 0, /*
@@ -2113,6 +3260,20 @@
 {
  again:
   CHECK_LIVE_EVENT (event);
+#ifdef USE_KKCC
+  switch (XEVENT_TYPE (event))
+    {
+    case timeout_event:
+      return XTIMEOUT_DATA_FUNCTION (XEVENT_DATA (event));
+    case misc_user_event:
+      return XMISC_USER_DATA_FUNCTION (XEVENT_DATA (event));
+    case eval_event:
+      return XEVAL_DATA_FUNCTION (XEVENT_DATA (event));
+    default:
+      event = wrong_type_argument (intern ("timeout-or-eval-event-p"), event);
+      goto again;
+    }
+#else /* not USE_KKCC */
   switch (XEVENT (event)->event_type)
     {
     case timeout_event:
@@ -2125,6 +3286,7 @@
       event = wrong_type_argument (intern ("timeout-or-eval-event-p"), event);
       goto again;
     }
+#endif /* not USE_KKCC */
 }
 
 DEFUN ("event-object", Fevent_object, 1, 1, 0, /*
@@ -2135,6 +3297,20 @@
 {
  again:
   CHECK_LIVE_EVENT (event);
+#ifdef USE_KKCC
+  switch (XEVENT_TYPE (event))
+    {
+    case timeout_event:
+      return XTIMEOUT_DATA_OBJECT (XEVENT_DATA (event));
+    case misc_user_event:
+      return XMISC_USER_DATA_OBJECT (XEVENT_DATA (event));
+    case eval_event:
+      return XEVAL_DATA_OBJECT (XEVENT_DATA (event));
+    default:
+      event = wrong_type_argument (intern ("timeout-or-eval-event-p"), event);
+      goto again;
+    }
+#else /* not USE_KKCC */
   switch (XEVENT (event)->event_type)
     {
     case timeout_event:
@@ -2147,6 +3323,7 @@
       event = wrong_type_argument (intern ("timeout-or-eval-event-p"), event);
       goto again;
     }
+#endif /* not USE_KKCC */
 }
 
 DEFUN ("event-properties", Fevent_properties, 1, 1, 0, /*
@@ -2165,18 +3342,30 @@
 
   props = cons3 (Qtimestamp, Fevent_timestamp (event), props);
 
+#ifdef USE_KKCC
+  switch (EVENT_TYPE (e))
+#else /* not USE_KKCC */
   switch (e->event_type)
+#endif /* not USE_KKCC */
     {
     default: abort ();
 
     case process_event:
+#ifdef USE_KKCC
+      props = cons3 (Qprocess, XPROCESS_DATA_PROCESS (EVENT_DATA (e)), props);
+#else /* not USE_KKCC */
       props = cons3 (Qprocess, e->event.process.process, props);
+#endif /* not USE_KKCC */
       break;
 
     case timeout_event:
       props = cons3 (Qobject,	Fevent_object	(event), props);
       props = cons3 (Qfunction, Fevent_function (event), props);
+#ifdef USE_KKCC
+      props = cons3 (Qid, make_int (XTIMEOUT_DATA_ID_NUMBER (EVENT_DATA (e))), props);
+#else /* not USE_KKCC */
       props = cons3 (Qid, make_int (e->event.timeout.id_number), props);
+#endif /* not USE_KKCC */
       break;
 
     case key_press_event:
@@ -2236,6 +3425,17 @@
 syms_of_events (void)
 {
   INIT_LRECORD_IMPLEMENTATION (event);
+#ifdef USE_KKCC
+  INIT_LRECORD_IMPLEMENTATION (key_data);
+  INIT_LRECORD_IMPLEMENTATION (button_data);
+  INIT_LRECORD_IMPLEMENTATION (motion_data);
+  INIT_LRECORD_IMPLEMENTATION (process_data);
+  INIT_LRECORD_IMPLEMENTATION (timeout_data);
+  INIT_LRECORD_IMPLEMENTATION (eval_data);
+  INIT_LRECORD_IMPLEMENTATION (misc_user_data);
+  INIT_LRECORD_IMPLEMENTATION (magic_eval_data);
+  INIT_LRECORD_IMPLEMENTATION (magic_data);
+#endif /* USE_KKCC */  
 
   DEFSUBR (Fcharacter_to_event);
   DEFSUBR (Fevent_to_character);
--- a/src/events.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/events.h	Mon Jul 29 09:21:25 2002 +0000
@@ -27,6 +27,10 @@
 
 #include "systime.h"
 
+#ifdef USE_KKCC
+#include "opaque.h"
+#endif /* USE_KKCC */
+
 /* There is one object called an event_stream.  This object contains
    callback functions for doing the window-system-dependent operations
    that XEmacs requires.
@@ -227,6 +231,18 @@
 
 extern struct event_stream *event_stream;
 
+#ifdef USE_KKCC
+Lisp_Object make_key_data (void);
+Lisp_Object make_button_data (void);
+Lisp_Object make_motion_data (void);
+Lisp_Object make_process_data (void);
+Lisp_Object make_timeout_data (void);
+Lisp_Object make_magic_data (void);
+Lisp_Object make_magic_eval_data (void);
+Lisp_Object make_eval_data (void);
+Lisp_Object make_misc_user_data (void);
+#endif USE_KKCC
+
 typedef enum emacs_event_type
 {
   empty_event,
@@ -262,8 +278,15 @@
 
 #endif /* MULE */
 
+#ifdef USE_KKCC
+struct Lisp_Key_Data
+#else /* not USE_KKCC */
 struct key_data
+#endif /* not USE_KKCC */
 {
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   /* What keysym this is; a character or a symbol. */
   Lisp_Object keysym;
   /* Modifiers held down when key was pressed: control, meta, etc.
@@ -292,8 +315,36 @@
 #endif /* MULE */
 };
 
+#ifdef USE_KKCC
+typedef struct Lisp_Key_Data Lisp_Key_Data;
+
+DECLARE_LRECORD (key_data, Lisp_Key_Data);
+#define XKEY_DATA(x) XRECORD (x, key_data, Lisp_Key_Data)
+#define wrap_key_data(p) wrap_record (p, key_data)
+#define KEY_DATAP(x) RECORDP (x, key_data)
+#define CHECK_KEY_DATA(x) CHECK_RECORD (x, key_data)
+#define CONCHECK_KEY_DATA(x) CONCHECK_RECORD (x, key_data)
+
+#define XKEY_DATA_KEYSYM(d) (XKEY_DATA (d)->keysym)
+#define KEY_DATA_KEYSYM(d) ((d)->keysym)
+#define XKEY_DATA_MODIFIERS(d) (XKEY_DATA (d)->modifiers)
+#define KEY_DATA_MODIFIERS(d) ((d)->modifiers)
+
+#define XSET_KEY_DATA_KEYSYM(d, k) (XKEY_DATA (d)->keysym = (k))
+#define SET_KEY_DATA_KEYSYM(d, k) ((d)->keysym = k)
+#define XSET_KEY_DATA_MODIFIERS(d, m) (XKEY_DATA (d)->modifiers = m)
+#define SET_KEY_DATA_MODIFIERS(d, m) ((d)->modifiers = m)
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+struct Lisp_Button_Data
+#else /* not USE_KKCC */
 struct button_data
+#endif /* not USE_KKCC */
 {
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   /* What button went down or up. */
   int button;
   /* Bucky-bits on that button: shift, control, meta, etc.  Also
@@ -302,22 +353,91 @@
   /*  Where it was at the button-state-change (in pixels). */
   int x, y;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Button_Data Lisp_Button_Data;
 
+DECLARE_LRECORD (button_data, Lisp_Button_Data);
+#define XBUTTON_DATA(x) XRECORD (x, button_data, Lisp_Button_Data)
+#define wrap_button_data(p) wrap_record (p, button_data)
+#define BUTTON_DATAP(x) RECORDP (x, button_data)
+#define CHECK_BUTTON_DATA(x) CHECK_RECORD (x, button_data)
+#define CONCHECK_BUTTON_DATA(x) CONCHECK_RECORD (x, button_data)
+
+#define XBUTTON_DATA_BUTTON(d) (XBUTTON_DATA (d)->button)
+#define XBUTTON_DATA_MODIFIERS(d) (XBUTTON_DATA (d)->modifiers)
+#define XBUTTON_DATA_X(d) (XBUTTON_DATA (d)->x)
+#define XBUTTON_DATA_Y(d) (XBUTTON_DATA (d)->y)
+
+#define XSET_BUTTON_DATA_BUTTON(d, b) (XBUTTON_DATA (d)->button = (b))
+#define XSET_BUTTON_DATA_MODIFIERS(d, m) (XBUTTON_DATA (d)->modifiers = (m))
+#define XSET_BUTTON_DATA_X(d, new_x) (XBUTTON_DATA (d)->x = (new_x))
+#define XSET_BUTTON_DATA_Y(d, new_y) (XBUTTON_DATA (d)->y = (new_y))
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+struct Lisp_Motion_Data
+#else /* not USE_KKCC */
 struct motion_data
+#endif /* not USE_KKCC */
 {
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   /* Where it was after it moved (in pixels). */
   int x, y;
   /* Bucky-bits down when the motion was detected. */
   int modifiers;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Motion_Data Lisp_Motion_Data;
 
+DECLARE_LRECORD (motion_data, Lisp_Motion_Data);
+#define XMOTION_DATA(x) XRECORD (x, motion_data, Lisp_Motion_Data)
+#define wrap_motion_data(p) wrap_record (p, motion_data)
+#define MOTION_DATAP(x) RECORDP (x, motion_data)
+#define CHECK_MOTION_DATA(x) CHECK_RECORD (x, motion_data)
+#define CONCHECK_MOTION_DATA(x) CONCHECK_RECORD (x, motion_data)
+
+#define XMOTION_DATA_X(d) (XMOTION_DATA (d)->x)
+#define XMOTION_DATA_Y(d) (XMOTION_DATA (d)->y)
+#define XMOTION_DATA_MODIFIERS(d) (XMOTION_DATA (d)->modifiers)
+
+#define XSET_MOTION_DATA_X(d, new_x) (XMOTION_DATA (d)->x = (new_x))
+#define XSET_MOTION_DATA_Y(d, new_y) (XMOTION_DATA (d)->y = (new_y))
+#define XSET_MOTION_DATA_MODIFIERS(d, m) (XMOTION_DATA (d)->modifiers = (m))
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+struct Lisp_Process_Data
+#else /* not USE_KKCC */
 struct process_data
+#endif /* not USE_KKCC */
 {
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   /* the XEmacs "process" object in question */
   Lisp_Object process;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Process_Data Lisp_Process_Data;
 
+DECLARE_LRECORD (process_data, Lisp_Process_Data);
+#define XPROCESS_DATA(x) XRECORD (x, process_data, Lisp_Process_Data)
+#define wrap_process_data(p) wrap_record (p, process_data)
+#define PROCESS_DATAP(x) RECORDP (x, process_data)
+#define CHECK_PROCESS_DATA(x) CHECK_RECORD (x, process_data)
+#define CONCHECK_PROCESS_DATA(x) CONCHECK_RECORD (x, process_data)
+
+#define XPROCESS_DATA_PROCESS(d) (XPROCESS_DATA (d)->process)
+#define XSET_PROCESS_DATA_PROCESS(d, p) (XPROCESS_DATA (d)->process = (p))
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+struct Lisp_Timeout_Data
+#else /* not USE_KKCC */
 struct timeout_data
+#endif /* not USE_KKCC */
 {
 /*
     interval_id		The ID returned when the associated call to
@@ -332,13 +452,40 @@
 			processed.
     object		The object passed to that function.
 */
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   int interval_id;
   int id_number;
   Lisp_Object function;
   Lisp_Object object;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Timeout_Data Lisp_Timeout_Data;
 
+DECLARE_LRECORD (timeout_data, Lisp_Timeout_Data);
+#define XTIMEOUT_DATA(x) XRECORD (x, timeout_data, Lisp_Timeout_Data)
+#define wrap_timeout_data(p) wrap_record(p, timeout_data)
+#define TIMEOUT_DATAP(x) RECORDP (x, timeout_data)
+#define CHECK_TIMEOUT_DATA(x) CHECK_RECORD (x, timeout_data)
+#define CONCHECK_TIMEOUT_DATA(x) CONCHECK_RECORD (x, timeout_data)
+
+#define XTIMEOUT_DATA_INTERVAL_ID(d) XTIMEOUT_DATA (d)->interval_id
+#define XTIMEOUT_DATA_ID_NUMBER(d) XTIMEOUT_DATA (d)->id_number
+#define XTIMEOUT_DATA_FUNCTION(d) XTIMEOUT_DATA (d)->function
+#define XTIMEOUT_DATA_OBJECT(d) XTIMEOUT_DATA (d)->object
+
+#define XSET_TIMEOUT_DATA_INTERVAL_ID(d, i) XTIMEOUT_DATA (d)->interval_id = (i)
+#define XSET_TIMEOUT_DATA_ID_NUMBER(d, n) XTIMEOUT_DATA (d)->id_number = (n)
+#define XSET_TIMEOUT_DATA_FUNCTION(d, f) XTIMEOUT_DATA (d)->function = f
+#define XSET_TIMEOUT_DATA_OBJECT(d, o) XTIMEOUT_DATA (d)->object = o
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+struct Lisp_Eval_Data
+#else /* not USE_KKCC */
 struct eval_data
+#endif /* not USE_KKCC */
 {
 /* This kind of event is used internally; sometimes the window system
    interface would like to inform XEmacs of some user action (such as
@@ -350,11 +497,34 @@
     function		An elisp function to call with this event object.
     object		Argument of function.
 */
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   Lisp_Object function;
   Lisp_Object object;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Eval_Data Lisp_Eval_Data;
 
+DECLARE_LRECORD (eval_data, Lisp_Eval_Data);
+#define XEVAL_DATA(x) XRECORD (x, eval_data, Lisp_Eval_Data)
+#define wrap_eval_data(p) wrap_record(p, eval_data)
+#define EVAL_DATAP(x) RECORDP (x, eval_data)
+#define CHECK_EVAL_DATA(x) CHECK_RECORD (x, eval_data)
+#define CONCHECK_EVAL_DATA(x) CONCHECK_RECORD (x, eval_data)
+
+#define XEVAL_DATA_FUNCTION(d) (XEVAL_DATA (d)->function)
+#define XEVAL_DATA_OBJECT(d) (XEVAL_DATA (d)->object)
+
+#define XSET_EVAL_DATA_FUNCTION(d, f) (XEVAL_DATA (d)->function = f)
+#define XSET_EVAL_DATA_OBJECT(d, o) (XEVAL_DATA (d)->object = o)
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+struct Lisp_Misc_User_Data
+#else /* not USE_KKCC */
 struct misc_user_data
+#endif /* not USE_KKCC */
 {
 /* #### The misc-user type is serious junk.  It should be separated
    out into different events.  There's no reason to create
@@ -376,14 +546,48 @@
 			by the XEmacs Drag'n'Drop system. Don't depend on their
 			values for other types of misc_user_events.
 */
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   Lisp_Object function;
   Lisp_Object object;
   int button;
   int modifiers;
   int x, y;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Misc_User_Data Lisp_Misc_User_Data;
 
+DECLARE_LRECORD (misc_user_data, Lisp_Misc_User_Data);
+#define XMISC_USER_DATA(x) XRECORD (x, misc_user_data, Lisp_Misc_User_Data)
+#define wrap_misc_user_data(p) wrap_record(p, misc_user_data)
+#define MISC_USER_DATAP(x) RECORDP (x, misc_user_data)
+#define CHECK_MISC_USER_DATA(x) CHECK_RECORD (x, misc_user_data)
+#define CONCHECK_MISC_USER_DATA(x) CONCHECK_RECORD (x, misc_user_data)
+
+#define XMISC_USER_DATA_FUNCTION(d) (XMISC_USER_DATA (d)->function)
+#define XMISC_USER_DATA_OBJECT(d) (XMISC_USER_DATA (d)->object)
+#define XMISC_USER_DATA_BUTTON(d) (XMISC_USER_DATA (d)->button)
+#define XMISC_USER_DATA_MODIFIERS(d) (XMISC_USER_DATA (d)->modifiers)
+#define XMISC_USER_DATA_X(d) (XMISC_USER_DATA (d)->x)
+#define XMISC_USER_DATA_Y(d) (XMISC_USER_DATA (d)->y)
+
+#define XSET_MISC_USER_DATA_FUNCTION(d, f) (XMISC_USER_DATA (d)->function = (f))
+#define XSET_MISC_USER_DATA_OBJECT(d, o) (XMISC_USER_DATA (d)->object = (o))
+#define XSET_MISC_USER_DATA_BUTTON(d, b) (XMISC_USER_DATA (d)->button = (b))
+#define XSET_MISC_USER_DATA_MODIFIERS(d, m) (XMISC_USER_DATA (d)->modifiers = (m))
+#define XSET_MISC_USER_DATA_X(d, new_x) (XMISC_USER_DATA (d)->x = (new_x))
+#define XSET_MISC_USER_DATA_Y(d, new_y) (XMISC_USER_DATA (d)->y = (new_y))
+#endif /* USE_KKCC */
+
+#ifdef USE_KKCC
+typedef void (*lisp_obj_arg_fun) (Lisp_Object);
+
+
+struct Lisp_Magic_Eval_Data
+#else /* not USE_KKCC */
 struct magic_eval_data
+#endif /* not USE_KKCC */
 {
 /* This is like an eval event but its contents are not
    Lisp-accessible.  This allows for "internal eval events" that call
@@ -398,9 +602,32 @@
     object		Argument of function.
 
 */
+#ifdef USE_KKCC
+  struct lrecord_header lheader;
+#endif /* USE_KKCC */
   void (*internal_function) (Lisp_Object);
   Lisp_Object object;
 };
+#ifdef USE_KKCC
+typedef struct Lisp_Magic_Eval_Data Lisp_Magic_Eval_Data;
+
+DECLARE_LRECORD (magic_eval_data, Lisp_Magic_Eval_Data);
+#define XMAGIC_EVAL_DATA(x) XRECORD (x, magic_eval_data, Lisp_Magic_Eval_Data)
+#define wrap_magic_eval_data(p) wrap_record(p, magic_eval_data)
+#define MAGIC_EVAL_DATAP(x) RECORDP (x, magic_eval_data)
+#define CHECK_MAGIC_EVAL_DATA(x) CHECK_RECORD (x, magic_eval_data)
+#define CONCHECK_MAGIC_EVAL_DATA(x) CONCHECK_RECORD (x, magic_eval_data)
+
+#define XMAGIC_EVAL_DATA_INTERNAL_FUNCTION(d) \
+  XMAGIC_EVAL_DATA (d)->internal_function
+#define XMAGIC_EVAL_DATA_INTERNAL_FUNOBJ(d) (XMAGIC_EVAL_DATA (d)->internal_function)
+#define XMAGIC_EVAL_DATA_OBJECT(d) (XMAGIC_EVAL_DATA (d)->object)
+
+#define XSET_MAGIC_EVAL_DATA_INTERNAL_FUNCTION(d, f) \
+  (XMAGIC_EVAL_DATA (d)->internal_function = f)
+#define XSET_MAGIC_EVAL_DATA_INTERNAL_FUNOBJ(d, f) (XMAGIC_EVAL_DATA (d)->internal_function = (f))
+#define XSET_MAGIC_EVAL_DATA_OBJECT(d, o) (XMAGIC_EVAL_DATA (d)->object = (o))
+#endif /* USE_KKCC */
 
 #if defined (HAVE_X_WINDOWS) && defined(emacs)
 # include <X11/Xlib.h>
@@ -410,6 +637,53 @@
 #include <gdk/gdk.h>
 #endif
 
+
+#ifdef USE_KKCC
+struct Lisp_Magic_Data
+{
+  struct lrecord_header lheader;
+
+  union {
+#ifdef HAVE_GTK
+    GdkEvent          gdk_event;
+#endif
+#ifdef HAVE_X_WINDOWS
+    XEvent            x_event;
+#endif
+#ifdef HAVE_MS_WINDOWS
+    int               mswindows_event;
+#endif
+  } underlying;
+};
+
+typedef struct Lisp_Magic_Data Lisp_Magic_Data;
+
+DECLARE_LRECORD (magic_data, Lisp_Magic_Data);
+#define XMAGIC_DATA(x) XRECORD (x, magic_data, Lisp_Magic_Data)
+#define wrap_magic_data(p) wrap_record(p, magic_data)
+#define MAGIC_DATAP(x) RECORDP (x, magic_data)
+#define CHECK_MAGIC_DATA(x) CHECK_RECORD (x, magic_data)
+#define CONCHECK_MAGIC_DATA(x) CONCHECK_RECORD (x, magic_data)
+
+#define XMAGIC_DATA_UNDERLYING(d) (XMAGIC_DATA (d)->underlying)
+#define XSET_MAGIC_DATA_UNDERLYING(d, u) (XMAGIC_DATA (d)->underlying = (u))
+
+#ifdef HAVE_GTK
+#define XMAGIC_DATA_GDK_EVENT(d) (XMAGIC_DATA (d)->underlying.gdk_event)
+#define XSET_MAGIC_DATA_GDK_EVENT(d, e) (XMAGIC_DATA (d)->underlying.gdk_event = (e))
+#endif /*HAVE_GTK*/
+
+#ifdef HAVE_X_WINDOWS
+#define XMAGIC_DATA_X_EVENT(d) (XMAGIC_DATA (d)->underlying.x_event)
+#define XSET_MAGIC_DATA_X_EVENT(d, e) (XMAGIC_DATA (d)->underlying.x_event = (e))
+#endif
+
+#ifdef HAVE_MS_WINDOWS
+#define XMAGIC_DATA_MSWINDOWS_EVENT(d) (XMAGIC_DATA (d)->underlying.mswindows_event)
+#define XSET_MAGIC_DATA_MSWINDOWS_EVENT(d, e) (XMAGIC_DATA (d)->underlying.mswindows_event = (e))
+#endif
+
+#else /* not USE_KKCC */
 union magic_data
 {
 /* No user-serviceable parts within.  This is for things like
@@ -436,6 +710,8 @@
   int               underlying_mswindows_event;
 #endif
 };
+#endif /* not USE_KKCC */
+
 
 struct Lisp_Timeout
 {
@@ -506,8 +782,11 @@
      started.  Currently they are raw server timestamps. (The X
      protocol doesn't provide any easy way of translating between
      server time and real process time; yuck.) */
+  unsigned int          timestamp;
 
-  unsigned int          timestamp;
+#ifdef USE_KKCC
+  Lisp_Object event_data;
+#else /* not USE_KKCC */
   union
     {
       struct key_data           key;
@@ -520,6 +799,7 @@
       union magic_data          magic;
       struct magic_eval_data    magic_eval;
     } event;
+#endif /* not USE_KKCC */
 };
 
 DECLARE_LRECORD (event, Lisp_Event);
@@ -536,7 +816,93 @@
 #define XEVENT_TYPE(a) (XEVENT (a)->event_type)
 #define EVENT_NEXT(a) ((a)->next)
 #define XEVENT_NEXT(e) (XEVENT (e)->next)
+#ifdef USE_KKCC
+#else /* not USE_KKCC */
 #define XSET_EVENT_NEXT(e, n) do { (XEVENT (e)->next = (n)); } while (0)
+#endif /* not USE_KKCC */
+
+#ifdef USE_KKCC
+#define XEVENT_DATA(ev) (XEVENT (ev)->event_data)
+#define EVENT_DATA(ev) ((ev)->event_data)
+#define XEVENT_CHANNEL(ev) (XEVENT (ev)->channel)
+#define EVENT_CHANNEL(ev) ((ev)->channel)
+#define EVENT_TIMESTAMP(ev)                                     \
+  ((ev)->timestamp)
+#define XEVENT_TIMESTAMP(ev) EVENT_TIMESTAMP (XEVENT (ev))
+
+#define SET_EVENT_TIMESTAMP_ZERO(ev) \
+  ((ev)->timestamp = Qzero)
+#define SET_EVENT_TIMESTAMP(ev, t)                      \
+  (ev)->timestamp = (t)
+#define XSET_EVENT_TIMESTAMP(ev, t) SET_EVENT_TIMESTAMP (XEVENT (ev), t)
+
+
+#define SET_EVENT_CHANNEL(ev, c)                        \
+do {                                                    \
+  Lisp_Event *mac_event = (ev);                         \
+  mac_event->channel = (c);                             \
+} while (0)
+#define XSET_EVENT_CHANNEL(ev, c) SET_EVENT_CHANNEL (XEVENT (ev), c) 
+
+#define SET_EVENT_DATA(ev, d)                           \
+do {                                                    \
+  Lisp_Event *mac_event = (ev);                         \
+  mac_event->event_data = (d);                          \
+} while (0)
+#define XSET_EVENT_DATA(ev, d) SET_EVENT_DATA (XEVENT (ev), d)
+
+INLINE_HEADER  void set_event_type(struct Lisp_Event *event, emacs_event_type t);
+INLINE_HEADER  void
+set_event_type(struct Lisp_Event *event, emacs_event_type t) 
+{
+  event->event_type = t;
+
+  switch (t) {
+  case key_press_event:
+    event->event_data = make_key_data ();
+    break;
+  case button_press_event:
+  case button_release_event:
+    event->event_data = make_button_data ();
+    break;
+  case pointer_motion_event:
+    event->event_data = make_motion_data ();
+    break;
+  case process_event:
+    event->event_data = make_process_data ();
+    break;
+  case timeout_event:
+    event->event_data = make_timeout_data ();
+    break;
+  case magic_event:
+    event->event_data = make_magic_data ();
+    break;
+  case magic_eval_event:
+    event->event_data = make_magic_eval_data ();
+    break;
+  case eval_event:
+    event->event_data = make_eval_data ();
+    break;
+  case misc_user_event:
+    event->event_data = make_misc_user_data ();
+    break;
+  default:
+    break;
+  }
+}
+#define XSET_EVENT_TYPE(ev, t) set_event_type (XEVENT (ev), t)
+#define SET_EVENT_TYPE(ev, t) set_event_type (ev, t)
+
+
+#define SET_EVENT_NEXT(ev, n)                           \
+do {                                                    \
+  Lisp_Event *mac_event = (ev);                         \
+  mac_event->next = (n);                                \
+} while (0)
+#define XSET_EVENT_NEXT(ev, n) SET_EVENT_NEXT (XEVENT (ev), n)
+
+#endif /* USE_KKCC */
+
 
 #define EVENT_CHAIN_LOOP(event, chain) \
   for (event = chain; !NILP (event); event = XEVENT_NEXT (event))
@@ -594,7 +960,15 @@
 #define KEYSYM(x) (intern (x))
 
 /* from events.c */
+#ifdef USE_KKCC
+void format_event_object (Eistring *buf, Lisp_Object event, int brief);
+#else /* not USE_KKCC */
 void format_event_object (Eistring *buf, Lisp_Event *event, int brief);
+#endif /* not USE_KKCC */
+#ifdef USE_KKCC
+//void format_event_data_object (Eistring *buf, Lisp_Object data, int brief);
+void copy_event_data (Lisp_Object dest, Lisp_Object src);
+#endif /* USE_KKCC */
 void character_to_event (Ichar c, Lisp_Event *event,
                          struct console *con,
                          int use_console_meta_flag,
@@ -783,8 +1157,8 @@
        the first that can begin a function key sequence. */
     Lisp_Object first_mungeable_event;
   } munge_me[2];
+  Ibyte *echo_buf;
 
-  Ibyte *echo_buf;
   Bytecount echo_buf_length;          /* size of echo_buf */
   Bytecount echo_buf_index;           /* index into echo_buf
                                        * -1 before doing echoing for new cmd */
--- a/src/extents.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/extents.c	Mon Jul 29 09:21:25 2002 +0000
@@ -909,6 +909,21 @@
 /*                       Auxiliary extent structure                     */
 /************************************************************************/
 
+#ifdef USE_KKCC
+static const struct lrecord_description extent_auxiliary_description[] ={
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, begin_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, end_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, parent) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, children) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, invisible) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, read_only) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, mouse_face) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, initial_redisplay_function) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, before_change_functions) },
+  { XD_LISP_OBJECT, offsetof (struct extent_auxiliary, after_change_functions) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
 static Lisp_Object
 mark_extent_auxiliary (Lisp_Object obj)
 {
@@ -925,10 +940,16 @@
   return data->parent;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("extent-auxiliary", extent_auxiliary,
+			       0, /*dumpable-flag*/
+                               mark_extent_auxiliary, internal_object_printer,
+			       0, 0, 0, extent_auxiliary_description, struct extent_auxiliary);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("extent-auxiliary", extent_auxiliary,
                                mark_extent_auxiliary, internal_object_printer,
 			       0, 0, 0, 0, struct extent_auxiliary);
-
+#endif /* not USE_KKCC */
 void
 allocate_extent_auxiliary (EXTENT ext)
 {
@@ -972,6 +993,17 @@
 static void free_soe (struct stack_of_extents *soe);
 static void soe_invalidate (Lisp_Object obj);
 
+#ifdef USE_KKCC
+static const struct struct_description extent_list_description = {
+};
+
+static const struct lrecord_description extent_info_description [] = {
+  { XD_STRUCT_PTR, offsetof (struct extent_info, extents), 
+    XD_INDIRECT (0, 0), &extent_list_description },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_extent_info (Lisp_Object obj)
 {
@@ -1022,10 +1054,19 @@
     }
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("extent-info", extent_info,
+			       0, /*dumpable-flag*/
+                               mark_extent_info, internal_object_printer,
+			       finalize_extent_info, 0, 0, 
+			       0 /*extent_info_description*/,
+			       struct extent_info);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("extent-info", extent_info,
                                mark_extent_info, internal_object_printer,
 			       finalize_extent_info, 0, 0, 0,
 			       struct extent_info);
+#endif /* not USE_KKCC */
 
 static Lisp_Object
 allocate_extent_info (void)
@@ -3175,6 +3216,22 @@
   return Fextent_properties (obj);
 }
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("extent", extent,
+						1, /*dumpable-flag*/
+						mark_extent,
+						print_extent,
+						/* NOTE: If you declare a
+						   finalization method here,
+						   it will NOT be called.
+						   Shaft city. */
+						0,
+						extent_equal, extent_hash,
+						extent_description,
+						extent_getprop, extent_putprop,
+						extent_remprop, extent_plist,
+						struct extent);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("extent", extent,
 						mark_extent,
 						print_extent,
@@ -3188,7 +3245,7 @@
 						extent_getprop, extent_putprop,
 						extent_remprop, extent_plist,
 						struct extent);
-
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*			basic extent accessors				*/
--- a/src/faces.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/faces.c	Mon Jul 29 09:21:25 2002 +0000
@@ -276,11 +276,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("face", face,
+					  1, /*dumpable-flag*/
+					  mark_face, print_face, 0, face_equal,
+					  face_hash, face_description, face_getprop,
+					  face_putprop, face_remprop,
+					  face_plist, Lisp_Face);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("face", face,
 					  mark_face, print_face, 0, face_equal,
 					  face_hash, face_description, face_getprop,
 					  face_putprop, face_remprop,
 					  face_plist, Lisp_Face);
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*                             face read syntax                         */
--- a/src/file-coding.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/file-coding.c	Mon Jul 29 09:21:25 2002 +0000
@@ -621,6 +621,16 @@
   { XD_CODING_SYSTEM_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("coding-system", coding_system,
+					1, /*dumpable-flag*/
+					mark_coding_system,
+					print_coding_system,
+					finalize_coding_system,
+					0, 0, coding_system_description,
+					sizeof_coding_system,
+					Lisp_Coding_System);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("coding-system", coding_system,
 					mark_coding_system,
 					print_coding_system,
@@ -628,7 +638,7 @@
 					0, 0, coding_system_description,
 					sizeof_coding_system,
 					Lisp_Coding_System);
-
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*                       Creating coding systems                        */
--- a/src/floatfns.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/floatfns.c	Mon Jul 29 09:21:25 2002 +0000
@@ -185,10 +185,18 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION ("float", float,
+				     1, /*dumpable-flag*/
+				     mark_float, print_float, 0, float_equal,
+				     float_hash, float_description,
+				     Lisp_Float);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("float", float,
 				     mark_float, print_float, 0, float_equal,
 				     float_hash, float_description,
 				     Lisp_Float);
+#endif /* not USE_KKCC */
 
 /* Extract a Lisp number as a `double', or signal an error.  */
 
--- a/src/fns.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/fns.c	Mon Jul 29 09:21:25 2002 +0000
@@ -131,11 +131,21 @@
 };
 
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION ("bit-vector", bit_vector,
+					      1, /*dumpable-flag*/
+					      mark_bit_vector, print_bit_vector, 0,
+					      bit_vector_equal, bit_vector_hash,
+					      bit_vector_description, size_bit_vector,
+					      Lisp_Bit_Vector);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION ("bit-vector", bit_vector,
 					      mark_bit_vector, print_bit_vector, 0,
 					      bit_vector_equal, bit_vector_hash,
 					      bit_vector_description, size_bit_vector,
 					      Lisp_Bit_Vector);
+#endif /* not USE_KKCC */
+
 
 DEFUN ("identity", Fidentity, 1, 1, 0, /*
 Return the argument unchanged.
--- a/src/frame.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/frame.c	Mon Jul 29 09:21:25 2002 +0000
@@ -166,9 +166,16 @@
   write_fmt_string (printcharfun, " 0x%x>", frm->header.uid);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("frame", frame,
+			       0, /*dumpable-flag*/
+                               mark_frame, print_frame, 0, 0, 0, 0,
+			       struct frame);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("frame", frame,
                                mark_frame, print_frame, 0, 0, 0, 0,
 			       struct frame);
+#endif /* not USE_KKCC */
 
 static void
 nuke_all_frame_slots (struct frame *f)
@@ -1896,10 +1903,17 @@
   if (mouse_pixel_position_1 (d, &frame, &intx, &inty))
     {
       Lisp_Object event = Fmake_event (Qnil, Qnil);
+#ifdef USE_KKCC
+      XSET_EVENT_TYPE (event, pointer_motion_event);
+      XSET_EVENT_CHANNEL (event, frame);
+      XSET_MOTION_DATA_X (XEVENT_DATA (event), intx);
+      XSET_MOTION_DATA_Y (XEVENT_DATA (event), inty);
+#else /* not USE_KKCC */
       XEVENT (event)->event_type = pointer_motion_event;
       XEVENT (event)->channel = frame;
       XEVENT (event)->event.motion.x = intx;
       XEVENT (event)->event.motion.y = inty;
+#endif /* not USE_KKCC */
       return event;
     }
   else
--- a/src/glyphs.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/glyphs.c	Mon Jul 29 09:21:25 2002 +0000
@@ -1229,11 +1229,20 @@
 		 0));
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
+			       0, /*dumpable-flag*/
+			       mark_image_instance, print_image_instance,
+			       finalize_image_instance, image_instance_equal,
+			       image_instance_hash, 0,
+			       Lisp_Image_Instance);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
 			       mark_image_instance, print_image_instance,
 			       finalize_image_instance, image_instance_equal,
 			       image_instance_hash, 0,
 			       Lisp_Image_Instance);
+#endif /* not USE_KKCC */
 
 static Lisp_Object
 allocate_image_instance (Lisp_Object governing_domain, Lisp_Object parent,
@@ -3683,12 +3692,22 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC 
+DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph,
+					  1, /*dumpable-flag*/
+					  mark_glyph, print_glyph, 0,
+					  glyph_equal, glyph_hash, glyph_description,
+					  glyph_getprop, glyph_putprop,
+					  glyph_remprop, glyph_plist,
+					  Lisp_Glyph);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph,
 					  mark_glyph, print_glyph, 0,
 					  glyph_equal, glyph_hash, glyph_description,
 					  glyph_getprop, glyph_putprop,
 					  glyph_remprop, glyph_plist,
 					  Lisp_Glyph);
+#endif /* not USE_KKCC */
 
 Lisp_Object
 allocate_glyph (enum glyph_type type,
@@ -4670,7 +4689,7 @@
   register_ignored_expose (f, IMAGE_INSTANCE_DISPLAY_X (ii),
 			   IMAGE_INSTANCE_DISPLAY_Y (ii),
 			   IMAGE_INSTANCE_DISPLAY_WIDTH (ii),
-			   IMAGE_INSTANCE_DISPLAY_HEIGHT (ii));
+			   IMAGE_INSTANCE_DISPLAY_HEIGHT (ii));  
   IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
 
   MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)),
@@ -4944,7 +4963,7 @@
 	    {
 	      /* Increment the index of the image slice we are currently
 		 viewing. */
-	      IMAGE_INSTANCE_PIXMAP_SLICE (ii) =
+	      IMAGE_INSTANCE_PIXMAP_SLICE (ii) = 
 		(IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1)
 		% IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii);
 	      /* We might need to kick redisplay at this point - but we
--- a/src/gpmevent.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/gpmevent.c	Mon Jul 29 09:21:25 2002 +0000
@@ -158,19 +158,35 @@
     {
     case GPM_DOWN:
     case GPM_UP:
+#ifdef USE_KKCC
+      SET_EVENT_TYPE (event,
+	(ev.type & GPM_DOWN) ? button_press_event : button_release_event);
+      XSET_BUTTON_DATA_X (EVENT_DATA (event), ev.x);
+      XSET_BUTTON_DATA_Y (EVENT_DATA (event), ev.y);
+      XSET_BUTTON_DATA_BUTTON (EVENT_DATA (event), button);
+      XSET_BUTTON_DATA_MODIFIERS (EVENT_DATA (event), modifiers);
+#else /* not USE_KKCC */
       event->event_type =
 	(ev.type & GPM_DOWN) ? button_press_event : button_release_event;
       event->event.button.x         = ev.x;
       event->event.button.y         = ev.y;
       event->event.button.button    = button;
       event->event.button.modifiers = modifiers;
+#endif /* not USE_KKCC */
       break;
     case GPM_MOVE:
     case GPM_DRAG:
+#ifdef USE_KKCC
+      SET_EVENT_TYPE (event, pointer_motion_event);
+      XSET_MOTION_DATA_X (EVENT_DATA (event), ev.x);
+      XSET_MOTION_DATA_Y (EVENT_DATA (event), ev.y);
+      XSET_MOTION_DATA_MODIFIERS (EVENT_DATA (event), modifiers);
+#else /* not USE_KKCC */
       event->event_type             = pointer_motion_event;
       event->event.motion.x         = ev.x;
       event->event.motion.y         = ev.y;
       event->event.motion.modifiers = modifiers;
+#endif /* not USE_KKCC */
     default:
       /* This will never happen */
       break;
@@ -435,7 +451,11 @@
 	   ** William M. Perry - Nov 9, 1999
 	   */
 
+#ifdef USE_KKCC
+	  Gpm_DrawPointer (XMOTION_DATA_X (EVENT_DATA (event)),XMOTION_DATA_Y (EVENT_DATA (event)), fd);
+#else /* not USE_KKCC */
 	  Gpm_DrawPointer (event->event.motion.x,event->event.motion.y, fd);
+#endif /* not USE_KKCC */
 	}
 
       return;
--- a/src/gui-x.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/gui-x.c	Mon Jul 29 09:21:25 2002 +0000
@@ -95,9 +95,16 @@
   return data->last_menubar_buffer;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("popup-data", popup_data,
+			       0, /*dumpable-flag*/
+                               mark_popup_data, internal_object_printer,
+			       0, 0, 0, 0, struct popup_data);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("popup-data", popup_data,
                                mark_popup_data, internal_object_printer,
 			       0, 0, 0, 0, struct popup_data);
+#endif /* not USE_KKCC */
 
 /* This is like FRAME_MENUBAR_DATA (f), but contains an alist of
    (id . popup-data) for GCPRO'ing the callbacks of the popup menus
@@ -250,10 +257,17 @@
     {
       event = Fmake_event (Qnil, Qnil);
 
+#ifdef USE_KKCC
+      XSET_EVENT_TYPE (event, misc_user_event);
+      XSET_EVENT_CHANNEL (event, frame);
+      XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), Qrun_hooks);
+      XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), Qmenu_no_selection_hook);
+#else /* not USE_KKCC */
       XEVENT (event)->event_type = misc_user_event;
       XEVENT (event)->channel = frame;
       XEVENT (event)->event.eval.function = Qrun_hooks;
       XEVENT (event)->event.eval.object = Qmenu_no_selection_hook;
+#endif /* not USE_KKCC */
     }
   else
     {
@@ -271,11 +285,18 @@
 	{
 	  event = Fmake_event (Qnil, Qnil);
 
+#ifdef USE_KKCC
+	  XSET_EVENT_TYPE (event, misc_user_event);
+	  XSET_EVENT_CHANNEL (event, frame);
+	  XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), Qeval);
+	  XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), list4 (Qfuncall, callback_ex, image_instance, event));
+#else /* not USE_KKCC */
 	  XEVENT (event)->event_type = misc_user_event;
 	  XEVENT (event)->channel = frame;
 	  XEVENT (event)->event.eval.function = Qeval;
 	  XEVENT (event)->event.eval.object =
 	    list4 (Qfuncall, callback_ex, image_instance, event);
+#endif /* not USE_KKCC */
 	}
       else if (NILP (callback) || UNBOUNDP (callback))
 	event = Qnil;
@@ -286,10 +307,17 @@
 	  event = Fmake_event (Qnil, Qnil);
 
 	  get_gui_callback (callback, &fn, &arg);
+#ifdef USE_KKCC
+	  XSET_EVENT_TYPE (event, misc_user_event);
+	  XSET_EVENT_CHANNEL (event, frame);
+	  XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), fn);
+	  XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), arg);
+#else /* not USE_KKCC */
 	  XEVENT (event)->event_type = misc_user_event;
 	  XEVENT (event)->channel = frame;
 	  XEVENT (event)->event.eval.function = fn;
 	  XEVENT (event)->event.eval.object = arg;
+#endif /* not USE_KKCC */
 	}
     }
 
--- a/src/gui.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/gui.c	Mon Jul 29 09:21:25 2002 +0000
@@ -549,6 +549,25 @@
   return Qnil;
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description gui_item_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, name) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, callback) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, callback_ex) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, suffix) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, active) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, included) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, config) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, filter) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, style) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, selected) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, keys) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, accelerator) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Gui_Item, value) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_gui_item (Lisp_Object obj)
 {
@@ -770,13 +789,22 @@
 {
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("gui-item", gui_item,
+			       0, /*dumpable-flag*/
+			       mark_gui_item, print_gui_item,
+			       finalize_gui_item, gui_item_equal,
+			       gui_item_hash,
+			       gui_item_description,
+			       Lisp_Gui_Item);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("gui-item", gui_item,
 			       mark_gui_item, print_gui_item,
 			       finalize_gui_item, gui_item_equal,
 			       gui_item_hash,
 			       0,
 			       Lisp_Gui_Item);
-
+#endif /* not USE_KKCC */
 
 DOESNT_RETURN
 gui_error (const Char_ASCII *reason, Lisp_Object frob)
--- a/src/keymap.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/keymap.c	Mon Jul 29 09:21:25 2002 +0000
@@ -281,10 +281,18 @@
 };
 
 /* No need for keymap_equal #### Why not? */
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
+			       1, /*dumpable-flag*/
+                               mark_keymap, print_keymap, 0, 0, 0,
+			       keymap_description,
+			       Lisp_Keymap);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
                                mark_keymap, print_keymap, 0, 0, 0,
 			       keymap_description,
 			       Lisp_Keymap);
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*                Traversing keymaps and their parents                  */
@@ -428,11 +436,17 @@
 }
 
 static Lisp_Object
+#ifdef USE_KKCC
+make_key_description (const Lisp_Key_Data *key, int prettify)
+{
+  Lisp_Object keysym = KEY_DATA_KEYSYM(key);
+  int modifiers = KEY_DATA_MODIFIERS (key);
+#else /* not USE_KKCC */
 make_key_description (const struct key_data *key, int prettify)
 {
   Lisp_Object keysym = key->keysym;
   int modifiers = key->modifiers;
-
+#endif /* not USE_KKCC */
   if (prettify && CHARP (keysym))
     {
       /* This is a little slow, but (control a) is prettier than (control 65).
@@ -456,7 +470,11 @@
 
 static Lisp_Object
 raw_lookup_key (Lisp_Object keymap,
+#ifdef USE_KKCC
+                const Lisp_Key_Data *raw_keys, int raw_keys_count,
+#else /* not USE_KKCC */
                 const struct key_data *raw_keys, int raw_keys_count,
+#endif /* not USE_KKCC */
                 int keys_so_far, int accept_default);
 
 /* Relies on caller to gc-protect args */
@@ -640,11 +658,20 @@
 
 /* Relies on caller to gc-protect keymap, keysym, value */
 static void
+#ifdef USE_KKCC
+keymap_store (Lisp_Object keymap, const Lisp_Key_Data *key,
+#else /* not USE_KKCC */
 keymap_store (Lisp_Object keymap, const struct key_data *key,
+#endif /* not USE_KKCC */
               Lisp_Object value)
 {
+#ifdef USE_KKCC
+  Lisp_Object keysym = KEY_DATA_KEYSYM (key);
+  int modifiers = KEY_DATA_MODIFIERS (key);
+#else /* not USE_KKCC */
   Lisp_Object keysym = key->keysym;
   int modifiers = key->modifiers;
+#endif /* not USE_KKCC */
   Lisp_Keymap *k = XKEYMAP (keymap);
 
   modifiers &= ~(XEMACS_MOD_BUTTON1 | XEMACS_MOD_BUTTON2 | XEMACS_MOD_BUTTON3
@@ -1054,14 +1081,28 @@
   if (!NILP (map))
     {
       Lisp_Object idx = Fcdr (object);
+#ifdef USE_KKCC
+      Lisp_Key_Data indirection;
+#else /* not USE_KKCC */
       struct key_data indirection;
+#endif /* not USE_KKCC */
       if (CHARP (idx))
 	{
+#ifdef USE_KKCC
+	  Lisp_Object event = Fmake_event (Qnil, Qnil);
+          struct gcpro gcpro1;
+          GCPRO1 (event);
+	  XSET_EVENT_TYPE (event, empty_event);
+	  character_to_event (XCHAR (idx), XEVENT (event),
+			      XCONSOLE (Vselected_console), 0, 0);
+	  indirection = *XKEY_DATA (XEVENT_DATA (event));
+#else /* not USE_KKCC */
 	  Lisp_Event event;
 	  event.event_type = empty_event;
 	  character_to_event (XCHAR (idx), &event,
 			      XCONSOLE (Vselected_console), 0, 0);
 	  indirection = event.event.key;
+#endif /* not USE_KKCC */
 	}
       else if (CONSP (idx))
 	{
@@ -1073,7 +1114,11 @@
       else if (SYMBOLP (idx))
 	{
 	  indirection.keysym = idx;
+#ifdef USE_KKCC
+	  SET_KEY_DATA_MODIFIERS (&indirection, XINT (XCDR (idx)));
+#else /* not USE_KKCC */
 	  indirection.modifiers = 0;
+#endif /* not USE_KKCC */
 	}
       else
 	{
@@ -1099,13 +1144,24 @@
 }
 
 static Lisp_Object
+#ifdef USE_KKCC
+keymap_lookup_1 (Lisp_Object keymap, const Lisp_Key_Data *key,
+#else /* not USE_KKCC */
 keymap_lookup_1 (Lisp_Object keymap, const struct key_data *key,
+#endif /* not USE_KKCC */
                  int accept_default)
 {
   /* This function can GC */
+#ifdef USE_KKCC
+  return get_keyelt (keymap_lookup_directly (keymap,
+					     KEY_DATA_KEYSYM (key), 
+                                             KEY_DATA_MODIFIERS (key)),
+		     accept_default);
+#else /* not USE_KKCC */
   return get_keyelt (keymap_lookup_directly (keymap,
 					     key->keysym, key->modifiers),
 		     accept_default);
+#endif /* not USE_KKCC */
 }
 
 
@@ -1398,30 +1454,86 @@
  */
 
 static void
+#ifdef USE_KKCC
+define_key_parser (Lisp_Object spec, Lisp_Key_Data *returned_value)
+#else /* not USE_KKCC */
 define_key_parser (Lisp_Object spec, struct key_data *returned_value)
+#endif /* not USE_KKCC */
 {
   if (CHAR_OR_CHAR_INTP (spec))
     {
+#ifdef USE_KKCC
+      Lisp_Object event = Fmake_event (Qnil, Qnil);
+      struct gcpro gcpro1;
+      GCPRO1 (event);
+      XSET_EVENT_TYPE (event, empty_event);
+      character_to_event (XCHAR_OR_CHAR_INT (spec), XEVENT (event),
+			  XCONSOLE (Vselected_console), 0, 0);
+      SET_KEY_DATA_KEYSYM (returned_value, XKEY_DATA_KEYSYM (XEVENT_DATA (event)));
+      SET_KEY_DATA_MODIFIERS (returned_value, 
+                              XKEY_DATA_MODIFIERS (XEVENT_DATA (event)));
+#else /* not USE_KKCC */
       Lisp_Event event;
       event.event_type = empty_event;
       character_to_event (XCHAR_OR_CHAR_INT (spec), &event,
 			  XCONSOLE (Vselected_console), 0, 0);
       returned_value->keysym    = event.event.key.keysym;
       returned_value->modifiers = event.event.key.modifiers;
+#endif /* not USE_KKCC */
     }
   else if (EVENTP (spec))
     {
+#ifdef USE_KKCC
+      switch (XEVENT_TYPE (spec))
+#else /* not USE_KKCC */
       switch (XEVENT (spec)->event_type)
+#endif /* not USE_KKCC */
 	{
 	case key_press_event:
           {
+#ifdef USE_KKCC
+            SET_KEY_DATA_KEYSYM (returned_value, XKEY_DATA_KEYSYM (XEVENT_DATA (spec)));
+            SET_KEY_DATA_MODIFIERS (returned_value, XKEY_DATA_MODIFIERS (XEVENT_DATA (spec)));
+#else /* not USE_KKCC */
             returned_value->keysym    = XEVENT (spec)->event.key.keysym;
             returned_value->modifiers = XEVENT (spec)->event.key.modifiers;
+#endif /* not USE_KKCC */
 	    break;
           }
 	case button_press_event:
 	case button_release_event:
 	  {
+#ifdef USE_KKCC
+	    int down = (XEVENT_TYPE (spec) == button_press_event);
+	    switch (XBUTTON_DATA_BUTTON (XEVENT_DATA (spec)))
+	      {
+	      case 1:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton1 : Qbutton1up)); 
+		break;
+	      case 2:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton2 : Qbutton2up)); 
+		break;
+	      case 3:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton3 : Qbutton3up)); 
+		break;
+	      case 4:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton4 : Qbutton4up)); 
+		break;
+	      case 5:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton5 : Qbutton5up)); 
+		break;
+	      case 6:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton6 : Qbutton6up)); 
+		break;
+	      case 7:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton7 : Qbutton7up)); 
+		break;
+	      default:
+		SET_KEY_DATA_KEYSYM (returned_value, (down ? Qbutton0 : Qbutton0up)); 
+		break;
+	      }
+	    SET_KEY_DATA_MODIFIERS (returned_value, XBUTTON_DATA_MODIFIERS (XEVENT_DATA (spec)));
+#else /* not USE_KKCC */
 	    int down = (XEVENT (spec)->event_type == button_press_event);
 	    switch (XEVENT (spec)->event.button.button)
 	      {
@@ -1443,6 +1555,7 @@
 		returned_value->keysym = (down ? Qbutton0 : Qbutton0up); break;
 	      }
 	    returned_value->modifiers = XEVENT (spec)->event.button.modifiers;
+#endif /* not USE_KKCC */
 	    break;
 	  }
 	default:
@@ -1455,8 +1568,13 @@
       if (bucky_sym_to_bucky_bit (spec) != 0)
         invalid_argument ("Key is a modifier name", spec);
       define_key_check_and_coerce_keysym (spec, &spec, 0);
+#ifdef USE_KKCC
+      SET_KEY_DATA_KEYSYM (returned_value, spec);
+      SET_KEY_DATA_MODIFIERS (returned_value, 0);
+#else /* not USE_KKCC */
       returned_value->keysym = spec;
       returned_value->modifiers = 0;
+#endif /* not USE_KKCC */
     }
   else if (CONSP (spec))
     {
@@ -1491,8 +1609,13 @@
 			   "List must be nil-terminated", spec);
 
       define_key_check_and_coerce_keysym (spec, &keysym, modifiers);
+#ifdef USE_KKCC
+      SET_KEY_DATA_KEYSYM(returned_value, keysym);
+      SET_KEY_DATA_MODIFIERS (returned_value, modifiers);
+#else /* not USE_KKCC */
       returned_value->keysym = keysym;
       returned_value->modifiers = modifiers;
+#endif /* not USE_KKCC */
     }
   else
     {
@@ -1506,7 +1629,11 @@
 key_desc_list_to_event (Lisp_Object list, Lisp_Object event,
                         int allow_menu_events)
 {
+#ifdef USE_KKCC
+  Lisp_Key_Data raw_key;
+#else /* not USE_KKCC */
   struct key_data raw_key;
+#endif /* not USE_KKCC */
 
   if (allow_menu_events &&
       CONSP (list) &&
@@ -1521,10 +1648,17 @@
 	fn = Qcall_interactively;
       else
 	fn = Qeval;
+#ifdef USE_KKCC
+      XSET_EVENT_TYPE (event, misc_user_event);
+      XSET_EVENT_CHANNEL (event, wrap_frame (selected_frame));
+      XSET_MISC_USER_DATA_FUNCTION (XEVENT_DATA (event), fn);
+      XSET_MISC_USER_DATA_OBJECT (XEVENT_DATA (event), arg);
+#else /* not USE_KKCC */
       XEVENT (event)->channel = wrap_frame (selected_frame ());
       XEVENT (event)->event_type = misc_user_event;
       XEVENT (event)->event.eval.function = fn;
       XEVENT (event)->event.eval.object = arg;
+#endif /* not USE_KKCC */
       return;
     }
 
@@ -1541,10 +1675,17 @@
     invalid_operation ("Mouse-clicks can't appear in saved keyboard macros",
 		       Qunbound);
 
+#ifdef USE_KKCC
+  XSET_EVENT_CHANNEL (event, Vselected_console);
+  XSET_EVENT_TYPE (event, key_press_event);
+  XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), raw_key.keysym);
+  XSET_KEY_DATA_MODIFIERS (XEVENT_DATA (event), KEY_DATA_MODIFIERS (&raw_key));
+#else /* not USE_KKCC */
   XEVENT (event)->channel = Vselected_console;
   XEVENT (event)->event_type = key_press_event;
   XEVENT (event)->event.key.keysym = raw_key.keysym;
   XEVENT (event)->event.key.modifiers = raw_key.modifiers;
+#endif /* not USE_KKCC */
 }
 
 
@@ -1589,8 +1730,13 @@
       ch2 = event_to_character (XEVENT (event2), 0, 0, 0);
       retval = (ch1 >= 0 && ch2 >= 0 && ch1 == ch2);
     }
+#ifdef USE_KKCC
+  else if (EQ (XKEY_DATA_KEYSYM (EVENT_DATA (event)), XKEY_DATA_KEYSYM (XEVENT_DATA (event2))) &&
+	   XKEY_DATA_MODIFIERS (EVENT_DATA (event)) == XKEY_DATA_MODIFIERS (XEVENT_DATA (event2)))
+#else /* not USE_KKCC */
   else if (EQ (event->event.key.keysym, XEVENT (event2)->event.key.keysym) &&
 	   event->event.key.modifiers == XEVENT (event2)->event.key.modifiers)
+#endif /* not USE_KKCC */
     retval = 1;
   else
     retval = 0;
@@ -1600,8 +1746,23 @@
 }
 
 static int
+#ifdef USE_KKCC
+meta_prefix_char_p (const Lisp_Key_Data *key)
+#else /* not USE_KKCC */
 meta_prefix_char_p (const struct key_data *key)
+#endif /* not USE_KKCC */
 {
+#ifdef USE_KKCC
+  Lisp_Object event = Fmake_event (Qnil, Qnil);
+  struct gcpro gcpro1;
+  GCPRO1 (event);
+
+  XSET_EVENT_TYPE (event, key_press_event);
+  XSET_EVENT_CHANNEL (event, Vselected_console);
+  XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), KEY_DATA_KEYSYM (key));
+  XSET_KEY_DATA_MODIFIERS (XEVENT_DATA (event), KEY_DATA_MODIFIERS (key));
+  return event_matches_key_specifier_p (XEVENT(event), Vmeta_prefix_char);
+#else /* not USE_KKCC */
   Lisp_Event event;
 
   event.event_type = key_press_event;
@@ -1609,6 +1770,7 @@
   event.event.key.keysym = key->keysym;
   event.event.key.modifiers = key->modifiers;
   return event_matches_key_specifier_p (&event, Vmeta_prefix_char);
+#endif /* not USE_KKCC */
 }
 
 DEFUN ("event-matches-key-specifier-p", Fevent_matches_key_specifier_p, 2, 2, 0, /*
@@ -1622,28 +1784,49 @@
   return (event_matches_key_specifier_p (XEVENT (event), key_specifier)
 	  ? Qt : Qnil);
 }
-
+#ifdef USE_KKCC
+#define MACROLET(k,m) do {		\
+  SET_KEY_DATA_KEYSYM(returned_value, k);		\
+  SET_KEY_DATA_MODIFIERS(returned_value, m);    	\
+  RETURN_SANS_WARNINGS;			\
+} while (0)
+#else /* not USE_KKCC */
 #define MACROLET(k,m) do {		\
   returned_value->keysym = (k);		\
   returned_value->modifiers = (m);	\
   RETURN_SANS_WARNINGS;			\
 } while (0)
-
+#endif /* not USE_KKCC */
 /* ASCII grunge.
    Given a keysym, return another keysym/modifier pair which could be
    considered the same key in an ASCII world.  Backspace returns ^H, for
    example.
  */
 static void
+#ifdef USE_KKCC
+define_key_alternate_name (Lisp_Key_Data *key,
+                           Lisp_Key_Data *returned_value)
+#else /* not USE_KKCC */
 define_key_alternate_name (struct key_data *key,
                            struct key_data *returned_value)
+#endif /* not USE_KKCC */
 {
+#ifdef USE_KKCC
+  Lisp_Object keysym = KEY_DATA_KEYSYM (key);
+  int modifiers = KEY_DATA_MODIFIERS (key);
+#else /* not USE_KKCC */
   Lisp_Object keysym = key->keysym;
   int modifiers = key->modifiers;
+#endif /* not USE_KKCC */
   int modifiers_sans_control = (modifiers & (~XEMACS_MOD_CONTROL));
   int modifiers_sans_meta = (modifiers & (~XEMACS_MOD_META));
+#ifdef USE_KKCC
+  SET_KEY_DATA_KEYSYM (returned_value, Qnil); /* By default, no "alternate" key */
+  SET_KEY_DATA_MODIFIERS (returned_value, 0);
+#else /* not USE_KKCC */
   returned_value->keysym = Qnil; /* By default, no "alternate" key */
   returned_value->modifiers = 0;
+#endif /* not USE_KKCC */
   if (modifiers_sans_meta == XEMACS_MOD_CONTROL)
     {
       if (EQ (keysym, QKspace))
@@ -1694,8 +1877,11 @@
   Lisp_Object new_keys;
   int i;
   Lisp_Object mpc_binding;
+#ifdef USE_KKCC
+  Lisp_Key_Data meta_key;
+#else /* not USE_KKCC */
   struct key_data meta_key;
-
+#endif /* not USE_KKCC */
   if (NILP (Vmeta_prefix_char) ||
       (INTP (Vmeta_prefix_char) && !CHAR_INTP (Vmeta_prefix_char)))
     return;
@@ -1896,9 +2082,13 @@
   while (1)
     {
       Lisp_Object c;
+#ifdef USE_KKCC
+      Lisp_Key_Data raw_key1;
+      Lisp_Key_Data raw_key2;
+#else /* not USE_KKCC */
       struct key_data raw_key1;
       struct key_data raw_key2;
-
+#endif /* not USE_KKCC */
       if (STRINGP (keys))
 	c = make_char (string_ichar (keys, idx));
       else
@@ -2012,7 +2202,11 @@
 struct raw_lookup_key_mapper_closure
 {
   int remaining;
+#ifdef USE_KKCC
+  const Lisp_Key_Data *raw_keys;
+#else /* not USE_KKCC */
   const struct key_data *raw_keys;
+#endif /* not USE_KKCC */
   int raw_keys_count;
   int keys_so_far;
   int accept_default;
@@ -2023,7 +2217,11 @@
 /* Caller should gc-protect args (keymaps may autoload) */
 static Lisp_Object
 raw_lookup_key (Lisp_Object keymap,
+#ifdef USE_KKCC
+                const Lisp_Key_Data *raw_keys, int raw_keys_count,
+#else /* not USE_KKCC */
                 const struct key_data *raw_keys, int raw_keys_count,
+#endif /* not USE_KKCC */
                 int keys_so_far, int accept_default)
 {
   /* This function can GC */
@@ -2046,7 +2244,11 @@
   int accept_default = c->accept_default;
   int remaining = c->remaining;
   int keys_so_far = c->keys_so_far;
+#ifdef USE_KKCC
+  const Lisp_Key_Data *raw_keys = c->raw_keys;
+#else /* not USE_KKCC */
   const struct key_data *raw_keys = c->raw_keys;
+#endif /* not USE_KKCC */
   Lisp_Object cmd;
 
   if (! meta_prefix_char_p (&(raw_keys[0])))
@@ -2099,7 +2301,11 @@
 				  keys_so_far + 1, accept_default);
 	  else if ((raw_keys[1].modifiers & XEMACS_MOD_META) == 0)
 	    {
+#ifdef USE_KKCC
+	      Lisp_Key_Data metified;
+#else /* not USE_KKCC */
 	      struct key_data metified;
+#endif /* not USE_KKCC */
 	      metified.keysym = raw_keys[1].keysym;
 	      metified.modifiers = raw_keys[1].modifiers |
 		(unsigned char) XEMACS_MOD_META;
@@ -2131,8 +2337,13 @@
              int accept_default)
 {
   /* This function can GC */
+#ifdef USE_KKCC
+  Lisp_Key_Data kkk[20];
+  Lisp_Key_Data *raw_keys;
+#else /* not USE_KKCC */
   struct key_data kkk[20];
   struct key_data *raw_keys;
+#endif /* not USE_KKCC */
   int i;
 
   if (nkeys == 0)
@@ -2141,7 +2352,11 @@
   if (nkeys < countof (kkk))
     raw_keys = kkk;
   else
+#ifdef USE_KKCC
+    raw_keys = alloca_array (Lisp_Key_Data, nkeys);
+#else /* not USE_KKCC */
     raw_keys = alloca_array (struct key_data, nkeys);
+#endif /* not USE_KKCC */
 
   for (i = 0; i < nkeys; i++)
     {
@@ -2155,11 +2370,19 @@
                int accept_default)
 {
   /* This function can GC */
+#ifdef USE_KKCC
+  Lisp_Key_Data kkk[20];
+#else /* not USE_KKCC */
   struct key_data kkk[20];
+#endif /* not USE_KKCC */
   Lisp_Object event;
 
   int nkeys;
+#ifdef USE_KKCC
+  Lisp_Key_Data *raw_keys;
+#else /* not USE_KKCC */
   struct key_data *raw_keys;
+#endif /* not USE_KKCC */
   Lisp_Object tem = Qnil;
   struct gcpro gcpro1, gcpro2;
   int iii;
@@ -2171,7 +2394,11 @@
   if (nkeys < countof (kkk))
     raw_keys = kkk;
   else
+#ifdef USE_KKCC
+    raw_keys = alloca_array (Lisp_Key_Data, nkeys);
+#else /* not USE_KKCC */
     raw_keys = alloca_array (struct key_data, nkeys);
+#endif /* not USE_KKCC */
 
   nkeys = 0;
   EVENT_CHAIN_LOOP (event, event_head)
@@ -2220,7 +2447,11 @@
     {
       int length = string_char_length (keys);
       int i;
+#ifdef USE_KKCC
+      Lisp_Key_Data *raw_keys = alloca_array (Lisp_Key_Data, length);
+#else /* not USE_KKCC */
       struct key_data *raw_keys = alloca_array (struct key_data, length);
+#endif /* not USE_KKCC */
       if (length == 0)
 	return Qnil;
 
@@ -2799,7 +3030,11 @@
 
 struct map_keymap_unsorted_closure
 {
+#ifdef USE_KKCC
+  void (*fn) (const Lisp_Key_Data *, Lisp_Object binding, void *arg);
+#else /* not USE_KKCC */
   void (*fn) (const struct key_data *, Lisp_Object binding, void *arg);
+#endif /* not USE_KKCC */
   void *arg;
   int modifiers;
 };
@@ -2827,7 +3062,11 @@
     }
   else
     {
+#ifdef USE_KKCC
+      Lisp_Key_Data key;
+#else /* not USE_KKCC */
       struct key_data key;
+#endif /* not USE_KKCC */
       key.keysym = keysym;
       key.modifiers = modifiers;
       ((*closure->fn) (&key, value, closure->arg));
@@ -2934,7 +3173,11 @@
 static void
 map_keymap_sorted (Lisp_Object keymap_table,
                    int modifiers,
+#ifdef USE_KKCC
+                   void (*function) (const Lisp_Key_Data *key,
+#else /* not USE_KKCC */
                    void (*function) (const struct key_data *key,
+#endif /* not USE_KKCC */
                                      Lisp_Object binding,
                                      void *map_keymap_sorted_closure),
                    void *map_keymap_sorted_closure)
@@ -2967,7 +3210,11 @@
 			   map_keymap_sorted_closure);
       else
 	{
+#ifdef USE_KKCC
+	  Lisp_Key_Data k;
+#else /* not USE_KKCC */
 	  struct key_data k;
+#endif /* not USE_KKCC */
 	  k.keysym = keysym;
 	  k.modifiers = modifiers;
 	  ((*function) (&k, binding, map_keymap_sorted_closure));
@@ -2979,7 +3226,11 @@
 
 /* used by Fmap_keymap() */
 static void
+#ifdef USE_KKCC
+map_keymap_mapper (const Lisp_Key_Data *key,
+#else /* not USE_KKCC */
 map_keymap_mapper (const struct key_data *key,
+#endif /* not USE_KKCC */
                    Lisp_Object binding,
                    void *function)
 {
@@ -2992,7 +3243,11 @@
 
 static void
 map_keymap (Lisp_Object keymap_table, int sort_first,
+#ifdef USE_KKCC
+            void (*function) (const Lisp_Key_Data *key,
+#else /* not USE_KKCC */
             void (*function) (const struct key_data *key,
+#endif /* not USE_KKCC */
                               Lisp_Object binding,
                               void *fn_arg),
             void *fn_arg)
@@ -3091,7 +3346,11 @@
       Lisp_Object vec;
       int j;
       int len;
+#ifdef USE_KKCC
+      Lisp_Key_Data key;
+#else /* not USE_KKCC */
       struct key_data key;
+#endif /* not USE_KKCC */
       key.keysym = keysym;
       key.modifiers = modifiers;
 
@@ -3179,7 +3438,11 @@
       NGCPRO1 (p);
       for (iii = 0; iii < len; iii++)
 	{
+#ifdef USE_KKCC
+	  Lisp_Key_Data key;
+#else /* not USE_KKCC */
 	  struct key_data key;
+#endif /* not USE_KKCC */
 	  define_key_parser (Faref (prefix, make_int (iii)), &key);
 	  XVECTOR_DATA (p)[iii] = make_key_description (&key, 1);
 	}
@@ -3275,6 +3538,17 @@
       
       if (!EVENTP (key))
 	{
+#ifdef USE_KKCC
+	  Lisp_Object event = Fmake_event (Qnil, Qnil);
+	  XSET_EVENT_TYPE (event, empty_event);
+	  CHECK_CHAR_COERCE_INT (key);
+	  character_to_event (XCHAR (key), XEVENT(event),
+			      XCONSOLE (Vselected_console), 0, 1);
+	  format_event_object (buf, event, 1);
+	}
+      else
+	format_event_object (buf, key, 1);
+#else /* not USE_KKCC */
 	  Lisp_Event event;
 	  event.event_type = empty_event;
 	  CHECK_CHAR_COERCE_INT (key);
@@ -3284,6 +3558,7 @@
 	}
       else
 	format_event_object (buf, XEVENT (key), 1);
+#endif /* not USE_KKCC */
       str = eimake_string (buf);
       eifree (buf);
       return str;
@@ -3507,7 +3782,11 @@
 
 
 static Lisp_Object
+#ifdef USE_KKCC
+raw_keys_to_keys (Lisp_Key_Data *keys, int count)
+#else /* not USE_KKCC */
 raw_keys_to_keys (struct key_data *keys, int count)
+#endif /* not USE_KKCC */
 {
   Lisp_Object result = make_vector (count, Qnil);
   while (count--)
@@ -3517,17 +3796,33 @@
 
 
 static void
+#ifdef USE_KKCC
+format_raw_keys (Lisp_Key_Data *keys, int count, Eistring *buf)
+#else /* not USE_KKCC */
 format_raw_keys (struct key_data *keys, int count, Eistring *buf)
+#endif /* not USE_KKCC */
 {
   int i;
+#ifdef USE_KKCC
+  Lisp_Object event = Fmake_event (Qnil, Qnil);
+  XSET_EVENT_TYPE (event, key_press_event);
+  XSET_EVENT_CHANNEL (event, Vselected_console);
+#else /* not USE_KKCC */
   Lisp_Event event;
   event.event_type = key_press_event;
   event.channel = Vselected_console;
+#endif /* not USE_KKCC */
   for (i = 0; i < count; i++)
     {
+#ifdef USE_KKCC
+      XSET_KEY_DATA_KEYSYM (XEVENT_DATA (event), keys[i].keysym);
+      XSET_KEY_DATA_MODIFIERS (XEVENT_DATA (event), KEY_DATA_MODIFIERS (&keys[i]));
+      format_event_object (buf, event, 1);
+#else /* not USE_KKCC */
       event.event.key.keysym    = keys[i].keysym;
       event.event.key.modifiers = keys[i].modifiers;
       format_event_object (buf, &event, 1);
+#endif /* not USE_KKCC */
       if (i < count - 1)
 	eicat_c (buf, " ");
     }
@@ -3563,7 +3858,11 @@
     int keys_count;
     int modifiers_so_far;
     Eistring *target_buffer;
+#ifdef USE_KKCC
+    Lisp_Key_Data *keys_so_far;
+#else /* not USE_KKCC */
     struct key_data *keys_so_far;
+#endif /* not USE_KKCC */
     int keys_so_far_total_size;
     int keys_so_far_malloced;
   };
@@ -3592,7 +3891,11 @@
 	 Verify that these bindings aren't shadowed by other bindings
 	 in the shadow maps.  Either nil or number as value from
 	 raw_lookup_key() means undefined.  */
+#ifdef USE_KKCC
+      Lisp_Key_Data *so_far = c->keys_so_far;
+#else /* not USE_KKCC */
       struct key_data *so_far = c->keys_so_far;
+#endif /* not USE_KKCC */
 
       for (;;) /* loop over all keys that match */
 	{
@@ -3600,7 +3903,11 @@
 	  int i;
 
 	  so_far [keys_count].keysym = k;
+#ifdef USE_KKCC
+	  SET_KEY_DATA_MODIFIERS (&so_far [keys_count], modifiers_so_far);
+#else /* not USE_KKCC */
 	  so_far [keys_count].modifiers = modifiers_so_far;
+#endif /* not USE_KKCC */
 
 	  /* now loop over all shadow maps */
 	  for (i = 0; i < c->shadow_count; i++)
@@ -3681,10 +3988,18 @@
 	lower_modifiers = (modifiers_so_far | bucky);
       else
 	{
+#ifdef USE_KKCC
+	  Lisp_Key_Data *so_far = c->keys_so_far;
+#else /* not USE_KKCC */
 	  struct key_data *so_far = c->keys_so_far;
+#endif /* not USE_KKCC */
 	  lower_modifiers = 0;
 	  so_far [lower_keys_count].keysym = key;
+#ifdef USE_KKCC
+	  SET_KEY_DATA_MODIFIERS (&so_far [lower_keys_count], modifiers_so_far);
+#else /* not USE_KKCC */
 	  so_far [lower_keys_count].modifiers = modifiers_so_far;
+#endif /* not USE_KKCC */
 	  lower_keys_count++;
 	}
 
@@ -3693,12 +4008,24 @@
 	  int size = lower_keys_count + 50;
 	  if (! c->keys_so_far_malloced)
 	    {
+#ifdef USE_KKCC
+	      Lisp_Key_Data *new = xnew_array (Lisp_Key_Data, size);
+#else /* not USE_KKCC */
 	      struct key_data *new = xnew_array (struct key_data, size);
+#endif /* not USE_KKCC */
 	      memcpy ((void *)new, (const void *)c->keys_so_far,
+#ifdef USE_KKCC
+		      c->keys_so_far_total_size * sizeof (Lisp_Key_Data));
+#else /* not USE_KKCC */
 		      c->keys_so_far_total_size * sizeof (struct key_data));
+#endif /* not USE_KKCC */
 	    }
 	  else
+#ifdef USE_KKCC
+	    XREALLOC_ARRAY (c->keys_so_far, Lisp_Key_Data, size);
+#else /* not USE_KKCC */
 	    XREALLOC_ARRAY (c->keys_so_far, struct key_data, size);
+#endif /* not USE_KKCC */
 
 	  c->keys_so_far_total_size = size;
 	  c->keys_so_far_malloced = 1;
@@ -3732,7 +4059,11 @@
   /* This function can GC */
   Lisp_Object result = Qnil;
   int i;
+#ifdef USE_KKCC
+  Lisp_Key_Data raw[20];
+#else /* not USE_KKCC */
   struct key_data raw[20];
+#endif /* not USE_KKCC */
   struct where_is_closure c;
 
   c.definition = definition;
@@ -3947,7 +4278,11 @@
 
 struct describe_map_shadow_closure
   {
+#ifdef USE_KKCC
+    const Lisp_Key_Data *raw_key;
+#else /* not USE_KKCC */
     const struct key_data *raw_key;
+#endif /* not USE_KKCC */
     Lisp_Object self;
   };
 
@@ -3960,9 +4295,15 @@
   if (EQ (map, c->self))
     return Qzero;		/* Not shadowed; terminate search */
 
+#ifdef USE_KKCC
+  return !NILP (keymap_lookup_directly (map,
+					KEY_DATA_KEYSYM (c->raw_key),
+					KEY_DATA_MODIFIERS (c->raw_key)))
+#else /* not USE_KKCC */
   return !NILP (keymap_lookup_directly (map,
 					c->raw_key->keysym,
 					c->raw_key->modifiers))
+#endif /* not USE_KKCC */
     ? Qt : Qnil;
 }
 
@@ -3970,21 +4311,35 @@
 static Lisp_Object
 keymap_lookup_inherited_mapper (Lisp_Object km, void *arg)
 {
+#ifdef USE_KKCC
+  Lisp_Key_Data *k = (Lisp_Key_Data *) arg;
+  return keymap_lookup_directly (km, KEY_DATA_KEYSYM (k), KEY_DATA_MODIFIERS (k));
+#else /* not USE_KKCC */
   struct key_data *k = (struct key_data *) arg;
   return keymap_lookup_directly (km, k->keysym, k->modifiers);
+#endif /* not USE_KKCC */
 }
 
 
 static void
+#ifdef USE_KKCC
+describe_map_mapper (const Lisp_Key_Data *key,
+#else /* not USE_KKCC */
 describe_map_mapper (const struct key_data *key,
+#endif /* not USE_KKCC */
                      Lisp_Object binding,
 		     void *describe_map_closure)
 {
   /* This function can GC */
   struct describe_map_closure *closure =
     (struct describe_map_closure *) describe_map_closure;
+#ifdef USE_KKCC
+  Lisp_Object keysym = KEY_DATA_KEYSYM (key);
+  int modifiers = KEY_DATA_MODIFIERS (key);
+#else /* not USE_KKCC */
   Lisp_Object keysym = key->keysym;
   int modifiers = key->modifiers;
+#endif /* not USE_KKCC */
 
   /* Don't mention suppressed commands.  */
   if (SYMBOLP (binding)
--- a/src/lisp.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/lisp.h	Mon Jul 29 09:21:25 2002 +0000
@@ -1525,7 +1525,6 @@
 
 /* OK, you can open them again */
 
-
 /************************************************************************/
 /**		     Definitions of basic Lisp objects		       **/
 /************************************************************************/
@@ -3426,6 +3425,20 @@
 #define DUMPEDP(adr) 0
 #endif
 
+
+#ifdef USE_KKCC
+Lisp_Object allocate_event (void);
+Lisp_Object allocate_key_data (void);
+Lisp_Object allocate_button_data (void);
+Lisp_Object allocate_motion_data (void);
+Lisp_Object allocate_process_data (void);
+Lisp_Object allocate_timeout_data (void);
+Lisp_Object allocate_magic_data (void);
+Lisp_Object allocate_magic_eval_data (void);
+Lisp_Object allocate_eval_data (void);
+Lisp_Object allocate_misc_user_data (void);
+#endif /* USE_KKCC */
+
 /* Defined in buffer.c */
 Lisp_Object get_truename_buffer (Lisp_Object);
 void switch_to_buffer (Lisp_Object, Lisp_Object);
--- a/src/lrecord.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/lrecord.h	Mon Jul 29 09:21:25 2002 +0000
@@ -77,6 +77,7 @@
   unsigned int lisp_readonly :1;
 
   unsigned int unused :21;
+
 };
 
 struct lrecord_implementation;
@@ -165,6 +166,17 @@
   lrecord_type_extent_auxiliary,
   lrecord_type_marker,
   lrecord_type_event,
+#ifdef USE_KKCC
+  lrecord_type_key_data,
+  lrecord_type_button_data,
+  lrecord_type_motion_data,
+  lrecord_type_process_data,
+  lrecord_type_timeout_data,
+  lrecord_type_eval_data,
+  lrecord_type_misc_user_data,
+  lrecord_type_magic_eval_data,
+  lrecord_type_magic_data,
+#endif /* USE_KKCC */
   lrecord_type_keymap,
   lrecord_type_command_builder,
   lrecord_type_timeout,
@@ -209,6 +221,10 @@
 {
   const char *name;
 
+  /* information for the dumper: is the object dumpable and should it 
+     be dumped. */
+  unsigned int dumpable :1;
+
   /* `marker' is called at GC time, to make sure that all Lisp_Objects
      pointed to by this object get properly marked.  It should call
      the mark_object function on all Lisp_Objects in the object.  If
@@ -304,6 +320,10 @@
   ((void) ((lheader)->lisp_readonly = 1))
 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type]
 
+#ifdef USE_KKCC
+#define RECORD_DUMPABLE(lheader) (lrecord_implementations_table[(lheader)->type])->dumpable
+#endif /* USE_KKCC */
+
 /* External description stuff
 
    PLEASE NOTE: Both lrecord_description and struct_description are
@@ -635,31 +655,83 @@
 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype)
 #endif
 
+
+#ifdef USE_KKCC
+#define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \
+DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
+
+#define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype)
+
+#define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \
+DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
+
+#define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
+
+#define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype)
+
+#define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype)
+
+#define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
+
+#define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
+DECLARE_ERROR_CHECK_TYPES(c_name, structtype)			\
+const struct lrecord_implementation lrecord_##c_name =			\
+  { name, dumpable, marker, printer, nuker, equal, hash, desc,		\
+    getprop, putprop, remprop, plist, size, sizer,			\
+    lrecord_type_##c_name, basic_p }
+
+#define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \
+DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
+
+#define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
+MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
+
+#define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
+DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype)
+
+#define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \
+MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
+
+#define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
+DECLARE_ERROR_CHECK_TYPES(c_name, structtype)			\
+int lrecord_type_##c_name;						\
+struct lrecord_implementation lrecord_##c_name =			\
+  { name, dumpable, marker, printer, nuker, equal, hash, desc,		\
+    getprop, putprop, remprop, plist, size, sizer,			\
+    lrecord_type_last_built_in_type, basic_p }
+
+#else /* not USE_KKCC */
+
 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
 
 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
-MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype)
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype)
 
 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
 
 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
-MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
 
 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype)
 
 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
-MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype)
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype)
 
 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \
-MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
+MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
 
-#define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
+#define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
 DECLARE_ERROR_CHECK_TYPES(c_name, structtype)			\
 const struct lrecord_implementation lrecord_##c_name =			\
-  { name, marker, printer, nuker, equal, hash, desc,			\
+  { name, dumpable, marker, printer, nuker, equal, hash, desc,		\
     getprop, putprop, remprop, plist, size, sizer,			\
     lrecord_type_##c_name, basic_p }
 
@@ -667,22 +739,22 @@
 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
 
 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
-MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
+MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
 
 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype)
 
 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \
-MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
+MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
 
-#define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
+#define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
 DECLARE_ERROR_CHECK_TYPES(c_name, structtype)			\
 int lrecord_type_##c_name;						\
 struct lrecord_implementation lrecord_##c_name =			\
-  { name, marker, printer, nuker, equal, hash, desc,			\
+  { name, dumpable, marker, printer, nuker, equal, hash, desc,		\
     getprop, putprop, remprop, plist, size, sizer,			\
     lrecord_type_last_built_in_type, basic_p }
-
+#endif /* not USE_KKCC */
 
 extern Lisp_Object (*lrecord_markers[]) (Lisp_Object);
 
--- a/src/lstream.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/lstream.c	Mon Jul 29 09:21:25 2002 +0000
@@ -114,10 +114,18 @@
   return aligned_sizeof_lstream (((const Lstream *) header)->imp->size);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
+					0, /*dumpable-flag*/
+					mark_lstream, print_lstream,
+					finalize_lstream, 0, 0, 0,
+					sizeof_lstream, Lstream);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
 					mark_lstream, print_lstream,
 					finalize_lstream, 0, 0, 0,
 					sizeof_lstream, Lstream);
+#endif /* not USE_KKCC */
 
 
 /* Change the buffering of a stream.  See lstream.h.  By default the
--- a/src/marker.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/marker.c	Mon Jul 29 09:21:25 2002 +0000
@@ -103,10 +103,18 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION ("marker", marker,
+				     1, /*dumpable-flag*/
+				     mark_marker, print_marker, 0,
+				     marker_equal, marker_hash, marker_description,
+				     Lisp_Marker);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("marker", marker,
 				     mark_marker, print_marker, 0,
 				     marker_equal, marker_hash, marker_description,
 				     Lisp_Marker);
+#endif /* not USE_KKCC */
 
 /* Operations on markers. */
 
--- a/src/menubar-x.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/menubar-x.c	Mon Jul 29 09:21:25 2002 +0000
@@ -672,12 +672,21 @@
     {
       Position shellx, shelly, framex, framey;
       Arg al [2];
+#ifdef USE_KKCC
+      btn->time = EVENT_TIMESTAMP (eev);
+      btn->button = XBUTTON_DATA_BUTTON (EVENT_DATA (eev));
+      btn->root = RootWindowOfScreen (XtScreen (daddy));
+      btn->subwindow = (Window) NULL;
+      btn->x = XBUTTON_DATA_X (EVENT_DATA (eev));
+      btn->y = XBUTTON_DATA_Y (EVENT_DATA (eev));
+#else /* not USE_KKCC */
       btn->time = eev->timestamp;
       btn->button = eev->event.button.button;
       btn->root = RootWindowOfScreen (XtScreen (daddy));
       btn->subwindow = (Window) NULL;
       btn->x = eev->event.button.x;
       btn->y = eev->event.button.y;
+#endif /* not USE_KKCC */
       shellx = shelly = 0;
 #ifndef HAVE_WMCOMMAND
       {
--- a/src/mule-charset.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/mule-charset.c	Mon Jul 29 09:21:25 2002 +0000
@@ -196,10 +196,16 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
+			       1, /* dumpable flag */
+                               mark_charset, print_charset, finalize_charset,
+			       0, 0, charset_description, Lisp_Charset);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("charset", charset,
                                mark_charset, print_charset, finalize_charset,
 			       0, 0, charset_description, Lisp_Charset);
-
+#endif /* not USE_KKCC */
 /* Make a new charset. */
 /* #### SJT Should generic properties be allowed? */
 static Lisp_Object
--- a/src/objects-impl.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/objects-impl.h	Mon Jul 29 09:21:25 2002 +0000
@@ -103,6 +103,10 @@
   Lisp_Object name;
   Lisp_Object device;
 
+#ifdef USE_KKCC
+  enum console_variant color_instance_type;
+#endif /* USE_KKCC */
+
   /* console-type-specific data */
   void *data;
 };
@@ -125,6 +129,10 @@
 			   check this and enforce it as a general policy) */
   Lisp_Object device;
 
+#ifdef USE_KKCC
+  enum console_variant font_instance_type;
+#endif /* USE_KKCC */
+
   unsigned short ascent;	/* extracted from `font', or made up */
   unsigned short descent;
   unsigned short width;
--- a/src/objects.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/objects.c	Mon Jul 29 09:21:25 2002 +0000
@@ -35,6 +35,10 @@
 #include "specifier.h"
 #include "window.h"
 
+#ifdef USE_KKCC
+#include "objects-tty-impl.h"
+#endif /* USE_KKCC */
+
 /* Objects that are substituted when an instantiation fails.
    If we leave in the Qunbound value, we will probably get crashes. */
 Lisp_Object Vthe_null_color_instance, Vthe_null_font_instance;
@@ -58,6 +62,36 @@
 
 Lisp_Object Qcolor_instancep;
 
+#ifdef USE_KKCC
+static const struct lrecord_description empty_color_instance_data_description [] = {
+  { XD_END }
+};
+
+static const struct lrecord_description tty_color_instance_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct tty_color_instance_data, symbol) },
+  { XD_END }
+};
+
+static const struct struct_description color_instance_data_description []= {
+  { dead_console, empty_color_instance_data_description},
+  { tty_console, tty_color_instance_data_description},
+  { gtk_console, empty_color_instance_data_description},
+  { x_console, empty_color_instance_data_description},
+  { mswindows_console, empty_color_instance_data_description},
+  { stream_console, empty_color_instance_data_description},
+  { XD_END }
+};
+
+static const struct lrecord_description color_instance_description[] = {
+  { XD_INT, offsetof (Lisp_Color_Instance, color_instance_type) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Color_Instance, name)},
+  { XD_LISP_OBJECT, offsetof (Lisp_Color_Instance, device)},
+  { XD_UNION, offsetof (Lisp_Color_Instance, data), 
+    XD_INDIRECT (0, 0), color_instance_data_description },
+  {XD_END}
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_color_instance (Lisp_Object obj)
 {
@@ -122,11 +156,21 @@
 				    LISP_HASH (obj)));
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("color-instance", color_instance,
+			       0, /*dumpable-flag*/
+			       mark_color_instance, print_color_instance,
+			       finalize_color_instance, color_instance_equal,
+			       color_instance_hash, 
+			       color_instance_description,
+			       Lisp_Color_Instance);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("color-instance", color_instance,
 			       mark_color_instance, print_color_instance,
 			       finalize_color_instance, color_instance_equal,
 			       color_instance_hash, 0,
 			       Lisp_Color_Instance);
+#endif /* not USE_KKCC */
 
 DEFUN ("make-color-instance", Fmake_color_instance, 1, 3, 0, /*
 Return a new `color-instance' object named NAME (a string).
@@ -157,6 +201,9 @@
   c->name = name;
   c->device = device;
   c->data = 0;
+#ifdef USE_KKCC
+  c->color_instance_type = get_console_variant(XDEVICE_TYPE(c->device));
+#endif /* USE_KKCC */
 
   retval = MAYBE_INT_DEVMETH (XDEVICE (device), initialize_color_instance,
 			      (c, name, device,
@@ -231,6 +278,37 @@
 
 static Lisp_Object font_instance_truename_internal (Lisp_Object xfont,
 						    Error_Behavior errb);
+#ifdef USE_KKCC
+static const struct lrecord_description empty_font_instance_data_description [] = {
+  { XD_END }
+};
+
+static const struct lrecord_description tty_font_instance_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct tty_font_instance_data, charset) },
+  { XD_END }
+};
+
+static const struct struct_description font_instance_data_description []= {
+  { dead_console, empty_font_instance_data_description},
+  { tty_console, tty_font_instance_data_description},
+  { gtk_console, empty_font_instance_data_description},
+  { x_console, empty_font_instance_data_description},
+  { mswindows_console, empty_font_instance_data_description},
+  { stream_console, empty_font_instance_data_description},
+  { XD_END }
+};
+
+static const struct lrecord_description font_instance_description[] = {
+  { XD_INT, offsetof (Lisp_Font_Instance, font_instance_type) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, name)},
+  { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, truename)},
+  { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, device)},
+  { XD_UNION, offsetof (Lisp_Font_Instance, data), 
+    XD_INDIRECT (0, 0), font_instance_data_description },
+  {XD_END}
+};
+#endif /* USE_KKCC */
+
 
 static Lisp_Object
 mark_font_instance (Lisp_Object obj)
@@ -294,10 +372,19 @@
 			depth + 1);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("font-instance", font_instance,
+			       0, /*dumpable-flag*/
+			       mark_font_instance, print_font_instance,
+			       finalize_font_instance, font_instance_equal,
+			       font_instance_hash, font_instance_description, Lisp_Font_Instance);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("font-instance", font_instance,
 			       mark_font_instance, print_font_instance,
 			       finalize_font_instance, font_instance_equal,
 			       font_instance_hash, 0, Lisp_Font_Instance);
+#endif /* not USE_KKCC */
+
 
 DEFUN ("make-font-instance", Fmake_font_instance, 1, 3, 0, /*
 Return a new `font-instance' object named NAME.
@@ -330,6 +417,9 @@
   f->device = device;
 
   f->data = 0;
+#ifdef USE_KKCC
+  f->font_instance_type = get_console_variant(XDEVICE_TYPE(f->device));
+#endif /* USE_KKCC */
 
   /* Stick some default values here ... */
   f->ascent = f->height = 1;
--- a/src/opaque.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/opaque.c	Mon Jul 29 09:21:25 2002 +0000
@@ -112,11 +112,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("opaque", opaque,
+					1, /*dumpable-flag*/
+					0, print_opaque, 0,
+					equal_opaque, hash_opaque,
+					opaque_description,
+					sizeof_opaque, Lisp_Opaque);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("opaque", opaque,
 					0, print_opaque, 0,
 					equal_opaque, hash_opaque,
 					opaque_description,
 					sizeof_opaque, Lisp_Opaque);
+#endif /* not USE_KKCC */
 
 /* stuff to handle opaque pointers */
 
@@ -144,10 +153,18 @@
   return (unsigned long) XOPAQUE_PTR (obj)->ptr;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("opaque-ptr", opaque_ptr,
+			       0, /*dumpable-flag*/
+			       0, print_opaque_ptr, 0,
+			       equal_opaque_ptr, hash_opaque_ptr, 0,
+			       Lisp_Opaque_Ptr);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("opaque-ptr", opaque_ptr,
 			       0, print_opaque_ptr, 0,
 			       equal_opaque_ptr, hash_opaque_ptr, 0,
 			       Lisp_Opaque_Ptr);
+#endif /* not USE_KKCC */
 
 Lisp_Object
 make_opaque_ptr (void *val)
--- a/src/postgresql.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/postgresql.c	Mon Jul 29 09:21:25 2002 +0000
@@ -178,6 +178,12 @@
   return wrap_pgconn (pgconn);
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description pgconn_description [] = {
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 #ifdef RUNNING_XEMACS_21_1
 mark_pgconn (Lisp_Object obj, void (*markobj) (Lisp_Object))
@@ -261,11 +267,19 @@
 			       NULL, NULL,
 			       Lisp_PGconn);
 #else
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("pgconn", pgconn,
+			       mark_pgconn, print_pgconn, finalize_pgconn,
+			       NULL, NULL,
+			       pgconn_description,
+			       Lisp_PGconn);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("pgconn", pgconn,
 			       mark_pgconn, print_pgconn, finalize_pgconn,
 			       NULL, NULL,
 			       0,
 			       Lisp_PGconn);
+#endif /* not USE_KKCC */
 #endif
 /****/
 
@@ -280,6 +294,13 @@
   return wrap_pgresult (pgresult);
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description pgresult_description [] = {
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
+
 static Lisp_Object
 #ifdef RUNNING_XEMACS_21_1
 mark_pgresult (Lisp_Object obj, void (*markobj) (Lisp_Object))
@@ -378,11 +399,19 @@
 			       NULL, NULL,
 			       Lisp_PGresult);
 #else
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("pgresult", pgresult,
+			       mark_pgresult, print_pgresult, finalize_pgresult,
+			       NULL, NULL,
+			       pgresult_description,
+			       Lisp_PGresult);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("pgresult", pgresult,
 			       mark_pgresult, print_pgresult, finalize_pgresult,
 			       NULL, NULL,
 			       0,
 			       Lisp_PGresult);
+#endif /* not USE_KKCC */
 #endif
 
 /***********************/
--- a/src/process.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/process.c	Mon Jul 29 09:21:25 2002 +0000
@@ -138,6 +138,47 @@
 
 
 
+#ifdef USE_KKCC
+static const struct lrecord_description empty_process_data_description [] = {
+  { XD_END }
+};
+
+static const struct lrecord_description unix_process_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct unix_process_data, tty_name) },
+  { XD_END }
+};
+
+static const struct struct_description process_data_description []= {
+  { unix_process, unix_process_data_description},
+  { nt_process, empty_process_data_description},
+  { XD_END }
+};
+
+static const struct lrecord_description process_description [] = {
+  { XD_INT, offsetof (Lisp_Process, process_type) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, name) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, command) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, filter) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, stderr_filter) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, sentinel) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, buffer) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, mark) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, stderr_buffer) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, stderr_mark) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, pid) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, pipe_instream) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, pipe_outstream) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, pipe_errstream) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, coding_instream) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, coding_outstream) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, coding_errstream) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Process, status_symbol) },
+  { XD_UNION, offsetof (Lisp_Process, process_data), 
+    XD_INDIRECT (0, 0), process_data_description },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_process (Lisp_Object object)
 {
@@ -214,9 +255,16 @@
     }
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("process", process,
+			       0, /*dumpable-flag*/
+                               mark_process, print_process, finalize_process,
+                               0, 0, process_description, Lisp_Process);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("process", process,
                                mark_process, print_process, finalize_process,
                                0, 0, 0, Lisp_Process);
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*                       basic process accessors                        */
@@ -532,6 +580,14 @@
   p->process_data = 0;
   MAYBE_PROCMETH (alloc_process_data, (p));
 
+#ifdef USE_KKCC
+#ifdef HAVE_MS_WINDOWS
+  p->process_type = nt_process;
+#else /*HAVE_MS_WINDOWS*/
+  p->process_type = unix_process;
+#endif /*HAVE_MS_WINDOWS*/
+#endif /* USE_KKCC */
+
   val = wrap_process (p);
 
   Vprocess_list = Fcons (val, Vprocess_list);
--- a/src/process.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/process.h	Mon Jul 29 09:21:25 2002 +0000
@@ -39,6 +39,15 @@
 /* struct Lisp_Process is defined in procimpl.h; only process-*.c need
    to know about the guts of it. */
 
+#ifdef USE_KKCC
+enum process_variant
+{
+  unix_process,
+  nt_process
+};
+
+#endif /* USE_KKCC */
+
 DECLARE_LRECORD (process, Lisp_Process);
 #define XPROCESS(x) XRECORD (x, process, Lisp_Process)
 #define wrap_process(p) wrap_record (p, process)
--- a/src/procimpl.h	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/procimpl.h	Mon Jul 29 09:21:25 2002 +0000
@@ -149,6 +149,10 @@
   Lisp_Object coding_outstream;
   Lisp_Object coding_errstream;
 
+#ifdef USE_KKCC
+  enum process_variant process_type;
+#endif /* USE_KKCC */
+
   /* Implementation dependent data */
   void *process_data;
 };
@@ -186,4 +190,24 @@
 		   const Ibyte *nonrelocatable,
 		   int start, int len);
 
+#ifdef USE_KKCC
+struct unix_process_data
+{
+  /* Non-0 if this is really a ToolTalk channel. */
+  int connected_via_filedesc_p;
+  /* Descriptor by which we read from this process.  -1 for dead process */
+  int infd;
+  /* Descriptor by which we read stderr from this process.  -1 for
+     dead process */
+  int errfd;
+  /* Descriptor for the tty which this process is using.
+     -1 if we didn't record it (on some systems, there's no need).  */
+  int subtty;
+  /* Name of subprocess terminal. */
+  Lisp_Object tty_name;
+  /* Non-false if communicating through a pty.  */
+  char pty_flag;
+};
+#endif /* USE_KKCC */
+
 #endif /* INCLUDED_procimpl_h_ */
--- a/src/rangetab.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/rangetab.c	Mon Jul 29 09:21:25 2002 +0000
@@ -156,11 +156,20 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("range-table", range_table,
+			       1, /*dumpable-flag*/
+                               mark_range_table, print_range_table, 0,
+			       range_table_equal, range_table_hash,
+			       range_table_description,
+			       Lisp_Range_Table);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("range-table", range_table,
                                mark_range_table, print_range_table, 0,
 			       range_table_equal, range_table_hash,
 			       range_table_description,
 			       Lisp_Range_Table);
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*                        Range table operations                        */
--- a/src/scrollbar.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/scrollbar.c	Mon Jul 29 09:21:25 2002 +0000
@@ -77,6 +77,14 @@
 static void update_scrollbar_instance (struct window *w, int vertical,
 				       struct scrollbar_instance *instance);
 
+#ifdef USE_KKCC
+static const struct lrecord_description scrollbar_instance_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct scrollbar_instance, mirror) },
+  { XD_LISP_OBJECT, offsetof (struct scrollbar_instance, next) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 
 static Lisp_Object
 mark_scrollbar_instance (Lisp_Object obj)
@@ -89,10 +97,19 @@
     return Qnil;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("scrollbar-instance", scrollbar_instance,
+			       0, /*dumpable-flag*/
+			       mark_scrollbar_instance,
+			       internal_object_printer, 0, 0, 0, 
+			       scrollbar_instance_description,
+			       struct scrollbar_instance);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("scrollbar-instance", scrollbar_instance,
 			       mark_scrollbar_instance,
 			       internal_object_printer, 0, 0, 0, 0,
 			       struct scrollbar_instance);
+#endif /* not USE_KKCC */
 
 static void
 free_scrollbar_instance (struct scrollbar_instance *instance,
--- a/src/specifier.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/specifier.c	Mon Jul 29 09:21:25 2002 +0000
@@ -407,6 +407,16 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier,
+					1, /*dumpable-flag*/
+					mark_specifier, print_specifier,
+					finalize_specifier,
+					specifier_equal, specifier_hash,
+					specifier_description,
+					sizeof_specifier,
+					Lisp_Specifier);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier,
 					mark_specifier, print_specifier,
 					finalize_specifier,
@@ -414,6 +424,7 @@
 					specifier_description,
 					sizeof_specifier,
 					Lisp_Specifier);
+#endif /* not USE_KKCC */
 
 /************************************************************************/
 /*                       Creating specifiers                            */
--- a/src/symbols.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/symbols.c	Mon Jul 29 09:21:25 2002 +0000
@@ -136,6 +136,17 @@
   return external_remprop (&XSYMBOL (symbol)->plist, property, 0, ERROR_ME);
 }
 
+#ifdef USE_KKCC
+DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("symbol", symbol,
+						1, /*dumpable-flag*/
+						mark_symbol, print_symbol,
+						0, 0, 0, symbol_description,
+						symbol_getprop,
+						symbol_putprop,
+						symbol_remprop,
+						Fsymbol_plist,
+						Lisp_Symbol);
+#else /* not USE_KKCC */
 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("symbol", symbol,
 						mark_symbol, print_symbol,
 						0, 0, 0, symbol_description,
@@ -144,7 +155,7 @@
 						symbol_remprop,
 						Fsymbol_plist,
 						Lisp_Symbol);
-
+#endif /* not USE_KKCC */
 
 /**********************************************************************/
 /*                              Intern				      */
@@ -1007,6 +1018,41 @@
   { XD_END }
 };
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-forward",
+			       symbol_value_forward,
+			       1, /*dumpable-flag*/
+			       0,
+			       print_symbol_value_magic, 0, 0, 0,
+			       symbol_value_forward_description,
+			       struct symbol_value_forward);
+
+DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-buffer-local",
+			       symbol_value_buffer_local,
+			       1, /*dumpable-flag*/
+			       mark_symbol_value_buffer_local,
+			       print_symbol_value_magic, 0, 0, 0,
+			       symbol_value_buffer_local_description,
+			       struct symbol_value_buffer_local);
+
+DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-lisp-magic",
+			       symbol_value_lisp_magic,
+			       1, /*dumpable-flag*/
+			       mark_symbol_value_lisp_magic,
+			       print_symbol_value_magic, 0, 0, 0,
+			       symbol_value_lisp_magic_description,
+			       struct symbol_value_lisp_magic);
+
+DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-varalias",
+			       symbol_value_varalias,
+			       1, /*dumpable-flag*/
+			       mark_symbol_value_varalias,
+			       print_symbol_value_magic, 0, 0, 0,
+			       symbol_value_varalias_description,
+			       struct symbol_value_varalias);
+
+#else /* not USE_KKCC */
+
 DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-forward",
 			       symbol_value_forward,
 			       0,
@@ -1034,7 +1080,7 @@
 			       print_symbol_value_magic, 0, 0, 0,
 			       symbol_value_varalias_description,
 			       struct symbol_value_varalias);
-
+#endif /* not USE_KKCC */
 
 /* Getting and setting values of symbols */
 
@@ -3373,7 +3419,6 @@
 	assert (subr->max_args <= SUBR_MAX_ARGS);
 	assert (subr->min_args <= subr->max_args);
       }
-
     assert (UNBOUNDP (XSYMBOL (sym)->function));
   }
 }
--- a/src/toolbar.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/toolbar.c	Mon Jul 29 09:21:25 2002 +0000
@@ -56,6 +56,22 @@
 
 Lisp_Object Qinit_toolbar_from_resources;
 
+#ifdef USE_KKCC
+static const struct lrecord_description toolbar_button_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, next) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, frame) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, up_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, down_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, disabled_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_up_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_down_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_disabled_glyph) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, callback) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, enabled_p) },
+  { XD_LISP_OBJECT, offsetof (struct toolbar_button, help_string) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
 
 static Lisp_Object
 mark_toolbar_button (Lisp_Object obj)
@@ -74,9 +90,17 @@
   return data->help_string;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button,
+			       0, /*dumpable-flag*/
+			       mark_toolbar_button, 0, 0, 0, 0, 
+			       toolbar_button_description,
+			       struct toolbar_button);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button,
 			       mark_toolbar_button, 0, 0, 0, 0, 0,
 			       struct toolbar_button);
+#endif /* not USE_KKCC */
 
 DEFUN ("toolbar-button-p", Ftoolbar_button_p, 1, 1, 0, /*
 Return non-nil if OBJECT is a toolbar button.
--- a/src/tooltalk.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/tooltalk.c	Mon Jul 29 09:21:25 2002 +0000
@@ -152,6 +152,14 @@
   Tt_message m;
 };
 
+#ifdef USE_KKCC
+static const struct lrecord_description tooltalk_message_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Message, callback) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Message, plist_sym) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_tooltalk_message (Lisp_Object obj)
 {
@@ -173,10 +181,18 @@
 		    (long) (p->m), p->header.uid);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("tooltalk-message", tooltalk_message,
+                               mark_tooltalk_message, print_tooltalk_message,
+                               0, 0, 0, 
+			       tooltalk_message_description,
+			       Lisp_Tooltalk_Message);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("tooltalk-message", tooltalk_message,
                                mark_tooltalk_message, print_tooltalk_message,
                                0, 0, 0, 0,
 			       Lisp_Tooltalk_Message);
+#endif /* not USE_KKCC */
 
 static Lisp_Object
 make_tooltalk_message (Tt_message m)
@@ -222,6 +238,14 @@
   Tt_pattern p;
 };
 
+#ifdef USE_KKCC
+static const struct lrecord_description tooltalk_pattern_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Pattern, callback) },
+  { XD_LISP_OBJECT, offsetof (struct Lisp_Tooltalk_Pattern, plist_sym) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_tooltalk_pattern (Lisp_Object obj)
 {
@@ -243,10 +267,18 @@
 		    (long) (p->p), p->header.uid);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("tooltalk-pattern", tooltalk_pattern,
+                               mark_tooltalk_pattern, print_tooltalk_pattern,
+                               0, 0, 0, 
+			       tooltalk_pattern_description,
+			       Lisp_Tooltalk_Pattern);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("tooltalk-pattern", tooltalk_pattern,
                                mark_tooltalk_pattern, print_tooltalk_pattern,
                                0, 0, 0, 0,
 			       Lisp_Tooltalk_Pattern);
+#endif /* not USE_KKCC */
 
 static Lisp_Object
 make_tooltalk_pattern (Tt_pattern p)
--- a/src/ui-gtk.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/ui-gtk.c	Mon Jul 29 09:21:25 2002 +0000
@@ -298,6 +298,13 @@
   return (data);
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description ffi_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct emacs_ffi_data, function_name) }, 
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_ffi_data (Lisp_Object obj)
 {
@@ -319,9 +326,16 @@
   write_fmt_string (printcharfun, " %p>", (void *)XFFI (obj)->function_ptr);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("ffi", emacs_ffi,
+			       mark_ffi_data, ffi_object_printer,
+			       0, 0, 0, 
+			       ffi_data_description, emacs_ffi_data);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("ffi", emacs_ffi,
 			       mark_ffi_data, ffi_object_printer,
 			       0, 0, 0, NULL, emacs_ffi_data);
+#endif /* not USE_KKCC */
 
 typedef GtkObject * (*__OBJECT_fn) ();
 typedef gint (*__INT_fn) ();
@@ -885,6 +899,13 @@
   return (1);
 }
 
+#ifdef USE_KKCC
+static const struct lrecord_description gtk_object_data_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct emacs_gtk_object_data, plist) }, 
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_gtk_object_data (Lisp_Object obj)
 {
@@ -911,6 +932,20 @@
     }
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("GtkObject", emacs_gtk_object,
+					  mark_gtk_object_data, /* marker function */
+					  emacs_gtk_object_printer, /* print function */
+					  emacs_gtk_object_finalizer, /* finalizer */
+					  0, /* equality */
+					  0, /* hash */
+					  gtk_object_data_description, /* desc */
+					  object_getprop, /* get prop */
+					  object_putprop, /* put prop */
+					  0, /* rem prop */
+					  0, /* plist */
+					  emacs_gtk_object_data);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("GtkObject", emacs_gtk_object,
 					  mark_gtk_object_data, /* marker function */
 					  emacs_gtk_object_printer, /* print function */
@@ -923,6 +958,7 @@
 					  0, /* rem prop */
 					  0, /* plist */
 					  emacs_gtk_object_data);
+#endif /* not USE_KKCC */
 
 static emacs_gtk_object_data *
 allocate_emacs_gtk_object_data (void)
--- a/src/window.c	Sat Jul 27 03:53:09 2002 +0000
+++ b/src/window.c	Mon Jul 29 09:21:25 2002 +0000
@@ -231,10 +231,16 @@
   return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, HASH_TABLE_EQ);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("window", window,
+			       0, /*dumpable-flag*/
+                               mark_window, print_window, finalize_window,
+			       0, 0, 0, struct window);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("window", window,
                                mark_window, print_window, finalize_window,
 			       0, 0, 0, struct window);
-
+#endif /* not USE_KKCC */
 
 #define INIT_DISP_VARIABLE(field, initialization)	\
   p->field[CURRENT_DISP] = initialization;		\
@@ -336,6 +342,12 @@
    because neither structure is created very often (only when windows are
    created or deleted). --ben */
 
+#ifdef USE_KKCC
+static const struct lrecord_description window_mirror_description [] = {
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_window_mirror (Lisp_Object obj)
 {
@@ -368,9 +380,16 @@
     return Qnil;
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_IMPLEMENTATION ("window-mirror", window_mirror,
+			       0, /*dumpable-flag*/
+                               mark_window_mirror, internal_object_printer,
+			       0, 0, 0, 0/*window_mirror_description*/, struct window_mirror);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_IMPLEMENTATION ("window-mirror", window_mirror,
                                mark_window_mirror, internal_object_printer,
 			       0, 0, 0, 0, struct window_mirror);
+#endif /* not USE_KKCC */
 
 /* Create a new window mirror structure and associated redisplay
    structs. */
@@ -5192,6 +5211,19 @@
 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration)
 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration)
 
+#ifdef USE_KKCC
+static const struct struct_description saved_window_description = {
+};
+
+static const struct lrecord_description window_config_description [] = {
+  { XD_LISP_OBJECT, offsetof (struct window_config, current_window) },
+  { XD_LISP_OBJECT, offsetof (struct window_config, current_buffer) },
+  { XD_LISP_OBJECT, offsetof (struct window_config, minibuffer_scroll_window) },
+  { XD_LISP_OBJECT, offsetof (struct window_config, root_window) },
+  { XD_END }
+};
+#endif /* USE_KKCC */
+
 static Lisp_Object
 mark_window_config (Lisp_Object obj)
 {
@@ -5251,13 +5283,23 @@
   write_fmt_string (printcharfun, "0x%x>", config->header.uid);
 }
 
+#ifdef USE_KKCC
+DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
+					window_configuration,
+					0, /*dumpable-flag*/
+					mark_window_config,
+					print_window_config,
+					0, 0, 0, 
+					0/*window_config_description*/, sizeof_window_config,
+					struct window_config);
+#else /* not USE_KKCC */
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
 					window_configuration,
 					mark_window_config,
 					print_window_config,
 					0, 0, 0, 0, sizeof_window_config,
 					struct window_config);
-
+#endif /* not USE_KKCC */
 
 /* Returns a boolean indicating whether the two saved windows are
    identical. */