/* X Selection processing for Emacs.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1993-1997, 2000-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-#ifdef HAVE_UNISTD_H
+
#include <unistd.h>
-#endif
#include "lisp.h"
#include "xterm.h" /* for all of the X includes */
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 *,
+static Lisp_Object selection_data_to_lisp_data (Display *,
+ const 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. */
#endif
-#define CUT_BUFFER_SUPPORT
-
-Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
+Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP,
QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL,
QATOM_PAIR;
Lisp_Object Qcompound_text_with_extensions;
-#ifdef CUT_BUFFER_SUPPORT
-Lisp_Object QCUT_BUFFER0, QCUT_BUFFER1, QCUT_BUFFER2, QCUT_BUFFER3,
- QCUT_BUFFER4, QCUT_BUFFER5, QCUT_BUFFER6, QCUT_BUFFER7;
-#endif
-
-static Lisp_Object Vx_lost_selection_functions;
-static Lisp_Object Vx_sent_selection_functions;
static Lisp_Object Qforeign_selection;
/* If this is a smaller number than the max-request-size of the display,
selection-values. */
static Lisp_Object Vselection_alist;
-/* This is an alist whose CARs are selection-types (whose names are the same
- as the names of X Atoms) and whose CDRs are the names of Lisp functions to
- call to convert the given Emacs selection value to a string representing
- the given selection type. This is for Lisp-level extension of the emacs
- selection handling. */
-static Lisp_Object Vselection_converter_alist;
-
-/* If the selection owner takes too long to reply to a selection request,
- we give up on it. This is in milliseconds (0 = no timeout.) */
-static EMACS_INT x_selection_timeout;
-
\f
/* Define a queue to save up SELECTION_REQUEST_EVENT events for later
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;
-#ifdef CUT_BUFFER_SUPPORT
- if (EQ (sym, QCUT_BUFFER0)) return XA_CUT_BUFFER0;
- if (EQ (sym, QCUT_BUFFER1)) return XA_CUT_BUFFER1;
- if (EQ (sym, QCUT_BUFFER2)) return XA_CUT_BUFFER2;
- if (EQ (sym, QCUT_BUFFER3)) return XA_CUT_BUFFER3;
- if (EQ (sym, QCUT_BUFFER4)) return XA_CUT_BUFFER4;
- if (EQ (sym, QCUT_BUFFER5)) return XA_CUT_BUFFER5;
- if (EQ (sym, QCUT_BUFFER6)) return XA_CUT_BUFFER6;
- if (EQ (sym, QCUT_BUFFER7)) return XA_CUT_BUFFER7;
-#endif
if (!SYMBOLP (sym)) abort ();
- TRACE1 (" XInternAtom %s", (char *) SDATA (SYMBOL_NAME (sym)));
+ TRACE1 (" XInternAtom %s", SSDATA (SYMBOL_NAME (sym)));
BLOCK_INPUT;
- val = XInternAtom (display, (char *) SDATA (SYMBOL_NAME (sym)), False);
+ val = XInternAtom (display, SSDATA (SYMBOL_NAME (sym)), False);
UNBLOCK_INPUT;
return val;
}
return QINTEGER;
case XA_ATOM:
return QATOM;
-#ifdef CUT_BUFFER_SUPPORT
- case XA_CUT_BUFFER0:
- return QCUT_BUFFER0;
- case XA_CUT_BUFFER1:
- return QCUT_BUFFER1;
- case XA_CUT_BUFFER2:
- return QCUT_BUFFER2;
- case XA_CUT_BUFFER3:
- return QCUT_BUFFER3;
- case XA_CUT_BUFFER4:
- return QCUT_BUFFER4;
- case XA_CUT_BUFFER5:
- return QCUT_BUFFER5;
- case XA_CUT_BUFFER6:
- return QCUT_BUFFER6;
- case XA_CUT_BUFFER7:
- return QCUT_BUFFER7;
-#endif
}
dpyinfo = x_display_info_for_display (dpy);
selecting_window = FRAME_X_WINDOW (sf);
display = FRAME_X_DISPLAY (sf);
dpyinfo = FRAME_X_DISPLAY_INFO (sf);
-
+
CHECK_SYMBOL (selection_name);
selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
Lisp_Object prev_value;
selection_time = long_to_cons ((unsigned long) time);
- selection_data = Fcons (selection_name,
- Fcons (selection_value,
- Fcons (selection_time,
- Fcons (selected_frame, Qnil))));
+ selection_data = list4 (selection_name, selection_value,
+ selection_time, selected_frame);
prev_value = assq_no_quit (selection_name, Vselection_alist);
Vselection_alist = Fcons (selection_data, Vselection_alist);
}
}
UNBLOCK_INPUT;
-
+
selection_symbol = x_atom_to_symbol (display, selection);
local_selection_data = assq_no_quit (selection_symbol, Vselection_alist);
/* Use xfree, not XFree, to free the data obtained with this function. */
static void
-x_get_window_property (display, window, property, data_ret, bytes_ret,
- actual_type_ret, actual_format_ret, actual_size_ret,
- delete_p)
- Display *display;
- Window window;
- Atom property;
- unsigned char **data_ret;
- int *bytes_ret;
- Atom *actual_type_ret;
- int *actual_format_ret;
- unsigned long *actual_size_ret;
- int delete_p;
+x_get_window_property (Display *display, Window window, Atom property,
+ unsigned char **data_ret, int *bytes_ret,
+ Atom *actual_type_ret, int *actual_format_ret,
+ unsigned long *actual_size_ret, int delete_p)
{
int total_size;
unsigned long bytes_remaining;
/* Use xfree, not XFree, to free the data obtained with this function. */
static void
-receive_incremental_selection (display, window, property, target_type,
- min_size_bytes, data_ret, size_bytes_ret,
- type_ret, format_ret, size_ret)
- Display *display;
- Window window;
- Atom property;
- Lisp_Object target_type; /* for error messages only */
- unsigned int min_size_bytes;
- unsigned char **data_ret;
- int *size_bytes_ret;
- Atom *type_ret;
- unsigned long *size_ret;
- int *format_ret;
+receive_incremental_selection (Display *display, Window window, Atom property,
+ Lisp_Object target_type,
+ unsigned int min_size_bytes,
+ unsigned char **data_ret, int *size_bytes_ret,
+ Atom *type_ret, int *format_ret,
+ unsigned long *size_ret)
{
int offset = 0;
struct prop_location *wait_object;
TARGET_TYPE and SELECTION_ATOM are used in error message if this fails. */
static Lisp_Object
-x_get_window_property_as_lisp_data (display, window, property, target_type,
- selection_atom)
- Display *display;
- Window window;
- Atom property;
- Lisp_Object target_type; /* for error messages only */
- Atom selection_atom; /* for error messages only */
+x_get_window_property_as_lisp_data (Display *display, Window window,
+ Atom property,
+ Lisp_Object target_type,
+ Atom selection_atom)
{
Atom actual_type;
int actual_format;
static Lisp_Object
-selection_data_to_lisp_data (Display *display, unsigned char *data, int size, Atom type, int format)
+selection_data_to_lisp_data (Display *display, const unsigned char *data,
+ int size, Atom type, int format)
{
struct x_display_info *dpyinfo = x_display_info_for_display (display);
/* Use xfree, not XFree, to free the data obtained with this function. */
static void
-lisp_data_to_selection_data (display, obj,
- data_ret, type_ret, size_ret,
- format_ret, nofree_ret)
- Display *display;
- Lisp_Object obj;
- unsigned char **data_ret;
- Atom *type_ret;
- unsigned int *size_ret;
- int *format_ret;
- int *nofree_ret;
+lisp_data_to_selection_data (Display *display, Lisp_Object obj,
+ unsigned char **data_ret, Atom *type_ret,
+ unsigned int *size_ret,
+ int *format_ret, int *nofree_ret)
{
Lisp_Object type = Qnil;
struct x_display_info *dpyinfo = x_display_info_for_display (display);
}
\f
-#ifdef CUT_BUFFER_SUPPORT
-
-/* Ensure that all 8 cut buffers exist. ICCCM says we gotta... */
-static void
-initialize_cut_buffers (Display *display, Window window)
-{
- unsigned char *data = (unsigned char *) "";
- BLOCK_INPUT;
-#define FROB(atom) XChangeProperty (display, window, atom, XA_STRING, 8, \
- PropModeAppend, data, 0)
- FROB (XA_CUT_BUFFER0);
- FROB (XA_CUT_BUFFER1);
- FROB (XA_CUT_BUFFER2);
- FROB (XA_CUT_BUFFER3);
- FROB (XA_CUT_BUFFER4);
- FROB (XA_CUT_BUFFER5);
- FROB (XA_CUT_BUFFER6);
- FROB (XA_CUT_BUFFER7);
-#undef FROB
- UNBLOCK_INPUT;
-}
-
-
-#define CHECK_CUT_BUFFER(symbol) \
- do { CHECK_SYMBOL ((symbol)); \
- if (!EQ((symbol), QCUT_BUFFER0) && !EQ((symbol), QCUT_BUFFER1) \
- && !EQ((symbol), QCUT_BUFFER2) && !EQ((symbol), QCUT_BUFFER3) \
- && !EQ((symbol), QCUT_BUFFER4) && !EQ((symbol), QCUT_BUFFER5) \
- && !EQ((symbol), QCUT_BUFFER6) && !EQ((symbol), QCUT_BUFFER7)) \
- signal_error ("Doesn't name a cut buffer", (symbol)); \
- } while (0)
-
-DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
- Sx_get_cut_buffer_internal, 1, 1, 0,
- doc: /* Returns the value of the named cut buffer (typically CUT_BUFFER0). */)
- (Lisp_Object buffer)
-{
- Window window;
- Atom buffer_atom;
- unsigned char *data = NULL;
- int bytes;
- Atom type;
- int format;
- unsigned long size;
- Lisp_Object ret;
- Display *display;
- struct x_display_info *dpyinfo;
- struct frame *sf = SELECTED_FRAME ();
-
- check_x ();
-
- if (! FRAME_X_P (sf))
- return Qnil;
-
- display = FRAME_X_DISPLAY (sf);
- dpyinfo = FRAME_X_DISPLAY_INFO (sf);
- window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
- CHECK_CUT_BUFFER (buffer);
- buffer_atom = symbol_to_x_atom (dpyinfo, display, buffer);
-
- x_get_window_property (display, window, buffer_atom, &data, &bytes,
- &type, &format, &size, 0);
-
- if (!data || !format)
- {
- xfree (data);
- return Qnil;
- }
-
- if (format != 8 || type != XA_STRING)
- signal_error ("Cut buffer doesn't contain 8-bit data",
- list2 (x_atom_to_symbol (display, type),
- make_number (format)));
-
- ret = (bytes ? make_unibyte_string ((char *) data, bytes) : Qnil);
- /* Use xfree, not XFree, because x_get_window_property
- calls xmalloc itself. */
- xfree (data);
- return ret;
-}
-
-
-DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal,
- Sx_store_cut_buffer_internal, 2, 2, 0,
- doc: /* Sets the value of the named cut buffer (typically CUT_BUFFER0). */)
- (Lisp_Object buffer, Lisp_Object string)
-{
- Window window;
- Atom buffer_atom;
- unsigned char *data;
- int bytes;
- int bytes_remaining;
- int max_bytes;
- Display *display;
- struct frame *sf = SELECTED_FRAME ();
-
- check_x ();
-
- if (! FRAME_X_P (sf))
- return Qnil;
-
- display = FRAME_X_DISPLAY (sf);
- window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
-
- max_bytes = SELECTION_QUANTUM (display);
- if (max_bytes > MAX_SELECTION_QUANTUM)
- max_bytes = MAX_SELECTION_QUANTUM;
-
- CHECK_CUT_BUFFER (buffer);
- CHECK_STRING (string);
- buffer_atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (sf),
- display, buffer);
- data = (unsigned char *) SDATA (string);
- bytes = SBYTES (string);
- bytes_remaining = bytes;
-
- if (! FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized)
- {
- initialize_cut_buffers (display, window);
- FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized = 1;
- }
-
- BLOCK_INPUT;
-
- /* Don't mess up with an empty value. */
- if (!bytes_remaining)
- XChangeProperty (display, window, buffer_atom, XA_STRING, 8,
- PropModeReplace, data, 0);
-
- while (bytes_remaining)
- {
- int chunk = (bytes_remaining < max_bytes
- ? bytes_remaining : max_bytes);
- XChangeProperty (display, window, buffer_atom, XA_STRING, 8,
- (bytes_remaining == bytes
- ? PropModeReplace
- : PropModeAppend),
- data, chunk);
- data += chunk;
- bytes_remaining -= chunk;
- }
- UNBLOCK_INPUT;
- return string;
-}
-
-
-DEFUN ("x-rotate-cut-buffers-internal", Fx_rotate_cut_buffers_internal,
- Sx_rotate_cut_buffers_internal, 1, 1, 0,
- doc: /* Rotate the values of the cut buffers by N steps.
-Positive N means shift the values forward, negative means backward. */)
- (Lisp_Object n)
-{
- Window window;
- Atom props[8];
- Display *display;
- struct frame *sf = SELECTED_FRAME ();
-
- check_x ();
-
- if (! FRAME_X_P (sf))
- return Qnil;
-
- display = FRAME_X_DISPLAY (sf);
- window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
- CHECK_NUMBER (n);
- if (XINT (n) == 0)
- return n;
- if (! FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized)
- {
- initialize_cut_buffers (display, window);
- FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized = 1;
- }
-
- props[0] = XA_CUT_BUFFER0;
- props[1] = XA_CUT_BUFFER1;
- props[2] = XA_CUT_BUFFER2;
- props[3] = XA_CUT_BUFFER3;
- props[4] = XA_CUT_BUFFER4;
- props[5] = XA_CUT_BUFFER5;
- props[6] = XA_CUT_BUFFER6;
- props[7] = XA_CUT_BUFFER7;
- BLOCK_INPUT;
- XRotateWindowProperties (display, window, props, 8, XINT (n));
- UNBLOCK_INPUT;
- return n;
-}
-
-#endif
-\f
/***********************************************************************
Drag and drop support
***********************************************************************/
else if (STRINGP (o))
{
BLOCK_INPUT;
- val = (long) XInternAtom (dpy, (char *) SDATA (o), False);
+ val = (long) XInternAtom (dpy, SSDATA (o), False);
UNBLOCK_INPUT;
}
else
Also see comment for selection_data_to_lisp_data above. */
Lisp_Object
-x_property_data_to_lisp (struct frame *f, unsigned char *data, Atom type, int format, long unsigned int size)
+x_property_data_to_lisp (struct frame *f, const 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);
{
struct frame *f = check_x_frame (frame);
char *name = 0;
+ char empty[] = "";
Lisp_Object ret = Qnil;
Display *dpy = FRAME_X_DISPLAY (f);
Atom atom;
BLOCK_INPUT;
x_catch_errors (dpy);
- name = atom ? XGetAtomName (dpy, atom) : "";
+ name = atom ? XGetAtomName (dpy, atom) : empty;
had_errors = x_had_errors_p (dpy);
x_uncatch_errors ();
else if (STRINGP (atom))
{
BLOCK_INPUT;
- x_atom = XInternAtom (FRAME_X_DISPLAY (f), (char *) SDATA (atom), False);
+ x_atom = XInternAtom (FRAME_X_DISPLAY (f), SSDATA (atom), False);
UNBLOCK_INPUT;
}
else
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)
+{
+ 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);
+
+ 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)
{
struct x_display_info *dpyinfo = check_x_display_info (display);
Window wdest;
XEvent event;
- Lisp_Object cons;
- int size;
struct frame *f = check_x_frame (from);
int to_root;
- CHECK_STRING (message_type);
CHECK_NUMBER (format);
CHECK_CONS (values);
}
else if (STRINGP (dest))
{
- if (strcmp (SDATA (dest), "PointerWindow") == 0)
+ if (strcmp (SSDATA (dest), "PointerWindow") == 0)
wdest = PointerWindow;
- else if (strcmp (SDATA (dest), "InputFocus") == 0)
+ else if (strcmp (SSDATA (dest), "InputFocus") == 0)
wdest = InputFocus;
else
error ("DEST as a string must be one of PointerWindow or InputFocus");
if (wdest == 0) wdest = dpyinfo->root_window;
to_root = wdest == dpyinfo->root_window;
- for (cons = values, size = 0; CONSP (cons); cons = XCDR (cons), ++size)
- ;
-
BLOCK_INPUT;
- event.xclient.message_type
- = XInternAtom (dpyinfo->display, SDATA (message_type), False);
+ event.xclient.message_type = message_type;
event.xclient.display = dpyinfo->display;
/* Some clients (metacity for example) expects sending window to be here
}
x_uncatch_errors ();
UNBLOCK_INPUT;
-
- return Qnil;
}
\f
defsubr (&Sx_selection_owner_p);
defsubr (&Sx_selection_exists_p);
-#ifdef CUT_BUFFER_SUPPORT
- defsubr (&Sx_get_cut_buffer_internal);
- defsubr (&Sx_store_cut_buffer_internal);
- defsubr (&Sx_rotate_cut_buffers_internal);
-#endif
-
defsubr (&Sx_get_atom_name);
defsubr (&Sx_send_client_message);
defsubr (&Sx_register_dnd_atom);
Vselection_alist = Qnil;
staticpro (&Vselection_alist);
- DEFVAR_LISP ("selection-converter-alist", &Vselection_converter_alist,
+ DEFVAR_LISP ("selection-converter-alist", Vselection_converter_alist,
doc: /* An alist associating X Windows selection-types with functions.
These functions are called to convert the selection, with three args:
the name of the selection (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
and there is no meaningful selection value. */);
Vselection_converter_alist = Qnil;
- DEFVAR_LISP ("x-lost-selection-functions", &Vx_lost_selection_functions,
+ DEFVAR_LISP ("x-lost-selection-functions", Vx_lost_selection_functions,
doc: /* A list of functions to be called when Emacs loses an X selection.
\(This happens when some other X client makes its own selection
or when a Lisp program explicitly clears the selection.)
\(a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'). */);
Vx_lost_selection_functions = Qnil;
- DEFVAR_LISP ("x-sent-selection-functions", &Vx_sent_selection_functions,
+ DEFVAR_LISP ("x-sent-selection-functions", Vx_sent_selection_functions,
doc: /* A list of functions to be called when Emacs answers a selection request.
The functions are called with four arguments:
- the selection name (typically `PRIMARY', `SECONDARY', or `CLIPBOARD');
it merely informs you that they have happened. */);
Vx_sent_selection_functions = Qnil;
- DEFVAR_INT ("x-selection-timeout", &x_selection_timeout,
+ DEFVAR_INT ("x-selection-timeout", x_selection_timeout,
doc: /* Number of milliseconds to wait for a selection reply.
If the selection owner doesn't reply in this time, we give up.
A value of 0 means wait as long as necessary. This is initialized from the
\"*selectionTimeout\" resource. */);
x_selection_timeout = 0;
- QPRIMARY = intern_c_string ("PRIMARY"); staticpro (&QPRIMARY);
+ /* QPRIMARY is defined in keyboard.c. */
QSECONDARY = intern_c_string ("SECONDARY"); staticpro (&QSECONDARY);
QSTRING = intern_c_string ("STRING"); staticpro (&QSTRING);
QINTEGER = intern_c_string ("INTEGER"); staticpro (&QINTEGER);
Qcompound_text_with_extensions = intern_c_string ("compound-text-with-extensions");
staticpro (&Qcompound_text_with_extensions);
-#ifdef CUT_BUFFER_SUPPORT
- 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_c_string ("foreign-selection");
staticpro (&Qforeign_selection);
}
-
-/* arch-tag: 7c293b0f-9918-4f69-8ac7-03e142307236
- (do not change this comment) */