]> code.delx.au - gnu-emacs/blobdiff - src/xselect.c
frame-override-unsplittable/inhibit-frame-unsplittable name change.
[gnu-emacs] / src / xselect.c
index ead207aedf3af20104ad1380b4e8a15ab30e98ad..20a977b8fa59178cbb19dd9ace6dfe598e7fcea6 100644 (file)
@@ -1,5 +1,5 @@
 /* X Selection processing for Emacs.
 /* X Selection processing for Emacs.
-   Copyright (C) 1993, 1994, 1995 Free Software Foundation.
+   Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -27,8 +27,8 @@ Boston, MA 02111-1307, USA.  */
 #include "dispextern.h"        /* frame.h seems to want this */
 #include "frame.h"     /* Need this to get the X window of selected_frame */
 #include "blockinput.h"
 #include "dispextern.h"        /* frame.h seems to want this */
 #include "frame.h"     /* Need this to get the X window of selected_frame */
 #include "blockinput.h"
-
-#define xfree free
+#include "charset.h"
+#include "coding.h"
 
 #define CUT_BUFFER_SUPPORT
 
 
 #define CUT_BUFFER_SUPPORT
 
@@ -36,6 +36,8 @@ Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
   QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
   QATOM_PAIR;
 
   QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
   QATOM_PAIR;
 
+Lisp_Object QCOMPOUND_TEXT;    /* This is a type of selection.  */
+
 #ifdef CUT_BUFFER_SUPPORT
 Lisp_Object QCUT_BUFFER0, QCUT_BUFFER1, QCUT_BUFFER2, QCUT_BUFFER3,
   QCUT_BUFFER4, QCUT_BUFFER5, QCUT_BUFFER6, QCUT_BUFFER7;
 #ifdef CUT_BUFFER_SUPPORT
 Lisp_Object QCUT_BUFFER0, QCUT_BUFFER1, QCUT_BUFFER2, QCUT_BUFFER3,
   QCUT_BUFFER4, QCUT_BUFFER5, QCUT_BUFFER6, QCUT_BUFFER7;
@@ -59,7 +61,8 @@ static Lisp_Object Vx_sent_selection_hooks;
 #endif
 
 /* The timestamp of the last input event Emacs received from the X server.  */
 #endif
 
 /* The timestamp of the last input event Emacs received from the X server.  */
