~ubuntu-branches/debian/stretch/gnome-builder/stretch

« back to all changes in this revision

Viewing changes to libide/ide-device-manager.c

  • Committer: Package Import Robot
  • Author(s): Andreas Henriksson
  • Date: 2015-10-11 12:38:45 UTC
  • Revision ID: package-import@ubuntu.com-20151011123845-a0hvkz01se0p1p5a
Tags: upstream-3.16.3
ImportĀ upstreamĀ versionĀ 3.16.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ide-device-manager.c
 
2
 *
 
3
 * Copyright (C) 2015 Christian Hergert <christian@hergert.me>
 
4
 *
 
5
 * This program is free software: you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation, either version 3 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
#include <glib/gi18n.h>
 
20
 
 
21
#include "ide-device.h"
 
22
#include "ide-device-manager.h"
 
23
#include "ide-device-provider.h"
 
24
 
 
25
#include "local/ide-local-device.h"
 
26
 
 
27
struct _IdeDeviceManager
 
28
{
 
29
  IdeObject  parent_instance;
 
30
 
 
31
  GPtrArray *devices;
 
32
  GPtrArray *providers;
 
33
};
 
34
 
 
35
static void list_model_init_interface (GListModelInterface *iface);
 
36
 
 
37
G_DEFINE_TYPE_WITH_CODE (IdeDeviceManager, ide_device_manager, IDE_TYPE_OBJECT,
 
38
                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
 
39
                                                list_model_init_interface))
 
40
 
 
41
enum {
 
42
  PROP_0,
 
43
  PROP_SETTLED,
 
44
  LAST_PROP
 
45
};
 
46
 
 
47
enum {
 
48
  DEVICE_ADDED,
 
49
  DEVICE_REMOVED,
 
50
  LAST_SIGNAL
 
51
};
 
52
 
 
53
static guint gSignals [LAST_SIGNAL];
 
54
static GParamSpec *gParamSpecs [LAST_PROP];
 
55
 
 
56
gboolean
 
57
ide_device_manager_get_settled (IdeDeviceManager *self)
 
58
{
 
59
  gsize i;
 
60
 
 
61
  g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), FALSE);
 
62
 
 
63
  for (i = 0; i < self->providers->len; i++)
 
64
    {
 
65
      IdeDeviceProvider *provider;
 
66
 
 
67
      provider = g_ptr_array_index (self->providers, i);
 
68
      if (!ide_device_provider_get_settled (provider))
 
69
        return FALSE;
 
70
    }
 
71
 
 
72
  return TRUE;
 
73
}
 
74
 
 
75
static void
 
76
ide_device_manager_device_notify_settled (IdeDeviceManager  *self,
 
77
                                          GParamSpec        *pspec,
 
78
                                          IdeDeviceProvider *provider)
 
79
{
 
80
  g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
 
81
  g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
 
82
 
 
83
  g_object_notify_by_pspec (G_OBJECT (self),
 
84
                            gParamSpecs [PROP_SETTLED]);
 
85
}
 
86
 
 
87
static void
 
88
ide_device_manager_do_add_device (IdeDeviceManager *self,
 
89
                                  IdeDevice        *device)
 
90
{
 
91
  guint position;
 
92
 
 
93
  g_assert (IDE_IS_DEVICE_MANAGER (self));
 
94
  g_assert (IDE_IS_DEVICE (device));
 
95
 
 
96
  position = self->devices->len;
 
97
  g_ptr_array_add (self->devices, g_object_ref (device));
 
98
  g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
 
99
}
 
100
 
 
101
static void
 
102
ide_device_manager_device_added (IdeDeviceManager  *self,
 
103
                                 IdeDevice         *device,
 
104
                                 IdeDeviceProvider *provider)
 
105
{
 
106
  g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
 
107
  g_return_if_fail (IDE_IS_DEVICE (device));
 
108
  g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
 
109
 
 
110
  ide_device_manager_do_add_device (self, device);
 
111
  g_signal_emit (self, gSignals [DEVICE_ADDED], 0, provider, device);
 
112
}
 
113
 
 
114
static void
 
