Rewrite the queue management a bit so that blocks are not completed until
they have finished playing. This also makes the queue system mandatory for all backends. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1301 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
227fad6d96
commit
22d88645ff
7
proto.h
7
proto.h
@ -163,15 +163,14 @@ struct async_iorequest *rdpdr_remove_iorequest(struct async_iorequest *prev,
|
||||
void rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out);
|
||||
BOOL rdpdr_abort_io(uint32 fd, uint32 major, NTSTATUS status);
|
||||
/* rdpsnd.c */
|
||||
void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
|
||||
BOOL rdpsnd_init(char *optarg);
|
||||
void rdpsnd_show_help(void);
|
||||
void rdpsnd_play(void);
|
||||
void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
|
||||
void rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv);
|
||||
void rdpsnd_check_fds(fd_set * rfds, fd_set * wfds);
|
||||
struct audio_packet *rdpsnd_queue_current_packet(void);
|
||||
BOOL rdpsnd_queue_empty(void);
|
||||
void rdpsnd_queue_init(void);
|
||||
void rdpsnd_queue_next(void);
|
||||
void rdpsnd_queue_next(unsigned long completed_in_us);
|
||||
int rdpsnd_queue_next_tick(void);
|
||||
/* secure.c */
|
||||
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
|
||||
|
131
rdpsnd.c
131
rdpsnd.c
@ -47,11 +47,16 @@ static BOOL device_open;
|
||||
static WAVEFORMATEX formats[MAX_FORMATS];
|
||||
static unsigned int format_count;
|
||||
static unsigned int current_format;
|
||||
unsigned int queue_hi, queue_lo;
|
||||
unsigned int queue_hi, queue_lo, queue_pending;
|
||||
struct audio_packet packet_queue[MAX_QUEUE];
|
||||
|
||||
void (*wave_out_play) (void);
|
||||
|
||||
static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
|
||||
static void rdpsnd_queue_init(void);
|
||||
static void rdpsnd_queue_complete_pending(void);
|
||||
static long rdpsnd_queue_next_completion(void);
|
||||
|
||||
static STREAM
|
||||
rdpsnd_init_packet(uint16 type, uint16 size)
|
||||
{
|
||||
@ -74,7 +79,7 @@ rdpsnd_send(STREAM s)
|
||||
channel_send(s, rdpsnd_channel);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
rdpsnd_send_completion(uint16 tick, uint8 packet_index)
|
||||
{
|
||||
STREAM s;
|
||||
@ -232,10 +237,9 @@ rdpsnd_process(STREAM s)
|
||||
/* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
|
||||
memcpy(s->data, missing_bytes, 4);
|
||||
|
||||
current_driver->
|
||||
wave_out_write(rdpsnd_dsp_process
|
||||
(s, current_driver, &formats[current_format]), tick,
|
||||
packet_index);
|
||||
rdpsnd_queue_write(rdpsnd_dsp_process
|
||||
(s, current_driver, &formats[current_format]), tick,
|
||||
packet_index);
|
||||
awaiting_data_packet = False;
|
||||
return;
|
||||
}
|
||||
@ -338,7 +342,7 @@ rdpsnd_register_drivers(char *options)
|
||||
#endif
|
||||
#if defined(RDPSND_LIBAO)
|
||||
*reg = libao_register(options);
|
||||
assert(*reg);
|
||||
assert(*reg);
|
||||
reg = &((*reg)->next);
|
||||
#endif
|
||||
}
|
||||
@ -362,6 +366,8 @@ rdpsnd_init(char *optarg)
|
||||
return False;
|
||||
}
|
||||
|
||||
rdpsnd_queue_init();
|
||||
|
||||
if (optarg != NULL && strlen(optarg) > 0)
|
||||
{
|
||||
driver = options = optarg;
|
||||
@ -424,12 +430,46 @@ rdpsnd_play(void)
|
||||
}
|
||||
|
||||
void
|
||||
rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
|
||||
{
|
||||
long next_pending;
|
||||
|
||||
if (g_dsp_busy)
|
||||
{
|
||||
FD_SET(g_dsp_fd, wfds);
|
||||
*n = (g_dsp_fd > *n) ? g_dsp_fd : *n;
|
||||
}
|
||||
|
||||
next_pending = rdpsnd_queue_next_completion();
|
||||
if (next_pending >= 0)
|
||||
{
|
||||
long cur_timeout;
|
||||
|
||||
cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
|
||||
if (cur_timeout > next_pending)
|
||||
{
|
||||
tv->tv_sec = next_pending / 1000000;
|
||||
tv->tv_usec = next_pending % 1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
|
||||
{
|
||||
rdpsnd_queue_complete_pending();
|
||||
|
||||
if (g_dsp_busy && FD_ISSET(g_dsp_fd, wfds))
|
||||
rdpsnd_play();
|
||||
}
|
||||
|
||||
static void
|
||||
rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
|
||||
{
|
||||
struct audio_packet *packet = &packet_queue[queue_hi];
|
||||
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
|
||||
|
||||
if (next_hi == queue_lo)
|
||||
if (next_hi == queue_pending)
|
||||
{
|
||||
error("No space to queue audio packet\n");
|
||||
return;
|
||||
@ -441,6 +481,8 @@ rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
|
||||
packet->tick = tick;
|
||||
packet->index = index;
|
||||
|
||||
gettimeofday(&packet->arrive_tv, NULL);
|
||||
|
||||
if (!g_dsp_busy)
|
||||
current_driver->wave_out_play();
|
||||
}
|
||||
@ -457,17 +499,30 @@ rdpsnd_queue_empty(void)
|
||||
return (queue_lo == queue_hi);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
rdpsnd_queue_init(void)
|
||||
{
|
||||
queue_lo = queue_hi = 0;
|
||||
queue_pending = queue_lo = queue_hi = 0;
|
||||
}
|
||||
|
||||
void
|
||||
rdpsnd_queue_next(void)
|
||||
rdpsnd_queue_next(unsigned long completed_in_us)
|
||||
{
|
||||
xfree(packet_queue[queue_lo].s.data);
|
||||
struct audio_packet *packet;
|
||||
|
||||
assert(!rdpsnd_queue_empty());
|
||||
|
||||
packet = &packet_queue[queue_lo];
|
||||
|
||||
gettimeofday(&packet->completion_tv, NULL);
|
||||
|
||||
packet->completion_tv.tv_usec += completed_in_us;
|
||||
packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
|
||||
packet->completion_tv.tv_usec %= 1000000;
|
||||
|
||||
queue_lo = (queue_lo + 1) % MAX_QUEUE;
|
||||
|
||||
rdpsnd_queue_complete_pending();
|
||||
}
|
||||
|
||||
int
|
||||
@ -482,3 +537,55 @@ rdpsnd_queue_next_tick(void)
|
||||
return (packet_queue[queue_lo].tick + 65535) % 65536;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rdpsnd_queue_complete_pending(void)
|
||||
{
|
||||
struct timeval now;
|
||||
long elapsed;
|
||||
struct audio_packet *packet;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
while (queue_pending != queue_lo)
|
||||
{
|
||||
packet = &packet_queue[queue_pending];
|
||||
|
||||
if (now.tv_sec < packet->completion_tv.tv_sec)
|
||||
break;
|
||||
|
||||
if ((now.tv_sec == packet->completion_tv.tv_sec) &&
|
||||
(now.tv_usec < packet->completion_tv.tv_usec))
|
||||
break;
|
||||
|
||||
elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
|
||||
(packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
|
||||
|
||||
xfree(packet->s.data);
|
||||
rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
|
||||
queue_pending = (queue_pending + 1) % MAX_QUEUE;
|
||||
}
|
||||
}
|
||||
|
||||
static long
|
||||
rdpsnd_queue_next_completion(void)
|
||||
{
|
||||
struct audio_packet *packet;
|
||||
long remaining;
|
||||
struct timeval now;
|
||||
|
||||
if (queue_pending == queue_lo)
|
||||
return -1;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
packet = &packet_queue[queue_pending];
|
||||
|
||||
remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
|
||||
(packet->completion_tv.tv_usec - now.tv_usec);
|
||||
|
||||
if (remaining < 0)
|
||||
return 0;
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
6
rdpsnd.h
6
rdpsnd.h
@ -23,12 +23,14 @@ struct audio_packet
|
||||
struct stream s;
|
||||
uint16 tick;
|
||||
uint8 index;
|
||||
|
||||
struct timeval arrive_tv;
|
||||
struct timeval completion_tv;
|
||||
};
|
||||
|
||||
struct audio_driver
|
||||
{
|
||||
void (*wave_out_write) (STREAM s, uint16 tick, uint8 index);
|
||||
BOOL(*wave_out_open) (void);
|
||||
BOOL(*wave_out_open) (void);
|
||||
void (*wave_out_close) (void);
|
||||
BOOL(*wave_out_format_supported) (WAVEFORMATEX * pwfx);
|
||||
BOOL(*wave_out_set_format) (WAVEFORMATEX * pwfx);
|
||||
|
@ -37,6 +37,7 @@ static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
|
||||
static BOOL reopened;
|
||||
static short samplewidth;
|
||||
static int audiochannels;
|
||||
static unsigned int rate;
|
||||
static char *pcm_name;
|
||||
|
||||
BOOL
|
||||
@ -51,7 +52,6 @@ alsa_open(void)
|
||||
}
|
||||
|
||||
g_dsp_fd = 0;
|
||||
rdpsnd_queue_init();
|
||||
|
||||
reopened = True;
|
||||
|
||||
@ -63,11 +63,7 @@ alsa_close(void)
|
||||
{
|
||||
/* Ack all remaining packets */
|
||||
while (!rdpsnd_queue_empty())
|
||||
{
|
||||
rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
|
||||
rdpsnd_queue_current_packet()->index);
|
||||
rdpsnd_queue_next();
|
||||
}
|
||||
rdpsnd_queue_next(0);
|
||||
|
||||
if (pcm_handle)
|
||||
{
|
||||
@ -113,7 +109,6 @@ BOOL
|
||||
alsa_set_format(WAVEFORMATEX * pwfx)
|
||||
{
|
||||
snd_pcm_hw_params_t *hwparams = NULL;
|
||||
unsigned int rate, exact_rate;
|
||||
int err;
|
||||
unsigned int buffertime;
|
||||
|
||||
@ -165,8 +160,8 @@ alsa_set_format(WAVEFORMATEX * pwfx)
|
||||
}
|
||||
#endif
|
||||
|
||||
exact_rate = rate = pwfx->nSamplesPerSec;
|
||||
if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0)) < 0)
|
||||
rate = pwfx->nSamplesPerSec;
|
||||
if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0)) < 0)
|
||||
{
|
||||
error("snd_pcm_hw_params_set_rate_near: %s\n", snd_strerror(err));
|
||||
return False;
|
||||
@ -254,6 +249,9 @@ alsa_play(void)
|
||||
|
||||
if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
|
||||
{
|
||||
snd_pcm_sframes_t delay_frames;
|
||||
unsigned long delay_us;
|
||||
|
||||
prev_s = tv.tv_sec;
|
||||
prev_us = tv.tv_usec;
|
||||
|
||||
@ -264,8 +262,14 @@ alsa_play(void)
|
||||
(packet->tick + duration) % 65536, next_tick % 65536));
|
||||
}
|
||||
|
||||
rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
|
||||
rdpsnd_queue_next();
|
||||
if (snd_pcm_delay(pcm_handle, &delay_frames) < 0)
|
||||
delay_frames = out->size / (samplewidth * audiochannels);
|
||||
if (delay_frames < 0)
|
||||
delay_frames = 0;
|
||||
|
||||
delay_us = delay_frames * (1000000 / rate);
|
||||
|
||||
rdpsnd_queue_next(delay_us);
|
||||
}
|
||||
|
||||
g_dsp_busy = 1;
|
||||
@ -277,7 +281,6 @@ alsa_register(char *options)
|
||||
{
|
||||
static struct audio_driver alsa_driver;
|
||||
|
||||
alsa_driver.wave_out_write = rdpsnd_queue_write;
|
||||
alsa_driver.wave_out_open = alsa_open;
|
||||
alsa_driver.wave_out_close = alsa_close;
|
||||
alsa_driver.wave_out_format_supported = alsa_format_supported;
|
||||
|
@ -65,7 +65,6 @@ libao_open(void)
|
||||
}
|
||||
|
||||
g_dsp_fd = 0;
|
||||
rdpsnd_queue_init();
|
||||
|
||||
reopened = True;
|
||||
|
||||
@ -78,9 +77,7 @@ libao_close(void)
|
||||
/* Ack all remaining packets */
|
||||
while (!rdpsnd_queue_empty())
|
||||
{
|
||||
rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
|
||||
rdpsnd_queue_current_packet()->index);
|
||||
rdpsnd_queue_next();
|
||||
rdpsnd_queue_next(0);
|
||||
}
|
||||
|
||||
if (o_device != NULL)
|
||||
@ -171,8 +168,7 @@ libao_play(void)
|
||||
(packet->tick + duration) % 65536, next_tick % 65536));
|
||||
}
|
||||
|
||||
rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
|
||||
rdpsnd_queue_next();
|
||||
rdpsnd_queue_next(duration);
|
||||
}
|
||||
|
||||
g_dsp_busy = 1;
|
||||
@ -186,7 +182,6 @@ libao_register(char *options)
|
||||
struct ao_info *libao_info;
|
||||
static char description[101];
|
||||
|
||||
libao_driver.wave_out_write = rdpsnd_queue_write;
|
||||
libao_driver.wave_out_open = libao_open;
|
||||
libao_driver.wave_out_close = libao_close;
|
||||
libao_driver.wave_out_format_supported = rdpsnd_dsp_resample_supported;
|
||||
|
87
rdpsnd_oss.c
87
rdpsnd_oss.c
@ -33,9 +33,12 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define DEFAULTDEVICE "/dev/dsp"
|
||||
#define MAX_LEN 512
|
||||
@ -44,6 +47,29 @@ static int snd_rate;
|
||||
static short samplewidth;
|
||||
static char *dsp_dev;
|
||||
static struct audio_driver oss_driver;
|
||||
static BOOL in_esddsp;
|
||||
|
||||
static BOOL
|
||||
detect_esddsp(void)
|
||||
{
|
||||
struct stat s;
|
||||
char *preload;
|
||||
|
||||
if (fstat(g_dsp_fd, &s) == -1)
|
||||
return False;
|
||||
|
||||
if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
|
||||
return False;
|
||||
|
||||
preload = getenv("LD_PRELOAD");
|
||||
if (preload == NULL)
|
||||
return False;
|
||||
|
||||
if (strstr(preload, "esddsp") == NULL)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL
|
||||
oss_open(void)
|
||||
@ -54,6 +80,8 @@ oss_open(void)
|
||||
return False;
|
||||
}
|
||||
|
||||
in_esddsp = detect_esddsp();
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -202,10 +230,6 @@ oss_play(void)
|
||||
struct audio_packet *packet;
|
||||
ssize_t len;
|
||||
STREAM out;
|
||||
static long startedat_us;
|
||||
static long startedat_s;
|
||||
static BOOL started = False;
|
||||
struct timeval tv;
|
||||
|
||||
if (rdpsnd_queue_empty())
|
||||
{
|
||||
@ -216,14 +240,6 @@ oss_play(void)
|
||||
packet = rdpsnd_queue_current_packet();
|
||||
out = &packet->s;
|
||||
|
||||
if (!started)
|
||||
{
|
||||
gettimeofday(&tv, NULL);
|
||||
startedat_us = tv.tv_usec;
|
||||
startedat_s = tv.tv_sec;
|
||||
started = True;
|
||||
}
|
||||
|
||||
len = out->end - out->p;
|
||||
|
||||
len = write(g_dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len);
|
||||
@ -236,37 +252,52 @@ oss_play(void)
|
||||
}
|
||||
|
||||
out->p += len;
|
||||
|
||||
if (out->p == out->end)
|
||||
{
|
||||
long long duration;
|
||||
long elapsed;
|
||||
int delay_bytes;
|
||||
unsigned long delay_us;
|
||||
audio_buf_info info;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
duration = (out->size * (1000000 / (samplewidth * snd_rate)));
|
||||
elapsed = (tv.tv_sec - startedat_s) * 1000000 + (tv.tv_usec - startedat_us);
|
||||
|
||||
if (elapsed >= (duration * 85) / 100)
|
||||
if (in_esddsp)
|
||||
{
|
||||
/* We need to add 50 to tell windows that time has passed while
|
||||
* playing this packet */
|
||||
rdpsnd_send_completion(packet->tick + 50, packet->index);
|
||||
rdpsnd_queue_next();
|
||||
started = False;
|
||||
/* EsounD has no way of querying buffer status, so we have to
|
||||
* go with a fixed size. */
|
||||
delay_bytes = out->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_dsp_busy = 1;
|
||||
return;
|
||||
#ifdef SNDCTL_DSP_GETODELAY
|
||||
delay_bytes = 0;
|
||||
if (ioctl(g_dsp_fd, SNDCTL_DSP_GETODELAY, &delay_bytes) == -1)
|
||||
delay_bytes = -1;
|
||||
#else
|
||||
delay_bytes = -1;
|
||||
#endif
|
||||
|
||||
if (delay_bytes == -1)
|
||||
{
|
||||
if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) != -1)
|
||||
delay_bytes = info.fragstotal * info.fragsize - info.bytes;
|
||||
else
|
||||
delay_bytes = out->size;
|
||||
}
|
||||
}
|
||||
|
||||
delay_us = delay_bytes * (1000000 / (samplewidth * snd_rate));
|
||||
rdpsnd_queue_next(delay_us);
|
||||
}
|
||||
g_dsp_busy = 1;
|
||||
else
|
||||
{
|
||||
g_dsp_busy = 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct audio_driver *
|
||||
oss_register(char *options)
|
||||
{
|
||||
oss_driver.wave_out_write = rdpsnd_queue_write;
|
||||
oss_driver.wave_out_open = oss_open;
|
||||
oss_driver.wave_out_close = oss_close;
|
||||
oss_driver.wave_out_format_supported = oss_format_supported;
|
||||
|
@ -68,8 +68,6 @@ sgi_open(void)
|
||||
min_volume, max_volume, volume_range);
|
||||
#endif
|
||||
|
||||
rdpsnd_queue_init();
|
||||
|
||||
audioconfig = alNewConfig();
|
||||
if (audioconfig == (ALconfig) 0)
|
||||
{
|
||||
@ -266,8 +264,7 @@ sgi_play(void)
|
||||
gf = alGetFilled(output_port);
|
||||
if (gf < (4 * maxFillable / 10))
|
||||
{
|
||||
rdpsnd_send_completion(packet->tick, packet->index);
|
||||
rdpsnd_queue_next();
|
||||
rdpsnd_queue_next(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -287,7 +284,6 @@ sgi_register(char *options)
|
||||
{
|
||||
static struct audio_driver sgi_driver;
|
||||
|
||||
sgi_driver.wave_out_write = rdpsnd_queue_write;
|
||||
sgi_driver.wave_out_open = sgi_open;
|
||||
sgi_driver.wave_out_close = sgi_close;
|
||||
sgi_driver.wave_out_format_supported = sgi_format_supported;
|
||||
|
@ -50,7 +50,6 @@ sun_open(void)
|
||||
/* Non-blocking so that user interface is responsive */
|
||||
fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
rdpsnd_queue_init();
|
||||
g_reopened = True;
|
||||
|
||||
return True;
|
||||
@ -235,8 +234,7 @@ sun_play(void)
|
||||
samplecnt += numsamples;
|
||||
/* We need to add 50 to tell windows that time has passed while
|
||||
* playing this packet */
|
||||
rdpsnd_send_completion(packet->tick + 50, packet->index);
|
||||
rdpsnd_queue_next();
|
||||
rdpsnd_queue_next(50);
|
||||
sentcompletion = True;
|
||||
}
|
||||
else
|
||||
@ -253,7 +251,6 @@ sun_register(char *options)
|
||||
{
|
||||
static struct audio_driver sun_driver;
|
||||
|
||||
sun_driver.wave_out_write = rdpsnd_queue_write;
|
||||
sun_driver.wave_out_open = sun_open;
|
||||
sun_driver.wave_out_close = sun_close;
|
||||
sun_driver.wave_out_format_supported = sun_format_supported;
|
||||
|
24
xwin.c
24
xwin.c
@ -2268,18 +2268,14 @@ ui_select(int rdp_socket)
|
||||
FD_SET(rdp_socket, &rfds);
|
||||
FD_SET(g_x_socket, &rfds);
|
||||
|
||||
#ifdef WITH_RDPSND
|
||||
/* FIXME: there should be an API for registering fds */
|
||||
if (g_dsp_busy)
|
||||
{
|
||||
FD_SET(g_dsp_fd, &wfds);
|
||||
n = (g_dsp_fd > n) ? g_dsp_fd : n;
|
||||
}
|
||||
#endif
|
||||
/* default timeout */
|
||||
tv.tv_sec = 60;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
#ifdef WITH_RDPSND
|
||||
rdpsnd_add_fds(&n, &rfds, &wfds, &tv);
|
||||
#endif
|
||||
|
||||
/* add redirection handles */
|
||||
rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
|
||||
seamless_select_timeout(&tv);
|
||||
@ -2292,21 +2288,25 @@ ui_select(int rdp_socket)
|
||||
error("select: %s\n", strerror(errno));
|
||||
|
||||
case 0:
|
||||
#ifdef WITH_RDPSND
|
||||
rdpsnd_check_fds(&rfds, &wfds);
|
||||
#endif
|
||||
|
||||
/* Abort serial read calls */
|
||||
if (s_timeout)
|
||||
rdpdr_check_fds(&rfds, &wfds, (BOOL) True);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef WITH_RDPSND
|
||||
rdpsnd_check_fds(&rfds, &wfds);
|
||||
#endif
|
||||
|
||||
rdpdr_check_fds(&rfds, &wfds, (BOOL) False);
|
||||
|
||||
if (FD_ISSET(rdp_socket, &rfds))
|
||||
return 1;
|
||||
|
||||
#ifdef WITH_RDPSND
|
||||
if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
|
||||
rdpsnd_play();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user