--- ../orig/xemacs-21.2/lisp/select.el	Fri Jul 14 15:57:36 2000
+++ xemacs-21.2/lisp/select.el	Fri Jul 14 15:51:09 2000
@@ -408,6 +408,10 @@
 	     (buffer-substring (car value) (cdr value)))))
 	(t nil)))
 
+(defun select-convert-from-text (selection type value)
+  (when (stringp value)
+    value))
+
 (defun select-convert-to-string (selection type value)
   (let ((outval (select-convert-to-text selection type value)))
     ;; force the string to be not in Compound Text format.
@@ -438,6 +442,9 @@
 	(cons (ash value -16) (logand value 65535))
       nil)))
 
+(defun select-convert-from-length (selection type value)
+  (select-convert-to-length selection type value))
+
 (defun select-convert-to-targets (selection type value)
   ;; return a vector of atoms, but remove duplicates first.
   (let* ((all (cons 'TIMESTAMP (mapcar 'car selection-converter-alist)))
@@ -469,6 +476,11 @@
 			       (error "selection is in a killed buffer"))))
 	(t nil)))
 
+(defun select-convert-from-filename (selection type value)
+  (cond ((stringp value)
+	 value)
+	(t (select-convert-to-filename selection type value))))
+
 (defun select-convert-to-charpos (selection type value)
   (let (a b tmp)
     (cond ((cond ((extentp value)
@@ -586,12 +598,68 @@
   (and (integerp value)
        (cons (ash value -16) (logand value 65535))))
 
+;; Can convert from the following integer representations
+;;
+;;    integer
+;;    (integer . integer)
+;;    (integer integer)
+;;    (list [integer|(integer . integer)]*)
+;;    (vector [integer|(integer . integer)]*)
+;;
+;; Cons'd integers get cleaned up a little.
+
+(defun select-convert-from-integer (selection type value)
+  (cond ((integerp value)		; Integer
+	 value)
+	
+	((and (consp value)		; (integer . integer)
+	      (integerp (car value))
+	      (integerp (cdr value)))
+	 (if (eq (car value) 0)
+	     (cdr value)
+	   (if (and (eq (car value) -1)
+		    (< (cdr value) 0))
+	       (cdr value)
+	     value)))
+	
+	((and (listp value)		; (integer integer)
+	      (eq (length value) 2)
+	      (integerp (car value))
+	      (integerp (cadr value)))
+	 (if (eq (car value) 0)
+	     (cadr value)
+	   (if (and (eq (car value) -1)
+		    (< (cdr value) 0))
+	       (- (cadr value))
+	     (cons (car value) (cadr value)))))
+	
+	((listp value)			; list
+	 (if (cdr value)
+	     (mapcar '(lambda (x)
+			(select-convert-from-integer selection type x))
+		     value)
+	   (select-convert-from-integer selection type (car value))))
+	
+	((vectorp value)		; vector
+	 (if (eq (length value) 1)
+	     (select-convert-from-integer selection type (aref value 0))
+	   (mapvector '(lambda (x)
+			(select-convert-from-integer selection type x))
+		     value)))
+	
+	(t nil)
+	))
+
 (defun select-convert-to-atom (selection type value)
   (and (symbolp value) value))
 
+;; #### What are these for?
 (defun select-convert-to-identity (selection type value) ; used internally
   (vector value))
 
+(defun select-convert-from-identity (selection type value) ; used internally
+  (vector value))
+
 ;;; CF_xxx conversions
 (defun select-convert-from-cf-text (selection type value)
   (replace-in-string (if (string-match "\0" value)
@@ -630,8 +698,7 @@
 ;; appending numbers to strings, etc...
   (cond ((and (stringp value1) (stringp value2))
 	 (select-append-to-string selection 'STRING value1 value2))
-	(t
-	 nil)))
+	(t nil)))
 
 ;; Types listed in here can be selections of XEmacs
 (setq selection-converter-out-alist
@@ -659,7 +726,22 @@
 
 ;; Types listed here can be selections foreign to XEmacs
 (setq selection-converter-in-alist
-      '((CF_TEXT . select-convert-from-cf-text)
+      '(; Specific types that get handled by generic converters
+	(COMPOUND_TEXT . select-convert-from-text)
+	(SOURCE_LOC . select-convert-from-text)
+	(OWNER_OS . select-convert-from-text)
+	(HOST_NAME . select-convert-from-text)
+	(USER . select-convert-from-text)
+	(CLASS . select-convert-from-text)
+	(NAME . select-convert-from-text)
+	; Generic types
+	(INTEGER . select-convert-from-integer)
+	(TEXT . select-convert-from-text)
+	(STRING . select-convert-from-text)
+	(LENGTH . select-convert-from-length)
+	(FILE_NAME . select-convert-from-filename)
+	(_EMACS_INTERNAL . select-convert-from-identity)
+	(CF_TEXT . select-convert-from-cf-text)
 	))
 
 ;; Types listed here can be appended by own-selection
--- ../orig/xemacs-21.2/src/select.c	Fri Jul 14 16:03:45 2000
+++ xemacs-21.2/src/select.c	Fri Jul 14 15:00:12 2000
@@ -78,6 +78,8 @@
  */
 Lisp_Object Vselection_alist;
 
+#if 0 /* This function is obsolete and should have been in select-x.c
+	 (though it really belongs in the Lisp in select.el) - ajh */
 static Lisp_Object
 clean_local_selection_data (Lisp_Object obj)
 {
@@ -112,11 +114,13 @@
     }
   return obj;
 }
+#endif
 
 /* Given a selection-name and desired type, this looks up our local copy of
    the selection value and converts it to the type. */
 Lisp_Object
-get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type)
+get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
+		     int output)
 {
   /* This function can GC */
   Lisp_Object local_value = assq_no_quit (selection_symbol, Vselection_alist);
@@ -129,12 +133,13 @@
       /* First try to find an entry of the appropriate type */
       value = assq_no_quit (target_type, value_list);
       if (!NILP (value))
-	return value;
-      
-      /* We couldn't. Try for a generic type instead. */
-      value = assq_no_quit (target_type, Qnil);
-  
-      return convert_selection (selection_symbol, value, target_type, 0);    
+	return convert_selection (selection_symbol, XCDR (value),
+				  target_type, output);
+
+      /* Don't look for a generic type here; only go for generic type if
+	 the target_type was specified as Qnil - otherwise we could get
+	 *wierd* results. */
+      return Qnil;
     }
 
   return Qnil;
@@ -250,6 +255,141 @@
 #endif
 }
 
+DEFUN ("select-internal-int-bin", Fselect_internal_int_bin, 1, 2, 0, /*
+Return a string containing a binary representation of the specified
+integer. The integer may either be a Lisp integer, in which case a
+size should be specified, or a cons 16-bit integers of the form (HI . LO).
+*/
+       (value, bytes))
+{
+  Lisp_Object ret;
+  void        *vdata;
+  int         vlen;
+
+  unsigned char c;
+  unsigned short s;
+  unsigned long l;
+  
+  if (!(INTP (value)
+	|| (CONSP (value)
+	    && INTP (XCAR (value))
+	    && INTP (XCDR (value)))
+	))
+    error ("value must be an integer or a cons of two integers.");
+
+  /* #### Bad assumptions about sizes of char, short & long - ajh */
+  switch (XINT (bytes))
+    {
+    case 1:
+      {
+	if (INTP (value))
+	  c = (unsigned char) XINT (value);
+	else if (CONSP (value))
+	  c = (unsigned char) XINT (XCDR (value));
+
+	vdata = &c;
+	vlen = 1;
+
+	break;
+      }
+
+    case 2:
+      {
+	if (INTP (value))
+	  s = (unsigned short) XINT (value);
+	else if (CONSP (value))
+	  s = (unsigned short) XINT (XCDR (value));
+
+	vdata = &s;
+	vlen = 2;
+
+	break;
+      }
+
+    case 4:
+      {
+	if (INTP (value))
+	  l = (unsigned long) XINT (value);
+	else if (CONSP (value))
+	  l = ((unsigned long) (XINT (XCAR (value)) << 16)
+	       | (XINT (XCDR (value)) & 65535));
+
+	vdata = &l;
+	vlen = 4;
+
+	break;
+      }
+
+    default:
+      error ("bytes must be 1, 2 or 4.");
+
+      return Qnil;
+    }
+
+  TO_INTERNAL_FORMAT (DATA, (vdata, vlen),
+		      LISP_STRING, ret,
+		      Qbinary);
+
+  return ret;
+}
+       
+DEFUN ("select-internal-bin-int", Fselect_internal_bin_int, 2, 2, 0, /*
+Retrieve a binary integer from the given string. If the string is
+of length 2, return an integer. If length is 4, return a cons pair of
+two 16-bit values in the form (HI . LO).
+*/
+       (string, bytes))
+{
+  void *vdata;
+  int   vlen;
+  
+  CHECK_STRING (string);
+  CHECK_INT (bytes);
+
+  TO_EXTERNAL_FORMAT (LISP_STRING, string,
+		      ALLOCA, (vdata, vlen),
+		      Qbinary);
+
+  if (XINT (bytes) > vlen)
+    error ("string is not long enough.");
+
+  if (!vdata)
+    error ("yikes - something very very bad just happened.");
+  
+  /* #### Bad assumptions about sizes of char, short and long - ajh */
+  switch (XINT (bytes))
+    {
+    case 1:
+      {
+	unsigned char *data = (unsigned char *) vdata;
+	
+	return make_int (*data);
+      }
+      
+    case 2:
+      {
+	unsigned short *data = (unsigned short *) vdata;
+      
+	return make_int (*data);
+      }
+      break;
+
+    case 4:
+      {
+	/* #### This type is wrong (assumes long == 32 bits). select-x does
+	        this as well, and this could break e.g. on DEC Alpha.
+		Something needs doing about this - ajh */
+	unsigned long *data = (unsigned long *) vdata;
+
+	return word_to_lisp (*data);
+      }
+    }
+
+  error ("bytes should be 1, 2 or 4.");
+  
+  return Qnil;
+}
+       
 DEFUN ("own-selection-internal", Fown_selection_internal, 2, 5, 0, /*
 Assert a selection of the given NAME with the given VALUE, and
 optional window-system DATA-TYPE. HOW-TO-ADD specifies how the
@@ -475,9 +615,9 @@
       if (STRINGP (value) && (NILP (type) || EQ (type, QSTRING)
 			      || EQ (type, QTEXT) || EQ (type, QCOMPOUND_TEXT)))
 	types = Fcons (QTEXT, Fcons (QCOMPOUND_TEXT, Fcons (QSTRING, types)));
-      else if (INTP (value) && (NILP (type) || EQ (type, QINTEGER)))
+      else if (INTP (value) && NILP (type))
 	types = Fcons (QINTEGER, types);
-      else if (SYMBOLP (value) && (NILP (type) || EQ (type, QATOM)))
+      else if (SYMBOLP (value) && NILP (type))
 	types = Fcons (QATOM, types);
     }
   
@@ -622,23 +762,18 @@
      the device (in which case target_type would be a device-specific
      identifier - probably an integer) - ajh */
 
-  val = get_local_selection (selection_symbol, target_type);
+  val = get_local_selection (selection_symbol, target_type, 0);
 
   if (NILP (val) && (HAS_DEVMETH_P (XDEVICE (device), get_foreign_selection)))
     {
       val = DEVMETH (XDEVICE (device), get_foreign_selection,
 		     (selection_symbol, target_type));
     }
-  else
-    {
-      if (CONSP (val) && SYMBOLP (XCAR (val)))
-	{
-	  val = XCDR (val);
-	  if (CONSP (val) && NILP (XCDR (val)))
-	    val = XCAR (val);
-	}
-      val = clean_local_selection_data (val);
-    }
+
+  /* Used to call clean_local_selection here... but that really belonged
+     in Lisp (so the equivalent is now built-in to the INTEGER conversion
+     function select-convert-from-integer) - ajh */
+  
   UNGCPRO;
   return val;
 }
@@ -654,6 +789,8 @@
   DEFSUBR (Favailable_selection_types);
   DEFSUBR (Fregister_selection_data_type);
   DEFSUBR (Fselection_data_type_name);
+  DEFSUBR (Fselect_internal_bin_int);
+  DEFSUBR (Fselect_internal_int_bin);
   
   /* X Atoms */
   defsymbol (&QPRIMARY, "PRIMARY");
--- ../orig/xemacs-21.2/src/select-x.c	Fri Jul 14 16:03:43 2000
+++ xemacs-21.2/src/select-x.c	Fri Jul 14 10:51:07 2000
@@ -376,10 +376,8 @@
       {
 	Display *dpy = XtDisplay (widget);
 	Window window = (Window) *private_id;
-	Lisp_Object selection = assq_no_quit (QCLIPBOARD, Vselection_alist);
+	Lisp_Object selection = get_local_selection (QCLIPBOARD, Qnil, 1);
 	if (NILP (selection)) abort ();
-	/* #### This should probably be using get_local_selection - ajh */
-	selection = assq_no_quit (Qnil, XCDR (selection));
 	if (!STRINGP (selection)) abort ();
 	XmClipboardCopyByName (dpy, window, *data_id,
 			       (char *) XSTRING_DATA (selection),
@@ -607,7 +605,7 @@
   /* Convert lisp objects back into binary data */
 
   converted_selection =
-    get_local_selection (selection_symbol, target_symbol);
+    get_local_selection (selection_symbol, target_symbol, 1);
 
   if (! NILP (converted_selection))
     {
--- ../orig/xemacs-21.2/src/select-msw.c	Fri Jul 14 16:03:40 2000
+++ xemacs-21.2/src/select-msw.c	Fri Jul 14 13:03:40 2000
@@ -33,6 +33,7 @@
 #include "select.h"
 #include "opaque.h"
 #include "file-coding.h"
+#include "buffer.h"
 
 #include "console-msw.h"
 
@@ -484,8 +485,9 @@
     }
 
   /* Place it in a Lisp string */
-  ret = make_uninit_string (size);
-  memcpy (XSTRING_DATA (ret), data, size);
+  TO_INTERNAL_FORMAT (DATA, (data, size),
+		      LISP_STRING, ret,
+		      Qbinary);
 
   GlobalUnlock (data);
   CloseClipboard ();
--- ../orig/xemacs-21.2/src/select.h	Fri Jul 14 16:04:00 2000
+++ xemacs-21.2/src/select.h	Fri Jul 14 10:46:25 2000
@@ -56,11 +56,12 @@
 extern Lisp_Object Qselection_conversion_error;
 
 Lisp_Object get_local_selection (Lisp_Object selection_symbol,
-				 Lisp_Object target_type);
+				 Lisp_Object target_type,
+				 int	     output);
 Lisp_Object convert_selection (Lisp_Object selection_symbol,
 			       Lisp_Object selection_value,
 			       Lisp_Object target_type,
-			       int output);
+			       int	   output);
 void handle_selection_clear (Lisp_Object selection_symbol);
 
 #endif /* INCLUDED_select_h_ */
