X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/929bb973dd3faf1655f03ac758942d5b009354ad..6d12ff8b3344d4284f78e0be56cda076f9a3d6e7:/src/xselect.c
diff --git a/src/xselect.c b/src/xselect.c
index 9eee4ee959..5a3b7452c6 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -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 . */
#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
@@ -180,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. */
@@ -198,7 +193,7 @@ static void
x_start_queuing_selection_requests (void)
{
if (x_queue_selection_requests)
- abort ();
+ emacs_abort ();
x_queue_selection_requests++;
TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests);
@@ -221,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);
}
}
@@ -250,7 +245,7 @@ symbol_to_x_atom (struct x_display_info *dpyinfo, Lisp_Object sym)
if (EQ (sym, QEMACS_TMP)) return dpyinfo->Xatom_EMACS_TMP;
if (EQ (sym, QTARGETS)) return dpyinfo->Xatom_TARGETS;
if (EQ (sym, QNULL)) return dpyinfo->Xatom_NULL;
- if (!SYMBOLP (sym)) abort ();
+ if (!SYMBOLP (sym)) emacs_abort ();
TRACE1 (" XInternAtom %s", SSDATA (SYMBOL_NAME (sym)));
BLOCK_INPUT;
@@ -358,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. */
@@ -515,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
@@ -692,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)
{
@@ -731,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));
@@ -739,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);
@@ -756,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
@@ -912,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;
@@ -929,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;
@@ -993,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. */
{
@@ -1043,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. */
@@ -1084,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;
@@ -1138,11 +1135,10 @@ wait_for_property_change_unwind (Lisp_Object loc)
static void
wait_for_property_change (struct prop_location *location)
{
- int secs, usecs;
ptrdiff_t count = SPECPDL_INDEX ();
if (property_change_reply_object)
- abort ();
+ emacs_abort ();
/* Make sure to do unexpect_property_change if we quit or err. */
record_unwind_protect (wait_for_property_change_unwind,
@@ -1155,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)))
@@ -1227,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;
@@ -1263,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)));
@@ -1323,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;
@@ -1356,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
@@ -1405,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);
@@ -1443,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);
@@ -1570,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,
@@ -1591,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;
}
@@ -1777,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)
@@ -1799,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 (unsigned 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 (unsigned long)] = 0;
- (*(unsigned long **) data_ret) [0] = cons_to_x_long (obj);
+ *x_long_ptr = cons_to_x_long (obj);
if (NILP (type)) type = QINTEGER;
}
else if (VECTORP (obj))
@@ -1815,30 +1820,35 @@ 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++)
{
- if (! RANGED_INTEGERP (X_SHRT_MIN, XVECTOR (obj)->contents[i],
+ if (! RANGED_INTEGERP (X_SHRT_MIN, AREF (obj, i),
X_SHRT_MAX))
{
/* Use sizeof (long) even if it is more than 32 bits.
@@ -1849,17 +1859,17 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
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++)
{
if (format == 32)
- (*((unsigned long **) data_ret)) [i] =
- cons_to_x_long (XVECTOR (obj)->contents[i]);
+ x_atoms[i] = cons_to_x_long (AREF (obj, i));
else
- (*((short **) data_ret)) [i] =
- XINT (XVECTOR (obj)->contents[i]);
+ shorts[i] = XINT (AREF (obj, i));
}
}
}
@@ -1894,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;
@@ -1981,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;
@@ -2002,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)
{
@@ -2051,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;
@@ -2109,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);
@@ -2128,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;
@@ -2257,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);
+ }
}
}
@@ -2354,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.