A tiling window manager
at master 157 lines 3.3 kB view raw
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}