summaryrefslogtreecommitdiff
path: root/gtk/spice-channel-priv.h
blob: 7ad4354438cc7b80955c8756ffaf297b5a02b25d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#ifndef __SPICE_CLIENT_CHANNEL_PRIV_H__
#define __SPICE_CLIENT_CHANNEL_PRIV_H__

#include <pixman.h>
#include <jpeglib.h>

#include <openssl/ssl.h>

#include "decode.h"

/* spice/common */
#include "canvas_base.h"
#include "canvas_utils.h"
#include "sw_canvas.h"
#include "ring.h"
#include "quic.h"
#include "rop3.h"

#define SPICE_CHANNEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_CHANNEL, spice_channel))

struct spice_msg_in {
    int                   refcount;
    SpiceChannel          *channel;
    SpiceDataHeader       header;
    uint8_t               *data;
    int                   hpos,dpos;
    uint8_t               *parsed;
    size_t                psize;
    message_destructor_t  pfree;
};

struct spice_msg_out {
    int                   refcount;
    SpiceChannel          *channel;
    SpiceMarshaller       *marshaller;
    SpiceDataHeader       *header;
};

enum spice_channel_state {
    SPICE_CHANNEL_STATE_UNCONNECTED = 0,
    SPICE_CHANNEL_STATE_TLS,
    SPICE_CHANNEL_STATE_LINK_HDR,
    SPICE_CHANNEL_STATE_LINK_MSG,
    SPICE_CHANNEL_STATE_AUTH,
    SPICE_CHANNEL_STATE_READY,
};

struct main_channel {
    enum SpiceMouseMode         mouse_mode;
    int                         agent_connected;
    int                         agent_tokens;
    uint8_t                     *agent_msg;
    uint8_t                     *agent_msg_pos;
    uint8_t                     *agent_msg_size;
    struct {
        int                     x;
        int                     y;
        int                     width;
        int                     height;
    } display[1];
};

#define DISPLAY_PIXMAP_CACHE (1024 * 1024 * 32)
#define GLZ_WINDOW_SIZE      (1024 * 1024 * 16)

typedef struct display_surface {
    RingItem                    link;
    int                         surface_id;
    bool                        primary;
    enum SpiceSurfaceFmt        format;
    int                         width, height, stride, size;
    int                         shmid;
    uint8_t                     *data;
    SpiceCanvas                 *canvas;
    SpiceGlzDecoder             *glz_decoder;
} display_surface;

typedef struct display_cursor {
    SpiceCursorHeader           hdr;
    uint8_t                     data[];
} display_cursor;

typedef struct display_stream {
    spice_msg_in                *msg_create;
    spice_msg_in                *msg_clip;
    spice_msg_in                *msg_data;

    /* from messages */
    display_surface             *surface;
    SpiceClip                   *clip;
    int                         codec;

    /* mjpeg decoder */
    struct jpeg_source_mgr         mjpeg_src;
    struct jpeg_decompress_struct  mjpeg_cinfo;
    struct jpeg_error_mgr          mjpeg_jerr;

    uint8_t                     *out_frame;
} display_stream;

typedef struct display_cache_item {
    RingItem                    hash_link;
    RingItem                    lru_link;
    uint64_t                    id;
    uint32_t                    refcount;
    union {
        pixman_image_t          *image;
        SpicePalette            *palette;
        display_cursor          *cursor;
    } ptr;
} display_cache_item;

typedef struct display_cache {
    const char                  *name;
    Ring                        hash[64];
    Ring                        lru;
    int                         nitems;
} display_cache;

struct display_channel {
    Ring                        surfaces;
    display_cache               images;
    display_cache               palettes;
    SpiceImageCache             image_cache;
    SpicePaletteCache           palette_cache;
    SpiceGlzDecoderWindow       *glz_window;
    display_stream              *streams[128];
};

struct inputs_channel {
    int                         bs;
    int                         dx, dy;
    unsigned int                x, y, dpy;
    int                         motion_count;
};

struct spice_channel {
    SpiceSession                *session;
    char                        name[16];
    enum spice_channel_state    state;
    int                         socket;
    spice_parse_channel_func_t  parser;
    SpiceMessageMarshallers     *marshallers;
    spice_watch                 *watch;
    SSL_CTX                     *ctx;
    SSL                         *ssl;

    int                         protocol;
    int                         tls;

    int                         connection_id;
    int                         channel_id;
    int                         channel_type;
    int                         serial;
    spice_channel_info          *info;
    SpiceLinkHeader             link_hdr;
    SpiceLinkMess               link_msg;
    SpiceLinkHeader             peer_hdr;
    SpiceLinkReply*             peer_msg;

    spice_msg_in                *msg_in;
    int                         message_ack_window;
    int                         message_ack_count;

    union {
        struct main_channel     main;
        struct display_channel  display;
        struct inputs_channel   inputs;
    };
};

enum {
    SPICE_CHANNEL_EVENT,

    SPICE_MAIN_MOUSE_MODE,
    SPICE_MAIN_AGENT_EVENT,

    SPICE_DISPLAY_PRIMARY_CREATE,
    SPICE_DISPLAY_PRIMARY_DESTROY,
    SPICE_DISPLAY_INVALIDATE,

    SPICE_CHANNEL_LAST_SIGNAL,
};

extern guint channel_signals[SPICE_CHANNEL_LAST_SIGNAL];

/* channel-display-mjpeg.c */
void stream_mjpeg_init(display_stream *st);
void stream_mjpeg_data(display_stream *st);
void stream_mjpeg_cleanup(display_stream *st);

/* channel-*.c */
void base_handle_set_ack(SpiceChannel *channel, spice_msg_in *in);
void base_handle_ping(SpiceChannel *channel, spice_msg_in *in);
void base_handle_notify(SpiceChannel *channel, spice_msg_in *in);

struct spice_channel_info {
    char               *name;
    spice_channel_func alloc;
    spice_channel_func ready;
    spice_msg_handler  *handlers;
    int                nhandlers;
};

extern spice_channel_info main_channel_info;
extern spice_channel_info display_channel_info;
extern spice_channel_info inputs_channel_info;

#endif /* __SPICE_CLIENT_CHANNEL_PRIV_H__ */