* termhooks.h (TSET): Remove.
[bpt/emacs.git] / src / xselect.c
index 77bda79..463bd6e 100644 (file)
@@ -1,5 +1,5 @@
 /* X Selection processing for Emacs.
-   Copyright (C) 1993-1997, 2000-2011 Free Software Foundation, Inc.
+   Copyright (C) 1993-1997, 2000-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -35,11 +35,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #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 "character.h"
 #include "buffer.h"
 #include "process.h"
 #include "termhooks.h"
 #include "keyboard.h"
-#include "character.h"
 
 #include <X11/Xproto.h>
 
@@ -81,13 +81,13 @@ static Lisp_Object clean_local_selection_data (Lisp_Object);
 
 #ifdef TRACE_SELECTION
 #define TRACE0(fmt) \
-  fprintf (stderr, "%d: " fmt "\n", getpid ())
+  fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid ())
 #define TRACE1(fmt, a0) \
-  fprintf (stderr, "%d: " fmt "\n", getpid (), a0)
+  fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0)
 #define TRACE2(fmt, a0, a1) \
-  fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1)
+  fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0, a1)
 #define TRACE3(fmt, a0, a1, a2) \
-  fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1, a2)
+  fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0, a1, a2)
 #else
 #define TRACE0(fmt)            (void) 0
 #define TRACE1(fmt, a0)                (void) 0
@@ -116,6 +116,7 @@ static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions;
 #define X_SHRT_MIN (-1 - X_SHRT_MAX)
 #define X_LONG_MAX 0x7fffffff
 #define X_LONG_MIN (-1 - X_LONG_MAX)
+#define X_ULONG_MAX 0xffffffffUL
 
 /* If this is a smaller number than the max-request-size of the display,
    emacs will use INCR selection transfer when the selection is larger
@@ -179,16 +180,11 @@ x_queue_event (struct input_event *event)
        }
     }
 
-  queue_tmp
-    = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue));
-
-  if (queue_tmp != NULL)
-    {
-      TRACE1 ("QUEUE SELECTION EVENT %p", queue_tmp);
-      queue_tmp->event = *event;
-      queue_tmp->next = selection_queue;
-      selection_queue = queue_tmp;
-    }
+  queue_tmp = xmalloc (sizeof *queue_tmp);
+  TRACE1 ("QUEUE SELECTION EVENT %p", queue_tmp);
+  queue_tmp->event = *event;
+  queue_tmp->next = selection_queue;
+  selection_queue = queue_tmp;
 }
 
 /* Start queuing SELECTION_REQUEST_EVENT events.  */
@@ -220,7 +216,7 @@ x_stop_queuing_selection_requests (void)
       TRACE1 ("RESTORE SELECTION EVENT %p", queue_tmp);
       kbd_buffer_unget_event (&queue_tmp->event);
       selection_queue = queue_tmp->next;
-      xfree ((char *)queue_tmp);
+      xfree (queue_tmp);
     }
 }
 \f
@@ -357,8 +353,9 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
                            INTEGER_TO_CONS (timestamp), frame);
     prev_value = LOCAL_SELECTION (selection_name, dpyinfo);
 
-    dpyinfo->terminal->Vselection_alist
-      = Fcons (selection_data, dpyinfo->terminal->Vselection_alist);
+    tset_selection_alist
+      (dpyinfo->terminal,
+       Fcons (selection_data, dpyinfo->terminal->Vselection_alist));
 
     /* If we already owned the selection, remove the old selection
        data.  Don't use Fdelq as that may QUIT.  */
@@ -378,7 +375,8 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
 \f
 /* Given a selection-name and desired type, look up our local copy of
    the selection value and convert it to the type.
-   The value is nil or a string.
+   Return nil, a string, a vector, a symbol, an integer, or a cons
+   that CONS_TO_INTEGER could plausibly handle.
    This function is used both for remote requests (LOCAL_REQUEST is zero)
    and for local x-get-selection-internal (LOCAL_REQUEST is nonzero).
 
@@ -390,7 +388,6 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
 {
   Lisp_Object local_value;
   Lisp_Object handler_fn, value, check;
-  int count;
 
   local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
 
@@ -407,7 +404,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
       /* Don't allow a quit within the converter.
         When the user types C-g, he would be surprised
         if by luck it came during a converter.  */
