server: use rdpContext for server-side components.

This commit is contained in:
Vic Lee 2011-10-18 15:10:12 +08:00
parent c11dc9a36e
commit 296d5ea753
9 changed files with 302 additions and 279 deletions

View File

@ -28,6 +28,7 @@ typedef struct rdp_channels rdpChannels;
typedef struct rdp_freerdp freerdp;
typedef struct rdp_context rdpContext;
typedef struct rdp_freerdp_peer freerdp_peer;
#include <freerdp/api.h>
#include <freerdp/types.h>
@ -55,6 +56,7 @@ typedef int (*pcReceiveChannelData)(freerdp* instance, int channelId, uint8* dat
struct rdp_context
{
freerdp* instance;
freerdp_peer* peer;
int argc;
char** argv;

View File

@ -20,14 +20,16 @@
#ifndef __FREERDP_PEER_H
#define __FREERDP_PEER_H
typedef struct rdp_freerdp_peer freerdp_peer;
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/input.h>
#include <freerdp/update.h>
typedef void (*psPeerContextSize)(freerdp_peer* client, uint32* size);
typedef void (*psPeerContextNew)(freerdp_peer* client, rdpContext* context);
typedef void (*psPeerContextFree)(freerdp_peer* client, rdpContext* context);
typedef boolean (*psPeerInitialize)(freerdp_peer* client);
typedef boolean (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount);
typedef boolean (*psPeerCheckFileDescriptor)(freerdp_peer* client);
@ -37,17 +39,18 @@ typedef boolean (*psPeerActivate)(freerdp_peer* client);
struct rdp_freerdp_peer
{
void* info;
void* peer;
void* param1;
void* param2;
void* param3;
void* param4;
rdpContext* context;
int sockfd;
char hostname[50];
rdpInput* input;
rdpUpdate* update;
rdpSettings* settings;
psPeerContextSize ContextSize;
psPeerContextNew ContextNew;
psPeerContextFree ContextFree;
psPeerInitialize Initialize;
psPeerGetFileDescriptor GetFileDescriptor;
psPeerCheckFileDescriptor CheckFileDescriptor;
@ -57,6 +60,9 @@ struct rdp_freerdp_peer
psPeerActivate Activate;
};
FREERDP_API void freerdp_peer_context_new(freerdp_peer* client);
FREERDP_API void freerdp_peer_context_free(freerdp_peer* client);
FREERDP_API freerdp_peer* freerdp_peer_new(int sockfd);
FREERDP_API void freerdp_peer_free(freerdp_peer* client);

View File

@ -183,10 +183,7 @@ static boolean freerdp_listener_check_fds(freerdp_listener* instance)
sin_addr = &(((struct sockaddr_in*)&peer_addr)->sin_addr);
else
sin_addr = &(((struct sockaddr_in6*)&peer_addr)->sin6_addr);
client->settings->hostname = xzalloc(50);
inet_ntop(peer_addr.ss_family, sin_addr, client->settings->hostname, 50);
printf("Accepted client from %s.\n", client->settings->hostname);
inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname));
IFCALL(instance->PeerAccepted, instance, client);
}

View File

