Preliminary documentation of provider interfaces

* Preliminary documentation of CallsCall and CallsMessageSource
* Documentation and cleaning up of CallsCallData
* Add data files and meson rules to create gtk-doc documentation
* Move some macros from util.h to calls-message-source.h
This commit is contained in:
Bob Ham 2018-05-23 09:52:58 +01:00
parent 5abe9cad4e
commit e81567786c
16 changed files with 325 additions and 120 deletions

View File

@ -10,7 +10,7 @@
<shortdesc>A phone call dialer</shortdesc>
<description>Calls is a dialer for phone calls, initially PSTN calls
but eventually other systems like SIP in future.</description>
<homepage rdf:resource="https://gitlab.gnome.org/Community/Purism/calls" />
<homepage rdf:resource="https://code.puri.sm/Librem5/calls" />
<license rdf:resource="http://usefulinc.com/doap/licenses/gpl" />
<programming-language>C</programming-language>

38
doc/calls-docs.xml Normal file
View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY % gtkdocentities SYSTEM "xml/gtkdocentities.ent">
%gtkdocentities;
]>
<book id="index">
<bookinfo>
<title>&package_name; Reference Manual</title>
<releaseinfo>
<para>This document is the API reference for &package_name; &package_version;</para>
<para>
<ulink type="http" url="&package_url;">Calls</ulink> is a dialer program for telephony calls.
</para>
<para>
If you find any issues in this API reference, please report it
using <ulink type="http" url="&package_bugreport;">at the
bugtracker</ulink>
</para>
</releaseinfo>
<copyright>
<year>2018</year>
<holder>Purism SPC</holder>
</copyright>
</bookinfo>
<chapter id="provider-abstraction">
<title>Provider abstraction</title>
<xi:include href="xml/calls-message-source.xml"/>
<xi:include href="xml/calls-provider.xml"/>
<xi:include href="xml/calls-origin.xml"/>
<xi:include href="xml/calls-call.xml"/>
</chapter>
</book>

31
doc/meson.build Normal file
View File

@ -0,0 +1,31 @@
if get_option('gtk_doc')
subdir('xml')
glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
gnome.gtkdoc('calls',
main_xml: 'calls-docs.xml',
src_dir: [
join_paths(meson.source_root(), 'src'),
join_paths(meson.build_root(), 'src'),
join_paths(meson.build_root(), 'libgdbofono'),
],
dependencies: calls_deps,
scan_args: [
'--rebuild-types',
],
fixxref_args: [
'--html-dir=@0@'.format(docpath),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gio')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gi')),
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'gtk3')),
],
install_dir: 'calls',
install: true)
endif

View File

@ -0,0 +1,7 @@
<!ENTITY package "@PACKAGE@">
<!ENTITY package_bugreport "@PACKAGE_BUGREPORT@">
<!ENTITY package_name "@PACKAGE_NAME@">
<!ENTITY package_string "@PACKAGE_STRING@">
<!ENTITY package_tarname "@PACKAGE_TARNAME@">
<!ENTITY package_url "@PACKAGE_URL@">
<!ENTITY package_version "@PACKAGE_VERSION@">

9
doc/xml/meson.build Normal file
View File

@ -0,0 +1,9 @@
ent_conf = configuration_data()
ent_conf.set('PACKAGE', 'Calls')
ent_conf.set('PACKAGE_BUGREPORT', 'https://code.puri.sm/Librem5/calls/issues')
ent_conf.set('PACKAGE_NAME', 'Calls')
ent_conf.set('PACKAGE_STRING', 'calls')
ent_conf.set('PACKAGE_TARNAME', 'calls-' + meson.project_version())
ent_conf.set('PACKAGE_URL', 'https://code.puri.sm/Librem5/calls')
ent_conf.set('PACKAGE_VERSION', meson.project_version())
configure_file(input: 'gtkdocentities.ent.in', output: 'gtkdocentities.ent', configuration: ent_conf)

View File