-unsigned long last_event_timestamp;
+/* Defined in keyboard.c.  */
+extern unsigned long last_event_timestamp;
 
 /* This is an association list whose elements are of the form
      ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
 
 /* This is an association list whose elements are of the form
      ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME)
@@ -111,6 +114,7 @@ symbol_to_x_atom (dpyinfo, display, sym)
   if (EQ (sym, QCLIPBOARD)) return dpyinfo->Xatom_CLIPBOARD;
   if (EQ (sym, QTIMESTAMP)) return dpyinfo->Xatom_TIMESTAMP;
   if (EQ (sym, QTEXT))     return dpyinfo->Xatom_TEXT;
   if (EQ (sym, QCLIPBOARD)) return dpyinfo->Xatom_CLIPBOARD;
   if (EQ (sym, QTIMESTAMP)) return dpyinfo->Xatom_TIMESTAMP;
   if (EQ (sym, QTEXT))     return dpyinfo->Xatom_TEXT;
+  if (EQ (sym, QCOMPOUND_TEXT)) return dpyinfo->Xatom_COMPOUND_TEXT;
   if (EQ (sym, QDELETE))    return dpyinfo->Xatom_DELETE;
   if (EQ (sym, QMULTIPLE))  return dpyinfo->Xatom_MULTIPLE;
   if (EQ (sym, QINCR))     return dpyinfo->Xatom_INCR;
   if (EQ (sym, QDELETE))    return dpyinfo->Xatom_DELETE;
   if (EQ (sym, QMULTIPLE))  return dpyinfo->Xatom_MULTIPLE;
   if (EQ (sym, QINCR))     return dpyinfo->Xatom_INCR;
@@ -189,6 +193,8 @@ x_atom_to_symbol (dpyinfo, display, atom)
     return QTIMESTAMP;
   if (atom == dpyinfo->Xatom_TEXT)
     return QTEXT;
     return QTIMESTAMP;
   if (atom == dpyinfo->Xatom_TEXT)
     return QTEXT;
+  if (atom == dpyinfo->Xatom_COMPOUND_TEXT)
+    return QCOMPOUND_TEXT;
   if (atom == dpyinfo->Xatom_DELETE)
     return QDELETE;
   if (atom == dpyinfo->Xatom_MULTIPLE)
   if (atom == dpyinfo->Xatom_DELETE)
     return QDELETE;
   if (atom == dpyinfo->Xatom_MULTIPLE)
@@ -230,15 +236,16 @@ x_own_selection (selection_name, selection_value)
   Time time = last_event_timestamp;
   Atom selection_atom;
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
   Time time = last_event_timestamp;
   Atom selection_atom;
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (selected_frame);
+  int count;
 
   CHECK_SYMBOL (selection_name, 0);
   selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
 
   BLOCK_INPUT;
 
   CHECK_SYMBOL (selection_name, 0);
   selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
 
   BLOCK_INPUT;
-  x_catch_errors (display);
+  count = x_catch_errors (display);
   XSetSelectionOwner (display, selection_atom, selecting_window, time);
   x_check_errors (display, "Can't set selection: %s");
   XSetSelectionOwner (display, selection_atom, selecting_window, time);
   x_check_errors (display, "Can't set selection: %s");
-  x_uncatch_errors (display);
+  x_uncatch_errors (display, count);
   UNBLOCK_INPUT;
 
   /* Now update the local cache */
   UNBLOCK_INPUT;
 
   /* Now update the local cache */
@@ -505,6 +512,7 @@ x_reply_selection_request (event, format, data, size, type)
   int format_bytes = format/8;
   int max_bytes = SELECTION_QUANTUM (display);
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
   int format_bytes = format/8;
   int max_bytes = SELECTION_QUANTUM (display);
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
+  int count;
 
   if (max_bytes > MAX_SELECTION_QUANTUM)
     max_bytes = MAX_SELECTION_QUANTUM;
 
   if (max_bytes > MAX_SELECTION_QUANTUM)
     max_bytes = MAX_SELECTION_QUANTUM;
@@ -521,7 +529,7 @@ x_reply_selection_request (event, format, data, size, type)
 
   /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
   BLOCK_INPUT;
 
   /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
   BLOCK_INPUT;
-  x_catch_errors (display);
+  count = x_catch_errors (display);
 
   /* Store the data on the requested property.
      If the selection is large, only store the first N bytes of it.
 
   /* Store the data on the requested property.
      If the selection is large, only store the first N bytes of it.
@@ -543,7 +551,6 @@ x_reply_selection_request (event, format, data, size, type)
       /* Send an INCR selection.  */
       struct prop_location *wait_object;
       int had_errors;
       /* Send an INCR selection.  */
       struct prop_location *wait_object;
       int had_errors;
-      int count = specpdl_ptr - specpdl;
       Lisp_Object frame;
 
       frame = some_frame_on_display (dpyinfo);
       Lisp_Object frame;
 
       frame = some_frame_on_display (dpyinfo);
@@ -625,12 +632,10 @@ x_reply_selection_request (event, format, data, size, type)
 
       XChangeProperty (display, window, reply.property, type, format,
                       PropModeReplace, data, 0);
 
       XChangeProperty (display, window, reply.property, type, format,
                       PropModeReplace, data, 0);
-
-      unbind_to (count, Qnil);
     }
 
   XFlush (display);
     }
 
   XFlush (display);
