/* 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.
#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>
#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
#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
}
}
- 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. */
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
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. */
\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).
{
Lisp_Object local_value;
Lisp_Object handler_fn, value, check;
- int count;
local_value = LOCAL_SELECTION (selection_symbol, dpyinfo);
/* 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);
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
#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);
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;
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)
{
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));
}
/* 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);
/* 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
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;
{
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;
}
/* 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;
break;
}
}
- dpyinfo->terminal->Vselection_alist = Vselection_alist;
+ tset_selection_alist (dpyinfo->terminal, Vselection_alist);
/* Run the `x-lost-selection-functions' abnormal hook. */
{
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. */
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;
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 ();
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)))
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;
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)));
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;
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
offset += bytes_gotten;
/* This was allocated by Xlib, so use XFree. */
- XFree ((char *) tmp_data);
+ XFree (tmp_data);
}
XFlush (display);
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);
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,
/* Use xfree, not XFree, because x_get_window_property
calls xmalloc itself. */
- xfree ((char *) data);
+ xfree (data);
return val;
}
\f
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.)
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;
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. */
}
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)
|| (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))
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));
}
}
}
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;
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;
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)
{
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;
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);
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;
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);
+ }
}
}
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.
/* 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;
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;
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);