* termhooks.h (TSET): Remove.
[bpt/emacs.git] / src / xselect.c
index 241622e..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
@@ -601,7 +598,7 @@ x_reply_selection_request (struct input_event *event,
   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;
@@ -691,7 +688,7 @@ x_reply_selection_request (struct input_event *event,
        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)
          {
@@ -730,7 +727,7 @@ x_reply_selection_request (struct input_event *event,
 
            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));
@@ -738,7 +735,7 @@ x_reply_selection_request (struct input_event *event,
          }
 
        /* 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);
@@ -755,7 +752,7 @@ x_reply_selection_request (struct input_event *event,
   /* 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
@@ -790,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;
@@ -911,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;
@@ -928,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;
@@ -992,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.  */
   {
@@ -1042,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.  */
@@ -1083,7 +1081,7 @@ static struct prop_location *
 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;
@@ -1137,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 ();
@@ -1154,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)))
@@ -1226,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;
@@ -1262,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)));
 
@@ -1322,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;
@@ -1355,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
@@ -1404,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);
@@ -1442,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);
@@ -1569,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,
@@ -1590,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
@@ -1685,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.)
@@ -1699,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;
@@ -1711,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.  */
 
@@ -1761,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)
@@ -1783,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))
@@ -1799,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));
            }
        }
     }
@@ -1878,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;
@@ -1965,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;
@@ -1986,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)
 {
@@ -2035,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;
@@ -2093,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);
@@ -2112,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;
@@ -2241,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);
+       }
     }
 }
 
@@ -2338,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.
@@ -2584,13 +2630,12 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from,
   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);