-  x_uncatch_errors (display);
+  x_uncatch_errors (display, count);
   UNBLOCK_INPUT;
 }
 \f
   UNBLOCK_INPUT;
 }
 \f
@@ -721,10 +726,10 @@ x_handle_selection_request (event)
       /* Indicate we have successfully processed this event.  */
       x_selection_current_request = 0;
 
       /* Indicate we have successfully processed this event.  */
       x_selection_current_request = 0;
 
-      /* Use xfree, not XFree, because lisp_data_to_selection_data
+      /* Use free, not XFree, because lisp_data_to_selection_data
         calls xmalloc itself.  */
       if (!nofree)
         calls xmalloc itself.  */
       if (!nofree)
-       xfree (data);
+       free (data);
     }
   unbind_to (count, Qnil);
 
     }
   unbind_to (count, Qnil);
 
@@ -836,7 +841,11 @@ x_clear_frame_selections (f)
        {
          for (; CONSP (hooks); hooks = Fcdr (hooks))
            call1 (Fcar (hooks), selection_symbol);
        {
          for (; CONSP (hooks); hooks = Fcdr (hooks))
            call1 (Fcar (hooks), selection_symbol);
+#if 0 /* This can crash when deleting a frame
+        from x_connection_closed.  Anyway, it seems unnecessary;
+        something else should cause a redisplay.  */
          redisplay_preserve_echo_area ();
          redisplay_preserve_echo_area ();
+#endif
        }
 
       Vselection_alist = Fcdr (Vselection_alist);
        }
 
       Vselection_alist = Fcdr (Vselection_alist);
@@ -856,7 +865,9 @@ x_clear_frame_selections (f)
          {
            for (; CONSP (hooks); hooks = Fcdr (hooks))
              call1 (Fcar (hooks), selection_symbol);
          {
            for (; CONSP (hooks); hooks = Fcdr (hooks))
              call1 (Fcar (hooks), selection_symbol);
+#if 0 /* See above */
            redisplay_preserve_echo_area ();
            redisplay_preserve_echo_area ();
+#endif
          }
        XCONS (rest)->cdr = Fcdr (XCONS (rest)->cdr);
        break;
          }
        XCONS (rest)->cdr = Fcdr (XCONS (rest)->cdr);
        break;
@@ -889,7 +900,7 @@ static struct prop_location *
 expect_property_change (display, window, property, state)
      Display *display;
      Window window;
 expect_property_change (display, window, property, state)
      Display *display;
      Window window;
-     Lisp_Object property;
+     Atom property;
      int state;
 {
   struct prop_location *pl
      int state;
 {
   struct prop_location *pl
@@ -921,7 +932,7 @@ unexpect_property_change (location)
            prev->next = rest->next;
          else
            property_change_wait_list = rest->next;
            prev->next = rest->next;
          else
            property_change_wait_list = rest->next;
-         xfree (rest);
+         free (rest);
          return;
        }
       prev = rest;
          return;
        }
       prev = rest;
@@ -1010,7 +1021,7 @@ x_handle_property_notify (event)
            prev->next = rest->next;
          else
            property_change_wait_list = rest->next;
            prev->next = rest->next;
          else
            property_change_wait_list = rest->next;
-         xfree (rest);
+         free (rest);
          return;
        }
       prev = rest;
          return;
        }
       prev = rest;
@@ -1097,7 +1108,7 @@ x_get_foreign_selection (selection_symbol, target_type)
   Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
   Atom type_atom;
   int secs, usecs;
   Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
   Atom type_atom;
   int secs, usecs;
-  int count = specpdl_ptr - specpdl;
+  int count;
   Lisp_Object frame;
 
   if (CONSP (target_type))
   Lisp_Object frame;
 
   if (CONSP (target_type))