-      count = SPECPDL_INDEX ();
+      ptrdiff_t count = SPECPDL_INDEX ();
       specbind (Qinhibit_quit, Qt);
 
       CHECK_SYMBOL (target_type);
@@ -514,7 +511,7 @@ static struct selection_data *converted_selections;
 static Atom conversion_fail_tag;
 
 /* Used as an unwind-protect clause so that, if a selection-converter signals
-   an error, we tell the requester that we were unable to do what they wanted
+   an error, we tell the requestor that we were unable to do what they wanted
    before we throw to top-level or go into the debugger or whatever.  */
 
 static Lisp_Object
@@ -592,7 +589,8 @@ static int x_reply_selection_request_cnt;
 #endif  /* TRACE_SELECTION */
 
 static void
-x_reply_selection_request (struct input_event *event, struct x_display_info *dpyinfo)
+x_reply_selection_request (struct input_event *event,
+                           struct x_display_info *dpyinfo)
 {
   XEvent reply_base;
   XSelectionEvent *reply = &(reply_base.xselection);
@@ -600,7 +598,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
   Window window = SELECTION_EVENT_REQUESTOR (event);
   ptrdiff_t bytes_remaining;
   int max_bytes = selection_quantum (display);
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   struct selection_data *cs;
 
   reply->type = SelectionNotify;
@@ -690,7 +688,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
        bytes_remaining = cs->size;
        bytes_remaining *= format_bytes;
 
-       /* Wait for the requester to ack by deleting the property.
+       /* Wait for the requestor to ack by deleting the property.
           This can run Lisp code (process handlers) or signal.  */
        if (! had_errors)
          {
@@ -729,7 +727,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
 
            if (had_errors) break;
 
-           /* Wait for the requester to ack this chunk by deleting
+           /* Wait for the requestor to ack this chunk by deleting
               the property.  This can run Lisp code or signal.  */
            TRACE1 ("Waiting for increment ACK (deletion of %s)",
                    XGetAtomName (display, cs->property));
@@ -737,7 +735,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
          }
 
        /* Now write a zero-length chunk to the property to tell the
-          requester that we're done.  */
+          requestor that we're done.  */
        BLOCK_INPUT;
        if (! waiting_for_other_props_on_window (display, window))
          XSelectInput (display, window, 0L);
@@ -754,7 +752,7 @@ x_reply_selection_request (struct input_event *event, struct x_display_info *dpy
   /* The window we're communicating with may have been deleted
      in the meantime (that's a real situation from a bug report).
      In this case, there may be events in the event queue still
-     refering to the deleted window, and we'll get a BadWindow error
+     referring to the deleted window, and we'll get a BadWindow error
      in XTread_socket when processing the events.  I don't have
      an idea how to fix that.  gerd, 2001-01-98.   */
   /* 2004-09-10: XSync and UNBLOCK so that possible protocol errors are
@@ -789,7 +787,7 @@ x_handle_selection_request (struct input_event *event)
   Atom property = SELECTION_EVENT_PROPERTY (event);
   Lisp_Object local_selection_data;
   int success = 0;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   GCPRO2 (local_selection_data, target_symbol);
 
   if (!dpyinfo) goto DONE;
@@ -910,7 +908,7 @@ x_convert_selection (struct input_event *event, Lisp_Object selection_symbol,
     {
       if (for_multiple)
        {
-         cs = xmalloc (sizeof (struct selection_data));
+         cs = xmalloc (sizeof *cs);
          cs->data = (unsigned char *) &conversion_fail_tag;
          cs->size = 1;
          cs->format = 32;
@@ -927,7 +925,8 @@ x_convert_selection (struct input_event *event, Lisp_Object selection_symbol,
     }
 
   /* Otherwise, record the converted selection to binary.  */
-  cs = xmalloc (sizeof (struct selection_data));
+  cs = xmalloc (sizeof *cs);
+  cs->data = NULL;
   cs->nofree = 1;
   cs->property = property;
   cs->wait_object = NULL;
@@ -991,7 +990,7 @@ x_handle_selection_clear (struct input_event *event)
            break;
          }
     }