@ -21,19 +21,15 @@
static boolean freerdp_peer_initialize(freerdp_peer* client)
{
rdpPeer* peer = (rdpPeer*)client->peer;
peer->rdp->settings->server_mode = True;
peer->rdp->state = CONNECTION_STATE_INITIAL;
client->context->rdp->settings->server_mode = True;
client->context->rdp->state = CONNECTION_STATE_INITIAL;
return True;
}
static boolean freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
{
rdpPeer* peer = (rdpPeer*)client->peer;
rfds[*rcount] = (void*)(long)(peer->rdp->transport->tcp->sockfd);
rfds[*rcount] = (void*)(long)(client->context->rdp->transport->tcp->sockfd);
(*rcount)++;
return True;
@ -41,11 +37,10 @@ static boolean freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcou
static boolean freerdp_peer_check_fds(freerdp_peer* client)
{
rdpPeer* peer = (rdpPeer*)client->peer;
rdpRdp* rdp;
int status;
rdp = (rdpRdp*) peer->rdp;
rdp = client->context->rdp;
status = rdp_check_fds(rdp);
if (status < 0)
@ -54,7 +49,7 @@ static boolean freerdp_peer_check_fds(freerdp_peer* client)
return True;
}
static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
{
uint8 type;
uint16 length;
@ -74,7 +69,7 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
break;
case DATA_PDU_TYPE_CONTROL:
if (!rdp_server_accept_client_control_pdu(peer->rdp, s))
if (!rdp_server_accept_client_control_pdu(client->context->rdp, s))
return False;
break;
@ -83,28 +78,28 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
break;
case DATA_PDU_TYPE_FONT_LIST:
if (!rdp_server_accept_client_font_list_pdu(peer->rdp, s))
if (!rdp_server_accept_client_font_list_pdu(client->context->rdp, s))
return False;
if (peer->client->PostConnect)
if (client->PostConnect)
{
if (!peer->client->PostConnect(peer->client))
if (!client->PostConnect(client))
return False;
/**
* PostConnect should only be called once and should not be called
* after a reactivation sequence.
*/
peer->client->PostConnect = NULL;
client->PostConnect = NULL;
}
if (peer->client->Activate)
if (client->Activate)
{
/* Activate will be called everytime after the client is activated/reactivated. */
if (!peer->client->Activate(peer->client))
if (!client->Activate(client))
return False;
}
break;
case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
mcs_send_disconnect_provider_ultimatum(peer->rdp->mcs);
mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs);
return False;
default:
@ -115,14 +110,14 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
return True;
}
static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
static boolean peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
{
uint16 length;
uint16 pduType;
uint16 pduLength;
uint16 channelId;
if (!rdp_read_header(peer->rdp, s, &length, &channelId))
if (!rdp_read_header(client->context->rdp, s, &length, &channelId))
{
printf("Incorrect RDP header.\n");
return False;
@ -134,13 +129,13 @@ static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
}
else
{
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &peer->rdp->settings->pdu_source))
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &client->settings->pdu_source))
return False;
switch (pduType)
{
case PDU_TYPE_DATA:
if (!peer_recv_data_pdu(peer, s))
if (!peer_recv_data_pdu(client, s))
return False;
break;
@ -153,13 +148,13 @@ static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
return True;
}
static boolean peer_recv_fastpath_pdu(rdpPeer* peer, STREAM* s)
static boolean peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s)
{
uint16 length;
rdpRdp* rdp;
rdpFastPath* fastpath;
rdp = peer->rdp;
rdp = client->context->rdp;
fastpath = rdp->fastpath;
length = fastpath_read_header_rdp(fastpath, s);
@ -177,62 +172,62 @@ static boolean peer_recv_fastpath_pdu(rdpPeer* peer, STREAM* s)
return fastpath_recv_inputs(fastpath, s);
}
static boolean peer_recv_pdu(rdpPeer* peer, STREAM* s)
static boolean peer_recv_pdu(freerdp_peer* client, STREAM* s)
{
if (tpkt_verify_header(s))
return peer_recv_tpkt_pdu(peer, s);
return peer_recv_tpkt_pdu(client, s);
else
return peer_recv_fastpath_pdu(peer, s);
return peer_recv_fastpath_pdu(client, s);
}
static boolean peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
{
rdpPeer* peer = (rdpPeer*) extra;
freerdp_peer* client = (freerdp_peer*) extra;
switch (peer->rdp->state)
switch (client->context->rdp->state)
{
case CONNECTION_STATE_INITIAL:
if (!rdp_server_accept_nego(peer->rdp, s))
if (!rdp_server_accept_nego(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_NEGO:
if (!rdp_server_accept_mcs_connect_initial(peer->rdp, s))
if (!rdp_server_accept_mcs_connect_initial(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_MCS_CONNECT:
if (!rdp_server_accept_mcs_erect_domain_request(peer->rdp, s))
if (!rdp_server_accept_mcs_erect_domain_request(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_MCS_ERECT_DOMAIN:
if (!rdp_server_accept_mcs_attach_user_request(peer->rdp, s))
if (!rdp_server_accept_mcs_attach_user_request(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_MCS_ATTACH_USER:
if (!rdp_server_accept_mcs_channel_join_request(peer->rdp, s))
if (!rdp_server_accept_mcs_channel_join_request(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
if (!rdp_server_accept_client_info(peer->rdp, s))
if (!rdp_server_accept_client_info(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_LICENSE:
if (!rdp_server_accept_confirm_active(peer->rdp, s))
if (!rdp_server_accept_confirm_active(client->context->rdp, s))
return False;
break;
case CONNECTION_STATE_ACTIVE:
if (!peer_recv_pdu(peer, s))
if (!peer_recv_pdu(client, s))
return False;
break;
default:
printf("Invalid state %d\n", peer->rdp->state);
printf("Invalid state %d\n", client->context->rdp->state);
return False;
}
@ -241,49 +236,65 @@ static boolean peer_recv_callback(rdpTransport* transport, STREAM* s, void* extr
static void freerdp_peer_disconnect(freerdp_peer* client)
{
rdpPeer* peer = (rdpPeer*) client->peer;
transport_disconnect(client->context->rdp->transport);
}
transport_disconnect(peer->rdp->transport);
void freerdp_peer_context_new(freerdp_peer* client)
{
rdpRdp* rdp;
uint32 size = sizeof(rdpContext);
rdp = rdp_new(NULL);
client->input = rdp->input;
client->update = rdp->update;
client->settings = rdp->settings;
IFCALL(client->ContextSize, client, &size);
client->context = (rdpContext*) xzalloc(size);
client->context->rdp = rdp;
client->context->peer = client;
client->update->context = client->context;
client->input->context = client->context;
update_register_server_callbacks(client->update);
transport_attach(rdp->transport, client->sockfd);
rdp->transport->recv_callback = peer_recv_callback;
rdp->transport->recv_extra = client;
transport_set_blocking_mode(rdp->transport, False);
IFCALL(client->ContextNew, client, client->context);
}
void freerdp_peer_context_free(freerdp_peer* client)
{
IFCALL(client->ContextFree, client, client->context);
}
freerdp_peer* freerdp_peer_new(int sockfd)
{
freerdp_peer* client;
rdpPeer* peer;
client = xnew(freerdp_peer);
client->sockfd = sockfd;
client->Initialize = freerdp_peer_initialize;
client->GetFileDescriptor = freerdp_peer_get_fds;
client->CheckFileDescriptor = freerdp_peer_check_fds;
client->Disconnect = freerdp_peer_disconnect;
peer = xnew(rdpPeer);
peer->client = client;
peer->rdp = rdp_new(NULL);
client->peer = (void*) peer;
client->settings = peer->rdp->settings;
client->input = peer->rdp->input;
client->update = peer->rdp->update;
update_register_server_callbacks(client->update);
transport_attach(peer->rdp->transport, sockfd);
peer->rdp->transport->recv_callback = peer_recv_callback;
peer->rdp->transport->recv_extra = peer;
transport_set_blocking_mode(peer->rdp->transport, False);
return client;
}
void freerdp_peer_free(freerdp_peer* client)
{
rdpPeer* peer = (rdpPeer*)client->peer;
rdp_free(peer->rdp);
xfree(peer);
xfree(client);
if (client)
{
rdp_free(client->context->rdp);
xfree(client);
}
}

View File

@ -20,17 +20,8 @@
#ifndef __PEER
#define __PEER
typedef struct rdp_peer rdpPeer;
#include "rdp.h"
#include <freerdp/peer.h>
struct rdp_peer
{
freerdp_peer* client;
rdpRdp* rdp;
};
#endif /* __PEER */

View File

@ -32,40 +32,123 @@ extern char* xf_pcap_file;
#include "xf_peer.h"
void xf_peer_init(freerdp_peer* client)
xfInfo* xf_info_init()
{
xfPeer* info;
int i;
xfInfo* xfi;
int pf_count;
int vi_count;
XVisualInfo* vi;
XVisualInfo* vis;
XVisualInfo template;
XPixmapFormatValues* pf;
XPixmapFormatValues* pfs;
info = xnew(xfPeer);
xfi = xnew(xfInfo);
info->context = rfx_context_new();
info->context->mode = RLGR3;
info->context->width = client->settings->width;
info->context->height = client->settings->height;
rfx_context_set_pixel_format(info->context, RFX_PIXEL_FORMAT_RGB);
xfi->display = XOpenDisplay(NULL);
info->s = stream_new(65536);
if (xfi->display == NULL)
printf("failed to open display: %s\n", XDisplayName(NULL));
client->param1 = info;
xfi->number = DefaultScreen(xfi->display);
xfi->screen = ScreenOfDisplay(xfi->display, xfi->number);
xfi->depth = DefaultDepthOfScreen(xfi->screen);
xfi->width = WidthOfScreen(xfi->screen);
xfi->height = HeightOfScreen(xfi->screen);
pfs = XListPixmapFormats(xfi->display, &pf_count);
if (pfs == NULL)
{
printf("XListPixmapFormats failed\n");
exit(1);
}
for (i = 0; i < pf_count; i++)
{
pf = pfs + i;
if (pf->depth == xfi->depth)
{
xfi->bpp = pf->bits_per_pixel;
xfi->scanline_pad = pf->scanline_pad;
break;
}
}
XFree(pfs);
memset(&template, 0, sizeof(template));
template.class = TrueColor;
template.screen = xfi->number;
vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
if (vis == NULL)
{
printf("XGetVisualInfo failed\n");
exit(1);
}
for (i = 0; i < vi_count; i++)
{
vi = vis + i;
if (vi->depth == xfi->depth)
{
xfi->visual = vi->visual;
break;
}
}
XFree(vis);
xfi->clrconv = (HCLRCONV) xnew(HCLRCONV);
xfi->clrconv->invert = 1;
xfi->clrconv->alpha = 1;
return xfi;
}
void xf_peer_uninit(freerdp_peer* client)
void xf_peer_context_size(freerdp_peer* client, uint32* size)
{
xfPeer* info = (xfPeer*) client->param1;
*size = sizeof(xfPeerContext);
}
if (info)
void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context)
{
context->info = xf_info_init();
context->rfx_context = rfx_context_new();
context->rfx_context->mode = RLGR3;
context->rfx_context->width = client->settings->width;
context->rfx_context->height = client->settings->height;
rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_RGB);
context->s = stream_new(65536);
}
void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context)
{
if (context)
{
stream_free(info->s);
rfx_context_free(info->context);
xfree(info);
stream_free(context->s);
rfx_context_free(context->rfx_context);
xfree(context);
}
}
STREAM* xf_peer_stream_init(xfPeer* info)
void xf_peer_init(freerdp_peer* client)
{
stream_clear(info->s);
stream_set_pos(info->s, 0);
return info->s;
client->ContextSize = (psPeerContextSize) xf_peer_context_size;
client->ContextNew = (psPeerContextNew) xf_peer_context_new;
client->ContextFree = (psPeerContextFree) xf_peer_context_free;
freerdp_peer_context_new(client);
}
STREAM* xf_peer_stream_init(xfPeerContext* context)
{
stream_clear(context->s);
stream_set_pos(context->s, 0);
return context->s;
}
void xf_peer_live_rfx(freerdp_peer* client)
@ -79,19 +162,19 @@ void xf_peer_live_rfx(freerdp_peer* client)
int nrects;
uint8* data;
xfInfo* xfi;
xfPeer* xfp;
XImage* image;
RFX_RECT* rects;
uint32 seconds;
uint32 useconds;
rdpUpdate* update;
xfPeerContext* xfp;
SURFACE_BITS_COMMAND* cmd;
seconds = 1;
useconds = 0;
update = client->update;
xfi = (xfInfo*) client->info;
xfp = (xfPeer*) client->param1;
xfp = (xfPeerContext*) client->context;
xfi = (xfInfo*) xfp->info;
cmd = &update->surface_bits_command;
wrects = 16;
@ -128,7 +211,7 @@ void xf_peer_live_rfx(freerdp_peer* client)
image = xf_snapshot(xfi, 0, 0, width, height);
freerdp_image_convert((uint8*) image->data, data, width, height, 32, 24, xfi->clrconv);
rfx_compose_message(xfp->context, s, rects, nrects, data, width, height, 64 * wrects * 3);
rfx_compose_message(xfp->rfx_context, s, rects, nrects, data, width, height, 64 * wrects * 3);
cmd->destLeft = 0;
cmd->destTop = 0;
@ -198,7 +281,7 @@ boolean xf_peer_post_connect(freerdp_peer* client)
* The server may start sending graphics output and receiving keyboard/mouse input after this
* callback returns.
*/
printf("Client %s is activated", client->settings->hostname);
printf("Client %s is activated", client->hostname);
if (client->settings->autologon)
{
printf(" and wants to login automatically as %s\\%s",
@ -213,7 +296,6 @@ boolean xf_peer_post_connect(freerdp_peer* client)
client->settings->width, client->settings->height, client->settings->color_depth);
/* A real server should tag the peer as activated here and start sending updates in mainloop. */
xf_peer_init(client);
/* Return False here would stop the execution of the peer mainloop. */
return True;
@ -221,9 +303,9 @@ boolean xf_peer_post_connect(freerdp_peer* client)
boolean xf_peer_activate(freerdp_peer* client)
{
xfPeer* xfp = (xfPeer*) client->param1;
xfPeerContext* xfp = (xfPeerContext*) client->context;
rfx_context_reset(xfp->context);
rfx_context_reset(xfp->rfx_context);
xfp->activated = True;
if (xf_pcap_file != NULL)
@ -246,9 +328,9 @@ void xf_peer_synchronize_event(rdpInput* input, uint32 flags)
void xf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
{
freerdp_peer* client = (freerdp_peer*) input->param1;
freerdp_peer* client = (freerdp_peer*) input->context->peer;
rdpUpdate* update = client->update;
xfPeer* xfp = (xfPeer*) client->param1;
xfPeerContext* xfp = (xfPeerContext*) input->context;
printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
@ -296,7 +378,9 @@ void* xf_peer_main_loop(void* arg)
memset(rfds, 0, sizeof(rfds));
printf("We've got a client %s\n", client->settings->hostname);
printf("We've got a client %s\n", client->hostname);
xf_peer_init(client);
/* Initialize the real server settings here */
client->settings->cert_file = xstrdup("server.crt");
@ -307,7 +391,6 @@ void* xf_peer_main_loop(void* arg)
client->PostConnect = xf_peer_post_connect;
client->Activate = xf_peer_activate;
client->input->param1 = client;
client->input->SynchronizeEvent = xf_peer_synchronize_event;
client->input->KeyboardEvent = xf_peer_keyboard_event;
client->input->UnicodeKeyboardEvent = xf_peer_unicode_keyboard_event;
@ -359,10 +442,10 @@ void* xf_peer_main_loop(void* arg)
break;
}
printf("Client %s disconnected.\n", client->settings->hostname);
printf("Client %s disconnected.\n", client->hostname);
client->Disconnect(client);
xf_peer_uninit(client);
freerdp_peer_context_free(client);
freerdp_peer_free(client);
return NULL;
@ -372,7 +455,6 @@ void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
{
pthread_t th;
client->info = instance->info;
pthread_create(&th, 0, xf_peer_main_loop, client);
pthread_detach(th);
}

View File

@ -24,13 +24,18 @@
#include <freerdp/listener.h>
#include <freerdp/utils/stream.h>
struct xf_peer_info
#include "xfreerdp.h"
struct xf_peer_context
{
rdpContext _p;
STREAM* s;
xfInfo* info;
boolean activated;
RFX_CONTEXT* context;
RFX_CONTEXT* rfx_context;
};
typedef struct xf_peer_info xfPeer;
typedef struct xf_peer_context xfPeerContext;
void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);

View File

@ -27,83 +27,6 @@
char* xf_pcap_file = NULL;
xfInfo* xf_info_init()
{
int i;
xfInfo* xfi;
int pf_count;
int vi_count;
XVisualInfo* vi;
XVisualInfo* vis;
XVisualInfo template;
XPixmapFormatValues* pf;
XPixmapFormatValues* pfs;
xfi = xnew(xfInfo);
xfi->display = XOpenDisplay(NULL);
if (xfi->display == NULL)
printf("failed to open display: %s\n", XDisplayName(NULL));
xfi->number = DefaultScreen(xfi->display);
xfi->screen = ScreenOfDisplay(xfi->display, xfi->number);
xfi->depth = DefaultDepthOfScreen(xfi->screen);
xfi->width = WidthOfScreen(xfi->screen);
xfi->height = HeightOfScreen(xfi->screen);
pfs = XListPixmapFormats(xfi->display, &pf_count);
if (pfs == NULL)
{
printf("XListPixmapFormats failed\n");
exit(1);
}
for (i = 0; i < pf_count; i++)
{
pf = pfs + i;
if (pf->depth == xfi->depth)
{
xfi->bpp = pf->bits_per_pixel;
xfi->scanline_pad = pf->scanline_pad;
break;
}
}
XFree(pfs);
memset(&template, 0, sizeof(template));
template.class = TrueColor;
template.screen = xfi->number;
vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
if (vis == NULL)
{
printf("XGetVisualInfo failed\n");
exit(1);
}
for (i = 0; i < vi_count; i++)
{
vi = vis + i;
if (vi->depth == xfi->depth)
{
xfi->visual = vi->visual;
break;
}
}
XFree(vis);
xfi->clrconv = (HCLRCONV) xnew(HCLRCONV);
xfi->clrconv->invert = 1;
xfi->clrconv->alpha = 1;
return xfi;
}
void xf_server_main_loop(freerdp_listener* instance)
{
int i;
@ -172,7 +95,6 @@ int main(int argc, char* argv[])
signal(SIGPIPE, SIG_IGN);
instance = freerdp_listener_new();
instance->info = (void*) xf_info_init();
instance->PeerAccepted = xf_peer_accepted;
if (argc > 1)

View File

@ -40,9 +40,11 @@ static const unsigned int test_quantization_values[] =
6, 6, 6, 6, 7, 7, 8, 8, 8, 9
};
struct test_peer_info
struct test_peer_context
{
RFX_CONTEXT* context;
rdpContext _p;
RFX_CONTEXT* rfx_context;
STREAM* s;
uint8* icon_data;
uint8* bg_data;
@ -52,52 +54,57 @@ struct test_peer_info
int icon_y;
boolean activated;
};
typedef struct test_peer_info testPeerInfo;
typedef struct test_peer_context testPeerContext;
static void test_peer_init(freerdp_peer* client)
void test_peer_context_size(freerdp_peer* client, uint32* size)
{
testPeerInfo* info;
info = xnew(testPeerInfo);
info->context = rfx_context_new();
info->context->mode = RLGR3;
info->context->width = client->settings->width;
info->context->height = client->settings->height;
rfx_context_set_pixel_format(info->context, RFX_PIXEL_FORMAT_RGB);
info->s = stream_new(65536);
info->icon_x = -1;
info->icon_y = -1;
client->param1 = info;
*size = sizeof(testPeerContext);
}
static void test_peer_uninit(freerdp_peer* client)
void test_peer_context_new(freerdp_peer* client, testPeerContext* context)
{
testPeerInfo* info = (testPeerInfo*)client->param1;
context->rfx_context = rfx_context_new();
context->rfx_context->mode = RLGR3;
context->rfx_context->width = client->settings->width;
context->rfx_context->height = client->settings->height;
rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_RGB);
if (info)
context->s = stream_new(65536);
context->icon_x = -1;
context->icon_y = -1;
}
void test_peer_context_free(freerdp_peer* client, testPeerContext* context)
{
if (context)
{
stream_free(info->s);
xfree(info->icon_data);
xfree(info->bg_data);
rfx_context_free(info->context);
xfree(info);
stream_free(context->s);
xfree(context->icon_data);
xfree(context->bg_data);
rfx_context_free(context->rfx_context);
xfree(context);
}
}
static STREAM* test_peer_stream_init(testPeerInfo* info)
static void test_peer_init(freerdp_peer* client)
{
stream_clear(info->s);
stream_set_pos(info->s, 0);
return info->s;
client->ContextSize = (psPeerContextSize) test_peer_context_size;
client->ContextNew = (psPeerContextNew) test_peer_context_new;
client->ContextFree = (psPeerContextFree) test_peer_context_free;
freerdp_peer_context_new(client);
}
static STREAM* test_peer_stream_init(testPeerContext* context)
{
stream_clear(context->s);
stream_set_pos(context->s, 0);
return context->s;
}
static void test_peer_draw_background(freerdp_peer* client)
{
testPeerInfo* info = (testPeerInfo*)client->param1;
testPeerContext* context = (testPeerContext*) client->context;
rdpUpdate* update = client->update;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
STREAM* s;
@ -108,7 +115,7 @@ static void test_peer_draw_background(freerdp_peer* client)
if (!client->settings->rfx_codec)
return;
s = test_peer_stream_init(info);
s = test_peer_stream_init(context);
rect.x = 0;
rect.y = 0;
@ -119,7 +126,7 @@ static void test_peer_draw_background(freerdp_peer* client)
rgb_data = xmalloc(size);
memset(rgb_data, 0xA0, size);
rfx_compose_message(info->context, s,
rfx_compose_message(context->rfx_context, s,
&rect, 1, rgb_data, rect.width, rect.height, rect.width * 3);
cmd->destLeft = 0;
@ -139,7 +146,7 @@ static void test_peer_draw_background(freerdp_peer* client)
static void test_peer_load_icon(freerdp_peer* client)
{
testPeerInfo* info = (testPeerInfo*)client->param1;
testPeerContext* context = (testPeerContext*) client->context;
FILE* fp;
int i;
char line[50];
@ -158,13 +165,13 @@ static void test_peer_load_icon(freerdp_peer* client)
fgets(line, sizeof(line), fp);
/* width height */
fgets(line, sizeof(line), fp);
sscanf(line, "%d %d", &info->icon_width, &info->icon_height);
sscanf(line, "%d %d", &context->icon_width, &context->icon_height);
/* Max */
fgets(line, sizeof(line), fp);
rgb_data = xmalloc(info->icon_width * info->icon_height * 3);
rgb_data = xmalloc(context->icon_width * context->icon_height * 3);
for (i = 0; i < info->icon_width * info->icon_height * 3; i++)
for (i = 0; i < context->icon_width * context->icon_height * 3; i++)
{
if (fgets(line, sizeof(line), fp))
{
@ -173,16 +180,16 @@ static void test_peer_load_icon(freerdp_peer* client)
}
}
info->icon_data = rgb_data;
context->icon_data = rgb_data;
/* background with same size, which will be used to erase the icon from old position */
info->bg_data = xmalloc(info->icon_width * info->icon_height * 3);
memset(info->bg_data, 0xA0, info->icon_width * info->icon_height * 3);
context->bg_data = xmalloc(context->icon_width * context->icon_height * 3);
memset(context->bg_data, 0xA0, context->icon_width * context->icon_height * 3);
}
static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
{
testPeerInfo* info = (testPeerInfo*)client->param1;
testPeerContext* context = (testPeerContext*) client->context;
rdpUpdate* update = client->update;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
RFX_RECT rect;
@ -190,53 +197,53 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
if (client->update->dump_rfx)
return;
if (!client->settings->rfx_codec || !info)
if (!client->settings->rfx_codec || !context)
return;
if (info->icon_width < 1 || !info->activated)
if (context->icon_width < 1 || !context->activated)
return;
rect.x = 0;
rect.y = 0;
rect.width = info->icon_width;
rect.height = info->icon_height;
rect.width = context->icon_width;
rect.height = context->icon_height;
if (info->icon_x >= 0)
if (context->icon_x >= 0)
{
s = test_peer_stream_init(info);
rfx_compose_message(info->context, s,
&rect, 1, info->bg_data, rect.width, rect.height, rect.width * 3);
s = test_peer_stream_init(context);
rfx_compose_message(context->rfx_context, s,
&rect, 1, context->bg_data, rect.width, rect.height, rect.width * 3);
cmd->destLeft = info->icon_x;
cmd->destTop = info->icon_y;
cmd->destRight = info->icon_x + info->icon_width;
cmd->destBottom = info->icon_y + info->icon_height;
cmd->destLeft = context->icon_x;
cmd->destTop = context->icon_y;
cmd->destRight = context->icon_x + context->icon_width;
cmd->destBottom = context->icon_y + context->icon_height;
cmd->bpp = 32;
cmd->codecID = client->settings->rfx_codec_id;
cmd->width = info->icon_width;
cmd->height = info->icon_height;
cmd->width = context->icon_width;
cmd->height = context->icon_height;
cmd->bitmapDataLength = stream_get_length(s);
cmd->bitmapData = stream_get_head(s);
update->SurfaceBits(update, cmd);
}
s = test_peer_stream_init(info);
rfx_compose_message(info->context, s,
&rect, 1, info->icon_data, rect.width, rect.height, rect.width * 3);
s = test_peer_stream_init(context);
rfx_compose_message(context->rfx_context, s,
&rect, 1, context->icon_data, rect.width, rect.height, rect.width * 3);
cmd->destLeft = x;
cmd->destTop = y;
cmd->destRight = x + info->icon_width;
cmd->destBottom = y + info->icon_height;
cmd->destRight = x + context->icon_width;
cmd->destBottom = y + context->icon_height;
cmd->bpp = 32;
cmd->codecID = client->settings->rfx_codec_id;
cmd->width = info->icon_width;
cmd->height = info->icon_height;
cmd->width = context->icon_width;
cmd->height = context->icon_height;
cmd->bitmapDataLength = stream_get_length(s);
cmd->bitmapData = stream_get_head(s);
update->SurfaceBits(update, cmd);
info->icon_x = x;
info->icon_y = y;
context->icon_x = x;
context->icon_y = y;
}
void tf_peer_dump_rfx(freerdp_peer* client)
@ -287,7 +294,7 @@ boolean tf_peer_post_connect(freerdp_peer* client)
* The server may start sending graphics output and receiving keyboard/mouse input after this
* callback returns.
*/
printf("Client %s is activated", client->settings->hostname);
printf("Client %s is activated", client->hostname);
if (client->settings->autologon)
{
printf(" and wants to login automatically as %s\\%s",
@ -302,7 +309,6 @@ boolean tf_peer_post_connect(freerdp_peer* client)
client->settings->width, client->settings->height, client->settings->color_depth);
/* A real server should tag the peer as activated here and start sending updates in mainloop. */
test_peer_init(client);
test_peer_load_icon(client);
/* Return False here would stop the execution of the peer mainloop. */
@ -311,10 +317,10 @@ boolean tf_peer_post_connect(freerdp_peer* client)
boolean tf_peer_activate(freerdp_peer* client)
{
testPeerInfo* info = (testPeerInfo*)client->param1;
testPeerContext* context = (testPeerContext*) client->context;
rfx_context_reset(info->context);
info->activated = True;
rfx_context_reset(context->rfx_context);
context->activated = True;
if (test_pcap_file != NULL)
{
@ -336,9 +342,9 @@ void tf_peer_synchronize_event(rdpInput* input, uint32 flags)
void tf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
{
freerdp_peer* client = (freerdp_peer*) input->param1;
freerdp_peer* client = input->context->peer;
rdpUpdate* update = client->update;
testPeerInfo* info = (testPeerInfo*)client->param1;
testPeerContext* context = (testPeerContext*) input->context;
printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
@ -355,7 +361,7 @@ void tf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
client->settings->height = 480;
}
update->DesktopResize(update);
info->activated = False;
context->activated = False;
}
}
@ -368,7 +374,7 @@ void tf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
{
printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
test_peer_draw_icon(input->param1, x + 10, y);
test_peer_draw_icon(input->context->peer, x + 10, y);
}
void tf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
@ -388,7 +394,7 @@ static void* test_peer_mainloop(void* arg)
memset(rfds, 0, sizeof(rfds));
printf("We've got a client %s\n", client->settings->hostname);
test_peer_init(client);
/* Initialize the real server settings here */
client->settings->cert_file = xstrdup("server.crt");
@ -399,7 +405,6 @@ static void* test_peer_mainloop(void* arg)
client->PostConnect = tf_peer_post_connect;
client->Activate = tf_peer_activate;
client->input->param1 = client;
client->input->SynchronizeEvent = tf_peer_synchronize_event;
client->input->KeyboardEvent = tf_peer_keyboard_event;
client->input->UnicodeKeyboardEvent = tf_peer_unicode_keyboard_event;
@ -408,6 +413,8 @@ static void* test_peer_mainloop(void* arg)
client->Initialize(client);
printf("We've got a client %s\n", client->hostname);
while (1)
{
rcount = 0;
@ -451,10 +458,10 @@ static void* test_peer_mainloop(void* arg)
break;
}
printf("Client %s disconnected.\n", client->settings->hostname);
printf("Client %s disconnected.\n", client->hostname);
client->Disconnect(client);
test_peer_uninit(client);
freerdp_peer_context_free(client);
freerdp_peer_free(client);
return NULL;