1 /**
2  * xrdp: A Remote Desktop Protocol server.
3  *
4  * Copyright (C) Jay Sorg 2012-2013
5  * Copyright (C) Kevin Zhou 2012
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #if defined(HAVE_CONFIG_H)
21 #include <config_ac.h>
22 #endif
23 
24 #include "libxrdp.h"
25 #include "freerdp/codec/rfx.h"
26 
27 /*****************************************************************************/
28 struct xrdp_surface *
xrdp_surface_create(struct xrdp_session * session,struct xrdp_fastpath * fastpath)29 xrdp_surface_create(struct xrdp_session *session, struct xrdp_fastpath *fastpath)
30 {
31     struct xrdp_surface *self;
32 
33     self = (struct xrdp_surface *)g_malloc(sizeof(struct xrdp_surface), 1);
34     self->session = session;
35     self->fastpath = fastpath;
36     self->rfx_context = rfx_context_new();
37     self->s = stream_new(16384);
38     return self;
39 }
40 
41 /*****************************************************************************/
42 void
xrdp_surface_delete(struct xrdp_surface * self)43 xrdp_surface_delete(struct xrdp_surface *self)
44 {
45     STREAM *s;
46     RFX_CONTEXT *rfx_context;
47 
48     if (self == 0)
49     {
50         return;
51     }
52 
53     s = (STREAM *)(self->s);
54     rfx_context = (RFX_CONTEXT *)(self->rfx_context);
55     free_stream(self->out_s);
56     stream_free(s);
57     rfx_context_free(rfx_context);
58     g_free(self);
59 }
60 
61 /*****************************************************************************/
62 /* returns error */
63 int
xrdp_surface_reset(struct xrdp_surface * self)64 xrdp_surface_reset(struct xrdp_surface *self)
65 {
66     return 0;
67 }
68 
69 /*****************************************************************************/
70 int
xrdp_surface_init(struct xrdp_surface * self)71 xrdp_surface_init(struct xrdp_surface *self)
72 {
73     int width;
74     int height;
75     RFX_CONTEXT *rfx_context;
76 
77     rfx_context = (RFX_CONTEXT *)(self->rfx_context);
78     width = self->session->client_info->width;
79     height = self->session->client_info->height;
80 
81     rfx_context->mode = self->session->client_info->rfx_entropy;
82     rfx_context->width = width;
83     rfx_context->height = height;
84 
85     make_stream(self->out_s);
86     init_stream(self->out_s, 2 * 3 * width * height + 22);
87 
88     return 0;
89 }
90 
91 /*****************************************************************************/
92 int
xrdp_surface_send_surface_bits(struct xrdp_surface * self,int bpp,char * data,int x,int y,int cx,int cy)93 xrdp_surface_send_surface_bits(struct xrdp_surface *self, int bpp, char *data,
94                                int x, int y, int cx, int cy)
95 {
96     RFX_RECT rect;
97     char *buf;
98     int Bpp;
99     int i;
100     int j;
101     int codecId;
102     uint32 bitmapDataLength;
103     STREAM *s;
104     RFX_CONTEXT *rfx_context;
105 
106     s = (STREAM *)(self->s);
107     rfx_context = (RFX_CONTEXT *)(self->rfx_context);
108 
109     if ((bpp == 24) || (bpp == 32))
110     {
111     }
112     else
113     {
114         LOG(LOG_LEVEL_ERROR, "bpp = %d is not supported\n", bpp);
115         return 1;
116     }
117 
118     Bpp = 4;
119 
120     rect.x = 0;
121     rect.y = 0;
122     rect.width  = cx;
123     rect.height = cy;
124 
125     init_stream(self->out_s, 0);
126 
127     stream_set_pos(s, 0);
128     rfx_compose_message(rfx_context, s, &rect, 1, data, cx, cy, Bpp * cx);
129 
130     codecId = self->session->client_info->rfx_codecId;
131     /* surface_bits_command */
132     out_uint16_le(self->out_s, CMDTYPE_STREAM_SURFACE_BITS); /* cmdType */
133     out_uint16_le(self->out_s, x);                           /* destLeft */
134     out_uint16_le(self->out_s, y);                           /* destTop */
135     out_uint16_le(self->out_s, x + cx);                      /* destRight */
136     out_uint16_le(self->out_s, y + cy);                      /* destBottom */
137     out_uint8(self->out_s, 32);                              /* bpp */
138     out_uint8(self->out_s, 0);                               /* reserved1 */
139     out_uint8(self->out_s, 0);                               /* reserved2 */
140     out_uint8(self->out_s, codecId);                         /* codecId */
141     out_uint16_le(self->out_s, cx);                          /* width */
142     out_uint16_le(self->out_s, cy);                          /* height */
143     bitmapDataLength = stream_get_length(s);
144     out_uint32_le(self->out_s, bitmapDataLength); /* bitmapDataLength */
145 
146     /* rfx bit stream */
147     out_uint8p(self->out_s, s->data, bitmapDataLength);
148 
149     s_mark_end(self->out_s);
150     return xrdp_fastpath_send_update_pdu(self->fastpath,
151                                          FASTPATH_UPDATETYPE_SURFCMDS,
152                                          self->out_s);
153 }
154 
155 /*****************************************************************************/
156 int
xrdp_surface_send_frame_marker(struct xrdp_surface * self,uint16 frameAction,uint32 frameId)157 xrdp_surface_send_frame_marker(struct xrdp_surface *self,
158                                uint16 frameAction, uint32 frameId)
159 {
160     init_stream(self->out_s, 0);
161     out_uint16_le(self->out_s, CMDTYPE_FRAME_MARKER);
162     out_uint16_le(self->out_s, frameAction);
163     out_uint32_le(self->out_s, frameId);
164     s_mark_end(self->out_s);
165     return xrdp_fastpath_send_update_pdu(self->fastpath,
166                                          FASTPATH_UPDATETYPE_SURFCMDS,
167                                          self->out_s);
168 }
169