@@ -1106,7 +1117,7 @@ x_get_foreign_selection (selection_symbol, target_type)
     type_atom = symbol_to_x_atom (dpyinfo, display, target_type);
 
   BLOCK_INPUT;
     type_atom = symbol_to_x_atom (dpyinfo, display, target_type);
 
   BLOCK_INPUT;
-  x_catch_errors (display);
+  count = x_catch_errors (display);
   XConvertSelection (display, selection_atom, type_atom, target_property,
                     requestor_window, requestor_time);
   XFlush (display);
   XConvertSelection (display, selection_atom, type_atom, target_property,
                     requestor_window, requestor_time);
   XFlush (display);
@@ -1137,8 +1148,7 @@ x_get_foreign_selection (selection_symbol, target_type)
 
   BLOCK_INPUT;
   x_check_errors (display, "Cannot get selection: %s");
 
   BLOCK_INPUT;
   x_check_errors (display, "Cannot get selection: %s");
-  x_uncatch_errors (display);
-  unbind_to (count, Qnil);
+  x_uncatch_errors (display, count);
   UNBLOCK_INPUT;
 
   if (NILP (XCONS (reading_selection_reply)->car))
   UNBLOCK_INPUT;
 
   if (NILP (XCONS (reading_selection_reply)->car))
@@ -1155,7 +1165,7 @@ x_get_foreign_selection (selection_symbol, target_type)
 \f
 /* Subroutines of x_get_window_property_as_lisp_data */
 
 \f
 /* Subroutines of x_get_window_property_as_lisp_data */
 
-/* Use xfree, not XFree, to free the data obtained with this function.  */
+/* Use free, not XFree, to free the data obtained with this function.  */
 
 static void
 x_get_window_property (display, window, property, data_ret, bytes_ret,
 
 static void
 x_get_window_property (display, window, property, data_ret, bytes_ret,
@@ -1238,7 +1248,7 @@ x_get_window_property (display, window, property, data_ret, bytes_ret,
   *bytes_ret = offset;
 }
 \f
   *bytes_ret = offset;
 }
 \f
-/* Use xfree, not XFree, to free the data obtained with this function.  */
+/* Use free, not XFree, to free the data obtained with this function.  */
 
 static void
 receive_incremental_selection (display, window, property, target_type,
 
 static void
 receive_incremental_selection (display, window, property, target_type,
@@ -1300,9 +1310,9 @@ receive_incremental_selection (display, window, property, target_type,
          if (! waiting_for_other_props_on_window (display, window))
            XSelectInput (display, window, STANDARD_EVENT_SET);
          unexpect_property_change (wait_object);
          if (! waiting_for_other_props_on_window (display, window))
            XSelectInput (display, window, STANDARD_EVENT_SET);
          unexpect_property_change (wait_object);
-         /* Use xfree, not XFree, because x_get_window_property
+         /* Use free, not XFree, because x_get_window_property
             calls xmalloc itself.  */
             calls xmalloc itself.  */
-         if (tmp_data) xfree (tmp_data);
+         if (tmp_data) free (tmp_data);
          break;
        }
 
          break;
        }
 
@@ -1327,9 +1337,9 @@ receive_incremental_selection (display, window, property, target_type,
        }
       bcopy (tmp_data, (*data_ret) + offset, tmp_size_bytes);
       offset += tmp_size_bytes;
        }
       bcopy (tmp_data, (*data_ret) + offset, tmp_size_bytes);
       offset += tmp_size_bytes;
-      /* Use xfree, not XFree, because x_get_window_property
+      /* Use free, not XFree, because x_get_window_property
         calls xmalloc itself.  */
         calls xmalloc itself.  */
-      xfree (tmp_data);
+      free (tmp_data);
     }
 }
 \f
     }
 }
 \f