-  dpyinfo->terminal->Vselection_alist = Vselection_alist;
+  tset_selection_alist (dpyinfo->terminal, Vselection_alist);
 
   /* Run the `x-lost-selection-functions' abnormal hook.  */
   {
@@ -1041,7 +1040,7 @@ x_clear_frame_selections (FRAME_PTR f)
       args[1] = Fcar (Fcar (t->Vselection_alist));
       Frun_hook_with_args (2, args);
 
-      t->Vselection_alist = XCDR (t->Vselection_alist);
+      tset_selection_alist (t, XCDR (t->Vselection_alist));
     }
 
   /* Delete elements after the beginning of Vselection_alist.  */
@@ -1079,9 +1078,10 @@ waiting_for_other_props_on_window (Display *display, Window window)
    this awaited property change.  */
 
 static struct prop_location *
-expect_property_change (Display *display, Window window, Atom property, int state)
+expect_property_change (Display *display, Window window,
+                        Atom property, int state)
 {
-  struct prop_location *pl = (struct prop_location *) xmalloc (sizeof *pl);
+  struct prop_location *pl = xmalloc (sizeof *pl);
   pl->identifier = ++prop_location_identifier;
   pl->display = display;
   pl->window = window;
@@ -1135,8 +1135,7 @@ wait_for_property_change_unwind (Lisp_Object loc)
 static void
 wait_for_property_change (struct prop_location *location)
 {
-  int secs, usecs;
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   if (property_change_reply_object)
     abort ();
@@ -1152,10 +1151,11 @@ wait_for_property_change (struct prop_location *location)
      property_change_reply, because property_change_reply_object says so.  */
   if (! location->arrived)
     {
-      secs = x_selection_timeout / 1000;
-      usecs = (x_selection_timeout % 1000) * 1000;
-      TRACE2 ("  Waiting %d secs, %d usecs", secs, usecs);
-      wait_reading_process_output (secs, usecs, 0, 0,
+      EMACS_INT timeout = max (0, x_selection_timeout);
+      EMACS_INT secs = timeout / 1000;
+      int nsecs = (timeout % 1000) * 1000000;
+      TRACE2 ("  Waiting %"pI"d secs, %d nsecs", secs, nsecs);
+      wait_reading_process_output (secs, nsecs, 0, 0,
                                   property_change_reply, NULL, 0);
 
       if (NILP (XCAR (property_change_reply)))
@@ -1224,7 +1224,8 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
   Atom type_atom = (CONSP (target_type)
                    ? symbol_to_x_atom (dpyinfo, XCAR (target_type))
                    : symbol_to_x_atom (dpyinfo, target_type));
-  int secs, usecs;
+  EMACS_INT timeout, secs;
+  int nsecs;
 
   if (!FRAME_LIVE_P (f))
     return Qnil;
@@ -1260,10 +1261,11 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type,
   UNBLOCK_INPUT;
 
   /* This allows quits.  Also, don't wait forever.  */
-  secs = x_selection_timeout / 1000;
-  usecs = (x_selection_timeout % 1000) * 1000;
-  TRACE1 ("  Start waiting %d secs for SelectionNotify", secs);
-  wait_reading_process_output (secs, usecs, 0, 0,
+  timeout = max (0, x_selection_timeout);
+  secs = timeout / 1000;
+  nsecs = (timeout % 1000) * 1000000;
+  TRACE1 ("  Start waiting %"pI"d secs for SelectionNotify", secs);
+  wait_reading_process_output (secs, nsecs, 0, 0,
                               reading_selection_reply, NULL, 0);
   TRACE1 ("  Got event = %d", !NILP (XCAR (reading_selection_reply)));
 
@@ -1320,7 +1322,7 @@ x_get_window_property (Display *display, Window window, Atom property,
     goto done;
 
   /* This was allocated by Xlib, so use XFree.  */
-  XFree ((char *) tmp_data);
+  XFree (tmp_data);
 
   if (*actual_type_ret == None || *actual_format_ret == 0)
     goto done;
@@ -1353,7 +1355,7 @@ x_get_window_property (Display *display, Window window, Atom property,
        break;
 
       bytes_per_item = *actual_format_ret >> 3;
-      xassert (*actual_size_ret <= buffer_size / bytes_per_item);
+      eassert (*actual_size_ret <= buffer_size / bytes_per_item);
 
       /* The man page for XGetWindowProperty says:
          "If the returned format is 32, the returned data is represented
@@ -1402,7 +1404,7 @@ x_get_window_property (Display *display, Window window, Atom property,
       offset += bytes_gotten;
 
       /* This was allocated by Xlib, so use XFree.  */
-      XFree ((char *) tmp_data);
+      XFree (tmp_data);
     }
 
   XFlush (display);
@@ -1440,7 +1442,7 @@ receive_incremental_selection (Display *display, Window window, Atom property,
   struct prop_location *wait_object;
   if (min (PTRDIFF_MAX, SIZE_MAX) < min_size_bytes)
     memory_full (SIZE_MAX);
-  *data_ret = (unsigned char *) xmalloc (min_size_bytes);
+  *data_ret = xmalloc (min_size_bytes);
   *size_bytes_ret = min_size_bytes;
 
   TRACE1 ("Read %u bytes incrementally", min_size_bytes);
@@ -1567,7 +1569,7 @@ x_get_window_property_as_lisp_data (Display *display, Window window,
       BLOCK_INPUT;
       /* Use xfree, not XFree, because x_get_window_property
         calls xmalloc itself.  */
-      xfree ((char *) data);
+      xfree (data);
       UNBLOCK_INPUT;
       receive_incremental_selection (display, window, property, target_type,
                                     min_size_bytes, &data, &bytes,
@@ -1588,7 +1590,7 @@ x_get_window_property_as_lisp_data (Display *display, Window window,
 
   /* Use xfree, not XFree, because x_get_window_property
      calls xmalloc itself.  */
-  xfree ((char *) data);
+  xfree (data);
   return val;
 }
 \f
@@ -1683,9 +1685,9 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
      convert it to a cons of integers, 16 bits in each half.
    */
   else if (format == 32 && size == sizeof (int))
-    return INTEGER_TO_CONS (((unsigned int *) data) [0]);
+    return INTEGER_TO_CONS (((int *) data) [0]);
   else if (format == 16 && size == sizeof (short))
-    return make_number (((unsigned short *) data) [0]);
+    return make_number (((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.)
@@ -1697,7 +1699,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
       v = Fmake_vector (make_number (size / 2), make_number (0));
       for (i = 0; i < size / 2; i++)
        {
-         EMACS_INT j = ((unsigned short *) data) [i];
+         short j = ((short *) data) [i];
          Faset (v, make_number (i), make_number (j));
        }
       return v;
@@ -1709,13 +1711,28 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data,
                                    make_number (0));
       for (i = 0; i < size / X_LONG_SIZE; i++)
        {
-         unsigned int j = ((unsigned int *) data) [i];
+         int j = ((int *) data) [i];
          Faset (v, make_number (i), INTEGER_TO_CONS (j));
        }
       return v;
     }
 }
 
+/* Convert OBJ to an X long value, and return it as unsigned long.
+   OBJ should be an integer or a cons representing an integer.
+   Treat values in the range X_LONG_MAX + 1 .. X_ULONG_MAX as X
+   unsigned long values: in theory these values are supposed to be
+   signed but in practice unsigned 32-bit data are communicated via X
+   selections and we need to support that.  */
+static unsigned long
+cons_to_x_long (Lisp_Object obj)
+{
+  if (X_ULONG_MAX <= INTMAX_MAX
+      || XINT (INTEGERP (obj) ? obj : XCAR (obj)) < 0)
+    return cons_to_signed (obj, X_LONG_MIN, min (X_ULONG_MAX, INTMAX_MAX));
+  else
+    return cons_to_unsigned (obj, X_ULONG_MAX);
+}
 
 /* Use xfree, not XFree, to free the data obtained with this function.  */
 
@@ -1759,20 +1776,24 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
     }
   else if (SYMBOLP (obj))
     {
-      *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1);
+      void *data = xmalloc (sizeof (Atom) + 1);
+      Atom *x_atom_ptr = data;
+      *data_ret = data;
       *format_ret = 32;
       *size_ret = 1;
       (*data_ret) [sizeof (Atom)] = 0;
-      (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj);
+      *x_atom_ptr = symbol_to_x_atom (dpyinfo, obj);
       if (NILP (type)) type = QATOM;
     }
   else if (RANGED_INTEGERP (X_SHRT_MIN, obj, X_SHRT_MAX))
     {
-      *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1);
+      void *data = xmalloc (sizeof (short) + 1);
+      short *short_ptr = data;
+      *data_ret = data;
       *format_ret = 16;
       *size_ret = 1;
       (*data_ret) [sizeof (short)] = 0;
-      (*(short **) data_ret) [0] = XINT (obj);
+      *short_ptr = XINT (obj);
       if (NILP (type)) type = QINTEGER;
     }
   else if (INTEGERP (obj)
@@ -1781,11 +1802,13 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
                   || (CONSP (XCDR (obj))
                       && INTEGERP (XCAR (XCDR (obj)))))))
     {
-      *data_ret = (unsigned char *) xmalloc (sizeof (long) + 1);
+      void *data = xmalloc (sizeof (unsigned long) + 1);
+      unsigned long *x_long_ptr = data;
+      *data_ret = data;
       *format_ret = 32;
       *size_ret = 1;
-      (*data_ret) [sizeof (long)] = 0;
-      (*(long **) data_ret) [0] = cons_to_signed (obj, X_LONG_MIN, X_LONG_MAX);
+      (*data_ret) [sizeof (unsigned long)] = 0;
+      *x_long_ptr = cons_to_x_long (obj);
       if (NILP (type)) type = QINTEGER;
     }
   else if (VECTORP (obj))
@@ -1797,51 +1820,56 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
       ptrdiff_t i;
       ptrdiff_t size = ASIZE (obj);
 
-      if (SYMBOLP (XVECTOR (obj)->contents [0]))
+      if (SYMBOLP (AREF (obj, 0)))
        /* This vector is an ATOM set */
        {
+         void *data;
+         Atom *x_atoms;
          if (NILP (type)) type = QATOM;
          for (i = 0; i < size; i++)
-           if (!SYMBOLP (XVECTOR (obj)->contents [i]))
+           if (!SYMBOLP (AREF (obj, i)))
              signal_error ("All elements of selection vector must have same type", obj);
 
-         *data_ret = xnmalloc (size, sizeof (Atom));
+         *data_ret = data = xnmalloc (size, sizeof *x_atoms);
+         x_atoms = data;
          *format_ret = 32;
          *size_ret = size;
          for (i = 0; i < size; i++)
-           (*(Atom **) data_ret) [i]
-             = symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]);
+           x_atoms[i] = symbol_to_x_atom (dpyinfo, AREF (obj, i));
        }
       else
        /* This vector is an INTEGER set, or something like it */
        {
          int format = 16;
          int data_size = sizeof (short);
+         void *data;
+         unsigned long *x_atoms;
+         short *shorts;
          if (NILP (type)) type = QINTEGER;
          for (i = 0; i < size; i++)
            {
-             intmax_t v = cons_to_signed (XVECTOR (obj)->contents[i],
-                                          X_LONG_MIN, X_LONG_MAX);
-             if (X_SHRT_MIN <= v && v <= X_SHRT_MAX)
+             if (! RANGED_INTEGERP (X_SHRT_MIN, AREF (obj, i),
+                                    X_SHRT_MAX))
                {
                  /* Use sizeof (long) even if it is more than 32 bits.
                     See comment in x_get_window_property and
                     x_fill_property_data.  */
                  data_size = sizeof (long);
                  format = 32;
+                 break;
                }
            }
-         *data_ret = xnmalloc (size, data_size);
+         *data_ret = data = xnmalloc (size, data_size);
+         x_atoms = data;
+         shorts = data;
          *format_ret = format;
          *size_ret = size;
          for (i = 0; i < size; i++)
            {
-             long v = cons_to_signed (XVECTOR (obj)->contents[i],
-                                      X_LONG_MIN, X_LONG_MAX);
              if (format == 32)
-               (*((long **) data_ret)) [i] = v;
+               x_atoms[i] = cons_to_x_long (AREF (obj, i));
              else
-               (*((short **) data_ret)) [i] = v;
+               shorts[i] = XINT (AREF (obj, i));
            }
        }
     }
