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 (¶mspec[i], value, set_param, params, error)) { return FALSE; } tp_intset_add (params_present, i); g_hash_table_remove (provided, paramspec[i].name); } } return TRUE; }
/** * 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); } }
/** * 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); } }
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); } }
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; }
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; }
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); }
/** * 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); }