@@ -1363,20 +1373,19 @@ x_get_window_property_as_lisp_data (display, window, property, target_type,
       there_is_a_selection_owner
        = XGetSelectionOwner (display, selection_atom);
       UNBLOCK_INPUT;
       there_is_a_selection_owner
        = XGetSelectionOwner (display, selection_atom);
       UNBLOCK_INPUT;
-      while (1) /* Note debugger can no longer return, so this is obsolete */
-       Fsignal (Qerror,
-                there_is_a_selection_owner ?
-                Fcons (build_string ("selection owner couldn't convert"),
+      Fsignal (Qerror,
+              there_is_a_selection_owner
+              ? Fcons (build_string ("selection owner couldn't convert"),
                        actual_type
                        ? Fcons (target_type,
                                 Fcons (x_atom_to_symbol (dpyinfo, display,
                                                          actual_type),
                                        Qnil))
                        : Fcons (target_type, Qnil))
                        actual_type
                        ? Fcons (target_type,
                                 Fcons (x_atom_to_symbol (dpyinfo, display,
                                                          actual_type),
                                        Qnil))
                        : Fcons (target_type, Qnil))
-                : Fcons (build_string ("no selection"),
-                         Fcons (x_atom_to_symbol (dpyinfo, display,
-                                                  selection_atom),
-                                Qnil)));
+              : Fcons (build_string ("no selection"),
+                       Fcons (x_atom_to_symbol (dpyinfo, display,
+                                                selection_atom),
+                              Qnil)));
     }
   
   if (actual_type == dpyinfo->Xatom_INCR)
     }
   
   if (actual_type == dpyinfo->Xatom_INCR)
@@ -1385,9 +1394,9 @@ x_get_window_property_as_lisp_data (display, window, property, target_type,
 
       unsigned int min_size_bytes = * ((unsigned int *) data);
       BLOCK_INPUT;
 
       unsigned int min_size_bytes = * ((unsigned int *) data);
       BLOCK_INPUT;
-      /* Use xfree, not XFree, because x_get_window_property
+      /* Use free, not XFree, because x_get_window_property
         calls xmalloc itself.  */
         calls xmalloc itself.  */
-      xfree ((char *) data);
+      free ((char *) data);
       UNBLOCK_INPUT;
       receive_incremental_selection (display, window, property, target_type,
                                     min_size_bytes, &data, &bytes,
       UNBLOCK_INPUT;
       receive_incremental_selection (display, window, property, target_type,
                                     min_size_bytes, &data, &bytes,
@@ -1405,9 +1414,9 @@ x_get_window_property_as_lisp_data (display, window, property, target_type,
   val = selection_data_to_lisp_data (display, data, bytes,
                                     actual_type, actual_format);
   
   val = selection_data_to_lisp_data (display, data, bytes,
                                     actual_type, actual_format);
   
-  /* Use xfree, not XFree, because x_get_window_property
+  /* Use free, not XFree, because x_get_window_property
      calls xmalloc itself.  */
      calls xmalloc itself.  */
-  xfree ((char *) data);
+  free ((char *) data);
   return val;
 }
 \f
   return val;
 }
 \f
@@ -1452,8 +1461,48 @@ selection_data_to_lisp_data (display, data, size, type, format)
 
   /* Convert any 8-bit data to a string, for compactness.  */
   else if (format == 8)
 
   /* Convert any 8-bit data to a string, for compactness.  */
   else if (format == 8)
-    return make_string ((char *) data, size);
-
+    {
+      Lisp_Object str;
+      int require_encoding = 0;
+
+      /* If TYPE is `TEXT' or `COMPOUND_TEXT', we should decode DATA
+        to Emacs internal format because DATA may be encoded in
+        compound text format.  In addtion, if TYPE is `STRING' and
+        DATA contains any 8-bit Latin-1 code, we should also decode
+        it.  */
+      if (type == dpyinfo->Xatom_TEXT || type == dpyinfo->Xatom_COMPOUND_TEXT)
+       require_encoding = 1;
+      else if (type == XA_STRING)
+       {
+         int i;
+         for (i = 0; i < size; i++)
+           {
+             if (data[i] >= 0x80)
+               {
+                 require_encoding = 1;
+                 break;
+               }
+           }
+       }
+      if (!require_encoding)
+       str = make_string ((char *) data, size);
+      else
+       {
+         int bufsize, dummy;
+         unsigned char *buf;
+         struct coding_system coding;
+         Lisp_Object sym = intern ("iso-8859-1");
+
+         setup_coding_system (Fcheck_coding_system (sym), &coding);
+         coding.last_block = 1;
+         bufsize = decoding_buffer_size (&coding, size);
+         buf = (unsigned char *) xmalloc (bufsize);
+         size = decode_coding (&coding, data, buf, size, bufsize, &dummy);
+         str = make_string ((char *) buf, size);
+         xfree (buf);
+       }
+      return str;
+    }
   /* Convert a single atom to a Lisp_Symbol.  Convert a set of atoms to
      a vector of symbols.
    */
   /* Convert a single atom to a Lisp_Symbol.  Convert a set of atoms to
      a vector of symbols.
    */
@@ -1509,7 +1558,7 @@ selection_data_to_lisp_data (display, data, size, type, format)
 }
 
 
 }
 
 