@@ -1876,11 +1904,10 @@ clean_local_selection_data (Lisp_Object obj)
       ptrdiff_t size = ASIZE (obj);
       Lisp_Object copy;
       if (size == 1)
-       return clean_local_selection_data (XVECTOR (obj)->contents [0]);
+       return clean_local_selection_data (AREF (obj, 0));
       copy = Fmake_vector (make_number (size), Qnil);
       for (i = 0; i < size; i++)
-       XVECTOR (copy)->contents [i]
-         = clean_local_selection_data (XVECTOR (obj)->contents [i]);
+       ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
       return copy;
     }
   return obj;
@@ -1963,7 +1990,9 @@ VALUE is typically a string, or a cons of two markers, but may be
 anything that the functions on `selection-converter-alist' know about.
 
 FRAME should be a frame that should own the selection.  If omitted or
-nil, it defaults to the selected frame.  */)
+nil, it defaults to the selected frame.
+
+On Nextstep, FRAME is unused.  */)
   (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
 {
   if (NILP (frame)) frame = selected_frame;
@@ -1984,15 +2013,18 @@ nil, it defaults to the selected frame.  */)
 DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
        Sx_get_selection_internal, 2, 4, 0,
        doc: /* Return text selected from some X window.
-SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
 \(Those are literal upper-case symbol names, since that's what X expects.)
-TYPE is the type of data desired, typically `STRING'.
-TIME_STAMP is the time to use in the XConvertSelection call for foreign
+TARGET-TYPE is the type of data desired, typically `STRING'.
+
+TIME-STAMP is the time to use in the XConvertSelection call for foreign
 selections.  If omitted, defaults to the time for the last event.
 
 TERMINAL should be a terminal object or a frame specifying the X
 server to query.  If omitted or nil, that stands for the selected
-frame's display, or the first available X display.  */)
+frame's display, or the first available X display.
+
+On Nextstep, TIME-STAMP and TERMINAL are unused.  */)
   (Lisp_Object selection_symbol, Lisp_Object target_type,
    Lisp_Object time_stamp, Lisp_Object terminal)
 {
@@ -2033,9 +2065,15 @@ DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
        doc: /* If we own the selection SELECTION, disown it.
 Disowning it means there is no such selection.
 
+Sets the last-change time for the selection to TIME-OBJECT (by default
+the time of the last event).
+
 TERMINAL should be a terminal object or a frame specifying the X
 server to query.  If omitted or nil, that stands for the selected
-frame's display, or the first available X display.  */)
+frame's display, or the first available X display.
+
+On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
+On MS-DOS, all this does is return non-nil if we own the selection.  */)
   (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
 {
   Time timestamp;
@@ -2091,7 +2129,9 @@ and t is the same as `SECONDARY'.
 
 TERMINAL should be a terminal object or a frame specifying the X
 server to query.  If omitted or nil, that stands for the selected
