コード例 #1
0
static gboolean
parse_parameters (const TpCMParamSpec *paramspec,
                  GHashTable *provided,
                  TpIntset *params_present,
                  const TpCMParamSetter set_param,
                  void *params,
                  GError **error)
{
  int i;
  GValue *value;

  for (i = 0; paramspec[i].name; i++)
    {
      value = g_hash_table_lookup (provided, paramspec[i].name);

      if (value != NULL)
        {
          if (!set_param_from_value (&paramspec[i], value, set_param, params,
                error))
            {
              return FALSE;
            }

          tp_intset_add (params_present, i);

          g_hash_table_remove (provided, paramspec[i].name);
        }
    }

  return TRUE;
}
コード例 #2
0
ファイル: properties-mixin.c プロジェクト: psunkari/spicebird
/**
 * tp_properties_mixin_change_value:
 * @obj: An object with the properties mixin
 * @prop_id: A property ID on which to act
 * @new_value: Property value
 * @props: either %NULL, or a pointer to a TpIntSet
 *
 * Change the value of the given property ID in response to a server state
 * change.
 *
 * If the old and new values match, nothing happens; no signal is emitted and
 * @props is ignored. Otherwise, the following applies:
 *
 * If @props is %NULL the PropertiesChanged signal is emitted for this one
 * property.
 *
 * Otherwise, the property ID is added to the set; the caller is responsible
 * for passing the set to tp_properties_mixin_emit_changed() once a batch of
 * properties have been changed.
 */
void
tp_properties_mixin_change_value (GObject *obj,
                                  guint prop_id,
                                  const GValue *new_value,
                                  TpIntSet *props)
{
  TpPropertiesMixin *mixin = TP_PROPERTIES_MIXIN (obj);
  TpPropertiesMixinClass *mixin_cls = TP_PROPERTIES_MIXIN_CLASS (
      G_OBJECT_GET_CLASS (obj));
  TpProperty *prop;

  g_assert (prop_id < mixin_cls->num_props);

  prop = &mixin->properties[prop_id];

  if (prop->value)
    {
      if (values_are_equal (prop->value, new_value))
        return;
    }
  else
    {
      prop->value = tp_g_value_slice_new (mixin_cls->signatures[prop_id].type);
    }

  g_value_copy (new_value, prop->value);

  if (props)
    {
      tp_intset_add (props, prop_id);
    }
  else
    {
      TpIntSet *changed_props = tp_intset_sized_new (prop_id + 1);

      tp_intset_add (changed_props, prop_id);
      tp_properties_mixin_emit_changed (obj, changed_props);
      tp_intset_destroy (changed_props);
    }
}
コード例 #3
0
ファイル: properties-mixin.c プロジェクト: psunkari/spicebird
/**
 * tp_properties_mixin_change_flags:
 * @obj: An object with the properties mixin
 * @prop_id: A property ID on which to act
 * @add: Property flags to be added via bitwise OR
 * @del: Property flags to be removed via bitwise AND
 * @props: either %NULL, or a pointer to a TpIntSet
 *
 * Change the flags for the given property ID in response to a server state
 * change.
 *
 * Flags removed by @del override flags added by @add. This should not be
 * relied upon.
 *
 * If @props is %NULL the PropertyFlagsChanged signal is emitted for this
 * single property.
 *
 * Otherwise, the property ID is added to the set; the caller is responsible
 * for passing the set to tp_properties_mixin_emit_flags() once a batch of
 * properties have been changed.
 */
