~ubuntu-branches/ubuntu/trusty/geis/trusty

« back to all changes in this revision

Viewing changes to libgeis/geis_backend.c

  • Committer: Package Import Robot
  • Author(s): Chase Douglas
  • Date: 2012-07-30 08:51:42 UTC
  • Revision ID: package-import@ubuntu.com-20120730085142-jrc33ygjvt0ob1wl
Tags: upstream-2.2.11
ImportĀ upstreamĀ versionĀ 2.2.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @file geis_backend.c
 
3
 * @brief internal GEIS back end base class implementation
 
4
 *
 
5
 * Copyright 2010 Canonical Ltd.
 
6
 *
 
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
 
10
 * later version.
 
11
 *
 
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
 
15
 * details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
#include "geis_config.h"
 
21
#include "geis_backend.h"
 
22
#include "geis_backend_protected.h"
 
23
 
 
24
#include "geis_logging.h"
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
 
 
28
 
 
29
typedef struct GeisBackendClass
 
30
{
 
31
  GeisString        name;
 
32
  GeisSize          size;
 
33
  GeisBackendVtable vtbl;
 
34
} *GeisBackendClass;
 
35
 
 
36
 
 
37
struct GeisBackend
 
38
{
 
39
  GeisBackendClass  be_class;
 
40
  char              be_data[1];
 
41
};
 
42
 
 
43
 
 
44
struct GeisBackendRegistry
 
45
{
 
46
  GeisBackendClass be;
 
47
  GeisSize         size;
 
48
  GeisSize         count;
 
49
};
 
50
 
 
51
static struct GeisBackendRegistry _be_registry = { NULL, 0, 0 };
 
52
 
 
53
 
 
54
/*
 
55
 * Gets the child part of the back end instance.
 
56
 */
 
57
static inline void *
 
58
_data_from_be(GeisBackend be)
 
59
{
 
60
  return (void *)be->be_data;
 
61
}
 
62
 
 
63
 
 
64
/*
 
65
 * Initializes a new back end class object.
 
66
 */
 
67
static void
 
68
_backend_class_init(GeisBackendClass  self,
 
69
                    GeisString        name,
 
70
                    GeisSize          size,
 
71
                    GeisBackendVtable vtbl)
 
72
{
 
73
  self->name = strdup(name);
 
74
  self->size = size;
 
75
  self->vtbl = vtbl;
 
76
}
 
77
 
 
78
 
 
79
/*
 
80
 * Registers back ends with the API.
 
81
 */
 
82
void
 
83
geis_register_backend(GeisString name, GeisSize size, GeisBackendVtable vtbl)
 
84
{
 
85
  GeisSize new_size = _be_registry.size + 1;
 
86
  GeisBackendClass new_be = realloc(_be_registry.be,
 
87
                                    new_size * sizeof(struct GeisBackendClass));
 
88
  if (!new_be)
 
89
  {
 
90
    geis_error("error reallocating back end registry");
 
91
    goto final_exit;
 
92
  }
 
93
 
 
94
  _backend_class_init(&new_be[_be_registry.size], name, size, vtbl);
 
95
  geis_debug("back end %zu registered as '%s'", _be_registry.count, name);
 
96
 
 
97
  _be_registry.be = new_be;
 
98
  ++_be_registry.size;
 
99
  ++_be_registry.count;
 
100
 
 
101
final_exit:
 
102
  return;
 
103
}
 
104
 
 
105
 
 
106
GeisBackendToken
 
107
geis_backend_create_token(GeisBackend be, GeisBackendTokenInitState init_state)
 
108
{
 
109
  return be->be_class->vtbl->create_token(_data_from_be(be), init_state);
 
110
}
 
111
 
 
112
 
 
113
/*
 
114
 * Creates a back end by name.
 
115
 */
 
116
GeisBackend
 
117
geis_backend_by_name(Geis geis, GeisString name)
 
