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;