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);