2
* @file libgeis/geis_region.c
3
* @brief implementation of the GEIS v2.0 API Input Device module
5
* Copyright 2010, 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_device.h"
24
#include "geis_atomic.h"
25
#include "geis_attr.h"
26
#include "geis_logging.h"
33
GeisRefCount ref_count;
39
GeisDevice *device_store;
40
GeisSize device_store_size;
41
GeisSize device_count;
44
static const int device_bag_growth_constant = 2;
50
GeisDeviceBag bag = calloc(1, sizeof(struct _GeisDeviceBag));
53
geis_error("error allocating device bag");
57
bag->device_store = calloc(1, sizeof(struct _GeisDevice));
58
if (!bag->device_store)
60
geis_error("error allocating device bag store");
64
bag->device_store_size = 1;
65
bag->device_count = 0;
77
geis_device_bag_delete(GeisDeviceBag bag)
80
for (i = bag->device_count; i > 0; --i)
82
geis_device_unref(bag->device_store[i-1]);
84
free(bag->device_store);
90
geis_device_bag_count(GeisDeviceBag bag)
92
return bag->device_count;
97
geis_device_bag_device(GeisDeviceBag bag, GeisSize index)
99
GeisDevice device = NULL;
100
if (index >= bag->device_count)
102
geis_warning("device bag index out of range");
106
device = bag->device_store[index];
113
geis_device_bag_insert(GeisDeviceBag bag, GeisDevice device)
115
GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
116
for (GeisSize i = 0; i < bag->device_count; ++i)
118
if (bag->device_store[i] == device)
120
geis_device_ref(device);
125
if (bag->device_count >= bag->device_store_size)
127
GeisSize new_store_size = bag->device_store_size * device_bag_growth_constant;
128
GeisDevice *new_store = realloc(bag->device_store,
129
new_store_size * sizeof(struct _GeisDevice));
132
geis_error("failed to reallocate device bag");
135
bag->device_store = new_store;
136
bag->device_store_size = new_store_size;
138
bag->device_store[bag->device_count++] = geis_device_ref(device);
139
status = GEIS_STATUS_SUCCESS;
147
geis_device_bag_remove(GeisDeviceBag bag, GeisDevice device)
150
GeisStatus status = GEIS_STATUS_SUCCESS;
151
for (i = 0; i < bag->device_count; ++i)
153
if (bag->device_store[i] == device)
156
geis_device_unref(bag->device_store[i]);
158
for (j = i; j < bag->device_count; ++j)
160
bag->device_store[j] = bag->device_store[j+1];
170
* Creates a new, empty device.
173
geis_device_new(GeisString name, GeisInteger id)
176
GeisDevice device = calloc(1, sizeof(struct _GeisDevice));
179
geis_error("error allocating input device");
183
device->attr_bag = geis_attr_bag_new(4);
184
if (!device->attr_bag)
186
geis_debug("error allocating attr bag");
190
attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_NAME,
191
GEIS_ATTR_TYPE_STRING,
195
geis_debug("error allocating device name attr");
198
geis_attr_bag_insert(device->attr_bag, attr);
200
attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_ID,
201
GEIS_ATTR_TYPE_INTEGER,
205
geis_debug("error allocating device id attr");
208
geis_attr_bag_insert(device->attr_bag, attr);
210
geis_device_ref(device);
214
geis_attr_bag_delete(device->attr_bag);
227
_device_delete(GeisDevice device)
229
geis_attr_bag_delete(device->attr_bag);
235
* Adds a reference count to a device.
238
geis_device_ref(GeisDevice device)
240
geis_atomic_ref(&device->ref_count);
246
* Removes a reference count from a device.
249
geis_device_unref(GeisDevice device)
251
if (0 == geis_atomic_unref(&device->ref_count))
253
_device_delete(device);
259
* Gets the name of the input device.
262
geis_device_name(GeisDevice device)
264
GeisString device_name = NULL;
265
GeisAttr name_attr = geis_attr_bag_find(device->attr_bag,
266
GEIS_DEVICE_ATTRIBUTE_NAME);
269
device_name = geis_attr_value_to_string(name_attr);
276
* Gets the system identifier of the iput device.
279
geis_device_id(GeisDevice device)
281
GeisInteger device_id = -1;
282
GeisAttr attr = geis_attr_bag_find(device->attr_bag, GEIS_DEVICE_ATTRIBUTE_ID);
285
device_id = geis_attr_value_to_integer(attr);
292
* Gets the number of attributes of the device.
295
geis_device_attr_count(GeisDevice device)
297
return geis_attr_bag_count(device->attr_bag);
302
* Inserts an attr into a device.
305
geis_device_add_attr(GeisDevice device, GeisAttr attr)
307
geis_attr_bag_insert(device->attr_bag, attr);
312
* Gets the indicated attribute of the device.
315
geis_device_attr(GeisDevice device, GeisSize index)
317
return geis_attr_bag_attr(device->attr_bag, index);
324
geis_device_attr_by_name(GeisDevice device, GeisString attr_name)
326
return geis_attr_bag_find(device->attr_bag, attr_name);