2
* @file libgeis/geis_region.c
3
* @brief implementation of the GEIS v2.0 API region module
5
* Copyright 2010 Canonical Ltd.
7
* This library is free software; you can redistribute it and/or modify it under
8
* the terms of the GNU Lesser General Public License as published by the Free
9
* Software Foundation; either version 3 of the License, or (at your option) any
12
* This library is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17
* You should have received a copy of the GNU Lesser General Public License
18
* along with this program; if not, write to the Free Software Foundation, Inc.,
19
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include "geis_config.h"
22
#include "geis_region.h"
24
#include "geis_atomic.h"
25
#include "geis_error.h"
26
#include "geis_logging.h"
34
GeisRefCount refcount;
44
GeisRegion *region_store;
45
GeisSize region_store_size;
46
GeisSize region_count;
49
static const int region_bag_growth_constant = 2;
53
* Constructs a region bag.
58
GeisRegionBag bag = calloc(1, sizeof(struct _GeisRegionBag));
61
geis_error("failed to allocate region bag");
65
bag->region_store_size = 3;
66
bag->region_count = 0;
67
bag->region_store = calloc(bag->region_store_size, sizeof(GeisRegion));
68
if (!bag->region_store)
70
geis_error("failed to allocate region bag store");
83
* Destroys a region bag.
86
geis_region_bag_delete(GeisRegionBag bag)
89
for (i = bag->region_count; i > 0; --i)
91
geis_region_delete(bag->region_store[i-1]);
98
* Gets the number of regions held in a bag.
101
geis_region_bag_count(GeisRegionBag bag)
103
return bag->region_count;
108
* Gets an indicated region from a bag.
111
geis_region_bag_region(GeisRegionBag bag, GeisSize index)
113
GeisRegion region = NULL;
114
if (index < bag->region_count)
116
region = bag->region_store[index];
123
* Puts a region into a bag.
126
geis_region_bag_insert(GeisRegionBag bag, GeisRegion region)
128
GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
129
if (bag->region_count >= bag->region_store_size)
131
GeisSize new_store_size = bag->region_store_size * region_bag_growth_constant;
132
GeisRegion *new_store = realloc(bag->region_store,
133
new_store_size * sizeof(struct _GeisRegion));
136
geis_error("failed to reallocate region bag");
139
bag->region_store = new_store;
140
bag->region_store_size = new_store_size;
142
bag->region_store[bag->region_count++] = region;
143
status = GEIS_STATUS_SUCCESS;
151
* Takes a region out of a bag.
154
geis_region_bag_remove(GeisRegionBag bag, GeisRegion region)
157
GeisStatus status = GEIS_STATUS_SUCCESS;
158
for (i = 0; i < bag->region_count; ++i)
160
if (bag->region_store[i] == region)
163
geis_region_delete(bag->region_store[i]);
165
for (j = i; j < bag->region_count; ++j)
167
bag->region_store[j] = bag->region_store[j+1];
177
* Constructs a region.
180
geis_region_new(Geis geis,
182
GeisString init_arg_name, ...)
184
GeisRegion region = NULL;
187
region = calloc(1, sizeof(struct _GeisRegion));
190
geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR);
191
geis_error("error allocating region");
195
va_start(varargs, init_arg_name);
196
while (init_arg_name)
198
if (0 == strcmp(init_arg_name, GEIS_REGION_X11_ROOT))
202
geis_warning("multiple region types requested, only using the first");
205
region->type = strdup(init_arg_name);
206
geis_debug("using X11 root");
208
else if (0 == strcmp(init_arg_name, GEIS_REGION_X11_WINDOWID))
212
geis_warning("multiple region types requested, only using the first");
215
region->type = strdup(init_arg_name);
216
region->data.windowid = va_arg(varargs, int);
217
geis_debug("using X11 windowid 0x%08x", region->data.windowid);
220
init_arg_name = va_arg(varargs, GeisString);
225
region->name = strdup(name);
233
* Destroys a GEIS v2.0 region.
236
geis_region_delete(GeisRegion region)
238
if (0 == geis_atomic_unref(®ion->refcount))
240
free((char *)region->name);
241
free((char *)region->type);
244
return GEIS_STATUS_SUCCESS;
249
* Gets the name of a GEIS v2.0 region.
252
geis_region_name(GeisRegion region)
259
* Adds a reference to a region.
262
geis_region_ref(GeisRegion region)
264
geis_atomic_ref(®ion->refcount);
269
* Gets the type of the region.
272
geis_region_type(GeisRegion region)
279
* Gets the data (if any) associated with the region type.
282
geis_region_data(GeisRegion region)
284
return ®ion->data;