Mercurial > hg > xemacs-beta
comparison src/event-stream.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 41dbb7a9d5f2 |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
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; |
387 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) | 384 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) |
388 #define GC_COMMAND_BUILDERP(x) GC_RECORDP (x, command_builder) | 385 #define GC_COMMAND_BUILDERP(x) GC_RECORDP (x, command_builder) |
389 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) | 386 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) |
390 | 387 |
391 static Lisp_Object | 388 static Lisp_Object |
392 mark_command_builder (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 389 mark_command_builder (Lisp_Object obj) |
393 { | 390 { |
394 struct command_builder *builder = XCOMMAND_BUILDER (obj); | 391 struct command_builder *builder = XCOMMAND_BUILDER (obj); |
395 markobj (builder->prefix_events); | 392 mark_object (builder->prefix_events); |
396 markobj (builder->current_events); | 393 mark_object (builder->current_events); |
397 markobj (builder->most_current_event); | 394 mark_object (builder->most_current_event); |
398 markobj (builder->last_non_munged_event); | 395 mark_object (builder->last_non_munged_event); |
399 markobj (builder->munge_me[0].first_mungeable_event); | 396 mark_object (builder->munge_me[0].first_mungeable_event); |
400 markobj (builder->munge_me[1].first_mungeable_event); | 397 mark_object (builder->munge_me[1].first_mungeable_event); |
401 return builder->console; | 398 return builder->console; |
402 } | 399 } |
403 | 400 |
404 static void | 401 static void |
405 finalize_command_builder (void *header, int for_disksave) | 402 finalize_command_builder (void *header, int for_disksave) |
983 | 980 |
984 /* We ensure that 0 is never a valid ID, so that a value of 0 can be | 981 /* 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. */ | 982 used to indicate an absence of a timer. */ |
986 static int low_level_timeout_id_tick; | 983 static int low_level_timeout_id_tick; |
987 | 984 |
988 struct low_level_timeout_blocktype | 985 static struct low_level_timeout_blocktype |
989 { | 986 { |
990 Blocktype_declare (struct low_level_timeout); | 987 Blocktype_declare (struct low_level_timeout); |
991 } *the_low_level_timeout_blocktype; | 988 } *the_low_level_timeout_blocktype; |
992 | 989 |
993 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return | 990 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return |
1099 | 1096 |
1100 /**** High-level timeout functions. ****/ | 1097 /**** High-level timeout functions. ****/ |
1101 | 1098 |
1102 static int timeout_id_tick; | 1099 static int timeout_id_tick; |
1103 | 1100 |
1104 /* Since timeout structures contain Lisp_Objects, they need to be GC'd | 1101 static Lisp_Object pending_timeout_list, pending_async_timeout_list; |
1105 properly. The opaque data type provides a convenient way of doing | 1102 |
1106 this without having to create a new Lisp object, since we can | 1103 static Lisp_Object Vtimeout_free_list; |
1107 provide our own mark function. */ | 1104 |
1108 | 1105 static Lisp_Object |
1109 struct timeout | 1106 mark_timeout (Lisp_Object obj) |
1110 { | 1107 { |
1111 int id; /* Id we use to identify the timeout over its lifetime */ | 1108 struct Lisp_Timeout *tm = XTIMEOUT (obj); |
1112 int interval_id; /* Id for this particular interval; this may | 1109 mark_object (tm->function); |
1113 be different each time the timeout is | 1110 return tm->object; |
1114 signalled.*/ | 1111 } |
1115 Lisp_Object function, object; /* Function and object associated | 1112 |
1116 with timeout. */ | 1113 /* Should never, ever be called. (except by an external debugger) */ |
1117 EMACS_TIME next_signal_time; /* Absolute time when the timeout | 1114 static void |
1118 is next going to be signalled. */ | 1115 print_timeout (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
1119 unsigned int resignal_msecs; /* How far after the next timeout | 1116 { |
1120 should the one after that | 1117 CONST struct Lisp_Timeout *t = XTIMEOUT (obj); |
1121 occur? */ | 1118 char buf[64]; |
1119 | |
1120 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (timeout) 0x%lx>", | |
1121 (unsigned long) t); | |
1122 write_c_string (buf, printcharfun); | |
1123 } | |
1124 | |
1125 static const struct lrecord_description timeout_description[] = { | |
1126 { XD_LISP_OBJECT, offsetof(struct Lisp_Timeout, function), 2 }, | |
1127 { XD_END } | |
1122 }; | 1128 }; |
1123 | 1129 |
1124 static Lisp_Object pending_timeout_list, pending_async_timeout_list; | 1130 DEFINE_LRECORD_IMPLEMENTATION ("timeout", timeout, |
1125 | 1131 mark_timeout, print_timeout, |
1126 static Lisp_Object Vtimeout_free_list; | 1132 0, 0, 0, timeout_description, struct 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 | 1133 |
1136 /* Generate a timeout and return its ID. */ | 1134 /* Generate a timeout and return its ID. */ |
1137 | 1135 |
1138 int | 1136 int |
1139 event_stream_generate_wakeup (unsigned int milliseconds, | 1137 event_stream_generate_wakeup (unsigned int milliseconds, |
1140 unsigned int vanilliseconds, | 1138 unsigned int vanilliseconds, |
1141 Lisp_Object function, Lisp_Object object, | 1139 Lisp_Object function, Lisp_Object object, |
1142 int async_p) | 1140 int async_p) |
1143 { | 1141 { |
1144 Lisp_Object op = allocate_managed_opaque (Vtimeout_free_list, 0); | 1142 Lisp_Object op = allocate_managed_lcrecord (Vtimeout_free_list); |
1145 struct timeout *timeout = (struct timeout *) XOPAQUE_DATA (op); | 1143 struct Lisp_Timeout *timeout = XTIMEOUT (op); |
1146 EMACS_TIME current_time; | 1144 EMACS_TIME current_time; |
1147 EMACS_TIME interval; | 1145 EMACS_TIME interval; |
1148 | 1146 |
1149 timeout->id = timeout_id_tick++; | 1147 timeout->id = timeout_id_tick++; |
1150 timeout->resignal_msecs = vanilliseconds; | 1148 timeout->resignal_msecs = vanilliseconds; |
1189 static int | 1187 static int |
1190 event_stream_resignal_wakeup (int interval_id, int async_p, | 1188 event_stream_resignal_wakeup (int interval_id, int async_p, |
1191 Lisp_Object *function, Lisp_Object *object) | 1189 Lisp_Object *function, Lisp_Object *object) |
1192 { | 1190 { |
1193 Lisp_Object op = Qnil, rest; | 1191 Lisp_Object op = Qnil, rest; |
1194 struct timeout *timeout; | 1192 struct Lisp_Timeout *timeout; |
1195 Lisp_Object *timeout_list; | 1193 Lisp_Object *timeout_list; |
1196 struct gcpro gcpro1; | 1194 struct gcpro gcpro1; |
1197 int id; | 1195 int id; |
1198 | 1196 |
1199 GCPRO1 (op); /* just in case ... because it's removed from the list | 1197 GCPRO1 (op); /* just in case ... because it's removed from the list |
1202 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; | 1200 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; |
1203 | 1201 |
1204 /* Find the timeout on the list of pending ones. */ | 1202 /* Find the timeout on the list of pending ones. */ |
1205 LIST_LOOP (rest, *timeout_list) | 1203 LIST_LOOP (rest, *timeout_list) |
1206 { | 1204 { |
1207 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | 1205 timeout = XTIMEOUT (XCAR (rest)); |
1208 if (timeout->interval_id == interval_id) | 1206 if (timeout->interval_id == interval_id) |
1209 break; | 1207 break; |
1210 } | 1208 } |
1211 | 1209 |
1212 assert (!NILP (rest)); | 1210 assert (!NILP (rest)); |
1213 op = XCAR (rest); | 1211 op = XCAR (rest); |
1214 timeout = (struct timeout *) XOPAQUE_DATA (op); | 1212 timeout = XTIMEOUT (op); |
1215 /* We make sure to snarf the data out of the timeout object before | 1213 /* We make sure to snarf the data out of the timeout object before |
1216 we free it with free_managed_opaque(). */ | 1214 we free it with free_managed_lcrecord(). */ |
1217 id = timeout->id; | 1215 id = timeout->id; |
1218 *function = timeout->function; | 1216 *function = timeout->function; |
1219 *object = timeout->object; | 1217 *object = timeout->object; |
1220 | 1218 |
1221 /* Remove this one from the list of pending timeouts */ | 1219 /* Remove this one from the list of pending timeouts */ |
1253 is to move frequently-hit timeouts to the front of the | 1251 is to move frequently-hit timeouts to the front of the |
1254 list, which is a good thing. */ | 1252 list, which is a good thing. */ |
1255 *timeout_list = noseeum_cons (op, *timeout_list); | 1253 *timeout_list = noseeum_cons (op, *timeout_list); |
1256 } | 1254 } |
1257 else | 1255 else |
1258 free_managed_opaque (Vtimeout_free_list, op); | 1256 free_managed_lcrecord (Vtimeout_free_list, op); |
1259 | 1257 |
1260 UNGCPRO; | 1258 UNGCPRO; |
1261 return id; | 1259 return id; |
1262 } | 1260 } |
1263 | 1261 |
1264 void | 1262 void |
1265 event_stream_disable_wakeup (int id, int async_p) | 1263 event_stream_disable_wakeup (int id, int async_p) |
1266 { | 1264 { |
1267 struct timeout *timeout = 0; | 1265 struct Lisp_Timeout *timeout = 0; |
1268 Lisp_Object rest; | 1266 Lisp_Object rest; |
1269 Lisp_Object *timeout_list; | 1267 Lisp_Object *timeout_list; |
1270 | 1268 |
1271 if (async_p) | 1269 if (async_p) |
1272 timeout_list = &pending_async_timeout_list; | 1270 timeout_list = &pending_async_timeout_list; |
1274 timeout_list = &pending_timeout_list; | 1272 timeout_list = &pending_timeout_list; |
1275 | 1273 |
1276 /* Find the timeout on the list of pending ones, if it's still there. */ | 1274 /* Find the timeout on the list of pending ones, if it's still there. */ |
1277 LIST_LOOP (rest, *timeout_list) | 1275 LIST_LOOP (rest, *timeout_list) |
1278 { | 1276 { |
1279 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | 1277 timeout = XTIMEOUT (XCAR (rest)); |
1280 if (timeout->id == id) | 1278 if (timeout->id == id) |
1281 break; | 1279 break; |
1282 } | 1280 } |
1283 | 1281 |
1284 /* If we found it, remove it from the list and disable the pending | 1282 /* If we found it, remove it from the list and disable the pending |
1290 delq_no_quit_and_free_cons (op, *timeout_list); | 1288 delq_no_quit_and_free_cons (op, *timeout_list); |
1291 if (async_p) | 1289 if (async_p) |
1292 event_stream_remove_async_timeout (timeout->interval_id); | 1290 event_stream_remove_async_timeout (timeout->interval_id); |
1293 else | 1291 else |
1294 event_stream_remove_timeout (timeout->interval_id); | 1292 event_stream_remove_timeout (timeout->interval_id); |
1295 free_managed_opaque (Vtimeout_free_list, op); | 1293 free_managed_lcrecord (Vtimeout_free_list, op); |
1296 } | 1294 } |
1297 } | 1295 } |
1298 | 1296 |
1299 static int | 1297 static int |
1300 event_stream_wakeup_pending_p (int id, int async_p) | 1298 event_stream_wakeup_pending_p (int id, int async_p) |
1301 { | 1299 { |
1302 struct timeout *timeout; | 1300 struct Lisp_Timeout *timeout; |
1303 Lisp_Object rest; | 1301 Lisp_Object rest; |
1304 Lisp_Object timeout_list; | 1302 Lisp_Object timeout_list; |
1305 int found = 0; | 1303 int found = 0; |
1306 | 1304 |
1307 | 1305 |
1311 timeout_list = pending_timeout_list; | 1309 timeout_list = pending_timeout_list; |
1312 | 1310 |
1313 /* Find the element on the list of pending ones, if it's still there. */ | 1311 /* Find the element on the list of pending ones, if it's still there. */ |
1314 LIST_LOOP (rest, timeout_list) | 1312 LIST_LOOP (rest, timeout_list) |
1315 { | 1313 { |
1316 timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest)); | 1314 timeout = XTIMEOUT (XCAR (rest)); |
1317 if (timeout->id == id) | 1315 if (timeout->id == id) |
1318 { | 1316 { |
1319 found = 1; | 1317 found = 1; |
1320 break; | 1318 break; |
1321 } | 1319 } |
4907 defsymbol (&Qdisabled, "disabled"); | 4905 defsymbol (&Qdisabled, "disabled"); |
4908 defsymbol (&Qcommand_event_p, "command-event-p"); | 4906 defsymbol (&Qcommand_event_p, "command-event-p"); |
4909 | 4907 |
4910 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", | 4908 deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence", |
4911 "Undefined keystroke sequence", Qerror); | 4909 "Undefined keystroke sequence", Qerror); |
4912 defsymbol (&Qcommand_execute, "command-execute"); | |
4913 | 4910 |
4914 DEFSUBR (Frecent_keys); | 4911 DEFSUBR (Frecent_keys); |
4915 DEFSUBR (Frecent_keys_ring_size); | 4912 DEFSUBR (Frecent_keys_ring_size); |
4916 DEFSUBR (Fset_recent_keys_ring_size); | 4913 DEFSUBR (Fset_recent_keys_ring_size); |
4917 DEFSUBR (Finput_pending_p); | 4914 DEFSUBR (Finput_pending_p); |
4964 | 4961 |
4965 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); | 4962 defsymbol (&Qcancel_mode_internal, "cancel-mode-internal"); |
4966 } | 4963 } |
4967 | 4964 |
4968 void | 4965 void |
4969 vars_of_event_stream (void) | 4966 reinit_vars_of_event_stream (void) |
4970 { | 4967 { |
4971 recent_keys_ring_index = 0; | 4968 recent_keys_ring_index = 0; |
4972 recent_keys_ring_size = 100; | 4969 recent_keys_ring_size = 100; |
4970 num_input_chars = 0; | |
4971 Vtimeout_free_list = make_lcrecord_list (sizeof (struct Lisp_Timeout), | |
4972 &lrecord_timeout); | |
4973 staticpro_nodump (&Vtimeout_free_list); | |
4974 the_low_level_timeout_blocktype = | |
4975 Blocktype_new (struct low_level_timeout_blocktype); | |
4976 something_happened = 0; | |
4977 recursive_sit_for = Qnil; | |
4978 } | |
4979 | |
4980 void | |
4981 vars_of_event_stream (void) | |
4982 { | |
4983 reinit_vars_of_event_stream (); | |
4973 Vrecent_keys_ring = Qnil; | 4984 Vrecent_keys_ring = Qnil; |
4974 staticpro (&Vrecent_keys_ring); | 4985 staticpro (&Vrecent_keys_ring); |
4975 | 4986 |
4976 Vthis_command_keys = Qnil; | 4987 Vthis_command_keys = Qnil; |
4977 staticpro (&Vthis_command_keys); | 4988 staticpro (&Vthis_command_keys); |
4978 Vthis_command_keys_tail = Qnil; | 4989 Vthis_command_keys_tail = Qnil; |
4979 | 4990 pdump_wire (&Vthis_command_keys_tail); |
4980 num_input_chars = 0; | |
4981 | 4991 |
4982 command_event_queue = Qnil; | 4992 command_event_queue = Qnil; |
4983 staticpro (&command_event_queue); | 4993 staticpro (&command_event_queue); |
4984 command_event_queue_tail = Qnil; | 4994 command_event_queue_tail = Qnil; |
4995 pdump_wire (&command_event_queue_tail); | |
4985 | 4996 |
4986 Vlast_selected_frame = Qnil; | 4997 Vlast_selected_frame = Qnil; |
4987 staticpro (&Vlast_selected_frame); | 4998 staticpro (&Vlast_selected_frame); |
4988 | 4999 |
4989 pending_timeout_list = Qnil; | 5000 pending_timeout_list = Qnil; |
4990 staticpro (&pending_timeout_list); | 5001 staticpro (&pending_timeout_list); |
4991 | 5002 |
4992 pending_async_timeout_list = Qnil; | 5003 pending_async_timeout_list = Qnil; |
4993 staticpro (&pending_async_timeout_list); | 5004 staticpro (&pending_async_timeout_list); |
4994 | 5005 |
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; | 5006 last_point_position_buffer = Qnil; |
5005 staticpro (&last_point_position_buffer); | 5007 staticpro (&last_point_position_buffer); |
5006 | |
5007 recursive_sit_for = Qnil; | |
5008 | 5008 |
5009 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* | 5009 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* |
5010 *Nonzero means echo unfinished commands after this many seconds of pause. | 5010 *Nonzero means echo unfinished commands after this many seconds of pause. |
5011 */ ); | 5011 */ ); |
5012 Vecho_keystrokes = make_int (1); | 5012 Vecho_keystrokes = make_int (1); |