diff options
| author | Gerd Moellmann | 1999-07-21 21:43:52 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-07-21 21:43:52 +0000 |
| commit | 7ee32cda427368906e23a0209aa4136cf2974781 (patch) | |
| tree | c59138bae8de4d1004112a973bbb68bd401ea0f0 /src | |
| parent | 0552666bc1f8989999967b575977b08a5f57ecb7 (diff) | |
| download | emacs-7ee32cda427368906e23a0209aa4136cf2974781.tar.gz emacs-7ee32cda427368906e23a0209aa4136cf2974781.zip | |
(read_char): Use message3_nolog to show help-echo.
(make_lispy_event) <TOOLBAR_EVENT>: Apply modifiers.
(kbd_store_ptr): Declare it as a volatile pointer
instead of a pointer to a volatile input_event.
(kbd_buffer_store_event): Remove volatile modifier from
declaration of local variable `sp'.
(Fdiscard_input): Don't cast when assigning kbd_store_ptr
to kbd_fetch_ptr.
(make_lispy_event): Handle mouse on top lines.
(make_lispy_movement): Ditto.
(read_char): Rename local variable echo_area_message
because it shadows the global one.
(cmd_error_internal): Set echo_areA_message.
(command_loop_1): Test echo_areA_message.
(read_char): Ditto.
(record_menu_key): Set echo_area_message to nil.
(Fexecute_extended_command): Test echo_area_message.
(Fexecute_extended_command): Handle echo_area_message.
(toolbar_items): Call access_keymap with third
parameter 1, so that we don't get inherited toolbar item
definitions.
Ditto.
(kbd_buffer_get_event): Set flag to prevent recording
TOOLBAR_EVENT events in last_nonmenu_event.
(timer_check): Inhibit busy cursor around calls to
timer-event-handler. This busy cursor tends to be anoying if
fontifying stealthily.
(command_loop_1): Display busy cursor.
(Vshow_help_function): New.
(read_char): Use it.
(make_lispy_event): Add string and string position
info to mouse-click events.
(read_key_sequence): Handle `local-map' property of mode line
strings.
(Qend_scroll): New.
(scroll_bar_parts): Add it.
(scroll_bar_parts): Add Qtop and Qbottom.
(syms_of_keyboard): Add Qbottom.
(make_lispy_event): Handle scroll_bar_click
differently when using toolkit scroll bars.
(cmd_error_internal): Bug fix.
(syms_of_keyboard): Staticpro toolbar_item_properties
and toolbar_items_vectors.
(Qhelp_echo): New symbol.
(read_char): Handle `toolbar' and `help_echo' events.
(kbd_buffer_get_event): Handle HELP_ECHO input event.
(make_lispy_event): Handle TOOLBAR_EVENT.
(toolbar_items): New.
(process_toolbar_item): New.
(PROP): New.
(init_toolbar_items): New.
(append_toolbar_item): New.
(read_char_x_menu_prompt): Handle `toolbar' event.
(read_key_sequence): Ditto.
(syms_of_keyboard): Intern `:help'.
(toolbar_items): New.
(process_toolbar_item): New.
(parse_toolbar_item): New.
(init_toolbar_items): New.
(append_toolbar_item): New.
(detect_input_pending_run_timers): Likewise.
(detect_input_pending_run_timers): Call gobble_input
after redisplaying.
(clear_waiting_for_input): Return void.
(record_asynch_buffer_change): Return void.
(stop_polling): Return void.
(start_polling): Ditto.
(cmd_error_internal): Write to stderr if selected
frame is Vterminal_frame under X. This is the case when a font
cannot be loaded when Emacs starts. Replace test for
FRAME_MESSAGE_BUF with test for glyphs_initialized_p.
(quit_throw_to_read_char): Ditto.
(make_lispy_event): mouse clicks; don't do frame
glyph position calculations.
(make_lispy_movement): Use buffer_posn_from_coords and window
relative coordinates.
(make_lispy_event): For mouse clicks, use
x_y_to_hpos_vpos.
(make_lispy_event): Use BUFFER_POSN_FROM_COORDS
with window relative pixel coordinates. Use GLYPH_TO_PIXEL_-
COORDS mit new arguments.
(make_lispy_event): WINDOW_FROM_COORDINATES with
pixel coords.
(make_lispy_movement): Same.
(interrupt_signal): Cursor_to with 4 params.
(command_loop_1): Call DIRECT_OUTPUT_FOR_INSERT
for any character.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 837 |
1 files changed, 716 insertions, 121 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 78860dd6496..282ce450297 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -166,6 +166,11 @@ extern int message_enable_multibyte; | |||
| 166 | 166 | ||
| 167 | extern struct backtrace *backtrace_list; | 167 | extern struct backtrace *backtrace_list; |
| 168 | 168 | ||
| 169 | /* If non-nil, the function that implements the display of help. | ||
| 170 | It's called with one argument, the help string to display. */ | ||
| 171 | |||
| 172 | Lisp_Object Vshow_help_function; | ||
| 173 | |||
| 169 | /* Nonzero means do menu prompting. */ | 174 | /* Nonzero means do menu prompting. */ |
| 170 | static int menu_prompting; | 175 | static int menu_prompting; |
| 171 | 176 | ||
| @@ -459,7 +464,7 @@ static struct input_event *kbd_fetch_ptr; | |||
| 459 | /* Pointer to next place to store character in kbd_buffer. This | 464 | /* Pointer to next place to store character in kbd_buffer. This |
| 460 | may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next | 465 | may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next |
| 461 | character should go in kbd_buffer[0]. */ | 466 | character should go in kbd_buffer[0]. */ |
| 462 | static volatile struct input_event *kbd_store_ptr; | 467 | static struct input_event * volatile kbd_store_ptr; |
| 463 | 468 | ||
| 464 | /* The above pair of variables forms a "queue empty" flag. When we | 469 | /* The above pair of variables forms a "queue empty" flag. When we |
| 465 | enqueue a non-hook event, we increment kbd_store_ptr. When we | 470 | enqueue a non-hook event, we increment kbd_store_ptr. When we |
| @@ -482,6 +487,7 @@ Lisp_Object Qswitch_frame; | |||
| 482 | Lisp_Object Qdelete_frame; | 487 | Lisp_Object Qdelete_frame; |
| 483 | Lisp_Object Qiconify_frame; | 488 | Lisp_Object Qiconify_frame; |
| 484 | Lisp_Object Qmake_frame_visible; | 489 | Lisp_Object Qmake_frame_visible; |
| 490 | Lisp_Object Qhelp_echo; | ||
| 485 | 491 | ||
| 486 | /* Symbols to denote kinds of events. */ | 492 | /* Symbols to denote kinds of events. */ |
| 487 | Lisp_Object Qfunction_key; | 493 | Lisp_Object Qfunction_key; |
| @@ -600,6 +606,7 @@ static Lisp_Object make_lispy_switch_frame (); | |||
| 600 | static int parse_solitary_modifier (); | 606 | static int parse_solitary_modifier (); |
| 601 | static void save_getcjmp (); | 607 | static void save_getcjmp (); |
| 602 | static void restore_getcjmp (); | 608 | static void restore_getcjmp (); |
| 609 | static Lisp_Object apply_modifiers P_ ((int, Lisp_Object)); | ||
| 603 | 610 | ||
| 604 | /* > 0 if we are to echo keystrokes. */ | 611 | /* > 0 if we are to echo keystrokes. */ |
| 605 | static int echo_keystrokes; | 612 | static int echo_keystrokes; |
| @@ -1014,17 +1021,27 @@ cmd_error_internal (data, context) | |||
| 1014 | char *context; | 1021 | char *context; |
| 1015 | { | 1022 | { |
| 1016 | Lisp_Object stream; | 1023 | Lisp_Object stream; |
| 1024 | int kill_emacs_p = 0; | ||
| 1017 | 1025 | ||
| 1018 | Vquit_flag = Qnil; | 1026 | Vquit_flag = Qnil; |
| 1019 | Vinhibit_quit = Qt; | 1027 | Vinhibit_quit = Qt; |
| 1020 | echo_area_glyphs = 0; | 1028 | echo_area_glyphs = 0; |
| 1029 | echo_area_message = Qnil; | ||
| 1021 | 1030 | ||
| 1022 | /* If the window system or terminal frame hasn't been initialized | 1031 | /* If the window system or terminal frame hasn't been initialized |
| 1023 | yet, or we're not interactive, it's best to dump this message out | 1032 | yet, or we're not interactive, it's best to dump this message out |
| 1024 | to stderr and exit. */ | 1033 | to stderr and exit. */ |
| 1025 | if (! FRAME_MESSAGE_BUF (selected_frame) | 1034 | if (!selected_frame->glyphs_initialized_p |
| 1035 | /* This is the case of the frame dumped with Emacs, when we're | ||
| 1036 | running under a window system. */ | ||
| 1037 | || (!NILP (Vwindow_system) | ||
| 1038 | && !inhibit_window_system | ||
| 1039 | && !FRAME_WINDOW_P (selected_frame)) | ||
| 1026 | || noninteractive) | 1040 | || noninteractive) |
| 1027 | stream = Qexternal_debugging_output; | 1041 | { |
| 1042 | stream = Qexternal_debugging_output; | ||
| 1043 | kill_emacs_p = 1; | ||
| 1044 | } | ||
| 1028 | else | 1045 | else |
| 1029 | { | 1046 | { |
| 1030 | Fdiscard_input (); | 1047 | Fdiscard_input (); |
| @@ -1039,8 +1056,7 @@ cmd_error_internal (data, context) | |||
| 1039 | 1056 | ||
| 1040 | /* If the window system or terminal frame hasn't been initialized | 1057 | /* If the window system or terminal frame hasn't been initialized |
| 1041 | yet, or we're in -batch mode, this error should cause Emacs to exit. */ | 1058 | yet, or we're in -batch mode, this error should cause Emacs to exit. */ |
| 1042 | if (! FRAME_MESSAGE_BUF (selected_frame) | 1059 | if (kill_emacs_p) |
| 1043 | || noninteractive) | ||
| 1044 | { | 1060 | { |
| 1045 | Fterpri (stream); | 1061 | Fterpri (stream); |
| 1046 | Fkill_emacs (make_number (-1)); | 1062 | Fkill_emacs (make_number (-1)); |
| @@ -1222,7 +1238,8 @@ command_loop_1 () | |||
| 1222 | /* If minibuffer on and echo area in use, | 1238 | /* If minibuffer on and echo area in use, |
| 1223 | wait 2 sec and redraw minibuffer. */ | 1239 | wait 2 sec and redraw minibuffer. */ |
| 1224 | 1240 | ||
| 1225 | if (minibuf_level && echo_area_glyphs | 1241 | if (minibuf_level |
| 1242 | && (echo_area_glyphs || STRINGP (echo_area_message)) | ||
| 1226 | && EQ (minibuf_window, echo_area_window)) | 1243 | && EQ (minibuf_window, echo_area_window)) |
| 1227 | { | 1244 | { |
| 1228 | /* Bind inhibit-quit to t so that C-g gets read in | 1245 | /* Bind inhibit-quit to t so that C-g gets read in |
| @@ -1421,7 +1438,6 @@ command_loop_1 () | |||
| 1421 | { | 1438 | { |
| 1422 | unsigned int c = XINT (last_command_char); | 1439 | unsigned int c = XINT (last_command_char); |
| 1423 | int value; | 1440 | int value; |
| 1424 | |||
| 1425 | if (NILP (Vexecuting_macro) | 1441 | if (NILP (Vexecuting_macro) |
| 1426 | && !EQ (minibuf_window, selected_window)) | 1442 | && !EQ (minibuf_window, selected_window)) |
| 1427 | { | 1443 | { |
| @@ -1432,6 +1448,7 @@ command_loop_1 () | |||
| 1432 | } | 1448 | } |
| 1433 | nonundocount++; | 1449 | nonundocount++; |
| 1434 | } | 1450 | } |
| 1451 | |||
| 1435 | lose = ((XFASTINT (XWINDOW (selected_window)->last_modified) | 1452 | lose = ((XFASTINT (XWINDOW (selected_window)->last_modified) |
| 1436 | < MODIFF) | 1453 | < MODIFF) |
| 1437 | || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified) | 1454 | || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified) |
| @@ -1444,58 +1461,33 @@ command_loop_1 () | |||
| 1444 | || detect_input_pending () | 1461 | || detect_input_pending () |
| 1445 | || !NILP (XWINDOW (selected_window)->column_number_displayed) | 1462 | || !NILP (XWINDOW (selected_window)->column_number_displayed) |
| 1446 | || !NILP (Vexecuting_macro)); | 1463 | || !NILP (Vexecuting_macro)); |
| 1464 | |||
| 1447 | value = internal_self_insert (c, 0); | 1465 | value = internal_self_insert (c, 0); |
| 1448 | if (value) | 1466 | |
| 1449 | lose = 1; | ||
| 1450 | if (value == 2) | 1467 | if (value == 2) |
| 1451 | nonundocount = 0; | 1468 | nonundocount = 0; |
| 1452 | 1469 | ||
| 1453 | if (!lose | 1470 | /* VALUE == 1 when AFTER-CHANGE functions are |
| 1454 | && (PT == ZV || FETCH_BYTE (PT_BYTE) == '\n')) | 1471 | installed which is the case most of the time |
| 1455 | { | 1472 | because FONT-LOCK installs one. */ |
| 1456 | struct Lisp_Char_Table *dp | 1473 | if (!lose && !value) |
| 1457 | = window_display_table (XWINDOW (selected_window)); | 1474 | no_redisplay = direct_output_for_insert (c); |
| 1458 | int lose = c; | ||
| 1459 | |||
| 1460 | /* Add the offset to the character, for Finsert_char. | ||
| 1461 | We pass internal_self_insert the unmodified character | ||
| 1462 | because it itself does this offsetting. */ | ||
| 1463 | if (! NILP (current_buffer->enable_multibyte_characters)) | ||
| 1464 | lose = unibyte_char_to_multibyte (lose); | ||
| 1465 | |||
| 1466 | if (dp) | ||
| 1467 | { | ||
| 1468 | Lisp_Object obj; | ||
| 1469 | |||
| 1470 | obj = DISP_CHAR_VECTOR (dp, lose); | ||
| 1471 | if (NILP (obj)) | ||
| 1472 | { | ||
| 1473 | /* Do it only for char codes | ||
| 1474 | that by default display as themselves. */ | ||
| 1475 | if (lose >= 0x20 && lose <= 0x7e) | ||
| 1476 | no_redisplay = direct_output_for_insert (lose); | ||
| 1477 | } | ||
| 1478 | else if (VECTORP (obj) | ||
| 1479 | && XVECTOR (obj)->size == 1 | ||
| 1480 | && (obj = XVECTOR (obj)->contents[0], | ||
| 1481 | INTEGERP (obj)) | ||
| 1482 | /* Insist face not specified in glyph. */ | ||
| 1483 | && (XINT (obj) & ((-1) << 8)) == 0) | ||
| 1484 | no_redisplay | ||
| 1485 | = direct_output_for_insert (XINT (obj)); | ||
| 1486 | } | ||
| 1487 | else | ||
| 1488 | { | ||
| 1489 | if (lose >= 0x20 && lose <= 0x7e) | ||
| 1490 | no_redisplay = direct_output_for_insert (lose); | ||
| 1491 | } | ||
| 1492 | } | ||
| 1493 | goto directly_done; | 1475 | goto directly_done; |
| 1494 | } | 1476 | } |
| 1495 | } | 1477 | } |
| 1496 | 1478 | ||
| 1497 | /* Here for a command that isn't executed directly */ | 1479 | /* Here for a command that isn't executed directly */ |
| 1498 | 1480 | ||
| 1481 | #ifdef HAVE_X_WINDOWS | ||
| 1482 | if (display_busy_cursor_p) | ||
| 1483 | { | ||
| 1484 | if (inhibit_busy_cursor != 2) | ||
| 1485 | inhibit_busy_cursor = 0; | ||
| 1486 | if (!inhibit_busy_cursor) | ||
| 1487 | Fx_show_busy_cursor (); | ||
| 1488 | } | ||
| 1489 | #endif | ||
| 1490 | |||
| 1499 | nonundocount = 0; | 1491 | nonundocount = 0; |
| 1500 | if (NILP (current_kboard->Vprefix_arg)) | 1492 | if (NILP (current_kboard->Vprefix_arg)) |
| 1501 | Fundo_boundary (); | 1493 | Fundo_boundary (); |
| @@ -1810,7 +1802,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1810 | jmp_buf save_jump; | 1802 | jmp_buf save_jump; |
| 1811 | int key_already_recorded = 0; | 1803 | int key_already_recorded = 0; |
| 1812 | Lisp_Object tem, save; | 1804 | Lisp_Object tem, save; |
| 1813 | Lisp_Object echo_area_message; | 1805 | Lisp_Object previous_echo_area_message; |
| 1814 | Lisp_Object also_record; | 1806 | Lisp_Object also_record; |
| 1815 | int reread; | 1807 | int reread; |
| 1816 | struct gcpro gcpro1, gcpro2; | 1808 | struct gcpro gcpro1, gcpro2; |
| @@ -1820,9 +1812,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1820 | before_command_key_count = this_command_key_count; | 1812 | before_command_key_count = this_command_key_count; |
| 1821 | before_command_echo_length = echo_length (); | 1813 | before_command_echo_length = echo_length (); |
| 1822 | c = Qnil; | 1814 | c = Qnil; |
| 1823 | echo_area_message = Qnil; | 1815 | previous_echo_area_message = Qnil; |
| 1824 | 1816 | ||
| 1825 | GCPRO2 (c, echo_area_message); | 1817 | GCPRO2 (c, previous_echo_area_message); |
| 1826 | 1818 | ||
| 1827 | retry: | 1819 | retry: |
| 1828 | 1820 | ||
| @@ -1958,10 +1950,13 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1958 | } | 1950 | } |
| 1959 | 1951 | ||
| 1960 | /* Message turns off echoing unless more keystrokes turn it on again. */ | 1952 | /* Message turns off echoing unless more keystrokes turn it on again. */ |
| 1961 | if (echo_area_glyphs && *echo_area_glyphs | 1953 | if (echo_area_glyphs |
| 1954 | && *echo_area_glyphs | ||
| 1962 | && echo_area_glyphs != current_kboard->echobuf | 1955 | && echo_area_glyphs != current_kboard->echobuf |
| 1963 | && ok_to_echo_at_next_pause != echo_area_glyphs) | 1956 | && ok_to_echo_at_next_pause != echo_area_glyphs) |
| 1964 | cancel_echoing (); | 1957 | cancel_echoing (); |
| 1958 | else if (STRINGP (echo_area_message)) | ||
| 1959 | cancel_echoing (); | ||
| 1965 | else | 1960 | else |
| 1966 | /* If already echoing, continue. */ | 1961 | /* If already echoing, continue. */ |
| 1967 | echo_dash (); | 1962 | echo_dash (); |
| @@ -2034,10 +2029,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2034 | /* If in middle of key sequence and minibuffer not active, | 2029 | /* If in middle of key sequence and minibuffer not active, |
| 2035 | start echoing if enough time elapses. */ | 2030 | start echoing if enough time elapses. */ |
| 2036 | 2031 | ||
| 2037 | if (minibuf_level == 0 && !current_kboard->immediate_echo | 2032 | if (minibuf_level == 0 |
| 2033 | && !current_kboard->immediate_echo | ||
| 2038 | && this_command_key_count > 0 | 2034 | && this_command_key_count > 0 |
| 2039 | && ! noninteractive | 2035 | && ! noninteractive |
| 2040 | && echo_keystrokes > 0 | 2036 | && echo_keystrokes > 0 |
| 2037 | && !STRINGP (echo_area_message) | ||
| 2041 | && (echo_area_glyphs == 0 || *echo_area_glyphs == 0 | 2038 | && (echo_area_glyphs == 0 || *echo_area_glyphs == 0 |
| 2042 | || ok_to_echo_at_next_pause == echo_area_glyphs)) | 2039 | || ok_to_echo_at_next_pause == echo_area_glyphs)) |
| 2043 | { | 2040 | { |
| @@ -2081,6 +2078,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2081 | && !NILP (prev_event) | 2078 | && !NILP (prev_event) |
| 2082 | && EVENT_HAS_PARAMETERS (prev_event) | 2079 | && EVENT_HAS_PARAMETERS (prev_event) |
| 2083 | && !EQ (XCONS (prev_event)->car, Qmenu_bar) | 2080 | && !EQ (XCONS (prev_event)->car, Qmenu_bar) |
| 2081 | && !EQ (XCONS (prev_event)->car, Qtoolbar) | ||
| 2084 | /* Don't bring up a menu if we already have another event. */ | 2082 | /* Don't bring up a menu if we already have another event. */ |
| 2085 | && NILP (Vunread_command_events) | 2083 | && NILP (Vunread_command_events) |
| 2086 | && unread_command_char < 0) | 2084 | && unread_command_char < 0) |
| @@ -2333,7 +2331,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2333 | posn = POSN_BUFFER_POSN (EVENT_START (c)); | 2331 | posn = POSN_BUFFER_POSN (EVENT_START (c)); |
| 2334 | /* Handle menu-bar events: | 2332 | /* Handle menu-bar events: |
| 2335 | insert the dummy prefix event `menu-bar'. */ | 2333 | insert the dummy prefix event `menu-bar'. */ |
| 2336 | if (EQ (posn, Qmenu_bar)) | 2334 | if (EQ (posn, Qmenu_bar) || EQ (posn, Qtoolbar)) |
| 2337 | { | 2335 | { |
| 2338 | /* Change menu-bar to (menu-bar) as the event "position". */ | 2336 | /* Change menu-bar to (menu-bar) as the event "position". */ |
| 2339 | POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil); | 2337 | POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil); |
| @@ -2357,12 +2355,16 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2357 | && ! NILP (Vinput_method_function) | 2355 | && ! NILP (Vinput_method_function) |
| 2358 | && (unsigned) XINT (c) >= ' ' | 2356 | && (unsigned) XINT (c) >= ' ' |
| 2359 | && (unsigned) XINT (c) < 127) | 2357 | && (unsigned) XINT (c) < 127) |
| 2360 | Vinput_method_previous_message = echo_area_message = Fcurrent_message (); | 2358 | { |
| 2359 | previous_echo_area_message = Fcurrent_message (); | ||
| 2360 | Vinput_method_previous_message = previous_echo_area_message; | ||
| 2361 | } | ||
| 2361 | 2362 | ||
| 2362 | /* Now wipe the echo area. */ | 2363 | /* Now wipe the echo area. */ |
| 2363 | if (echo_area_glyphs) | 2364 | if (echo_area_glyphs || STRINGP (echo_area_message)) |
| 2364 | safe_run_hooks (Qecho_area_clear_hook); | 2365 | safe_run_hooks (Qecho_area_clear_hook); |
| 2365 | echo_area_glyphs = 0; | 2366 | echo_area_glyphs = 0; |
| 2367 | echo_area_message = Qnil; | ||
| 2366 | 2368 | ||
| 2367 | reread_for_input_method: | 2369 | reread_for_input_method: |
| 2368 | from_macro: | 2370 | from_macro: |
| @@ -2407,9 +2409,10 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2407 | this_command_key_count = 0; | 2409 | this_command_key_count = 0; |
| 2408 | 2410 | ||
| 2409 | /* Now wipe the echo area. */ | 2411 | /* Now wipe the echo area. */ |
| 2410 | if (echo_area_glyphs) | 2412 | if (echo_area_glyphs || STRINGP (echo_area_message)) |
| 2411 | safe_run_hooks (Qecho_area_clear_hook); | 2413 | safe_run_hooks (Qecho_area_clear_hook); |
| 2412 | echo_area_glyphs = 0; | 2414 | echo_area_glyphs = 0; |
| 2415 | echo_area_message = Qnil; | ||
| 2413 | echo_truncate (0); | 2416 | echo_truncate (0); |
| 2414 | 2417 | ||
| 2415 | /* If we are not reading a key sequence, | 2418 | /* If we are not reading a key sequence, |
| @@ -2442,8 +2445,8 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2442 | if (! CONSP (tem)) | 2445 | if (! CONSP (tem)) |
| 2443 | { | 2446 | { |
| 2444 | /* Bring back the previous message, if any. */ | 2447 | /* Bring back the previous message, if any. */ |
| 2445 | if (! NILP (echo_area_message)) | 2448 | if (! NILP (previous_echo_area_message)) |
| 2446 | message_with_string ("%s", echo_area_message, 0); | 2449 | message_with_string ("%s", previous_echo_area_message, 0); |
| 2447 | goto retry; | 2450 | goto retry; |
| 2448 | } | 2451 | } |
| 2449 | /* It returned one event or more. */ | 2452 | /* It returned one event or more. */ |
| @@ -2454,6 +2457,25 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 2454 | 2457 | ||
| 2455 | reread_first: | 2458 | reread_first: |
| 2456 | 2459 | ||
| 2460 | /* Display help if not echoing. */ | ||
| 2461 | if (CONSP (c) | ||
| 2462 | && EQ (XCAR (c), Qhelp_echo)) | ||
| 2463 | { | ||
| 2464 | Lisp_Object msg = XCDR (XCDR (c)); | ||
| 2465 | |||
| 2466 | if (!NILP (Vshow_help_function)) | ||
| 2467 | call1 (Vshow_help_function, msg); | ||
| 2468 | else if (!echoing && !MINI_WINDOW_P (XWINDOW (selected_window))) | ||
| 2469 | { | ||
| 2470 | if (STRINGP (msg)) | ||
| 2471 | message3_nolog (msg, XSTRING (msg)->size, STRING_MULTIBYTE (msg)); | ||
| 2472 | else | ||
| 2473 | message (0); | ||
| 2474 | } | ||
| 2475 | |||
| 2476 | goto retry; | ||
| 2477 | } | ||
| 2478 | |||
| 2457 | if (this_command_key_count == 0 || ! reread) | 2479 | if (this_command_key_count == 0 || ! reread) |
| 2458 | { | 2480 | { |
| 2459 | before_command_key_count = this_command_key_count; | 2481 | before_command_key_count = this_command_key_count; |
| @@ -2523,6 +2545,7 @@ record_menu_key (c) | |||
| 2523 | { | 2545 | { |
| 2524 | /* Wipe the echo area. */ | 2546 | /* Wipe the echo area. */ |
| 2525 | echo_area_glyphs = 0; | 2547 | echo_area_glyphs = 0; |
| 2548 | echo_area_message = Qnil; | ||
| 2526 | 2549 | ||
| 2527 | record_char (c); | 2550 | record_char (c); |
| 2528 | 2551 | ||
| @@ -2855,7 +2878,7 @@ kbd_buffer_store_event (event) | |||
| 2855 | Discard the event if it would fill the last slot. */ | 2878 | Discard the event if it would fill the last slot. */ |
| 2856 | if (kbd_fetch_ptr - 1 != kbd_store_ptr) | 2879 | if (kbd_fetch_ptr - 1 != kbd_store_ptr) |
| 2857 | { | 2880 | { |
| 2858 | volatile struct input_event *sp = kbd_store_ptr; | 2881 | struct input_event *sp = kbd_store_ptr; |
| 2859 | sp->kind = event->kind; | 2882 | sp->kind = event->kind; |
| 2860 | if (event->kind == selection_request_event) | 2883 | if (event->kind == selection_request_event) |
| 2861 | { | 2884 | { |
| @@ -3100,7 +3123,13 @@ kbd_buffer_get_event (kbp, used_mouse_menu) | |||
| 3100 | mouse events during a popup-menu call. */ | 3123 | mouse events during a popup-menu call. */ |
| 3101 | else if (event->kind == no_event) | 3124 | else if (event->kind == no_event) |
| 3102 | kbd_fetch_ptr = event + 1; | 3125 | kbd_fetch_ptr = event + 1; |
| 3103 | 3126 | else if (event->kind == HELP_EVENT) | |
| 3127 | { | ||
| 3128 | /* The car of event->frame_or_window is a frame, | ||
| 3129 | the cdr is the help to display. */ | ||
| 3130 | obj = Fcons (Qhelp_echo, event->frame_or_window); | ||
| 3131 | kbd_fetch_ptr = event + 1; | ||
| 3132 | } | ||
| 3104 | /* If this event is on a different frame, return a switch-frame this | 3133 | /* If this event is on a different frame, return a switch-frame this |
| 3105 | time, and leave the event in the queue for next time. */ | 3134 | time, and leave the event in the queue for next time. */ |
| 3106 | else | 3135 | else |
| @@ -3135,8 +3164,10 @@ kbd_buffer_get_event (kbp, used_mouse_menu) | |||
| 3135 | we're returning is (menu-bar), though; that indicates the | 3164 | we're returning is (menu-bar), though; that indicates the |
| 3136 | beginning of the menu sequence, and we might as well leave | 3165 | beginning of the menu sequence, and we might as well leave |
| 3137 | that as the `event with parameters' for this selection. */ | 3166 | that as the `event with parameters' for this selection. */ |
| 3138 | if (event->kind == menu_bar_event | 3167 | if ((event->kind == menu_bar_event |
| 3168 | || event->kind == TOOLBAR_EVENT) | ||
| 3139 | && !(CONSP (obj) && EQ (XCONS (obj)->car, Qmenu_bar)) | 3169 | && !(CONSP (obj) && EQ (XCONS (obj)->car, Qmenu_bar)) |
| 3170 | && !(CONSP (obj) && EQ (XCONS (obj)->car, Qtoolbar)) | ||
| 3140 | && used_mouse_menu) | 3171 | && used_mouse_menu) |
| 3141 | *used_mouse_menu = 1; | 3172 | *used_mouse_menu = 1; |
| 3142 | #endif | 3173 | #endif |
| @@ -3471,6 +3502,9 @@ timer_check (do_it_now) | |||
| 3471 | Lisp_Object tem; | 3502 | Lisp_Object tem; |
| 3472 | int was_locked = single_kboard; | 3503 | int was_locked = single_kboard; |
| 3473 | int count = specpdl_ptr - specpdl; | 3504 | int count = specpdl_ptr - specpdl; |
| 3505 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 3506 | int old_inhibit_busy_cursor = inhibit_busy_cursor; | ||
| 3507 | #endif | ||
| 3474 | 3508 | ||
| 3475 | /* Mark the timer as triggered to prevent problems if the lisp | 3509 | /* Mark the timer as triggered to prevent problems if the lisp |
| 3476 | code fails to reschedule it right. */ | 3510 | code fails to reschedule it right. */ |
| @@ -3478,9 +3512,17 @@ timer_check (do_it_now) | |||
| 3478 | 3512 | ||
| 3479 | specbind (Qinhibit_quit, Qt); | 3513 | specbind (Qinhibit_quit, Qt); |
| 3480 | 3514 | ||
| 3515 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 3516 | inhibit_busy_cursor = 2; | ||
| 3517 | #endif | ||
| 3518 | |||
| 3481 | call1 (Qtimer_event_handler, chosen_timer); | 3519 | call1 (Qtimer_event_handler, chosen_timer); |
| 3482 | timers_run++; | 3520 | timers_run++; |
| 3483 | 3521 | ||
| 3522 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 3523 | inhibit_busy_cursor = old_inhibit_busy_cursor; | ||
| 3524 | #endif | ||
| 3525 | |||
| 3484 | unbind_to (count, Qnil); | 3526 | unbind_to (count, Qnil); |
| 3485 | 3527 | ||
| 3486 | /* Resume allowing input from any kboard, if that was true before. */ | 3528 | /* Resume allowing input from any kboard, if that was true before. */ |
| @@ -3946,12 +3988,13 @@ static char *lispy_drag_n_drop_names[] = | |||
| 3946 | 3988 | ||
| 3947 | /* Scroll bar parts. */ | 3989 | /* Scroll bar parts. */ |
| 3948 | Lisp_Object Qabove_handle, Qhandle, Qbelow_handle; | 3990 | Lisp_Object Qabove_handle, Qhandle, Qbelow_handle; |
| 3949 | Lisp_Object Qup, Qdown; | 3991 | Lisp_Object Qup, Qdown, Qbottom, Qend_scroll; |
| 3992 | Lisp_Object Qtop; | ||
| 3950 | 3993 | ||
| 3951 | /* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */ | 3994 | /* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */ |
| 3952 | Lisp_Object *scroll_bar_parts[] = { | 3995 | Lisp_Object *scroll_bar_parts[] = { |
| 3953 | &Qabove_handle, &Qhandle, &Qbelow_handle, | 3996 | &Qabove_handle, &Qhandle, &Qbelow_handle, |
| 3954 | &Qup, &Qdown, | 3997 | &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll |
| 3955 | }; | 3998 | }; |
| 3956 | 3999 | ||
| 3957 | /* User signal events. */ | 4000 | /* User signal events. */ |
| @@ -4095,7 +4138,9 @@ make_lispy_event (event) | |||
| 4095 | /* A mouse click. Figure out where it is, decide whether it's | 4138 | /* A mouse click. Figure out where it is, decide whether it's |
| 4096 | a press, click or drag, and build the appropriate structure. */ | 4139 | a press, click or drag, and build the appropriate structure. */ |
| 4097 | case mouse_click: | 4140 | case mouse_click: |
| 4141 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 4098 | case scroll_bar_click: | 4142 | case scroll_bar_click: |
| 4143 | #endif | ||
| 4099 | { | 4144 | { |
| 4100 | int button = event->code; | 4145 | int button = event->code; |
| 4101 | int is_double; | 4146 | int is_double; |
| @@ -4113,6 +4158,7 @@ make_lispy_event (event) | |||
| 4113 | FRAME_PTR f = XFRAME (event->frame_or_window); | 4158 | FRAME_PTR f = XFRAME (event->frame_or_window); |
| 4114 | Lisp_Object window; | 4159 | Lisp_Object window; |
| 4115 | Lisp_Object posn; | 4160 | Lisp_Object posn; |
| 4161 | Lisp_Object string_info = Qnil; | ||
| 4116 | int row, column; | 4162 | int row, column; |
| 4117 | 4163 | ||
| 4118 | /* Ignore mouse events that were made on frame that | 4164 | /* Ignore mouse events that were made on frame that |
| @@ -4120,8 +4166,13 @@ make_lispy_event (event) | |||
| 4120 | if (! FRAME_LIVE_P (f)) | 4166 | if (! FRAME_LIVE_P (f)) |
| 4121 | return Qnil; | 4167 | return Qnil; |
| 4122 | 4168 | ||
| 4123 | pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), | 4169 | /* EVENT->x and EVENT->y are frame-relative pixel |
| 4124 | &column, &row, NULL, 1); | 4170 | coordinates at this place. Under old redisplay, COLUMN |
| 4171 | and ROW are set to frame relative glyph coordinates | ||
| 4172 | which are then used to determine whether this click is | ||
| 4173 | in a menu (non-toolkit version). */ | ||
| 4174 | pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), | ||
| 4175 | &column, &row, NULL, 1); | ||
| 4125 | 4176 | ||
| 4126 | #ifndef USE_X_TOOLKIT | 4177 | #ifndef USE_X_TOOLKIT |
| 4127 | /* In the non-toolkit version, clicks on the menu bar | 4178 | /* In the non-toolkit version, clicks on the menu bar |
| @@ -4146,6 +4197,7 @@ make_lispy_event (event) | |||
| 4146 | return Qnil; | 4197 | return Qnil; |
| 4147 | #endif | 4198 | #endif |
| 4148 | 4199 | ||
| 4200 | /* Find the menu bar item under `column'. */ | ||
| 4149 | item = Qnil; | 4201 | item = Qnil; |
| 4150 | items = FRAME_MENU_BAR_ITEMS (f); | 4202 | items = FRAME_MENU_BAR_ITEMS (f); |
| 4151 | for (i = 0; i < XVECTOR (items)->size; i += 4) | 4203 | for (i = 0; i < XVECTOR (items)->size; i += 4) |
| @@ -4163,6 +4215,8 @@ make_lispy_event (event) | |||
| 4163 | } | 4215 | } |
| 4164 | } | 4216 | } |
| 4165 | 4217 | ||
| 4218 | /* ELisp manual 2.4b says (x y) are window relative but | ||
| 4219 | code says they are frame-relative. */ | ||
| 4166 | position | 4220 | position |
| 4167 | = Fcons (event->frame_or_window, | 4221 | = Fcons (event->frame_or_window, |
| 4168 | Fcons (Qmenu_bar, | 4222 | Fcons (Qmenu_bar, |
| @@ -4174,7 +4228,10 @@ make_lispy_event (event) | |||
| 4174 | } | 4228 | } |
| 4175 | #endif /* not USE_X_TOOLKIT */ | 4229 | #endif /* not USE_X_TOOLKIT */ |
| 4176 | 4230 | ||
| 4177 | window = window_from_coordinates (f, column, row, &part); | 4231 | /* Set `window' to the window under frame pixel coordinates |
| 4232 | event->x/event->y. */ | ||
| 4233 | window = window_from_coordinates (f, XINT (event->x), | ||
| 4234 | XINT (event->y), &part, 0); | ||
| 4178 | 4235 | ||
| 4179 | if (!WINDOWP (window)) | 4236 | if (!WINDOWP (window)) |
| 4180 | { | 4237 | { |
| @@ -4183,21 +4240,36 @@ make_lispy_event (event) | |||
| 4183 | } | 4240 | } |
| 4184 | else | 4241 | else |
| 4185 | { | 4242 | { |
| 4186 | int pixcolumn, pixrow; | 4243 | /* It's a click in window window at frame coordinates |
| 4187 | column -= WINDOW_LEFT_MARGIN (XWINDOW (window)); | 4244 | event->x/ event->y. */ |
| 4188 | row -= XINT (XWINDOW (window)->top); | 4245 | struct window *w = XWINDOW (window); |
| 4189 | glyph_to_pixel_coords (f, column, row, &pixcolumn, &pixrow); | 4246 | |
| 4190 | XSETINT (event->x, pixcolumn); | 4247 | /* Get window relative coordinates. Original code |
| 4191 | XSETINT (event->y, pixrow); | 4248 | `rounded' this to glyph boundaries. */ |
| 4192 | 4249 | int wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (event->x)); | |
| 4193 | if (part == 1) | 4250 | int wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (event->y)); |
| 4194 | posn = Qmode_line; | 4251 | |
| 4252 | /* Set event coordinates to window-relative coordinates | ||
| 4253 | for constructing the Lisp event below. */ | ||
| 4254 | XSETINT (event->x, wx); | ||
| 4255 | XSETINT (event->y, wy); | ||
| 4256 | |||
| 4257 | if (part == 1 || part == 3) | ||
| 4258 | { | ||
| 4259 | /* Mode line or top line. Look for a string under | ||
| 4260 | the mouse that may have a `local-map' property. */ | ||
| 4261 | Lisp_Object string; | ||
| 4262 | int charpos; | ||
| 4263 | |||
| 4264 | posn = part == 1 ? Qmode_line : Qtop_line; | ||
| 4265 | string = mode_line_string (w, wx, wy, part == 1, &charpos); | ||
| 4266 | if (STRINGP (string)) | ||
| 4267 | string_info = Fcons (string, make_number (charpos)); | ||
| 4268 | } | ||
| 4195 | else if (part == 2) | 4269 | else if (part == 2) |
| 4196 | posn = Qvertical_line; | 4270 | posn = Qvertical_line; |
| 4197 | else | 4271 | else |
| 4198 | XSETINT (posn, | 4272 | XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy)); |
| 4199 | buffer_posn_from_coords (XWINDOW (window), | ||
| 4200 | column, row)); | ||
| 4201 | } | 4273 | } |
| 4202 | 4274 | ||
| 4203 | position | 4275 | position |
| @@ -4205,10 +4277,14 @@ make_lispy_event (event) | |||
| 4205 | Fcons (posn, | 4277 | Fcons (posn, |
| 4206 | Fcons (Fcons (event->x, event->y), | 4278 | Fcons (Fcons (event->x, event->y), |
| 4207 | Fcons (make_number (event->timestamp), | 4279 | Fcons (make_number (event->timestamp), |
| 4208 | Qnil)))); | 4280 | (NILP (string_info) |
| 4281 | ? Qnil | ||
| 4282 | : Fcons (string_info, Qnil)))))); | ||
| 4209 | } | 4283 | } |
| 4284 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 4210 | else | 4285 | else |
| 4211 | { | 4286 | { |
| 4287 | /* It's a scrollbar click. */ | ||
| 4212 | Lisp_Object window; | 4288 | Lisp_Object window; |
| 4213 | Lisp_Object portion_whole; | 4289 | Lisp_Object portion_whole; |
| 4214 | Lisp_Object part; | 4290 | Lisp_Object part; |
| @@ -4224,6 +4300,7 @@ make_lispy_event (event) | |||
| 4224 | Fcons (make_number (event->timestamp), | 4300 | Fcons (make_number (event->timestamp), |
| 4225 | Fcons (part, Qnil))))); | 4301 | Fcons (part, Qnil))))); |
| 4226 | } | 4302 | } |
| 4303 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 4227 | 4304 | ||
| 4228 | start_pos_ptr = &XVECTOR (button_down_location)->contents[button]; | 4305 | start_pos_ptr = &XVECTOR (button_down_location)->contents[button]; |
| 4229 | 4306 | ||
| @@ -4335,6 +4412,55 @@ make_lispy_event (event) | |||
| 4335 | } | 4412 | } |
| 4336 | } | 4413 | } |
| 4337 | 4414 | ||
| 4415 | #if USE_TOOLKIT_SCROLL_BARS | ||
| 4416 | |||
| 4417 | /* We don't have down and up events if using toolkit scroll bars, | ||
| 4418 | so make this always a click event. Store in the `part' of | ||
| 4419 | the Lisp event a symbol which maps to the following actions: | ||
| 4420 | |||
| 4421 | `above_handle' page up | ||
| 4422 | `below_handle' page down | ||
| 4423 | `up' line up | ||
| 4424 | `down' line down | ||
| 4425 | `top' top of buffer | ||
| 4426 | `bottom' bottom of buffer | ||
| 4427 | `handle' thumb has been dragged. | ||
| 4428 | `end-scroll' end of interaction with scroll bar | ||
| 4429 | |||
| 4430 | The incoming input_event contains in its `part' member an | ||
| 4431 | index of type `enum scroll_bar_part' which we can use as an | ||
| 4432 | index in scroll_bar_parts to get the appropriate symbol. */ | ||
| 4433 | |||
| 4434 | case scroll_bar_click: | ||
| 4435 | { | ||
| 4436 | Lisp_Object position, head, window, portion_whole, part; | ||
| 4437 | |||
| 4438 | window = event->frame_or_window; | ||
| 4439 | portion_whole = Fcons (event->x, event->y); | ||
| 4440 | part = *scroll_bar_parts[(int) event->part]; | ||
| 4441 | |||
| 4442 | position | ||
| 4443 | = Fcons (window, | ||
| 4444 | Fcons (Qvertical_scroll_bar, | ||
| 4445 | Fcons (portion_whole, | ||
| 4446 | Fcons (make_number (event->timestamp), | ||
| 4447 | Fcons (part, Qnil))))); | ||
| 4448 | |||
| 4449 | /* Always treat scroll bar events as clicks. */ | ||
| 4450 | event->modifiers |= click_modifier; | ||
| 4451 | |||
| 4452 | /* Get the symbol we should use for the mouse click. */ | ||
| 4453 | head = modify_event_symbol (event->code, | ||
| 4454 | event->modifiers, | ||
| 4455 | Qmouse_click, Qnil, | ||
| 4456 | lispy_mouse_names, &mouse_syms, | ||
| 4457 | (sizeof (lispy_mouse_names) | ||
| 4458 | / sizeof (lispy_mouse_names[0]))); | ||
| 4459 | return Fcons (head, Fcons (position, Qnil)); | ||
| 4460 | } | ||
| 4461 | |||
| 4462 | #endif /* USE_TOOLKIT_SCROLL_BARS */ | ||
| 4463 | |||
| 4338 | #ifdef WINDOWSNT | 4464 | #ifdef WINDOWSNT |
| 4339 | case w32_scroll_bar_click: | 4465 | case w32_scroll_bar_click: |
| 4340 | { | 4466 | { |
| @@ -4397,7 +4523,7 @@ make_lispy_event (event) | |||
| 4397 | return Qnil; | 4523 | return Qnil; |
| 4398 | pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), | 4524 | pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), |
| 4399 | &column, &row, NULL, 1); | 4525 | &column, &row, NULL, 1); |
| 4400 | window = window_from_coordinates (f, column, row, &part); | 4526 | window = window_from_coordinates (f, column, row, &part, 0); |
| 4401 | 4527 | ||
| 4402 | if (!WINDOWP (window)) | 4528 | if (!WINDOWP (window)) |
| 4403 | { | 4529 | { |
| @@ -4417,6 +4543,8 @@ make_lispy_event (event) | |||
| 4417 | posn = Qmode_line; | 4543 | posn = Qmode_line; |
| 4418 | else if (part == 2) | 4544 | else if (part == 2) |
| 4419 | posn = Qvertical_line; | 4545 | posn = Qvertical_line; |
| 4546 | else if (part == 3) | ||
| 4547 | posn = Qtop_line; | ||
| 4420 | else | 4548 | else |
| 4421 | XSETINT (posn, | 4549 | XSETINT (posn, |
| 4422 | buffer_posn_from_coords (XWINDOW (window), | 4550 | buffer_posn_from_coords (XWINDOW (window), |
| @@ -4470,7 +4598,7 @@ make_lispy_event (event) | |||
| 4470 | return Qnil; | 4598 | return Qnil; |
| 4471 | pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), | 4599 | pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), |
| 4472 | &column, &row, NULL, 1); | 4600 | &column, &row, NULL, 1); |
| 4473 | window = window_from_coordinates (f, column, row, &part); | 4601 | window = window_from_coordinates (f, column, row, &part, 0); |
| 4474 | 4602 | ||
| 4475 | if (!WINDOWP (window)) | 4603 | if (!WINDOWP (window)) |
| 4476 | { | 4604 | { |
| @@ -4479,21 +4607,27 @@ make_lispy_event (event) | |||
| 4479 | } | 4607 | } |
| 4480 | else | 4608 | else |
| 4481 | { | 4609 | { |
| 4482 | int pixcolumn, pixrow; | 4610 | /* It's an event in window `window' at frame coordinates |
| 4483 | column -= XINT (XWINDOW (window)->left); | 4611 | event->x/ event->y. */ |
| 4484 | row -= XINT (XWINDOW (window)->top); | 4612 | struct window *w = XWINDOW (window); |
| 4485 | glyph_to_pixel_coords (f, column, row, &pixcolumn, &pixrow); | 4613 | |
| 4486 | XSETINT (event->x, pixcolumn); | 4614 | /* Get window relative coordinates. */ |
| 4487 | XSETINT (event->y, pixrow); | 4615 | int wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (event->x)); |
| 4616 | int wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (event->y)); | ||
| 4617 | |||
| 4618 | /* Set event coordinates to window-relative coordinates | ||
| 4619 | for constructing the Lisp event below. */ | ||
| 4620 | XSETINT (event->x, wx); | ||
| 4621 | XSETINT (event->y, wy); | ||
| 4488 | 4622 | ||
| 4489 | if (part == 1) | 4623 | if (part == 1) |
| 4490 | posn = Qmode_line; | 4624 | posn = Qmode_line; |
| 4491 | else if (part == 2) | 4625 | else if (part == 2) |
| 4492 | posn = Qvertical_line; | 4626 | posn = Qvertical_line; |
| 4627 | else if (part == 3) | ||
| 4628 | posn = Qtop_line; | ||
| 4493 | else | 4629 | else |
| 4494 | XSETINT (posn, | 4630 | XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy)); |
| 4495 | buffer_posn_from_coords (XWINDOW (window), | ||
| 4496 | column, row)); | ||
| 4497 | } | 4631 | } |
| 4498 | 4632 | ||
| 4499 | { | 4633 | { |
| @@ -4526,6 +4660,17 @@ make_lispy_event (event) | |||
| 4526 | return XCONS (event->frame_or_window)->cdr; | 4660 | return XCONS (event->frame_or_window)->cdr; |
| 4527 | #endif | 4661 | #endif |
| 4528 | 4662 | ||
| 4663 | case TOOLBAR_EVENT: | ||
| 4664 | { | ||
| 4665 | Lisp_Object key; | ||
| 4666 | if (!CONSP (event->frame_or_window)) | ||
| 4667 | abort (); | ||
| 4668 | key = XCDR (event->frame_or_window); | ||
| 4669 | if (SYMBOLP (key)) | ||
| 4670 | key = apply_modifiers (event->modifiers, key); | ||
| 4671 | return key; | ||
| 4672 | } | ||
| 4673 | |||
| 4529 | case user_signal: | 4674 | case user_signal: |
| 4530 | /* A user signal. */ | 4675 | /* A user signal. */ |
| 4531 | return *lispy_user_signals[event->code]; | 4676 | return *lispy_user_signals[event->code]; |
| @@ -4568,34 +4713,34 @@ make_lispy_movement (frame, bar_window, part, x, y, time) | |||
| 4568 | int area; | 4713 | int area; |
| 4569 | Lisp_Object window; | 4714 | Lisp_Object window; |
| 4570 | Lisp_Object posn; | 4715 | Lisp_Object posn; |
| 4571 | int column, row; | ||
| 4572 | 4716 | ||
| 4573 | if (frame) | 4717 | if (frame) |
| 4574 | { | 4718 | /* It's in a frame; which window on that frame? */ |
| 4575 | /* It's in a frame; which window on that frame? */ | 4719 | window = window_from_coordinates (frame, XINT (x), XINT (y), &area, 0); |
| 4576 | pixel_to_glyph_coords (frame, XINT (x), XINT (y), &column, &row, | ||
| 4577 | NULL, 1); | ||
| 4578 | window = window_from_coordinates (frame, column, row, &area); | ||
| 4579 | } | ||
| 4580 | else | 4720 | else |
| 4581 | window = Qnil; | 4721 | window = Qnil; |
| 4582 | 4722 | ||
| 4583 | if (WINDOWP (window)) | 4723 | if (WINDOWP (window)) |
| 4584 | { | 4724 | { |
| 4585 | int pixcolumn, pixrow; | 4725 | struct window *w = XWINDOW (window); |
| 4586 | column -= WINDOW_LEFT_MARGIN (XWINDOW (window)); | 4726 | int hpos, vpos; |
| 4587 | row -= XINT (XWINDOW (window)->top); | 4727 | int wx, wy; |
| 4588 | glyph_to_pixel_coords (frame, column, row, &pixcolumn, &pixrow); | 4728 | int pos; |
| 4589 | XSETINT (x, pixcolumn); | 4729 | |
| 4590 | XSETINT (y, pixrow); | 4730 | /* Get window relative coordinates. */ |
| 4591 | 4731 | wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (x)); | |
| 4732 | wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (y)); | ||
| 4733 | XSETINT (x, wx); | ||
| 4734 | XSETINT (y, wy); | ||
| 4735 | |||
| 4592 | if (area == 1) | 4736 | if (area == 1) |
| 4593 | posn = Qmode_line; | 4737 | posn = Qmode_line; |
| 4594 | else if (area == 2) | 4738 | else if (area == 2) |
| 4595 | posn = Qvertical_line; | 4739 | posn = Qvertical_line; |
| 4740 | else if (area == 3) | ||
| 4741 | posn = Qtop_line; | ||
| 4596 | else | 4742 | else |
| 4597 | XSETINT (posn, | 4743 | XSETINT (posn, buffer_posn_from_coords (w, &wx, &wy)); |
| 4598 | buffer_posn_from_coords (XWINDOW (window), column, row)); | ||
| 4599 | } | 4744 | } |
| 4600 | else if (frame != 0) | 4745 | else if (frame != 0) |
| 4601 | { | 4746 | { |
| @@ -5846,7 +5991,7 @@ menu_item_eval_property_1 (arg) | |||
| 5846 | 5991 | ||
| 5847 | /* Evaluate an expression and return the result (or nil if something | 5992 | /* Evaluate an expression and return the result (or nil if something |
| 5848 | went wrong). Used to evaluate dynamic parts of menu items. */ | 5993 | went wrong). Used to evaluate dynamic parts of menu items. */ |
| 5849 | static Lisp_Object | 5994 | Lisp_Object |
| 5850 | menu_item_eval_property (sexpr) | 5995 | menu_item_eval_property (sexpr) |
| 5851 | Lisp_Object sexpr; | 5996 | Lisp_Object sexpr; |
| 5852 | { | 5997 | { |
| @@ -6206,6 +6351,392 @@ parse_menu_item (item, notreal, inmenubar) | |||
| 6206 | 6351 | ||
| 6207 | return 1; | 6352 | return 1; |
| 6208 | } | 6353 | } |
| 6354 | |||
| 6355 | |||
| 6356 | |||
| 6357 | /*********************************************************************** | ||
| 6358 | Tool-bars | ||
| 6359 | ***********************************************************************/ | ||
| 6360 | |||
| 6361 | /* A vector holding toolbar items while they are parsed in function | ||
| 6362 | toolbar_items runs Each item occupies TOOLBAR_ITEM_NSCLOTS | ||
| 6363 | elements in the vector. */ | ||
| 6364 | |||
| 6365 | static Lisp_Object toolbar_items_vector; | ||
| 6366 | |||
| 6367 | /* A vector holding the result of parse_toolbar_item. Layout is like | ||
| 6368 | the one for a single item in toolbar_items_vector. */ | ||
| 6369 | |||
| 6370 | static Lisp_Object toolbar_item_properties; | ||
| 6371 | |||
| 6372 | /* Next free index in toolbar_items_vector. */ | ||
| 6373 | |||
| 6374 | static int ntoolbar_items; | ||
| 6375 | |||
| 6376 | /* The symbols `toolbar', `toolbar-item', and `:image'. */ | ||
| 6377 | |||
| 6378 | extern Lisp_Object Qtoolbar; | ||
| 6379 | Lisp_Object QCimage; | ||
| 6380 | |||
| 6381 | /* Function prototypes. */ | ||
| 6382 | |||
| 6383 | static void init_toolbar_items P_ ((Lisp_Object)); | ||
| 6384 | static void process_toolbar_item P_ ((Lisp_Object, Lisp_Object)); | ||
| 6385 | static int parse_toolbar_item P_ ((Lisp_Object, Lisp_Object)); | ||
| 6386 | static void append_toolbar_item P_ ((void)); | ||
| 6387 | |||
| 6388 | |||
| 6389 | /* Return a vector of toolbar items for keymaps currently in effect. | ||
| 6390 | Reuse vector REUSE if non-nil. Return in *NITEMS the number of | ||
| 6391 | toolbar items found. */ | ||
| 6392 | |||
| 6393 | Lisp_Object | ||
| 6394 | toolbar_items (reuse, nitems) | ||
| 6395 | Lisp_Object reuse; | ||
| 6396 | int *nitems; | ||
| 6397 | { | ||
| 6398 | Lisp_Object *maps; | ||
| 6399 | int nmaps, i; | ||
| 6400 | Lisp_Object oquit; | ||
| 6401 | Lisp_Object *tmaps; | ||
| 6402 | extern Lisp_Object Voverriding_local_map_menu_flag; | ||
| 6403 | extern Lisp_Object Voverriding_local_map; | ||
| 6404 | |||
| 6405 | *nitems = 0; | ||
| 6406 | |||
| 6407 | /* In order to build the menus, we need to call the keymap | ||
| 6408 | accessors. They all call QUIT. But this function is called | ||
| 6409 | during redisplay, during which a quit is fatal. So inhibit | ||
| 6410 | quitting while building the menus. We do this instead of | ||
| 6411 | specbind because (1) errors will clear it anyway and (2) this | ||
| 6412 | avoids risk of specpdl overflow. */ | ||
| 6413 | oquit = Vinhibit_quit; | ||
| 6414 | Vinhibit_quit = Qt; | ||
| 6415 | |||
| 6416 | /* Initialize toolbar_items_vector and protect it from GC. */ | ||
| 6417 | init_toolbar_items (reuse); | ||
| 6418 | |||
| 6419 | /* Build list of keymaps in maps. Set nmaps to the number of maps | ||
| 6420 | to process. */ | ||
| 6421 | |||
| 6422 | /* Should overriding-terminal-local-map and overriding-local-map apply? */ | ||
| 6423 | if (!NILP (Voverriding_local_map_menu_flag)) | ||
| 6424 | { | ||
| 6425 | /* Yes, use them (if non-nil) as well as the global map. */ | ||
| 6426 | maps = (Lisp_Object *) alloca (3 * sizeof (maps[0])); | ||
| 6427 | nmaps = 0; | ||
| 6428 | if (!NILP (current_kboard->Voverriding_terminal_local_map)) | ||
| 6429 | maps[nmaps++] = current_kboard->Voverriding_terminal_local_map; | ||
| 6430 | if (!NILP (Voverriding_local_map)) | ||
| 6431 | maps[nmaps++] = Voverriding_local_map; | ||
| 6432 | } | ||
| 6433 | else | ||
| 6434 | { | ||
| 6435 | /* No, so use major and minor mode keymaps. */ | ||
| 6436 | nmaps = current_minor_maps (NULL, &tmaps); | ||
| 6437 | maps = (Lisp_Object *) alloca ((nmaps + 2) * sizeof (maps[0])); | ||
| 6438 | bcopy (tmaps, maps, nmaps * sizeof (maps[0])); | ||
| 6439 | #ifdef USE_TEXT_PROPERTIES | ||
| 6440 | maps[nmaps++] = get_local_map (PT, current_buffer); | ||
| 6441 | #else | ||
| 6442 | maps[nmaps++] = current_buffer->keymap; | ||
| 6443 | #endif | ||
| 6444 | } | ||
| 6445 | |||
| 6446 | /* Add global keymap at the end. */ | ||
| 6447 | maps[nmaps++] = current_global_map; | ||
| 6448 | |||
| 6449 | /* Process maps in reverse order and look up in each map the prefix | ||
| 6450 | key `toolbar'. */ | ||
| 6451 | for (i = nmaps - 1; i >= 0; --i) | ||
| 6452 | if (!NILP (maps[i])) | ||
| 6453 | { | ||
| 6454 | Lisp_Object keymap; | ||
| 6455 | |||
| 6456 | keymap = get_keyelt (access_keymap (maps[i], Qtoolbar, 1, 1), 0); | ||
| 6457 | if (!NILP (Fkeymapp (keymap))) | ||
| 6458 | { | ||
| 6459 | Lisp_Object tail; | ||
| 6460 | |||
| 6461 | /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'. */ | ||
| 6462 | for (tail = keymap; CONSP (tail); tail = XCONS (tail)->cdr) | ||
| 6463 | { | ||
| 6464 | Lisp_Object keydef = XCAR (tail); | ||
| 6465 | if (CONSP (keydef)) | ||
| 6466 | process_toolbar_item (XCAR (keydef), XCDR (keydef)); | ||
| 6467 | } | ||
| 6468 | } | ||
| 6469 | } | ||
| 6470 | |||
| 6471 | Vinhibit_quit = oquit; | ||
| 6472 | *nitems = ntoolbar_items / TOOLBAR_ITEM_NSLOTS; | ||
| 6473 | return toolbar_items_vector; | ||
| 6474 | } | ||
| 6475 | |||
| 6476 | |||
| 6477 | /* Process the definition of KEY which is DEF. */ | ||
| 6478 | |||
| 6479 | static void | ||
| 6480 | process_toolbar_item (key, def) | ||
| 6481 | Lisp_Object key, def; | ||
| 6482 | { | ||
| 6483 | int i; | ||
| 6484 | extern Lisp_Object Qundefined; | ||
| 6485 | struct gcpro gcpro1, gcpro2; | ||
| 6486 | |||
| 6487 | /* Protect KEY and DEF from GC because parse_toolbar_item may call | ||
| 6488 | eval. */ | ||
| 6489 | GCPRO2 (key, def); | ||
| 6490 | |||
| 6491 | if (EQ (def, Qundefined)) | ||
| 6492 | { | ||
| 6493 | /* If a map has an explicit `undefined' as definition, | ||
| 6494 | discard any previously made item. */ | ||
| 6495 | for (i = 0; i < ntoolbar_items; i += TOOLBAR_ITEM_NSLOTS) | ||
| 6496 | { | ||
| 6497 | Lisp_Object *v = XVECTOR (toolbar_items_vector)->contents + i; | ||
| 6498 | |||
| 6499 | if (EQ (key, v[TOOLBAR_ITEM_KEY])) | ||
| 6500 | { | ||
| 6501 | if (ntoolbar_items > i + TOOLBAR_ITEM_NSLOTS) | ||
| 6502 | bcopy (v + TOOLBAR_ITEM_NSLOTS, v, | ||
| 6503 | ((ntoolbar_items - i - TOOLBAR_ITEM_NSLOTS) | ||
| 6504 | * sizeof (Lisp_Object))); | ||
| 6505 | ntoolbar_items -= TOOLBAR_ITEM_NSLOTS; | ||
| 6506 | break; | ||
| 6507 | } | ||
| 6508 | } | ||
| 6509 | } | ||
| 6510 | else if (parse_toolbar_item (key, def)) | ||
| 6511 | /* Append a new toolbar item to toolbar_items_vector. Accept | ||
| 6512 | more than one definition for the same key. */ | ||
| 6513 | append_toolbar_item (); | ||
| 6514 | |||
| 6515 | UNGCPRO; | ||
| 6516 | } | ||
| 6517 | |||
| 6518 | |||
| 6519 | /* Parse a toolbar item specification ITEM for key KEY and return the | ||
| 6520 | result in toolbar_item_properties. Value is zero if ITEM is | ||
| 6521 | invalid. | ||
| 6522 | |||
| 6523 | ITEM is a list `(menu-item CAPTION BINDING PROPS...)'. | ||
| 6524 | |||
| 6525 | CAPTION is the caption of the item, If it's not a string, it is | ||
| 6526 | evaluated to get a string. | ||
| 6527 | |||
| 6528 | BINDING is the toolbar item's binding. Toolbar items with keymaps | ||
| 6529 | as binding are currently ignored. | ||
| 6530 | |||
| 6531 | The following properties are recognized: | ||
| 6532 | |||
| 6533 | - `:enable FORM'. | ||
| 6534 | |||
| 6535 | FORM is evaluated and specifies whether the toolbar item is enabled | ||
| 6536 | or disabled. | ||
| 6537 | |||
| 6538 | - `:visible FORM' | ||
| 6539 | |||
| 6540 | FORM is evaluated and specifies whether the toolbar item is visible. | ||
| 6541 | |||
| 6542 | - `:filter FUNCTION' | ||
| 6543 | |||
| 6544 | FUNCTION is invoked with one parameter `(quote BINDING)'. Its | ||
| 6545 | result is stored as the new binding. | ||
| 6546 | |||
| 6547 | - `:button (TYPE SELECTED)' | ||
| 6548 | |||
| 6549 | TYPE must be one of `:radio' or `:toggle'. SELECTED is evaluated | ||
| 6550 | and specifies whether the button is selected (pressed) or not. | ||
| 6551 | |||
| 6552 | - `:image IMAGES' | ||
| 6553 | |||
| 6554 | IMAGES is either a single image specification or a vector of four | ||
| 6555 | image specifications. See enum toolbar_item_images. | ||
| 6556 | |||
| 6557 | - `:help HELP-STRING'. | ||
| 6558 | |||
| 6559 | Gives a help string to display for the toolbar item. */ | ||
| 6560 | |||
| 6561 | static int | ||
| 6562 | parse_toolbar_item (key, item) | ||
| 6563 | Lisp_Object key, item; | ||
| 6564 | { | ||
| 6565 | /* Access slot with index IDX of vector toolbar_item_properties. */ | ||
| 6566 | #define PROP(IDX) XVECTOR (toolbar_item_properties)->contents[IDX] | ||
| 6567 | |||
| 6568 | Lisp_Object filter = Qnil; | ||
| 6569 | Lisp_Object caption; | ||
| 6570 | extern Lisp_Object QCenable, QCvisible, QChelp, QCfilter; | ||
| 6571 | extern Lisp_Object QCbutton, QCtoggle, QCradio; | ||
| 6572 | int i; | ||
| 6573 | struct gcpro gcpro1; | ||
| 6574 | |||
| 6575 | /* Defininition looks like `(toolbar-item CAPTION BINDING | ||
| 6576 | PROPS...)'. Rule out items that aren't lists, don't start with | ||
| 6577 | `toolbar-item' or whose rest following `toolbar-item' is not a | ||
| 6578 | list. */ | ||
| 6579 | if (!CONSP (item) | ||
| 6580 | || !EQ (XCAR (item), Qmenu_item) | ||
| 6581 | || (item = XCDR (item), | ||
| 6582 | !CONSP (item))) | ||
| 6583 | return 0; | ||
| 6584 | |||
| 6585 | /* Create toolbar_item_properties vector if necessary. Reset it to | ||
| 6586 | defaults. */ | ||
| 6587 | if (VECTORP (toolbar_item_properties)) | ||
| 6588 | { | ||
| 6589 | for (i = 0; i < TOOLBAR_ITEM_NSLOTS; ++i) | ||
| 6590 | PROP (i) = Qnil; | ||
| 6591 | } | ||
| 6592 | else | ||
| 6593 | toolbar_item_properties | ||
| 6594 | = Fmake_vector (make_number (TOOLBAR_ITEM_NSLOTS), Qnil); | ||
| 6595 | |||
| 6596 | /* Set defaults. */ | ||
| 6597 | PROP (TOOLBAR_ITEM_KEY) = key; | ||
| 6598 | PROP (TOOLBAR_ITEM_ENABLED_P) = Qt; | ||
| 6599 | |||
| 6600 | /* Get the caption of the item. If the caption is not a string, | ||
| 6601 | evaluate it to get a string. If we don't get a string, skip this | ||
| 6602 | item. */ | ||
| 6603 | caption = XCAR (item); | ||
| 6604 | if (!STRINGP (caption)) | ||
| 6605 | { | ||
| 6606 | caption = menu_item_eval_property (caption); | ||
| 6607 | if (!STRINGP (caption)) | ||
| 6608 | return 0; | ||
| 6609 | } | ||
| 6610 | PROP (TOOLBAR_ITEM_CAPTION) = caption; | ||
| 6611 | |||
| 6612 | /* Give up if rest following the caption is not a list. */ | ||
| 6613 | item = XCDR (item); | ||
| 6614 | if (!CONSP (item)) | ||
| 6615 | return 0; | ||
| 6616 | |||
| 6617 | /* Store the binding. */ | ||
| 6618 | PROP (TOOLBAR_ITEM_BINDING) = XCAR (item); | ||
| 6619 | item = XCDR (item); | ||
| 6620 | |||
| 6621 | /* Process the rest of the properties. */ | ||
| 6622 | for (; CONSP (item) && CONSP (XCDR (item)); item = XCDR (XCDR (item))) | ||
| 6623 | { | ||
| 6624 | Lisp_Object key, value; | ||
| 6625 | |||
| 6626 | key = XCAR (item); | ||
| 6627 | value = XCAR (XCDR (item)); | ||
| 6628 | |||
| 6629 | if (EQ (key, QCenable)) | ||
| 6630 | /* `:enable FORM'. */ | ||
| 6631 | PROP (TOOLBAR_ITEM_ENABLED_P) = value; | ||
| 6632 | else if (EQ (key, QCvisible)) | ||
| 6633 | { | ||
| 6634 | /* `:visible FORM'. If got a visible property and that | ||
| 6635 | evaluates to nil then ignore this item. */ | ||
| 6636 | if (NILP (menu_item_eval_property (value))) | ||
| 6637 | return 0; | ||
| 6638 | } | ||
| 6639 | else if (EQ (key, QChelp)) | ||
| 6640 | /* `:help HELP-STRING'. */ | ||
| 6641 | PROP (TOOLBAR_ITEM_HELP) = value; | ||
| 6642 | else if (EQ (key, QCfilter)) | ||
| 6643 | /* ':filter FORM'. */ | ||
| 6644 | filter = value; | ||
| 6645 | else if (EQ (key, QCbutton) && CONSP (value)) | ||
| 6646 | { | ||
| 6647 | /* `:button (TYPE . SELECTED)'. */ | ||
| 6648 | Lisp_Object type, selected; | ||
| 6649 | |||
| 6650 | type = XCAR (value); | ||
| 6651 | selected = XCDR (value); | ||
| 6652 | if (EQ (type, QCtoggle) || EQ (type, QCradio)) | ||
| 6653 | { | ||
| 6654 | PROP (TOOLBAR_ITEM_SELECTED_P) = selected; | ||
| 6655 | PROP (TOOLBAR_ITEM_TYPE) = type; | ||
| 6656 | } | ||
| 6657 | } | ||
| 6658 | else if (EQ (key, QCimage) | ||
| 6659 | && (CONSP (value) | ||
| 6660 | || (VECTORP (value) && XVECTOR (value)->size == 4))) | ||
| 6661 | /* Value is either a single image specification or a vector | ||
| 6662 | of 4 such specifications for the different buttion states. */ | ||
| 6663 | PROP (TOOLBAR_ITEM_IMAGES) = value; | ||
| 6664 | } | ||
| 6665 | |||
| 6666 | /* If got a filter apply it on binding. */ | ||
| 6667 | if (!NILP (filter)) | ||
| 6668 | PROP (TOOLBAR_ITEM_BINDING) | ||
| 6669 | = menu_item_eval_property (list2 (filter, | ||
| 6670 | list2 (Qquote, | ||
| 6671 | PROP (TOOLBAR_ITEM_BINDING)))); | ||
| 6672 | |||
| 6673 | /* See if the binding is a keymap. Give up if it is. */ | ||
| 6674 | if (!NILP (get_keymap_1 (PROP (TOOLBAR_ITEM_BINDING), 0, 1))) | ||
| 6675 | return 0; | ||
| 6676 | |||
| 6677 | /* Enable or disable selection of item. */ | ||
| 6678 | if (!EQ (PROP (TOOLBAR_ITEM_ENABLED_P), Qt)) | ||
| 6679 | PROP (TOOLBAR_ITEM_ENABLED_P) | ||
| 6680 | = menu_item_eval_property (PROP (TOOLBAR_ITEM_ENABLED_P)); | ||
| 6681 | |||
| 6682 | /* Handle radio buttons or toggle boxes. */ | ||
| 6683 | if (!NILP (PROP (TOOLBAR_ITEM_SELECTED_P))) | ||
| 6684 | PROP (TOOLBAR_ITEM_SELECTED_P) | ||
| 6685 | = menu_item_eval_property (PROP (TOOLBAR_ITEM_SELECTED_P)); | ||
| 6686 | |||
| 6687 | return 1; | ||
| 6688 | |||
| 6689 | #undef PROP | ||
| 6690 | } | ||
| 6691 | |||
| 6692 | |||
| 6693 | /* Initialize Vtoolbar_items. REUSE, if non-nil, is a vector that can | ||
| 6694 | be reused. */ | ||
| 6695 | |||
| 6696 | static void | ||
| 6697 | init_toolbar_items (reuse) | ||
| 6698 | Lisp_Object reuse; | ||
| 6699 | { | ||
| 6700 | if (VECTORP (reuse)) | ||
| 6701 | toolbar_items_vector = reuse; | ||
| 6702 | else | ||
| 6703 | toolbar_items_vector = Fmake_vector (make_number (64), Qnil); | ||
| 6704 | ntoolbar_items = 0; | ||
| 6705 | } | ||
| 6706 | |||
| 6707 | |||
| 6708 | /* Append parsed toolbar item properties from toolbar_item_properties */ | ||
| 6709 | |||
| 6710 | static void | ||
| 6711 | append_toolbar_item () | ||
| 6712 | { | ||
| 6713 | Lisp_Object *to, *from; | ||
| 6714 | |||
| 6715 | /* Enlarge toolbar_items_vector if necessary. */ | ||
| 6716 | if (ntoolbar_items + TOOLBAR_ITEM_NSLOTS | ||
| 6717 | >= XVECTOR (toolbar_items_vector)->size) | ||
| 6718 | { | ||
| 6719 | Lisp_Object new_vector; | ||
| 6720 | int old_size = XVECTOR (toolbar_items_vector)->size; | ||
| 6721 | |||
| 6722 | new_vector = Fmake_vector (make_number (2 * old_size), Qnil); | ||
| 6723 | bcopy (XVECTOR (toolbar_items_vector)->contents, | ||
| 6724 | XVECTOR (new_vector)->contents, | ||
| 6725 | old_size * sizeof (Lisp_Object)); | ||
| 6726 | toolbar_items_vector = new_vector; | ||
| 6727 | } | ||
| 6728 | |||
| 6729 | /* Append entries from toolbar_item_properties to the end of | ||
| 6730 | toolbar_items_vector. */ | ||
| 6731 | to = XVECTOR (toolbar_items_vector)->contents + ntoolbar_items; | ||
| 6732 | from = XVECTOR (toolbar_item_properties)->contents; | ||
| 6733 | bcopy (from, to, TOOLBAR_ITEM_NSLOTS * sizeof *to); | ||
| 6734 | ntoolbar_items += TOOLBAR_ITEM_NSLOTS; | ||
| 6735 | } | ||
| 6736 | |||
| 6737 | |||
| 6738 | |||
| 6739 | |||
| 6209 | 6740 | ||
| 6210 | /* Read a character using menus based on maps in the array MAPS. | 6741 | /* Read a character using menus based on maps in the array MAPS. |
| 6211 | NMAPS is the length of MAPS. Return nil if there are no menus in the maps. | 6742 | NMAPS is the length of MAPS. Return nil if there are no menus in the maps. |
| @@ -6269,7 +6800,8 @@ read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) | |||
| 6269 | /* If we got to this point via a mouse click, | 6800 | /* If we got to this point via a mouse click, |
| 6270 | use a real menu for mouse selection. */ | 6801 | use a real menu for mouse selection. */ |
| 6271 | if (EVENT_HAS_PARAMETERS (prev_event) | 6802 | if (EVENT_HAS_PARAMETERS (prev_event) |
| 6272 | && !EQ (XCONS (prev_event)->car, Qmenu_bar)) | 6803 | && !EQ (XCONS (prev_event)->car, Qmenu_bar) |
| 6804 | && !EQ (XCONS (prev_event)->car, Qtoolbar)) | ||
| 6273 | { | 6805 | { |
| 6274 | /* Display the menu and get the selection. */ | 6806 | /* Display the menu and get the selection. */ |
| 6275 | Lisp_Object *realmaps | 6807 | Lisp_Object *realmaps |
| @@ -7114,6 +7646,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, | |||
| 7114 | 7646 | ||
| 7115 | window = POSN_WINDOW (EVENT_START (key)); | 7647 | window = POSN_WINDOW (EVENT_START (key)); |
| 7116 | posn = POSN_BUFFER_POSN (EVENT_START (key)); | 7648 | posn = POSN_BUFFER_POSN (EVENT_START (key)); |
| 7649 | |||
| 7117 | if (CONSP (posn)) | 7650 | if (CONSP (posn)) |
| 7118 | { | 7651 | { |
| 7119 | /* We're looking at the second event of a | 7652 | /* We're looking at the second event of a |
| @@ -7154,15 +7687,18 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, | |||
| 7154 | orig_local_map = get_local_map (PT, current_buffer); | 7687 | orig_local_map = get_local_map (PT, current_buffer); |
| 7155 | goto replay_sequence; | 7688 | goto replay_sequence; |
| 7156 | } | 7689 | } |
| 7690 | |||
| 7157 | /* For a mouse click, get the local text-property keymap | 7691 | /* For a mouse click, get the local text-property keymap |
| 7158 | of the place clicked on, rather than point. */ | 7692 | of the place clicked on, rather than point. */ |
| 7159 | if (last_real_key_start == 0 && CONSP (XCONS (key)->cdr) | 7693 | if (last_real_key_start == 0 |
| 7694 | && CONSP (XCONS (key)->cdr) | ||
| 7160 | && ! localized_local_map) | 7695 | && ! localized_local_map) |
| 7161 | { | 7696 | { |
| 7162 | Lisp_Object map_here, start, pos; | 7697 | Lisp_Object map_here, start, pos; |
| 7163 | 7698 | ||
| 7164 | localized_local_map = 1; | 7699 | localized_local_map = 1; |
| 7165 | start = EVENT_START (key); | 7700 | start = EVENT_START (key); |
| 7701 | |||
| 7166 | if (CONSP (start) && CONSP (XCONS (start)->cdr)) | 7702 | if (CONSP (start) && CONSP (XCONS (start)->cdr)) |
| 7167 | { | 7703 | { |
| 7168 | pos = POSN_BUFFER_POSN (start); | 7704 | pos = POSN_BUFFER_POSN (start); |
| @@ -7191,11 +7727,33 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, | |||
| 7191 | keybuf[t] = posn; | 7727 | keybuf[t] = posn; |
| 7192 | keybuf[t+1] = key; | 7728 | keybuf[t+1] = key; |
| 7193 | mock_input = t + 2; | 7729 | mock_input = t + 2; |
| 7194 | 7730 | ||
| 7195 | /* Zap the position in key, so we know that we've | 7731 | /* Zap the position in key, so we know that we've |
| 7196 | expanded it, and don't try to do so again. */ | 7732 | expanded it, and don't try to do so again. */ |
| 7197 | POSN_BUFFER_POSN (EVENT_START (key)) | 7733 | POSN_BUFFER_POSN (EVENT_START (key)) |
| 7198 | = Fcons (posn, Qnil); | 7734 | = Fcons (posn, Qnil); |
| 7735 | |||
| 7736 | /* If on a mode line string with a local keymap, | ||
| 7737 | reconsider the key sequence with that keymap. */ | ||
| 7738 | if (CONSP (POSN_STRING (EVENT_START (key)))) | ||
| 7739 | { | ||
| 7740 | Lisp_Object string, pos, map; | ||
| 7741 | |||
| 7742 | string = POSN_STRING (EVENT_START (key)); | ||
| 7743 | pos = XCDR (string); | ||
| 7744 | string = XCAR (string); | ||
| 7745 | |||
| 7746 | if (pos >= 0 | ||
| 7747 | && pos < XSTRING (string)->size | ||
| 7748 | && (map = Fget_text_property (pos, Qlocal_map, | ||
| 7749 | string), | ||
| 7750 | !NILP (map))) | ||
| 7751 | { | ||
| 7752 | orig_local_map = map; | ||
| 7753 | goto replay_sequence; | ||
| 7754 | } | ||
| 7755 | } | ||
| 7756 | |||
| 7199 | goto replay_key; | 7757 | goto replay_key; |
| 7200 | } | 7758 | } |
| 7201 | } | 7759 | } |
| @@ -7208,7 +7766,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, | |||
| 7208 | posn = POSN_BUFFER_POSN (EVENT_START (key)); | 7766 | posn = POSN_BUFFER_POSN (EVENT_START (key)); |
| 7209 | /* Handle menu-bar events: | 7767 | /* Handle menu-bar events: |
| 7210 | insert the dummy prefix event `menu-bar'. */ | 7768 | insert the dummy prefix event `menu-bar'. */ |
| 7211 | if (EQ (posn, Qmenu_bar)) | 7769 | if (EQ (posn, Qmenu_bar) || EQ (posn, Qtoolbar)) |
| 7212 | { | 7770 | { |
| 7213 | if (t + 1 >= bufsize) | 7771 | if (t + 1 >= bufsize) |
| 7214 | error ("Key sequence too long"); | 7772 | error ("Key sequence too long"); |
| @@ -8085,7 +8643,7 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_ | |||
| 8085 | { | 8643 | { |
| 8086 | /* But first wait, and skip the message if there is input. */ | 8644 | /* But first wait, and skip the message if there is input. */ |
| 8087 | int delay_time; | 8645 | int delay_time; |
| 8088 | if (echo_area_glyphs != 0) | 8646 | if (echo_area_glyphs != 0 || STRINGP (echo_area_message)) |
| 8089 | /* This command displayed something in the echo area; | 8647 | /* This command displayed something in the echo area; |
| 8090 | so wait a few seconds, then display our suggestion message. */ | 8648 | so wait a few seconds, then display our suggestion message. */ |
| 8091 | delay_time = (NUMBERP (Vsuggest_key_bindings) | 8649 | delay_time = (NUMBERP (Vsuggest_key_bindings) |
| @@ -8101,6 +8659,7 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_ | |||
| 8101 | Lisp_Object binding; | 8659 | Lisp_Object binding; |
| 8102 | char *newmessage; | 8660 | char *newmessage; |
| 8103 | char *oldmessage = echo_area_glyphs; | 8661 | char *oldmessage = echo_area_glyphs; |
| 8662 | Lisp_Object oldmessage_string = echo_area_message; | ||
| 8104 | int oldmessage_len = echo_area_glyphs_length; | 8663 | int oldmessage_len = echo_area_glyphs_length; |
| 8105 | int oldmultibyte = message_enable_multibyte; | 8664 | int oldmultibyte = message_enable_multibyte; |
| 8106 | 8665 | ||
| @@ -8119,7 +8678,13 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_ | |||
| 8119 | if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings) | 8678 | if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings) |
| 8120 | ? Vsuggest_key_bindings : make_number (2)), | 8679 | ? Vsuggest_key_bindings : make_number (2)), |
| 8121 | Qnil, Qnil))) | 8680 | Qnil, Qnil))) |
| 8122 | message2_nolog (oldmessage, oldmessage_len, oldmultibyte); | 8681 | { |
| 8682 | if (STRINGP (oldmessage_string)) | ||
| 8683 | message3_nolog (oldmessage_string, oldmessage_len, | ||
| 8684 | oldmultibyte); | ||
| 8685 | else | ||
| 8686 | message2_nolog (oldmessage, oldmessage_len, oldmultibyte); | ||
| 8687 | } | ||
| 8123 | } | 8688 | } |
| 8124 | } | 8689 | } |
| 8125 | 8690 | ||
| @@ -8190,7 +8755,16 @@ detect_input_pending_run_timers (do_display) | |||
| 8190 | get_input_pending (&input_pending, 1); | 8755 | get_input_pending (&input_pending, 1); |
| 8191 | 8756 | ||
| 8192 | if (old_timers_run != timers_run && do_display) | 8757 | if (old_timers_run != timers_run && do_display) |
| 8193 | redisplay_preserve_echo_area (); | 8758 | { |
| 8759 | redisplay_preserve_echo_area (); | ||
| 8760 | /* The following fixes a bug when using lazy-lock with | ||
| 8761 | lazy-lock-defer-on-the-fly set to t, i.e. when fontifying | ||
| 8762 | from an idle timer function. The symptom of the bug is that | ||
| 8763 | the cursor sometimes doesn't become visible until the next X | ||
| 8764 | event is processed. --gerd. */ | ||
| 8765 | if (rif) | ||
| 8766 | rif->flush_display (NULL); | ||
| 8767 | } | ||
| 8194 | 8768 | ||
| 8195 | return input_pending; | 8769 | return input_pending; |
| 8196 | } | 8770 | } |
| @@ -8369,10 +8943,7 @@ Also cancel any kbd macro being defined.") | |||
| 8369 | 8943 | ||
| 8370 | discard_tty_input (); | 8944 | discard_tty_input (); |
| 8371 | 8945 | ||
| 8372 | /* Without the cast, GCC complains that this assignment loses the | 8946 | kbd_fetch_ptr = kbd_store_ptr; |
| 8373 | volatile qualifier of kbd_store_ptr. Is there anything wrong | ||
| 8374 | with that? */ | ||
| 8375 | kbd_fetch_ptr = (struct input_event *) kbd_store_ptr; | ||
| 8376 | Ffillarray (kbd_buffer_frame_or_window, Qnil); | 8947 | Ffillarray (kbd_buffer_frame_or_window, Qnil); |
| 8377 | input_pending = 0; | 8948 | input_pending = 0; |
| 8378 | 8949 | ||
| @@ -8658,7 +9229,6 @@ interrupt_signal (signalnum) /* If we don't have an argument, */ | |||
| 8658 | void | 9229 | void |
| 8659 | quit_throw_to_read_char () | 9230 | quit_throw_to_read_char () |
| 8660 | { | 9231 | { |
| 8661 | quit_error_check (); | ||
| 8662 | sigfree (); | 9232 | sigfree (); |
| 8663 | /* Prevent another signal from doing this before we finish. */ | 9233 | /* Prevent another signal from doing this before we finish. */ |
| 8664 | clear_waiting_for_input (); | 9234 | clear_waiting_for_input (); |
| @@ -8936,9 +9506,21 @@ struct event_head head_table[] = { | |||
| 8936 | void | 9506 | void |
| 8937 | syms_of_keyboard () | 9507 | syms_of_keyboard () |
| 8938 | { | 9508 | { |
| 9509 | /* Toolbars. */ | ||
| 9510 | QCimage = intern (":image"); | ||
| 9511 | staticpro (&QCimage); | ||
| 9512 | |||
| 9513 | staticpro (&Qhelp_echo); | ||
| 9514 | Qhelp_echo = intern ("help-echo"); | ||
| 9515 | |||
| 8939 | staticpro (&item_properties); | 9516 | staticpro (&item_properties); |
| 8940 | item_properties = Qnil; | 9517 | item_properties = Qnil; |
| 8941 | 9518 | ||
| 9519 | staticpro (&toolbar_item_properties); | ||
| 9520 | toolbar_item_properties = Qnil; | ||
| 9521 | staticpro (&toolbar_items_vector); | ||
| 9522 | toolbar_items_vector = Qnil; | ||
| 9523 | |||
| 8942 | staticpro (&real_this_command); | 9524 | staticpro (&real_this_command); |
| 8943 | real_this_command = Qnil; | 9525 | real_this_command = Qnil; |
| 8944 | 9526 | ||
| @@ -9004,6 +9586,8 @@ syms_of_keyboard () | |||
| 9004 | staticpro (&QCenable); | 9586 | staticpro (&QCenable); |
| 9005 | QCvisible = intern (":visible"); | 9587 | QCvisible = intern (":visible"); |
| 9006 | staticpro (&QCvisible); | 9588 | staticpro (&QCvisible); |
| 9589 | QChelp = intern (":help"); | ||
| 9590 | staticpro (&QChelp); | ||
| 9007 | QCfilter = intern (":filter"); | 9591 | QCfilter = intern (":filter"); |
| 9008 | staticpro (&QCfilter); | 9592 | staticpro (&QCfilter); |
| 9009 | QCbutton = intern (":button"); | 9593 | QCbutton = intern (":button"); |
| @@ -9036,6 +9620,12 @@ syms_of_keyboard () | |||
| 9036 | staticpro (&Qup); | 9620 | staticpro (&Qup); |
| 9037 | Qdown = intern ("down"); | 9621 | Qdown = intern ("down"); |
| 9038 | staticpro (&Qdown); | 9622 | staticpro (&Qdown); |
| 9623 | Qtop = intern ("top"); | ||
| 9624 | staticpro (&Qtop); | ||
| 9625 | Qbottom = intern ("bottom"); | ||
| 9626 | staticpro (&Qbottom); | ||
| 9627 | Qend_scroll = intern ("end-scroll"); | ||
| 9628 | staticpro (&Qend_scroll); | ||
| 9039 | 9629 | ||
| 9040 | Qevent_kind = intern ("event-kind"); | 9630 | Qevent_kind = intern ("event-kind"); |
| 9041 | staticpro (&Qevent_kind); | 9631 | staticpro (&Qevent_kind); |
| @@ -9493,6 +10083,11 @@ for guidance on what to do."); | |||
| 9493 | This variable exists because `read-event' clears the echo area\n\ | 10083 | This variable exists because `read-event' clears the echo area\n\ |
| 9494 | before running the input method. It is nil if there was no message."); | 10084 | before running the input method. It is nil if there was no message."); |
| 9495 | Vinput_method_previous_message = Qnil; | 10085 | Vinput_method_previous_message = Qnil; |
| 10086 | |||
| 10087 | DEFVAR_LISP ("show-help-function", &Vshow_help_function, | ||
| 10088 | "If non-nil, the function that implements the display of help.\n\ | ||
| 10089 | It's called with one argument, the help string to display."); | ||
| 10090 | Vshow_help_function = Qnil; | ||
| 9496 | } | 10091 | } |
| 9497 | 10092 | ||
| 9498 | void | 10093 | void |