115
ide_device_manager_device_removed (IdeDeviceManager  *self,
 
116
                                   IdeDevice         *device,
 
117
                                   IdeDeviceProvider *provider)
 
118
{
 
119
  guint i;
 
120
 
 
121
  g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
 
122
  g_return_if_fail (IDE_IS_DEVICE (device));
 
123
  g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
 
124
 
 
125
  g_signal_handlers_disconnect_by_func (provider,
 
126
                                        G_CALLBACK (ide_device_manager_device_notify_settled),
 
127
                                        self);
 
128
  g_signal_handlers_disconnect_by_func (provider,
 
129
                                        G_CALLBACK (ide_device_manager_device_added),
 
130
                                        self);
 
131
  g_signal_handlers_disconnect_by_func (provider,
 
132
                                        G_CALLBACK (ide_device_manager_device_removed),
 
133
                                        self);
 
134
 
 
135
  for (i = 0; i < self->devices->len; i++)
 
136
    {
 
137
      IdeDevice *iter;
 
138
 
 
139
      iter = g_ptr_array_index (self->devices, i);
 
140
 
 
141
      if (iter == device)
 
142
        {
 
143
          g_ptr_array_remove_index (self->devices, i);
 
144
          g_list_model_items_changed (G_LIST_MODEL (self), i, 1, 0);
 
145
          g_signal_emit (self, gSignals [DEVICE_REMOVED], 0, provider, device);
 
146
 
 
147
          break;
 
148
        }
 
149
    }
 
150
}
 
151
 
 
152
void
 
153
ide_device_manager_add_provider (IdeDeviceManager  *self,
 
154
                                 IdeDeviceProvider *provider)
 
155
{
 
156
  GPtrArray *devices;
 
157
  guint i;
 
158
 
 
159
  g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
 
160
  g_return_if_fail (IDE_IS_DEVICE_PROVIDER (provider));
 
161
 
 
162
  for (i = 0; i < self->providers->len; i++)
 
163
    {
 
164
      if (provider == g_ptr_array_index (self->providers, i))
 
165
        {
 
166
          g_warning ("Cannot add provider, already registered.");
 
167
          return;
 
168
        }
 
169
    }
 
170
 
 
171
  g_ptr_array_add (self->providers, g_object_ref (provider));
 
172
 
 
173
  g_signal_connect_object (provider,
 
174
                           "notify::settled",
 
175
                           G_CALLBACK (ide_device_manager_device_notify_settled),
 
176
                           self,
 
177
                           G_CONNECT_SWAPPED);
 
178
 
 
179
  g_signal_connect_object (provider,
 
180
                           "device-added",
 
181
                           G_CALLBACK (ide_device_manager_device_added),
 
182
                           self,
 
183
                           G_CONNECT_SWAPPED);
 
184
 
 
185
  g_signal_connect_object (provider,
 
186
                           "device-removed",
 
187
                           G_CALLBACK (ide_device_manager_device_removed),
 
188
                           self,
 
189
                           G_CONNECT_SWAPPED);
 
190
 
 
191
  devices = ide_device_provider_get_devices (provider);
 
192
 
 
193
  for (i = 0; i < devices->len; i++)
 
194
    {
 
195
      IdeDevice *device;
 
196
 
 
197
      device = g_ptr_array_index (devices, i);
 
198
      ide_device_manager_device_added (self, device, provider);
 
199
    }
 
200
}
 
201
 
 
202
static void
 
203
ide_device_manager_add_providers (IdeDeviceManager *self)
 
