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