A tiling window manager
1/*
2 * handles the handing out of and uniqueness of window numbers.
3 * Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA.
18 */
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <err.h>
23
24#include "sdorfehs.h"
25
26/* Keep track of a set of numbers. For frames and windows. */
27struct numset {
28 /* A list of the numbers taken. */
29 int *numbers_taken;
30
31 /*
32 * the number of numbers currently stored in the numbers_taken array.
33 */
34 int num_taken;
35
36 /* the size of the numbers_taken array. */
37 int max_taken;
38};
39
40/* Initialize a numset structure. */
41static void
42numset_init(struct numset *ns)
43{
44 ns->max_taken = 10;
45 ns->num_taken = 0;
46
47 ns->numbers_taken = xmalloc(ns->max_taken * sizeof(int));
48}
49
50static int
51numset_num_is_taken(struct numset *ns, int n)
52{
53 int i;
54
55 for (i = 0; i < ns->num_taken; i++) {
56 if (ns->numbers_taken[i] == n)
57 return 1;
58 }
59 return 0;
60}
61
62/* returns index into numbers_taken that can be used. */
63static int
64numset_find_empty_cell(struct numset *ns)
65{
66 int i;
67
68 for (i = 0; i < ns->num_taken; i++) {
69 if (ns->numbers_taken[i] == -1)
70 return i;
71 }
72
73 /* no vacant ones, so grow the array. */
74 if (ns->num_taken >= ns->max_taken) {
75 ns->max_taken *= 2;
76 ns->numbers_taken = xrealloc(ns->numbers_taken,
77 sizeof(int) * ns->max_taken);
78 }
79 ns->num_taken++;
80
81 return ns->num_taken - 1;
82}
83
84int
85numset_add_num(struct numset *ns, int n)
86{
87 int ec;
88
89 if (numset_num_is_taken(ns, n))
90 return 0; /* failed. */
91
92 /*
93 * numset_find_empty_cell calls realloc on numbers_taken. So store the
94 * ret val in ec then use ec as an index into the array.
95 */
96 ec = numset_find_empty_cell(ns);
97 ns->numbers_taken[ec] = n;
98 return 1; /* success! */
99}
100
101/*
102 * returns a unique number that can be used as the window number in the program
103 * bar.
104 */
105int
106numset_request(struct numset *ns)
107{
108 int i;
109
110 /*
111 * look for a unique number, and add it to the list of taken numbers.
112 */
113 i = 0;
114 while (!numset_add_num(ns, i))
115 i++;
116
117 return i;
118}
119
120/*
121 * When a window is destroyed, it gives back its window number with this
122 * function.
123 */
124void
125numset_release(struct numset *ns, int n)
126{
127 int i;
128
129 if (n < 0)
130 warnx("ns=%p attempt to release %d!", ns, n);
131
132 for (i = 0; i < ns->num_taken; i++) {
133 if (ns->numbers_taken[i] == n) {
134 ns->numbers_taken[i] = -1;
135 return;
136 }
137 }
138}
139
140/* Create a new numset and return a pointer to it. */
141struct numset *
142numset_new(void)
143{
144 struct numset *ns;
145
146 ns = xmalloc(sizeof(struct numset));
147 numset_init(ns);
148 return ns;
149}
150
151/* Free a numset structure and it's internal data. */
152void
153numset_free(struct numset *ns)
154{
155 free(ns->numbers_taken);
156 free(ns);
157}