/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpsnd.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdpsnd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 435 by astrand, Wed Jul 9 09:18:20 2003 UTC revision 493 by stargo, Tue Oct 14 07:53:10 2003 UTC
# Line 1  Line 1 
1    /*
2       rdesktop: A Remote Desktop Protocol client.
3       Sound Channel Process Functions
4       Copyright (C) Matthew Chapman 2003
5       Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6    
7       This program is free software; you can redistribute it and/or modify
8       it under the terms of the GNU General Public License as published by
9       the Free Software Foundation; either version 2 of the License, or
10       (at your option) any later version.
11    
12       This program is distributed in the hope that it will be useful,
13       but WITHOUT ANY WARRANTY; without even the implied warranty of
14       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15       GNU General Public License for more details.
16    
17       You should have received a copy of the GNU General Public License
18       along with this program; if not, write to the Free Software
19       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    */
21    
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24    #define RDPSND_CLOSE            1
25    #define RDPSND_WRITE            2
26    #define RDPSND_SET_VOLUME       3
27    #define RDPSND_UNKNOWN4         4
28    #define RDPSND_COMPLETION       5
29    #define RDPSND_UNKNOWN6         6
30    #define RDPSND_NEGOTIATE        7
31    
32    #define MAX_FORMATS             10
33    
34  static VCHANNEL *rdpsnd_channel;  static VCHANNEL *rdpsnd_channel;
35    
36  static void  static BOOL device_open;
37    static WAVEFORMATEX formats[MAX_FORMATS];
38    static unsigned int format_count;
39    static unsigned int current_format;
40    
41    STREAM
42    rdpsnd_init_packet(uint16 type, uint16 size)
43    {
44            STREAM s;
45    
46            s = channel_init(rdpsnd_channel, size+4);
47            out_uint16_le(s, type);
48            out_uint16_le(s, size);
49            return s;
50    }
51    
52    void
53    rdpsnd_send(STREAM s)
54    {
55    #ifdef RDPSND_DEBUG
56            printf("RDPSND send:\n");
57            hexdump(s->channel_hdr+8, s->end-s->channel_hdr-8);
58    #endif
59    
60            channel_send(s, rdpsnd_channel);
61    }
62    
63    void rdpsnd_send_completion(uint16 tick, uint8 packet_index)
64    {
65            STREAM s;
66    
67            s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
68            out_uint16_le(s, tick+50);
69            out_uint8(s, packet_index);
70            out_uint8(s, 0);
71            s_mark_end(s);
72            rdpsnd_send(s);
73    }
74    
75    void
76    rdpsnd_process_negotiate(STREAM in)
77    {
78            unsigned int in_format_count, i;
79            WAVEFORMATEX *format;
80            STREAM out;
81            BOOL device_available = False;
82            int readcnt;
83            int discardcnt;
84    
85            in_uint8s(in, 14);      /* flags, volume, pitch, UDP port */
86            in_uint16_le(in, in_format_count);
87            in_uint8s(in, 4);       /* pad, status, pad */
88    
89            if (wave_out_open())
90            {
91                    wave_out_close();
92                    device_available = True;
93            }
94    
95            format_count = 0;
96            if (s_check_rem(in, 18*in_format_count))
97            {
98                    for (i = 0; i < in_format_count; i++)
99                    {
100                            format = &formats[format_count];
101                            in_uint16_le(in, format->wFormatTag);
102                            in_uint16_le(in, format->nChannels);
103                            in_uint32_le(in, format->nSamplesPerSec);
104                            in_uint32_le(in, format->nAvgBytesPerSec);
105                            in_uint16_le(in, format->nBlockAlign);
106                            in_uint16_le(in, format->wBitsPerSample);
107                            in_uint16_le(in, format->cbSize);
108    
109                            /* read in the buffer of unknown use */
110                            readcnt = format->cbSize;
111                            discardcnt = 0;
112                            if (format->cbSize > MAX_CBSIZE)
113                            {
114                                    fprintf(stderr, "cbSize too large for buffer: %d\n", format->cbSize);
115                                    readcnt = MAX_CBSIZE;
116                                    discardcnt = format->cbSize - MAX_CBSIZE;
117                            }
118                            in_uint8a(in, format->cb, readcnt);
119                            in_uint8s(in, discardcnt);
120    
121                            if (device_available && wave_out_format_supported(format))
122                            {
123                                    format_count++;
124                                    if (format_count == MAX_FORMATS)
125                                            break;
126                            }
127                    }
128            }
129    
130            out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18*format_count);
131            out_uint32_le(out, 3);          /* flags */
132            out_uint32(out, 0xffffffff);    /* volume */
133            out_uint32(out, 0);             /* pitch */
134            out_uint16(out, 0);             /* UDP port */
135    
136            out_uint16_le(out, format_count);
137            out_uint8(out, 0x95);           /* pad? */
138            out_uint16_le(out, 2);          /* status */
139            out_uint8(out, 0x77);           /* pad? */
140    
141            for (i = 0; i < format_count; i++)
142            {
143                    format = &formats[i];
144                    out_uint16_le(out, format->wFormatTag);
145                    out_uint16_le(out, format->nChannels);
146                    out_uint32_le(out, format->nSamplesPerSec);
147                    out_uint32_le(out, format->nAvgBytesPerSec);
148                    out_uint16_le(out, format->nBlockAlign);
149                    out_uint16_le(out, format->wBitsPerSample);
150                    out_uint16(out, 0); /* cbSize */
151            }
152    
153            s_mark_end(out);
154            rdpsnd_send(out);
155    }
156    
157    void
158    rdpsnd_process_unknown6(STREAM in)
159    {
160            uint16 unknown1, unknown2;
161            STREAM out;
162    
163            /* in_uint8s(in, 4); unknown */
164            in_uint16_le(in, unknown1);
165            in_uint16_le(in, unknown2);
166    
167            out = rdpsnd_init_packet(RDPSND_UNKNOWN6 | 0x2300, 4);
168            out_uint16_le(out, unknown1);
169            out_uint16_le(out, unknown2);
170            s_mark_end(out);
171            rdpsnd_send(out);
172    }
173    
174    void
175  rdpsnd_process(STREAM s)  rdpsnd_process(STREAM s)
176  {  {
177          printf("rdpsnd_process\n");          uint8 type;
178          hexdump(s->p, s->end - s->p);          uint16 datalen;
179            uint32 volume;
180            static uint16 tick, format;
181            static uint8 packet_index;
182            static BOOL awaiting_data_packet;
183    
184    #ifdef RDPSND_DEBUG
185            printf("RDPSND recv:\n");
186            hexdump(s->p, s->end-s->p);
187    #endif
188    
189            if (awaiting_data_packet)
190            {
191                    if (format >= MAX_FORMATS)
192                    {
193                            error("RDPSND: Invalid format index\n");
194                            return;
195                    }
196    
197                    if (!device_open || (format != current_format))
198                    {
199                            if (!device_open && !wave_out_open())
200                            {
201                                    rdpsnd_send_completion(tick, packet_index);
202                                    return;
203                            }
204                            if (!wave_out_set_format(&formats[format]))
205                            {
206                                    rdpsnd_send_completion(tick, packet_index);
207                                    wave_out_close();
208                                    device_open = False;
209                                    return;
210                            }
211                            device_open = True;
212                            current_format = format;
213                    }
214    
215                    wave_out_write(s, tick, packet_index);
216                    awaiting_data_packet = False;
217                    return;
218            }
219    
220            in_uint8(s, type);
221            in_uint8s(s, 1); /* unknown? */
222            in_uint16_le(s, datalen);
223    
224            switch (type)
225            {
226            case RDPSND_WRITE:
227                    in_uint16_le(s, tick);
228                    in_uint16_le(s, format);
229                    in_uint8(s, packet_index);
230                    awaiting_data_packet = True;
231                    break;
232            case RDPSND_CLOSE:
233                    wave_out_close();
234                    device_open = False;
235                    break;
236            case RDPSND_NEGOTIATE:
237                    rdpsnd_process_negotiate(s);
238                    break;
239            case RDPSND_UNKNOWN6:
240                    rdpsnd_process_unknown6(s);
241                    break;
242            case RDPSND_SET_VOLUME:
243                    in_uint32(s, volume);
244                    if ( device_open )
245                    {
246                            wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);
247                    }
248                    break;
249            default:
250                    unimpl("RDPSND packet type %d\n", type);
251                    break;
252            }
253  }  }
254    
255  BOOL  BOOL

Legend:
Removed from v.435  
changed lines
  Added in v.493

  ViewVC Help
Powered by ViewVC 1.1.26