/* X Selection processing for Emacs.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h> /* termhooks.h needs this */
+#include <setjmp.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
struct prop_location;
-static Lisp_Object x_atom_to_symbol P_ ((Display *dpy, Atom atom));
-static Atom symbol_to_x_atom P_ ((struct x_display_info *, Display *,
- Lisp_Object));
-static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
-static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
-static void x_decline_selection_request P_ ((struct input_event *));
-static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object));
-static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object));
-static Lisp_Object some_frame_on_display P_ ((struct x_display_info *));
-static Lisp_Object x_catch_errors_unwind P_ ((Lisp_Object));
-static void x_reply_selection_request P_ ((struct input_event *, int,
- unsigned char *, int, Atom));
-static int waiting_for_other_props_on_window P_ ((Display *, Window));
-static struct prop_location *expect_property_change P_ ((Display *, Window,
- Atom, int));
-static void unexpect_property_change P_ ((struct prop_location *));
-static Lisp_Object wait_for_property_change_unwind P_ ((Lisp_Object));
-static void wait_for_property_change P_ ((struct prop_location *));
-static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
- Lisp_Object,
- Lisp_Object));
-static void x_get_window_property P_ ((Display *, Window, Atom,
- unsigned char **, int *,
- Atom *, int *, unsigned long *, int));
-static void receive_incremental_selection P_ ((Display *, Window, Atom,
- Lisp_Object, unsigned,
- unsigned char **, int *,
- Atom *, int *, unsigned long *));
-static Lisp_Object x_get_window_property_as_lisp_data P_ ((Display *,
- Window, Atom,
- Lisp_Object, Atom));
-static Lisp_Object selection_data_to_lisp_data P_ ((Display *, unsigned char *,
- int, Atom, int));
-static void lisp_data_to_selection_data P_ ((Display *, Lisp_Object,
- unsigned char **, Atom *,
- unsigned *, int *, int *));
-static Lisp_Object clean_local_selection_data P_ ((Lisp_Object));
-static void initialize_cut_buffers P_ ((Display *, Window));
+static Lisp_Object x_atom_to_symbol (Display *dpy, Atom atom);
+static Atom symbol_to_x_atom (struct x_display_info *, Display *,
+ Lisp_Object);
+static void x_own_selection (Lisp_Object, Lisp_Object);
+static Lisp_Object x_get_local_selection (Lisp_Object, Lisp_Object, int);
+static void x_decline_selection_request (struct input_event *);
+static Lisp_Object x_selection_request_lisp_error (Lisp_Object);
+static Lisp_Object queue_selection_requests_unwind (Lisp_Object);
+static Lisp_Object some_frame_on_display (struct x_display_info *);
+static Lisp_Object x_catch_errors_unwind (Lisp_Object);
+static void x_reply_selection_request (struct input_event *, int,
+ unsigned char *, int, Atom);
+static int waiting_for_other_props_on_window (Display *, Window);
+static struct prop_location *expect_property_change (Display *, Window,
+ Atom, int);
+static void unexpect_property_change (struct prop_location *);
+static Lisp_Object wait_for_property_change_unwind (Lisp_Object);
+static void wait_for_property_change (struct prop_location *);
+static Lisp_Object x_get_foreign_selection (Lisp_Object,
+ Lisp_Object,
+ Lisp_Object);
+static void x_get_window_property (Display *, Window, Atom,
+ unsigned char **, int *,
+ Atom *, int *, unsigned long *, int);
+static void receive_incremental_selection (Display *, Window, Atom,
+ Lisp_Object, unsigned,
+ unsigned char **, int *,
+ Atom *, int *, unsigned long *);
+static Lisp_Object x_get_window_property_as_lisp_data (Display *,
+ Window, Atom,
+ Lisp_Object, Atom);
+static Lisp_Object selection_data_to_lisp_data (Display *, unsigned char *,
+ int, Atom, int);
+static void lisp_data_to_selection_data (Display *, Lisp_Object,
+ unsigned char **, Atom *,
+ unsigned *, int *, int *);
+static Lisp_Object clean_local_selection_data (Lisp_Object);
+static void initialize_cut_buffers (Display *, Window);
/* Printing traces to stderr. */
/* Queue up an SELECTION_REQUEST_EVENT *EVENT, to be processed later. */
static void
-x_queue_event (event)
- struct input_event *event;
+x_queue_event (struct input_event *event)
{
struct selection_event_queue *queue_tmp;
This only happens for large requests which uses the incremental protocol. */
for (queue_tmp = selection_queue; queue_tmp; queue_tmp = queue_tmp->next)
{
- if (!bcmp (&queue_tmp->event, event, sizeof (*event)))
+ if (!memcmp (&queue_tmp->event, event, sizeof (*event)))
{
TRACE1 ("DECLINE DUP SELECTION EVENT %08lx", (unsigned long)queue_tmp);
x_decline_selection_request (event);
/* Start queuing SELECTION_REQUEST_EVENT events. */
static void
-x_start_queuing_selection_requests ()
+x_start_queuing_selection_requests (void)
{
if (x_queue_selection_requests)
abort ();
/* Stop queuing SELECTION_REQUEST_EVENT events. */
static void
-x_stop_queuing_selection_requests ()
+x_stop_queuing_selection_requests (void)
{
TRACE1 ("x_stop_queuing_selection_requests %d", x_queue_selection_requests);
--x_queue_selection_requests;
roundtrip whenever possible. */
static Atom
-symbol_to_x_atom (dpyinfo, display, sym)
- struct x_display_info *dpyinfo;
- Display *display;
- Lisp_Object sym;
+symbol_to_x_atom (struct x_display_info *dpyinfo, Display *display, Lisp_Object sym)
{
Atom val;
if (NILP (sym)) return 0;
and calls to intern whenever possible. */
static Lisp_Object
-x_atom_to_symbol (dpy, atom)
- Display *dpy;
- Atom atom;
+x_atom_to_symbol (Display *dpy, Atom atom)
{
struct x_display_info *dpyinfo;
char *str;
our selection. */
static void
-x_own_selection (selection_name, selection_value)
- Lisp_Object selection_name, selection_value;
+x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value)
{
struct frame *sf = SELECTED_FRAME ();
Window selecting_window;
This calls random Lisp code, and may signal or gc. */
static Lisp_Object
-x_get_local_selection (selection_symbol, target_type, local_request)
- Lisp_Object selection_symbol, target_type;
- int local_request;
+x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, int local_request)
{
Lisp_Object local_value;
Lisp_Object handler_fn, value, type, check;
meaning we were unable to do what they wanted. */
static void
-x_decline_selection_request (event)
- struct input_event *event;
+x_decline_selection_request (struct input_event *event)
{
XSelectionEvent reply;
before we throw to top-level or go into the debugger or whatever. */
static Lisp_Object
-x_selection_request_lisp_error (ignore)
- Lisp_Object ignore;
+x_selection_request_lisp_error (Lisp_Object ignore)
{
if (x_selection_current_request != 0
&& selection_request_dpyinfo->display)
}
static Lisp_Object
-x_catch_errors_unwind (dummy)
- Lisp_Object dummy;
+x_catch_errors_unwind (Lisp_Object dummy)
{
BLOCK_INPUT;
x_uncatch_errors ();
struct prop_location *next;
};
-static struct prop_location *expect_property_change ();
-static void wait_for_property_change ();
-static void unexpect_property_change ();
-static int waiting_for_other_props_on_window ();
+static struct prop_location *expect_property_change (Display *display, Window window, Atom property, int state);
+static void wait_for_property_change (struct prop_location *location);
+static void unexpect_property_change (struct prop_location *location);
+static int waiting_for_other_props_on_window (Display *display, Window window);
static int prop_location_identifier;
static struct prop_location *property_change_wait_list;
static Lisp_Object
-queue_selection_requests_unwind (tem)
- Lisp_Object tem;
+queue_selection_requests_unwind (Lisp_Object tem)
{
x_stop_queuing_selection_requests ();
return Qnil;
Return nil if there is none. */
static Lisp_Object
-some_frame_on_display (dpyinfo)
- struct x_display_info *dpyinfo;
+some_frame_on_display (struct x_display_info *dpyinfo)
{
Lisp_Object list, frame;
#endif /* TRACE_SELECTION */
static void
-x_reply_selection_request (event, format, data, size, type)
- struct input_event *event;
- int format, size;
- unsigned char *data;
- Atom type;
+x_reply_selection_request (struct input_event *event, int format, unsigned char *data, int size, Atom type)
{
XSelectionEvent reply;
Display *display = SELECTION_EVENT_DISPLAY (event);
This is called from keyboard.c when such an event is found in the queue. */
static void
-x_handle_selection_request (event)
- struct input_event *event;
+x_handle_selection_request (struct input_event *event)
{
struct gcpro gcpro1, gcpro2, gcpro3;
Lisp_Object local_selection_data;
This is called from keyboard.c when such an event is found in the queue. */
static void
-x_handle_selection_clear (event)
- struct input_event *event;
+x_handle_selection_clear (struct input_event *event)
{
Display *display = SELECTION_EVENT_DISPLAY (event);
Atom selection = SELECTION_EVENT_SELECTION (event);
}
void
-x_handle_selection_event (event)
- struct input_event *event;
+x_handle_selection_event (struct input_event *event)
{
TRACE0 ("x_handle_selection_event");
We do this when about to delete a frame. */
void
-x_clear_frame_selections (f)
- FRAME_PTR f;
+x_clear_frame_selections (FRAME_PTR f)
{
Lisp_Object frame;
Lisp_Object rest;
are on the list of what we are waiting for. */
static int
-waiting_for_other_props_on_window (display, window)
- Display *display;
- Window window;
+waiting_for_other_props_on_window (Display *display, Window window)
{
struct prop_location *rest = property_change_wait_list;
while (rest)
this awaited property change. */
static struct prop_location *
-expect_property_change (display, window, property, state)
- 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);
pl->identifier = ++prop_location_identifier;
IDENTIFIER is the number that uniquely identifies the entry. */
static void
-unexpect_property_change (location)
- struct prop_location *location;
+unexpect_property_change (struct prop_location *location)
{
struct prop_location *prev = 0, *rest = property_change_wait_list;
while (rest)
/* Remove the property change expectation element for IDENTIFIER. */
static Lisp_Object
-wait_for_property_change_unwind (loc)
- Lisp_Object loc;
+wait_for_property_change_unwind (Lisp_Object loc)
{
struct prop_location *location = XSAVE_VALUE (loc)->pointer;
IDENTIFIER should be the value that expect_property_change returned. */
static void
-wait_for_property_change (location)
- struct prop_location *location;
+wait_for_property_change (struct prop_location *location)
{
int secs, usecs;
int count = SPECPDL_INDEX ();
/* Called from XTread_socket in response to a PropertyNotify event. */
void
-x_handle_property_notify (event)
- XPropertyEvent *event;
+x_handle_property_notify (XPropertyEvent *event)
{
struct prop_location *prev = 0, *rest = property_change_wait_list;
Converts this to Lisp data and returns it. */
static Lisp_Object
-x_get_foreign_selection (selection_symbol, target_type, time_stamp)
- Lisp_Object selection_symbol, target_type, time_stamp;
+x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, Lisp_Object time_stamp)
{
struct frame *sf = SELECTED_FRAME ();
Window requestor_window;
if (NILP (XCAR (reading_selection_reply)))
error ("Timed out waiting for reply from selection owner");
if (EQ (XCAR (reading_selection_reply), Qlambda))
- error ("No `%s' selection", SDATA (SYMBOL_NAME (selection_symbol)));
+ return Qnil;
/* Otherwise, the selection is waiting for us on the requested property. */
return
elements."
This applies even if long is more than 32 bits, the X library
converts from 32 bit elements received from the X server to long
- and passes the long array to us. Thus, for that case bcopy can not
+ and passes the long array to us. Thus, for that case memcpy can not
be used. We convert to a 32 bit type here, because so much code
assume on that.
else
{
*actual_size_ret *= *actual_format_ret / 8;
- bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret);
+ memcpy ((*data_ret) + offset, tmp_data, *actual_size_ret);
offset += *actual_size_ret;
}
*data_ret = (unsigned char *) xrealloc (*data_ret, *size_bytes_ret);
}
- bcopy (tmp_data, (*data_ret) + offset, tmp_size_bytes);
+ memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
offset += tmp_size_bytes;
/* Use xfree, not XFree, because x_get_window_property
static Lisp_Object
-selection_data_to_lisp_data (display, data, size, type, format)
- Display *display;
- unsigned char *data;
- Atom type;
- int size, format;
+selection_data_to_lisp_data (Display *display, unsigned char *data, int size, Atom type, int format)
{
struct x_display_info *dpyinfo = x_display_info_for_display (display);
}
static Lisp_Object
-clean_local_selection_data (obj)
- Lisp_Object obj;
+clean_local_selection_data (Lisp_Object obj)
{
if (CONSP (obj)
&& INTEGERP (XCAR (obj))
We store t there if the reply is successful, lambda if not. */
void
-x_handle_selection_notify (event)
- XSelectionEvent *event;
+x_handle_selection_notify (XSelectionEvent *event)
{
if (event->requestor != reading_selection_window)
return;
This is used when we kill a buffer. */
void
-x_disown_buffer_selections (buffer)
- Lisp_Object buffer;
+x_disown_buffer_selections (Lisp_Object buffer)
{
Lisp_Object tail;
struct buffer *buf = XBUFFER (buffer);
/* Ensure that all 8 cut buffers exist. ICCCM says we gotta... */
static void
-initialize_cut_buffers (display, window)
- Display *display;
- Window window;
+initialize_cut_buffers (Display *display, Window window)
{
unsigned char *data = (unsigned char *) "";
BLOCK_INPUT;
{
Window window;
Atom buffer_atom;
- unsigned char *data;
+ unsigned char *data = NULL;
int bytes;
Atom type;
int format;
x_get_window_property (display, window, buffer_atom, &data, &bytes,
&type, &format, &size, 0);
+
if (!data || !format)
- return Qnil;
+ {
+ xfree (data);
+ return Qnil;
+ }
if (format != 8 || type != XA_STRING)
signal_error ("Cut buffer doesn't contain 8-bit data",
bit parts of a 32 bit number). */
int
-x_check_property_data (data)
- Lisp_Object data;
+x_check_property_data (Lisp_Object data)
{
Lisp_Object iter;
int size = 0;
XClientMessageEvent). */
void
-x_fill_property_data (dpy, data, ret, format)
- Display *dpy;
- Lisp_Object data;
- void *ret;
- int format;
+x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
{
long val;
long *d32 = (long *) ret;
Also see comment for selection_data_to_lisp_data above. */
Lisp_Object
-x_property_data_to_lisp (f, data, type, format, size)
- struct frame *f;
- unsigned char *data;
- Atom type;
- int format;
- unsigned long size;
+x_property_data_to_lisp (struct frame *f, unsigned char *data, Atom type, int format, long unsigned int size)
{
return selection_data_to_lisp_data (FRAME_X_DISPLAY (f),
data, size*format/8, type, format);
/* Get the mouse position in frame relative coordinates. */
static void
-mouse_position_for_drop (f, x, y)
- FRAME_PTR f;
- int *x;
- int *y;
+mouse_position_for_drop (FRAME_PTR f, int *x, int *y)
{
Window root, dummy_window;
int dummy;
/* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT. */
int
-x_handle_dnd_message (f, event, dpyinfo, bufp)
- 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;
\f
void
-syms_of_xselect ()
+syms_of_xselect (void)
{
defsubr (&Sx_get_selection_internal);
defsubr (&Sx_own_selection_internal);
\"*selectionTimeout\" resource. */);
x_selection_timeout = 0;
- QPRIMARY = intern ("PRIMARY"); staticpro (&QPRIMARY);
- QSECONDARY = intern ("SECONDARY"); staticpro (&QSECONDARY);
- QSTRING = intern ("STRING"); staticpro (&QSTRING);
- QINTEGER = intern ("INTEGER"); staticpro (&QINTEGER);
- QCLIPBOARD = intern ("CLIPBOARD"); staticpro (&QCLIPBOARD);
- QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP);
- QTEXT = intern ("TEXT"); staticpro (&QTEXT);
- QCOMPOUND_TEXT = intern ("COMPOUND_TEXT"); staticpro (&QCOMPOUND_TEXT);
- QUTF8_STRING = intern ("UTF8_STRING"); staticpro (&QUTF8_STRING);
- QDELETE = intern ("DELETE"); staticpro (&QDELETE);
- QMULTIPLE = intern ("MULTIPLE"); staticpro (&QMULTIPLE);
- QINCR = intern ("INCR"); staticpro (&QINCR);
- QEMACS_TMP = intern ("_EMACS_TMP_"); staticpro (&QEMACS_TMP);
- QTARGETS = intern ("TARGETS"); staticpro (&QTARGETS);
- QATOM = intern ("ATOM"); staticpro (&QATOM);
- QATOM_PAIR = intern ("ATOM_PAIR"); staticpro (&QATOM_PAIR);
- QNULL = intern ("NULL"); staticpro (&QNULL);
- Qcompound_text_with_extensions = intern ("compound-text-with-extensions");
+ QPRIMARY = intern_c_string ("PRIMARY"); staticpro (&QPRIMARY);
+ QSECONDARY = intern_c_string ("SECONDARY"); staticpro (&QSECONDARY);
+ QSTRING = intern_c_string ("STRING"); staticpro (&QSTRING);
+ QINTEGER = intern_c_string ("INTEGER"); staticpro (&QINTEGER);
+ QCLIPBOARD = intern_c_string ("CLIPBOARD"); staticpro (&QCLIPBOARD);
+ QTIMESTAMP = intern_c_string ("TIMESTAMP"); staticpro (&QTIMESTAMP);
+ QTEXT = intern_c_string ("TEXT"); staticpro (&QTEXT);
+ QCOMPOUND_TEXT = intern_c_string ("COMPOUND_TEXT"); staticpro (&QCOMPOUND_TEXT);
+ QUTF8_STRING = intern_c_string ("UTF8_STRING"); staticpro (&QUTF8_STRING);
+ QDELETE = intern_c_string ("DELETE"); staticpro (&QDELETE);
+ QMULTIPLE = intern_c_string ("MULTIPLE"); staticpro (&QMULTIPLE);
+ QINCR = intern_c_string ("INCR"); staticpro (&QINCR);
+ QEMACS_TMP = intern_c_string ("_EMACS_TMP_"); staticpro (&QEMACS_TMP);
+ QTARGETS = intern_c_string ("TARGETS"); staticpro (&QTARGETS);
+ QATOM = intern_c_string ("ATOM"); staticpro (&QATOM);
+ QATOM_PAIR = intern_c_string ("ATOM_PAIR"); staticpro (&QATOM_PAIR);
+ QNULL = intern_c_string ("NULL"); staticpro (&QNULL);
+ Qcompound_text_with_extensions = intern_c_string ("compound-text-with-extensions");
staticpro (&Qcompound_text_with_extensions);
#ifdef CUT_BUFFER_SUPPORT
- QCUT_BUFFER0 = intern ("CUT_BUFFER0"); staticpro (&QCUT_BUFFER0);
- QCUT_BUFFER1 = intern ("CUT_BUFFER1"); staticpro (&QCUT_BUFFER1);
- QCUT_BUFFER2 = intern ("CUT_BUFFER2"); staticpro (&QCUT_BUFFER2);
- QCUT_BUFFER3 = intern ("CUT_BUFFER3"); staticpro (&QCUT_BUFFER3);
- QCUT_BUFFER4 = intern ("CUT_BUFFER4"); staticpro (&QCUT_BUFFER4);
- QCUT_BUFFER5 = intern ("CUT_BUFFER5"); staticpro (&QCUT_BUFFER5);
- QCUT_BUFFER6 = intern ("CUT_BUFFER6"); staticpro (&QCUT_BUFFER6);
- QCUT_BUFFER7 = intern ("CUT_BUFFER7"); staticpro (&QCUT_BUFFER7);
+ QCUT_BUFFER0 = intern_c_string ("CUT_BUFFER0"); staticpro (&QCUT_BUFFER0);
+ QCUT_BUFFER1 = intern_c_string ("CUT_BUFFER1"); staticpro (&QCUT_BUFFER1);
+ QCUT_BUFFER2 = intern_c_string ("CUT_BUFFER2"); staticpro (&QCUT_BUFFER2);
+ QCUT_BUFFER3 = intern_c_string ("CUT_BUFFER3"); staticpro (&QCUT_BUFFER3);
+ QCUT_BUFFER4 = intern_c_string ("CUT_BUFFER4"); staticpro (&QCUT_BUFFER4);
+ QCUT_BUFFER5 = intern_c_string ("CUT_BUFFER5"); staticpro (&QCUT_BUFFER5);
+ QCUT_BUFFER6 = intern_c_string ("CUT_BUFFER6"); staticpro (&QCUT_BUFFER6);
+ QCUT_BUFFER7 = intern_c_string ("CUT_BUFFER7"); staticpro (&QCUT_BUFFER7);
#endif
- Qforeign_selection = intern ("foreign-selection");
+ Qforeign_selection = intern_c_string ("foreign-selection");
staticpro (&Qforeign_selection);
}