comparison src/dispnew.c @ 64776:42f593faa113

(Fframe_or_buffer_changed_p): Take an arg so it can be used with various state vectors.
author Richard M. Stallman <rms@gnu.org>
date Sun, 07 Aug 2005 17:40:18 +0000
parents a0d1312ede66
children 74ab28cf1192
comparison
equal deleted inserted replaced
64775:17ea5769514d 64776:42f593faa113
6461 Other Lisp Functions 6461 Other Lisp Functions
6462 ***********************************************************************/ 6462 ***********************************************************************/
6463 6463
6464 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the 6464 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
6465 session's frames, frame names, buffers, buffer-read-only flags, and 6465 session's frames, frame names, buffers, buffer-read-only flags, and
6466 buffer-modified-flags, and a trailing sentinel (so we don't need to 6466 buffer-modified-flags. */
6467 add length checks). */
6468 6467
6469 static Lisp_Object frame_and_buffer_state; 6468 static Lisp_Object frame_and_buffer_state;
6470 6469
6471 6470
6472 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p, 6471 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
6473 Sframe_or_buffer_changed_p, 0, 0, 0, 6472 Sframe_or_buffer_changed_p, 0, 1, 0,
6474 doc: /* Return non-nil if the frame and buffer state appears to have changed. 6473 doc: /* Return non-nil if the frame and buffer state appears to have changed.
6475 The state variable is an internal vector containing all frames and buffers, 6474 VARIABLE is a variable name whose value is either nil or a state vector
6475 that will be updated to contain all frames and buffers,
6476 aside from buffers whose names start with space, 6476 aside from buffers whose names start with space,
6477 along with the buffers' read-only and modified flags, which allows a fast 6477 along with the buffers' read-only and modified flags. This allows a fast
6478 check to see whether the menu bars might need to be recomputed. 6478 check to see whether buffer menus might need to be recomputed.
6479 If this function returns non-nil, it updates the internal vector to reflect 6479 If this function returns non-nil, it updates the internal vector to reflect
6480 the current state. */) 6480 the current state.
6481 () 6481
6482 { 6482 If VARIABLE is nil, an internal variable is used. Users should not
6483 Lisp_Object tail, frame, buf; 6483 pass nil for VARIABLE. */)
6484 Lisp_Object *vecp; 6484 (variable)
6485 Lisp_Object variable;
6486 {
6487 Lisp_Object state, tail, frame, buf;
6488 Lisp_Object *vecp, *end;
6485 int n; 6489 int n;
6486 6490
6487 vecp = XVECTOR (frame_and_buffer_state)->contents; 6491 if (! NILP (variable))
6492 {
6493 CHECK_SYMBOL (variable);
6494 state = Fsymbol_value (variable);
6495 if (! VECTORP (state))
6496 goto changed;
6497 }
6498 else
6499 state = frame_and_buffer_state;
6500
6501 vecp = XVECTOR (state)->contents;
6502 end = vecp + XVECTOR (state)->size;
6503
6488 FOR_EACH_FRAME (tail, frame) 6504 FOR_EACH_FRAME (tail, frame)
6489 { 6505 {
6506 if (vecp == end)
6507 goto changed;
6490 if (!EQ (*vecp++, frame)) 6508 if (!EQ (*vecp++, frame))
6509 goto changed;
6510 if (vecp == end)
6491 goto changed; 6511 goto changed;
6492 if (!EQ (*vecp++, XFRAME (frame)->name)) 6512 if (!EQ (*vecp++, XFRAME (frame)->name))
6493 goto changed; 6513 goto changed;
6494 } 6514 }
6495 /* Check that the buffer info matches. 6515 /* Check that the buffer info matches. */
6496 No need to test for the end of the vector
6497 because the last element of the vector is lambda
6498 and that will always cause a mismatch. */
6499 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 6516 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6500 { 6517 {
6501 buf = XCDR (XCAR (tail)); 6518 buf = XCDR (XCAR (tail));
6502 /* Ignore buffers that aren't included in buffer lists. */ 6519 /* Ignore buffers that aren't included in buffer lists. */
6503 if (SREF (XBUFFER (buf)->name, 0) == ' ') 6520 if (SREF (XBUFFER (buf)->name, 0) == ' ')
6504 continue; 6521 continue;
6522 if (vecp == end)
6523 goto changed;
6505 if (!EQ (*vecp++, buf)) 6524 if (!EQ (*vecp++, buf))
6525 goto changed;
6526 if (vecp == end)
6506 goto changed; 6527 goto changed;
6507 if (!EQ (*vecp++, XBUFFER (buf)->read_only)) 6528 if (!EQ (*vecp++, XBUFFER (buf)->read_only))
6508 goto changed; 6529 goto changed;
6530 if (vecp == end)
6531 goto changed;
6509 if (!EQ (*vecp++, Fbuffer_modified_p (buf))) 6532 if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
6510 goto changed; 6533 goto changed;
6511 } 6534 }
6535 if (vecp == end)
6536 goto changed;
6512 /* Detect deletion of a buffer at the end of the list. */ 6537 /* Detect deletion of a buffer at the end of the list. */
6513 if (EQ (*vecp, Qlambda)) 6538 if (EQ (*vecp, Qlambda))
6514 return Qnil; 6539 return Qnil;
6540
6541 /* Come here if we decide the data has changed. */
6515 changed: 6542 changed:
6516 /* Start with 1 so there is room for at least one lambda at the end. */ 6543 /* Count the size we will need.
6544 Start with 1 so there is room for at least one lambda at the end. */
6517 n = 1; 6545 n = 1;
6518 FOR_EACH_FRAME (tail, frame) 6546 FOR_EACH_FRAME (tail, frame)
6519 n += 2; 6547 n += 2;
6520 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 6548 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6521 n += 3; 6549 n += 3;
6522 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */ 6550 /* Reallocate the vector if data has grown to need it,
6523 if (n > XVECTOR (frame_and_buffer_state)->size 6551 or if it has shrunk a lot. */
6524 || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2) 6552 if (! VECTORP (state)
6553 || n > XVECTOR (state)->size
6554 || n + 20 < XVECTOR (state)->size / 2)
6525 /* Add 20 extra so we grow it less often. */ 6555 /* Add 20 extra so we grow it less often. */
6526 frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda); 6556 {
6527 vecp = XVECTOR (frame_and_buffer_state)->contents; 6557 state = Fmake_vector (make_number (n + 20), Qlambda);
6558 if (! NILP (variable))
6559 Fset (variable, state);
6560 else
6561 frame_and_buffer_state = state;
6562 }
6563
6564 /* Record the new data in the (possibly reallocated) vector. */
6565 vecp = XVECTOR (state)->contents;
6528 FOR_EACH_FRAME (tail, frame) 6566 FOR_EACH_FRAME (tail, frame)
6529 { 6567 {
6530 *vecp++ = frame; 6568 *vecp++ = frame;
6531 *vecp++ = XFRAME (frame)->name; 6569 *vecp++ = XFRAME (frame)->name;
6532 } 6570 }
6540 *vecp++ = XBUFFER (buf)->read_only; 6578 *vecp++ = XBUFFER (buf)->read_only;
6541 *vecp++ = Fbuffer_modified_p (buf); 6579 *vecp++ = Fbuffer_modified_p (buf);
6542 } 6580 }
6543 /* Fill up the vector with lambdas (always at least one). */ 6581 /* Fill up the vector with lambdas (always at least one). */
6544 *vecp++ = Qlambda; 6582 *vecp++ = Qlambda;
6545 while (vecp - XVECTOR (frame_and_buffer_state)->contents 6583 while (vecp - XVECTOR (state)->contents
6546 < XVECTOR (frame_and_buffer_state)->size) 6584 < XVECTOR (state)->size)
6547 *vecp++ = Qlambda; 6585 *vecp++ = Qlambda;
6548 /* Make sure we didn't overflow the vector. */ 6586 /* Make sure we didn't overflow the vector. */
6549 if (vecp - XVECTOR (frame_and_buffer_state)->contents 6587 if (vecp - XVECTOR (state)->contents
6550 > XVECTOR (frame_and_buffer_state)->size) 6588 > XVECTOR (state)->size)
6551 abort (); 6589 abort ();
6552 return Qt; 6590 return Qt;
6553 } 6591 }
6554 6592
6555 6593