src/audio/bsd/SDL_bsdaudio.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 14 Jul 2013 18:17:28 -0700
changeset 7523 9e9ab1dc3811
parent 7038 7f22b9ba218f
child 7719 31b5f9ff36ca
permissions -rw-r--r--
Fixed bug 1919 - Window icon disappears as soon as a renderer is created

Sebastian

Setting a window icon works just fine until a renderer is added to the window.
After adding the renderer the icon disappears.

Reproduce by:
- Take the example code from the wiki: http://wiki.libsdl.org/moin.fcg/SDL_SetWindowIcon

- Add the following two lines after SDL_FreeSurface(surface);
SDL_Delay(1000);
SDL_Renderer* ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

-compile and run

You will see the window icon correctly at first. After the Delay the Icon will disappear.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 #if SDL_AUDIO_DRIVER_BSD
    24 
    25 /*
    26  * Driver for native OpenBSD/NetBSD audio(4).
    27  * vedge@vedge.com.ar.
    28  */
    29 
    30 #include <errno.h>
    31 #include <unistd.h>
    32 #include <fcntl.h>
    33 #include <sys/time.h>
    34 #include <sys/ioctl.h>
    35 #include <sys/stat.h>
    36 #include <sys/types.h>
    37 #include <sys/audioio.h>
    38 
    39 #include "SDL_timer.h"
    40 #include "SDL_audio.h"
    41 #include "../SDL_audiomem.h"
    42 #include "../SDL_audio_c.h"
    43 #include "../SDL_audiodev_c.h"
    44 #include "SDL_bsdaudio.h"
    45 
    46 /* Use timer for synchronization */
    47 /* #define USE_TIMER_SYNC */
    48 
    49 /* #define DEBUG_AUDIO */
    50 /* #define DEBUG_AUDIO_STREAM */
    51 
    52 
    53 static void
    54 BSDAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
    55 {
    56     SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn);
    57 }
    58 
    59 
    60 static void
    61 BSDAUDIO_Status(_THIS)
    62 {
    63 #ifdef DEBUG_AUDIO
    64     /* *INDENT-OFF* */
    65     audio_info_t info;
    66 
    67     if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
    68         fprintf(stderr, "AUDIO_GETINFO failed.\n");
    69         return;
    70     }
    71     fprintf(stderr, "\n"
    72             "[play/record info]\n"
    73             "buffer size	:   %d bytes\n"
    74             "sample rate	:   %i Hz\n"
    75             "channels	:   %i\n"
    76             "precision	:   %i-bit\n"
    77             "encoding	:   0x%x\n"
    78             "seek		:   %i\n"
    79             "sample count	:   %i\n"
    80             "EOF count	:   %i\n"
    81             "paused		:   %s\n"
    82             "error occured	:   %s\n"
    83             "waiting		:   %s\n"
    84             "active		:   %s\n"
    85             "",
    86             info.play.buffer_size,
    87             info.play.sample_rate,
    88             info.play.channels,
    89             info.play.precision,
    90             info.play.encoding,
    91             info.play.seek,
    92             info.play.samples,
    93             info.play.eof,
    94             info.play.pause ? "yes" : "no",
    95             info.play.error ? "yes" : "no",
    96             info.play.waiting ? "yes" : "no",
    97             info.play.active ? "yes" : "no");
    98 
    99     fprintf(stderr, "\n"
   100             "[audio info]\n"
   101             "monitor_gain	:   %i\n"
   102             "hw block size	:   %d bytes\n"
   103             "hi watermark	:   %i\n"
   104             "lo watermark	:   %i\n"
   105             "audio mode	:   %s\n"
   106             "",
   107             info.monitor_gain,
   108             info.blocksize,
   109             info.hiwat, info.lowat,
   110             (info.mode == AUMODE_PLAY) ? "PLAY"
   111             : (info.mode = AUMODE_RECORD) ? "RECORD"
   112             : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" : "?"));
   113     /* *INDENT-ON* */
   114 #endif /* DEBUG_AUDIO */
   115 }
   116 
   117 
   118 /* This function waits until it is possible to write a full sound buffer */
   119 static void
   120 BSDAUDIO_WaitDevice(_THIS)
   121 {
   122 #ifndef USE_BLOCKING_WRITES     /* Not necessary when using blocking writes */
   123     /* See if we need to use timed audio synchronization */
   124     if (this->hidden->frame_ticks) {
   125         /* Use timer for general audio synchronization */
   126         Sint32 ticks;
   127 
   128         ticks =
   129             ((Sint32) (this->hidden->next_frame - SDL_GetTicks())) -
   130             FUDGE_TICKS;
   131         if (ticks > 0) {
   132             SDL_Delay(ticks);
   133         }
   134     } else {
   135         /* Use select() for audio synchronization */
   136         fd_set fdset;
   137         struct timeval timeout;
   138 
   139         FD_ZERO(&fdset);
   140         FD_SET(this->hidden->audio_fd, &fdset);
   141         timeout.tv_sec = 10;
   142         timeout.tv_usec = 0;
   143 #ifdef DEBUG_AUDIO
   144         fprintf(stderr, "Waiting for audio to get ready\n");
   145 #endif
   146         if (select(this->hidden->audio_fd + 1, NULL, &fdset, NULL, &timeout)
   147             <= 0) {
   148             const char *message =
   149                 "Audio timeout - buggy audio driver? (disabled)";
   150             /* In general we should never print to the screen,
   151                but in this case we have no other way of letting
   152                the user know what happened.
   153              */
   154             fprintf(stderr, "SDL: %s\n", message);
   155             this->enabled = 0;
   156             /* Don't try to close - may hang */
   157             this->hidden->audio_fd = -1;
   158 #ifdef DEBUG_AUDIO
   159             fprintf(stderr, "Done disabling audio\n");
   160 #endif
   161         }
   162 #ifdef DEBUG_AUDIO
   163         fprintf(stderr, "Ready!\n");
   164 #endif
   165     }
   166 #endif /* !USE_BLOCKING_WRITES */
   167 }
   168 
   169 static void
   170 BSDAUDIO_PlayDevice(_THIS)
   171 {
   172     int written, p = 0;
   173 
   174     /* Write the audio data, checking for EAGAIN on broken audio drivers */
   175     do {
   176         written = write(this->hidden->audio_fd,
   177                         &this->hidden->mixbuf[p], this->hidden->mixlen - p);
   178 
   179         if (written > 0)
   180             p += written;
   181         if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) {
   182             /* Non recoverable error has occurred. It should be reported!!! */
   183             perror("audio");
   184             break;
   185         }
   186 
   187         if (p < written
   188             || ((written < 0) && ((errno == 0) || (errno == EAGAIN)))) {
   189             SDL_Delay(1);       /* Let a little CPU time go by */
   190         }
   191     } while (p < written);
   192 
   193     /* If timer synchronization is enabled, set the next write frame */
   194     if (this->hidden->frame_ticks) {
   195         this->hidden->next_frame += this->hidden->frame_ticks;
   196     }
   197 
   198     /* If we couldn't write, assume fatal error for now */
   199     if (written < 0) {
   200         this->enabled = 0;
   201     }
   202 #ifdef DEBUG_AUDIO
   203     fprintf(stderr, "Wrote %d bytes of audio data\n", written);
   204 #endif
   205 }
   206 
   207 static Uint8 *
   208 BSDAUDIO_GetDeviceBuf(_THIS)
   209 {
   210     return (this->hidden->mixbuf);
   211 }
   212 
   213 static void
   214 BSDAUDIO_CloseDevice(_THIS)
   215 {
   216     if (this->hidden != NULL) {
   217         if (this->hidden->mixbuf != NULL) {
   218             SDL_FreeAudioMem(this->hidden->mixbuf);
   219             this->hidden->mixbuf = NULL;
   220         }
   221         if (this->hidden->audio_fd >= 0) {
   222             close(this->hidden->audio_fd);
   223             this->hidden->audio_fd = -1;
   224         }
   225         SDL_free(this->hidden);
   226         this->hidden = NULL;
   227     }
   228 }
   229 
   230 static int
   231 BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
   232 {
   233     const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
   234     SDL_AudioFormat format = 0;
   235     audio_info_t info;
   236 
   237     /* We don't care what the devname is...we'll try to open anything. */
   238     /*  ...but default to first name in the list... */
   239     if (devname == NULL) {
   240         devname = SDL_GetAudioDeviceName(0, iscapture);
   241         if (devname == NULL) {
   242             return SDL_SetError("No such audio device");
   243         }
   244     }
   245 
   246     /* Initialize all variables that we clean on shutdown */
   247     this->hidden = (struct SDL_PrivateAudioData *)
   248         SDL_malloc((sizeof *this->hidden));
   249     if (this->hidden == NULL) {
   250         return SDL_OutOfMemory();
   251     }
   252     SDL_memset(this->hidden, 0, (sizeof *this->hidden));
   253 
   254     /* Open the audio device */
   255     this->hidden->audio_fd = open(devname, flags, 0);
   256     if (this->hidden->audio_fd < 0) {
   257         return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
   258     }
   259 
   260     AUDIO_INITINFO(&info);
   261 
   262     /* Calculate the final parameters for this audio specification */
   263     SDL_CalculateAudioSpec(&this->spec);
   264 
   265     /* Set to play mode */
   266     info.mode = AUMODE_PLAY;
   267     if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
   268         BSDAUDIO_CloseDevice(this);
   269         return SDL_SetError("Couldn't put device into play mode");
   270     }
   271 
   272     AUDIO_INITINFO(&info);
   273     for (format = SDL_FirstAudioFormat(this->spec.format);
   274          format; format = SDL_NextAudioFormat()) {
   275         switch (format) {
   276         case AUDIO_U8:
   277             info.play.encoding = AUDIO_ENCODING_ULINEAR;
   278             info.play.precision = 8;
   279             break;
   280         case AUDIO_S8:
   281             info.play.encoding = AUDIO_ENCODING_SLINEAR;
   282             info.play.precision = 8;
   283             break;
   284         case AUDIO_S16LSB:
   285             info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
   286             info.play.precision = 16;
   287             break;
   288         case AUDIO_S16MSB:
   289             info.play.encoding = AUDIO_ENCODING_SLINEAR_BE;
   290             info.play.precision = 16;
   291             break;
   292         case AUDIO_U16LSB:
   293             info.play.encoding = AUDIO_ENCODING_ULINEAR_LE;
   294             info.play.precision = 16;
   295             break;
   296         case AUDIO_U16MSB:
   297             info.play.encoding = AUDIO_ENCODING_ULINEAR_BE;
   298             info.play.precision = 16;
   299             break;
   300         default:
   301             continue;
   302         }
   303 
   304         if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
   305             break;
   306         }
   307     }
   308 
   309     if (!format) {
   310         BSDAUDIO_CloseDevice(this);
   311         return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
   312     }
   313 
   314     this->spec.format = format;
   315 
   316     AUDIO_INITINFO(&info);
   317     info.play.channels = this->spec.channels;
   318     if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) {
   319         this->spec.channels = 1;
   320     }
   321     AUDIO_INITINFO(&info);
   322     info.play.sample_rate = this->spec.freq;
   323     info.blocksize = this->spec.size;
   324     info.hiwat = 5;
   325     info.lowat = 3;
   326     (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);
   327     (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);
   328     this->spec.freq = info.play.sample_rate;
   329     /* Allocate mixing buffer */
   330     this->hidden->mixlen = this->spec.size;
   331     this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
   332     if (this->hidden->mixbuf == NULL) {
   333         BSDAUDIO_CloseDevice(this);
   334         return SDL_OutOfMemory();
   335     }
   336     SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
   337 
   338     BSDAUDIO_Status(this);
   339 
   340     /* We're ready to rock and roll. :-) */
   341     return 0;
   342 }
   343 
   344 static int
   345 BSDAUDIO_Init(SDL_AudioDriverImpl * impl)
   346 {
   347     /* Set the function pointers */
   348     impl->DetectDevices = BSDAUDIO_DetectDevices;
   349     impl->OpenDevice = BSDAUDIO_OpenDevice;
   350     impl->PlayDevice = BSDAUDIO_PlayDevice;
   351     impl->WaitDevice = BSDAUDIO_WaitDevice;
   352     impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
   353     impl->CloseDevice = BSDAUDIO_CloseDevice;
   354 
   355     return 1;   /* this audio target is available. */
   356 }
   357 
   358 
   359 AudioBootStrap BSD_AUDIO_bootstrap = {
   360     "bsd", "BSD audio", BSDAUDIO_Init, 0
   361 };
   362 
   363 #endif /* SDL_AUDIO_DRIVER_BSD */
   364 
   365 /* vi: set ts=4 sw=4 expandtab: */