comparison src/xselect.c @ 83037:03a73693678e

Merged in changes from CVS HEAD Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-71 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-72 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-73 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-74 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-75 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-76 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-77 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-78 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-79 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-80 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-81 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-82 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-83 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-84 Add lisp/emacs-lisp/macroexp.el * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-85 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-86 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-87 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-88 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-89 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-90 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-91 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-92 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-93 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-94 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-95 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-96 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-97 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-77
author Karoly Lorentey <lorentey@elte.hu>
date Tue, 17 Feb 2004 01:52:25 +0000
parents 7900111db01c 26dc8943ee64
children dbcd0af66869
comparison
equal deleted inserted replaced
83036:fc638739c70f 83037:03a73693678e
21 21
22 22
23 /* Rewritten by jwz */ 23 /* Rewritten by jwz */
24 24
25 #include <config.h> 25 #include <config.h>
26 #include <stdio.h> /* termhooks.h needs this */
26 #include "lisp.h" 27 #include "lisp.h"
27 #include "xterm.h" /* for all of the X includes */ 28 #include "xterm.h" /* for all of the X includes */
28 #include "dispextern.h" /* frame.h seems to want this */ 29 #include "dispextern.h" /* frame.h seems to want this */
29 #include "frame.h" /* Need this to get the X window of selected_frame */ 30 #include "frame.h" /* Need this to get the X window of selected_frame */
30 #include "blockinput.h" 31 #include "blockinput.h"
31 #include "buffer.h" 32 #include "buffer.h"
32 #include "process.h" 33 #include "process.h"
34 #include "termhooks.h"
35
36 #include <X11/Xproto.h>
33 37
34 struct prop_location; 38 struct prop_location;
35 39
36 static Lisp_Object x_atom_to_symbol P_ ((Display *dpy, Atom atom)); 40 static Lisp_Object x_atom_to_symbol P_ ((Display *dpy, Atom atom));
37 static Atom symbol_to_x_atom P_ ((struct x_display_info *, Display *, 41 static Atom symbol_to_x_atom P_ ((struct x_display_info *, Display *,
48 static struct prop_location *expect_property_change P_ ((Display *, Window, 52 static struct prop_location *expect_property_change P_ ((Display *, Window,
49 Atom, int)); 53 Atom, int));
50 static void unexpect_property_change P_ ((struct prop_location *)); 54 static void unexpect_property_change P_ ((struct prop_location *));
51 static Lisp_Object wait_for_property_change_unwind P_ ((Lisp_Object)); 55 static Lisp_Object wait_for_property_change_unwind P_ ((Lisp_Object));
52 static void wait_for_property_change P_ ((struct prop_location *)); 56 static void wait_for_property_change P_ ((struct prop_location *));
53 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, Lisp_Object)); 57 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
58 Lisp_Object,
59 Lisp_Object));
54 static void x_get_window_property P_ ((Display *, Window, Atom, 60 static void x_get_window_property P_ ((Display *, Window, Atom,
55 unsigned char **, int *, 61 unsigned char **, int *,
56 Atom *, int *, unsigned long *, int)); 62 Atom *, int *, unsigned long *, int));
57 static void receive_incremental_selection P_ ((Display *, Window, Atom, 63 static void receive_incremental_selection P_ ((Display *, Window, Atom,
58 Lisp_Object, unsigned, 64 Lisp_Object, unsigned,
1221 1227
1222 /* Do protocol to read selection-data from the server. 1228 /* Do protocol to read selection-data from the server.
1223 Converts this to Lisp data and returns it. */ 1229 Converts this to Lisp data and returns it. */
1224 1230
1225 static Lisp_Object 1231 static Lisp_Object
1226 x_get_foreign_selection (selection_symbol, target_type) 1232 x_get_foreign_selection (selection_symbol, target_type, time_stamp)
1227 Lisp_Object selection_symbol, target_type; 1233 Lisp_Object selection_symbol, target_type, time_stamp;
1228 { 1234 {
1229 struct frame *sf = SELECTED_FRAME (); 1235 struct frame *sf = SELECTED_FRAME ();
1230 Window requestor_window; 1236 Window requestor_window;
1231 Display *display; 1237 Display *display;
1232 struct x_display_info *dpyinfo; 1238 struct x_display_info *dpyinfo;
1249 1255
1250 if (CONSP (target_type)) 1256 if (CONSP (target_type))
1251 type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type)); 1257 type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type));
1252 else 1258 else
1253 type_atom = symbol_to_x_atom (dpyinfo, display, target_type); 1259 type_atom = symbol_to_x_atom (dpyinfo, display, target_type);
1260
1261 if (! NILP (time_stamp))
1262 {
1263 if (CONSP (time_stamp))
1264 requestor_time = (Time) cons_to_long (time_stamp);
1265 else if (INTEGERP (time_stamp))
1266 requestor_time = (Time) XUINT (time_stamp);
1267 else if (FLOATP (time_stamp))
1268 requestor_time = (Time) XFLOAT (time_stamp);
1269 else
1270 error ("TIME_STAMP must be cons or number");
1271 }
1254 1272
1255 BLOCK_INPUT; 1273 BLOCK_INPUT;
1256 1274
1257 count = x_catch_errors (display); 1275 count = x_catch_errors (display);
1258 1276
1941 /* Request the selection value from the owner. If we are the owner, 1959 /* Request the selection value from the owner. If we are the owner,
1942 simply return our selection value. If we are not the owner, this 1960 simply return our selection value. If we are not the owner, this
1943 will block until all of the data has arrived. */ 1961 will block until all of the data has arrived. */
1944 1962
1945 DEFUN ("x-get-selection-internal", Fx_get_selection_internal, 1963 DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
1946 Sx_get_selection_internal, 2, 2, 0, 1964 Sx_get_selection_internal, 2, 3, 0,
1947 doc: /* Return text selected from some X window. 1965 doc: /* Return text selected from some X window.
1948 SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. 1966 SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
1949 \(Those are literal upper-case symbol names, since that's what X expects.) 1967 \(Those are literal upper-case symbol names, since that's what X expects.)
1950 TYPE is the type of data desired, typically `STRING'. */) 1968 TYPE is the type of data desired, typically `STRING'.
1951 (selection_symbol, target_type) 1969 TIME_STAMP is the time to use in the XConvertSelection call for foreign
1952 Lisp_Object selection_symbol, target_type; 1970 selections. If omitted, defaults to the time for the last event. */)
1971 (selection_symbol, target_type, time_stamp)
1972 Lisp_Object selection_symbol, target_type, time_stamp;
1953 { 1973 {
1954 Lisp_Object val = Qnil; 1974 Lisp_Object val = Qnil;
1955 struct gcpro gcpro1, gcpro2; 1975 struct gcpro gcpro1, gcpro2;
1956 GCPRO2 (target_type, val); /* we store newly consed data into these */ 1976 GCPRO2 (target_type, val); /* we store newly consed data into these */
1957 check_x (); 1977 check_x ();
1971 1991
1972 val = x_get_local_selection (selection_symbol, target_type, 1); 1992 val = x_get_local_selection (selection_symbol, target_type, 1);
1973 1993
1974 if (NILP (val)) 1994 if (NILP (val))
1975 { 1995 {
1976 val = x_get_foreign_selection (selection_symbol, target_type); 1996 val = x_get_foreign_selection (selection_symbol, target_type, time_stamp);
1977 goto DONE; 1997 goto DONE;
1978 } 1998 }
1979 1999
1980 if (CONSP (val) 2000 if (CONSP (val)
1981 && SYMBOLP (XCAR (val))) 2001 && SYMBOLP (XCAR (val)))
2308 return n; 2328 return n;
2309 } 2329 }
2310 2330
2311 #endif 2331 #endif
2312 2332
2333 /***********************************************************************
2334 Drag and drop support
2335 ***********************************************************************/
2336 /* Check that lisp values are of correct type for x_fill_property_data.
2337 That is, number, string or a cons with two numbers (low and high 16
2338 bit parts of a 32 bit number). */
2339
2340 int
2341 x_check_property_data (data)
2342 Lisp_Object data;
2343 {
2344 Lisp_Object iter;
2345 int size = 0;
2346
2347 for (iter = data; CONSP (iter) && size != -1; iter = XCDR (iter), ++size)
2348 {
2349 Lisp_Object o = XCAR (iter);
2350
2351 if (! NUMBERP (o) && ! STRINGP (o) && ! CONSP (o))
2352 size = -1;
2353 else if (CONSP (o) &&
2354 (! NUMBERP (XCAR (o)) || ! NUMBERP (XCDR (o))))
2355 size = -1;
2356 }
2357
2358 return size;
2359 }
2360
2361 /* Convert lisp values to a C array. Values may be a number, a string
2362 which is taken as an X atom name and converted to the atom value, or
2363 a cons containing the two 16 bit parts of a 32 bit number.
2364
2365 DPY is the display use to look up X atoms.
2366 DATA is a Lisp list of values to be converted.
2367 RET is the C array that contains the converted values. It is assumed
2368 it is big enough to hol all values.
2369 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
2370 be stored in RET. */
2371
2372 void
2373 x_fill_property_data (dpy, data, ret, format)
2374 Display *dpy;
2375 Lisp_Object data;
2376 void *ret;
2377 int format;
2378 {
2379 CARD32 val;
2380 CARD32 *d32 = (CARD32 *) ret;
2381 CARD16 *d16 = (CARD16 *) ret;
2382 CARD8 *d08 = (CARD8 *) ret;
2383 Lisp_Object iter;
2384
2385 for (iter = data; CONSP (iter); iter = XCDR (iter))
2386 {
2387 Lisp_Object o = XCAR (iter);
2388
2389 if (INTEGERP (o))
2390 val = (CARD32) XFASTINT (o);
2391 else if (FLOATP (o))
2392 val = (CARD32) XFLOAT (o);
2393 else if (CONSP (o))
2394 val = (CARD32) cons_to_long (o);
2395 else if (STRINGP (o))
2396 {
2397 BLOCK_INPUT;
2398 val = XInternAtom (dpy, (char *) SDATA (o), False);
2399 UNBLOCK_INPUT;
2400 }
2401 else
2402 error ("Wrong type, must be string, number or cons");
2403
2404 if (format == 8)
2405 *d08++ = (CARD8) val;
2406 else if (format == 16)
2407 *d16++ = (CARD16) val;
2408 else
2409 *d32++ = val;
2410 }
2411 }
2412
2413 /* Convert an array of C values to a Lisp list.
2414 F is the frame to be used to look up X atoms if the TYPE is XA_ATOM.
2415 DATA is a C array of values to be converted.
2416 TYPE is the type of the data. Only XA_ATOM is special, it converts
2417 each number in DATA to its corresponfing X atom as a symbol.
2418 FORMAT is 8, 16 or 32 and gives the size in bits for each C value to
2419 be stored in RET.
2420 SIZE is the number of elements in DATA.
2421
2422 Also see comment for selection_data_to_lisp_data above. */
2423
2424 Lisp_Object
2425 x_property_data_to_lisp (f, data, type, format, size)
2426 struct frame *f;
2427 unsigned char *data;
2428 Atom type;
2429 int format;
2430 unsigned long size;
2431 {
2432 return selection_data_to_lisp_data (FRAME_X_DISPLAY (f),
2433 data, size*format/8, type, format);
2434 }
2435
2436 /* Get the mouse position frame relative coordinates. */
2437
2438 static void
2439 mouse_position_for_drop (f, x, y)
2440 FRAME_PTR f;
2441 int *x;
2442 int *y;
2443 {
2444 Window root, dummy_window;
2445 int dummy;
2446
2447 BLOCK_INPUT;
2448
2449 XQueryPointer (FRAME_X_DISPLAY (f),
2450 DefaultRootWindow (FRAME_X_DISPLAY (f)),
2451
2452 /* The root window which contains the pointer. */
2453 &root,
2454
2455 /* Window pointer is on, not used */
2456 &dummy_window,
2457
2458 /* The position on that root window. */
2459 x, y,
2460
2461 /* x/y in dummy_window coordinates, not used. */
2462 &dummy, &dummy,
2463
2464 /* Modifier keys and pointer buttons, about which
2465 we don't care. */
2466 (unsigned int *) &dummy);
2467
2468
2469 /* Absolute to relative. */
2470 *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
2471 *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
2472
2473 UNBLOCK_INPUT;
2474 }
2475
2476 DEFUN ("x-get-atom-name", Fx_get_atom_name,
2477 Sx_get_atom_name, 1, 2, 0,
2478 doc: /* Return the X atom name for VALUE as a string.
2479 VALUE may be a number or a cons where the car is the upper 16 bits and
2480 the cdr is the lower 16 bits of a 32 bit value.
2481 Use the display for FRAME or the current frame if FRAME is not given or nil.
2482
2483 If the value is 0 or the atom is not known, return the empty string. */)
2484 (value, frame)
2485 Lisp_Object value, frame;
2486 {
2487 struct frame *f = check_x_frame (frame);
2488 char *name = 0;
2489 Lisp_Object ret = Qnil;
2490 int count;
2491 Display *dpy = FRAME_X_DISPLAY (f);
2492 Atom atom;
2493
2494 if (INTEGERP (value))
2495 atom = (Atom) XUINT (value);
2496 else if (FLOATP (value))
2497 atom = (Atom) XFLOAT (value);
2498 else if (CONSP (value))
2499 atom = (Atom) cons_to_long (value);
2500 else
2501 error ("Wrong type, value must be number or cons");
2502
2503 BLOCK_INPUT;
2504 count = x_catch_errors (dpy);
2505
2506 name = atom ? XGetAtomName (dpy, atom) : "";
2507
2508 if (! x_had_errors_p (dpy))
2509 ret = make_string (name, strlen (name));
2510
2511 x_uncatch_errors (dpy, count);
2512
2513 if (atom && name) XFree (name);
2514 if (NILP (ret)) ret = make_string ("", 0);
2515
2516 UNBLOCK_INPUT;
2517
2518 return ret;
2519 }
2520
2521 /* Convert an XClientMessageEvent to a Lisp event of type DRAG_N_DROP_EVENT.
2522 TODO: Check if this client event really is a DND event? */
2523
2524 int
2525 x_handle_dnd_message (f, event, dpyinfo, bufp)
2526 struct frame *f;
2527 XClientMessageEvent *event;
2528 struct x_display_info *dpyinfo;
2529 struct input_event *bufp;
2530 {
2531 Lisp_Object vec;
2532 Lisp_Object frame;
2533 unsigned long size = (8*sizeof (event->data))/event->format;
2534 int x, y;
2535
2536 XSETFRAME (frame, f);
2537
2538 vec = Fmake_vector (make_number (4), Qnil);
2539 AREF (vec, 0) = SYMBOL_NAME (x_atom_to_symbol (FRAME_X_DISPLAY (f),
2540 event->message_type));
2541 AREF (vec, 1) = frame;
2542 AREF (vec, 2) = make_number (event->format);
2543 AREF (vec, 3) = x_property_data_to_lisp (f,
2544 event->data.b,
2545 event->message_type,
2546 event->format,
2547 size);
2548
2549 mouse_position_for_drop (f, &x, &y);
2550 bufp->kind = DRAG_N_DROP_EVENT;
2551 bufp->frame_or_window = Fcons (frame, vec);
2552 bufp->timestamp = CurrentTime;
2553 bufp->x = make_number (x);
2554 bufp->y = make_number (y);
2555 bufp->arg = Qnil;
2556 bufp->modifiers = 0;
2557
2558 return 1;
2559 }
2560
2561 DEFUN ("x-send-client-message", Fx_send_client_event,
2562 Sx_send_client_message, 6, 6, 0,
2563 doc: /* Send a client message of MESSAGE-TYPE to window DEST on DISPLAY.
2564
2565 For DISPLAY, specify either a frame or a display name (a string).
2566 If DISPLAY is nil, that stands for the selected frame's display.
2567 DEST may be a number, in which case it is a Window id. The value 0 may
2568 be used to send to the root window of the DISPLAY.
2569 If DEST is a cons, it is converted to a 32 bit number
2570 with the high 16 bits from the car and the lower 16 bit from the cdr. That
2571 number is then used as a window id.
2572 If DEST is a frame the event is sent to the outer window of that frame.
2573 Nil means the currently selected frame.
2574 If DEST is the string "PointerWindow" the event is sent to the window that
2575 contains the pointer. If DEST is the string "InputFocus" the event is
2576 sent to the window that has the input focus.
2577 FROM is the frame sending the event. Use nil for currently selected frame.
2578 MESSAGE-TYPE is the name of an Atom as a string.
2579 FORMAT must be one of 8, 16 or 32 and determines the size of the values in
2580 bits. VALUES is a list of numbers, cons and/or strings containing the values
2581 to send. If a value is a string, it is converted to an Atom and the value of
2582 the Atom is sent. If a value is a cons, it is converted to a 32 bit number
2583 with the high 16 bits from the car and the lower 16 bit from the cdr.
2584 If more values than fits into the event is given, the excessive values
2585 are ignored. */)
2586 (display, dest, from, message_type, format, values)
2587 Lisp_Object display, dest, from, message_type, format, values;
2588 {
2589 struct x_display_info *dpyinfo = check_x_display_info (display);
2590 Window wdest;
2591 XEvent event;
2592 Lisp_Object cons;
2593 int size;
2594 struct frame *f = check_x_frame (from);
2595 int count;
2596 int to_root;
2597
2598 CHECK_STRING (message_type);
2599 CHECK_NUMBER (format);
2600 CHECK_CONS (values);
2601
2602 if (x_check_property_data (values) == -1)
2603 error ("Bad data in VALUES, must be number, cons or string");
2604
2605 event.xclient.type = ClientMessage;
2606 event.xclient.format = XFASTINT (format);
2607
2608 if (event.xclient.format != 8 && event.xclient.format != 16
2609 && event.xclient.format != 32)
2610 error ("FORMAT must be one of 8, 16 or 32");
2611
2612 if (FRAMEP (dest) || NILP (dest))
2613 {
2614 struct frame *fdest = check_x_frame (dest);
2615 wdest = FRAME_OUTER_WINDOW (fdest);
2616 }
2617 else if (STRINGP (dest))
2618 {
2619 if (strcmp (SDATA (dest), "PointerWindow") == 0)
2620 wdest = PointerWindow;
2621 else if (strcmp (SDATA (dest), "InputFocus") == 0)
2622 wdest = InputFocus;
2623 else
2624 error ("DEST as a string must be one of PointerWindow or InputFocus");
2625 }
2626 else if (INTEGERP (dest))
2627 wdest = (Window) XFASTINT (dest);
2628 else if (FLOATP (dest))
2629 wdest = (Window) XFLOAT (dest);
2630 else if (CONSP (dest))
2631 {
2632 if (! NUMBERP (XCAR (dest)) || ! NUMBERP (XCDR (dest)))
2633 error ("Both car and cdr for DEST must be numbers");
2634 else
2635 wdest = (Window) cons_to_long (dest);
2636 }
2637 else
2638 error ("DEST must be a frame, nil, string, number or cons");
2639
2640 if (wdest == 0) wdest = dpyinfo->root_window;
2641 to_root = wdest == dpyinfo->root_window;
2642
2643 for (cons = values, size = 0; CONSP (cons); cons = XCDR (cons), ++size)
2644 ;
2645
2646 BLOCK_INPUT;
2647
2648 event.xclient.message_type
2649 = XInternAtom (dpyinfo->display, SDATA (message_type), False);
2650 event.xclient.display = dpyinfo->display;
2651
2652 /* Some clients (metacity for example) expects sending window to be here
2653 when sending to the root window. */
2654 event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
2655
2656 memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
2657 x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
2658 event.xclient.format);
2659
2660 /* If event mask is 0 the event is sent to the client that created
2661 the destination window. But if we are sending to the root window,
2662 there is no such client. Then we set the event mask to 0xffff. The
2663 event then goes to clients selecting for events on the root window. */
2664 count = x_catch_errors (dpyinfo->display);
2665 {
2666 int propagate = to_root ? False : True;
2667 unsigned mask = to_root ? 0xffff : 0;
2668 XSendEvent (dpyinfo->display, wdest, propagate, mask, &event);
2669 XFlush (dpyinfo->display);
2670 }
2671 x_uncatch_errors (dpyinfo->display, count);
2672 UNBLOCK_INPUT;
2673
2674 return Qnil;
2675 }
2676
2677
2313 void 2678 void
2314 syms_of_xselect () 2679 syms_of_xselect ()
2315 { 2680 {
2316 defsubr (&Sx_get_selection_internal); 2681 defsubr (&Sx_get_selection_internal);
2317 defsubr (&Sx_own_selection_internal); 2682 defsubr (&Sx_own_selection_internal);
2322 #ifdef CUT_BUFFER_SUPPORT 2687 #ifdef CUT_BUFFER_SUPPORT
2323 defsubr (&Sx_get_cut_buffer_internal); 2688 defsubr (&Sx_get_cut_buffer_internal);
2324 defsubr (&Sx_store_cut_buffer_internal); 2689 defsubr (&Sx_store_cut_buffer_internal);
2325 defsubr (&Sx_rotate_cut_buffers_internal); 2690 defsubr (&Sx_rotate_cut_buffers_internal);
2326 #endif 2691 #endif
2692
2693 defsubr (&Sx_get_atom_name);
2694 defsubr (&Sx_send_client_message);
2327 2695
2328 reading_selection_reply = Fcons (Qnil, Qnil); 2696 reading_selection_reply = Fcons (Qnil, Qnil);
2329 staticpro (&reading_selection_reply); 2697 staticpro (&reading_selection_reply);
2330 reading_selection_window = 0; 2698 reading_selection_window = 0;
2331 reading_which_selection = 0; 2699 reading_which_selection = 0;