]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
seq: tstamp: use wrapper structure instead of union
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 13 Apr 2020 06:28:27 +0000 (15:28 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Mon, 13 Apr 2020 11:45:01 +0000 (20:45 +0900)
In UAPI for ALSA Sequencer, snd_seq_timestamp is union with
snd_seq_tick_time_t and struct snd_seq_real_time types. The
libalsaseq has GLib Boxed object for the union, named as
ALSASeqTstamp.

```
$ cat build/src/seq/ALSASeq-0.0.gir
    ...
    <union name="Tstamp"
           c:type="ALSASeqTstamp"
           glib:type-name="ALSASeqTstamp"
           glib:get-type="alsaseq_tstamp_get_type"
           c:symbol-prefix="tstamp">
      <source-position filename="../src/seq/tstamp.h" line="14"/>
      ...
    </union>
    ...
```

Although this is valid in a view of GObject
Introspection, it's not nesessarily convenient to language
bindings because some programming language doesn't support
union type. In this case, the type is not available.

This commit adds an alternative structure to wrap the union.
As a result, ALSASeqTstamp is GLib Boxed object for the
wrapper structure.

```
$ cat build/src/seq/ALSASeq-0.0.gir
    ...
    <record name="Tstamp"
            c:type="ALSASeqTstamp"
            glib:type-name="ALSASeqTstamp"
            glib:get-type="alsaseq_tstamp_get_type"
            c:symbol-prefix="tstamp">
      <source-position filename="../src/seq/tstamp.h" line="18"/>
      <field name="tstamp" writable="1">
        <type name="gpointer" c:type="snd_seq_timestamp"/>
      </field>
      ...
    </record>
    ...
```

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/seq/event-data-queue.c
src/seq/event-fixed.c
src/seq/event.c
src/seq/tstamp.c
src/seq/tstamp.h

index 477593ffc97870ed65e36b517955abe30e2486d7..87c9a18f5cb646df40f4ac41513735ac1df672eb 100644 (file)
@@ -70,7 +70,9 @@ void alsaseq_event_data_queue_set_value_param(ALSASeqEventDataQueue *self,
 void alsaseq_event_data_queue_get_tstamp_param(ALSASeqEventDataQueue *self,
                                                const ALSASeqTstamp **tstamp)
 {
-    *tstamp = &self->param.time;
+    // MEMO: I wish the structure has no padding in its head in all of supported
+    // ABIs.
+    *tstamp = (const ALSASeqTstamp *)&self->param.time;
 }
 
 /**
@@ -83,7 +85,7 @@ void alsaseq_event_data_queue_get_tstamp_param(ALSASeqEventDataQueue *self,
 void alsaseq_event_data_queue_set_tstamp_param(ALSASeqEventDataQueue *self,
                                                const ALSASeqTstamp *tstamp)
 {
-    self->param.time = *tstamp;
+    self->param.time = tstamp->tstamp;
 }
 
 /**
index da285eb8b87ac088cc3c34184b957421967d3f57..63ddbfd61f4268914de433e152650f50f059a4c8 100644 (file)
@@ -72,7 +72,7 @@ static void seq_event_fixed_set_property(GObject *obj, guint id,
     {
         ALSASeqTstamp *data = g_value_get_boxed(val);
         if (data != NULL)
-            ev->data.time = *data;
+            ev->data.time = data->tstamp;
         break;
     }
     default:
@@ -108,7 +108,9 @@ static void seq_event_fixed_get_property(GObject *obj, guint id, GValue *val,
         g_value_set_static_boxed(val, &ev->data.connect);
         break;
     case SEQ_EVENT_FIXED_PROP_TSTAMP_DATA:
-        g_value_set_static_boxed(val, &ev->data.time);
+        // MEMO: I wish the structure has no padding in its head in all of
+       // supported ABIs.
+        g_value_set_static_boxed(val, (ALSASeqTstamp *)&ev->data.time);
         break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec);
index dd4958405abd1c6359a2b6a9d40e91484296d2e8..f4ea612f7df220ce4d30706bf0cfc051634568ef 100644 (file)
@@ -60,7 +60,7 @@ static void seq_event_set_property(GObject *obj, guint id, const GValue *val,
     {
         ALSASeqTstamp *tstamp = g_value_get_boxed(val);
         if (tstamp != NULL)
-            ev->time = *tstamp;
+            ev->time = tstamp->tstamp;
         break;
     }
     case SEQ_EVENT_PROP_SRC_ADDR:
@@ -129,7 +129,9 @@ static void seq_event_get_property(GObject *obj, guint id, GValue *val,
         g_value_set_uchar(val, ev->queue);
         break;
     case SEQ_EVENT_PROP_TSTAMP:
-        g_value_set_static_boxed(val, &ev->time);
+        // MEMO: I wish the structure has no padding in its head in all of
+       // supported ABIs.
+        g_value_set_static_boxed(val, (ALSASeqTstamp *)&ev->time);
         break;
     case SEQ_EVENT_PROP_SRC_ADDR:
         g_value_set_static_boxed(val, &ev->source);
index f0ceb4bd3a2bd2617981dad832a75c3606e61155..788c5df595230758a47e6887e307d881f983146b 100644 (file)
@@ -17,7 +17,7 @@ G_DEFINE_BOXED_TYPE(ALSASeqTstamp, alsaseq_tstamp, seq_tstamp_copy, g_free)
  */
 void alsaseq_tstamp_get_tick_time(ALSASeqTstamp *self, guint32 *tick_time)
 {
-    *tick_time = self->tick;
+    *tick_time = self->tstamp.tick;
 }
 
 /**
@@ -29,7 +29,7 @@ void alsaseq_tstamp_get_tick_time(ALSASeqTstamp *self, guint32 *tick_time)
  */
 void alsaseq_tstamp_set_tick_time(ALSASeqTstamp *self, const guint32 tick_time)
 {
-    self->tick = tick_time;
+    self->tstamp.tick = tick_time;
 }
 
 /**
@@ -44,7 +44,7 @@ void alsaseq_tstamp_get_real_time(ALSASeqTstamp *self, const guint32 **tstamp)
 {
     // MEMO: I wish 32-bit storage size is aligned to 32 bit offset in all of
     // supported ABIs.
-    *tstamp = (guint32 *)&self->time;
+    *tstamp = (guint32 *)&self->tstamp.time;
 }
 
 
@@ -58,6 +58,6 @@ void alsaseq_tstamp_get_real_time(ALSASeqTstamp *self, const guint32 **tstamp)
  */
 void alsaseq_tstamp_set_real_time(ALSASeqTstamp *self, const guint32 tstamp[2])
 {
-    self->time.tv_sec = tstamp[0];
-    self->time.tv_nsec = tstamp[1];
+    self->tstamp.time.tv_sec = tstamp[0];
+    self->tstamp.time.tv_nsec = tstamp[1];
 }
index 48e8e173f415b6e5bb64d32df488e7f10f6555fb..d51e2788cd685c62abc2c5c9ed0ab62939272fd8 100644 (file)
@@ -11,7 +11,11 @@ G_BEGIN_DECLS
 
 #define ALSASEQ_TYPE_TSTAMP   (alsaseq_tstamp_get_type())
 
-typedef union snd_seq_timestamp ALSASeqTstamp;
+// The usage of union is inconvenient to some programming languages which has
+// no support to handle it. Let's use wrapper structure.
+typedef struct {
+    union snd_seq_timestamp time;
+} ALSASeqTstamp;
 
 GType alsaseq_tstamp_get_type() G_GNUC_CONST;