src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Utils.c
changeset 49289 148e29df1644
parent 49288 6e2d71029781
child 49290 07779973cbe2
equal deleted inserted replaced
49288:6e2d71029781 49289:148e29df1644
     1 /*
       
     2  * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 #define USE_ERROR
       
    27 #define USE_TRACE
       
    28 
       
    29 #include "PLATFORM_API_SolarisOS_Utils.h"
       
    30 
       
    31 #define MAX_AUDIO_DEVICES 20
       
    32 
       
    33 // not thread safe...
       
    34 static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES];
       
    35 static int globalADCount = -1;
       
    36 static int globalADCacheTime = -1;
       
    37 /* how many seconds do we cache devices */
       
    38 #define AD_CACHE_TIME 30
       
    39 
       
    40 // return seconds
       
    41 long getTimeInSeconds() {
       
    42     struct timeval tv;
       
    43     gettimeofday(&tv, NULL);
       
    44     return tv.tv_sec;
       
    45 }
       
    46 
       
    47 
       
    48 int getAudioDeviceCount() {
       
    49     int count = MAX_AUDIO_DEVICES;
       
    50 
       
    51     getAudioDevices(globalADPaths, &count);
       
    52     return count;
       
    53 }
       
    54 
       
    55 /* returns TRUE if the path exists at all */
       
    56 int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) {
       
    57     int i;
       
    58     int found = 0;
       
    59     int fileExists = 0;
       
    60     // not thread safe...
       
    61     static struct stat statBuf;
       
    62 
       
    63     // get stats on the file
       
    64     if (stat(path, &statBuf) == 0) {
       
    65         // file exists.
       
    66         fileExists = 1;
       
    67         // If it is not yet in the adPath array, add it to the array
       
    68         for (i = 0; i < *count; i++) {
       
    69             if (adPath[i].st_ino == statBuf.st_ino
       
    70                 && adPath[i].st_dev == statBuf.st_dev) {
       
    71                 found = 1;
       
    72                 break;
       
    73             }
       
    74         }
       
    75         if (!found) {
       
    76             adPath[*count].st_ino = statBuf.st_ino;
       
    77             adPath[*count].st_dev = statBuf.st_dev;
       
    78             strncpy(adPath[*count].path, path, MAX_NAME_LENGTH);
       
    79             adPath[*count].path[MAX_NAME_LENGTH - 1] = 0;
       
    80             (*count)++;
       
    81             TRACE1("Added audio device %s\n", path);
       
    82         }
       
    83     }
       
    84     return fileExists;
       
    85 }
       
    86 
       
    87 
       
    88 void getAudioDevices(AudioDevicePath* adPath, int* count) {
       
    89     int maxCount = *count;
       
    90     char* audiodev;
       
    91     char devsound[15];
       
    92     int i;
       
    93     long timeInSeconds = getTimeInSeconds();
       
    94 
       
    95     if (globalADCount < 0
       
    96         || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME
       
    97         || (adPath != globalADPaths)) {
       
    98         *count = 0;
       
    99         // first device, if set, is AUDIODEV variable
       
   100         audiodev = getenv("AUDIODEV");
       
   101         if (audiodev != NULL && audiodev[0] != 0) {
       
   102             addAudioDevice(audiodev, adPath, count);
       
   103         }
       
   104         // then try /dev/audio
       
   105         addAudioDevice("/dev/audio", adPath, count);
       
   106         // then go through all of the /dev/sound/? devices
       
   107         for (i = 0; i < 100; i++) {
       
   108             sprintf(devsound, "/dev/sound/%d", i);
       
   109             if (!addAudioDevice(devsound, adPath, count)) {
       
   110                 break;
       
   111             }
       
   112         }
       
   113         if (adPath == globalADPaths) {
       
   114             /* commit cache */
       
   115             globalADCount = *count;
       
   116             /* set cache time */
       
   117             globalADCacheTime = timeInSeconds;
       
   118         }
       
   119     } else {
       
   120         /* return cache */
       
   121         *count = globalADCount;
       
   122     }
       
   123     // that's it
       
   124 }
       
   125 
       
   126 int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) {
       
   127     int count = MAX_AUDIO_DEVICES;
       
   128     int ret = 0;
       
   129 
       
   130     getAudioDevices(globalADPaths, &count);
       
   131     if (index>=0 && index < count) {
       
   132         ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames);
       
   133     }
       
   134     return ret;
       
   135 }
       
   136 
       
   137 int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) {
       
   138     int fd;
       
   139     int mixerMode;
       
   140     int len;
       
   141     audio_info_t info;
       
   142     audio_device_t deviceInfo;
       
   143 
       
   144     strncpy(adDesc->path, path, MAX_NAME_LENGTH);
       
   145     adDesc->path[MAX_NAME_LENGTH] = 0;
       
   146     strcpy(adDesc->pathctl, adDesc->path);
       
   147     strcat(adDesc->pathctl, "ctl");
       
   148     strcpy(adDesc->name, adDesc->path);
       
   149     adDesc->vendor[0] = 0;
       
   150     adDesc->version[0] = 0;
       
   151     adDesc->description[0] = 0;
       
   152     adDesc->maxSimulLines = 1;
       
   153 
       
   154     // try to open the pseudo device and get more information
       
   155     fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK);
       
   156     if (fd >= 0) {
       
   157         close(fd);
       
   158         if (getNames) {
       
   159             fd = open(adDesc->pathctl, O_RDONLY);
       
   160             if (fd >= 0) {
       
   161                 if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) {
       
   162                     strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN);
       
   163                     adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0;
       
   164                     strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN);
       
   165                     adDesc->version[MAX_AUDIO_DEV_LEN] = 0;
       
   166                     /* add config string to the dev name
       
   167                      * creates a string like "/dev/audio (onboard1)"
       
   168                      */
       
   169                     len = strlen(adDesc->name) + 1;
       
   170                     if (MAX_NAME_LENGTH - len > 3) {
       
   171                         strcat(adDesc->name, " (");
       
   172                         strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len);
       
   173                         strcat(adDesc->name, ")");
       
   174                     }
       
   175                     adDesc->name[MAX_NAME_LENGTH-1] = 0;
       
   176                 }
       
   177                 if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) {
       
   178                     if (mixerMode == AM_MIXER_MODE) {
       
   179                         TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path);
       
   180                         adDesc->maxSimulLines = -1;
       
   181                     }
       
   182                 } else {
       
   183                     ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path);
       
   184                 }
       
   185                 close(fd);
       
   186             } else {
       
   187                 ERROR1("could not open %s!\n", adDesc->pathctl);
       
   188             }
       
   189         }
       
   190         return 1;
       
   191     }
       
   192     return 0;
       
   193 }