X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d5db40779d7505244d37476b4f046641f07eea2b..3c9dc1cf0d6be64608cd309ad042d74e4fc02049:/src/xselect.c diff --git a/src/xselect.c b/src/xselect.c index 5519eecf64..5fd2c862cb 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1,5 +1,5 @@ /* X Selection processing for Emacs. - Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001 + Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2003 Free Software Foundation. This file is part of GNU Emacs. @@ -40,7 +40,7 @@ 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)); +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)); @@ -96,6 +96,7 @@ Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, QATOM_PAIR; Lisp_Object QCOMPOUND_TEXT; /* This is a type of selection. */ +Lisp_Object QUTF8_STRING; /* This is a type of selection. */ Lisp_Object Qcompound_text_with_extensions; @@ -182,6 +183,7 @@ symbol_to_x_atom (dpyinfo, display, sym) if (EQ (sym, QTIMESTAMP)) return dpyinfo->Xatom_TIMESTAMP; if (EQ (sym, QTEXT)) return dpyinfo->Xatom_TEXT; if (EQ (sym, QCOMPOUND_TEXT)) return dpyinfo->Xatom_COMPOUND_TEXT; + if (EQ (sym, QUTF8_STRING)) return dpyinfo->Xatom_UTF8_STRING; if (EQ (sym, QDELETE)) return dpyinfo->Xatom_DELETE; if (EQ (sym, QMULTIPLE)) return dpyinfo->Xatom_MULTIPLE; if (EQ (sym, QINCR)) return dpyinfo->Xatom_INCR; @@ -264,6 +266,8 @@ x_atom_to_symbol (dpy, atom) return QTEXT; if (atom == dpyinfo->Xatom_COMPOUND_TEXT) return QCOMPOUND_TEXT; + if (atom == dpyinfo->Xatom_UTF8_STRING) + return QUTF8_STRING; if (atom == dpyinfo->Xatom_DELETE) return QDELETE; if (atom == dpyinfo->Xatom_MULTIPLE) @@ -350,14 +354,15 @@ x_own_selection (selection_name, selection_value) /* 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. - This function is used both for remote requests - and for local x-get-selection-internal. + This function is used both for remote requests (LOCAL_REQUEST is zero) + and for local x-get-selection-internal (LOCAL_REQUEST is nonzero). This calls random Lisp code, and may signal or gc. */ static Lisp_Object -x_get_local_selection (selection_symbol, target_type) +x_get_local_selection (selection_symbol, target_type, local_request) Lisp_Object selection_symbol, target_type; + int local_request; { Lisp_Object local_value; Lisp_Object handler_fn, value, type, check; @@ -404,7 +409,8 @@ x_get_local_selection (selection_symbol, target_type) pair = XVECTOR (pairs)->contents [i]; XVECTOR (pair)->contents [1] = x_get_local_selection (XVECTOR (pair)->contents [0], - XVECTOR (pair)->contents [1]); + XVECTOR (pair)->contents [1], + local_request); } return pairs; } @@ -419,9 +425,12 @@ x_get_local_selection (selection_symbol, target_type) CHECK_SYMBOL (target_type); handler_fn = Fcdr (Fassq (target_type, Vselection_converter_alist)); + /* gcpro is not needed here since nothing but HANDLER_FN + is live, and that ought to be a symbol. */ + if (!NILP (handler_fn)) value = call3 (handler_fn, - selection_symbol, target_type, + selection_symbol, (local_request ? Qnil : target_type), XCAR (XCDR (local_value))); else value = Qnil; @@ -723,6 +732,7 @@ x_reply_selection_request (event, format, data, size, type) TRACE0 ("Done sending incrementally"); } + /* rms, 2003-01-03: I think I have fixed this bug. */ /* 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 @@ -801,7 +811,7 @@ x_handle_selection_request (event) /* Convert lisp objects back into binary data */ converted_selection - = x_get_local_selection (selection_symbol, target_symbol); + = x_get_local_selection (selection_symbol, target_symbol, 0); if (! NILP (converted_selection)) { @@ -830,8 +840,6 @@ x_handle_selection_request (event) DONE: - UNGCPRO; - /* Let random lisp code notice that the selection has been asked for. */ { Lisp_Object rest; @@ -840,6 +848,8 @@ x_handle_selection_request (event) for (; CONSP (rest); rest = Fcdr (rest)) call3 (Fcar (rest), selection_symbol, target_symbol, successful_p); } + + UNGCPRO; } /* Handle a SelectionClear event EVENT, which indicates that some @@ -1688,8 +1698,8 @@ selection_data_to_lisp_data (display, data, size, type, format) If the number is > 16 bits, convert it to a cons of integers, 16 bits in each half. */ - else if (format == 32 && size == sizeof (long)) - return long_to_cons (((unsigned long *) data) [0]); + else if (format == 32 && size == sizeof (int)) + return long_to_cons (((unsigned int *) data) [0]); else if (format == 16 && size == sizeof (short)) return make_number ((int) (((unsigned short *) data) [0])); @@ -1714,7 +1724,7 @@ selection_data_to_lisp_data (display, data, size, type, format) Lisp_Object v = Fmake_vector (make_number (size / 4), make_number (0)); for (i = 0; i < size / 4; i++) { - unsigned long j = ((unsigned long *) data) [i]; + unsigned int j = ((unsigned int *) data) [i]; Faset (v, make_number (i), long_to_cons (j)); } return v; @@ -1758,42 +1768,13 @@ lisp_data_to_selection_data (display, obj, } else if (STRINGP (obj)) { - /* Since we are now handling multilingual text, we must consider - sending back compound text. */ - int stringp; - extern Lisp_Object Qcompound_text; - - if (NILP (Vnext_selection_coding_system)) - Vnext_selection_coding_system = Vselection_coding_system; - - *format_ret = 8; - /* If the requested type is STRING, we must encode the selected - text as a string, even if the coding system set by the user - is ctext or its derivatives. */ - if (EQ (type, QSTRING) - && (EQ (Vnext_selection_coding_system, Qcompound_text) - || EQ (Vnext_selection_coding_system, - Qcompound_text_with_extensions))) - { - Lisp_Object unibyte_string; - - unibyte_string = string_make_unibyte (obj); - *data_ret = SDATA (unibyte_string); - *nofree_ret = 1; - *size_ret = SBYTES (unibyte_string); - } - else - { - *data_ret = x_encode_text (obj, Vnext_selection_coding_system, 1, - (int *) size_ret, &stringp); - *nofree_ret = (*data_ret == SDATA (obj)); - } + xassert (! STRING_MULTIBYTE (obj)); if (NILP (type)) - type = (stringp ? QSTRING : QCOMPOUND_TEXT); - Vlast_coding_system_used = (*nofree_ret - ? Qraw_text - : Vnext_selection_coding_system); - Vnext_selection_coding_system = Qnil; + type = QSTRING; + *format_ret = 8; + *size_ret = SBYTES (obj); + *data_ret = SDATA (obj); + *nofree_ret = 1; } else if (SYMBOLP (obj)) { @@ -2025,7 +2006,7 @@ TYPE is the type of data desired, typically `STRING'. */) #endif CHECK_SYMBOL (target_type); - val = x_get_local_selection (selection_symbol, target_type); + val = x_get_local_selection (selection_symbol, target_type, 1); if (NILP (val)) { @@ -2426,8 +2407,8 @@ The default value is `compound-text-with-extensions'. */); DEFVAR_LISP ("next-selection-coding-system", &Vnext_selection_coding_system, doc: /* Coding system for the next communication with other X clients. Usually, `selection-coding-system' is used for communicating with -other X clients. But, if this variable is set, it is used for the -next communication only. After the communication, this variable is +other X clients. But, if this variable is set, it is used for the +next communication only. After the communication, this variable is set to nil. */); Vnext_selection_coding_system = Qnil; @@ -2446,6 +2427,7 @@ A value of 0 means wait as long as necessary. This is initialized from the 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); QTIMESTAMP = intern ("TIMESTAMP"); staticpro (&QTIMESTAMP); QDELETE = intern ("DELETE"); staticpro (&QDELETE); QMULTIPLE = intern ("MULTIPLE"); staticpro (&QMULTIPLE);