/* X Selection processing for Emacs.
- Copyright (C) 1993-1997, 2000-2012 Free Software Foundation, Inc.
+ Copyright (C) 1993-1997, 2000-2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
struct prop_location;
struct selection_data;
-static Lisp_Object x_atom_to_symbol (Display *dpy, Atom atom);
-static Atom symbol_to_x_atom (struct x_display_info *, Lisp_Object);
-static void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object);
-static Lisp_Object x_get_local_selection (Lisp_Object, Lisp_Object, int,
- struct x_display_info *);
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 x_catch_errors_unwind (Lisp_Object);
-static void x_reply_selection_request (struct input_event *, struct x_display_info *);
static int x_convert_selection (struct input_event *, Lisp_Object, Lisp_Object,
Atom, int, struct x_display_info *);
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, Lisp_Object);
static Lisp_Object x_get_window_property_as_lisp_data (Display *,
Window, Atom,
Lisp_Object, Atom);
static void lisp_data_to_selection_data (Display *, Lisp_Object,
unsigned char **, Atom *,
ptrdiff_t *, int *, int *);
-static Lisp_Object clean_local_selection_data (Lisp_Object);
/* Printing traces to stderr. */
{
struct frame *f = XFRAME (frame);
Window selecting_window = FRAME_X_WINDOW (f);
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
Display *display = dpyinfo->display;
Time timestamp = last_event_timestamp;
Atom selection_atom = symbol_to_x_atom (dpyinfo, selection_name);
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
-x_selection_request_lisp_error (Lisp_Object ignore)
+static void
+x_selection_request_lisp_error (void)
{
struct selection_data *cs, *next;
if (x_selection_current_request != 0
&& selection_request_dpyinfo->display)
x_decline_selection_request (x_selection_current_request);
- return Qnil;
}
-static Lisp_Object
-x_catch_errors_unwind (Lisp_Object dummy)
+static void
+x_catch_errors_unwind (void)
{
block_input ();
x_uncatch_errors ();
unblock_input ();
- return Qnil;
}
\f
struct prop_location *next;
};
-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 Lisp_Object property_change_reply;
static struct prop_location *property_change_wait_list;
-static Lisp_Object
-queue_selection_requests_unwind (Lisp_Object tem)
-{
- x_stop_queuing_selection_requests ();
- return Qnil;
-}
-
\f
/* Send the reply to a selection request event EVENT. */
/* The protected block contains wait_for_property_change, which can
run random lisp code (process handlers) or signal. Therefore, we
put the x_uncatch_errors call in an unwind. */
- record_unwind_protect (x_catch_errors_unwind, Qnil);
+ record_unwind_protect_void (x_catch_errors_unwind);
x_catch_errors (display);
/* Loop over converted selections, storing them in the requested
if (cs->wait_object)
{
int format_bytes = cs->format / 8;
- int had_errors = x_had_errors_p (display);
+ bool had_errors_p = x_had_errors_p (display);
unblock_input ();
bytes_remaining = cs->size;
/* Wait for the requestor to ack by deleting the property.
This can run Lisp code (process handlers) or signal. */
- if (! had_errors)
+ if (! had_errors_p)
{
TRACE1 ("Waiting for ACK (deletion of %s)",
XGetAtomName (display, cs->property));
cs->data += i * ((cs->format == 32) ? sizeof (long)
: format_bytes);
XFlush (display);
- had_errors = x_had_errors_p (display);
+ had_errors_p = x_had_errors_p (display);
unblock_input ();
- if (had_errors) break;
+ if (had_errors_p) break;
/* Wait for the requestor to ack this chunk by deleting
the property. This can run Lisp code or signal. */
x_selection_current_request = event;
selection_request_dpyinfo = dpyinfo;
- record_unwind_protect (x_selection_request_lisp_error, Qnil);
+ record_unwind_protect_void (x_selection_request_lisp_error);
/* We might be able to handle nested x_handle_selection_requests,
but this is difficult to test, and seems unimportant. */
x_start_queuing_selection_requests ();
- record_unwind_protect (queue_selection_requests_unwind, Qnil);
+ record_unwind_protect_void (x_stop_queuing_selection_requests);
TRACE2 ("x_handle_selection_request: selection=%s, target=%s",
SDATA (SYMBOL_NAME (selection_symbol)),
We do this when about to delete a frame. */
void
-x_clear_frame_selections (FRAME_PTR f)
+x_clear_frame_selections (struct frame *f)
{
Lisp_Object frame;
Lisp_Object rest;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
struct terminal *t = dpyinfo->terminal;
XSETFRAME (frame, f);
/* Remove the property change expectation element for IDENTIFIER. */
-static Lisp_Object
-wait_for_property_change_unwind (Lisp_Object loc)
+static void
+wait_for_property_change_unwind (void *loc)
{
- struct prop_location *location = XSAVE_VALUE (loc)->pointer;
+ struct prop_location *location = loc;
unexpect_property_change (location);
if (location == property_change_reply_object)
property_change_reply_object = 0;
- return Qnil;
}
/* Actually wait for a property change.
emacs_abort ();
/* Make sure to do unexpect_property_change if we quit or err. */
- record_unwind_protect (wait_for_property_change_unwind,
- make_save_value (location, 0));
+ record_unwind_protect_ptr (wait_for_property_change_unwind, location);
XSETCAR (property_change_reply, Qnil);
property_change_reply_object = location;
/* Called from XTread_socket in response to a PropertyNotify event. */
void
-x_handle_property_notify (XPropertyEvent *event)
+x_handle_property_notify (const XPropertyEvent *event)
{
struct prop_location *rest;
Lisp_Object time_stamp, Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
Display *display = dpyinfo->display;
Window requestor_window = FRAME_X_WINDOW (f);
Time requestor_time = last_event_timestamp;
SelectionNotify. */
#if 0
x_start_queuing_selection_requests ();
- record_unwind_protect (queue_selection_requests_unwind, Qnil);
+ record_unwind_protect_void (x_stop_queuing_selection_requests);
#endif
unblock_input ();
data = data1;
}
- if (32 < BITS_PER_LONG && *actual_format_ret == 32)
+ if (BITS_PER_LONG > 32 && *actual_format_ret == 32)
{
unsigned long i;
int *idata = (int *) (data + offset);
return x_atom_to_symbol (display, (Atom) idata[0]);
else
{
- Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)),
- make_number (0));
+ Lisp_Object v = make_uninit_vector (size / sizeof (int));
+
for (i = 0; i < size / sizeof (int); i++)
- Faset (v, make_number (i),
- x_atom_to_symbol (display, (Atom) idata[i]));
+ ASET (v, i, x_atom_to_symbol (display, (Atom) idata[i]));
return v;
}
}
else if (format == 16)
{
ptrdiff_t i;
- Lisp_Object v;
- v = Fmake_vector (make_number (size / 2), make_number (0));
+ Lisp_Object v = make_uninit_vector (size / 2);
+
for (i = 0; i < size / 2; i++)
{
short j = ((short *) data) [i];
- Faset (v, make_number (i), make_number (j));
+ ASET (v, i, make_number (j));
}
return v;
}
else
{
ptrdiff_t i;
- Lisp_Object v = Fmake_vector (make_number (size / X_LONG_SIZE),
- make_number (0));
+ Lisp_Object v = make_uninit_vector (size / X_LONG_SIZE);
+
for (i = 0; i < size / X_LONG_SIZE; i++)
{
int j = ((int *) data) [i];
- Faset (v, make_number (i), INTEGER_TO_CONS (j));
+ ASET (v, i, INTEGER_TO_CONS (j));
}
return v;
}
Lisp_Object copy;
if (size == 1)
return clean_local_selection_data (AREF (obj, 0));
- copy = Fmake_vector (make_number (size), Qnil);
+ copy = make_uninit_vector (size);
for (i = 0; i < size; i++)
ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
return copy;
We store t there if the reply is successful, lambda if not. */
void
-x_handle_selection_notify (XSelectionEvent *event)
+x_handle_selection_notify (const XSelectionEvent *event)
{
if (event->requestor != reading_selection_window)
return;
error ("X selection unavailable for this frame");
val = x_get_local_selection (selection_symbol, target_type, 1,
- FRAME_X_DISPLAY_INFO (f));
+ FRAME_DISPLAY_INFO (f));
if (NILP (val) && FRAME_LIVE_P (f))
{
if (!f)
return Qnil;
- dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
CHECK_SYMBOL (selection);
/* Don't disown the selection when we're not the owner. */
if (EQ (selection, Qnil)) selection = QPRIMARY;
if (EQ (selection, Qt)) selection = QSECONDARY;
- if (f && !NILP (LOCAL_SELECTION (selection, FRAME_X_DISPLAY_INFO (f))))
+ if (f && !NILP (LOCAL_SELECTION (selection, FRAME_DISPLAY_INFO (f))))
return Qt;
else
return Qnil;
if (!f)
return Qnil;
- dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ dpyinfo = FRAME_DISPLAY_INFO (f);
if (!NILP (LOCAL_SELECTION (selection, dpyinfo)))
return Qt;
x_clipboard_manager_save (Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
Atom data = dpyinfo->Xatom_UTF8_STRING;
XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
&& (f = XFRAME (frame), FRAME_X_P (f))
&& FRAME_LIVE_P (f))
{
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
Lisp_Object local_selection
= LOCAL_SELECTION (QCLIPBOARD, dpyinfo);
/* Get the mouse position in frame relative coordinates. */
static void
-mouse_position_for_drop (FRAME_PTR f, int *x, int *y)
+mouse_position_for_drop (struct frame *f, int *x, int *y)
{
Window root, dummy_window;
int dummy;
If the value is 0 or the atom is not known, return the empty string. */)
(Lisp_Object value, Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
char *name = 0;
char empty[] = "";
Lisp_Object ret = Qnil;
Display *dpy = FRAME_X_DISPLAY (f);
Atom atom;
- int had_errors;
+ bool had_errors_p;
CONS_TO_INTEGER (value, Atom, atom);
block_input ();
x_catch_errors (dpy);
name = atom ? XGetAtomName (dpy, atom) : empty;
- had_errors = x_had_errors_p (dpy);
+ had_errors_p = x_had_errors_p (dpy);
x_uncatch_errors ();
- if (!had_errors)
+ if (!had_errors_p)
ret = build_string (name);
if (atom && name) XFree (name);
(Lisp_Object atom, Lisp_Object frame)
{
Atom x_atom;
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
ptrdiff_t i;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
if (SYMBOLP (atom))
/* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT. */
int
-x_handle_dnd_message (struct frame *f, XClientMessageEvent *event,
+x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
struct x_display_info *dpyinfo, struct input_event *bufp)
{
Lisp_Object vec;
function expects them to be of size int (i.e. 32). So to be able to
use that function, put the data in the form it expects if format is 32. */
- if (32 < BITS_PER_LONG && event->format == 32)
+ if (BITS_PER_LONG > 32 && event->format == 32)
{
for (i = 0; i < 5; ++i) /* There are only 5 longs in a ClientMessage. */
idata[i] = event->data.l[i];
return 1;
}
-DEFUN ("x-send-client-message", Fx_send_client_event,
+DEFUN ("x-send-client-message", Fx_send_client_message,
Sx_send_client_message, 6, 6, 0,
doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
struct x_display_info *dpyinfo = check_x_display_info (display);
Window wdest;
XEvent event;
- struct frame *f = check_x_frame (from);
+ struct frame *f = decode_window_system_frame (from);
int to_root;
CHECK_NUMBER (format);
if (FRAMEP (dest) || NILP (dest))
{
- struct frame *fdest = check_x_frame (dest);
+ struct frame *fdest = decode_window_system_frame (dest);
wdest = FRAME_OUTER_WINDOW (fdest);
}
else if (STRINGP (dest))
block_input ();
+ event.xclient.send_event = True;
+ event.xclient.serial = 0;
event.xclient.message_type = message_type;
event.xclient.display = dpyinfo->display;
when sending to the root window. */
event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
-
- memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
+ memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
event.xclient.format);
/* If event mask is 0 the event is sent to the client that created
the destination window. But if we are sending to the root window,
- there is no such client. Then we set the event mask to 0xffff. The
+ there is no such client. Then we set the event mask to 0xffffff. The
event then goes to clients selecting for events on the root window. */
x_catch_errors (dpyinfo->display);
{
int propagate = to_root ? False : True;
- unsigned mask = to_root ? 0xffff : 0;
+ long mask = to_root ? 0xffffff : 0;
+
XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
XFlush (dpyinfo->display);
}