diff src/select-common.h @ 647:b39c14581166

[xemacs-hg @ 2001-08-13 04:45:47 by ben] removal of unsigned, size_t, etc.
author ben
date Mon, 13 Aug 2001 04:46:48 +0000
parents
children fdefd0186b75
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/select-common.h	Mon Aug 13 04:46:48 2001 +0000
@@ -0,0 +1,339 @@
+/* Selection processing for XEmacs -- common btwn select-x.c and select-gtk.c
+   Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: Not synched with FSF. */
+
+#ifdef PROCESSING_X_CODE
+#define XE_ATOM_TYPE Atom
+#define XE_ATOM_TO_SYMBOL x_atom_to_symbol
+#define XE_SYMBOL_TO_ATOM symbol_to_x_atom
+#else
+#define XE_ATOM_TYPE GdkAtom
+#define XE_ATOM_TO_SYMBOL atom_to_symbol
+#define XE_SYMBOL_TO_ATOM symbol_to_gtk_atom
+#endif /* PROCESSING_X_CODE */
+
+/* #### These are going to move into Lisp code(!) with the aid of
+        some new functions I'm working on - ajh */
+
+/* These functions convert from the selection data read from the server into
+   something that we can use from elisp, and vice versa.
+
+	Type:	Format:	Size:		Elisp Type:
+	-----	-------	-----		-----------
+	*	8	*		String
+	ATOM	32	1		Symbol
+	ATOM	32	> 1		Vector of Symbols
+	*	16	1		Integer
+	*	16	> 1		Vector of Integers
+	*	32	1		if <=16 bits: Integer
+					if > 16 bits: Cons of top16, bot16
+	*	32	> 1		Vector of the above
+
+   When converting a Lisp number to C, it is assumed to be of format 16 if
+   it is an integer, and of format 32 if it is a cons of two integers.
+
+   When converting a vector of numbers from Elisp to C, it is assumed to be
+   of format 16 if every element in the vector is an integer, and is assumed
+   to be of format 32 if any element is a cons of two integers.
+
+   When converting an object to C, it may be of the form (SYMBOL . <data>)
+   where SYMBOL is what we should claim that the type is.  Format and
+   representation are as above.
+
+   NOTE: Under Mule, when someone shoves us a string without a type, we
+   set the type to 'COMPOUND_TEXT and automatically convert to Compound
+   Text.  If the string has a type, we assume that the user wants the
+   data sent as-is so we just do "binary" conversion.
+ */
+
+
+static Lisp_Object
+selection_data_to_lisp_data (struct device *d,
+			     UChar_Binary *data,
+			     Memory_Count size,
+			     XE_ATOM_TYPE type,
+			     int format)
+{
+#ifdef PROCESSING_X_CODE
+  if (type == DEVICE_XATOM_NULL (d))
+    return QNULL;
+
+  /* Convert any 8-bit data to a string, for compactness. */
+  else if (format == 8)
+    return make_ext_string ((Extbyte *) data, size,
+			    type == DEVICE_XATOM_TEXT (d) ||
+			    type == DEVICE_XATOM_COMPOUND_TEXT (d)
+			    ? Qctext : Qbinary);
+
+  /* Convert a single atom to a Lisp Symbol.
+     Convert a set of atoms to a vector of symbols. */
+  else if (type == XA_ATOM)
+#else
+  if (type == gdk_atom_intern ("NULL", 0))
+    return QNULL;
+
+  /* Convert any 8-bit data to a string, for compactness. */
+  else if (format == 8)
+    return make_ext_string ((Extbyte *) data, size,
+			    ((type == gdk_atom_intern ("TEXT", FALSE)) ||
+			     (type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)))
+			    ? Qctext : Qbinary);
+
+  /* Convert a single atom to a Lisp Symbol.
+     Convert a set of atoms to a vector of symbols. */
+  else if (type == gdk_atom_intern ("ATOM", FALSE))
+#endif /* PROCESSING_X_CODE */
+    {
+      if (size == sizeof (XE_ATOM_TYPE))
+	return XE_ATOM_TO_SYMBOL (d, *((XE_ATOM_TYPE *) data));
+      else
+	{
+	  Element_Count i;
+	  Element_Count len = size / sizeof (XE_ATOM_TYPE);
+	  Lisp_Object v = Fmake_vector (make_int (len), Qzero);
+	  for (i = 0; i < len; i++)
+	    Faset (v, make_int (i), XE_ATOM_TO_SYMBOL (d, ((XE_ATOM_TYPE *) data) [i]));
+	  return v;
+	}
+    }
+
+  /* Convert a single 16 or small 32 bit number to a Lisp Int.
+     If the number is > 16 bits, convert it to a cons of integers,
+     16 bits in each half.
+   */
+  else if (format == 32 && size == sizeof (long))
+    return word_to_lisp (((unsigned long *) data) [0]);
+  else if (format == 16 && size == sizeof (short))
+    return make_int ((int) (((unsigned short *) data) [0]));
+
+  /* Convert any other kind of data to a vector of numbers, represented
+     as above (as an integer, or a cons of two 16 bit integers).
+
+     #### Perhaps we should return the actual type to lisp as well.
+
+	(x-get-selection-internal 'PRIMARY 'LINE_NUMBER)
+	==> [4 4]
+
+     and perhaps it should be
+
+	(x-get-selection-internal 'PRIMARY 'LINE_NUMBER)
+	==> (SPAN . [4 4])
+
+     Right now the fact that the return type was SPAN is discarded before
+     lisp code gets to see it.
+   */
+  else if (format == 16)
+    {
+      Element_Count i;
+      Lisp_Object v = make_vector (size / 4, Qzero);
+      for (i = 0; i < size / 4; i++)
+	{
+	  int j = (int) ((unsigned short *) data) [i];
+	  Faset (v, make_int (i), make_int (j));
+	}
+      return v;
+    }
+  else
+    {
+      Element_Count i;
+      Lisp_Object v = make_vector (size / 4, Qzero);
+      for (i = 0; i < size / 4; i++)
+	{
+	  unsigned long j = ((unsigned long *) data) [i];
+	  Faset (v, make_int (i), word_to_lisp (j));
+	}
+      return v;
+    }
+}
+
+
+static void
+lisp_data_to_selection_data (struct device *d,
+			     Lisp_Object obj,
+			     UChar_Binary **data_ret,
+			     XE_ATOM_TYPE *type_ret,
+			     Memory_Count *size_ret,
+			     int *format_ret)
+{
+  Lisp_Object type = Qnil;
+
+  if (CONSP (obj) && SYMBOLP (XCAR (obj)))
+    {
+      type = XCAR (obj);
+      obj = XCDR (obj);
+      if (CONSP (obj) && NILP (XCDR (obj)))
+	obj = XCAR (obj);
+    }
+
+  if (EQ (obj, QNULL) || (EQ (type, QNULL)))
+    {				/* This is not the same as declining */
+      *format_ret = 32;
+      *size_ret = 0;
+      *data_ret = 0;
+      type = QNULL;
+    }
+  else if (STRINGP (obj))
+    {
+      const Extbyte *extval;
+      Extcount extvallen;
+
+      TO_EXTERNAL_FORMAT (LISP_STRING, obj,
+			  ALLOCA, (extval, extvallen),
+			  (NILP (type) ? Qctext : Qbinary));
+      *format_ret = 8;
+      *size_ret = extvallen;
+      *data_ret = (UChar_Binary *) xmalloc (*size_ret);
+      memcpy (*data_ret, extval, *size_ret);
+#ifdef MULE
+      if (NILP (type)) type = QCOMPOUND_TEXT;
+#else
+      if (NILP (type)) type = QSTRING;
+#endif
+    }
+  else if (CHARP (obj))
+    {
+      Bufbyte buf[MAX_EMCHAR_LEN];
+      Bytecount len;
+      const Extbyte *extval;
+      Extcount extvallen;
+
+      *format_ret = 8;
+      len = set_charptr_emchar (buf, XCHAR (obj));
+      TO_EXTERNAL_FORMAT (DATA, (buf, len),
+			  ALLOCA, (extval, extvallen),
+			  Qctext);
+      *size_ret = extvallen;
+      *data_ret = (UChar_Binary *) xmalloc (*size_ret);
+      memcpy (*data_ret, extval, *size_ret);
+#ifdef MULE
+      if (NILP (type)) type = QCOMPOUND_TEXT;
+#else
+      if (NILP (type)) type = QSTRING;
+#endif
+    }
+  else if (SYMBOLP (obj))
+    {
+      *format_ret = 32;
+      *size_ret = 1;
+      *data_ret = (UChar_Binary *) xmalloc (sizeof (XE_ATOM_TYPE) + 1);
+      (*data_ret) [sizeof (XE_ATOM_TYPE)] = 0;
+      (*(XE_ATOM_TYPE **) data_ret) [0] = XE_SYMBOL_TO_ATOM (d, obj, 0);
+      if (NILP (type)) type = QATOM;
+    }
+  else if (INTP (obj) &&
+	   XINT (obj) <= 0x7FFF &&
+	   XINT (obj) >= -0x8000)
+    {
+      *format_ret = 16;
+      *size_ret = 1;
+      *data_ret = (UChar_Binary *) xmalloc (sizeof (short) + 1);
+      (*data_ret) [sizeof (short)] = 0;
+      (*(short **) data_ret) [0] = (short) XINT (obj);
+      if (NILP (type)) type = QINTEGER;
+    }
+  else if (INTP (obj) || CONSP (obj))
+    {
+      *format_ret = 32;
+      *size_ret = 1;
+      *data_ret = (UChar_Binary *) xmalloc (sizeof (long) + 1);
+      (*data_ret) [sizeof (long)] = 0;
+      (*(unsigned long **) data_ret) [0] = lisp_to_word (obj);
+      if (NILP (type)) type = QINTEGER;
+    }
+  else if (VECTORP (obj))
+    {
+      /* Lisp Vectors may represent a set of ATOMs;
+	 a set of 16 or 32 bit INTEGERs;
+	 or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...]
+       */
+      Element_Count i;
+
+      if (SYMBOLP (XVECTOR_DATA (obj) [0]))
+	/* This vector is an ATOM set */
+	{
+	  if (NILP (type)) type = QATOM;
+	  *size_ret = XVECTOR_LENGTH (obj);
+	  *format_ret = 32;
+	  *data_ret = (UChar_Binary *) xmalloc ((*size_ret) * sizeof (XE_ATOM_TYPE));
+	  for (i = 0; i < *size_ret; i++)
+	    if (SYMBOLP (XVECTOR_DATA (obj) [i]))
+	      (*(XE_ATOM_TYPE **) data_ret) [i] =
+		XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (obj) [i], 0);
+	    else
+              syntax_error
+		("all elements of the vector must be of the same type", obj);
+	}
+#if 0 /* #### MULTIPLE doesn't work yet */
+      else if (VECTORP (XVECTOR_DATA (obj) [0]))
+	/* This vector is an ATOM_PAIR set */
+	{
+	  if (NILP (type)) type = QATOM_PAIR;
+	  *size_ret = XVECTOR_LENGTH (obj);
+	  *format_ret = 32;
+	  *data_ret = (UChar_Binary *)
+	    xmalloc ((*size_ret) * sizeof (XE_ATOM_TYPE) * 2);
+	  for (i = 0; i < *size_ret; i++)
+	    if (VECTORP (XVECTOR_DATA (obj) [i]))
+	      {
+		Lisp_Object pair = XVECTOR_DATA (obj) [i];
+		if (XVECTOR_LENGTH (pair) != 2)
+		  syntax_error
+		    ("elements of the vector must be vectors of exactly two elements", pair);
+
+		(*(XE_ATOM_TYPE **) data_ret) [i * 2] =
+		  XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (pair) [0], 0);
+		(*(XE_ATOM_TYPE **) data_ret) [(i * 2) + 1] =
+		  XE_SYMBOL_TO_ATOM (d, XVECTOR_DATA (pair) [1], 0);
+	      }
+	    else
+	      syntax_error
+		("all elements of the vector must be of the same type", obj);
+	}
+#endif
+      else
+	/* This vector is an INTEGER set, or something like it */
+	{
+	  *size_ret = XVECTOR_LENGTH (obj);
+	  if (NILP (type)) type = QINTEGER;
+	  *format_ret = 16;
+	  for (i = 0; i < *size_ret; i++)
+	    if (CONSP (XVECTOR_DATA (obj) [i]))
+	      *format_ret = 32;
+	    else if (!INTP (XVECTOR_DATA (obj) [i]))
+	      syntax_error
+		("all elements of the vector must be integers or conses of integers", obj);
+
+	  *data_ret = (UChar_Binary *) xmalloc (*size_ret * (*format_ret/8));
+	  for (i = 0; i < *size_ret; i++)
+	    if (*format_ret == 32)
+	      (*((unsigned long **) data_ret)) [i] =
+		lisp_to_word (XVECTOR_DATA (obj) [i]);
+	    else
+	      (*((unsigned short **) data_ret)) [i] =
+		(unsigned short) lisp_to_word (XVECTOR_DATA (obj) [i]);
+	}
+    }
+  else
+    invalid_argument ("unrecognized selection data", obj);
+
+  *type_ret = XE_SYMBOL_TO_ATOM (d, type, 0);
+}
+