-/* Use xfree, not XFree, to free the data obtained with this function.  */
+/* Use free, not XFree, to free the data obtained with this function.  */
 
 static void
 lisp_data_to_selection_data (display, obj,
 
 static void
 lisp_data_to_selection_data (display, obj,
@@ -1545,11 +1594,55 @@ lisp_data_to_selection_data (display, obj,
     }
   else if (STRINGP (obj))
     {
     }
   else if (STRINGP (obj))
     {
+      /* Since we are now handling multilingual text, we must consider
+        sending back compound text.  */
+      int charsets[MAX_CHARSET + 1];
+      int num;
+
       *format_ret = 8;
       *size_ret = XSTRING (obj)->size;
       *data_ret = XSTRING (obj)->data;
       *format_ret = 8;
       *size_ret = XSTRING (obj)->size;
       *data_ret = XSTRING (obj)->data;
-      *nofree_ret = 1;
-      if (NILP (type)) type = QSTRING;
+      bzero (charsets, (MAX_CHARSET + 1) * sizeof (int));
+      num = ((*size_ret <= 1)  /* Check the possibility of short cut.  */
+            ? 0
+            : find_charset_in_str (*data_ret, *size_ret, charsets, Qnil));
+
+      if (!num || (num == 1 && charsets[CHARSET_ASCII]))
+       {
+         /* No multibyte character in OBJ.  We need not encode it.  */
+         *nofree_ret = 1;
+         if (NILP (type)) type = QSTRING;
+       }
+      else
+       {
+         /* We must encode contents of OBJ to compound text format.
+             The format is compatible with what the target `STRING'
+             expects if OBJ contains only ASCII and Latin-1
+             characters.  */
+         int bufsize, dummy;
+         unsigned char *buf;
+         struct coding_system coding;
+         Lisp_Object sym = intern ("iso-8859-1");
+
+         setup_coding_system (Fcheck_coding_system (sym), &coding);
+         coding.last_block = 1;
+         bufsize = encoding_buffer_size (&coding, *size_ret);
+         buf = (unsigned char *) xmalloc (bufsize);
+         *size_ret = encode_coding (&coding, *data_ret, buf,
+                                    *size_ret, bufsize, &dummy);
+         *data_ret = buf;
+         if (charsets[charset_latin_iso8859_1]
+             && (num == 1 || (num == 2 && charsets[CHARSET_ASCII])))
+           {
+             /* Ok, we can return it as `STRING'.  */
+             if (NILP (type)) type = QSTRING;
+           }
+         else
+           {
+             /* We must return it as `COMPOUND_TEXT'.  */
+             if (NILP (type)) type = QCOMPOUND_TEXT;
+           }
+       }
     }
   else if (SYMBOLP (obj))
     {
     }
   else if (SYMBOLP (obj))
     {
@@ -1731,9 +1824,8 @@ x_handle_selection_notify (event)
 }
 
 \f
 }
 
 \f
-DEFUN ("x-own-selection-internal",
-       Fx_own_selection_internal, Sx_own_selection_internal,
-  2, 2, 0,
+DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
+  Sx_own_selection_internal, 2, 2, 0,
   "Assert an X selection of the given TYPE with the given VALUE.\n\
 TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
   "Assert an X selection of the given TYPE with the given VALUE.\n\
 TYPE is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
@@ -1754,8 +1846,8 @@ anything that the functions on `selection-converter-alist' know about.")
    simply return our selection value.  If we are not the owner, this
    will block until all of the data has arrived.  */
 
    simply return our selection value.  If we are not the owner, this
    will block until all of the data has arrived.  */
 
-DEFUN ("x-get-selection-internal",
-  Fx_get_selection_internal, Sx_get_selection_internal, 2, 2, 0,
+DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
+  Sx_get_selection_internal, 2, 2, 0,
   "Return text selected from some X window.\n\
 SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
   "Return text selected from some X window.\n\
 SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.\n\
 \(Those are literal upper-case symbol names, since that's what X expects.)\n\
@@ -1802,8 +1894,8 @@ TYPE is the type of data desired, typically `STRING'.")
   return val;
 }
 
   return val;
 }
 