118
{
 
119
  GeisBackend backend = NULL;
 
120
  GeisSize i;
 
121
  extern void geis_include_backend_test_fixture(void);
 
122
  extern void geis_include_dbus_backend(void);
 
123
  extern void geis_include_grail_backend(void);
 
124
 
 
125
  geis_debug("creating back end of class \"%s\"", name);
 
126
  /* temporary references to force symbol inclusion, replace with dlopen */
 
127
  geis_include_backend_test_fixture();
 
128
  geis_include_dbus_backend();
 
129
  geis_include_grail_backend();
 
130
 
 
131
  for (i = 0; i < _be_registry.count; ++i)
 
132
  {
 
133
    if (0 == strcmp(_be_registry.be[i].name, name))
 
134
    {
 
135
      size_t obj_size = sizeof(GeisBackend) + _be_registry.be[i].size;
 
136
      backend = malloc(obj_size);
 
137
      if (backend)
 
138
      {
 
139
        *(GeisBackendClass *)(backend) = &_be_registry.be[i];
 
140
        _be_registry.be[i].vtbl->construct(_data_from_be(backend), geis);
 
141
        if (geis_error_count(geis))
 
142
        {
 
143
          free(backend);
 
144
          backend = NULL;
 
145
        }
 
146
      }
 
147
      break;
 
148
    }
 
149
  }
 
150
  return backend;
 
151
}
 
152
 
 
153
 
 
154
/*
 
155
 * Destroys the back end.
 
156
 */
 
157
void
 
158
geis_backend_delete(GeisBackend be)
 
159
{
 
160
  if (be)
 
161
  {
 
162
    geis_debug("destroying back end %s", geis_backend_name(be));
 
163
    be->be_class->vtbl->finalize(_data_from_be(be));
 
164
    free(be);
 
165
  }
 
166
}
 
167
 
 
168
 
 
169
/*
 
170
 * Gets the name of the back end (RTTI).
 
171
 */
 
172
GeisString
 
173
geis_backend_name(GeisBackend be)
 
174
{
 
175
  return be->be_class->name;
 
176
}
 
177
 
 
178
 
 
179
GeisStatus
 
180
geis_backend_gesture_accept(GeisBackend   be,
 
181
                            GeisGroup     group,
 
182
                            GeisGestureId gesture_id)
 
183
{
 
184
  GeisStatus status = be->be_class->vtbl->accept_gesture(_data_from_be(be),
 
185
                                                         group,
 
186
                                                         gesture_id);
 
187
  return status;
 
188
}
 
189
 
 
190
 
 
191
GeisStatus
 
192
geis_backend_gesture_reject(GeisBackend   be,
 
193
                            GeisGroup     group,
 
194
                            GeisGestureId gesture_id)
 
195
{
 
196
  GeisStatus status = be->be_class->vtbl->reject_gesture(_data_from_be(be),
 
197
                                                         group,
 
198
                                                         gesture_id);
 
199
  return status;
 
200
}
 
201
 
 
202
 
 
203
/*
 
204
 * Gets a back end configuration value.
 
205
 */
 
206
GeisStatus
 
207
geis_backend_get_configuration(GeisBackend      be,
 
208
                               GeisSubscription subscription,
 
209
                               GeisString       configuration_item_name,
 
210
                               GeisPointer      configuration_item_value)
 
211
{
 
212
  return be->be_class->vtbl->get_configuration(be,
 
213
                                               subscription,
 
214
                                               configuration_item_name,
 
215
                                               configuration_item_value);
 
216
}
 
217
 
 
218
 
 
219
/*
 
220
 * Sets a back end configuration value.
 
221
 */
 
222
GeisStatus
 
223
geis_backend_set_configuration(GeisBackend      be,
 
224
                               GeisSubscription subscription,
 
225
                               GeisString       configuration_item_name,
 
226
                               GeisPointer      configuration_item_value)
 
227
{
 
228
  return be->be_class->vtbl->set_configuration(be,
 
229
                                               subscription,
 
230
                                               configuration_item_name,
 
231
                                               configuration_item_value);
 
232
}
 
233