~ubuntu-branches/ubuntu/dapper/rdesktop/dapper

« back to all changes in this revision

Viewing changes to cliprdr.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Johnston
  • Date: 2004-02-04 17:52:26 UTC
  • Revision ID: james.westby@ubuntu.com-20040204175226-87kz4bzs1nimji68
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- c-basic-offset: 8 -*-
 
2
   rdesktop: A Remote Desktop Protocol client.
 
3
   Protocol services - Clipboard functions
 
4
   Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
 
5
   Copyright (C) Matthew Chapman 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"
 
23
 
 
24
#define CLIPRDR_CONNECT                 1
 
25
#define CLIPRDR_FORMAT_ANNOUNCE         2
 
26
#define CLIPRDR_FORMAT_ACK              3
 
27
#define CLIPRDR_DATA_REQUEST            4
 
28
#define CLIPRDR_DATA_RESPONSE           5
 
29
 
 
30
#define CLIPRDR_REQUEST                 0
 
31
#define CLIPRDR_RESPONSE                1
 
32
#define CLIPRDR_ERROR                   2
 
33
 
 
34
static VCHANNEL *cliprdr_channel;
 
35
 
 
36
static void
 
37
cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
 
38
{
 
39
        STREAM s;
 
40
 
 
41
        DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length));
 
42
 
 
43
        s = channel_init(cliprdr_channel, length + 12);
 
44
        out_uint16_le(s, type);
 
45
        out_uint16_le(s, status);
 
46
        out_uint32_le(s, length);
 
47
        out_uint8p(s, data, length);
 
48
        out_uint32(s, 0);       /* pad? */
 
49
        s_mark_end(s);
 
50
        channel_send(s, cliprdr_channel);
 
51
}
 
52
 
 
53
void
 
54
cliprdr_send_text_format_announce(void)
 
55
{
 
56
        uint8 buffer[36];
 
57
 
 
58
        buf_out_uint32(buffer, CF_TEXT);
 
59
        memset(buffer + 4, 0, sizeof(buffer) - 4);      /* description */
 
60
        cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, buffer, sizeof(buffer));
 
61
}
 
62
 
 
63
void
 
64
cliprdr_send_blah_format_announce(void)
 
65
{
 
66
        uint8 buffer[36];
 
67
 
 
68
        buf_out_uint32(buffer, CF_OEMTEXT);
 
69
        memset(buffer + 4, 0, sizeof(buffer) - 4);      /* description */
 
70
        cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, buffer, sizeof(buffer));
 
71
}
 
72
 
 
73
void
 
74
cliprdr_send_native_format_announce(uint8 * data, uint32 length)
 
75
{
 
76
        cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, data, length);
 
77
}
 
78
 
 
79
void
 
80
cliprdr_send_data_request(uint32 format)
 
81
{
 
82
        uint8 buffer[4];
 
83
 
 
84
        buf_out_uint32(buffer, format);
 
85
        cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
 
86
}
 
87
 
 
88
void
 
89
cliprdr_send_data(uint8 * data, uint32 length)
 
90
{
 
91
        cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length);
 
92
}
 
93
 
 
94
static void
 
95
cliprdr_process(STREAM s)
 
96
{
 
97
        uint16 type, status;
 
98
        uint32 length, format;
 
99
        uint8 *data;
 
100
 
 
101
        in_uint16_le(s, type);
 
102
        in_uint16_le(s, status);
 
103
        in_uint32_le(s, length);
 
104
        data = s->p;
 
105
 
 
106
        DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length));
 
107
 
 
108
        if (status == CLIPRDR_ERROR)
 
109
        {
 
110
                if (type == CLIPRDR_FORMAT_ACK)
 
111
                {
 
112
                        /* FIXME: We seem to get this when we send an announce while the server is
 
113
                           still processing a paste. Try sending another announce. */
 
114
                        cliprdr_send_text_format_announce();
 
115
                        return;
 
116
                }
 
117
 
 
118
                DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type));
 
119
                return;
 
120
        }
 
121
 
 
122
        switch (type)
 
123
        {
 
124
                case CLIPRDR_CONNECT:
 
125
                        ui_clip_sync();
 
126
                        break;
 
127
                case CLIPRDR_FORMAT_ANNOUNCE:
 
128
                        ui_clip_format_announce(data, length);
 
129
                        cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
 
130
                        return;
 
131
                case CLIPRDR_FORMAT_ACK:
 
132
                        break;
 
133
                case CLIPRDR_DATA_REQUEST:
 
134
                        in_uint32_le(s, format);
 
135
                        ui_clip_request_data(format);
 
136
                        break;
 
137
                case CLIPRDR_DATA_RESPONSE:
 
138
                        ui_clip_handle_data(data, length);
 
139
                        break;
 
140
                default:
 
141
                        unimpl("CLIPRDR packet type %d\n", type);
 
142
        }
 
143
}
 
144
 
 
145
BOOL
 
146
cliprdr_init(void)
 
147
{
 
148
        cliprdr_channel =
 
149
                channel_register("cliprdr",
 
150
                                 CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
 
151
                                 CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
 
152
                                 cliprdr_process);
 
153
        return (cliprdr_channel != NULL);
 
154
}