~ctwm/ctwm/trunk

675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
1
/*
2
 * Functions related to the window ring.
675.1.10 by Olaf 'Rhialto' Seibert
Document some window ring invariants.
3
 *
4
 * Invariants:
5
 * - If a window is not on the ring, its TwmWindow::ring.next and .prev
6
 *   are both NULL.
7
 * - If a window is on the ring, they are both not NULL and point to a
8
 *   window which is also on the ring.
9
 * - Corollary: if a window is the only one on the ring, .next and .prev
10
 *   point to itself.
11
 * - Functions which act on the "current" ring window, i.e. the window
12
 *   that has most recently been entered and is on the ring, use
13
 *   Scr->RingLeader.
14
 * - If RingLeader is NULL, fall back to Scr->Ring.
15
 * - If Ring is NULL, the ring is empty (and RingLeader is also NULL).
675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
16
 */
17
18
#include "ctwm.h"
19
675.1.10 by Olaf 'Rhialto' Seibert
Document some window ring invariants.
20
#include <assert.h>
21
675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
22
#include "screen.h"
23
#include "win_ring.h"
24
25
void
26
UnlinkWindowFromRing(TwmWindow *win)
27
{
28
	TwmWindow *prev = win->ring.prev;
29
	TwmWindow *next = win->ring.next;
30
682 by Matthew Fuller
Escape early from UnlinkWindowFromRing() if the window isn't on the
31
	// We call this unconditionally at various window deletion times, and
32
	// if it's not on the ring, there's nothing to do.  e.g., if we don't
33
	// have any WindowRing config enabled...
34
	if(!WindowIsOnRing(win)) {
35
		return;
36
	}
37
38
	// But if it is, prev/next should always exist.
675.1.10 by Olaf 'Rhialto' Seibert
Document some window ring invariants.
39
	assert(prev != NULL);
40
	assert(next != NULL);
682 by Matthew Fuller
Escape early from UnlinkWindowFromRing() if the window isn't on the
41
675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
42
	/*
43
	* 1. Unlink window
44
	* 2. If window was only thing in ring, null out ring
45
	* 3. If window was ring leader, set to next (or null)
46
	*
47
	* If the window is the only one in the ring, prev == next == win,
48
	* so the unlinking effectively is a NOP, but that doesn't matter.
49
	*/
50
	prev->ring.next = next;
51
	next->ring.prev = prev;
52
53
	win->ring.next = win->ring.prev = NULL;
54
55
	if(Scr->Ring == win) {
56
		Scr->Ring = (next != win ? next : NULL);
57
	}
58
59
	if(!Scr->Ring || Scr->RingLeader == win) {
60
		Scr->RingLeader = Scr->Ring;
61
	}
62
}
63
64
static void
65
AddWindowToRingUnchecked(TwmWindow *win, TwmWindow *after)
66
{
67
	TwmWindow *before = after->ring.next;
68
69
	win->ring.next = before;
70
	win->ring.prev = after;
71
72
	after->ring.next = win;
73
	before->ring.prev = win;
74
}
75
76
void
77
AddWindowToRing(TwmWindow *win)
78
{
675.1.10 by Olaf 'Rhialto' Seibert
Document some window ring invariants.
79
	assert(win->ring.next == NULL);
80
	assert(win->ring.prev == NULL);
81
675.1.7 by Olaf 'Rhialto' Seibert
Move the window ring functions to their own file.
82
	if(Scr->Ring) {
83
		AddWindowToRingUnchecked(win, Scr->Ring);
84
	}
85
	else {
86
		win->ring.next = win->ring.prev = Scr->Ring = win;
87
	}
88
}