aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJim Blandy1993-01-26 01:58:16 +0000
committerJim Blandy1993-01-26 01:58:16 +0000
commitdbc4e1c12940079cad7b24e1654a0badcda8d6fc (patch)
treee0fbea5b15bd13d2839c8b59b624cec80f31bfd8 /src
parent72766144811cd7258b2a59e56f6e3657537ea508 (diff)
downloademacs-dbc4e1c12940079cad7b24e1654a0badcda8d6fc.tar.gz
emacs-dbc4e1c12940079cad7b24e1654a0badcda8d6fc.zip
JimB's changes since January 18th
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in13
-rw-r--r--src/buffer.c15
-rw-r--r--src/buffer.h3
-rw-r--r--src/callint.c43
-rw-r--r--src/commands.h6
-rw-r--r--src/data.c20
-rw-r--r--src/dispnew.c17
-rw-r--r--src/emacs.c4
-rw-r--r--src/fns.c9
-rw-r--r--src/frame.c84
-rw-r--r--src/frame.h4
-rw-r--r--src/insdel.c8
-rw-r--r--src/keyboard.c138
-rw-r--r--src/keyboard.h3
-rw-r--r--src/keymap.c10
-rw-r--r--src/lread.c12
-rw-r--r--src/minibuf.c4
-rw-r--r--src/term.c12
-rw-r--r--src/termhooks.h11
-rw-r--r--src/window.c48
-rw-r--r--src/xfns.c86
-rw-r--r--src/xmenu.c2
-rw-r--r--src/xselect.c.old128
-rw-r--r--src/xterm.c429
-rw-r--r--src/xterm.h19
25 files changed, 671 insertions, 457 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 468e312abd6..5e19aa0248e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -47,14 +47,17 @@ temacs: dotemacs
47dotemacs: xmakefile 47dotemacs: xmakefile
48 $(MAKE) CC='${CC}' -f xmakefile ${MFLAGS} temacs 48 $(MAKE) CC='${CC}' -f xmakefile ${MFLAGS} temacs
49 49
50# If you have a problem with cc -E here, changing 50### Some makes, like Ultrix's make, complain if you put a comment in
51# the definition of CPP above may fix it. 51### the middle of a rule's command list! Dummies.
52
53### The flags for optimization and debugging depend on the
54### system, so take an ordinary CFLAGS value and choose the
55### appropriate CPP symbols to use in ymakefile.
56### If you have a problem with cc -E here, changing
57### the definition of CPP above may fix it.
52xmakefile: ymakefile config.h 58xmakefile: ymakefile config.h
53 -rm -f xmakefile xmakefile.new junk.c junk.cpp 59 -rm -f xmakefile xmakefile.new junk.c junk.cpp
54 cp ymakefile junk.c 60 cp ymakefile junk.c
55 ## The flags for optimization and debugging depend on the
56 ## system, so take an ordinary CFLAGS value and choose the
57 ## appropriate CPP symbols to use in ymakefile.
58 $(CPP) junk.c > junk.cpp \ 61 $(CPP) junk.c > junk.cpp \
59 -DC_SWITCH_SITE="`echo ${CFLAGS}' ' \ 62 -DC_SWITCH_SITE="`echo ${CFLAGS}' ' \
60 | sed -e 's/-g /C_DEBUG_SWITCH /' \ 63 | sed -e 's/-g /C_DEBUG_SWITCH /' \
diff --git a/src/buffer.c b/src/buffer.c
index 4a78b568176..4057fffbf7d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -112,8 +112,9 @@ Lisp_Object Vbuffer_alist;
112Lisp_Object Vbefore_change_function; 112Lisp_Object Vbefore_change_function;
113Lisp_Object Vafter_change_function; 113Lisp_Object Vafter_change_function;
114 114
115/* Function to call before changing an unmodified buffer. */ 115/* List of functions to call before changing an unmodified buffer. */
116Lisp_Object Vfirst_change_function; 116Lisp_Object Vfirst_change_hook;
117Lisp_Object Qfirst_change_hook;
117 118
118Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local; 119Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
119 120
@@ -1655,10 +1656,12 @@ While executing the `after-change-function', changes to buffers do not\n\
1655cause calls to any `before-change-function' or `after-change-function'."); 1656cause calls to any `before-change-function' or `after-change-function'.");
1656 Vafter_change_function = Qnil; 1657 Vafter_change_function = Qnil;
1657 1658
1658 DEFVAR_LISP ("first-change-function", &Vfirst_change_function, 1659 DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
1659 "Function to call before changing a buffer which is unmodified.\n\ 1660 "A list of functions to call before changing a buffer which is unmodified.\n\
1660The function is called, with no arguments, if it is non-nil."); 1661The functions are run using the `run-hooks' function.");
1661 Vfirst_change_function = Qnil; 1662 Vfirst_change_hook = Qnil;
1663 Qfirst_change_hook = intern ("first-change-hook");
1664 staticpro (&Qfirst_change_hook);
1662 1665
1663 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil, 1666 DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
1664 "List of undo entries in current buffer.\n\ 1667 "List of undo entries in current buffer.\n\
diff --git a/src/buffer.h b/src/buffer.h
index 6e3f7a8ee23..77784d27da0 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -340,7 +340,8 @@ extern void reset_buffer ();
340/* Functions to call before and after each text change. */ 340/* Functions to call before and after each text change. */
341extern Lisp_Object Vbefore_change_function; 341extern Lisp_Object Vbefore_change_function;
342extern Lisp_Object Vafter_change_function; 342extern Lisp_Object Vafter_change_function;
343extern Lisp_Object Vfirst_change_function; 343extern Lisp_Object Vfirst_change_hook;
344extern Lisp_Object Qfirst_change_hook;
344 345
345/* Fields. 346/* Fields.
346 347
diff --git a/src/callint.c b/src/callint.c
index 53cad4a4a78..ffa2fa39539 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -1,11 +1,11 @@
1/* Call a Lisp function interactively. 1/* Call a Lisp function interactively.
2 Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
6GNU Emacs is free software; you can redistribute it and/or modify 6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by 7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option) 8the Free Software Foundation; either version 2, or (at your option)
9any later version. 9any later version.
10 10
11GNU Emacs is distributed in the hope that it will be useful, 11GNU Emacs is distributed in the hope that it will be useful,
@@ -89,10 +89,11 @@ X -- Lisp expression read and evaluated.\n\
89In addition, if the string begins with `*'\n\ 89In addition, if the string begins with `*'\n\
90 then an error is signaled if the buffer is read-only.\n\ 90 then an error is signaled if the buffer is read-only.\n\
91 This happens before reading any arguments.\n\ 91 This happens before reading any arguments.\n\
92If the string begins with `@', then the window the mouse is over is selected\n\ 92If the string begins with `@', then Emacs searches the key sequence\n\
93 before anything else is done. You may use both `@' and `*';\n\ 93 which invoked the command for its first mouse click (or any other\n\
94they are processed in the order that they appear." 94 event which specifies a window), and selects that window before\n\
95*/ 95 reading any arguments. You may use both `@' and `*'; they are\n\
96 processed in the order that they appear." */
96 97
97/* ARGSUSED */ 98/* ARGSUSED */
98DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0, 99DEFUN ("interactive", Finteractive, Sinteractive, 0, UNEVALLED, 0,
@@ -167,7 +168,7 @@ Otherwise, this is done only if an arg is read using the minibuffer.")
167 168
168 /* The index of the next element of this_command_keys to examine for 169 /* The index of the next element of this_command_keys to examine for
169 the 'e' interactive code. */ 170 the 'e' interactive code. */
170 int next_event = 0; 171 int next_event;
171 172
172 Lisp_Object prefix_arg; 173 Lisp_Object prefix_arg;
173 unsigned char *string; 174 unsigned char *string;
@@ -296,6 +297,12 @@ Otherwise, this is done only if an arg is read using the minibuffer.")
296 297
297 /* Here if function specifies a string to control parsing the defaults */ 298 /* Here if function specifies a string to control parsing the defaults */
298 299
300 /* Set next_event to point to the first event with parameters. */
301 for (next_event = 0; next_event < this_command_key_count; next_event++)
302 if (EVENT_HAS_PARAMETERS
303 (XVECTOR (this_command_keys)->contents[next_event]))
304 break;
305
299 /* Handle special starting chars `*' and `@'. */ 306 /* Handle special starting chars `*' and `@'. */
300 while (1) 307 while (1)
301 { 308 {
@@ -307,9 +314,15 @@ Otherwise, this is done only if an arg is read using the minibuffer.")
307 } 314 }
308 else if (*string == '@') 315 else if (*string == '@')
309 { 316 {
317 Lisp_Object event =
318 XVECTOR (this_command_keys)->contents[next_event];
319
320 if (EVENT_HAS_PARAMETERS (event)
321 && XTYPE (event = XCONS (event)->cdr) == Lisp_Cons
322 && XTYPE (event = XCONS (event)->car) == Lisp_Cons
323 && XTYPE (event = XCONS (event)->car) == Lisp_Window)
324 Fselect_window (event);
310 string++; 325 string++;
311 if (!NILP (Vmouse_window))
312 Fselect_window (Vmouse_window);
313 } 326 }
314 else break; 327 else break;
315 } 328 }
@@ -433,11 +446,6 @@ Otherwise, this is done only if an arg is read using the minibuffer.")
433 break; 446 break;
434 447
435 case 'e': /* The invoking event. */ 448 case 'e': /* The invoking event. */
436 /* Find the next parameterized event. */
437 while (next_event < this_command_key_count
438 && ! (EVENT_HAS_PARAMETERS
439 (XVECTOR (this_command_keys)->contents[next_event])))
440 next_event++;
441 if (next_event >= this_command_key_count) 449 if (next_event >= this_command_key_count)
442 error ("%s must be bound to an event with parameters", 450 error ("%s must be bound to an event with parameters",
443 (XTYPE (function) == Lisp_Symbol 451 (XTYPE (function) == Lisp_Symbol
@@ -445,6 +453,13 @@ Otherwise, this is done only if an arg is read using the minibuffer.")
445 : "command")); 453 : "command"));
446 args[i] = XVECTOR (this_command_keys)->contents[next_event++]; 454 args[i] = XVECTOR (this_command_keys)->contents[next_event++];
447 varies[i] = -1; 455 varies[i] = -1;
456
457 /* Find the next parameterized event. */
458 while (next_event < this_command_key_count
459 && ! (EVENT_HAS_PARAMETERS
460 (XVECTOR (this_command_keys)->contents[next_event])))
461 next_event++;
462
448 break; 463 break;
449 464
450 case 'm': /* Value of mark. Does not do I/O. */ 465 case 'm': /* Value of mark. Does not do I/O. */
diff --git a/src/commands.h b/src/commands.h
index 4e3d67d166e..4abdcac56f1 100644
--- a/src/commands.h
+++ b/src/commands.h
@@ -49,12 +49,12 @@ extern Lisp_Object last_command_char;
49 reached by the mouse. */ 49 reached by the mouse. */
50extern Lisp_Object last_nonmenu_event; 50extern Lisp_Object last_nonmenu_event;
51 51
52/* Command event to be re-read, or Qnil. */ 52/* List of command events to be re-read, or Qnil. */
53extern Lisp_Object unread_command_event; 53extern Lisp_Object unread_command_events;
54 54
55/* If not Qnil, this is a switch-frame event which we decided to put 55/* If not Qnil, this is a switch-frame event which we decided to put
56 off until the end of a key sequence. This should be read as the 56 off until the end of a key sequence. This should be read as the
57 next command input, after any unread_command_event. 57 next command input, after any unread_command_events.
58 58
59 read_key_sequence uses this to delay switch-frame events until the 59 read_key_sequence uses this to delay switch-frame events until the
60 end of the key sequence; Fread_char uses it to put off switch-frame 60 end of the key sequence; Fread_char uses it to put off switch-frame
diff --git a/src/data.c b/src/data.c
index 3a19314873c..071cfe853b7 100644
--- a/src/data.c
+++ b/src/data.c
@@ -256,8 +256,8 @@ DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0, "T if OBJECT is a built-in function.")
256 return Qnil; 256 return Qnil;
257} 257}
258 258
259DEFUN ("compiled-function-p", Fcompiled_function_p, Scompiled_function_p, 259DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
260 1, 1, 0, "T if OBJECT is a compiled function object.") 260 1, 1, 0, "T if OBJECT is a byte-compiled function object.")
261 (obj) 261 (obj)
262 Lisp_Object obj; 262 Lisp_Object obj;
263{ 263{
@@ -308,13 +308,10 @@ DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0,
308 (obj) 308 (obj)
309 Lisp_Object obj; 309 Lisp_Object obj;
310{ 310{
311 if (0 311 if (NUMBERP (obj))
312#ifdef LISP_FLOAT_TYPE
313 || XTYPE (obj) == Lisp_Float
314#endif
315 || XTYPE (obj) == Lisp_Int)
316 return Qt; 312 return Qt;
317 return Qnil; 313 else
314 return Qnil;
318} 315}
319 316
320DEFUN ("number-or-marker-p", Fnumber_or_marker_p, 317DEFUN ("number-or-marker-p", Fnumber_or_marker_p,
@@ -323,10 +320,7 @@ DEFUN ("number-or-marker-p", Fnumber_or_marker_p,
323 (obj) 320 (obj)
324 Lisp_Object obj; 321 Lisp_Object obj;
325{ 322{
326 if (XTYPE (obj) == Lisp_Int 323 if (NUMBERP (obj)
327#ifdef LISP_FLOAT_TYPE
328 || XTYPE (obj) == Lisp_Float
329#endif
330 || XTYPE (obj) == Lisp_Marker) 324 || XTYPE (obj) == Lisp_Marker)
331 return Qt; 325 return Qt;
332 return Qnil; 326 return Qnil;
@@ -2037,7 +2031,7 @@ syms_of_data ()
2037 defsubr (&Sbufferp); 2031 defsubr (&Sbufferp);
2038 defsubr (&Smarkerp); 2032 defsubr (&Smarkerp);
2039 defsubr (&Ssubrp); 2033 defsubr (&Ssubrp);
2040 defsubr (&Scompiled_function_p); 2034 defsubr (&Sbyte_code_function_p);
2041 defsubr (&Schar_or_string_p); 2035 defsubr (&Schar_or_string_p);
2042 defsubr (&Scar); 2036 defsubr (&Scar);
2043 defsubr (&Scdr); 2037 defsubr (&Scdr);
diff --git a/src/dispnew.c b/src/dispnew.c
index edcb7223f0b..5570129c389 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -173,7 +173,22 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
173 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) 173 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
174 { 174 {
175 frame = XCONS (tail)->car; 175 frame = XCONS (tail)->car;
176 if (FRAME_VISIBLE_P (XFRAME (frame))) 176
177 /* If we simply redrew all visible frames, whether or not they
178 were garbaged, then this would make all frames clear and
179 redraw whenever a new frame is created or an existing frame
180 is de-iconified; those events set the global frame_garbaged
181 flag, to which redisplay responds by calling this function.
182
183 This used to redraw all visible frames; the only advantage of
184 that approach is that if a frame changes from invisible to
185 visible without setting its garbaged flag, it still gets
186 redisplayed. But that should never happen; since invisible
187 frames are not updated, they should always be marked as
188 garbaged when they become visible again. If that doesn't
189 happen, it's a bug in the visibility code, not a bug here. */
190 if (FRAME_VISIBLE_P (XFRAME (frame))
191 && FRAME_GARBAGED_P (XFRAME (frame)))
177 Fredraw_frame (frame); 192 Fredraw_frame (frame);
178 } 193 }
179 return Qnil; 194 return Qnil;
diff --git a/src/emacs.c b/src/emacs.c
index da5916990d5..9209e4f7d6b 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -519,10 +519,8 @@ main (argc, argv, envp)
519#ifdef HAVE_X11 519#ifdef HAVE_X11
520 syms_of_xselect (); 520 syms_of_xselect ();
521#endif 521#endif
522#ifdef HAVE_X_WINDOWS 522#ifdef HAVE_X_MENU
523#ifndef NO_X_MENU
524 syms_of_xmenu (); 523 syms_of_xmenu ();
525#endif /* not NO_X_MENU */
526#endif /* HAVE_X_MENU */ 524#endif /* HAVE_X_MENU */
527#endif /* HAVE_X_WINDOWS */ 525#endif /* HAVE_X_WINDOWS */
528 526
diff --git a/src/fns.c b/src/fns.c
index 144d6ef345e..9f818e886f2 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -836,8 +836,12 @@ internal_equal (o1, o2, depth)
836 error ("Stack overflow in equal"); 836 error ("Stack overflow in equal");
837do_cdr: 837do_cdr:
838 QUIT; 838 QUIT;
839 if (EQ (o1, o2)) return Qt;
840 if (NUMBERP (o1) && NUMBERP (o2))
841 {
842 return (extract_float (o1) == extract_float (o2)) ? Qt : Qnil;
843 }
839 if (XTYPE (o1) != XTYPE (o2)) return Qnil; 844 if (XTYPE (o1) != XTYPE (o2)) return Qnil;
840 if (XINT (o1) == XINT (o2)) return Qt;
841 if (XTYPE (o1) == Lisp_Cons) 845 if (XTYPE (o1) == Lisp_Cons)
842 { 846 {
843 Lisp_Object v1; 847 Lisp_Object v1;
@@ -853,7 +857,8 @@ do_cdr:
853 && XMARKER (o1)->bufpos == XMARKER (o2)->bufpos) 857 && XMARKER (o1)->bufpos == XMARKER (o2)->bufpos)
854 ? Qt : Qnil; 858 ? Qt : Qnil;
855 } 859 }
856 if (XTYPE (o1) == Lisp_Vector) 860 if (XTYPE (o1) == Lisp_Vector
861 || XTYPE (o1) == Lisp_Compiled)
857 { 862 {
858 register int index; 863 register int index;
859 if (XVECTOR (o1)->size != XVECTOR (o2)->size) 864 if (XVECTOR (o1)->size != XVECTOR (o2)->size)
diff --git a/src/frame.c b/src/frame.c
index 7184c20b797..ca48c73105f 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -74,7 +74,7 @@ Lisp_Object Vdefault_frame_alist;
74 74
75/*&&& symbols declared here &&&*/ 75/*&&& symbols declared here &&&*/
76Lisp_Object Qframep; 76Lisp_Object Qframep;
77Lisp_Object Qlive_frame_p; 77Lisp_Object Qframe_live_p;
78Lisp_Object Qheight; 78Lisp_Object Qheight;
79Lisp_Object Qicon; 79Lisp_Object Qicon;
80Lisp_Object Qminibuffer; 80Lisp_Object Qminibuffer;
@@ -110,7 +110,7 @@ Also see `live-frame-p'.")
110 } 110 }
111} 111}
112 112
113DEFUN ("live-frame-p", Flive_frame_p, Slive_frame_p, 1, 1, 0, 113DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
114 "Return non-nil if OBJECT is a frame which has not been deleted.\n\ 114 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
115Value is nil if OBJECT is not a live frame. If object is a live\n\ 115Value is nil if OBJECT is not a live frame. If object is a live\n\
116frame, the return value indicates what sort of output device it is\n\ 116frame, the return value indicates what sort of output device it is\n\
@@ -381,15 +381,14 @@ Changing the selected frame can change focus redirections. See\n\
381 381
382 Fselect_window (XFRAME (frame)->selected_window); 382 Fselect_window (XFRAME (frame)->selected_window);
383 383
384 /* I think this should be done with a hook. */
384#ifdef HAVE_X_WINDOWS 385#ifdef HAVE_X_WINDOWS
385#ifdef MULTI_FRAME
386 if (FRAME_X_P (XFRAME (frame)) 386 if (FRAME_X_P (XFRAME (frame))
387 && NILP (no_enter)) 387 && NILP (no_enter))
388 { 388 {
389 Ffocus_frame (frame); 389 Ffocus_frame (frame);
390 } 390 }
391#endif 391#endif
392#endif
393 choose_minibuf_frame (); 392 choose_minibuf_frame ();
394 393
395 return frame; 394 return frame;
@@ -450,8 +449,6 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
450 return Fcopy_sequence (Vframe_list); 449 return Fcopy_sequence (Vframe_list);
451} 450}
452 451
453#ifdef MULTI_FRAME
454
455/* Return the next frame in the frame list after FRAME. 452/* Return the next frame in the frame list after FRAME.
456 If MINIBUF is nil, exclude minibuffer-only frames. 453 If MINIBUF is nil, exclude minibuffer-only frames.
457 If MINIBUF is a window, include only frames using that window for 454 If MINIBUF is a window, include only frames using that window for
@@ -469,6 +466,10 @@ next_frame (frame, minibuf)
469 if (! CONSP (Vframe_list)) 466 if (! CONSP (Vframe_list))
470 abort (); 467 abort ();
471 468
469 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
470 forever. Forestall that. */
471 CHECK_LIVE_FRAME (frame, 0);
472
472 while (1) 473 while (1)
473 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) 474 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
474 { 475 {
@@ -503,9 +504,6 @@ next_frame (frame, minibuf)
503 } 504 }
504} 505}
505 506
506#if 0
507/* Nobody seems to be using this code right now. */
508
509/* Return the previous frame in the frame list before FRAME. 507/* Return the previous frame in the frame list before FRAME.
510 If MINIBUF is nil, exclude minibuffer-only frames. 508 If MINIBUF is nil, exclude minibuffer-only frames.
511 If MINIBUF is a window, include only frames using that window for 509 If MINIBUF is a window, include only frames using that window for
@@ -561,7 +559,6 @@ prev_frame (frame, minibuf)
561 acceptable frame in the list, return it. */ 559 acceptable frame in the list, return it. */
562 return prev; 560 return prev;
563} 561}
564#endif
565 562
566DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0, 563DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
567 "Return the next frame in the frame list after FRAME.\n\ 564 "Return the next frame in the frame list after FRAME.\n\
@@ -583,7 +580,7 @@ If MINIFRAME is non-nil and not a window, include all frames.")
583 580
584 return next_frame (frame, miniframe); 581 return next_frame (frame, miniframe);
585} 582}
586#endif /* MULTI_FRAME */ 583
587 584
588DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "", 585DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
589 "Delete FRAME, permanently eliminating it from use.\n\ 586 "Delete FRAME, permanently eliminating it from use.\n\
@@ -659,6 +656,8 @@ A frame may not be deleted if its minibuffer is used by other frames.")
659 now, then we may trip up the event-handling code. Instead, we'll 656 now, then we may trip up the event-handling code. Instead, we'll
660 promise that the display of the frame must be valid until we have 657 promise that the display of the frame must be valid until we have
661 called the window-system-dependent frame destruction routine. */ 658 called the window-system-dependent frame destruction routine. */
659
660 /* I think this should be done with a hook. */
662#ifdef HAVE_X_WINDOWS 661#ifdef HAVE_X_WINDOWS
663 if (FRAME_X_P (f)) 662 if (FRAME_X_P (f))
664 x_destroy_window (f); 663 x_destroy_window (f);
@@ -739,19 +738,25 @@ to read the mouse position, it returns the selected frame for FRAME\n\
739and nil for X and Y.") 738and nil for X and Y.")
740 () 739 ()
741{ 740{
742 Lisp_Object x, y, dummy;
743 FRAME_PTR f; 741 FRAME_PTR f;
742 Lisp_Object lispy_dummy;
743 enum scrollbar_part party_dummy;
744 Lisp_Object x, y;
745 unsigned long long_dummy;
744 746
745 if (mouse_position_hook) 747 if (mouse_position_hook)
746 (*mouse_position_hook) (&f, &x, &y, &dummy); 748 (*mouse_position_hook) (&f,
749 &lispy_dummy, &party_dummy,
750 &x, &y,
751 &long_dummy);
747 else 752 else
748 { 753 {
749 f = selected_frame; 754 f = selected_frame;
750 x = y = Qnil; 755 x = y = Qnil;
751 } 756 }
752 757
753 XSET (dummy, Lisp_Frame, f); 758 XSET (lispy_dummy, Lisp_Frame, f);
754 return Fcons (dummy, Fcons (make_number (x), make_number (y))); 759 return Fcons (lispy_dummy, Fcons (make_number (x), make_number (y)));
755} 760}
756 761
757DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0, 762DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
@@ -764,6 +769,7 @@ WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
764 CHECK_NUMBER (x, 2); 769 CHECK_NUMBER (x, 2);
765 CHECK_NUMBER (y, 1); 770 CHECK_NUMBER (y, 1);
766 771
772 /* I think this should be done with a hook. */
767#ifdef HAVE_X_WINDOWS 773#ifdef HAVE_X_WINDOWS
768 if (FRAME_X_P (XFRAME (frame))) 774 if (FRAME_X_P (XFRAME (frame)))
769 /* Warping the mouse will cause enternotify and focus events. */ 775 /* Warping the mouse will cause enternotify and focus events. */
@@ -842,6 +848,7 @@ If omitted, FRAME defaults to the currently selected frame.")
842 848
843 CHECK_LIVE_FRAME (frame, 0); 849 CHECK_LIVE_FRAME (frame, 0);
844 850
851 /* I think this should be done with a hook. */
845#ifdef HAVE_X_WINDOWS 852#ifdef HAVE_X_WINDOWS
846 if (FRAME_X_P (XFRAME (frame))) 853 if (FRAME_X_P (XFRAME (frame)))
847 x_make_frame_visible (XFRAME (frame)); 854 x_make_frame_visible (XFRAME (frame));
@@ -862,6 +869,7 @@ If omitted, FRAME defaults to the currently selected frame.")
862 869
863 CHECK_LIVE_FRAME (frame, 0); 870 CHECK_LIVE_FRAME (frame, 0);
864 871
872 /* I think this should be done with a hook. */
865#ifdef HAVE_X_WINDOWS 873#ifdef HAVE_X_WINDOWS
866 if (FRAME_X_P (XFRAME (frame))) 874 if (FRAME_X_P (XFRAME (frame)))
867 x_make_frame_invisible (XFRAME (frame)); 875 x_make_frame_invisible (XFRAME (frame));
@@ -882,6 +890,7 @@ If omitted, FRAME defaults to the currently selected frame.")
882 890
883 CHECK_LIVE_FRAME (frame, 0); 891 CHECK_LIVE_FRAME (frame, 0);
884 892
893 /* I think this should be done with a hook. */
885#ifdef HAVE_X_WINDOWS 894#ifdef HAVE_X_WINDOWS
886 if (FRAME_X_P (XFRAME (frame))) 895 if (FRAME_X_P (XFRAME (frame)))
887 x_iconify_frame (XFRAME (frame)); 896 x_iconify_frame (XFRAME (frame));
@@ -931,6 +940,37 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
931} 940}
932 941
933 942
943DEFUN ("frame-to-front", Fframe_to_front, Sframe_to_front, 1, 1, 0,
944 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
945If FRAME is invisible, make it visible.\n\
946If Emacs is displaying on an ordinary terminal or some other device which\n\
947doesn't support multiple overlapping frames, this function does nothing.")
948 (frame)
949 Lisp_Object frame;
950{
951 CHECK_LIVE_FRAME (frame, 0);
952
953 if (frame_raise_lower_hook)
954 (*frame_raise_lower_hook) (XFRAME (frame), 1);
955
956 return Qnil;
957}
958
959DEFUN ("frame-to-back", Fframe_to_back, Sframe_to_back, 1, 1, 0,
960 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
961If Emacs is displaying on an ordinary terminal or some other device which\n\
962doesn't support multiple overlapping frames, this function does nothing.")
963 (frame)
964 Lisp_Object frame;
965{
966 CHECK_LIVE_FRAME (frame, 0);
967
968 if (frame_raise_lower_hook)
969 (*frame_raise_lower_hook) (XFRAME (frame), 0);
970
971 return Qnil;
972}
973
934 974
935DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus, 975DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
936 1, 2, 0, 976 1, 2, 0,
@@ -1075,6 +1115,7 @@ If FRAME is omitted, return information on the currently selected frame.")
1075 : FRAME_MINIBUF_WINDOW (f)))); 1115 : FRAME_MINIBUF_WINDOW (f))));
1076 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil)); 1116 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
1077 1117
1118 /* I think this should be done with a hook. */
1078#ifdef HAVE_X_WINDOWS 1119#ifdef HAVE_X_WINDOWS
1079 if (FRAME_X_P (f)) 1120 if (FRAME_X_P (f))
1080 x_report_frame_params (f, &alist); 1121 x_report_frame_params (f, &alist);
@@ -1102,6 +1143,7 @@ The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1102 f = XFRAME (frame); 1143 f = XFRAME (frame);
1103 } 1144 }
1104 1145
1146 /* I think this should be done with a hook. */
1105#ifdef HAVE_X_WINDOWS 1147#ifdef HAVE_X_WINDOWS
1106 if (FRAME_X_P (f)) 1148 if (FRAME_X_P (f))
1107#if 1 1149#if 1
@@ -1180,6 +1222,7 @@ but that the idea of the actual height of the frame should not be changed.")
1180 f = XFRAME (frame); 1222 f = XFRAME (frame);
1181 } 1223 }
1182 1224
1225 /* I think this should be done with a hook. */
1183#ifdef HAVE_X_WINDOWS 1226#ifdef HAVE_X_WINDOWS
1184 if (FRAME_X_P (f)) 1227 if (FRAME_X_P (f))
1185 { 1228 {
@@ -1209,6 +1252,7 @@ but that the idea of the actual width of the frame should not be changed.")
1209 f = XFRAME (frame); 1252 f = XFRAME (frame);
1210 } 1253 }
1211 1254
1255 /* I think this should be done with a hook. */
1212#ifdef HAVE_X_WINDOWS 1256#ifdef HAVE_X_WINDOWS
1213 if (FRAME_X_P (f)) 1257 if (FRAME_X_P (f))
1214 { 1258 {
@@ -1234,6 +1278,7 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1234 CHECK_NUMBER (rows, 1); 1278 CHECK_NUMBER (rows, 1);
1235 f = XFRAME (frame); 1279 f = XFRAME (frame);
1236 1280
1281 /* I think this should be done with a hook. */
1237#ifdef HAVE_X_WINDOWS 1282#ifdef HAVE_X_WINDOWS
1238 if (FRAME_X_P (f)) 1283 if (FRAME_X_P (f))
1239 { 1284 {
@@ -1264,6 +1309,7 @@ off the screen.")
1264 CHECK_NUMBER (yoffset, 2); 1309 CHECK_NUMBER (yoffset, 2);
1265 f = XFRAME (frame); 1310 f = XFRAME (frame);
1266 1311
1312 /* I think this should be done with a hook. */
1267#ifdef HAVE_X_WINDOWS 1313#ifdef HAVE_X_WINDOWS
1268 if (FRAME_X_P (f)) 1314 if (FRAME_X_P (f))
1269 x_set_offset (f, XINT (xoffset), XINT (yoffset)); 1315 x_set_offset (f, XINT (xoffset), XINT (yoffset));
@@ -1338,8 +1384,8 @@ syms_of_frame ()
1338 /*&&& init symbols here &&&*/ 1384 /*&&& init symbols here &&&*/
1339 Qframep = intern ("framep"); 1385 Qframep = intern ("framep");
1340 staticpro (&Qframep); 1386 staticpro (&Qframep);
1341 Qlive_frame_p = intern ("live-frame-p"); 1387 Qframe_live_p = intern ("frame-live-p");
1342 staticpro (&Qlive_frame_p); 1388 staticpro (&Qframe_live_p);
1343 Qheight = intern ("height"); 1389 Qheight = intern ("height");
1344 staticpro (&Qheight); 1390 staticpro (&Qheight);
1345 Qicon = intern ("icon"); 1391 Qicon = intern ("icon");
@@ -1396,7 +1442,7 @@ For values specific to the separate minibuffer frame, see\n\
1396 Vdefault_frame_alist = Qnil; 1442 Vdefault_frame_alist = Qnil;
1397 1443
1398 defsubr (&Sframep); 1444 defsubr (&Sframep);
1399 defsubr (&Slive_frame_p); 1445 defsubr (&Sframe_live_p);
1400 defsubr (&Sselect_frame); 1446 defsubr (&Sselect_frame);
1401 defsubr (&Sselected_frame); 1447 defsubr (&Sselected_frame);
1402 defsubr (&Swindow_frame); 1448 defsubr (&Swindow_frame);
@@ -1416,6 +1462,8 @@ For values specific to the separate minibuffer frame, see\n\
1416 defsubr (&Siconify_frame); 1462 defsubr (&Siconify_frame);
1417 defsubr (&Sframe_visible_p); 1463 defsubr (&Sframe_visible_p);
1418 defsubr (&Svisible_frame_list); 1464 defsubr (&Svisible_frame_list);
1465 defsubr (&Sframe_to_front);
1466 defsubr (&Sframe_to_back);
1419 defsubr (&Sredirect_frame_focus); 1467 defsubr (&Sredirect_frame_focus);
1420 defsubr (&Sframe_focus); 1468 defsubr (&Sframe_focus);
1421 defsubr (&Sframe_parameters); 1469 defsubr (&Sframe_parameters);
diff --git a/src/frame.h b/src/frame.h
index 5a3f45a080d..194b62147da 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -306,7 +306,7 @@ typedef struct frame *FRAME_PTR;
306 { \ 306 { \
307 if (! FRAMEP (x) \ 307 if (! FRAMEP (x) \
308 || ! FRAME_LIVE_P (XFRAME (x))) \ 308 || ! FRAME_LIVE_P (XFRAME (x))) \
309 x = wrong_type_argument (Qlive_frame_p, (x)); \ 309 x = wrong_type_argument (Qframe_live_p, (x)); \
310 } 310 }
311 311
312/* FOR_EACH_FRAME (LIST_VAR, FRAME_VAR) followed by a statement is a 312/* FOR_EACH_FRAME (LIST_VAR, FRAME_VAR) followed by a statement is a
@@ -325,7 +325,7 @@ typedef struct frame *FRAME_PTR;
325 list_var = XCONS (list_var)->cdr) 325 list_var = XCONS (list_var)->cdr)
326 326
327 327
328extern Lisp_Object Qframep, Qlive_frame_p; 328extern Lisp_Object Qframep, Qframe_live_p;
329 329
330extern struct frame *selected_frame; 330extern struct frame *selected_frame;
331extern struct frame *last_nonminibuf_frame; 331extern struct frame *last_nonminibuf_frame;
diff --git a/src/insdel.c b/src/insdel.c
index 256102dfe9d..7f25a967d46 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -545,10 +545,10 @@ signal_before_change (start, end)
545{ 545{
546 /* If buffer is unmodified, run a special hook for that case. */ 546 /* If buffer is unmodified, run a special hook for that case. */
547 if (current_buffer->save_modified >= MODIFF 547 if (current_buffer->save_modified >= MODIFF
548 && !NILP (Vfirst_change_function)) 548 && !NILP (Vfirst_change_hook)
549 { 549 && !NILP (Vrun_hooks))
550 call0 (Vfirst_change_function); 550 call1 (Vrun_hooks, Qfirst_change_hook);
551 } 551
552 /* Now in any case run the before-change-function if any. */ 552 /* Now in any case run the before-change-function if any. */
553 if (!NILP (Vbefore_change_function)) 553 if (!NILP (Vbefore_change_function))
554 { 554 {
diff --git a/src/keyboard.c b/src/keyboard.c
index 3c139c68644..6585c29a914 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -152,12 +152,12 @@ Lisp_Object last_nonmenu_event;
152/* Last input character read for any purpose. */ 152/* Last input character read for any purpose. */
153Lisp_Object last_input_char; 153Lisp_Object last_input_char;
154 154
155/* If not Qnil, an object to be read as the next command input. */ 155/* If not Qnil, a list of objects to be read as subsequent command input. */
156Lisp_Object unread_command_event; 156Lisp_Object unread_command_events;
157 157
158/* If not Qnil, this is a switch-frame event which we decided to put 158/* If not Qnil, this is a switch-frame event which we decided to put
159 off until the end of a key sequence. This should be read as the 159 off until the end of a key sequence. This should be read as the
160 next command input, after any unread_command_event. 160 next command input, after any unread_command_events.
161 161
162 read_key_sequence uses this to delay switch-frame events until the 162 read_key_sequence uses this to delay switch-frame events until the
163 end of the key sequence; Fread_char uses it to put off switch-frame 163 end of the key sequence; Fread_char uses it to put off switch-frame
@@ -867,7 +867,7 @@ command_loop_1 ()
867 if (!NILP (Vquit_flag)) 867 if (!NILP (Vquit_flag))
868 { 868 {
869 Vquit_flag = Qnil; 869 Vquit_flag = Qnil;
870 unread_command_event = make_number (quit_char); 870 unread_command_events = Fcons (make_number (quit_char), Qnil);
871 } 871 }
872 } 872 }
873 873
@@ -1145,10 +1145,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
1145 int count; 1145 int count;
1146 jmp_buf save_jump; 1146 jmp_buf save_jump;
1147 1147
1148 if (!NILP (unread_command_event)) 1148 if (CONSP (unread_command_events))
1149 { 1149 {
1150 c = unread_command_event; 1150 c = XCONS (unread_command_events)->car;
1151 unread_command_event = Qnil; 1151 unread_command_events = XCONS (unread_command_events)->cdr;
1152 1152
1153 if (this_command_key_count == 0) 1153 if (this_command_key_count == 0)
1154 goto reread_first; 1154 goto reread_first;
@@ -1229,7 +1229,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
1229 /* After a mouse event, start echoing right away. 1229 /* After a mouse event, start echoing right away.
1230 This is because we are probably about to display a menu, 1230 This is because we are probably about to display a menu,
1231 and we don't want to delay before doing so. */ 1231 and we don't want to delay before doing so. */
1232 if (XTYPE (prev_event) == Lisp_Cons) 1232 if (EVENT_HAS_PARAMETERS (prev_event))
1233 echo (); 1233 echo ();
1234 else 1234 else
1235 { 1235 {
@@ -1880,7 +1880,8 @@ make_lispy_event (event)
1880 { 1880 {
1881 int button = XFASTINT (event->code); 1881 int button = XFASTINT (event->code);
1882 Lisp_Object position; 1882 Lisp_Object position;
1883 Lisp_Object *start_pos; 1883 Lisp_Object *start_pos_ptr;
1884 Lisp_Object start_pos;
1884 1885
1885 if (button < 0 || button >= NUM_MOUSE_BUTTONS) 1886 if (button < 0 || button >= NUM_MOUSE_BUTTONS)
1886 abort (); 1887 abort ();
@@ -1899,21 +1900,20 @@ make_lispy_event (event)
1899 posn = Qnil; 1900 posn = Qnil;
1900 else 1901 else
1901 { 1902 {
1903 XSETINT (event->x,
1904 (XINT (event->x) - XINT (XWINDOW (window)->left)));
1905 XSETINT (event->y,
1906 (XINT (event->y) - XINT (XWINDOW (window)->top)));
1907
1902 if (part == 1) 1908 if (part == 1)
1903 posn = Qmode_line; 1909 posn = Qmode_line;
1904 else if (part == 2) 1910 else if (part == 2)
1905 posn = Qvertical_line; 1911 posn = Qvertical_line;
1906 else 1912 else
1907 { 1913 XSET (posn, Lisp_Int,
1908 XSETINT (event->x, (XINT (event->x) 1914 buffer_posn_from_coords (XWINDOW (window),
1909 - XINT (XWINDOW (window)->left))); 1915 XINT (event->x),
1910 XSETINT (event->y, (XINT (event->y) 1916 XINT (event->y)));
1911 - XINT (XWINDOW (window)->top)));
1912 XSET (posn, Lisp_Int,
1913 buffer_posn_from_coords (XWINDOW (window),
1914 XINT (event->x),
1915 XINT (event->y)));
1916 }
1917 } 1917 }
1918 1918
1919 position = 1919 position =
@@ -1938,29 +1938,43 @@ make_lispy_event (event)
1938 Qnil))))); 1938 Qnil)))));
1939 } 1939 }
1940 1940
1941 start_pos = &XVECTOR (button_down_location)->contents[button]; 1941 start_pos_ptr = &XVECTOR (button_down_location)->contents[button];
1942
1943 start_pos = *start_pos_ptr;
1944 *start_pos_ptr = Qnil;
1942 1945
1943 /* If this is a button press, squirrel away the location, so 1946 /* If this is a button press, squirrel away the location, so
1944 we can decide later whether it was a click or a drag. */ 1947 we can decide later whether it was a click or a drag. */
1945 if (event->modifiers & down_modifier) 1948 if (event->modifiers & down_modifier)
1946 *start_pos = Fcopy_alist (position); 1949 *start_pos_ptr = Fcopy_alist (position);
1947 1950
1948 /* Now we're releasing a button - check the co-ordinates to 1951 /* Now we're releasing a button - check the co-ordinates to
1949 see if this was a click or a drag. */ 1952 see if this was a click or a drag. */
1950 else if (event->modifiers & up_modifier) 1953 else if (event->modifiers & up_modifier)
1951 { 1954 {
1952 Lisp_Object down = Fnth (make_number (2), *start_pos); 1955 /* Is there a start position stored at all for this
1953 1956 button?
1954 /* The third element of every position should be the (x,y) 1957
1955 pair. */ 1958 It would be nice if we could assume that if we're
1956 if (! CONSP (down)) 1959 getting a button release, we must therefore have gotten
1957 abort (); 1960 a button press. Unfortunately, the X menu code thwarts
1958 1961 this assumption, so we'll have to be more robust. We
1962 treat a button release with no stored start position as
1963 a click. */
1959 event->modifiers &= ~up_modifier; 1964 event->modifiers &= ~up_modifier;
1960 event->modifiers |= ((EQ (event->x, XCONS (down)->car) 1965 if (XTYPE (start_pos) != Lisp_Cons)
1961 && EQ (event->y, XCONS (down)->cdr)) 1966 event->modifiers |= click_modifier;
1962 ? click_modifier 1967 else
1963 : drag_modifier); 1968 {
1969 /* The third element of every position should be the (x,y)
1970 pair. */
1971 Lisp_Object down = Fnth (make_number (2), start_pos);
1972
1973 event->modifiers |= ((EQ (event->x, XCONS (down)->car)
1974 && EQ (event->y, XCONS (down)->cdr))
1975 ? click_modifier
1976 : drag_modifier);
1977 }
1964 } 1978 }
1965 else 1979 else
1966 /* Every mouse event should either have the down_modifier or 1980 /* Every mouse event should either have the down_modifier or
@@ -1978,18 +1992,10 @@ make_lispy_event (event)
1978 / sizeof (lispy_mouse_names[0]))); 1992 / sizeof (lispy_mouse_names[0])));
1979 1993
1980 if (event->modifiers & drag_modifier) 1994 if (event->modifiers & drag_modifier)
1981 { 1995 return Fcons (head,
1982 Lisp_Object lispy_event = 1996 Fcons (start_pos,
1983 Fcons (head, 1997 Fcons (position,
1984 Fcons (*start_pos, 1998 Qnil)));
1985 Fcons (position,
1986 Qnil)));
1987
1988 /* Allow this to be GC'd. */
1989 *start_pos = Qnil;
1990
1991 return lispy_event;
1992 }
1993 else 1999 else
1994 return Fcons (head, 2000 return Fcons (head,
1995 Fcons (position, 2001 Fcons (position,
@@ -2454,21 +2460,6 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_table,
2454} 2460}
2455 2461
2456 2462
2457DEFUN ("mouse-click-p", Fmouse_click_p, Smouse_click_p, 1, 1, 0,
2458 "Return non-nil iff OBJECT is a representation of a mouse event.\n\
2459A mouse event is a list of five elements whose car is a symbol of the\n\
2460form <MODIFIERS>mouse-<DIGIT>. I hope this is a temporary hack.")
2461 (object)
2462 Lisp_Object object;
2463{
2464 if (EVENT_HAS_PARAMETERS (object)
2465 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (object)),
2466 Qmouse_click))
2467 return Qt;
2468 else
2469 return Qnil;
2470}
2471
2472/* Store into *addr a value nonzero if terminal input chars are available. 2463/* Store into *addr a value nonzero if terminal input chars are available.
2473 Serves the purpose of ioctl (0, FIONREAD, addr) 2464 Serves the purpose of ioctl (0, FIONREAD, addr)
2474 but works even if FIONREAD does not exist. 2465 but works even if FIONREAD does not exist.
@@ -2686,7 +2677,9 @@ static int echo_flag;
2686static int echo_now; 2677static int echo_now;
2687 2678
2688/* Read a character like read_char but optionally prompt based on maps 2679/* Read a character like read_char but optionally prompt based on maps
2689 in the array MAPS. NMAPS is the length of MAPS. 2680 in the array MAPS. NMAPS is the length of MAPS. Return nil if we
2681 decided not to read a character, because there are no menu items in
2682 MAPS.
2690 2683
2691 PREV_EVENT is the previous input event, or nil if we are reading 2684 PREV_EVENT is the previous input event, or nil if we are reading
2692 the first event of a key sequence. 2685 the first event of a key sequence.
@@ -2730,14 +2723,14 @@ read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
2730 } 2723 }
2731 2724
2732 /* If we don't have any menus, just read a character normally. */ 2725 /* If we don't have any menus, just read a character normally. */
2733 if (NILP (name)) 2726 if (mapno >= nmaps)
2734 return Qnil; 2727 return Qnil;
2735 2728
2736#ifdef HAVE_X_WINDOW 2729#ifdef HAVE_X_WINDOWS
2737#ifndef NO_X_MENU 2730#ifdef HAVE_X_MENU
2738 /* If we got to this point via a mouse click, 2731 /* If we got to this point via a mouse click,
2739 use a real menu for mouse selection. */ 2732 use a real menu for mouse selection. */
2740 if (XTYPE (prev_event) == Lisp_Cons) 2733 if (EVENT_HAS_PARAMETERS (prev_event))
2741 { 2734 {
2742 /* Display the menu and get the selection. */ 2735 /* Display the menu and get the selection. */
2743 Lisp_Object *realmaps 2736 Lisp_Object *realmaps
@@ -2757,8 +2750,8 @@ read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu)
2757 *used_mouse_menu = 1; 2750 *used_mouse_menu = 1;
2758 return value; 2751 return value;
2759 } 2752 }
2760#endif /* not NO_X_MENU */ 2753#endif /* HAVE_X_MENU */
2761#endif /* HAVE_X_WINDOW */ 2754#endif /* HAVE_X_WINDOWS */
2762 2755
2763 /* Prompt string always starts with map's prompt, and a space. */ 2756 /* Prompt string always starts with map's prompt, and a space. */
2764 strcpy (menu, XSTRING (name)->data); 2757 strcpy (menu, XSTRING (name)->data);
@@ -3677,7 +3670,7 @@ DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 0,
3677Actually, the value is nil only if we can be sure that no input is available.") 3670Actually, the value is nil only if we can be sure that no input is available.")
3678 () 3671 ()
3679{ 3672{
3680 if (!NILP (unread_command_event)) 3673 if (!NILP (unread_command_events))
3681 return (Qt); 3674 return (Qt);
3682 3675
3683 return detect_input_pending () ? Qt : Qnil; 3676 return detect_input_pending () ? Qt : Qnil;
@@ -3749,7 +3742,7 @@ Also cancel any kbd macro being defined.")
3749 defining_kbd_macro = 0; 3742 defining_kbd_macro = 0;
3750 update_mode_lines++; 3743 update_mode_lines++;
3751 3744
3752 unread_command_event = Qnil; 3745 unread_command_events = Qnil;
3753 3746
3754 discard_tty_input (); 3747 discard_tty_input ();
3755 3748
@@ -3997,7 +3990,7 @@ quit_throw_to_read_char ()
3997 clear_waiting_for_input (); 3990 clear_waiting_for_input ();
3998 input_pending = 0; 3991 input_pending = 0;
3999 3992
4000 unread_command_event = Qnil; 3993 unread_command_events = Qnil;
4001 3994
4002 _longjmp (getcjmp, 1); 3995 _longjmp (getcjmp, 1);
4003} 3996}
@@ -4051,7 +4044,7 @@ init_keyboard ()
4051 command_loop_level = -1; 4044 command_loop_level = -1;
4052 immediate_quit = 0; 4045 immediate_quit = 0;
4053 quit_char = Ctl ('g'); 4046 quit_char = Ctl ('g');
4054 unread_command_event = Qnil; 4047 unread_command_events = Qnil;
4055 total_keys = 0; 4048 total_keys = 0;
4056 recent_keys_index = 0; 4049 recent_keys_index = 0;
4057 kbd_fetch_ptr = kbd_buffer; 4050 kbd_fetch_ptr = kbd_buffer;
@@ -4219,7 +4212,6 @@ syms_of_keyboard ()
4219 defsubr (&Sread_key_sequence); 4212 defsubr (&Sread_key_sequence);
4220 defsubr (&Srecursive_edit); 4213 defsubr (&Srecursive_edit);
4221 defsubr (&Strack_mouse); 4214 defsubr (&Strack_mouse);
4222 defsubr (&Smouse_click_p);
4223 defsubr (&Sinput_pending_p); 4215 defsubr (&Sinput_pending_p);
4224 defsubr (&Scommand_execute); 4216 defsubr (&Scommand_execute);
4225 defsubr (&Srecent_keys); 4217 defsubr (&Srecent_keys);
@@ -4250,8 +4242,8 @@ so that you can determine whether the command was run by mouse or not.");
4250 DEFVAR_LISP ("last-input-char", &last_input_char, 4242 DEFVAR_LISP ("last-input-char", &last_input_char,
4251 "Last terminal input key."); 4243 "Last terminal input key.");
4252 4244
4253 DEFVAR_LISP ("unread-command-event", &unread_command_event, 4245 DEFVAR_LISP ("unread-command-events", &unread_command_events,
4254 "Object to be read as next input from input stream, or nil if none."); 4246 "Lisp of object to be read as next input from input stream, or nil if none.");
4255 4247
4256 DEFVAR_LISP ("meta-prefix-char", &meta_prefix_char, 4248 DEFVAR_LISP ("meta-prefix-char", &meta_prefix_char,
4257 "Meta-prefix character code. Meta-foo as command input\n\ 4249 "Meta-prefix character code. Meta-foo as command input\n\
diff --git a/src/keyboard.h b/src/keyboard.h
index c7048fd6c0c..1d4a82256d0 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -1,5 +1,5 @@
1/* Declarations useful when processing input. 1/* Declarations useful when processing input.
2 Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -84,7 +84,6 @@ extern Lisp_Object Qmode_line, Qvertical_line;
84extern Lisp_Object get_keymap_1 (); 84extern Lisp_Object get_keymap_1 ();
85extern Lisp_Object Fkeymapp (); 85extern Lisp_Object Fkeymapp ();
86extern Lisp_Object reorder_modifiers (); 86extern Lisp_Object reorder_modifiers ();
87extern Lisp_Object Fmouse_click_p ();
88extern Lisp_Object read_char (); 87extern Lisp_Object read_char ();
89/* User-supplied string to translate input characters through. */ 88/* User-supplied string to translate input characters through. */
90extern Lisp_Object Vkeyboard_translate_table; 89extern Lisp_Object Vkeyboard_translate_table;
diff --git a/src/keymap.c b/src/keymap.c
index 5282711bac0..e1b61f5db90 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -555,8 +555,14 @@ the front of KEYMAP.")
555 555
556 keymap = get_keymap_1 (cmd, 0, 1); 556 keymap = get_keymap_1 (cmd, 0, 1);
557 if (NILP (keymap)) 557 if (NILP (keymap))
558 error ("Key sequence %s uses invalid prefix characters", 558 {
559 XSTRING (key)->data); 559 /* We must use Fkey_description rather than just passing key to
560 error; key might be a vector, not a string. */
561 Lisp_Object description = Fkey_description (key);
562
563 error ("Key sequence %s uses invalid prefix characters",
564 XSTRING (description)->data);
565 }
560 } 566 }
561} 567}
562 568
diff --git a/src/lread.c b/src/lread.c
index 0198dda9aca..721955c358b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -203,7 +203,7 @@ If you want to read non-character events, or ignore them, call\n\
203 /* Only ASCII characters are acceptable. */ 203 /* Only ASCII characters are acceptable. */
204 if (XTYPE (val) != Lisp_Int) 204 if (XTYPE (val) != Lisp_Int)
205 { 205 {
206 unread_command_event = val; 206 unread_command_events = Fcons (val, Qnil);
207 error ("Object read was not a character"); 207 error ("Object read was not a character");
208 } 208 }
209 } 209 }
@@ -1045,9 +1045,17 @@ read1 (readcharfun)
1045 if (p1 != p) 1045 if (p1 != p)
1046 { 1046 {
1047 while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++; 1047 while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++;
1048#ifdef LISP_FLOAT_TYPE
1049 /* Integers can have trailing decimal points. */
1050 if (p1 < p && *p1 == '.') p1++;
1051#endif
1048 if (p1 == p) 1052 if (p1 == p)
1049 /* It is. */ 1053 /* It is an integer. */
1050 { 1054 {
1055#ifdef LISP_FLOAT_TYPE
1056 if (p1[-1] == '.')
1057 p1[-1] = '\0';
1058#endif
1051 XSET (val, Lisp_Int, atoi (read_buffer)); 1059 XSET (val, Lisp_Int, atoi (read_buffer));
1052 return val; 1060 return val;
1053 } 1061 }
diff --git a/src/minibuf.c b/src/minibuf.c
index c3625565000..bc1074c89d0 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1,5 +1,5 @@
1/* Minibuffer input and completion. 1/* Minibuffer input and completion.
2 Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -930,7 +930,7 @@ temp_echo_area_glyphs (m)
930 if (!NILP (Vquit_flag)) 930 if (!NILP (Vquit_flag))
931 { 931 {
932 Vquit_flag = Qnil; 932 Vquit_flag = Qnil;
933 XFASTINT (unread_command_event) = Ctl ('g'); 933 unread_command_events = Fcons (make_number (Ctl ('g')), Qnil);
934 } 934 }
935 Vinhibit_quit = oinhibit; 935 Vinhibit_quit = oinhibit;
936} 936}
diff --git a/src/term.c b/src/term.c
index f0cb67b8f6d..cd9e5a84a44 100644
--- a/src/term.c
+++ b/src/term.c
@@ -125,6 +125,18 @@ void (*mouse_position_hook) ( /* FRAME_PTR *f,
125 the highlight. */ 125 the highlight. */
126void (*frame_rehighlight_hook) ( /* FRAME_PTR f */ ); 126void (*frame_rehighlight_hook) ( /* FRAME_PTR f */ );
127 127
128/* If we're displaying frames using a window system that can stack
129 frames on top of each other, this hook allows you to bring a frame
130 to the front, or bury it behind all the other windows. If this
131 hook is zero, that means the device we're displaying on doesn't
132 support overlapping frames, so there's no need to raise or lower
133 anything.
134
135 If RAISE is non-zero, F is brought to the front, before all other
136 windows. If RAISE is zero, F is sent to the back, behind all other
137 windows. */
138void (*frame_raise_lower_hook) ( /* FRAME_PTR f, int raise */ );
139
128/* Set the vertical scrollbar for WINDOW to have its upper left corner 140/* Set the vertical scrollbar for WINDOW to have its upper left corner
129 at (TOP, LEFT), and be LENGTH rows high. Set its handle to 141 at (TOP, LEFT), and be LENGTH rows high. Set its handle to
130 indicate that we are displaying PORTION characters out of a total 142 indicate that we are displaying PORTION characters out of a total
diff --git a/src/termhooks.h b/src/termhooks.h
index 9b2c0146ce0..ce9e2ed3d45 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -96,6 +96,17 @@ extern int mouse_moved;
96 X, this means that Emacs lies about where the focus is. */ 96 X, this means that Emacs lies about where the focus is. */
97extern void (*frame_rehighlight_hook) ( /* void */ ); 97extern void (*frame_rehighlight_hook) ( /* void */ );
98 98
99/* If we're displaying frames using a window system that can stack
100 frames on top of each other, this hook allows you to bring a frame
101 to the front, or bury it behind all the other windows. If this
102 hook is zero, that means the device we're displaying on doesn't
103 support overlapping frames, so there's no need to raise or lower
104 anything.
105
106 If RAISE is non-zero, F is brought to the front, before all other
107 windows. If RAISE is zero, F is sent to the back, behind all other
108 windows. */
109extern void (*frame_raise_lower_hook) ( /* FRAME_PTR f, int raise */ );
99 110
100 111
101/* Scrollbar hooks. */ 112/* Scrollbar hooks. */
diff --git a/src/window.c b/src/window.c
index a14599bf786..b788c8f3fae 100644
--- a/src/window.c
+++ b/src/window.c
@@ -60,9 +60,6 @@ Lisp_Object Vminibuf_scroll_window;
60/* Non-nil means this is the buffer whose window C-M-v should scroll. */ 60/* Non-nil means this is the buffer whose window C-M-v should scroll. */
61Lisp_Object Vother_window_scroll_buffer; 61Lisp_Object Vother_window_scroll_buffer;
62 62
63/* Window that the mouse is over (nil if no mouse support). */
64Lisp_Object Vmouse_window;
65
66/* Last mouse click data structure (nil if no mouse support). */ 63/* Last mouse click data structure (nil if no mouse support). */
67Lisp_Object Vmouse_event; 64Lisp_Object Vmouse_event;
68 65
@@ -811,7 +808,12 @@ minibuffer does not count, only windows from WINDOW's frame count.\n\
811\n\ 808\n\
812Optional third arg ALL-FRAMES t means include windows on all frames.\n\ 809Optional third arg ALL-FRAMES t means include windows on all frames.\n\
813ALL-FRAMES nil or omitted means cycle within the frames as specified\n\ 810ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
814above. If neither nil nor t, restrict to WINDOW's frame.") 811above. If neither nil nor t, restrict to WINDOW's frame.\n\
812\n\
813If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
814`next-window' to iterate through the entire cycle of acceptable\n\
815windows, eventually ending up back at the window you started with.\n\
816`previous-window' traverses the same cycle, in the reverse order.")
815 (window, minibuf, all_frames) 817 (window, minibuf, all_frames)
816 register Lisp_Object window, minibuf, all_frames; 818 register Lisp_Object window, minibuf, all_frames;
817{ 819{
@@ -908,7 +910,12 @@ count.\n\
908\n\ 910\n\
909Optional third arg ALL-FRAMES t means include windows on all frames.\n\ 911Optional third arg ALL-FRAMES t means include windows on all frames.\n\
910ALL-FRAMES nil or omitted means cycle within the frames as specified\n\ 912ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
911above. If neither nil nor t, restrict to WINDOW's frame.") 913above. If neither nil nor t, restrict to WINDOW's frame.\n\
914\n\
915If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
916`previous-window' to iterate through the entire cycle of acceptable\n\
917windows, eventually ending up back at the window you started with.\n\
918`next-window' traverses the same cycle, in the reverse order.")
912 (window, minibuf, all_frames) 919 (window, minibuf, all_frames)
913 register Lisp_Object window, minibuf, all_frames; 920 register Lisp_Object window, minibuf, all_frames;
914{ 921{
@@ -955,7 +962,16 @@ above. If neither nil nor t, restrict to WINDOW's frame.")
955 tem = WINDOW_FRAME (XWINDOW (window)); 962 tem = WINDOW_FRAME (XWINDOW (window));
956#ifdef MULTI_FRAME 963#ifdef MULTI_FRAME
957 if (! NILP (all_frames)) 964 if (! NILP (all_frames))
958 tem = next_frame (tem, all_frames); 965 /* It's actually important that we use prev_frame here,
966 rather than next_frame. All the windows acceptable
967 according to the given parameters should form a ring;
968 Fnext_window and Fprevious_window should go back and
969 forth around the ring. If we use next_frame here,
970 then Fnext_window and Fprevious_window take different
971 paths through the set of acceptable windows.
972 window_loop assumes that these `ring' requirement are
973 met. */
974 tem = prev_frame (tem, all_frames);
959#endif 975#endif
960 tem = FRAME_ROOT_WINDOW (XFRAME (tem)); 976 tem = FRAME_ROOT_WINDOW (XFRAME (tem));
961 977
@@ -2205,8 +2221,20 @@ showing that buffer, popping the buffer up if necessary.")
2205 window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt); 2221 window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt);
2206 } 2222 }
2207 else 2223 else
2208 /* Nothing specified; pick a neighboring window. */ 2224 {
2209 window = Fnext_window (selected_window, Qnil, Qt); 2225 /* Nothing specified; look for a neighboring window on the same
2226 frame. */
2227 window = Fnext_window (selected_window, Qnil, Qnil);
2228
2229 if (EQ (window, selected_window))
2230 /* That didn't get us anywhere; look for a window on another
2231 visible frame. */
2232 do
2233 window = Fnext_window (window, Qnil, Qt);
2234 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window))))
2235 && ! EQ (window, selected_window));
2236 }
2237
2210 CHECK_LIVE_WINDOW (window, 0); 2238 CHECK_LIVE_WINDOW (window, 0);
2211 2239
2212 if (EQ (window, selected_window)) 2240 if (EQ (window, selected_window))
@@ -2866,10 +2894,6 @@ Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
2866work using this function."); 2894work using this function.");
2867 Vdisplay_buffer_function = Qnil; 2895 Vdisplay_buffer_function = Qnil;
2868 2896
2869 DEFVAR_LISP ("mouse-window", &Vmouse_window,
2870 "Window that the last mouse click occurred on.");
2871 Vmouse_window = Qnil;
2872
2873 DEFVAR_LISP ("mouse-event", &Vmouse_event, 2897 DEFVAR_LISP ("mouse-event", &Vmouse_event,
2874 "The last mouse-event object. A list of four elements:\n\ 2898 "The last mouse-event object. A list of four elements:\n\
2875 ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\ 2899 ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\
diff --git a/src/xfns.c b/src/xfns.c
index cb5aaca7af7..5b9f7da731f 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -37,6 +37,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
37#ifdef HAVE_X_WINDOWS 37#ifdef HAVE_X_WINDOWS
38extern void abort (); 38extern void abort ();
39 39
40#include <X11/bitmaps/gray>
41
40#define min(a,b) ((a) < (b) ? (a) : (b)) 42#define min(a,b) ((a) < (b) ? (a) : (b))
41#define max(a,b) ((a) > (b) ? (a) : (b)) 43#define max(a,b) ((a) > (b) ? (a) : (b))
42 44
@@ -58,9 +60,6 @@ Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
58/* Color of chars displayed in cursor box. */ 60/* Color of chars displayed in cursor box. */
59Lisp_Object Vx_cursor_fore_pixel; 61Lisp_Object Vx_cursor_fore_pixel;
60 62
61/* If non-nil, use vertical bar cursor. */
62Lisp_Object Vbar_cursor;
63
64/* The X Visual we are using for X windows (the default) */ 63/* The X Visual we are using for X windows (the default) */
65Visual *screen_visual; 64Visual *screen_visual;
66 65
@@ -115,7 +114,6 @@ static char *x_visual_strings[] =
115Lisp_Object Vmouse_depressed; 114Lisp_Object Vmouse_depressed;
116 115
117extern unsigned int x_mouse_x, x_mouse_y, x_mouse_grabbed; 116extern unsigned int x_mouse_x, x_mouse_y, x_mouse_grabbed;
118extern Lisp_Object unread_command_event;
119 117
120/* Atom for indicating window state to the window manager. */ 118/* Atom for indicating window state to the window manager. */
121Atom Xatom_wm_change_state; 119Atom Xatom_wm_change_state;
@@ -123,9 +121,6 @@ Atom Xatom_wm_change_state;
123/* When emacs became the selection owner. */ 121/* When emacs became the selection owner. */
124extern Time x_begin_selection_own; 122extern Time x_begin_selection_own;
125 123
126/* The value of the current emacs selection. */
127extern Lisp_Object Vx_selection_value;
128
129/* Emacs' selection property identifier. */ 124/* Emacs' selection property identifier. */
130extern Atom Xatom_emacs_selection; 125extern Atom Xatom_emacs_selection;
131 126
@@ -228,9 +223,12 @@ Time mouse_timestamp;
228Lisp_Object Qauto_raise; 223Lisp_Object Qauto_raise;
229Lisp_Object Qauto_lower; 224Lisp_Object Qauto_lower;
230Lisp_Object Qbackground_color; 225Lisp_Object Qbackground_color;
226Lisp_Object Qbar;
231Lisp_Object Qborder_color; 227Lisp_Object Qborder_color;
232Lisp_Object Qborder_width; 228Lisp_Object Qborder_width;
229Lisp_Object Qbox;
233Lisp_Object Qcursor_color; 230Lisp_Object Qcursor_color;
231Lisp_Object Qcursor_type;
234Lisp_Object Qfont; 232Lisp_Object Qfont;
235Lisp_Object Qforeground_color; 233Lisp_Object Qforeground_color;
236Lisp_Object Qgeometry; 234Lisp_Object Qgeometry;
@@ -261,14 +259,6 @@ extern Lisp_Object Vglobal_mouse_map;
261 259
262/* Points to table of defined typefaces. */ 260/* Points to table of defined typefaces. */
263struct face *x_face_table[MAX_FACES_AND_GLYPHS]; 261struct face *x_face_table[MAX_FACES_AND_GLYPHS];
264
265static char gray_bits[] =
266 {
267 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
268 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
269 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
270 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa
271 };
272 262
273/* Return the Emacs frame-object corresponding to an X window. 263/* Return the Emacs frame-object corresponding to an X window.
274 It could be the frame's main window or an icon window. */ 264 It could be the frame's main window or an icon window. */
@@ -330,6 +320,7 @@ void x_set_background_color ();
330void x_set_mouse_color (); 320void x_set_mouse_color ();
331void x_set_cursor_color (); 321void x_set_cursor_color ();
332void x_set_border_color (); 322void x_set_border_color ();
323void x_set_cursor_type ();
333void x_set_icon_type (); 324void x_set_icon_type ();
334void x_set_font (); 325void x_set_font ();
335void x_set_border_width (); 326void x_set_border_width ();
@@ -346,6 +337,7 @@ static struct x_frame_parm_table x_frame_parms[] =
346 "mouse-color", x_set_mouse_color, 337 "mouse-color", x_set_mouse_color,
347 "cursor-color", x_set_cursor_color, 338 "cursor-color", x_set_cursor_color,
348 "border-color", x_set_border_color, 339 "border-color", x_set_border_color,
340 "cursor-type", x_set_cursor_type,
349 "icon-type", x_set_icon_type, 341 "icon-type", x_set_icon_type,
350 "font", x_set_font, 342 "font", x_set_font,
351 "border-width", x_set_border_width, 343 "border-width", x_set_border_width,
@@ -808,7 +800,8 @@ x_set_border_pixel (f, pix)
808 pix); 800 pix);
809#else 801#else
810 if (pix < 0) 802 if (pix < 0)
811 temp = XMakePixmap ((Bitmap) XStoreBitmap (16, 16, gray_bits), 803 temp = XMakePixmap ((Bitmap) XStoreBitmap (gray_width, gray_height,
804 gray_bits),
812 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT); 805 BLACK_PIX_DEFAULT, WHITE_PIX_DEFAULT);
813 else 806 else
814 temp = XMakeTile (pix); 807 temp = XMakeTile (pix);
@@ -823,6 +816,24 @@ x_set_border_pixel (f, pix)
823} 816}
824 817
825void 818void
819x_set_cursor_type (f, arg, oldval)
820 FRAME_PTR f;
821 Lisp_Object arg, oldval;
822{
823 if (EQ (arg, Qbar))
824 FRAME_DESIRED_CURSOR (f) = bar_cursor;
825 else if (EQ (arg, Qbox))
826 FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
827 else
828 error
829 ("the `cursor-type' frame parameter should be either `bar' or `box'");
830
831 /* Make sure the cursor gets redrawn. This is overkill, but how
832 often do people change cursor types? */
833 update_mode_lines++;
834}
835
836void
826x_set_icon_type (f, arg, oldval) 837x_set_icon_type (f, arg, oldval)
827 struct frame *f; 838 struct frame *f;
828 Lisp_Object arg, oldval; 839 Lisp_Object arg, oldval;
@@ -1796,31 +1807,12 @@ x_make_gc (f)
1796 the frame. Since this depends on the frame's pixel values, 1807 the frame. Since this depends on the frame's pixel values,
1797 this must be done on a per-frame basis. */ 1808 this must be done on a per-frame basis. */
1798 f->display.x->border_tile = 1809 f->display.x->border_tile =
1799 XCreatePixmap (x_current_display, ROOT_WINDOW, 16, 16, 1810 XCreatePixmapFromBitmapData
1800 DefaultDepth (x_current_display, 1811 (x_current_display, ROOT_WINDOW,
1801 XDefaultScreen (x_current_display))); 1812 gray_bits, gray_width, gray_height,
1802 gc_values.foreground = f->display.x->foreground_pixel; 1813 f->display.x->foreground_pixel,
1803 gc_values.background = f->display.x->background_pixel; 1814 f->display.x->background_pixel,
1804 temp_gc = XCreateGC (x_current_display, 1815 DefaultDepth (x_current_display, XDefaultScreen (x_current_display)));
1805 (Drawable) f->display.x->border_tile,
1806 GCForeground | GCBackground, &gc_values);
1807
1808 /* These are things that should be determined by the server, in
1809 Fx_open_connection */
1810 tileimage.height = 16;
1811 tileimage.width = 16;
1812 tileimage.xoffset = 0;
1813 tileimage.format = XYBitmap;
1814 tileimage.data = gray_bits;
1815 tileimage.byte_order = LSBFirst;
1816 tileimage.bitmap_unit = 8;
1817 tileimage.bitmap_bit_order = LSBFirst;
1818 tileimage.bitmap_pad = 8;
1819 tileimage.bytes_per_line = (16 + 7) >> 3;
1820 tileimage.depth = 1;
1821 XPutImage (x_current_display, f->display.x->border_tile, temp_gc,
1822 &tileimage, 0, 0, 0, 0, 16, 16);
1823 XFreeGC (x_current_display, temp_gc);
1824} 1816}
1825#endif /* HAVE_X11 */ 1817#endif /* HAVE_X11 */
1826 1818
@@ -1930,6 +1922,8 @@ be shared by the new frame.")
1930 "autoRaise", "AutoRaiseLower", boolean); 1922 "autoRaise", "AutoRaiseLower", boolean);
1931 x_default_parameter (f, parms, Qauto_lower, Qnil, 1923 x_default_parameter (f, parms, Qauto_lower, Qnil,
1932 "autoLower", "AutoRaiseLower", boolean); 1924 "autoLower", "AutoRaiseLower", boolean);
1925 x_default_parameter (f, parms, Qcursor_type, Qbox,
1926 "cursorType", "CursorType", symbol);
1933 1927
1934 /* Dimensions, especially f->height, must be done via change_frame_size. 1928 /* Dimensions, especially f->height, must be done via change_frame_size.
1935 Change will not be effected unless different from the current 1929 Change will not be effected unless different from the current
@@ -3784,12 +3778,18 @@ syms_of_xfns ()
3784 staticpro (&Qauto_lower); 3778 staticpro (&Qauto_lower);
3785 Qbackground_color = intern ("background-color"); 3779 Qbackground_color = intern ("background-color");
3786 staticpro (&Qbackground_color); 3780 staticpro (&Qbackground_color);
3781 Qbar = intern ("bar");
3782 staticpro (&Qbar);
3787 Qborder_color = intern ("border-color"); 3783 Qborder_color = intern ("border-color");
3788 staticpro (&Qborder_color); 3784 staticpro (&Qborder_color);
3789 Qborder_width = intern ("border-width"); 3785 Qborder_width = intern ("border-width");
3790 staticpro (&Qborder_width); 3786 staticpro (&Qborder_width);
3787 Qbox = intern ("box");
3788 staticpro (&Qbox);
3791 Qcursor_color = intern ("cursor-color"); 3789 Qcursor_color = intern ("cursor-color");
3792 staticpro (&Qcursor_color); 3790 staticpro (&Qcursor_color);
3791 Qcursor_type = intern ("cursor-type");
3792 staticpro (&Qcursor_type);
3793 Qfont = intern ("font"); 3793 Qfont = intern ("font");
3794 staticpro (&Qfont); 3794 staticpro (&Qfont);
3795 Qforeground_color = intern ("foreground-color"); 3795 Qforeground_color = intern ("foreground-color");
@@ -3851,10 +3851,6 @@ syms_of_xfns ()
3851 "The shape of the pointer when over the mode line."); 3851 "The shape of the pointer when over the mode line.");
3852 Vx_mode_pointer_shape = Qnil; 3852 Vx_mode_pointer_shape = Qnil;
3853 3853
3854 DEFVAR_LISP ("x-bar-cursor", &Vbar_cursor,
3855 "*If non-nil, use a vertical bar cursor. Otherwise, use the traditional box.");
3856 Vbar_cursor = Qnil;
3857
3858 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel, 3854 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
3859 "A string indicating the foreground color of the cursor box."); 3855 "A string indicating the foreground color of the cursor box.");
3860 Vx_cursor_fore_pixel = Qnil; 3856 Vx_cursor_fore_pixel = Qnil;
diff --git a/src/xmenu.c b/src/xmenu.c
index 025b61e4084..70f635ac2f5 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -103,7 +103,7 @@ Alternatively, you can specify a menu of multiple panes\n\
103 with a list of the form\n\ 103 with a list of the form\n\
104\(TITLE PANE1 PANE2...), where each pane is a list of form\n\ 104\(TITLE PANE1 PANE2...), where each pane is a list of form\n\
105\(TITLE (LINE ITEM)...). Each line should be a string, and item should\n\ 105\(TITLE (LINE ITEM)...). Each line should be a string, and item should\n\
106be the return value for that line (i.e. if it is selected.") 106be the return value for that line (i.e. if it is selected).")
107 (position, menu) 107 (position, menu)
108 Lisp_Object position, menu; 108 Lisp_Object position, menu;
109{ 109{
diff --git a/src/xselect.c.old b/src/xselect.c.old
index fcbae4b4203..8a3e0443270 100644
--- a/src/xselect.c.old
+++ b/src/xselect.c.old
@@ -1,5 +1,5 @@
1/* X Selection processing for emacs 1/* X Selection processing for emacs
2 Copyright (C) 1990, 1992 Free Software Foundation. 2 Copyright (C) 1990, 1992, 1993 Free Software Foundation.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -188,17 +188,41 @@ own_selection (selection_type, time)
188 If we are already the owner, merely change data and timestamp values. 188 If we are already the owner, merely change data and timestamp values.
189 This avoids generating SelectionClear events for ourselves. */ 189 This avoids generating SelectionClear events for ourselves. */
190 190
191DEFUN ("x-own-selection", Fx_own_selection, Sx_own_selection, 191DEFUN ("x-set-selection", Fx_set_selection, Sx_set_selection,
192 1, 2, "", 192 2, 2, "",
193 "Make STRING the selection value. Default is the primary selection,\n\ 193 "Set the value of SELECTION to STRING.\n\
194but optional second argument TYPE may specify secondary or clipboard.\n\ 194SELECTION may be `primary', `secondary', or `clipboard'.\n\
195\n\ 195\n\
196TYPE may also be cut-buffer0, indicating that Emacs should set the X\n\ 196Selections are a mechanism for cutting and pasting information between\n\
197cut buffer 0 to STRING. This is for compatibility with older X\n\ 197X Windows clients. Emacs's kill ring commands set the `primary'\n\
198applications which still use the cut buffers; new applications should\n\ 198selection to the top string of the kill ring, making it available to\n\
199use X selections.") 199other clients, like xterm. Those commands also use the `primary'\n\
200 (string, type) 200selection to retrieve information from other clients.\n\
201 register Lisp_Object string, type; 201\n\
202According to the Inter-Client Communications Conventions Manual:\n\
203\n\
204The `primary' selection \"... is used for all commands that take only a\n\
205 single argument and is the principal means of communication between\n\
206 clients that use the selection mechanism.\" In Emacs, this means\n\
207 that the kill ring commands set the primary selection to the text\n\
208 put in the kill ring.\n\
209\n\
210The `secondary' selection \"... is used as the second argument to\n\
211 commands taking two arguments (for example, `exchange primary and\n\
212 secondary selections'), and as a means of obtaining data when there\n\
213 is a primary selection and the user does not want to disturb it.\"\n\
214 I am not sure how Emacs should use the secondary selection; if you\n\
215 come up with ideas, this function will at least let you get at it.\n\
216\n\
217The `clipboard' selection \"... is used to hold data that is being\n\
218 transferred between clients, that is, data that usually is being\n\
219 cut or copied, and then pasted.\" It seems that the `clipboard'\n\
220 selection is for the most part equivalent to the `primary'\n\
221 selection, so Emacs sets them both.\n\
222\n\
223Also see `x-selection', and the `interprogram-cut-function' variable.")
224 (selection, string)
225 register Lisp_Object selection, string;
202{ 226{
203 Atom selection_type; 227 Atom selection_type;
204 Lisp_Object val; 228 Lisp_Object val;
@@ -207,7 +231,7 @@ use X selections.")
207 231
208 val = Qnil; 232 val = Qnil;
209 233
210 if (NILP (type) || EQ (type, Qprimary)) 234 if (NILP (selection) || EQ (selection, Qprimary))
211 { 235 {
212 BLOCK_INPUT; 236 BLOCK_INPUT;
213 if (own_selection (XA_PRIMARY, event_time)) 237 if (own_selection (XA_PRIMARY, event_time))
@@ -217,7 +241,7 @@ use X selections.")
217 } 241 }
218 UNBLOCK_INPUT; 242 UNBLOCK_INPUT;
219 } 243 }
220 else if (EQ (type, Qsecondary)) 244 else if (EQ (selection, Qsecondary))
221 { 245 {
222 BLOCK_INPUT; 246 BLOCK_INPUT;
223 if (own_selection (XA_SECONDARY, event_time)) 247 if (own_selection (XA_SECONDARY, event_time))
@@ -227,7 +251,7 @@ use X selections.")
227 } 251 }
228 UNBLOCK_INPUT; 252 UNBLOCK_INPUT;
229 } 253 }
230 else if (EQ (type, Qclipboard)) 254 else if (EQ (selection, Qclipboard))
231 { 255 {
232 BLOCK_INPUT; 256 BLOCK_INPUT;
233 if (own_selection (Xatom_clipboard, event_time)) 257 if (own_selection (Xatom_clipboard, event_time))
@@ -237,33 +261,6 @@ use X selections.")
237 } 261 }
238 UNBLOCK_INPUT; 262 UNBLOCK_INPUT;
239 } 263 }
240#if 0
241 else if (EQ (type, Qcut_buffer0))
242 {
243 /* DECwindows and some other servers don't seem to like setting
244 properties to values larger than about 20k. For very large
245 values, they signal an error, but for intermediate values
246 they just seem to hang.
247
248 We could just truncate the request, but it's better to let
249 the user know that the strategy he/she's using isn't going to
250 work than to have it work partially, but incorrectly. */
251 BLOCK_INPUT;
252 if (XSTRING (string)->size > MAX_SELECTION (x_current_display))
253 {
254 XStoreBytes (x_current_display, (char *) 0, 0);
255 val = Qnil;
256 }
257 else
258 {
259 XStoreBytes (x_current_display,
260 (char *) XSTRING (string)->data,
261 XSTRING (string)->size);
262 val = string;
263 }
264 UNBLOCK_INPUT;
265 }
266#endif
267 else 264 else
268 error ("Invalid X selection type"); 265 error ("Invalid X selection type");
269 266
@@ -621,54 +618,45 @@ get_selection_value (type)
621 simply return our selection value. If we are not the owner, this 618 simply return our selection value. If we are not the owner, this
622 will block until all of the data has arrived. */ 619 will block until all of the data has arrived. */
623 620
624DEFUN ("x-selection-value", Fx_selection_value, Sx_selection_value, 621DEFUN ("x-selection", Fx_selection, Sx_selection,
625 0, 1, "", 622 1, 1, "",
626 "Return the value of one of the selections. Default is the primary\n\ 623 "Return the value of SELECTION.\n\
627selection, but optional argument TYPE may specify secondary or clipboard.") 624SELECTION is one of `primary', `secondary', or `clipboard'.\n\
628 (type) 625\n\
629 register Lisp_Object type; 626Selections are a mechanism for cutting and pasting information between\n\
627X Windows clients. When the user selects text in an X application,\n\
628the application should set the primary selection to that text; Emacs's\n\
629kill ring commands will then check the value of the `primary'\n\
630selection, and return it as the most recent kill.\n\
631The documentation for `x-set-selection' gives more information on how\n\
632the different selection types are intended to be used.\n\
633Also see the `interprogram-paste-function' variable.")
634 (selection)
635 register Lisp_Object selection;
630{ 636{
631 Atom selection_type; 637 Atom selection_type;
632 638
633 if (NILP (type) || EQ (type, Qprimary)) 639 if (NILP (selection) || EQ (selection, Qprimary))
634 { 640 {
635 if (!NILP (Vx_selection_value)) 641 if (!NILP (Vx_selection_value))
636 return Vx_selection_value; 642 return Vx_selection_value;
637 643
638 return get_selection_value (XA_PRIMARY); 644 return get_selection_value (XA_PRIMARY);
639 } 645 }
640 else if (EQ (type, Qsecondary)) 646 else if (EQ (selection, Qsecondary))
641 { 647 {
642 if (!NILP (Vx_secondary_selection_value)) 648 if (!NILP (Vx_secondary_selection_value))
643 return Vx_secondary_selection_value; 649 return Vx_secondary_selection_value;
644 650
645 return get_selection_value (XA_SECONDARY); 651 return get_selection_value (XA_SECONDARY);
646 } 652 }
647 else if (EQ (type, Qclipboard)) 653 else if (EQ (selection, Qclipboard))
648 { 654 {
649 if (!NILP (Vx_clipboard_value)) 655 if (!NILP (Vx_clipboard_value))
650 return Vx_clipboard_value; 656 return Vx_clipboard_value;
651 657
652 return get_selection_value (Xatom_clipboard); 658 return get_selection_value (Xatom_clipboard);
653 } 659 }
654#if 0
655 else if (EQ (type, Qcut_buffer0))
656 {
657 char *data;
658 int size;
659 Lisp_Object string;
660
661 BLOCK_INPUT;
662 data = XFetchBytes (x_current_display, &size);
663 if (data == 0)
664 string = Qnil;
665 else
666 string = make_string (data, size);
667 UNBLOCK_INPUT;
668
669 return string;
670 }
671#endif
672 else 660 else
673 error ("Invalid X selection type"); 661 error ("Invalid X selection type");
674} 662}
@@ -950,8 +938,8 @@ syms_of_xselect ()
950 Qclipboard = intern ("clipboard"); 938 Qclipboard = intern ("clipboard");
951 staticpro (&Qclipboard); 939 staticpro (&Qclipboard);
952 940
953 defsubr (&Sx_own_selection); 941 defsubr (&Sx_set_selection);
954 defsubr (&Sx_selection_value); 942 defsubr (&Sx_selection);
955 943
956 cut_buffer_value = Fmake_vector (make_number (NUM_CUT_BUFFERS), Qnil); 944 cut_buffer_value = Fmake_vector (make_number (NUM_CUT_BUFFERS), Qnil);
957 staticpro (&cut_buffer_value); 945 staticpro (&cut_buffer_value);
diff --git a/src/xterm.c b/src/xterm.c
index b534751dbf7..712a64ac26d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -657,95 +657,128 @@ XTclear_frame ()
657 curs_y = 0; 657 curs_y = 0;
658 658
659 BLOCK_INPUT; 659 BLOCK_INPUT;
660
660 XClear (FRAME_X_WINDOW (f)); 661 XClear (FRAME_X_WINDOW (f));
662
663 /* We have to clear the scrollbars, too. If we have changed
664 colors or something like that, then they should be notified. */
665 x_scrollbar_clear (f);
666
661#ifndef HAVE_X11 667#ifndef HAVE_X11
662 dumpborder (f, 0); 668 dumpborder (f, 0);
663#endif /* HAVE_X11 */ 669#endif /* HAVE_X11 */
670
664 XFlushQueue (); 671 XFlushQueue ();
665 UNBLOCK_INPUT; 672 UNBLOCK_INPUT;
666} 673}
667 674
668/* Paint horzontal bars down the frame for a visible bell. 675/* Invert the middle quarter of the frame for .15 sec. */
669 Note that this may be way too slow on some machines. */ 676
677/* We use the select system call to do the waiting, so we have to make sure
678 it's avaliable. If it isn't, we just won't do visual bells. */
679#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
680
681/* Subtract the `struct timeval' values X and Y,
682 storing the result in RESULT.
683 Return 1 if the difference is negative, otherwise 0. */
684
685static int
686timeval_subtract (result, x, y)
687 struct timeval *result, x, y;
688{
689 /* Perform the carry for the later subtraction by updating y.
690 This is safer because on some systems
691 the tv_sec member is unsigned. */
692 if (x.tv_usec < y.tv_usec)
693 {
694 int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
695 y.tv_usec -= 1000000 * nsec;
696 y.tv_sec += nsec;
697 }
698 if (x.tv_usec - y.tv_usec > 1000000)
699 {
700 int nsec = (y.tv_usec - x.tv_usec) / 1000000;
701 y.tv_usec += 1000000 * nsec;
702 y.tv_sec -= nsec;
703 }
704
705 /* Compute the time remaining to wait. tv_usec is certainly positive. */
706 result->tv_sec = x.tv_sec - y.tv_sec;
707 result->tv_usec = x.tv_usec - y.tv_usec;
708
709 /* Return indication of whether the result should be considered negative. */
710 return x.tv_sec < y.tv_sec;
711}
670 712
671XTflash (f) 713XTflash (f)
672 struct frame *f; 714 struct frame *f;
673{ 715{
674 register struct frame_glyphs *active_frame = FRAME_CURRENT_GLYPHS (f); 716 BLOCK_INPUT;
675 register int i;
676 int x, y;
677 717
678 if (updating_frame != 0) 718 {
679 abort (); 719 GC gc;
680 720
681 BLOCK_INPUT; 721 /* Create a GC that will use the GXxor function to flip foreground pixels
682#ifdef HAVE_X11 722 into background pixels. */
683#if 0 723 {
684 for (i = f->height * FONT_HEIGHT (f->display.x->font) - 10; 724 XGCValues values;
685 i >= 0;
686 i -= 100) /* Should be NO LOWER than 75 for speed reasons. */
687 XFillRectangle (x_current_display, FRAME_X_WINDOW (f),
688 f->display.x->cursor_gc,
689 0, i, f->width * FONT_WIDTH (f->display.x->font)
690 + 2 * f->display.x->internal_border_width, 25);
691#endif /* ! 0 */
692 725
693 x = (f->width * FONT_WIDTH (f->display.x->font)) / 4; 726 values.function = GXxor;
694 y = (f->height * FONT_HEIGHT (f->display.x->font)) / 4; 727 values.foreground = (f->display.x->foreground_pixel
695 XFillRectangle (x_current_display, FRAME_X_WINDOW (f), 728 ^ f->display.x->background_pixel);
696 f->display.x->cursor_gc, 729
697 x, y, 2 * x, 2 * y); 730 gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f),
698 dumpglyphs (f, (x + f->display.x->internal_border_width), 731 GCFunction | GCForeground, &values);
699 (y + f->display.x->internal_border_width), 732 }
700 &active_frame->glyphs[(f->height / 4) + 1][(f->width / 4)],
701 1, 0, f->display.x->font);
702 733
703#else /* ! defined (HAVE_X11) */ 734 {
704 for (i = f->height * FONT_HEIGHT (f->display.x->font) - 10; 735 int width = PIXEL_WIDTH (f);
705 i >= 0; 736 int height = PIXEL_HEIGHT (f);
706 i -= 50)
707 XPixFill (FRAME_X_WINDOW (f), 0, i,
708 f->width * FONT_WIDTH (f->display.x->font)
709 + 2 * f->display.x->internal_border_width, 10,
710 WHITE_PIX_DEFAULT, ClipModeClipped, GXinvert, AllPlanes);
711#endif /* ! defined (HAVE_X11) */
712 737
713 XFlushQueue (); 738 XFillRectangle (x_current_display, FRAME_X_WINDOW (f), gc,
714 UNBLOCK_INPUT; 739 width/4, height/4, width/2, height/2);
715} 740 XFlush (x_current_display);
716 741
717/* Flip background and forground colors of the frame. */ 742 {
743 struct timeval wakeup, now;
718 744
719x_invert_frame (f) 745 gettimeofday (&wakeup, (struct timezone *) 0);
720 struct frame *f;
721{
722#ifdef HAVE_X11
723 GC temp;
724 unsigned long pix_temp;
725 746
726 x_display_cursor (f, 0); 747 /* Compute time to wait until, propagating carry from usecs. */
727 XClearWindow (x_current_display, FRAME_X_WINDOW (f)); 748 wakeup.tv_usec += 150000;
728 temp = f->display.x->normal_gc; 749 wakeup.tv_sec += (wakeup.tv_usec / 1000000);
729 f->display.x->normal_gc = f->display.x->reverse_gc; 750 wakeup.tv_usec %= 1000000;
730 f->display.x->reverse_gc = temp; 751
731 pix_temp = f->display.x->foreground_pixel; 752 /* Keep waiting until past the time wakeup. */
732 f->display.x->foreground_pixel = f->display.x->background_pixel; 753 while (1)
733 f->display.x->background_pixel = pix_temp; 754 {
734 755 struct timeval timeout;
735 XSetWindowBackground (x_current_display, FRAME_X_WINDOW (f), 756
736 f->display.x->background_pixel); 757 gettimeofday (&timeout, (struct timezone *)0);
737 if (f->display.x->background_pixel == f->display.x->cursor_pixel) 758
738 { 759 /* In effect, timeout = wakeup - timeout.
739 f->display.x->cursor_pixel = f->display.x->foreground_pixel; 760 Break if result would be negative. */
740 XSetBackground (x_current_display, f->display.x->cursor_gc, 761 if (timeval_subtract (&timeout, wakeup, timeout))
741 f->display.x->cursor_pixel); 762 break;
742 XSetForeground (x_current_display, f->display.x->cursor_gc, 763
743 f->display.x->background_pixel); 764 /* Try to wait that long--but we might wake up sooner. */
765 select (0, 0, 0, 0, &timeout);
766 }
767 }
768
769 XFillRectangle (x_current_display, FRAME_X_WINDOW (f), gc,
770 width/4, height/4, width/2, height/2);
771 XFreeGC (x_current_display, gc);
772 XFlush (x_current_display);
744 } 773 }
745 redraw_frame (f); 774 }
746#endif /* ! defined (HAVE_X11) */ 775
776 UNBLOCK_INPUT;
747} 777}
748 778
779#endif
780
781
749/* Make audible bell. */ 782/* Make audible bell. */
750 783
751#ifdef HAVE_X11 784#ifdef HAVE_X11
@@ -756,15 +789,11 @@ x_invert_frame (f)
756 789
757XTring_bell () 790XTring_bell ()
758{ 791{
792#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
759 if (visible_bell) 793 if (visible_bell)
760#if 0
761 XTflash (selected_frame); 794 XTflash (selected_frame);
762#endif /* ! 0 */
763 {
764 x_invert_frame (selected_frame);
765 x_invert_frame (selected_frame);
766 }
767 else 795 else
796#endif
768 { 797 {
769 BLOCK_INPUT; 798 BLOCK_INPUT;
770 XRINGBELL; 799 XRINGBELL;
@@ -1758,9 +1787,8 @@ x_scrollbar_create (window, top, left, width, height)
1758 | ButtonMotionMask | PointerMotionHintMask 1787 | ButtonMotionMask | PointerMotionHintMask
1759 | ExposureMask); 1788 | ExposureMask);
1760 a.cursor = x_vertical_scrollbar_cursor; 1789 a.cursor = x_vertical_scrollbar_cursor;
1761 a.win_gravity = EastGravity;
1762 1790
1763 mask = (CWBackPixel | CWEventMask | CWCursor | CWWinGravity); 1791 mask = (CWBackPixel | CWEventMask | CWCursor);
1764 1792
1765 SET_SCROLLBAR_X_WINDOW 1793 SET_SCROLLBAR_X_WINDOW
1766 (bar, 1794 (bar,
@@ -2321,6 +2349,24 @@ x_scrollbar_report_motion (f, bar_window, part, x, y, time)
2321} 2349}
2322 2350
2323 2351
2352/* The screen has been cleared so we may have changed foreground or
2353 background colors, and the scrollbars may need to be redrawn.
2354 Clear out the scrollbars, and ask for expose events, so we can
2355 redraw them. */
2356
2357x_scrollbar_clear (f)
2358 FRAME_PTR f;
2359{
2360 Lisp_Object bar;
2361
2362 for (bar = FRAME_SCROLLBARS (f);
2363 XTYPE (bar) == Lisp_Vector;
2364 bar = XSCROLLBAR (bar)->next)
2365 XClearArea (x_current_display, SCROLLBAR_X_WINDOW (XSCROLLBAR (bar)),
2366 0, 0, 0, 0, True);
2367}
2368
2369
2324 2370
2325/* The main X event-reading loop - XTread_socket. */ 2371/* The main X event-reading loop - XTread_socket. */
2326 2372
@@ -2865,33 +2911,30 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
2865 break; 2911 break;
2866 2912
2867 case ConfigureNotify: 2913 case ConfigureNotify:
2868 { 2914 f = x_window_to_frame (event.xconfigure.window);
2869 int rows, columns; 2915 if (f)
2870 f = x_window_to_frame (event.xconfigure.window); 2916 {
2871 if (!f) 2917 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
2872 break; 2918 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
2873 2919
2874 columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width); 2920 /* Even if the number of character rows and columns has
2875 rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height); 2921 not changed, the font size may have changed, so we need
2876 2922 to check the pixel dimensions as well. */
2877 /* Even if the number of character rows and columns has 2923 if (columns != f->width
2878 not changed, the font size may have changed, so we need 2924 || rows != f->height
2879 to check the pixel dimensions as well. */ 2925 || event.xconfigure.width != f->display.x->pixel_width
2880 if (columns != f->width 2926 || event.xconfigure.height != f->display.x->pixel_height)
2881 || rows != f->height 2927 {
2882 || event.xconfigure.width != f->display.x->pixel_width 2928 change_frame_size (f, rows, columns, 0, 1);
2883 || event.xconfigure.height != f->display.x->pixel_height) 2929 SET_FRAME_GARBAGED (f);
2884 { 2930 }
2885 change_frame_size (f, rows, columns, 0, 1);
2886 SET_FRAME_GARBAGED (f);
2887 }
2888 2931
2889 f->display.x->pixel_width = event.xconfigure.width; 2932 f->display.x->pixel_width = event.xconfigure.width;
2890 f->display.x->pixel_height = event.xconfigure.height; 2933 f->display.x->pixel_height = event.xconfigure.height;
2891 f->display.x->left_pos = event.xconfigure.x; 2934 f->display.x->left_pos = event.xconfigure.x;
2892 f->display.x->top_pos = event.xconfigure.y; 2935 f->display.x->top_pos = event.xconfigure.y;
2893 break; 2936 }
2894 } 2937 break;
2895 2938
2896 case ButtonPress: 2939 case ButtonPress:
2897 case ButtonRelease: 2940 case ButtonRelease:
@@ -3153,52 +3196,6 @@ clear_cursor (f)
3153 f->phys_cursor_x = -1; 3196 f->phys_cursor_x = -1;
3154} 3197}
3155 3198
3156static void
3157x_display_bar_cursor (f, on)
3158 struct frame *f;
3159 int on;
3160{
3161 register int phys_x = f->phys_cursor_x;
3162 register int phys_y = f->phys_cursor_y;
3163 register int x1;
3164 register int y1;
3165 register int y2;
3166
3167 if (! FRAME_VISIBLE_P (f) || (! on && f->phys_cursor_x < 0))
3168 return;
3169
3170#ifdef HAVE_X11
3171 if (phys_x >= 0 &&
3172 (!on || phys_x != f->cursor_x || phys_y != f->cursor_y))
3173 {
3174 x1 = CHAR_TO_PIXEL_COL (f, phys_x);
3175 y1 = CHAR_TO_PIXEL_ROW (f, phys_y) - 1;
3176 y2 = y1 + FONT_HEIGHT (f->display.x->font) + 1;
3177
3178 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3179 f->display.x->reverse_gc, x1, y1, x1, y2);
3180
3181 f->phys_cursor_x = phys_x = -1;
3182 }
3183
3184 if (on && f == x_highlight_frame)
3185 {
3186 x1 = CHAR_TO_PIXEL_COL (f, f->cursor_x);
3187 y1 = CHAR_TO_PIXEL_ROW (f, f->cursor_y) - 1;
3188 y2 = y1 + FONT_HEIGHT (f->display.x->font) + 1;
3189
3190 XDrawLine (x_current_display, FRAME_X_WINDOW (f),
3191 f->display.x->cursor_gc, x1, y1, x1, y2);
3192
3193 f->phys_cursor_x = f->cursor_x;
3194 f->phys_cursor_y = f->cursor_y;
3195 }
3196#else /* ! defined (HAVE_X11) */
3197 Give it up, dude.
3198#endif /* ! defined (HAVE_X11) */
3199}
3200
3201
3202/* Redraw the glyph at ROW, COLUMN on frame F, in the style 3199/* Redraw the glyph at ROW, COLUMN on frame F, in the style
3203 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the 3200 HIGHLIGHT. HIGHLIGHT is as defined for dumpglyphs. Return the
3204 glyph drawn. */ 3201 glyph drawn. */
@@ -3216,17 +3213,19 @@ x_draw_single_glyph (f, row, column, glyph, highlight)
3216 &glyph, 1, highlight, f->display.x->font); 3213 &glyph, 1, highlight, f->display.x->font);
3217} 3214}
3218 3215
3219/* Turn the displayed cursor of frame F on or off according to ON.
3220 If ON is nonzero, where to put the cursor is specified
3221 by F->cursor_x and F->cursor_y. */
3222
3223static void 3216static void
3224x_display_box_cursor (f, on) 3217x_display_bar_cursor (f, on)
3225 struct frame *f; 3218 struct frame *f;
3226 int on; 3219 int on;
3227{ 3220{
3228 struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f); 3221 struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f);
3229 3222
3223 if (! FRAME_VISIBLE_P (f))
3224 return;
3225
3226 if (! on && f->phys_cursor_x < 0)
3227 return;
3228
3230 /* If we're not updating, then we want to use the current frame's 3229 /* If we're not updating, then we want to use the current frame's
3231 cursor position, not our local idea of where the cursor ought to be. */ 3230 cursor position, not our local idea of where the cursor ought to be. */
3232 if (f != updating_frame) 3231 if (f != updating_frame)
@@ -3235,6 +3234,58 @@ x_display_box_cursor (f, on)
3235 curs_y = FRAME_CURSOR_Y (f); 3234 curs_y = FRAME_CURSOR_Y (f);
3236 } 3235 }
3237 3236
3237 /* If there is anything wrong with the current cursor state, remove it. */
3238 if (f->phys_cursor_x >= 0
3239 && (!on
3240 || f->phys_cursor_x != curs_x
3241 || f->phys_cursor_y != curs_y
3242 || f->display.x->current_cursor != bar_cursor))
3243 {
3244 /* Erase the cursor by redrawing the character underneath it. */
3245 x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
3246 f->phys_cursor_glyph,
3247 current_glyphs->highlight[f->phys_cursor_y]);
3248 f->phys_cursor_x = -1;
3249 }
3250
3251 /* If we now need a cursor in the new place or in the new form, do it so. */
3252 if (on
3253 && (f->phys_cursor_x < 0
3254 || (f->display.x->current_cursor != bar_cursor)))
3255 {
3256 f->phys_cursor_glyph
3257 = ((current_glyphs->enable[curs_y]
3258 && curs_x < current_glyphs->used[curs_y])
3259 ? current_glyphs->glyphs[curs_y][curs_x]
3260 : SPACEGLYPH);
3261 XFillRectangle (x_current_display, FRAME_X_WINDOW (f),
3262 f->display.x->cursor_gc,
3263 CHAR_TO_PIXEL_COL (f, curs_x),
3264 CHAR_TO_PIXEL_ROW (f, curs_y),
3265 1, FONT_HEIGHT (f->display.x->font));
3266
3267 f->phys_cursor_x = curs_x;
3268 f->phys_cursor_y = curs_y;
3269
3270 f->display.x->current_cursor = bar_cursor;
3271 }
3272
3273 if (updating_frame != f)
3274 XFlushQueue ();
3275}
3276
3277
3278/* Turn the displayed cursor of frame F on or off according to ON.
3279 If ON is nonzero, where to put the cursor is specified
3280 by F->cursor_x and F->cursor_y. */
3281
3282static void
3283x_display_box_cursor (f, on)
3284 struct frame *f;
3285 int on;
3286{
3287 struct frame_glyphs *current_glyphs = FRAME_CURRENT_GLYPHS (f);
3288
3238 if (! FRAME_VISIBLE_P (f)) 3289 if (! FRAME_VISIBLE_P (f))
3239 return; 3290 return;
3240 3291
@@ -3242,6 +3293,14 @@ x_display_box_cursor (f, on)
3242 if (!on && f->phys_cursor_x < 0) 3293 if (!on && f->phys_cursor_x < 0)
3243 return; 3294 return;
3244 3295
3296 /* If we're not updating, then we want to use the current frame's
3297 cursor position, not our local idea of where the cursor ought to be. */
3298 if (f != updating_frame)
3299 {
3300 curs_x = FRAME_CURSOR_X (f);
3301 curs_y = FRAME_CURSOR_Y (f);
3302 }
3303
3245 /* If cursor is currently being shown and we don't want it to be 3304 /* If cursor is currently being shown and we don't want it to be
3246 or it is in the wrong place, 3305 or it is in the wrong place,
3247 or we want a hollow box and it's not so, (pout!) 3306 or we want a hollow box and it's not so, (pout!)
@@ -3250,7 +3309,7 @@ x_display_box_cursor (f, on)
3250 && (!on 3309 && (!on
3251 || f->phys_cursor_x != curs_x 3310 || f->phys_cursor_x != curs_x
3252 || f->phys_cursor_y != curs_y 3311 || f->phys_cursor_y != curs_y
3253 || (f->display.x->text_cursor_kind != hollow_box_cursor 3312 || (f->display.x->current_cursor != hollow_box_cursor
3254 && (f != x_highlight_frame)))) 3313 && (f != x_highlight_frame))))
3255 { 3314 {
3256 /* Erase the cursor by redrawing the character underneath it. */ 3315 /* Erase the cursor by redrawing the character underneath it. */
@@ -3265,7 +3324,7 @@ x_display_box_cursor (f, on)
3265 write it in the right place. */ 3324 write it in the right place. */
3266 if (on 3325 if (on
3267 && (f->phys_cursor_x < 0 3326 && (f->phys_cursor_x < 0
3268 || (f->display.x->text_cursor_kind != filled_box_cursor 3327 || (f->display.x->current_cursor != filled_box_cursor
3269 && f == x_highlight_frame))) 3328 && f == x_highlight_frame)))
3270 { 3329 {
3271 f->phys_cursor_glyph 3330 f->phys_cursor_glyph
@@ -3276,13 +3335,13 @@ x_display_box_cursor (f, on)
3276 if (f != x_highlight_frame) 3335 if (f != x_highlight_frame)
3277 { 3336 {
3278 x_draw_box (f); 3337 x_draw_box (f);
3279 f->display.x->text_cursor_kind = hollow_box_cursor; 3338 f->display.x->current_cursor = hollow_box_cursor;
3280 } 3339 }
3281 else 3340 else
3282 { 3341 {
3283 x_draw_single_glyph (f, curs_y, curs_x, 3342 x_draw_single_glyph (f, curs_y, curs_x,
3284 f->phys_cursor_glyph, 2); 3343 f->phys_cursor_glyph, 2);
3285 f->display.x->text_cursor_kind = filled_box_cursor; 3344 f->display.x->current_cursor = filled_box_cursor;
3286 } 3345 }
3287 3346
3288 f->phys_cursor_x = curs_x; 3347 f->phys_cursor_x = curs_x;
@@ -3293,16 +3352,17 @@ x_display_box_cursor (f, on)
3293 XFlushQueue (); 3352 XFlushQueue ();
3294} 3353}
3295 3354
3296extern Lisp_Object Vbar_cursor;
3297
3298x_display_cursor (f, on) 3355x_display_cursor (f, on)
3299 struct frame *f; 3356 struct frame *f;
3300 int on; 3357 int on;
3301{ 3358{
3302 if (EQ (Vbar_cursor, Qnil)) 3359 if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
3303 x_display_box_cursor (f, on); 3360 x_display_box_cursor (f, on);
3304 else 3361 else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
3305 x_display_bar_cursor (f, on); 3362 x_display_bar_cursor (f, on);
3363 else
3364 /* Those are the only two we have implemented! */
3365 abort ();
3306} 3366}
3307 3367
3308/* Icons. */ 3368/* Icons. */
@@ -3347,8 +3407,7 @@ refreshicon (f)
3347#endif /* ! defined (HAVE_X11) */ 3407#endif /* ! defined (HAVE_X11) */
3348} 3408}
3349 3409
3350/* Make the x-window of frame F use the kitchen-sink icon 3410/* Make the x-window of frame F use the gnu icon bitmap. */
3351 that's a window generated by Emacs. */
3352 3411
3353int 3412int
3354x_bitmap_icon (f) 3413x_bitmap_icon (f)
@@ -3424,12 +3483,6 @@ x_text_icon (f, icon_name)
3424 if (FRAME_X_WINDOW (f) == 0) 3483 if (FRAME_X_WINDOW (f) == 0)
3425 return 1; 3484 return 1;
3426 3485
3427 if (icon_font_info == 0)
3428 icon_font_info
3429 = XGetFont (XGetDefault (XDISPLAY
3430 (char *) XSTRING (invocation_name)->data,
3431 "BodyFont"));
3432
3433#ifdef HAVE_X11 3486#ifdef HAVE_X11
3434 if (icon_name) 3487 if (icon_name)
3435 f->display.x->icon_label = icon_name; 3488 f->display.x->icon_label = icon_name;
@@ -3443,6 +3496,12 @@ x_text_icon (f, icon_name)
3443 f->display.x->icon_bitmap_flag = 0; 3496 f->display.x->icon_bitmap_flag = 0;
3444 x_wm_set_icon_pixmap (f, 0); 3497 x_wm_set_icon_pixmap (f, 0);
3445#else /* ! defined (HAVE_X11) */ 3498#else /* ! defined (HAVE_X11) */
3499 if (icon_font_info == 0)
3500 icon_font_info
3501 = XGetFont (XGetDefault (XDISPLAY
3502 (char *) XSTRING (invocation_name)->data,
3503 "BodyFont"));
3504
3446 if (f->display.x->icon_desc) 3505 if (f->display.x->icon_desc)
3447 { 3506 {
3448 XClearIconWindow (XDISPLAY FRAME_X_WINDOW (f)); 3507 XClearIconWindow (XDISPLAY FRAME_X_WINDOW (f));
@@ -3801,12 +3860,24 @@ x_set_window_size (f, cols, rows)
3801 /* Now, strictly speaking, we can't be sure that this is accurate, 3860 /* Now, strictly speaking, we can't be sure that this is accurate,
3802 but the window manager will get around to dealing with the size 3861 but the window manager will get around to dealing with the size
3803 change request eventually, and we'll hear how it went when the 3862 change request eventually, and we'll hear how it went when the
3804 ConfigureNotify event gets here. */ 3863 ConfigureNotify event gets here.
3864
3865 We could just not bother storing any of this information here,
3866 and let the ConfigureNotify event set everything up, but that
3867 might be kind of confusing to the lisp code, since size changes
3868 wouldn't be reported in the frame parameters until some random
3869 point in the future when the ConfigureNotify event arrives. */
3805 FRAME_WIDTH (f) = cols; 3870 FRAME_WIDTH (f) = cols;
3806 FRAME_HEIGHT (f) = rows; 3871 FRAME_HEIGHT (f) = rows;
3807 PIXEL_WIDTH (f) = pixelwidth; 3872 PIXEL_WIDTH (f) = pixelwidth;
3808 PIXEL_HEIGHT (f) = pixelheight; 3873 PIXEL_HEIGHT (f) = pixelheight;
3809 3874
3875 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
3876 receive in the ConfigureNotify event; if we get what we asked
3877 for, then the event won't cause the screen to become garbaged, so
3878 we have to make sure to do it here. */
3879 SET_FRAME_GARBAGED (f);
3880
3810 XFlushQueue (); 3881 XFlushQueue ();
3811 UNBLOCK_INPUT; 3882 UNBLOCK_INPUT;
3812} 3883}
@@ -3903,6 +3974,18 @@ x_lower_frame (f)
3903 } 3974 }
3904} 3975}
3905 3976
3977static void
3978XTframe_raise_lower (f, raise)
3979 FRAME_PTR f;
3980 int raise;
3981{
3982 if (raise)
3983 x_raise_frame (f);
3984 else
3985 x_lower_frame (f);
3986}
3987
3988
3906/* Change from withdrawn state to mapped state. */ 3989/* Change from withdrawn state to mapped state. */
3907 3990
3908x_make_frame_visible (f) 3991x_make_frame_visible (f)
@@ -4259,8 +4342,13 @@ x_wm_set_icon_pixmap (f, icon_pixmap)
4259{ 4342{
4260 Window window = FRAME_X_WINDOW (f); 4343 Window window = FRAME_X_WINDOW (f);
4261 4344
4262 f->display.x->wm_hints.flags |= IconPixmapHint; 4345 if (icon_pixmap)
4263 f->display.x->wm_hints.icon_pixmap = icon_pixmap ? icon_pixmap : None; 4346 {
4347 f->display.x->wm_hints.icon_pixmap = icon_pixmap;
4348 f->display.x->wm_hints.flags |= IconPixmapHint;
4349 }
4350 else
4351 f->display.x->wm_hints.flags &= ~IconPixmapHint;
4264 4352
4265 XSetWMHints (x_current_display, window, &f->display.x->wm_hints); 4353 XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
4266} 4354}
@@ -4395,6 +4483,7 @@ x_term_init (display_name)
4395 reassert_line_highlight_hook = XTreassert_line_highlight; 4483 reassert_line_highlight_hook = XTreassert_line_highlight;
4396 mouse_position_hook = XTmouse_position; 4484 mouse_position_hook = XTmouse_position;
4397 frame_rehighlight_hook = XTframe_rehighlight; 4485 frame_rehighlight_hook = XTframe_rehighlight;
4486 frame_raise_lower_hook = XTframe_raise_lower;
4398 set_vertical_scrollbar_hook = XTset_vertical_scrollbar; 4487 set_vertical_scrollbar_hook = XTset_vertical_scrollbar;
4399 condemn_scrollbars_hook = XTcondemn_scrollbars; 4488 condemn_scrollbars_hook = XTcondemn_scrollbars;
4400 redeem_scrollbar_hook = XTredeem_scrollbar; 4489 redeem_scrollbar_hook = XTredeem_scrollbar;
diff --git a/src/xterm.h b/src/xterm.h
index 9bf083fa788..025e277a22f 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -239,9 +239,6 @@ enum text_cursor_kinds {
239 filled_box_cursor, hollow_box_cursor, bar_cursor 239 filled_box_cursor, hollow_box_cursor, bar_cursor
240}; 240};
241 241
242#define PIXEL_WIDTH(f) ((f)->display.x->pixel_width)
243#define PIXEL_HEIGHT(f) ((f)->display.x->pixel_height)
244
245/* Each X frame object points to its own struct x_display object 242/* Each X frame object points to its own struct x_display object
246 in the display.x field. The x_display structure contains all 243 in the display.x field. The x_display structure contains all
247 the information that is specific to X windows. */ 244 the information that is specific to X windows. */
@@ -316,9 +313,13 @@ struct x_display
316 /* Flag to set when the X window needs to be completely repainted. */ 313 /* Flag to set when the X window needs to be completely repainted. */
317 int needs_exposure; 314 int needs_exposure;
318 315
319 /* What kind of text cursor is drawn in this window right now? (If 316 /* What kind of text cursor is drawn in this window right now?
320 there is no cursor (phys_cursor_x < 0), then this means nothing. */ 317 (If there is no cursor (phys_cursor_x < 0), then this means nothing.) */
321 enum text_cursor_kinds text_cursor_kind; 318 enum text_cursor_kinds current_cursor;
319
320 /* What kind of text cursor should we draw in the future?
321 This should always be filled_box_cursor or bar_cursor. */
322 enum text_cursor_kinds desired_cursor;
322 323
323 /* These are the current window manager hints. It seems that 324 /* These are the current window manager hints. It seems that
324 XSetWMHints, when presented with an unset bit in the `flags' 325 XSetWMHints, when presented with an unset bit in the `flags'
@@ -341,6 +342,12 @@ struct x_display
341/* Return the window associated with the frame F. */ 342/* Return the window associated with the frame F. */
342#define FRAME_X_WINDOW(f) ((f)->display.x->window_desc) 343#define FRAME_X_WINDOW(f) ((f)->display.x->window_desc)
343 344
345/* These two really ought to be called FRAME_PIXEL_{WIDTH,HEIGHT}. */
346#define PIXEL_WIDTH(f) ((f)->display.x->pixel_width)
347#define PIXEL_HEIGHT(f) ((f)->display.x->pixel_height)
348
349#define FRAME_DESIRED_CURSOR(f) ((f)->display.x->desired_cursor)
350
344 351
345/* When X windows are used, a glyf may be a 16 bit unsigned datum. 352/* When X windows are used, a glyf may be a 16 bit unsigned datum.
346 The high order byte is the face number and is used as an index 353 The high order byte is the face number and is used as an index