@ -29,3 +29,4 @@ project('call', 'c',
subdir('libgdbofono')
subdir('src')
subdir('doc')

3
meson_options.txt Normal file
View File

@ -0,0 +1,3 @@
option('gtk_doc',
type: 'boolean', value: false,
description: 'Whether to generate the API reference for Calls')

View File

@ -31,7 +31,9 @@
/**
* SECTION:calls-call-data
* @short_description: An object to hold both a #CallsCall object and
* the #CallsParty participating in the call
* the #CallsParty participating in the call. These data are passed
* to both #CallsCallDisplay and #CallsCallSelectorItem so we create a
* convenient object to keep them together.
* @Title: CallsCallData
*/
@ -54,52 +56,9 @@ enum {
static GParamSpec *props[PROP_LAST_PROP];
CallsCallData *
calls_call_data_new (CallsCall *call, CallsParty *party)
{
return g_object_new (CALLS_TYPE_CALL_DATA,
"call", call,
"party", party,
NULL);
}
CallsCall *
calls_call_data_get_call (CallsCallData *data)
{
g_return_val_if_fail (CALLS_IS_CALL_DATA (data), NULL);
return data->call;
}
CallsParty *
calls_call_data_get_party (CallsCallData *data)
{
g_return_val_if_fail (CALLS_IS_CALL_DATA (data), NULL);
return data->party;
}
static void
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
calls_call_data_init (CallsCallData *self)
{
CallsCallData *self = CALLS_CALL_DATA (object);
switch (property_id) {
case PROP_CALL:
g_value_set_object (value, self->call);
break;
case PROP_PARTY:
g_value_set_object (value, self->party);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
@ -128,8 +87,26 @@ set_property (GObject *object,
static void
calls_call_data_init (CallsCallData *self)
get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
CallsCallData *self = CALLS_CALL_DATA (object);
switch (property_id) {
case PROP_CALL:
g_value_set_object (value, self->call);
break;
case PROP_PARTY:
g_value_set_object (value, self->party);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
@ -151,8 +128,8 @@ calls_call_data_class_init (CallsCallDataClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
props[PROP_CALL] =
@ -171,3 +148,53 @@ calls_call_data_class_init (CallsCallDataClass *klass)
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
/**
* calls_call_data_new:
*
* Create a new #CallsCallData object.
*
* Returns: the newly created #CallsCallData
*/
CallsCallData *
calls_call_data_new (CallsCall *call,
CallsParty *party)
{
return g_object_new (CALLS_TYPE_CALL_DATA,
"call", call,
"party", party,
NULL);
}
/**
* calls_call_data_get_call:
* @self: a #CallsCallData
*
* Get the #CallsCall stored in the object.
*
* Returns: the #CallsCall
*/
CallsCall *
calls_call_data_get_call (CallsCallData *self)
{
g_return_val_if_fail (CALLS_IS_CALL_DATA (self), NULL);
return self->call;
}
/**
* calls_call_data_get_party:
* @self: a #CallsCallData
*
* Get the #CallsParty stored in the object.
*
* Returns: the #CallsParty
*/
CallsParty *
calls_call_data_get_party (CallsCallData *self)
{
g_return_val_if_fail (CALLS_IS_CALL_DATA (self), NULL);
return self->party;
}

View File

@ -34,9 +34,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CallsCallData, calls_call_data, CALLS, CALL_DATA, GObject);
CallsCallData *calls_call_data_new (CallsCall *call, CallsParty *party);
CallsCall *calls_call_data_get_call (CallsCallData *data);
CallsParty *calls_call_data_get_party (CallsCallData *data);
CallsCallData *calls_call_data_new (CallsCall *call,
CallsParty *party);
CallsCall *calls_call_data_get_call (CallsCallData *data);
CallsParty *calls_call_data_get_party (CallsCallData *data);
G_END_DECLS

View File

@ -29,8 +29,8 @@
void
calls_call_state_to_string (GString *string,
CallsCallState state)
calls_call_state_to_string (GString *string,
CallsCallState state)
{
GEnumClass *klass;
GEnumValue *value;
@ -78,6 +78,15 @@ calls_call_state_parse_nick (CallsCallState *state,
* SECTION:calls-call
* @short_description: A call.
* @Title: CallsCall
*
* This is the interface to a call. It has a number, name and a
* state. Only the state changes after creation. If the state is
* #CALL_CALL_STATE_INCOMING, the call can be answered with #answer.
* The call can also be hung up at any time with #hang_up.
*
* DTMF tones can be played the call using #tone_start and
* #tone_stop. Valid characters for the key are 0-9, '*', '#', 'A',
* 'B', 'C' and 'D'.
*/
@ -89,11 +98,20 @@ enum {
};
static guint signals [SIGNAL_LAST_SIGNAL];
static void
calls_call_default_init (CallsCallInterface *iface)
{
GType arg_types = CALLS_TYPE_CALL_STATE;
/**
* CallsCall::state-changed:
* @self: The #CallsCall instance.
* @state: The new state of the call.
*
* This signal is emitted when the state of the call changes, for
* example when it's answered or when the call is disconnected.
*/
signals[SIGNAL_STATE_CHANGED] =
g_signal_newv ("state-changed",
G_TYPE_FROM_INTERFACE (iface),
@ -112,20 +130,55 @@ calls_call_default_init (CallsCallInterface *iface)
CALLS_DEFINE_IFACE_FUNC_VOID(call, Call, CALL, function)
/**
* calls_call_get_number:
* @self: a #CallsCall
*
* Get the number the call is connected to. It is possible that this
* could return NULL if the number is not known, for example if an
* incoming PTSN call has no caller ID information.
*
* Returns: the number, or NULL
*/
DEFINE_CALL_FUNC(get_number, const gchar *, NULL);
/**
* calls_call_get_name:
* @self: a #CallsCall
*
* Get the name of the party the call is connected to, if the network
* provides it.
*
* Returns: the number, or NULL
*/
DEFINE_CALL_FUNC(get_name, const gchar *, NULL);
/**
* calls_call_get_state:
* @self: a #CallsCall
*
* Get the current state of the call
* Get the current state of the call.
*
* Returns: the state
*/
DEFINE_CALL_FUNC(get_state, CallsCallState, ((CallsCallState)0));
/**
* calls_call_answer:
* @self: a #CallsCall
*
* If the call is incoming, answer it.
*
*/
DEFINE_CALL_FUNC_VOID(answer);
/**
* calls_call_hang_up:
* @self: a #CallsCall
*
* Hang up the call.
*
*/
DEFINE_CALL_FUNC_VOID(hang_up);
@ -155,5 +208,25 @@ tone_key_is_valid (gchar key)
return iface->tone_##which (self, key); \
}
/**
* calls_call_tone_start:
* @self: a #CallsCall
* @key: which tone to start
*
* Start playing a DTMF tone for the specified key. Implementations
* will stop playing the tone either after an implementation-specific
* timeout, or after #calls_call_tone_stop is called with the same
* value for @key.
*
*/
DEFINE_CALL_TONE_FUNC (start);
/**
* calls_call_tone_stop:
* @self: a #CallsCall
* @key: which tone to stop
*
* Stop playing a DTMF tone previously started with #calls_call_tone_start.
*
*/
DEFINE_CALL_TONE_FUNC (stop);

View File

@ -44,8 +44,8 @@ typedef enum
CALLS_CALL_STATE_DISCONNECTED
} CallsCallState;
void calls_call_state_to_string (GString *string,
CallsCallState state);
void calls_call_state_to_string (GString *string,
CallsCallState state);
gboolean calls_call_state_parse_nick (CallsCallState *state,
const gchar *nick);
@ -53,23 +53,28 @@ struct _CallsCallInterface
{
GTypeInterface parent_iface;
const gchar * (*get_number) (CallsCall *self);
const gchar * (*get_name) (CallsCall *self);
CallsCallState (*get_state) (CallsCall *self);
void (*answer) (CallsCall *self);
void (*hang_up) (CallsCall *self);
void (*tone_start) (CallsCall *self, gchar key);
void (*tone_stop) (CallsCall *self, gchar key);
const gchar * (*get_number) (CallsCall *self);
const gchar * (*get_name) (CallsCall *self);
CallsCallState (*get_state) (CallsCall *self);
void (*answer) (CallsCall *self);
void (*hang_up) (CallsCall *self);
void (*tone_start) (CallsCall *self,
gchar key);
void (*tone_stop) (CallsCall *self,
gchar key);
};
const gchar * calls_call_get_number (CallsCall *self);
const gchar * calls_call_get_name (CallsCall *self);
CallsCallState calls_call_get_state (CallsCall *self);
void calls_call_answer (CallsCall *self);
void calls_call_hang_up (CallsCall *self);
void calls_call_tone_start (CallsCall *self, gchar key);
void calls_call_tone_stop (CallsCall *self, gchar key);
const gchar * calls_call_get_number (CallsCall *self);
const gchar * calls_call_get_name (CallsCall *self);
CallsCallState calls_call_get_state (CallsCall *self);
void calls_call_answer (CallsCall *self);
void calls_call_hang_up (CallsCall *self);
void calls_call_tone_start (CallsCall *self,
gchar key);
void calls_call_tone_stop (CallsCall *self,
gchar key);
G_END_DECLS

View File

@ -24,6 +24,15 @@
#include "calls-message-source.h"
/**
* SECTION:calls-message-source
* @short_description: A source of messages for the user.
* @Title: CallsMessageSource
*
* All three of the main interfaces, #CallsProvider, #CallsOrigin and
* #CallsCall require #CallsMessageSource. They use this interface's
* message signal to emit messages intended for display to the user.
*/
G_DEFINE_INTERFACE (CallsMessageSource, calls_message_source, G_TYPE_OBJECT);
@ -37,29 +46,23 @@ static guint signals [SIGNAL_LAST_SIGNAL];
static void
calls_message_source_default_init (CallsMessageSourceInterface *iface)
{
GType arg_types[2] = { G_TYPE_STRING, GTK_TYPE_MESSAGE_TYPE };
/**
* CallsMessageSource::message:
* @self: The #CallsMessageSource instance.
* @text: The message text.
* @type: The type of the message; error, warning, etc.
*
* This signal is emitted when an implementing-object needs to emit
* a message to the user. The message should be suitable for
* presentation to the user as-is.
*/
signals[SIGNAL_MESSAGE] =
g_signal_newv ("message",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
NULL, NULL, NULL, NULL,
G_TYPE_NONE,
2, calls_message_signal_arg_types());
}
GType *
calls_message_signal_arg_types()
{
static gsize initialization_value = 0;
static GType arg_types[2];
if (g_once_init_enter (&initialization_value))
{
arg_types[0] = G_TYPE_STRING;
arg_types[1] = GTK_TYPE_MESSAGE_TYPE;
g_once_init_leave (&initialization_value, 1);
}
return arg_types;
2, arg_types);
}

View File

@ -40,11 +40,38 @@ struct _CallsMessageSourceInterface
GTypeInterface parent_iface;
};
#define CALLS_ERROR(obj,error) \
CALLS_EMIT_ERROR (CALLS_MESSAGE_SOURCE (obj), error)
/** Array of GTypes for message signals */
GType * calls_message_signal_arg_types();
/**
* CALLS_EMIT_MESSAGE:
* @obj: an object which can be cast to a #CallsMesssageSource
* @text: the message text as a string
* @type: the type of the message
*
* Emit a message signal with the specified information. This is a
* convenience macro for objects implementing interfaces that
* require #CallsMessageSource.
*
*/
#define CALLS_EMIT_MESSAGE(obj,text,type) \
g_signal_emit_by_name (CALLS_MESSAGE_SOURCE(obj), \
"message", text, type)
/**
* CALLS_ERROR:
* @obj: an object which can be cast to a #CallsMesssageSource
* @error: a pointer to a #GError containing the error message
*
* Emit a message signal with an error type, the text of which is
* contained as the message in a #GError. This is a convenience
* macro for objects implementing interfaces that require
* #CallsMessageSource.
*
*/
#define CALLS_ERROR(obj,error) \
CALLS_EMIT_MESSAGE (obj, error->message, GTK_MESSAGE_ERROR)
G_END_DECLS

View File

@ -177,10 +177,8 @@ set_properties (CallsOfonoCall *self,
g_variant_lookup (props, "Name", "s", &self->name);
g_variant_lookup (props, "State", "&s", &str);
if (str)
{
calls_call_state_parse_nick (&self->state, str);
}
g_return_if_fail (str != NULL);
calls_call_state_parse_nick (&self->state, str);
}

View File

@ -23,19 +23,10 @@
gnome = import('gnome')
#libgd = subproject('libgd',
# default_options: [
# 'with-main-box=true'
# ]
#)
#libgd_dep = libgd.get_variable('libgd_dep')
deps = [ dependency('gobject-2.0'),
dependency('gtk+-3.0'),
dependency('libhandy-0.0'),
# libgd.get_variable('libgd_dep')
]
calls_deps = [ dependency('gobject-2.0'),
dependency('gtk+-3.0'),
dependency('libhandy-0.0'),
]
enum_headers = ['calls-call.h']
sources = ['calls-message-source.c', 'calls-message-source.h',
@ -64,9 +55,7 @@ calls_resources = gnome.compile_resources(
c_name: 'call',
)
# Pass as dependency to another target
executable('calls', sources, enum_sources, calls_resources,
dependencies : deps,
dependencies : calls_deps,
link_with : gdbofono_lib,
include_directories : include_directories('..'))

View File

@ -99,13 +99,6 @@ G_BEGIN_DECLS
ptr = new_value;
#define CALLS_EMIT_MESSAGE(obj,text,type) \
g_signal_emit_by_name (obj, "message", text, type)
#define CALLS_EMIT_ERROR(obj,error) \
CALLS_EMIT_MESSAGE (obj, error->message, GTK_MESSAGE_ERROR)
/** Find a particular pointer value in a GtkListStore */
gboolean
calls_list_store_find (GtkListStore *store,