-frame's display, or the first available X display.  */)
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused.  */)
   (Lisp_Object selection, Lisp_Object terminal)
 {
   struct frame *f = frame_for_x_selection (terminal);
@@ -2110,13 +2150,15 @@ DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
        0, 2, 0,
        doc: /* Whether there is an owner for the given X selection.
 SELECTION should be the name of the selection in question, typically
-one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.  (X expects
-these literal upper-case names.)  The symbol nil is the same as
-`PRIMARY', and t is the same as `SECONDARY'.
+one of the symbols `PRIMARY', `SECONDARY', `CLIPBOARD', or
+`CLIPBOARD_MANAGER' (X expects these literal upper-case names.)  The
+symbol nil is the same as `PRIMARY', and t is the same as `SECONDARY'.
 
 TERMINAL should be a terminal object or a frame specifying the X
 server to query.  If omitted or nil, that stands for the selected
-frame's display, or the first available X display.  */)
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused.  */)
   (Lisp_Object selection, Lisp_Object terminal)
 {
   Window owner;
@@ -2239,8 +2281,14 @@ x_clipboard_manager_save_all (void)
 
       local_frame = XCAR (XCDR (XCDR (XCDR (local_selection))));
       if (FRAME_LIVE_P (XFRAME (local_frame)))
-       internal_condition_case_1 (x_clipboard_manager_save, local_frame,
-                                  Qt, x_clipboard_manager_error_2);
+       {
+         Lisp_Object args[1];
+         args[0] = build_string ("Saving clipboard to X clipboard manager...");
+         Fmessage (1, args);
+
+         internal_condition_case_1 (x_clipboard_manager_save, local_frame,
+                                    Qt, x_clipboard_manager_error_2);
+       }
     }
 }
 