204
{
 
205
  GIOExtensionPoint *extension_point;
 
206
  IdeContext *context;
 
207
  GList *extensions;
 
208
  GList *iter;
 
209
 
 
210
  g_assert (IDE_IS_DEVICE_MANAGER (self));
 
211
 
 
212
  context = ide_object_get_context (IDE_OBJECT (self));
 
213
 
 
214
  extension_point = g_io_extension_point_lookup (IDE_DEVICE_PROVIDER_EXTENSION_POINT);
 
215
  extensions = g_io_extension_point_get_extensions (extension_point);
 
216
 
 
217
  for (iter = extensions; iter; iter = iter->next)
 
218
    {
 
219
      GIOExtension *extension = iter->data;
 
220
      g_autoptr(IdeDeviceProvider) provider = NULL;
 
221
      GType type;
 
222
 
 
223
      type = g_io_extension_get_type (extension);
 
224
 
 
225
      if (!g_type_is_a (type, IDE_TYPE_DEVICE_PROVIDER))
 
226
        {
 
227
          g_warning (_("%s is not an IdeDeviceProvider."),
 
228
                     g_type_name (type));
 
229
          continue;
 
230
        }
 
231
 
 
232
      provider = g_object_new (type, "context", context, NULL);
 
233
      ide_device_manager_add_provider (self, provider);
 
234
    }
 
235
}
 
236
 
 
237
/**
 
238
 * ide_device_manager_get_devices:
 
239
 *
 
240
 * Retrieves all of the devices that are registered with the #IdeDeviceManager.
 
241
 *
 
242
 * Returns: (transfer container) (element-type IdeDevice*): An array of devices
 
243
 *   registered with the #IdeManager.
 
244
 */
 
245
GPtrArray *
 
246
ide_device_manager_get_devices (IdeDeviceManager *self)
 
247
{
 
248
  GPtrArray *ret;
 
249
  guint i;
 
250
 
 
251
  g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), NULL);
 
252
 
 
253
  ret = g_ptr_array_new_with_free_func (g_object_unref);
 
254
 
 
255
  for (i = 0; i < self->devices->len; i++)
 
256
    {
 
257
      IdeDevice *device;
 
258
 
 
259
      device = g_ptr_array_index (self->devices, i);
 
260
      g_ptr_array_add (ret, g_object_ref (device));
 
261
    }
 
262
 
 
263
  return ret;
 
264
}
 
265
 
 
266
static void
 
267
ide_device_manager_add_local (IdeDeviceManager *self)
 
268
{
 
269
  g_autoptr(IdeDevice) device = NULL;
 
270
  IdeContext *context;
 
271
 
 
272
  g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
 
273
 
 
274
  context = ide_object_get_context (IDE_OBJECT (self));
 
275
  device = g_object_new (IDE_TYPE_LOCAL_DEVICE,
 
276
                         "context", context,
 
277
                         NULL);
 
278
  ide_device_manager_do_add_device (self, device);
 
279
}
 
280
 
 
281
static GType
 
282
ide_device_manager_get_item_type (GListModel *list_model)
 
283
{
 
284
  return IDE_TYPE_DEVICE;
 
285
}
 
286
 
 
287
static guint
 
288
ide_device_manager_get_n_items (GListModel *list_model)
 
289
{
 
290
  IdeDeviceManager *self = (IdeDeviceManager *)list_model;
 
291
 
 
292
  g_assert (IDE_IS_DEVICE_MANAGER (self));
 
293
 
 
294
  return self->devices->len;
 
295
}
 
296
 
 
297
gpointer
 
298
ide_device_manager_get_item (GListModel *list_model,
 
299
                             guint       position)
 
300
{
 
301
  IdeDeviceManager *self = (IdeDeviceManager *)list_model;
 
302
 
 
303
  g_assert (IDE_IS_DEVICE_MANAGER (self));
 
304
  g_assert (position < self->devices->len);
 
305
 
 
306
  return g_object_ref (g_ptr_array_index (self->devices, position));
 
307
}
 
308
 
 
309
static void
 
310
ide_device_manager_constructed (GObject *object)
 
311
{
 
312
  IdeDeviceManager *self = (IdeDeviceManager *)object;
 
313
 
 
314
  g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
 
315
 
 
316
  G_OBJECT_CLASS (ide_device_manager_parent_class)->constructed (object);
 
317
 
 
318
  ide_device_manager_add_local (self);
 
319
  ide_device_manager_add_providers (self);
 
320
}
 
321
 
 
322
static void
 
323
ide_device_manager_finalize (GObject *object)
 
324
{
 
325
  IdeDeviceManager *self = (IdeDeviceManager *)object;
 
326
 
 
327
  g_clear_pointer (&self->devices, g_ptr_array_unref);
 
328
  g_clear_pointer (&self->providers, g_ptr_array_unref);
 
329
 
 
330
  G_OBJECT_CLASS (ide_device_manager_parent_class)->finalize (object);
 
331
}
 
