From 42928d7ae13fd257172e0666a7b42b829ae044dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C3=85strand?= Date: Fri, 9 Apr 2010 13:12:31 +0000 Subject: [PATCH] Properly reset sound subsystem when reconnecting due to screen size change (RandR). git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1592 423420c4-83ab-492f-b58f-81f9feb106b5 --- proto.h | 1 + rdesktop.c | 3 +++ rdpsnd.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/proto.h b/proto.h index 78764ea..7ae9d8d 100644 --- a/proto.h +++ b/proto.h @@ -174,6 +174,7 @@ struct audio_packet *rdpsnd_queue_current_packet(void); RD_BOOL rdpsnd_queue_empty(void); void rdpsnd_queue_next(unsigned long completed_in_us); int rdpsnd_queue_next_tick(void); +void rdpsnd_reset_state(void); /* secure.c */ void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt); void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2); diff --git a/rdesktop.c b/rdesktop.c index bc2ca95..2d83d3c 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -354,6 +354,9 @@ rdesktop_reset_state(void) #ifdef WITH_SCARD scard_reset_state(); #endif +#ifdef WITH_RDPSND + rdpsnd_reset_state(); +#endif } static RD_BOOL diff --git a/rdpsnd.c b/rdpsnd.c index 7ffdf97..1563ad7 100644 --- a/rdpsnd.c +++ b/rdpsnd.c @@ -73,6 +73,7 @@ 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_clear(void); static void rdpsnd_queue_complete_pending(void); static long rdpsnd_queue_next_completion(void); @@ -150,6 +151,16 @@ rdpsnd_flush_record(void) record_buffer_size = 0; } +static void +rdpsnd_clear_record(void) +{ + /* + * Silently drop everything we have in the record buffer as + * we've somehow gotten a reset in regard to the server. + */ + record_buffer_size = 0; +} + void rdpsnd_record(const void *data, unsigned int size) { @@ -726,6 +737,23 @@ rdpsnd_init(char *optarg) return False; } +void +rdpsnd_reset_state(void) +{ + if (device_open) + current_driver->wave_out_close(); + device_open = False; + + rdpsnd_queue_clear(); + + if (rec_device_open) + current_driver->wave_in_close(); + rec_device_open = False; + + rdpsnd_clear_record(); +} + + void rdpsnd_show_help(void) { @@ -811,6 +839,23 @@ rdpsnd_queue_init(void) queue_pending = queue_lo = queue_hi = 0; } +static void +rdpsnd_queue_clear(void) +{ + struct audio_packet *packet; + + /* Go through everything, not just the pending packets */ + while (queue_pending != queue_hi) + { + packet = &packet_queue[queue_pending]; + xfree(packet->s.data); + queue_pending = (queue_pending + 1) % MAX_QUEUE; + } + + /* Reset everything back to the initial state */ + queue_pending = queue_lo = queue_hi = 0; +} + void rdpsnd_queue_next(unsigned long completed_in_us) {