Mercurial > hg > xemacs-beta
diff src/event-stream.c @ 153:25f70ba0133c r20-3b3
Import from CVS: tag r20-3b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:38:25 +0200 |
parents | 1856695b1fa9 |
children | 15872534500d |
line wrap: on
line diff
--- a/src/event-stream.c Mon Aug 13 09:37:21 2007 +0200 +++ b/src/event-stream.c Mon Aug 13 09:38:25 2007 +0200 @@ -188,6 +188,11 @@ /* File in which we write all commands we read; an lstream */ static Lisp_Object Vdribble_file; +/* Recent keys ring location; a vector of events or nil-s */ +Lisp_Object Vrecent_keys_ring; +int recent_keys_ring_size; +int recent_keys_ring_index; + #ifdef DEBUG_XEMACS int debug_emacs_events; #endif @@ -3227,24 +3232,39 @@ data structure.) */ -#define RECENT_KEYS_SIZE 100 -Lisp_Object recent_keys_ring; -int recent_keys_ring_index; - -DEFUN ("recent-keys", Frecent_keys, 0, 0, 0, /* -Return vector of last 100 or so keyboard or mouse button events read. +DEFUN ("recent-keys", Frecent_keys, 0, 1, 0, /* +Return a vector of recent keyboard or mouse button events read. +If NUMBER is non-nil, not more than NUMBER events will be returned. +Change number of events stored using `set-recent-keys-size'. + This copies the event objects into a new vector; it is safe to keep and modify them. */ - ()) + (number)) { struct gcpro gcpro1; Lisp_Object val = Qnil; - int size = XVECTOR (recent_keys_ring)->size; + int nwanted; int start, nkeys, i, j; GCPRO1 (val); - if (NILP (vector_data (XVECTOR (recent_keys_ring))[recent_keys_ring_index])) + if (NILP (number)) + nwanted = recent_keys_ring_size; + else + { + CHECK_NATNUM (number); + nwanted = XINT (number); + } + + /* Create the keys ring vector, if none present. */ + if (NILP (Vrecent_keys_ring)) + { + Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil); + /* And return nothing in particular. */ + return make_vector (0, Qnil); + } + + if (NILP (vector_data (XVECTOR (Vrecent_keys_ring))[recent_keys_ring_index])) /* This means the vector has not yet wrapped */ { nkeys = recent_keys_ring_index; @@ -3252,26 +3272,102 @@ } else { - nkeys = size; - start = ((recent_keys_ring_index == size) ? 0 : recent_keys_ring_index); + nkeys = recent_keys_ring_size; + start = ((recent_keys_ring_index == nkeys) ? 0 : recent_keys_ring_index); } - val = make_vector (nkeys, Qnil); + if (nwanted < nkeys) + { + start += nkeys - nwanted; + if (start >= recent_keys_ring_size) + start -= recent_keys_ring_size; + nkeys = nwanted; + } + else + nwanted = nkeys; + + val = make_vector (nwanted, Qnil); for (i = 0, j = start; i < nkeys; i++) { - Lisp_Object e = vector_data (XVECTOR (recent_keys_ring))[j]; + Lisp_Object e = vector_data (XVECTOR (Vrecent_keys_ring))[j]; if (NILP (e)) abort (); vector_data (XVECTOR (val))[i] = Fcopy_event (e, Qnil); - if (++j >= size) + if (++j >= recent_keys_ring_size) j = 0; } UNGCPRO; return (val); } + +DEFUN ("recent-keys-ring-size", Frecent_keys_ring_size, 0, 0, 0, /* +The maximum number of events `recent-keys' can return. +*/ + ()) +{ + return make_int (recent_keys_ring_size); +} + +DEFUN ("set-recent-keys-ring-size", Fset_recent_keys_ring_size, 1, 1, 0, /* +Set the maximum number of events to be stored internally. +*/ + (size)) +{ + Lisp_Object new_vector = Qnil; + int i, j, nkeys, start, min; + struct gcpro gcpro1; + GCPRO1 (new_vector); + + CHECK_INT (size); + if (XINT (size) <= 0) + error ("Recent keys ring size must be positive"); + if (XINT (size) == recent_keys_ring_size) + return size; + + new_vector = make_vector (XINT (size), Qnil); + + if (NILP (Vrecent_keys_ring)) + { + Vrecent_keys_ring = new_vector; + return size; + } + + if (NILP (vector_data (XVECTOR (Vrecent_keys_ring))[recent_keys_ring_index])) + /* This means the vector has not yet wrapped */ + { + nkeys = recent_keys_ring_index; + start = 0; + } + else + { + nkeys = recent_keys_ring_size; + start = ((recent_keys_ring_index == nkeys) ? 0 : recent_keys_ring_index); + } + + if (XINT (size) > nkeys) + min = nkeys; + else + min = XINT (size); + + for (i = 0, j = start; i < min; i++) + { + vector_data (XVECTOR (new_vector))[i] + = vector_data (XVECTOR (Vrecent_keys_ring))[j]; + if (++j >= recent_keys_ring_size) + j = 0; + } + recent_keys_ring_size = XINT (size); + recent_keys_ring_index = (i < recent_keys_ring_size) ? i : 0; + + Vrecent_keys_ring = new_vector; + + UNGCPRO; + return size; +} + /* Vthis_command_keys having value Qnil means that the next time push_this_command_keys is called, it should start over. The times at which the command-keys are reset @@ -3372,16 +3468,20 @@ static void push_recent_keys (Lisp_Object event) { - Lisp_Object e - = vector_data (XVECTOR (recent_keys_ring)) [recent_keys_ring_index]; + Lisp_Object e; + + if (NILP (Vrecent_keys_ring)) + Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil); + + e = vector_data (XVECTOR (Vrecent_keys_ring)) [recent_keys_ring_index]; if (NILP (e)) { e = Fmake_event (); - vector_data (XVECTOR (recent_keys_ring)) [recent_keys_ring_index] = e; + vector_data (XVECTOR (Vrecent_keys_ring)) [recent_keys_ring_index] = e; } Fcopy_event (event, e); - if (++recent_keys_ring_index == XVECTOR (recent_keys_ring)->size) + if (++recent_keys_ring_index == recent_keys_ring_size) recent_keys_ring_index = 0; } @@ -4160,6 +4260,8 @@ defsymbol (&Qcommand_execute, "command-execute"); DEFSUBR (Frecent_keys); + DEFSUBR (Frecent_keys_ring_size); + DEFSUBR (Fset_recent_keys_ring_size); DEFSUBR (Finput_pending_p); DEFSUBR (Fenqueue_eval_event); DEFSUBR (Fnext_event); @@ -4207,8 +4309,9 @@ recent_keys_ring_index = 0; - recent_keys_ring = make_vector (RECENT_KEYS_SIZE, Qnil); - staticpro (&recent_keys_ring); + recent_keys_ring_size = 100; + Vrecent_keys_ring = Qnil; + staticpro (&Vrecent_keys_ring); Vthis_command_keys = Qnil; staticpro (&Vthis_command_keys); @@ -4472,7 +4575,6 @@ Vdribble_file = Qnil; staticpro (&Vdribble_file); - #ifdef DEBUG_XEMACS DEFVAR_INT ("debug-emacs-events", &debug_emacs_events /* If non-zero, display debug information about Emacs events that XEmacs sees.