void
tp_properties_mixin_change_flags (GObject *obj,
                                  guint prop_id,
                                  TpPropertyFlags add,
                                  TpPropertyFlags del,
                                  TpIntSet *props)
{
  TpPropertiesMixin *mixin = TP_PROPERTIES_MIXIN (obj);
  TpPropertiesMixinClass *mixin_cls = TP_PROPERTIES_MIXIN_CLASS (
                                            G_OBJECT_GET_CLASS (obj));
  TpProperty *prop;
  guint prev_flags;

  g_assert (prop_id < mixin_cls->num_props);

  prop = &mixin->properties[prop_id];

  prev_flags = prop->flags;

  prop->flags |= add;
  prop->flags &= ~del;

  if (prop->flags == prev_flags)
    return;

  if (props)
    {
      tp_intset_add (props, prop_id);
    }
  else
    {
      TpIntSet *changed_props = tp_intset_sized_new (prop_id + 1);

      tp_intset_add (changed_props, prop_id);
      tp_properties_mixin_emit_flags (obj, changed_props);
      tp_intset_destroy (changed_props);
    }
}
コード例 #4
0
ファイル: media-channel.c プロジェクト: KDE/ktp-testlib
static void
example_callable_media_channel_close (ExampleCallableMediaChannel *self,
                                      TpHandle actor,
                                      TpChannelGroupChangeReason reason)
{
  if (self->priv->progress != PROGRESS_ENDED)
    {
      TpIntSet *everyone;

      self->priv->progress = PROGRESS_ENDED;

      if (actor == self->group.self_handle)
        {
          const gchar *send_reason;

          /* In a real protocol these would be some sort of real protocol
           * construct, like an XMPP error stanza or a SIP error code */
          switch (reason)
            {
            case TP_CHANNEL_GROUP_CHANGE_REASON_BUSY:
              send_reason = "<user-is-busy/>";
              break;

            case TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER:
              send_reason = "<no-answer/>";
              break;

            default:
              send_reason = "<call-terminated/>";
            }

          g_message ("SIGNALLING: send: Terminating call: %s", send_reason);
        }

      everyone = tp_intset_new_containing (self->priv->handle);
      tp_intset_add (everyone, self->group.self_handle);
      tp_group_mixin_change_members ((GObject *) self, "",
          NULL /* nobody added */,
          everyone /* removed */,
          NULL /* nobody locally pending */,
          NULL /* nobody remotely pending */,
          actor,
          reason);
      tp_intset_destroy (everyone);

      g_signal_emit (self, signals[SIGNAL_CALL_TERMINATED], 0);
      tp_svc_channel_emit_closed (self);
    }
}
コード例 #5
0
static gboolean
tp_base_media_call_stream_request_receiving (TpBaseCallStream *bcs,
    TpHandle contact,
    gboolean receive,
    GError **error)
{
  TpBaseMediaCallStream *self = TP_BASE_MEDIA_CALL_STREAM (bcs);
  TpBaseMediaCallStreamClass *klass =
      TP_BASE_MEDIA_CALL_STREAM_GET_CLASS (self);
  TpBaseCallChannel *channel = _tp_base_call_stream_get_channel (bcs);

  if (receive)
    {
      tp_base_call_stream_update_remote_sending_state (bcs, contact,
          TP_SENDING_STATE_PENDING_SEND,
          tp_base_channel_get_self_handle (TP_BASE_CHANNEL (channel)),
          TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "",
          "User asked the remote side to start sending");

      if (self->priv->receiving_state == TP_STREAM_FLOW_STATE_STARTED)
        {
          if (klass->request_receiving != NULL)
            {
              klass->request_receiving (self, contact, TRUE);
              return TRUE;
            }
        }

      tp_intset_add (self->priv->receiving_requests, contact);

      tp_base_media_call_stream_update_receiving_state (self);
    }
  else
    {
      tp_base_call_stream_update_remote_sending_state (bcs, contact,
          TP_SENDING_STATE_PENDING_STOP_SENDING,
          tp_base_channel_get_self_handle (TP_BASE_CHANNEL (channel)),
          TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "",
          "User asked the remote side to stop sending");

      tp_intset_remove (self->priv->receiving_requests, contact);

      if (klass->request_receiving != NULL)
        klass->request_receiving (self, contact, FALSE);
    }

  return TRUE;
}
コード例 #6
0
static gboolean
add_member (GObject *obj,
            TpHandle handle,
            const gchar *message,
            GError **error)
{
  TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (obj);
  TpIntSet *add = tp_intset_new ();

  tp_intset_add (add, handle);
  tp_group_mixin_change_members (obj, message, add, NULL, NULL, NULL,
      self->conn->self_handle, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
  tp_intset_destroy (add);

  return TRUE;
}
コード例 #7
0
static void
service_handles_fetched_cb (TpConnection *tp_conn,
    TpHandleType handle_type,
    guint n_handles,
    const TpHandle *handles,
    const gchar * const *ids,
    const GError *error,
    gpointer user_data G_GNUC_UNUSED,
    GObject *weak)
{
  guint i;
  McdConnection *connection = MCD_CONNECTION (weak);
  TpIntset *e_handles = tp_intset_new ();

  if (error != NULL)
    return;

  for (i = 0; i < n_handles; i++)
    tp_intset_add (e_handles, handles[i]);

  _mcd_connection_take_emergency_handles (connection, e_handles);
}
コード例 #8
0
ファイル: properties-mixin.c プロジェクト: psunkari/spicebird
/**
 * tp_properties_mixin_set_properties:
 * @obj: An object with this mixin
 * @properties: An array of D-Bus structures containing property ID and value
 * @context: A D-Bus method invocation context for the SetProperties method
 *
 * Start to change properties in response to user request via D-Bus.
 */
void
tp_properties_mixin_set_properties (GObject *obj,
                                    const GPtrArray *properties,
                                    DBusGMethodInvocation *context)
{
  TpPropertiesMixin *mixin = TP_PROPERTIES_MIXIN (obj);
  TpPropertiesMixinClass *mixin_cls = TP_PROPERTIES_MIXIN_CLASS (
                                            G_OBJECT_GET_CLASS (obj));
  TpPropertiesContext *ctx = &mixin->priv->context;
  GError *error = NULL;
  GType value_type = TP_STRUCT_TYPE_PROPERTY_VALUE;
  guint i;

  /* Is another SetProperties request already in progress? */
  if (ctx->dbus_ctx)
    {
      error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
                           "A SetProperties request is already in progress");
      dbus_g_method_return_error (context, error);
      g_error_free (error);
      return;
    }

  ctx->dbus_ctx = context;
  ctx->remaining = tp_intset_new ();
  error = NULL;

  if (properties->len == 0)
    {
      DEBUG ("immediately returning from SetProperties with 0 properties");
      tp_properties_context_return (ctx, NULL);
      return;
    }

  /* Check input property identifiers */
  for (i = 0; i < properties->len; i++)
    {
      GValue val_struct = { 0, };
      guint prop_id;
      GValue *prop_val;

      g_value_init (&val_struct, value_type);
      g_value_set_static_boxed (&val_struct,
          g_ptr_array_index (properties, i));

      dbus_g_type_struct_get (&val_struct,
          0, &prop_id,
          1, &prop_val,
          G_MAXUINT);

      /* Valid? */
      if (prop_id >= mixin_cls->num_props)
        {
          g_value_unset (prop_val);

          error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
                               "invalid property identifier %d", prop_id);
          goto ERROR;
        }

      /* Store the value in the context */
      tp_intset_add (ctx->remaining, prop_id);
      ctx->values[prop_id] = prop_val;

      /* Permitted? */
      if (!tp_properties_mixin_is_writable (obj, prop_id))
        {
          error = g_error_new (TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
                               "permission denied for property identifier %d",
                               prop_id);
          goto ERROR;
        }

      /* Compatible type? */
      if (!g_value_type_compatible (G_VALUE_TYPE (prop_val),
                                    mixin_cls->signatures[prop_id].type))
        {
          error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
                               "incompatible value type for property "
                               "identifier %d", prop_id);
          goto ERROR;
        }
    }

  if (mixin_cls->set_properties)
    {
      if (mixin_cls->set_properties (obj, ctx, &error))
        return;
    }
  else
    {
      tp_properties_context_return (ctx, NULL);
      return;
    }

ERROR:
  tp_properties_context_return (ctx, error);
}
void
mcd_dbus_activate_optional_interface (TpSvcDBusProperties *object,
                                      GType interface)
{
    tp_intset_add (get_active_optional_interfaces (object), interface);
}