-DEFUN ("x-disown-selection-internal",
-  Fx_disown_selection_internal, Sx_disown_selection_internal, 1, 2, 0,
+DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
+  Sx_disown_selection_internal, 1, 2, 0,
   "If we own the selection SELECTION, disown it.\n\
 Disowning it means there is no such selection.")
   (selection, time)
   "If we own the selection SELECTION, disown it.\n\
 Disowning it means there is no such selection.")
   (selection, time)
@@ -1996,9 +2088,9 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
                           Fcons (make_number (format), Qnil))));
 
   ret = (bytes ? make_string ((char *) data, bytes) : Qnil);
                           Fcons (make_number (format), Qnil))));
 
   ret = (bytes ? make_string ((char *) data, bytes) : Qnil);
-  /* Use xfree, not XFree, because x_get_window_property
+  /* Use free, not XFree, because x_get_window_property
      calls xmalloc itself.  */
      calls xmalloc itself.  */
-  xfree (data);
+  free (data);
   return ret;
 }
 
   return ret;
 }
 
@@ -2181,6 +2273,7 @@ A value of 0 means wait as long as necessary.  This is initialized from the\n\
   QCLIPBOARD = intern ("CLIPBOARD");   staticpro (&QCLIPBOARD);
   QTIMESTAMP = intern ("TIMESTAMP");   staticpro (&QTIMESTAMP);
   QTEXT      = intern ("TEXT");        staticpro (&QTEXT);
   QCLIPBOARD = intern ("CLIPBOARD");   staticpro (&QCLIPBOARD);
   QTIMESTAMP = intern ("TIMESTAMP");   staticpro (&QTIMESTAMP);
   QTEXT      = intern ("TEXT");        staticpro (&QTEXT);
+  QCOMPOUND_TEXT = intern ("COMPOUND_TEXT"); staticpro (&QCOMPOUND_TEXT);
   QTIMESTAMP = intern ("TIMESTAMP");   staticpro (&QTIMESTAMP);
   QDELETE    = intern ("DELETE");      staticpro (&QDELETE);
   QMULTIPLE  = intern ("MULTIPLE");    staticpro (&QMULTIPLE);
   QTIMESTAMP = intern ("TIMESTAMP");   staticpro (&QTIMESTAMP);
   QDELETE    = intern ("DELETE");      staticpro (&QDELETE);
   QMULTIPLE  = intern ("MULTIPLE");    staticpro (&QMULTIPLE);