aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2006-02-28 14:52:46 +0000
committerChong Yidong2006-02-28 14:52:46 +0000
commitc525d842f8a75a19c870971c176ce7fd50cc21c9 (patch)
tree8dce8420691c4d932c8d9dc6cf602af00d39699e /src
parent29ecdb2212662dd0c73f9338aea8ea8dd0de2df3 (diff)
downloademacs-c525d842f8a75a19c870971c176ce7fd50cc21c9.tar.gz
emacs-c525d842f8a75a19c870971c176ce7fd50cc21c9.zip
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/window.c43
-rw-r--r--src/xselect.c39
3 files changed, 63 insertions, 29 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 79db6d09d0b..faba78efd63 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
12006-02-28 Chong Yidong <cyd@stupidchicken.com>
2
3 * xselect.c (x_catch_errors_unwind): New function.
4 (x_reply_selection_request): Put x_uncatch_errors in an unwind.
5 (Fx_get_atom_name): Call x_uncatch_errors earlier.
6
7 * window.c (Qscroll_up, Qscroll_down): New syms.
8 (window_scroll_pixel_based): Make preserve_y static to avoid
9 getting point stuck when scrolling 1 line.
10
12006-02-26 Chong Yidong <cyd@stupidchicken.com> 112006-02-26 Chong Yidong <cyd@stupidchicken.com>
2 12
3 * xterm.h, xterm.c (x_uncatch_errors): Delete unneccessary 13 * xterm.h, xterm.c (x_uncatch_errors): Delete unneccessary
diff --git a/src/window.c b/src/window.c
index 41eaf78bea0..cd7c1e6a625 100644
--- a/src/window.c
+++ b/src/window.c
@@ -50,6 +50,7 @@ Boston, MA 02110-1301, USA. */
50 50
51 51
52Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; 52Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
53Lisp_Object Qscroll_up, Qscroll_down;
53Lisp_Object Qwindow_size_fixed; 54Lisp_Object Qwindow_size_fixed;
54extern Lisp_Object Qleft_margin, Qright_margin; 55extern Lisp_Object Qleft_margin, Qright_margin;
55 56
@@ -4721,9 +4722,9 @@ window_scroll_pixel_based (window, n, whole, noerror)
4721 struct text_pos start; 4722 struct text_pos start;
4722 Lisp_Object tem; 4723 Lisp_Object tem;
4723 int this_scroll_margin; 4724 int this_scroll_margin;
4724 int preserve_y;
4725 /* True if we fiddled the window vscroll field without really scrolling. */ 4725 /* True if we fiddled the window vscroll field without really scrolling. */
4726 int vscrolled = 0; 4726 int vscrolled = 0;
4727 static int preserve_y = -1;
4727 4728
4728 SET_TEXT_POS_FROM_MARKER (start, w->start); 4729 SET_TEXT_POS_FROM_MARKER (start, w->start);
4729 4730
@@ -4787,9 +4788,18 @@ window_scroll_pixel_based (window, n, whole, noerror)
4787 point in the same window line as it is now, so get that line. */ 4788 point in the same window line as it is now, so get that line. */
4788 if (!NILP (Vscroll_preserve_screen_position)) 4789 if (!NILP (Vscroll_preserve_screen_position))
4789 { 4790 {
4790 start_display (&it, w, start); 4791 /* We preserve the goal pixel coordinate across consecutive
4791 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 4792 calls to scroll-up or scroll-down. This avoids the
4792 preserve_y = it.current_y; 4793 possibility of point becoming "stuck" on a tall line when
4794 scrolling by one line. */
4795 if (preserve_y < 0
4796 || (current_kboard->Vlast_command != Qscroll_up
4797 && current_kboard->Vlast_command != Qscroll_down))
4798 {
4799 start_display (&it, w, start);
4800 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
4801 preserve_y = it.current_y;
4802 }
4793 } 4803 }
4794 else 4804 else
4795 preserve_y = -1; 4805 preserve_y = -1;
@@ -4926,10 +4936,9 @@ window_scroll_pixel_based (window, n, whole, noerror)
4926 { 4936 {
4927 /* If we have a header line, take account of it. 4937 /* If we have a header line, take account of it.
4928 This is necessary because we set it.current_y to 0, above. */ 4938 This is necessary because we set it.current_y to 0, above. */
4929 if (WINDOW_WANTS_HEADER_LINE_P (w)) 4939 move_it_to (&it, -1, -1,
4930 preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w); 4940 preserve_y - (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 ),
4931 4941 -1, MOVE_TO_Y);
4932 move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y);
4933 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 4942 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
4934 } 4943 }
4935 else 4944 else
@@ -4983,15 +4992,9 @@ window_scroll_pixel_based (window, n, whole, noerror)
4983 { 4992 {
4984 SET_TEXT_POS_FROM_MARKER (start, w->start); 4993 SET_TEXT_POS_FROM_MARKER (start, w->start);
4985 start_display (&it, w, start); 4994 start_display (&it, w, start);
4986#if 0 /* It's wrong to subtract this here 4995 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
4987 because we called start_display again 4996 here because we called start_display again and did not
4988 and did not alter it.current_y this time. */ 4997 alter it.current_y this time. */
4989
4990 /* If we have a header line, take account of it. */
4991 if (WINDOW_WANTS_HEADER_LINE_P (w))
4992 preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w);
4993#endif
4994
4995 move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y); 4998 move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y);
4996 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 4999 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
4997 } 5000 }
@@ -6988,6 +6991,12 @@ init_window ()
6988void 6991void
6989syms_of_window () 6992syms_of_window ()
6990{ 6993{
6994 Qscroll_up = intern ("scroll-up");
6995 staticpro (&Qscroll_up);
6996
6997 Qscroll_down = intern ("scroll-down");
6998 staticpro (&Qscroll_down);
6999
6991 Qwindow_size_fixed = intern ("window-size-fixed"); 7000 Qwindow_size_fixed = intern ("window-size-fixed");
6992 staticpro (&Qwindow_size_fixed); 7001 staticpro (&Qwindow_size_fixed);
6993 Fset (Qwindow_size_fixed, Qnil); 7002 Fset (Qwindow_size_fixed, Qnil);
diff --git a/src/xselect.c b/src/xselect.c
index a0b4b091805..30739c74331 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -55,6 +55,7 @@ static void x_decline_selection_request P_ ((struct input_event *));
55static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object)); 55static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object));
56static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object)); 56static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object));
57static Lisp_Object some_frame_on_display P_ ((struct x_display_info *)); 57static Lisp_Object some_frame_on_display P_ ((struct x_display_info *));
58static Lisp_Object x_catch_errors_unwind P_ ((Lisp_Object));
58static void x_reply_selection_request P_ ((struct input_event *, int, 59static void x_reply_selection_request P_ ((struct input_event *, int,
59 unsigned char *, int, Atom)); 60 unsigned char *, int, Atom));
60static int waiting_for_other_props_on_window P_ ((Display *, Window)); 61static int waiting_for_other_props_on_window P_ ((Display *, Window));
@@ -611,6 +612,15 @@ x_selection_request_lisp_error (ignore)
611 x_decline_selection_request (x_selection_current_request); 612 x_decline_selection_request (x_selection_current_request);
612 return Qnil; 613 return Qnil;
613} 614}
615
616static Lisp_Object
617x_catch_errors_unwind (dummy)
618 Lisp_Object dummy;
619{
620 BLOCK_INPUT;
621 x_uncatch_errors ();
622 UNBLOCK_INPUT;
623}
614 624
615 625
616/* This stuff is so that INCR selections are reentrant (that is, so we can 626/* This stuff is so that INCR selections are reentrant (that is, so we can
@@ -703,8 +713,11 @@ x_reply_selection_request (event, format, data, size, type)
703 if (reply.property == None) 713 if (reply.property == None)
704 reply.property = reply.target; 714 reply.property = reply.target;
705 715
706 /* #### XChangeProperty can generate BadAlloc, and we must handle it! */
707 BLOCK_INPUT; 716 BLOCK_INPUT;
717 /* The protected block contains wait_for_property_change, which can
718 run random lisp code (process handlers) or signal. Therefore, we
719 put the x_uncatch_errors call in an unwind. */
720 record_unwind_protect (x_catch_errors_unwind, Qnil);
708 x_catch_errors (display); 721 x_catch_errors (display);
709 722
710#ifdef TRACE_SELECTION 723#ifdef TRACE_SELECTION
@@ -858,9 +871,8 @@ x_reply_selection_request (event, format, data, size, type)
858 UNBLOCK to enter the event loop and get possible errors delivered, 871 UNBLOCK to enter the event loop and get possible errors delivered,
859 and then BLOCK again because x_uncatch_errors requires it. */ 872 and then BLOCK again because x_uncatch_errors requires it. */
860 BLOCK_INPUT; 873 BLOCK_INPUT;
861 874 /* This calls x_uncatch_errors. */
862 unbind_to (count, Qnil); 875 unbind_to (count, Qnil);
863 x_uncatch_errors ();
864 UNBLOCK_INPUT; 876 UNBLOCK_INPUT;
865} 877}
866 878
@@ -1370,7 +1382,7 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1370 Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol); 1382 Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
1371 Atom type_atom; 1383 Atom type_atom;
1372 int secs, usecs; 1384 int secs, usecs;
1373 int count; 1385 int count = SPECPDL_INDEX ();
1374 Lisp_Object frame; 1386 Lisp_Object frame;
1375 1387
1376 if (CONSP (target_type)) 1388 if (CONSP (target_type))
@@ -1392,6 +1404,10 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1392 1404
1393 BLOCK_INPUT; 1405 BLOCK_INPUT;
1394 1406
1407 /* The protected block contains wait_reading_process_output, which
1408 can run random lisp code (process handlers) or signal.
1409 Therefore, we put the x_uncatch_errors call in an unwind. */
1410 record_unwind_protect (x_catch_errors_unwind, Qnil);
1395 x_catch_errors (display); 1411 x_catch_errors (display);
1396 1412
1397 TRACE2 ("Get selection %s, type %s", 1413 TRACE2 ("Get selection %s, type %s",
@@ -1409,8 +1425,6 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1409 1425
1410 frame = some_frame_on_display (dpyinfo); 1426 frame = some_frame_on_display (dpyinfo);
1411 1427
1412 count = SPECPDL_INDEX ();
1413
1414 /* If the display no longer has frames, we can't expect 1428 /* If the display no longer has frames, we can't expect
1415 to get many more selection requests from it, so don't 1429 to get many more selection requests from it, so don't
1416 bother trying to queue them. */ 1430 bother trying to queue them. */
@@ -1432,9 +1446,10 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1432 TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); 1446 TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply)));
1433 1447
1434 BLOCK_INPUT; 1448 BLOCK_INPUT;
1449 if (x_had_errors_p (display))
1450 error ("Cannot get selection");
1451 /* This calls x_uncatch_errors. */
1435 unbind_to (count, Qnil); 1452 unbind_to (count, Qnil);
1436 x_check_errors (display, "Cannot get selection: %s");
1437 x_uncatch_errors ();
1438 UNBLOCK_INPUT; 1453 UNBLOCK_INPUT;
1439 1454
1440 if (NILP (XCAR (reading_selection_reply))) 1455 if (NILP (XCAR (reading_selection_reply)))
@@ -2655,6 +2670,7 @@ If the value is 0 or the atom is not known, return the empty string. */)
2655 Lisp_Object ret = Qnil; 2670 Lisp_Object ret = Qnil;
2656 Display *dpy = FRAME_X_DISPLAY (f); 2671 Display *dpy = FRAME_X_DISPLAY (f);
2657 Atom atom; 2672 Atom atom;
2673 int had_errors;
2658 2674
2659 if (INTEGERP (value)) 2675 if (INTEGERP (value))
2660 atom = (Atom) XUINT (value); 2676 atom = (Atom) XUINT (value);
@@ -2667,14 +2683,13 @@ If the value is 0 or the atom is not known, return the empty string. */)
2667 2683
2668 BLOCK_INPUT; 2684 BLOCK_INPUT;
2669 x_catch_errors (dpy); 2685 x_catch_errors (dpy);
2670
2671 name = atom ? XGetAtomName (dpy, atom) : ""; 2686 name = atom ? XGetAtomName (dpy, atom) : "";
2687 had_errors = x_had_errors_p (dpy);
2688 x_uncatch_errors ();
2672 2689
2673 if (! x_had_errors_p (dpy)) 2690 if (!had_errors)
2674 ret = make_string (name, strlen (name)); 2691 ret = make_string (name, strlen (name));
2675 2692
2676 x_uncatch_errors ();
2677
2678 if (atom && name) XFree (name); 2693 if (atom && name) XFree (name);
2679 if (NILP (ret)) ret = make_string ("", 0); 2694 if (NILP (ret)) ret = make_string ("", 0);
2680 2695