Mercurial > emacs
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 |