src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.c
changeset 49289 148e29df1644
parent 47216 71c04702a3d5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.c	Fri Mar 23 09:51:02 2018 +0100
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#define USE_ERROR
+#define USE_TRACE
+
+#include "PLATFORM_API_SolarisOS_Utils.h"
+
+#define MAX_AUDIO_DEVICES 20
+
+// not thread safe...
+static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES];
+static int globalADCount = -1;
+static int globalADCacheTime = -1;
+/* how many seconds do we cache devices */
+#define AD_CACHE_TIME 30
+
+// return seconds
+long getTimeInSeconds() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec;
+}
+
+
+int getAudioDeviceCount() {
+    int count = MAX_AUDIO_DEVICES;
+
+    getAudioDevices(globalADPaths, &count);
+    return count;
+}
+
+/* returns TRUE if the path exists at all */
+int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) {
+    int i;
+    int found = 0;
+    int fileExists = 0;
+    // not thread safe...
+    static struct stat statBuf;
+
+    // get stats on the file
+    if (stat(path, &statBuf) == 0) {
+        // file exists.
+        fileExists = 1;
+        // If it is not yet in the adPath array, add it to the array
+        for (i = 0; i < *count; i++) {
+            if (adPath[i].st_ino == statBuf.st_ino
+                && adPath[i].st_dev == statBuf.st_dev) {
+                found = 1;
+                break;
+            }
+        }
+        if (!found) {
+            adPath[*count].st_ino = statBuf.st_ino;
+            adPath[*count].st_dev = statBuf.st_dev;
+            strncpy(adPath[*count].path, path, MAX_NAME_LENGTH);
+            adPath[*count].path[MAX_NAME_LENGTH - 1] = 0;
+            (*count)++;
+            TRACE1("Added audio device %s\n", path);
+        }
+    }
+    return fileExists;
+}
+
+
+void getAudioDevices(AudioDevicePath* adPath, int* count) {
+    int maxCount = *count;
+    char* audiodev;
+    char devsound[15];
+    int i;
+    long timeInSeconds = getTimeInSeconds();
+
+    if (globalADCount < 0
+        || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME
+        || (adPath != globalADPaths)) {
+        *count = 0;
+        // first device, if set, is AUDIODEV variable
+        audiodev = getenv("AUDIODEV");
+        if (audiodev != NULL && audiodev[0] != 0) {
+            addAudioDevice(audiodev, adPath, count);
+        }
+        // then try /dev/audio
+        addAudioDevice("/dev/audio", adPath, count);
+        // then go through all of the /dev/sound/? devices
+        for (i = 0; i < 100; i++) {
+            sprintf(devsound, "/dev/sound/%d", i);
+            if (!addAudioDevice(devsound, adPath, count)) {
+                break;
+            }
+        }
+        if (adPath == globalADPaths) {
+            /* commit cache */
+            globalADCount = *count;
+            /* set cache time */
+            globalADCacheTime = timeInSeconds;
+        }
+    } else {
+        /* return cache */
+        *count = globalADCount;
+    }
+    // that's it
+}
+
+int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) {
+    int count = MAX_AUDIO_DEVICES;
+    int ret = 0;
+
+    getAudioDevices(globalADPaths, &count);
+    if (index>=0 && index < count) {
+        ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames);
+    }
+    return ret;
+}
+
+int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) {
+    int fd;
+    int mixerMode;
+    int len;
+    audio_info_t info;
+    audio_device_t deviceInfo;
+
+    strncpy(adDesc->path, path, MAX_NAME_LENGTH);
+    adDesc->path[MAX_NAME_LENGTH] = 0;
+    strcpy(adDesc->pathctl, adDesc->path);
+    strcat(adDesc->pathctl, "ctl");
+    strcpy(adDesc->name, adDesc->path);
+    adDesc->vendor[0] = 0;
+    adDesc->version[0] = 0;
+    adDesc->description[0] = 0;
+    adDesc->maxSimulLines = 1;
+
+    // try to open the pseudo device and get more information
+    fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK);
+    if (fd >= 0) {
+        close(fd);
+        if (getNames) {
+            fd = open(adDesc->pathctl, O_RDONLY);
+            if (fd >= 0) {
+                if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) {
+                    strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN);
+                    adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0;
+                    strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN);
+                    adDesc->version[MAX_AUDIO_DEV_LEN] = 0;
+                    /* add config string to the dev name
+                     * creates a string like "/dev/audio (onboard1)"
+                     */
+                    len = strlen(adDesc->name) + 1;
+                    if (MAX_NAME_LENGTH - len > 3) {
+                        strcat(adDesc->name, " (");
+                        strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len);
+                        strcat(adDesc->name, ")");
+                    }
+                    adDesc->name[MAX_NAME_LENGTH-1] = 0;
+                }
+                if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) {
+                    if (mixerMode == AM_MIXER_MODE) {
+                        TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path);
+                        adDesc->maxSimulLines = -1;
+                    }
+                } else {
+                    ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path);
+                }
+                close(fd);
+            } else {
+                ERROR1("could not open %s!\n", adDesc->pathctl);
+            }
+        }
+        return 1;
+    }
+    return 0;
+}