Mercurial > hg > xemacs-beta
comparison src/event-stream.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 7d59cb494b73 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
79 #include "frame.h" | 79 #include "frame.h" |
80 #include "insdel.h" /* for buffer_reset_changes */ | 80 #include "insdel.h" /* for buffer_reset_changes */ |
81 #include "keymap.h" | 81 #include "keymap.h" |
82 #include "lstream.h" | 82 #include "lstream.h" |
83 #include "macros.h" /* for defining_keyboard_macro */ | 83 #include "macros.h" /* for defining_keyboard_macro */ |
84 #include "opaque.h" | |
85 #include "process.h" | 84 #include "process.h" |
86 #include "window.h" | 85 #include "window.h" |
87 | 86 |
88 #include "sysdep.h" /* init_poll_for_quit() */ | 87 #include "sysdep.h" /* init_poll_for_quit() */ |
89 #include "syssignal.h" /* SIGCHLD, etc. */ | 88 #include "syssignal.h" /* SIGCHLD, etc. */ |
99 | 98 |
100 /* The number of keystrokes between auto-saves. */ | 99 /* The number of keystrokes between auto-saves. */ |
101 static int auto_save_interval; | 100 static int auto_save_interval; |
102 | 101 |
103 Lisp_Object Qundefined_keystroke_sequence; | 102 Lisp_Object Qundefined_keystroke_sequence; |
104 | |
105 Lisp_Object Qcommand_execute; | |
106 | 103 |
107 Lisp_Object Qcommand_event_p; | 104 Lisp_Object Qcommand_event_p; |
108 | 105 |
109 /* Hooks to run before and after each command. */ | 106 /* Hooks to run before and after each command. */ |
110 Lisp_Object Vpre_command_hook, Vpost_command_hook; | 107 Lisp_Object Vpre_command_hook, Vpost_command_hook; |
259 Lisp_Object Qmenu_down; | 256 Lisp_Object Qmenu_down; |
260 Lisp_Object Qmenu_left; | 257 Lisp_Object Qmenu_left; |
261 Lisp_Object Qmenu_right; | 258 Lisp_Object Qmenu_right; |
262 Lisp_Object Qmenu_select; | 259 Lisp_Object Qmenu_select; |
263 Lisp_Object Qmenu_escape; | 260 Lisp_Object Qmenu_escape; |
261 | |
262 Lisp_Object Qself_insert_defer_undo; | |
264 | 263 |
265 /* this is in keymap.c */ | 264 /* this is in keymap.c */ |
266 extern Lisp_Object Fmake_keymap (Lisp_Object name); | 265 extern Lisp_Object Fmake_keymap (Lisp_Object name); |
267 | 266 |
268 #ifdef DEBUG_XEMACS | 267 #ifdef DEBUG_XEMACS |
383 | 382 |
384 #define XCOMMAND_BUILDER(x) \ | 383 #define XCOMMAND_BUILDER(x) \ |
385 XRECORD (x, command_builder, struct command_builder) | 384 XRECORD (x, command_builder, struct command_builder) |
386 #define XSETCOMMAND_BUILDER(x, p) XSETRECORD (x, p, command_builder) | 385 #define XSETCOMMAND_BUILDER(x, p) XSETRECORD (x, p, command_builder) |
387 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) | 386 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) |
388 #define GC_COMMAND_BUILDERP(x) GC_RECORDP (x, command_builder) | |
389 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) | 387 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) |
390 | 388 |
391 static Lisp_Object | 389 static Lisp_Object |
392 mark_command_builder (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 390 mark_command_builder (Lisp_Object obj) |
393 { | 391 { |
394 struct command_builder *builder = XCOMMAND_BUILDER (obj); | 392 struct command_builder *builder = XCOMMAND_BUILDER (obj); |
395 markobj (builder->prefix_events); | 393 mark_object (builder->prefix_events); |
396 markobj (builder->current_events); | 394 mark_object (builder->current_events); |
397 markobj (builder->most_current_event); | 395 mark_object (builder->most_current_event); |
398 markobj (builder->last_non_munged_event); | 396 mark_object (builder->last_non_munged_event); |
399 markobj (builder->munge_me[0].first_mungeable_event); | 397 mark_object (builder->munge_me[0].first_mungeable_event); |
400 markobj (builder->munge_me[1].first_mungeable_event); | 398 mark_object (builder->munge_me[1].first_mungeable_event); |
401 return builder->console; | 399 return builder->console; |
402 } | 400 } |
403 | 401 |
404 static void | 402 static void |
405 finalize_command_builder (void *header, int for_disksave) | 403 finalize_command_builder (void *header, int for_disksave) |
411 } | 409 } |
412 } | 410 } |
413 | 411 |
414 DEFINE_LRECORD_IMPLEMENTATION ("command-builder", command_builder, | 412 DEFINE_LRECORD_IMPLEMENTATION ("command-builder", command_builder, |
415 mark_command_builder, internal_object_printer, | 413 mark_command_builder, internal_object_printer, |
416 finalize_command_builder, 0, 0, | 414 finalize_command_builder, 0, 0, 0, |
417 struct command_builder); | 415 struct command_builder); |
418 | 416 |
419 static void | 417 static void |
420 reset_command_builder_event_chain (struct command_builder *builder) | 418 reset_command_builder_event_chain (struct command_builder *builder) |
421 { | 419 { |
430 Lisp_Object | 428 Lisp_Object |
431 allocate_command_builder (Lisp_Object console) | 429 allocate_command_builder (Lisp_Object console) |
432 { | 430 { |
433 Lisp_Object builder_obj; | 431 Lisp_Object builder_obj; |
434 struct command_builder *builder = | 432 struct command_builder *builder = |
435 alloc_lcrecord_type (struct command_builder, lrecord_command_builder); | 433 alloc_lcrecord_type (struct command_builder, &lrecord_command_builder); |
436 | 434 |
437 builder->console = console; | 435 builder->console = console; |
438 reset_command_builder_event_chain (builder); | 436 reset_command_builder_event_chain (builder); |
439 builder->echo_buf_length = 300; /* #### Kludge */ | 437 builder->echo_buf_length = 300; /* #### Kludge */ |
440 builder->echo_buf = xnew_array (Bufbyte, builder->echo_buf_length); | 438 builder->echo_buf = xnew_array (Bufbyte, builder->echo_buf_length); |
508 { | 506 { |
509 return event_stream && event_stream->event_pending_p (user); | 507 return event_stream && event_stream->event_pending_p (user); |
510 } | 508 } |
511 | 509 |
512 static int | 510 static int |
513 maybe_read_quit_event (struct Lisp_Event *event) | 511 maybe_read_quit_event (Lisp_Event *event) |
514 { | 512 { |
515 /* A C-g that came from `sigint_happened' will always come from the | 513 /* A C-g that came from `sigint_happened' will always come from the |
516 controlling terminal. If that doesn't exist, however, then the | 514 controlling terminal. If that doesn't exist, however, then the |
517 user manually sent us a SIGINT, and we pretend the C-g came from | 515 user manually sent us a SIGINT, and we pretend the C-g came from |
518 the selected console. */ | 516 the selected console. */ |
535 } | 533 } |
536 return 0; | 534 return 0; |
537 } | 535 } |
538 | 536 |
539 void | 537 void |
540 event_stream_next_event (struct Lisp_Event *event) | 538 event_stream_next_event (Lisp_Event *event) |
541 { | 539 { |
542 Lisp_Object event_obj; | 540 Lisp_Object event_obj; |
543 | 541 |
544 check_event_stream_ok (EVENT_STREAM_READ); | 542 check_event_stream_ok (EVENT_STREAM_READ); |
545 | 543 |
579 #endif | 577 #endif |
580 maybe_kbd_translate (event_obj); | 578 maybe_kbd_translate (event_obj); |
581 } | 579 } |
582 | 580 |
583 void | 581 void |
584 event_stream_handle_magic_event (struct Lisp_Event *event) | 582 event_stream_handle_magic_event (Lisp_Event *event) |
585 { | 583 { |
586 check_event_stream_ok (EVENT_STREAM_READ); | 584 check_event_stream_ok (EVENT_STREAM_READ); |
587 event_stream->handle_magic_event_cb (event); | 585 event_stream->handle_magic_event_cb (event); |
588 } | 586 } |
589 | 587 |
622 con->input_enabled = 0; | 620 con->input_enabled = 0; |
623 } | 621 } |
624 } | 622 } |
625 | 623 |
626 void | 624 void |
627 event_stream_select_process (struct Lisp_Process *proc) | 625 event_stream_select_process (Lisp_Process *proc) |
628 { | 626 { |
629 check_event_stream_ok (EVENT_STREAM_PROCESS); | 627 check_event_stream_ok (EVENT_STREAM_PROCESS); |
630 if (!get_process_selected_p (proc)) | 628 if (!get_process_selected_p (proc)) |
631 { | 629 { |
632 event_stream->select_process_cb (proc); | 630 event_stream->select_process_cb (proc); |
633 set_process_selected_p (proc, 1); | 631 set_process_selected_p (proc, 1); |
634 } | 632 } |
635 } | 633 } |
636 | 634 |
637 void | 635 void |
638 event_stream_unselect_process (struct Lisp_Process *proc) | 636 event_stream_unselect_process (Lisp_Process *proc) |
639 { | 637 { |
640 check_event_stream_ok (EVENT_STREAM_PROCESS); | 638 check_event_stream_ok (EVENT_STREAM_PROCESS); |
641 if (get_process_selected_p (proc)) | 639 if (get_process_selected_p (proc)) |
642 { | 640 { |
643 event_stream->unselect_process_cb (proc); | 641 event_stream->unselect_process_cb (proc); |
797 XEVENT (event)->event.key.modifiers = 0; | 795 XEVENT (event)->event.key.modifiers = 0; |
798 did_translate = 1; | 796 did_translate = 1; |
799 } | 797 } |
800 else if (CHARP (traduit)) | 798 else if (CHARP (traduit)) |
801 { | 799 { |
802 struct Lisp_Event ev2; | 800 Lisp_Event ev2; |
803 | 801 |
804 /* This used to call Fcharacter_to_event() directly into EVENT, | 802 /* This used to call Fcharacter_to_event() directly into EVENT, |
805 but that can eradicate timestamps and other such stuff. | 803 but that can eradicate timestamps and other such stuff. |
806 This way is safer. */ | 804 This way is safer. */ |
807 zero_event (&ev2); | 805 zero_event (&ev2); |
983 | 981 |
984 /* We ensure that 0 is never a valid ID, so that a value of 0 can be | 982 /* We ensure that 0 is never a valid ID, so that a value of 0 can be |
985 used to indicate an absence of a timer. */ | 983 used to indicate an absence of a timer. */ |
986 static int low_level_timeout_id_tick; | 984 static int low_level_timeout_id_tick; |
987 | 985 |
988 struct low_level_timeout_blocktype | 986 static struct low_level_timeout_blocktype |
989 { | 987 { |
990 Blocktype_declare (struct low_level_timeout); | 988 Blocktype_declare (struct low_level_timeout); |
991 } *the_low_level_timeout_blocktype; | 989 } *the_low_level_timeout_blocktype; |
992 | 990 |
993 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return | 991 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return |
1099 | 1097 |
1100 /**** High-level timeout functions. ****/ | 1098 /**** High-level timeout functions. ****/ |
1101 | 1099 |
1102 static int timeout_id_tick; | 1100 static int timeout_id_tick; |
1103 | 1101 |
1104 /* Since timeout structures contain Lisp_Objects, they need to be GC'd | 1102 static Lisp_Object pending_timeout_list, pending_async_timeout_list; |
1105 properly. The opaque data type provides a convenient way of doing | 1103 |
1106 this without having to create a new Lisp object, since we can | 1104 static Lisp_Object Vtimeout_free_list; |
1107 provide our own mark function. */ | 1105 |
1108 | 1106 static Lisp_Object |
1109 struct timeout | 1107 mark_timeout (Lisp_Object obj) |
1110 { | 1108 { |
1111 int id; /* Id we use to identify the timeout over its lifetime */ | 1109 Lisp_Timeout *tm = XTIMEOUT (obj); |
1112 int interval_id; /* Id for this particular interval; this may | 1110 mark_object (tm->function); |
1113 be different each time the timeout is | 1111 return tm->object; |
1114 signalled.*/ | 1112 } |
1115 Lisp_Object function, object; /* Function and object associated | 1113 |
1116 with timeout. */ | 1114 /* Should never, ever be called. (except by an external debugger) */ |
1117 EMACS_TIME next_signal_time; /* Absolute time when the timeout | 1115 static void |
1118 is next going to be signalled. */ | 1116 print_timeout (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
1119 unsigned int resignal_msecs; /* How far after the next timeout | 1117 { |
1120 should the one after that | 1118 const Lisp_Timeout *t = XTIMEOUT (obj); |
1121 occur? */ | 1119 char buf[64]; |
1120 | |
1121 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (timeout) 0x%lx>", | |
1122 (unsigned long) t); | |
1123 write_c_string (buf, printcharfun); | |
1124 } | |
1125 | |
1126 static const struct lrecord_description timeout_description[] = { | |
1127 { XD_LISP_OBJECT, offsetof (Lisp_Timeout, function) }, | |
1128 { XD_LISP_OBJECT, offsetof (Lisp_Timeout, object) }, | |
1129 { XD_END } | |
1122 }; | 1130 }; |
1123 | 1131 |
1124 static Lisp_Object pending_timeout_list, pending_async_timeout_list; | 1132 DEFINE_LRECORD_IMPLEMENTATION ("timeout", timeout, |
1125 | 1133 mark_timeout, print_timeout, |
1126 static Lisp_Object Vtimeout_free_list; | 1134 0, 0, 0, timeout_description, Lisp_Timeout); |
1127 | |
1128 static Lisp_Object | |
1129 mark_timeout (Lisp_Object obj, void (*markobj) (Lisp_Object)) | |
1130 { | |
1131 struct timeout *tm = (struct timeout *) XOPAQUE_DATA (obj); | |
1132 markobj (tm->function); | |
1133 return tm->object; | |
1134 } | |
1135 | 1135 |
1136 /* Generate a timeout and return its ID. */ | 1136 /* Generate a timeout and return its ID. */ |
1137 | 1137 |
1138 int | 1138 int |
1139 event_stream_generate_wakeup (unsigned int milliseconds, | 1139 event_stream_generate_wakeup (unsigned int milliseconds, |
1140 unsigned int vanilliseconds, | 1140 unsigned int vanilliseconds, |
1141 Lisp_Object function, Lisp_Object object, | 1141 Lisp_Object function, Lisp_Object object, |
1142 int async_p) | 1142 int async_p) |
1143 { | 1143 { |
1144 Lisp_Object op = allocate_managed_opaque (Vtimeout_free_list, 0); | 1144 Lisp_Object op = allocate_managed_lcrecord (Vtimeout_free_list); |
1145 struct timeout *timeout = (struct timeout *) XOPAQUE_DATA (op); | 1145 Lisp_Timeout *timeout = XTIMEOUT (op); |
1146 EMACS_TIME current_time; | 1146 EMACS_TIME current_time; |
1147 EMACS_TIME interval; | 1147 EMACS_TIME interval; |
1148 | 1148 |
1149 timeout->id = timeout_id_tick++; | 1149 timeout->id = timeout_id_tick++; |
1150 timeout->resignal_msecs = vanilliseconds; | 1150 timeout->resignal_msecs = vanilliseconds; |
1189 static int | 1189 static int |
1190 event_stream_resignal_wakeup (int interval_id, int async_p, | 1190 event_stream_resignal_wakeup (int interval_id, int async_p, |
1191 Lisp_Object *function, Lisp_Object *object) | 1191 Lisp_Object *function, Lisp_Object *object) |
1192 { | 1192 { |
1193 Lisp_Object op = Qnil, rest; | 1193 Lisp_Object op = Qnil, rest; |
1194 struct timeout *timeout; | 1194 Lisp_Timeout *timeout; |
1195 Lisp_Object *timeout_list; | 1195 Lisp_Object *timeout_list; |
1196 struct gcpro gcpro1; | 1196 struct gcpro gcpro1; |
1197 int id; | 1197 int id; |
1198 | 1198 |
1199 GCPRO1 (op); /* just in case ... because it's removed from the list | 1199 GCPRO1 (op); /* just in case ... because it's removed from the list |
1202 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; | 1202 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; |
1203 | 1203 |
1204 /* Find the timeout on the list of pending ones. */ | 1204 /* Find the timeout on the list of pending ones. */ |
1205 LIST_LOOP (rest, *timeout_list) | 1205 LIST_LOOP (rest, *timeout_list) |
1206 { | 1206 { |
1207 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | 1207 timeout = XTIMEOUT (XCAR (rest)); |
1208 if (timeout->interval_id == interval_id) | 1208 if (timeout->interval_id == interval_id) |
1209 break; | 1209 break; |
1210 } | 1210 } |
1211 | 1211 |
1212 assert (!NILP (rest)); | 1212 assert (!NILP (rest)); |
1213 op = XCAR (rest); | 1213 op = XCAR (rest); |
1214 timeout = (struct timeout *) XOPAQUE_DATA (op); | 1214 timeout = XTIMEOUT (op); |
1215 /* We make sure to snarf the data out of the timeout object before | 1215 /* We make sure to snarf the data out of the timeout object before |
1216 we free it with free_managed_opaque(). */ | 1216 we free it with free_managed_lcrecord(). */ |
1217 id = timeout->id; | 1217 id = timeout->id; |
1218 *function = timeout->function; | 1218 *function = timeout->function; |
1219 *object = timeout->object; | 1219 *object = timeout->object; |
1220 | 1220 |
1221 /* Remove this one from the list of pending timeouts */ | 1221 /* Remove this one from the list of pending timeouts */ |
1253 is to move frequently-hit timeouts to the front of the | 1253 is to move frequently-hit timeouts to the front of the |
1254 list, which is a good thing. */ | 1254 list, which is a good thing. */ |
1255 *timeout_list = noseeum_cons (op, *timeout_list); | 1255 *timeout_list = noseeum_cons (op, *timeout_list); |
1256 } | 1256 } |
1257 else | 1257 else |
1258 free_managed_opaque (Vtimeout_free_list, op); | 1258 free_managed_lcrecord (Vtimeout_free_list, op); |
1259 | 1259 |
1260 UNGCPRO; | 1260 UNGCPRO; |
1261 return id; | 1261 return id; |
1262 } | 1262 } |
1263 | 1263 |
1264 void | 1264 void |
1265 event_stream_disable_wakeup (int id, int async_p) | 1265 event_stream_disable_wakeup (int id, int async_p) |
1266 { | 1266 { |
1267 struct timeout *timeout = 0; | 1267 Lisp_Timeout *timeout = 0; |
1268 Lisp_Object rest; | 1268 Lisp_Object rest; |
1269 Lisp_Object *timeout_list; | 1269 Lisp_Object *timeout_list; |
1270 | 1270 |
1271 if (async_p) | 1271 if (async_p) |
1272 timeout_list = &pending_async_timeout_list; | 1272 timeout_list = &pending_async_timeout_list; |
1274 timeout_list = &pending_timeout_list; | 1274 timeout_list = &pending_timeout_list; |
1275 | 1275 |
1276 /* Find the timeout on the list of pending ones, if it's still there. */ | 1276 /* Find the timeout on the list of pending ones, if it's still there. */ |
1277 LIST_LOOP (rest, *timeout_list) | 1277 LIST_LOOP (rest, *timeout_list) |
1278 { | 1278 { |
1279 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | 1279 timeout = XTIMEOUT (XCAR (rest)); |
1280 if (timeout->id == id) | 1280 if (timeout->id == id) |
1281 break; | 1281 break; |
1282 } | 1282 } |
1283 | 1283 |
1284 /* If we found it, remove it from the list and disable the pending | 1284 /* If we found it, remove it from the list and disable the pending |
1290 delq_no_quit_and_free_cons (op, *timeout_list); | 1290 delq_no_quit_and_free_cons (op, *timeout_list); |
1291 if (async_p) | 1291 if (async_p) |
1292 event_stream_remove_async_timeout (timeout->interval_id); | 1292 event_stream_remove_async_timeout (timeout->interval_id); |
1293 else | 1293 else |
1294 event_stream_remove_timeout (timeout->interval_id); | 1294 event_stream_remove_timeout (timeout->interval_id); |
1295 free_managed_opaque (Vtimeout_free_list, op); | 1295 free_managed_lcrecord (Vtimeout_free_list, op); |
1296 } | 1296 } |
1297 } | 1297 } |
1298 | 1298 |
1299 static int | 1299 static int |
1300 event_stream_wakeup_pending_p (int id, int async_p) | 1300 event_stream_wakeup_pending_p (int id, int async_p) |
1301 { | 1301 { |
1302 struct timeout *timeout; | 1302 Lisp_Timeout *timeout; |
1303 Lisp_Object rest; | 1303 Lisp_Object rest; |
1304 Lisp_Object timeout_list; | 1304 Lisp_Object timeout_list; |
1305 int found = 0; | 1305 int found = 0; |
1306 | 1306 |
1307 | 1307 |
1311 timeout_list = pending_timeout_list; | 1311 timeout_list = pending_timeout_list; |
1312 | 1312 |
1313 /* Find the element on the list of pending ones, if it's still there. */ | 1313 /* Find the element on the list of pending ones, if it's still there. */ |
1314 LIST_LOOP (rest, timeout_list) | 1314 LIST_LOOP (rest, timeout_list) |
1315 { | 1315 { |
1316 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | 1316 timeout = XTIMEOUT (XCAR (rest)); |
1317 if (timeout->id == id) | 1317 if (timeout->id == id) |
1318 { | 1318 { |
1319 found = 1; | 1319 found = 1; |
1320 break; | 1320 break; |
1321 } | 1321 } |
2014 Fdeallocate_event (event); | 2014 Fdeallocate_event (event); |
2015 DEBUG_PRINT_EMACS_EVENT ("command event queue", target_event); | 2015 DEBUG_PRINT_EMACS_EVENT ("command event queue", target_event); |
2016 } | 2016 } |
2017 else | 2017 else |
2018 { | 2018 { |
2019 struct Lisp_Event *e = XEVENT (target_event); | 2019 Lisp_Event *e = XEVENT (target_event); |
2020 | 2020 |
2021 /* The command_event_queue was empty. Wait for an event. */ | 2021 /* The command_event_queue was empty. Wait for an event. */ |
2022 event_stream_next_event (e); | 2022 event_stream_next_event (e); |
2023 /* If this was a timeout, then we need to extract some data | 2023 /* If this was a timeout, then we need to extract some data |
2024 out of the returned closure and might need to resignal | 2024 out of the returned closure and might need to resignal |
3036 return; | 3036 return; |
3037 } | 3037 } |
3038 | 3038 |
3039 case timeout_event: | 3039 case timeout_event: |
3040 { | 3040 { |
3041 struct Lisp_Event *e = XEVENT (event); | 3041 Lisp_Event *e = XEVENT (event); |
3042 if (!NILP (e->event.timeout.function)) | 3042 if (!NILP (e->event.timeout.function)) |
3043 call1 (e->event.timeout.function, | 3043 call1 (e->event.timeout.function, |
3044 e->event.timeout.object); | 3044 e->event.timeout.object); |
3045 return; | 3045 return; |
3046 } | 3046 } |
3098 | 3098 |
3099 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) | 3099 #if defined(HAVE_X_WINDOWS) && defined(LWLIB_MENUBARS_LUCID) |
3100 static void | 3100 static void |
3101 menu_move_up (void) | 3101 menu_move_up (void) |
3102 { | 3102 { |
3103 widget_value *current, *prev; | 3103 widget_value *current = lw_get_entries (False); |
3104 widget_value *entries; | 3104 widget_value *entries = lw_get_entries (True); |
3105 | 3105 widget_value *prev = NULL; |
3106 current = lw_get_entries (False); | 3106 |
3107 entries = lw_get_entries (True); | 3107 while (entries != current) |
3108 prev = NULL; | 3108 { |
3109 if (current != entries) | 3109 if (entries->name /*&& entries->enabled*/) prev = entries; |
3110 { | 3110 entries = entries->next; |
3111 while (entries != current) | 3111 assert (entries); |
3112 { | |
3113 if (entries->name /*&& entries->enabled*/) prev = entries; | |
3114 entries = entries->next; | |
3115 assert (entries); | |
3116 } | |
3117 } | 3112 } |
3118 | 3113 |
3119 if (!prev) | 3114 if (!prev) |
3120 /* move to last item */ | 3115 /* move to last item */ |
3121 { | 3116 { |
3140 } | 3135 } |
3141 | 3136 |
3142 static void | 3137 static void |
3143 menu_move_down (void) | 3138 menu_move_down (void) |
3144 { | 3139 { |
3145 widget_value *current; | 3140 widget_value *current = lw_get_entries (False); |
3146 widget_value *new; | 3141 widget_value *new = current; |
3147 | |
3148 current = lw_get_entries (False); | |
3149 new = current; | |
3150 | 3142 |
3151 while (new->next) | 3143 while (new->next) |
3152 { | 3144 { |
3153 new = new->next; | 3145 new = new->next; |
3154 if (new->name /*&& new->enabled*/) break; | 3146 if (new->name /*&& new->enabled*/) break; |
3177 { | 3169 { |
3178 int level = lw_menu_level (); | 3170 int level = lw_menu_level (); |
3179 int l = level; | 3171 int l = level; |
3180 widget_value *current; | 3172 widget_value *current; |
3181 | 3173 |
3182 while (level >= 3) | 3174 while (level-- >= 3) |
3183 { | 3175 lw_pop_menu (); |
3184 --level; | 3176 |
3185 lw_pop_menu (); | |
3186 } | |
3187 menu_move_up (); | 3177 menu_move_up (); |
3188 current = lw_get_entries (False); | 3178 current = lw_get_entries (False); |
3189 if (l > 2 && current->contents) | 3179 if (l > 2 && current->contents) |
3190 lw_push_menu (current->contents); | 3180 lw_push_menu (current->contents); |
3191 } | 3181 } |
3195 { | 3185 { |
3196 int level = lw_menu_level (); | 3186 int level = lw_menu_level (); |
3197 int l = level; | 3187 int l = level; |
3198 widget_value *current; | 3188 widget_value *current; |
3199 | 3189 |
3200 while (level >= 3) | 3190 while (level-- >= 3) |
3201 { | 3191 lw_pop_menu (); |
3202 --level; | 3192 |
3203 lw_pop_menu (); | |
3204 } | |
3205 menu_move_down (); | 3193 menu_move_down (); |
3206 current = lw_get_entries (False); | 3194 current = lw_get_entries (False); |
3207 if (l > 2 && current->contents) | 3195 if (l > 2 && current->contents) |
3208 lw_push_menu (current->contents); | 3196 lw_push_menu (current->contents); |
3209 } | 3197 } |
3422 (with-output-to-string (display-error errordata)) | 3410 (with-output-to-string (display-error errordata)) |
3423 but that stuff is all in Lisp currently. */ | 3411 but that stuff is all in Lisp currently. */ |
3424 args[1] = errordata; | 3412 args[1] = errordata; |
3425 warn_when_safe_lispobj | 3413 warn_when_safe_lispobj |
3426 (Qerror, Qwarning, | 3414 (Qerror, Qwarning, |
3427 emacs_doprnt_string_lisp ((CONST Bufbyte *) "%s: %s", | 3415 emacs_doprnt_string_lisp ((const Bufbyte *) "%s: %s", |
3428 Qnil, -1, 2, args)); | 3416 Qnil, -1, 2, args)); |
3429 } | 3417 } |
3430 | 3418 |
3431 return Qnil; | 3419 return Qnil; |
3432 } | 3420 } |
3780 Emchar c = 0; | 3768 Emchar c = 0; |
3781 if ((key->modifiers & MOD_SHIFT) | 3769 if ((key->modifiers & MOD_SHIFT) |
3782 || (CHAR_OR_CHAR_INTP (key->keysym) | 3770 || (CHAR_OR_CHAR_INTP (key->keysym) |
3783 && ((c = XCHAR_OR_CHAR_INT (key->keysym)), c >= 'A' && c <= 'Z'))) | 3771 && ((c = XCHAR_OR_CHAR_INT (key->keysym)), c >= 'A' && c <= 'Z'))) |
3784 { | 3772 { |
3785 struct Lisp_Event terminal_copy = *XEVENT (terminal); | 3773 Lisp_Event terminal_copy = *XEVENT (terminal); |
3786 | 3774 |
3787 if (key->modifiers & MOD_SHIFT) | 3775 if (key->modifiers & MOD_SHIFT) |
3788 key->modifiers &= (~ MOD_SHIFT); | 3776 key->modifiers &= (~ MOD_SHIFT); |
3789 else | 3777 else |
3790 key->keysym = make_char (c + 'a' - 'A'); | 3778 key->keysym = make_char (c + 'a' - 'A'); |
4173 Lisp_Object recent = command_builder->most_current_event; | 4161 Lisp_Object recent = command_builder->most_current_event; |
4174 | 4162 |
4175 if (EVENTP (recent) | 4163 if (EVENTP (recent) |
4176 && event_matches_key_specifier_p (XEVENT (recent), Vmeta_prefix_char)) | 4164 && event_matches_key_specifier_p (XEVENT (recent), Vmeta_prefix_char)) |
4177 { | 4165 { |
4178 struct Lisp_Event *e; | 4166 Lisp_Event *e; |
4179 /* When we see a sequence like "ESC x", pretend we really saw "M-x". | 4167 /* When we see a sequence like "ESC x", pretend we really saw "M-x". |
4180 DoubleThink the recent-keys and this-command-keys as well. */ | 4168 DoubleThink the recent-keys and this-command-keys as well. */ |
4181 | 4169 |
4182 /* Modify the previous most-recently-pushed event on the command | 4170 /* Modify the previous most-recently-pushed event on the command |
4183 builder to be a copy of this one with the meta-bit set instead of | 4171 builder to be a copy of this one with the meta-bit set instead of |
4240 else | 4228 else |
4241 maybe_echo_keys (command_builder, 0); | 4229 maybe_echo_keys (command_builder, 0); |
4242 } | 4230 } |
4243 else if (!NILP (Vquit_flag)) { | 4231 else if (!NILP (Vquit_flag)) { |
4244 Lisp_Object quit_event = Fmake_event(Qnil, Qnil); | 4232 Lisp_Object quit_event = Fmake_event(Qnil, Qnil); |
4245 struct Lisp_Event *e = XEVENT (quit_event); | 4233 Lisp_Event *e = XEVENT (quit_event); |
4246 /* if quit happened during menu acceleration, pretend we read it */ | 4234 /* if quit happened during menu acceleration, pretend we read it */ |
4247 struct console *con = XCONSOLE (Fselected_console ()); | 4235 struct console *con = XCONSOLE (Fselected_console ()); |
4248 int ch = CONSOLE_QUIT_CHAR (con); | 4236 int ch = CONSOLE_QUIT_CHAR (con); |
4249 | 4237 |
4250 character_to_event (ch, e, con, 1, 1); | 4238 character_to_event (ch, e, con, 1, 1); |
4411 Lisp_Object win = Fselected_window (Qnil); | 4399 Lisp_Object win = Fselected_window (Qnil); |
4412 | 4400 |
4413 #if 0 | 4401 #if 0 |
4414 /* If the last command deleted the frame, `win' might be nil. | 4402 /* If the last command deleted the frame, `win' might be nil. |
4415 It seems safest to do nothing in this case. */ | 4403 It seems safest to do nothing in this case. */ |
4416 /* ### This doesn't really fix the problem, | 4404 /* #### This doesn't really fix the problem, |
4417 if delete-frame is called by some hook */ | 4405 if delete-frame is called by some hook */ |
4418 if (NILP (win)) | 4406 if (NILP (win)) |
4419 return; | 4407 return; |
4420 #endif | 4408 #endif |
4421 | 4409 |
4490 */ | 4478 */ |
4491 (event)) | 4479 (event)) |
4492 { | 4480 { |
4493 /* This function can GC */ | 4481 /* This function can GC */ |
4494 struct command_builder *command_builder; | 4482 struct command_builder *command_builder; |
4495 struct Lisp_Event *ev; | 4483 Lisp_Event *ev; |
4496 Lisp_Object console; | 4484 Lisp_Object console; |
4497 Lisp_Object channel; | 4485 Lisp_Object channel; |
4498 | 4486 |
4499 CHECK_LIVE_EVENT (event); | 4487 CHECK_LIVE_EVENT (event); |
4500 ev = XEVENT (event); | 4488 ev = XEVENT (event); |
4604 /* Reset the command builder for reading the next sequence. */ | 4592 /* Reset the command builder for reading the next sequence. */ |
4605 reset_this_command_keys (console, 1); | 4593 reset_this_command_keys (console, 1); |
4606 } | 4594 } |
4607 else /* key sequence is bound to a command */ | 4595 else /* key sequence is bound to a command */ |
4608 { | 4596 { |
4597 int magic_undo = 0; | |
4598 int magic_undo_count = 20; | |
4599 | |
4609 Vthis_command = leaf; | 4600 Vthis_command = leaf; |
4601 | |
4610 /* Don't push an undo boundary if the command set the prefix arg, | 4602 /* Don't push an undo boundary if the command set the prefix arg, |
4611 or if we are executing a keyboard macro, or if in the | 4603 or if we are executing a keyboard macro, or if in the |
4612 minibuffer. If the command we are about to execute is | 4604 minibuffer. If the command we are about to execute is |
4613 self-insert, it's tricky: up to 20 consecutive self-inserts may | 4605 self-insert, it's tricky: up to 20 consecutive self-inserts may |
4614 be done without an undo boundary. This counter is reset as | 4606 be done without an undo boundary. This counter is reset as |
4615 soon as a command other than self-insert-command is executed. | 4607 soon as a command other than self-insert-command is executed. |
4616 */ | 4608 |
4617 if (! EQ (leaf, Qself_insert_command)) | 4609 Programmers can also use the `self-insert-undo-magic' |
4610 property to install that behaviour on functions other | |
4611 than `self-insert-command', or to change the magic | |
4612 number 20 to something else. */ | |
4613 | |
4614 if (SYMBOLP (leaf)) | |
4615 { | |
4616 Lisp_Object prop = Fget (leaf, Qself_insert_defer_undo, Qnil); | |
4617 if (NATNUMP (prop)) | |
4618 magic_undo = 1, magic_undo_count = XINT (prop); | |
4619 else if (!NILP (prop)) | |
4620 magic_undo = 1; | |
4621 else if (EQ (leaf, Qself_insert_command)) | |
4622 magic_undo = 1; | |
4623 } | |
4624 | |
4625 if (!magic_undo) | |
4618 command_builder->self_insert_countdown = 0; | 4626 command_builder->self_insert_countdown = 0; |
4619 if (NILP (XCONSOLE (console)->prefix_arg) | 4627 if (NILP (XCONSOLE (console)->prefix_arg) |
4620 && NILP (Vexecuting_macro) | 4628 && NILP (Vexecuting_macro) |
4621 #if 0 | 4629 #if 0 |
4622 /* This was done in the days when there was no undo | 4630 /* This was done in the days when there was no undo |
4626 && !EQ (minibuf_window, Fselected_window (Qnil)) | 4634 && !EQ (minibuf_window, Fselected_window (Qnil)) |
4627 #endif | 4635 #endif |
4628 && command_builder->self_insert_countdown == 0) | 4636 && command_builder->self_insert_countdown == 0) |
4629 Fundo_boundary (); | 4637 Fundo_boundary (); |
4630 | 4638 |
4631 if (EQ (leaf, Qself_insert_command)) | 4639 if (magic_undo) |
4632 { | 4640 { |
4633 if (--command_builder->self_insert_countdown < 0) | 4641 if (--command_builder->self_insert_countdown < 0) |
4634 command_builder->self_insert_countdown = 20; | 4642 command_builder->self_insert_countdown = magic_undo_count; |
4635 } | 4643 } |
4636 execute_command_event | 4644 execute_command_event |
4637 (command_builder, | 4645 (command_builder, |
4638 internal_equal (event, command_builder-> most_current_event, 0) | 4646 internal_equal (event, command_builder-> most_current_event, 0) |
4639 ? event | 4647 ? event |
4815 the value of `this-command-keys' in addition to the raw original event. | 4823 the value of `this-command-keys' in addition to the raw original event. |
4816 That is not right. | 4824 That is not right. |
4817 | 4825 |
4818 Calling this function directs the translated event to replace | 4826 Calling this function directs the translated event to replace |
4819 the original event, so that only one version of the event actually | 4827 the original event, so that only one version of the event actually |
4820 appears in the echo area and in the value of `this-command-keys.'. | 4828 appears in the echo area and in the value of `this-command-keys'. |
4821 */ | 4829 */ |
4822 ()) | 4830 ()) |
4823 { | 4831 { |
4824 /* #### I don't understand this at all, so currently it does nothing. | 4832 /* #### I don't understand this at all, so currently it does nothing. |
4825 If there is ever a problem, maybe someone should investigate. */ | 4833 If there is ever a problem, maybe someone should investigate. */ |
4839 Lisp_Object keysym = XEVENT (event)->event.key.keysym; | 4847 Lisp_Object keysym = XEVENT (event)->event.key.keysym; |
4840 if (CHARP (XEVENT (event)->event.key.keysym)) | 4848 if (CHARP (XEVENT (event)->event.key.keysym)) |
4841 { | 4849 { |
4842 Emchar ch = XCHAR (keysym); | 4850 Emchar ch = XCHAR (keysym); |
4843 Bufbyte str[MAX_EMCHAR_LEN]; | 4851 Bufbyte str[MAX_EMCHAR_LEN]; |
4844 Bytecount len; | 4852 Bytecount len = set_charptr_emchar (str, ch); |
4845 | |
4846 len = set_charptr_emchar (str, ch); | |
4847 Lstream_write (XLSTREAM (Vdribble_file), str, len); | 4853 Lstream_write (XLSTREAM (Vdribble_file), str, len); |
4848 } | 4854 } |
4849 else if (string_char_length (XSYMBOL (keysym)->name) == 1) | 4855 else if (string_char_length (XSYMBOL (keysym)->name) == 1) |
4850 /* one-char key events are printed with just the key name */ | 4856 /* one-char key events are printed with just the key name */ |
4851 Fprinc (keysym, Vdribble_file); | 4857 Fprinc (keysym, Vdribble_file); |
4907 defsymbol (&Qdisabled, "disabled"); | 4913 defsymbol (&Qdisabled, "disabled"); |
4908 defsymbol (&Qcommand_event_p, "command-event-p"); | 4914 defsymbol (&Qcommand_event_p, "command-event-p"); |
4909 | 4915 |
4910 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", | 4916 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", |
4911 "Undefined keystroke sequence", Qerror); | 4917 "Undefined keystroke sequence", Qerror); |
4912 defsymbol (&Qcommand_execute, "command-execute"); | |
4913 | 4918 |
4914 DEFSUBR (Frecent_keys); | 4919 DEFSUBR (Frecent_keys); |
4915 DEFSUBR (Frecent_keys_ring_size); | 4920 DEFSUBR (Frecent_keys_ring_size); |
4916 DEFSUBR (Fset_recent_keys_ring_size); | 4921 DEFSUBR (Fset_recent_keys_ring_size); |
4917 DEFSUBR (Finput_pending_p); | 4922 DEFSUBR (Finput_pending_p); |
4960 defsymbol (&Qmenu_left, "menu-left"); | 4965 defsymbol (&Qmenu_left, "menu-left"); |
4961 defsymbol (&Qmenu_right, "menu-right"); | 4966 defsymbol (&Qmenu_right, "menu-right"); |
4962 defsymbol (&Qmenu_select, "menu-select"); | 4967 defsymbol (&Qmenu_select, "menu-select"); |
4963 defsymbol (&Qmenu_escape, "menu-escape"); | 4968 defsymbol (&Qmenu_escape, "menu-escape"); |
4964 | 4969 |
4970 defsymbol (&Qself_insert_defer_undo, "self-insert-defer-undo"); | |
4965 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); | 4971 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); |
4972 } | |
4973 | |
4974 void | |
4975 reinit_vars_of_event_stream (void) | |
4976 { | |
4977 recent_keys_ring_index = 0; | |
4978 recent_keys_ring_size = 100; | |
4979 num_input_chars = 0; | |
4980 Vtimeout_free_list = make_lcrecord_list (sizeof (Lisp_Timeout), | |
4981 &lrecord_timeout); | |
4982 staticpro_nodump (&Vtimeout_free_list); | |
4983 the_low_level_timeout_blocktype = | |
4984 Blocktype_new (struct low_level_timeout_blocktype); | |
4985 something_happened = 0; | |
4986 recursive_sit_for = Qnil; | |
4966 } | 4987 } |
4967 | 4988 |
4968 void | 4989 void |
4969 vars_of_event_stream (void) | 4990 vars_of_event_stream (void) |
4970 { | 4991 { |
4971 recent_keys_ring_index = 0; | 4992 reinit_vars_of_event_stream (); |
4972 recent_keys_ring_size = 100; | |
4973 Vrecent_keys_ring = Qnil; | 4993 Vrecent_keys_ring = Qnil; |
4974 staticpro (&Vrecent_keys_ring); | 4994 staticpro (&Vrecent_keys_ring); |
4975 | 4995 |
4976 Vthis_command_keys = Qnil; | 4996 Vthis_command_keys = Qnil; |
4977 staticpro (&Vthis_command_keys); | 4997 staticpro (&Vthis_command_keys); |
4978 Vthis_command_keys_tail = Qnil; | 4998 Vthis_command_keys_tail = Qnil; |
4979 | 4999 pdump_wire (&Vthis_command_keys_tail); |
4980 num_input_chars = 0; | |
4981 | 5000 |
4982 command_event_queue = Qnil; | 5001 command_event_queue = Qnil; |
4983 staticpro (&command_event_queue); | 5002 staticpro (&command_event_queue); |
4984 command_event_queue_tail = Qnil; | 5003 command_event_queue_tail = Qnil; |
5004 pdump_wire (&command_event_queue_tail); | |
4985 | 5005 |
4986 Vlast_selected_frame = Qnil; | 5006 Vlast_selected_frame = Qnil; |
4987 staticpro (&Vlast_selected_frame); | 5007 staticpro (&Vlast_selected_frame); |
4988 | 5008 |
4989 pending_timeout_list = Qnil; | 5009 pending_timeout_list = Qnil; |
4990 staticpro (&pending_timeout_list); | 5010 staticpro (&pending_timeout_list); |
4991 | 5011 |
4992 pending_async_timeout_list = Qnil; | 5012 pending_async_timeout_list = Qnil; |
4993 staticpro (&pending_async_timeout_list); | 5013 staticpro (&pending_async_timeout_list); |
4994 | 5014 |
4995 Vtimeout_free_list = make_opaque_list (sizeof (struct timeout), | |
4996 mark_timeout); | |
4997 staticpro (&Vtimeout_free_list); | |
4998 | |
4999 the_low_level_timeout_blocktype = | |
5000 Blocktype_new (struct low_level_timeout_blocktype); | |
5001 | |
5002 something_happened = 0; | |
5003 | |
5004 last_point_position_buffer = Qnil; | 5015 last_point_position_buffer = Qnil; |
5005 staticpro (&last_point_position_buffer); | 5016 staticpro (&last_point_position_buffer); |
5006 | |
5007 recursive_sit_for = Qnil; | |
5008 | 5017 |
5009 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* | 5018 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* |
5010 *Nonzero means echo unfinished commands after this many seconds of pause. | 5019 *Nonzero means echo unfinished commands after this many seconds of pause. |
5011 */ ); | 5020 */ ); |
5012 Vecho_keystrokes = make_int (1); | 5021 Vecho_keystrokes = make_int (1); |