X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/d31b6237e91336d5aca7bb0b4f4129ac1d83121a..645280b72c54063bedc239469f013dd1749f689d:/src/xselect.c diff --git a/src/xselect.c b/src/xselect.c index b7360a1038..053d7f0fa3 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -1,5 +1,5 @@ /* X Selection processing for Emacs. - Copyright (C) 1993, 1994, 1995 Free Software Foundation. + Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation. This file is part of GNU Emacs. @@ -15,7 +15,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Rewritten by jwz */ @@ -27,8 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "frame.h" /* Need this to get the X window of selected_frame */ #include "blockinput.h" -#define xfree free - #define CUT_BUFFER_SUPPORT Lisp_Object QPRIMARY, QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, @@ -58,7 +57,8 @@ static Lisp_Object Vx_sent_selection_hooks; #endif /* The timestamp of the last input event Emacs received from the X server. */ -unsigned long last_event_timestamp; +/* Defined in keyboard.c. */ +extern unsigned long last_event_timestamp; /* This is an association list whose elements are of the form ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME) @@ -210,6 +210,7 @@ x_atom_to_symbol (dpyinfo, display, atom) if (! str) return Qnil; val = intern (str); BLOCK_INPUT; + /* This was allocated by Xlib, so use XFree. */ XFree (str); UNBLOCK_INPUT; return val; @@ -412,7 +413,7 @@ x_decline_selection_request (event) static struct input_event *x_selection_current_request; /* Used as an unwind-protect clause so that, if a selection-converter signals - an error, we tell the requestor that we were unable to do what they wanted + an error, we tell the requester 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 @@ -558,7 +559,7 @@ x_reply_selection_request (event, format, data, size, type) } if (x_window_to_frame (dpyinfo, window)) /* #### debug */ - error ("attempt to transfer an INCR to ourself!"); + error ("Attempt to transfer an INCR to ourself!"); #if 0 fprintf (stderr, "\nINCR %d\n", bytes_remaining); #endif @@ -576,7 +577,7 @@ x_reply_selection_request (event, format, data, size, type) had_errors = x_had_errors_p (display); UNBLOCK_INPUT; - /* First, wait for the requestor to ack by deleting the property. + /* First, wait for the requester to ack by deleting the property. This can run random lisp code (process handlers) or signal. */ if (! had_errors) wait_for_property_change (wait_object); @@ -607,12 +608,12 @@ x_reply_selection_request (event, format, data, size, type) if (had_errors) break; - /* Now wait for the requestor to ack this chunk by deleting the + /* Now wait for the requester to ack this chunk by deleting the property. This can run random lisp code or signal. */ wait_for_property_change (wait_object); } - /* Now write a zero-length chunk to the property to tell the requestor + /* Now write a zero-length chunk to the property to tell the requester that we're done. */ #if 0 fprintf (stderr," INCR done\n"); @@ -719,8 +720,10 @@ x_handle_selection_request (event) /* Indicate we have successfully processed this event. */ x_selection_current_request = 0; + /* Use free, not XFree, because lisp_data_to_selection_data + calls xmalloc itself. */ if (!nofree) - xfree (data); + free (data); } unbind_to (count, Qnil); @@ -832,7 +835,11 @@ x_clear_frame_selections (f) { for (; CONSP (hooks); hooks = Fcdr (hooks)) call1 (Fcar (hooks), selection_symbol); +#if 0 /* This can crash when deleting a frame + from x_connection_closed. Anyway, it seems unnecessary; + something else should cause a redisplay. */ redisplay_preserve_echo_area (); +#endif } Vselection_alist = Fcdr (Vselection_alist); @@ -852,7 +859,9 @@ x_clear_frame_selections (f) { for (; CONSP (hooks); hooks = Fcdr (hooks)) call1 (Fcar (hooks), selection_symbol); +#if 0 /* See above */ redisplay_preserve_echo_area (); +#endif } XCONS (rest)->cdr = Fcdr (XCONS (rest)->cdr); break; @@ -917,7 +926,7 @@ unexpect_property_change (location) prev->next = rest->next; else property_change_wait_list = rest->next; - xfree (rest); + free (rest); return; } prev = rest; @@ -967,7 +976,7 @@ wait_for_property_change (location) wait_reading_process_input (secs, usecs, property_change_reply, 0); if (NILP (XCONS (property_change_reply)->car)) - error ("timed out waiting for property-notify event"); + error ("Timed out waiting for property-notify event"); } unbind_to (count, Qnil); @@ -1006,7 +1015,7 @@ x_handle_property_notify (event) prev->next = rest->next; else property_change_wait_list = rest->next; - xfree (rest); + free (rest); return; } prev = rest; @@ -1138,7 +1147,9 @@ x_get_foreign_selection (selection_symbol, target_type) UNBLOCK_INPUT; if (NILP (XCONS (reading_selection_reply)->car)) - error ("timed out waiting for reply from selection owner"); + error ("Timed out waiting for reply from selection owner"); + if (EQ (XCONS (reading_selection_reply)->car, Qlambda)) + error ("No `%s' selection", XSYMBOL (selection_symbol)->name->data); /* Otherwise, the selection is waiting for us on the requested property. */ return @@ -1149,6 +1160,8 @@ x_get_foreign_selection (selection_symbol, target_type) /* Subroutines of x_get_window_property_as_lisp_data */ +/* Use free, 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, @@ -1185,7 +1198,8 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, *bytes_ret = 0; return; } - xfree ((char *) tmp_data); + /* This was allocated by Xlib, so use XFree. */ + XFree ((char *) tmp_data); if (*actual_type_ret == None || *actual_format_ret == 0) { @@ -1196,7 +1210,7 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, total_size = bytes_remaining + 1; *data_ret = (unsigned char *) xmalloc (total_size); - /* Now read, until weve gotten it all. */ + /* Now read, until we've gotten it all. */ while (bytes_remaining) { #if 0 @@ -1220,7 +1234,8 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, *actual_size_ret *= *actual_format_ret / 8; bcopy (tmp_data, (*data_ret) + offset, *actual_size_ret); offset += *actual_size_ret; - xfree ((char *) tmp_data); + /* This was allocated by Xlib, so use XFree. */ + XFree ((char *) tmp_data); } XFlush (display); @@ -1228,6 +1243,8 @@ x_get_window_property (display, window, property, data_ret, bytes_ret, *bytes_ret = offset; } +/* Use free, 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, @@ -1273,7 +1290,7 @@ receive_incremental_selection (display, window, property, target_type, int tmp_size_bytes; wait_for_property_change (wait_object); /* expect it again immediately, because x_get_window_property may - .. no it wont, I dont get it. + .. no it won't, I don't get it. .. Ok, I get it now, the Xt code that implements INCR is broken. */ x_get_window_property (display, window, property, @@ -1288,7 +1305,9 @@ receive_incremental_selection (display, window, property, target_type, if (! waiting_for_other_props_on_window (display, window)) XSelectInput (display, window, STANDARD_EVENT_SET); unexpect_property_change (wait_object); - if (tmp_data) xfree (tmp_data); + /* Use free, not XFree, because x_get_window_property + calls xmalloc itself. */ + if (tmp_data) free (tmp_data); break; } @@ -1313,7 +1332,9 @@ receive_incremental_selection (display, window, property, target_type, } bcopy (tmp_data, (*data_ret) + offset, tmp_size_bytes); offset += tmp_size_bytes; - xfree (tmp_data); + /* Use free, not XFree, because x_get_window_property + calls xmalloc itself. */ + free (tmp_data); } } @@ -1369,7 +1390,9 @@ x_get_window_property_as_lisp_data (display, window, property, target_type, unsigned int min_size_bytes = * ((unsigned int *) data); BLOCK_INPUT; - XFree ((char *) data); + /* Use free, not XFree, because x_get_window_property + calls xmalloc itself. */ + free ((char *) data); UNBLOCK_INPUT; receive_incremental_selection (display, window, property, target_type, min_size_bytes, &data, &bytes, @@ -1387,7 +1410,9 @@ x_get_window_property_as_lisp_data (display, window, property, target_type, val = selection_data_to_lisp_data (display, data, bytes, actual_type, actual_format); - xfree ((char *) data); + /* Use free, not XFree, because x_get_window_property + calls xmalloc itself. */ + free ((char *) data); return val; } @@ -1489,6 +1514,8 @@ selection_data_to_lisp_data (display, data, size, type, format) } +/* Use free, 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, @@ -1691,7 +1718,9 @@ clean_local_selection_data (obj) } /* Called from XTread_socket to handle SelectionNotify events. - If it's the selection we are waiting for, stop waiting. */ + If it's the selection we are waiting for, stop waiting + by setting the car of reading_selection_reply to non-nil. + We store t there if the reply is successful, lambda if not. */ void x_handle_selection_notify (event) @@ -1702,7 +1731,8 @@ x_handle_selection_notify (event) if (event->selection != reading_which_selection) return; - XCONS (reading_selection_reply)->car = Qt; + XCONS (reading_selection_reply)->car + = (event->property != 0 ? Qt : Qlambda); } @@ -1719,7 +1749,7 @@ anything that the functions on `selection-converter-alist' know about.") { check_x (); CHECK_SYMBOL (selection_name, 0); - if (NILP (selection_value)) error ("selection-value may not be nil."); + if (NILP (selection_value)) error ("selection-value may not be nil"); x_own_selection (selection_name, selection_value); return selection_value; } @@ -1971,7 +2001,9 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal, Fcons (make_number (format), Qnil)))); ret = (bytes ? make_string ((char *) data, bytes) : Qnil); - xfree (data); + /* Use free, not XFree, because x_get_window_property + calls xmalloc itself. */ + free (data); return ret; } @@ -2142,7 +2174,7 @@ it merely informs you that they have happened."); DEFVAR_INT ("x-selection-timeout", &x_selection_timeout, "Number of milliseconds to wait for a selection reply.\n\ -If the selection owner doens't reply in this time, we give up.\n\ +If the selection owner doesn't reply in this time, we give up.\n\ A value of 0 means wait as long as necessary. This is initialized from the\n\ \"*selectionTimeout\" resource."); x_selection_timeout = 0;