332
 
 
333
static void
 
334
ide_device_manager_get_property (GObject    *object,
 
335
                                 guint       prop_id,
 
336
                                 GValue     *value,
 
337
                                 GParamSpec *pspec)
 
338
{
 
339
  IdeDeviceManager *self = IDE_DEVICE_MANAGER(object);
 
340
 
 
341
  switch (prop_id)
 
342
    {
 
343
    case PROP_SETTLED:
 
344
      g_value_set_boolean (value, ide_device_manager_get_settled (self));
 
345
      break;
 
346
 
 
347
    default:
 
348
      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
 
349
    }
 
350
}
 
351
 
 
352
static void
 
353
ide_device_manager_class_init (IdeDeviceManagerClass *klass)
 
354
{
 
355
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
356
 
 
357
  object_class->constructed = ide_device_manager_constructed;
 
358
  object_class->finalize = ide_device_manager_finalize;
 
359
  object_class->get_property = ide_device_manager_get_property;
 
360
 
 
361
  gParamSpecs [PROP_SETTLED] =
 
362
    g_param_spec_boolean ("settled",
 
363
                          _("Settled"),
 
364
                          _("If the device providers have settled."),
 
365
                          FALSE,
 
366
                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
367
 
 
368
  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
 
369
 
 
370
  gSignals [DEVICE_ADDED] =
 
371
    g_signal_new ("device-added",
 
372
                  G_TYPE_FROM_CLASS (klass),
 
373
                  G_SIGNAL_RUN_LAST,
 
374
                  0,
 
375
                  NULL, NULL, NULL,
 
376
                  G_TYPE_NONE,
 
377
                  2,
 
378
                  IDE_TYPE_DEVICE_PROVIDER,
 
379
                  IDE_TYPE_DEVICE);
 
380
 
 
381
  gSignals [DEVICE_REMOVED] =
 
382
    g_signal_new ("device-removed",
 
383
                  G_TYPE_FROM_CLASS (klass),
 
384
                  G_SIGNAL_RUN_LAST,
 
385
                  0,
 
386
                  NULL, NULL, NULL,
 
387
                  G_TYPE_NONE,
 
388
                  2,
 
389
                  IDE_TYPE_DEVICE_PROVIDER,
 
390
                  IDE_TYPE_DEVICE);
 
391
}
 
392
 
 
393
static void
 
394
list_model_init_interface (GListModelInterface *iface)
 
395
{
 
396
  iface->get_item_type = ide_device_manager_get_item_type;
 
397
  iface->get_n_items = ide_device_manager_get_n_items;
 
398
  iface->get_item = ide_device_manager_get_item;
 
399
}
 
400
 
 
401
static void
 
402
ide_device_manager_init (IdeDeviceManager *self)
 
403
{
 
404
  self->devices = g_ptr_array_new_with_free_func (g_object_unref);
 
405
  self->providers = g_ptr_array_new_with_free_func (g_object_unref);
 
406
}
 
407
 
 
408
/**
 
409
 * ide_device_manager_get_device:
 
410
 * @device_id: The device identifier string.
 
411
 *
 
412
 * Fetches the first device that matches the device identifier @device_id.
 
413
 *
 
414
 * Returns: (transfer none): An #IdeDevice or %NULL.
 
415
 */
 
416
IdeDevice *
 
417
ide_device_manager_get_device (IdeDeviceManager *self,
 
418
                               const gchar      *device_id)
 
419
{
 
420
  gsize i;
 
421
 
 
422
  g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), NULL);
 
423
 
 
424
  for (i = 0; i < self->devices->len; i++)
 
425
    {
 
426
      IdeDevice *device;
 
427
      const gchar *id;
 
428
 
 
429
      device = g_ptr_array_index (self->devices, i);
 
430
      id = ide_device_get_id (device);
 
431
 
 
432
      if (0 == g_strcmp0 (id, device_id))
 
433
        return device;
 
434
    }
 
435
 
 
436
  return NULL;
 
437
}