@@ -2336,7 +2384,7 @@ x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
    F is the frame to be used to look up X atoms if the TYPE is XA_ATOM.
    DATA is a C array of values to be converted.
    TYPE is the type of the data.  Only XA_ATOM is special, it converts
-   each number in DATA to its corresponfing X atom as a symbol.
+   each number in DATA to its corresponding X atom as a symbol.
    FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
    be stored in RET.
    SIZE is the number of elements in DATA.
@@ -2472,7 +2520,8 @@ FRAME is on.  If FRAME is nil, the selected frame is used.  */)
 /* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT.  */
 
 int
-x_handle_dnd_message (struct frame *f, XClientMessageEvent *event, struct x_display_info *dpyinfo, struct input_event *bufp)
+x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
+                      struct x_display_info *dpyinfo, struct input_event *bufp)
 {
   Lisp_Object vec;
   Lisp_Object frame;
@@ -2550,22 +2599,24 @@ the Atom is sent.  If a value is a cons, it is converted to a 32 bit number
 with the high 16 bits from the car and the lower 16 bit from the cdr.
 If more values than fits into the event is given, the excessive values
 are ignored.  */)
-  (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
+  (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
+   Lisp_Object message_type, Lisp_Object format, Lisp_Object values)
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
 
   CHECK_STRING (message_type);
-  x_send_client_event(display, dest, from,
-                      XInternAtom (dpyinfo->display,
-                                   SSDATA (message_type),
-                                   False),
-                      format, values);
+  x_send_client_event (display, dest, from,
+                       XInternAtom (dpyinfo->display,
+                                    SSDATA (message_type),
+                                    False),
+                       format, values);
 
   return Qnil;
 }
 
 void
-x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, Atom message_type, Lisp_Object format, Lisp_Object values)
+x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
+                     Atom message_type, Lisp_Object format, Lisp_Object values)
 {
   struct x_display_info *dpyinfo = check_x_display_info (display);
   Window wdest;
@@ -2579,13 +2630,12 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, At
   if (x_check_property_data (values) == -1)
     error ("Bad data in VALUES, must be number, cons or string");
 
-  event.xclient.type = ClientMessage;
-  event.xclient.format = XFASTINT (format);
-
-  if (event.xclient.format != 8 && event.xclient.format != 16
-      && event.xclient.format != 32)
+  if (XINT (format) != 8 && XINT (format) != 16 && XINT (format) != 32)
     error ("FORMAT must be one of 8, 16 or 32");
 
+  event.xclient.type = ClientMessage;
+  event.xclient.format = XINT (format);
+
   if (FRAMEP (dest) || NILP (dest))
     {
       struct frame *fdest = check_x_frame (dest);