]> git.alsa-project.org Git - alsa-utils.git/commitdiff
aconnect: Add UMP support
authorTakashi Iwai <tiwai@suse.de>
Wed, 22 Mar 2023 07:45:54 +0000 (08:45 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 6 Jun 2023 13:44:57 +0000 (15:44 +0200)
This patch extends the aconnect program for supporting UMP.
Now the verbose output can show the UMP client version.

Also, a new option -a is added to control the behavior whether to show
the all ports including the inactive ports or not.  As default, only
the active ports are shown, but UMP clients allow to hide some ports
as inactive.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
seq/aconnect/aconnect.1
seq/aconnect/aconnect.c

index 2050187a33629df9fe1f241ac3ad5585bd29dcb1..5c015196f19ccb2245695ac5d71a66013f1bcbfd 100644 (file)
@@ -120,6 +120,9 @@ List existing output (writable) ports.
 This option is exclusive to
 .B \-i.
 .TP
+.B \-a, \-\-all
+List inactive ports, too.
+.TP
 .B \-l, \-\-list
 List the current connection status.  The connected and connecting ports
 from/to each port are listed together.
index 85a7770156aa4ab431553a1a05368d6304cc0487..582b454c2c2261797e64564eefc8b95f917e7f76 100644 (file)
 #include "aconfig.h"
 #include "gettext.h"
 
+#ifdef SND_SEQ_PORT_CAP_INACTIVE
+#define HANDLE_SHOW_ALL
+static int show_all;
+#else
+#define show_all 0
+#endif
+
 static void error_handler(const char *file, int line, const char *function, int err, const char *fmt, ...)
 {
        va_list arg;
@@ -60,6 +67,9 @@ static void usage(void)
        printf(_("   aconnect -i|-o [-options]\n"));
        printf(_("     -i,--input          list input (readable) ports\n"));
        printf(_("     -o,--output         list output (writable) ports\n"));
+#ifdef HANDLE_SHOW_ALL
+       printf(_("     -a,--all            show inactive ports, too\n"));
+#endif
        printf(_("     -l,--list           list current connections of each port\n"));
        printf(_(" * Remove all exported connections\n"));
        printf(_("     -x, --removeall\n"));
@@ -72,25 +82,38 @@ static void usage(void)
 #define LIST_INPUT     1
 #define LIST_OUTPUT    2
 
-#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
+#define perm_ok(cap,bits) (((cap) & (bits)) == (bits))
+
+#ifdef SND_SEQ_PORT_DIR_INPUT
+static int check_direction(snd_seq_port_info_t *pinfo, int bit)
+{
+       int dir = snd_seq_port_info_get_direction(pinfo);
+       return !dir || (dir & bit);
+}
+#else
+#define check_direction(x, y)  1
+#endif
 
 static int check_permission(snd_seq_port_info_t *pinfo, int perm)
 {
-       if (perm) {
-               if (perm & LIST_INPUT) {
-                       if (perm_ok(pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ))
-                               goto __ok;
-               }
-               if (perm & LIST_OUTPUT) {
-                       if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE))
-                               goto __ok;
-               }
+       int cap = snd_seq_port_info_get_capability(pinfo);
+
+       if (cap & SND_SEQ_PORT_CAP_NO_EXPORT)
                return 0;
+
+       if (!perm)
+               return 1;
+       if (perm & LIST_INPUT) {
+               if (perm_ok(cap, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ) &&
+                   check_direction(pinfo, SND_SEQ_PORT_DIR_INPUT))
+                       return 1;
        }
- __ok:
-       if (snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)
-               return 0;
-       return 1;
+       if (perm & LIST_OUTPUT) {
+               if (perm_ok(cap, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE) &&
+                   check_direction(pinfo, SND_SEQ_PORT_DIR_OUTPUT))
+                       return 1;
+       }
+       return 0;
 }
 
 /*
@@ -151,12 +174,20 @@ static void do_search_port(snd_seq_t *seq, int perm, action_func_t do_action)
                /* reset query info */
                snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
                snd_seq_port_info_set_port(pinfo, -1);
+#ifdef HANDLE_SHOW_ALL
+               if (show_all)
+                       snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_INACTIVE);
+#endif
                count = 0;
                while (snd_seq_query_next_port(seq, pinfo) >= 0) {
                        if (check_permission(pinfo, perm)) {
                                do_action(seq, cinfo, pinfo, count);
                                count++;
                        }
+#ifdef HANDLE_SHOW_ALL
+                       if (show_all)
+                               snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_INACTIVE);
+#endif
                }
        }
 }
@@ -173,7 +204,20 @@ static void print_port(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
                       snd_seq_client_info_get_name(cinfo),
                       (snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ?
                        _("user") : _("kernel")));
-
+#ifdef HAVE_SEQ_CLIENT_INFO_GET_MIDI_VERSION
+               switch (snd_seq_client_info_get_midi_version(cinfo)) {
+               case SND_SEQ_CLIENT_UMP_MIDI_1_0:
+                       printf(",UMP-MIDI1");
+                       break;
+               case SND_SEQ_CLIENT_UMP_MIDI_2_0:
+                       printf(",UMP-MIDI2");
+                       break;
+               }
+#endif
+#ifdef HANDLE_SHOW_ALL
+               if (snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_INACTIVE)
+                       printf(",INACTIVE");
+#endif
 #ifdef HAVE_SEQ_CLIENT_INFO_GET_CARD
                card = snd_seq_client_info_get_card(cinfo);
 #endif
@@ -251,6 +295,12 @@ enum {
        SUBSCRIBE, UNSUBSCRIBE, LIST, REMOVE_ALL
 };
 
+#ifdef HANDLE_SHOW_ALL
+#define ACONNECT_OPTS "dior:t:elxa"
+#else
+#define ACONNECT_OPTS "dior:t:elx"
+#endif
+
 static const struct option long_option[] = {
        {"disconnect", 0, NULL, 'd'},
        {"input", 0, NULL, 'i'},
@@ -260,6 +310,9 @@ static const struct option long_option[] = {
        {"exclusive", 0, NULL, 'e'},
        {"list", 0, NULL, 'l'},
        {"removeall", 0, NULL, 'x'},
+#ifdef HANDLE_SHOW_ALL
+       {"all", 0, NULL, 'a'},
+#endif
        {NULL, 0, NULL, 0},
 };
 
@@ -280,7 +333,7 @@ int main(int argc, char **argv)
        textdomain(PACKAGE);
 #endif
 
-       while ((c = getopt_long(argc, argv, "dior:t:elx", long_option, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, ACONNECT_OPTS, long_option, NULL)) != -1) {
                switch (c) {
                case 'd':
                        command = UNSUBSCRIBE;
@@ -313,6 +366,12 @@ int main(int argc, char **argv)
                case 'x':
                        command = REMOVE_ALL;
                        break;
+#ifdef HANDLE_SHOW_ALL
+               case 'a':
+                       command = LIST;
+                       show_all = 1;
+                       break;
+#endif
                default:
                        usage();
                        exit(1);