From fc0d425711e8384019b9366e777d404013e0ef73 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Wed, 1 Apr 2020 18:13:28 +0900 Subject: [PATCH] seq: user_client: add an API to open ALSA Sequencer character device Signed-off-by: Takashi Sakamoto --- src/seq/alsaseq.map | 1 + src/seq/user-client.c | 71 +++++++++++++++++++++++++++++++++++++-- src/seq/user-client.h | 6 ++++ tests/alsaseq-user-client | 1 + 4 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index c68c921..c536a1f 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -31,6 +31,7 @@ ALSA_GOBJECT_0_0_0 { "alsaseq_user_client_get_type"; "alsaseq_user_client_new"; + "alsaseq_user_client_open"; local: *; }; diff --git a/src/seq/user-client.c b/src/seq/user-client.c index a74f2b6..15524dc 100644 --- a/src/seq/user-client.c +++ b/src/seq/user-client.c @@ -1,16 +1,45 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "user-client.h" +#include "query.h" +#include "privates.h" -G_DEFINE_TYPE(ALSASeqUserClient, alsaseq_user_client, G_TYPE_OBJECT) +#include +#include +#include +#include +#include +#include + +struct _ALSASeqUserClientPrivate { + int fd; + int client_id; +}; +G_DEFINE_TYPE_WITH_PRIVATE(ALSASeqUserClient, alsaseq_user_client, G_TYPE_OBJECT) + +static void seq_user_client_finalize(GObject *obj) +{ + ALSASeqUserClient *self = ALSASEQ_USER_CLIENT(obj); + ALSASeqUserClientPrivate *priv = + alsaseq_user_client_get_instance_private(self); + + if (priv->fd >= 0) + close(priv->fd); + + G_OBJECT_CLASS(alsaseq_user_client_parent_class)->finalize(obj); +} static void alsaseq_user_client_class_init(ALSASeqUserClientClass *klass) { - return; + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = seq_user_client_finalize; } static void alsaseq_user_client_init(ALSASeqUserClient *self) { - return; + ALSASeqUserClientPrivate *priv = + alsaseq_user_client_get_instance_private(self); + priv->fd = -1; } /** @@ -22,3 +51,39 @@ ALSASeqUserClient *alsaseq_user_client_new() { return g_object_new(ALSASEQ_TYPE_USER_CLIENT, NULL); } + +/** + * alsaseq_user_client_open: + * @self: A #ALSASeqUserClient. + * @open_flag: The flag of open(2) system call. O_RDWR is forced to fulfil internally. + * @error: A #GError. + * + * Open ALSA sequencer character device. + */ +void alsaseq_user_client_open(ALSASeqUserClient *self, gint open_flag, + GError **error) +{ + ALSASeqUserClientPrivate *priv; + char *devnode; + + g_return_if_fail(ALSASEQ_IS_USER_CLIENT(self)); + priv = alsaseq_user_client_get_instance_private(self); + + alsaseq_get_seq_devnode(&devnode, error); + if (*error != NULL) + return; + + open_flag |= O_RDWR; + priv->fd = open(devnode, open_flag); + g_free(devnode); + if (priv->fd < 0) { + generate_error(error, errno); + return; + } + + if (ioctl(priv->fd, SNDRV_SEQ_IOCTL_CLIENT_ID, &priv->client_id) < 0) { + generate_error(error, errno); + close(priv->fd); + priv->fd = -1; + } +} diff --git a/src/seq/user-client.h b/src/seq/user-client.h index 3d94bf4..1746c61 100644 --- a/src/seq/user-client.h +++ b/src/seq/user-client.h @@ -31,9 +31,12 @@ G_BEGIN_DECLS typedef struct _ALSASeqUserClient ALSASeqUserClient; typedef struct _ALSASeqUserClientClass ALSASeqUserClientClass; +typedef struct _ALSASeqUserClientPrivate ALSASeqUserClientPrivate; struct _ALSASeqUserClient { GObject parent_instance; + + ALSASeqUserClientPrivate *priv; }; struct _ALSASeqUserClientClass { @@ -44,6 +47,9 @@ GType alsaseq_user_client_get_type() G_GNUC_CONST; ALSASeqUserClient *alsaseq_user_client_new(); +void alsaseq_user_client_open(ALSASeqUserClient *self, gint open_flag, + GError **error); + G_END_DECLS #endif diff --git a/tests/alsaseq-user-client b/tests/alsaseq-user-client index d1dc621..e5098bd 100644 --- a/tests/alsaseq-user-client +++ b/tests/alsaseq-user-client @@ -13,6 +13,7 @@ target = ALSASeq.UserClient() props = () methods = ( 'new', + 'open', ) signals = () -- 2.47.3