Mercurial > emacs
diff src/xselect.c @ 69209:b9ad41f39bf6
* xselect.c (x_catch_errors_unwind): New function.
(x_reply_selection_request): Put x_uncatch_errors in an unwind.
(Fx_get_atom_name): Call x_uncatch_errors earlier.
* window.c (Qscroll_up, Qscroll_down): New syms.
(window_scroll_pixel_based): Make preserve_y static to avoid
getting point stuck when scrolling 1 line.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Tue, 28 Feb 2006 14:52:46 +0000 |
parents | fdee8318ddc9 |
children | a072ac3cca3f a380ca43a190 5754737d1e04 |
line wrap: on
line diff
--- a/src/xselect.c Tue Feb 28 14:28:42 2006 +0000 +++ b/src/xselect.c Tue Feb 28 14:52:46 2006 +0000 @@ -55,6 +55,7 @@ static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object)); static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object)); static Lisp_Object some_frame_on_display P_ ((struct x_display_info *)); +static Lisp_Object x_catch_errors_unwind P_ ((Lisp_Object)); static void x_reply_selection_request P_ ((struct input_event *, int, unsigned char *, int, Atom)); static int waiting_for_other_props_on_window P_ ((Display *, Window)); @@ -611,6 +612,15 @@ x_decline_selection_request (x_selection_current_request); return Qnil; } + +static Lisp_Object +x_catch_errors_unwind (dummy) + Lisp_Object dummy; +{ + BLOCK_INPUT; + x_uncatch_errors (); + UNBLOCK_INPUT; +} /* This stuff is so that INCR selections are reentrant (that is, so we can @@ -703,8 +713,11 @@ if (reply.property == None) reply.property = reply.target; - /* #### XChangeProperty can generate BadAlloc, and we must handle it! */ BLOCK_INPUT; + /* 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); x_catch_errors (display); #ifdef TRACE_SELECTION @@ -858,9 +871,8 @@ UNBLOCK to enter the event loop and get possible errors delivered, and then BLOCK again because x_uncatch_errors requires it. */ BLOCK_INPUT; - + /* This calls x_uncatch_errors. */ unbind_to (count, Qnil); - x_uncatch_errors (); UNBLOCK_INPUT; } @@ -1370,7 +1382,7 @@ Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol); Atom type_atom; int secs, usecs; - int count; + int count = SPECPDL_INDEX (); Lisp_Object frame; if (CONSP (target_type)) @@ -1392,6 +1404,10 @@ BLOCK_INPUT; + /* The protected block contains wait_reading_process_output, 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); x_catch_errors (display); TRACE2 ("Get selection %s, type %s", @@ -1409,8 +1425,6 @@ frame = some_frame_on_display (dpyinfo); - count = SPECPDL_INDEX (); - /* If the display no longer has frames, we can't expect to get many more selection requests from it, so don't bother trying to queue them. */ @@ -1432,9 +1446,10 @@ TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); BLOCK_INPUT; + if (x_had_errors_p (display)) + error ("Cannot get selection"); + /* This calls x_uncatch_errors. */ unbind_to (count, Qnil); - x_check_errors (display, "Cannot get selection: %s"); - x_uncatch_errors (); UNBLOCK_INPUT; if (NILP (XCAR (reading_selection_reply))) @@ -2655,6 +2670,7 @@ Lisp_Object ret = Qnil; Display *dpy = FRAME_X_DISPLAY (f); Atom atom; + int had_errors; if (INTEGERP (value)) atom = (Atom) XUINT (value); @@ -2667,14 +2683,13 @@ BLOCK_INPUT; x_catch_errors (dpy); - name = atom ? XGetAtomName (dpy, atom) : ""; - - if (! x_had_errors_p (dpy)) + had_errors = x_had_errors_p (dpy); + x_uncatch_errors (); + + if (!had_errors) ret = make_string (name, strlen (name)); - x_uncatch_errors (); - if (atom && name) XFree (name); if (NILP (ret)) ret = make_string ("", 0);