Mercurial > emacs
comparison 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 |
comparison
equal
deleted
inserted
replaced
69208:658f0dc9c1dc | 69209:b9ad41f39bf6 |
---|---|
53 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); | 53 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); |
54 static void x_decline_selection_request P_ ((struct input_event *)); | 54 static void x_decline_selection_request P_ ((struct input_event *)); |
55 static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object)); | 55 static Lisp_Object x_selection_request_lisp_error P_ ((Lisp_Object)); |
56 static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object)); | 56 static Lisp_Object queue_selection_requests_unwind P_ ((Lisp_Object)); |
57 static Lisp_Object some_frame_on_display P_ ((struct x_display_info *)); | 57 static Lisp_Object some_frame_on_display P_ ((struct x_display_info *)); |
58 static Lisp_Object x_catch_errors_unwind P_ ((Lisp_Object)); | |
58 static void x_reply_selection_request P_ ((struct input_event *, int, | 59 static void x_reply_selection_request P_ ((struct input_event *, int, |
59 unsigned char *, int, Atom)); | 60 unsigned char *, int, Atom)); |
60 static int waiting_for_other_props_on_window P_ ((Display *, Window)); | 61 static int waiting_for_other_props_on_window P_ ((Display *, Window)); |
61 static struct prop_location *expect_property_change P_ ((Display *, Window, | 62 static struct prop_location *expect_property_change P_ ((Display *, Window, |
62 Atom, int)); | 63 Atom, int)); |
609 if (x_selection_current_request != 0 | 610 if (x_selection_current_request != 0 |
610 && selection_request_dpyinfo->display) | 611 && selection_request_dpyinfo->display) |
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 | |
616 static Lisp_Object | |
617 x_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 |
617 be servicing multiple INCR selection requests simultaneously.) I haven't | 627 be servicing multiple INCR selection requests simultaneously.) I haven't |
618 actually tested that yet. */ | 628 actually tested that yet. */ |
701 reply.target = SELECTION_EVENT_TARGET (event); | 711 reply.target = SELECTION_EVENT_TARGET (event); |
702 reply.property = SELECTION_EVENT_PROPERTY (event); | 712 reply.property = SELECTION_EVENT_PROPERTY (event); |
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 |
711 { | 724 { |
712 static int cnt; | 725 static int cnt; |
856 | 869 |
857 /* GTK queues events in addition to the queue in Xlib. So we | 870 /* GTK queues events in addition to the queue in Xlib. So we |
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 |
867 /* Handle a SelectionRequest event EVENT. | 879 /* Handle a SelectionRequest event EVENT. |
868 This is called from keyboard.c when such an event is found in the queue. */ | 880 This is called from keyboard.c when such an event is found in the queue. */ |
1368 Time requestor_time = last_event_timestamp; | 1380 Time requestor_time = last_event_timestamp; |
1369 Atom target_property = dpyinfo->Xatom_EMACS_TMP; | 1381 Atom target_property = dpyinfo->Xatom_EMACS_TMP; |
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)) |
1377 type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type)); | 1389 type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type)); |
1378 else | 1390 else |
1390 error ("TIME_STAMP must be cons or number"); | 1402 error ("TIME_STAMP must be cons or number"); |
1391 } | 1403 } |
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", |
1398 XGetAtomName (display, type_atom), | 1414 XGetAtomName (display, type_atom), |
1399 XGetAtomName (display, target_property)); | 1415 XGetAtomName (display, target_property)); |
1406 reading_selection_window = requestor_window; | 1422 reading_selection_window = requestor_window; |
1407 reading_which_selection = selection_atom; | 1423 reading_which_selection = selection_atom; |
1408 XSETCAR (reading_selection_reply, Qnil); | 1424 XSETCAR (reading_selection_reply, Qnil); |
1409 | 1425 |
1410 frame = some_frame_on_display (dpyinfo); | 1426 frame = some_frame_on_display (dpyinfo); |
1411 | |
1412 count = SPECPDL_INDEX (); | |
1413 | 1427 |
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. */ |
1417 if (!NILP (frame)) | 1431 if (!NILP (frame)) |
1430 wait_reading_process_output (secs, usecs, 0, 0, | 1444 wait_reading_process_output (secs, usecs, 0, 0, |
1431 reading_selection_reply, NULL, 0); | 1445 reading_selection_reply, NULL, 0); |
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))) |
1441 error ("Timed out waiting for reply from selection owner"); | 1456 error ("Timed out waiting for reply from selection owner"); |
1442 if (EQ (XCAR (reading_selection_reply), Qlambda)) | 1457 if (EQ (XCAR (reading_selection_reply), Qlambda)) |
2653 struct frame *f = check_x_frame (frame); | 2668 struct frame *f = check_x_frame (frame); |
2654 char *name = 0; | 2669 char *name = 0; |
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); |
2661 else if (FLOATP (value)) | 2677 else if (FLOATP (value)) |
2662 atom = (Atom) XFLOAT_DATA (value); | 2678 atom = (Atom) XFLOAT_DATA (value); |
2665 else | 2681 else |
2666 error ("Wrong type, value must be number or cons"); | 2682 error ("Wrong type, value must be number or cons"); |
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) : ""; |
2672 | 2687 had_errors = x_had_errors_p (dpy); |
2673 if (! x_had_errors_p (dpy)) | 2688 x_uncatch_errors (); |
2689 | |
2690 if (!had_errors) | |
2674 ret = make_string (name, strlen (name)); | 2691 ret = make_string (name, strlen (name)); |
2675 | |
2676 x_uncatch_errors (); | |
2677 | 2692 |
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 |
2681 UNBLOCK_INPUT; | 2696 UNBLOCK_INPUT; |