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

View File

@ -20,14 +20,16 @@
#ifndef __FREERDP_PEER_H #ifndef __FREERDP_PEER_H
#define __FREERDP_PEER_H #define __FREERDP_PEER_H
typedef struct rdp_freerdp_peer freerdp_peer;
#include <freerdp/api.h> #include <freerdp/api.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/settings.h> #include <freerdp/settings.h>
#include <freerdp/input.h> #include <freerdp/input.h>
#include <freerdp/update.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 (*psPeerInitialize)(freerdp_peer* client);
typedef boolean (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount); typedef boolean (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount);
typedef boolean (*psPeerCheckFileDescriptor)(freerdp_peer* client); typedef boolean (*psPeerCheckFileDescriptor)(freerdp_peer* client);
@ -37,17 +39,18 @@ typedef boolean (*psPeerActivate)(freerdp_peer* client);
struct rdp_freerdp_peer struct rdp_freerdp_peer
{ {
void* info; rdpContext* context;
void* peer; int sockfd;
void* param1; char hostname[50];
void* param2;
void* param3;
void* param4;
rdpInput* input; rdpInput* input;
rdpUpdate* update; rdpUpdate* update;
rdpSettings* settings; rdpSettings* settings;
psPeerContextSize ContextSize;
psPeerContextNew ContextNew;
psPeerContextFree ContextFree;
psPeerInitialize Initialize; psPeerInitialize Initialize;
psPeerGetFileDescriptor GetFileDescriptor; psPeerGetFileDescriptor GetFileDescriptor;
psPeerCheckFileDescriptor CheckFileDescriptor; psPeerCheckFileDescriptor CheckFileDescriptor;
@ -57,6 +60,9 @@ struct rdp_freerdp_peer
psPeerActivate Activate; 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 freerdp_peer* freerdp_peer_new(int sockfd);
FREERDP_API void freerdp_peer_free(freerdp_peer* client); 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); sin_addr = &(((struct sockaddr_in*)&peer_addr)->sin_addr);
else else
sin_addr = &(((struct sockaddr_in6*)&peer_addr)->sin6_addr); sin_addr = &(((struct sockaddr_in6*)&peer_addr)->sin6_addr);
client->settings->hostname = xzalloc(50); inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname));
inet_ntop(peer_addr.ss_family, sin_addr, client->settings->hostname, 50);
printf("Accepted client from %s.\n", client->settings->hostname);
IFCALL(instance->PeerAccepted, instance, client); IFCALL(instance->PeerAccepted, instance, client);
} }

View File

@ -21,19 +21,15 @@
static boolean freerdp_peer_initialize(freerdp_peer* client) static boolean freerdp_peer_initialize(freerdp_peer* client)
{ {
rdpPeer* peer = (rdpPeer*)client->peer; client->context->rdp->settings->server_mode = True;
client->context->rdp->state = CONNECTION_STATE_INITIAL;
peer->rdp->settings->server_mode = True;
peer->rdp->state = CONNECTION_STATE_INITIAL;
return True; return True;
} }
static boolean freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) static boolean freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
{ {
rdpPeer* peer = (rdpPeer*)client->peer; rfds[*rcount] = (void*)(long)(client->context->rdp->transport->tcp->sockfd);
rfds[*rcount] = (void*)(long)(peer->rdp->transport->tcp->sockfd);
(*rcount)++; (*rcount)++;
return True; 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) static boolean freerdp_peer_check_fds(freerdp_peer* client)
{ {
rdpPeer* peer = (rdpPeer*)client->peer;
rdpRdp* rdp; rdpRdp* rdp;
int status; int status;
rdp = (rdpRdp*) peer->rdp; rdp = client->context->rdp;
status = rdp_check_fds(rdp); status = rdp_check_fds(rdp);
if (status < 0) if (status < 0)
@ -54,7 +49,7 @@ static boolean freerdp_peer_check_fds(freerdp_peer* client)
return True; 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; uint8 type;
uint16 length; uint16 length;
@ -74,7 +69,7 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
break; break;
case DATA_PDU_TYPE_CONTROL: 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; return False;
break; break;
@ -83,28 +78,28 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
break; break;
case DATA_PDU_TYPE_FONT_LIST: 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; return False;
if (peer->client->PostConnect) if (client->PostConnect)
{ {
if (!peer->client->PostConnect(peer->client)) if (!client->PostConnect(client))
return False; return False;
/** /**
* PostConnect should only be called once and should not be called * PostConnect should only be called once and should not be called
* after a reactivation sequence. * 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. */ /* Activate will be called everytime after the client is activated/reactivated. */
if (!peer->client->Activate(peer->client)) if (!client->Activate(client))
return False; return False;
} }
break; break;
case DATA_PDU_TYPE_SHUTDOWN_REQUEST: 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; return False;
default: default:
@ -115,14 +110,14 @@ static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
return True; 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 length;
uint16 pduType; uint16 pduType;
uint16 pduLength; uint16 pduLength;
uint16 channelId; 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"); printf("Incorrect RDP header.\n");
return False; return False;
@ -134,13 +129,13 @@ static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
} }
else 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; return False;
switch (pduType) switch (pduType)
{ {
case PDU_TYPE_DATA: case PDU_TYPE_DATA:
if (!peer_recv_data_pdu(peer, s)) if (!peer_recv_data_pdu(client, s))
return False; return False;
break; break;
@ -153,13 +148,13 @@ static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
return True; 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; uint16 length;
rdpRdp* rdp; rdpRdp* rdp;
rdpFastPath* fastpath; rdpFastPath* fastpath;
rdp = peer->rdp; rdp = client->context->rdp;
fastpath = rdp->fastpath; fastpath = rdp->fastpath;
length = fastpath_read_header_rdp(fastpath, s); 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); 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)) if (tpkt_verify_header(s))
return peer_recv_tpkt_pdu(peer, s); return peer_recv_tpkt_pdu(client, s);
else 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) 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: case CONNECTION_STATE_INITIAL:
if (!rdp_server_accept_nego(peer->rdp, s)) if (!rdp_server_accept_nego(client->context->rdp, s))
return False; return False;
break; break;
case CONNECTION_STATE_NEGO: 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; return False;
break; break;
case CONNECTION_STATE_MCS_CONNECT: 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; return False;
break; break;
case CONNECTION_STATE_MCS_ERECT_DOMAIN: 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; return False;
break; break;
case CONNECTION_STATE_MCS_ATTACH_USER: 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; return False;
break; break;
case CONNECTION_STATE_MCS_CHANNEL_JOIN: 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; return False;
break; break;
case CONNECTION_STATE_LICENSE: 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; return False;
break; break;
case CONNECTION_STATE_ACTIVE: case CONNECTION_STATE_ACTIVE:
if (!peer_recv_pdu(peer, s)) if (!peer_recv_pdu(client, s))
return False; return False;
break; break;
default: default:
printf("Invalid state %d\n", peer->rdp->state); printf("Invalid state %d\n", client->context->rdp->state);
return False; 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) 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* freerdp_peer_new(int sockfd)
{ {
freerdp_peer* client; freerdp_peer* client;
rdpPeer* peer;
client = xnew(freerdp_peer); client = xnew(freerdp_peer);
client->sockfd = sockfd;
client->Initialize = freerdp_peer_initialize; client->Initialize = freerdp_peer_initialize;
client->GetFileDescriptor = freerdp_peer_get_fds; client->GetFileDescriptor = freerdp_peer_get_fds;
client->CheckFileDescriptor = freerdp_peer_check_fds; client->CheckFileDescriptor = freerdp_peer_check_fds;
client->Disconnect = freerdp_peer_disconnect; 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; return client;
} }
void freerdp_peer_free(freerdp_peer* client) void freerdp_peer_free(freerdp_peer* client)
{ {
rdpPeer* peer = (rdpPeer*)client->peer; if (client)
{
rdp_free(peer->rdp); rdp_free(client->context->rdp);
xfree(peer); xfree(client);
xfree(client); }
} }

View File

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

View File

@ -32,40 +32,123 @@ extern char* xf_pcap_file;
#include "xf_peer.h" #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(); xfi->display = XOpenDisplay(NULL);
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); 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); stream_free(context->s);
rfx_context_free(info->context); rfx_context_free(context->rfx_context);
xfree(info); xfree(context);
} }
} }
STREAM* xf_peer_stream_init(xfPeer* info) void xf_peer_init(freerdp_peer* client)
{ {
stream_clear(info->s); client->ContextSize = (psPeerContextSize) xf_peer_context_size;
stream_set_pos(info->s, 0); client->ContextNew = (psPeerContextNew) xf_peer_context_new;
return info->s; 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) void xf_peer_live_rfx(freerdp_peer* client)
@ -79,19 +162,19 @@ void xf_peer_live_rfx(freerdp_peer* client)
int nrects; int nrects;
uint8* data; uint8* data;
xfInfo* xfi; xfInfo* xfi;
xfPeer* xfp;
XImage* image; XImage* image;
RFX_RECT* rects; RFX_RECT* rects;
uint32 seconds; uint32 seconds;
uint32 useconds; uint32 useconds;
rdpUpdate* update; rdpUpdate* update;
xfPeerContext* xfp;
SURFACE_BITS_COMMAND* cmd; SURFACE_BITS_COMMAND* cmd;
seconds = 1; seconds = 1;
useconds = 0; useconds = 0;
update = client->update; update = client->update;
xfi = (xfInfo*) client->info; xfp = (xfPeerContext*) client->context;
xfp = (xfPeer*) client->param1; xfi = (xfInfo*) xfp->info;
cmd = &update->surface_bits_command; cmd = &update->surface_bits_command;
wrects = 16; wrects = 16;
@ -128,7 +211,7 @@ void xf_peer_live_rfx(freerdp_peer* client)
image = xf_snapshot(xfi, 0, 0, width, height); image = xf_snapshot(xfi, 0, 0, width, height);
freerdp_image_convert((uint8*) image->data, data, width, height, 32, 24, xfi->clrconv); 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->destLeft = 0;
cmd->destTop = 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 * The server may start sending graphics output and receiving keyboard/mouse input after this
* callback returns. * callback returns.
*/ */
printf("Client %s is activated", client->settings->hostname); printf("Client %s is activated", client->hostname);
if (client->settings->autologon) if (client->settings->autologon)
{ {
printf(" and wants to login automatically as %s\\%s", 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); 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. */ /* 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 False here would stop the execution of the peer mainloop. */
return True; return True;
@ -221,9 +303,9 @@ boolean xf_peer_post_connect(freerdp_peer* client)
boolean xf_peer_activate(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; xfp->activated = True;
if (xf_pcap_file != NULL) 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) 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; 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); 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)); 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 */ /* Initialize the real server settings here */
client->settings->cert_file = xstrdup("server.crt"); 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->PostConnect = xf_peer_post_connect;
client->Activate = xf_peer_activate; client->Activate = xf_peer_activate;
client->input->param1 = client;
client->input->SynchronizeEvent = xf_peer_synchronize_event; client->input->SynchronizeEvent = xf_peer_synchronize_event;
client->input->KeyboardEvent = xf_peer_keyboard_event; client->input->KeyboardEvent = xf_peer_keyboard_event;
client->input->UnicodeKeyboardEvent = xf_peer_unicode_keyboard_event; client->input->UnicodeKeyboardEvent = xf_peer_unicode_keyboard_event;
@ -359,10 +442,10 @@ void* xf_peer_main_loop(void* arg)
break; break;
} }
printf("Client %s disconnected.\n", client->settings->hostname); printf("Client %s disconnected.\n", client->hostname);
client->Disconnect(client); client->Disconnect(client);
xf_peer_uninit(client); freerdp_peer_context_free(client);
freerdp_peer_free(client); freerdp_peer_free(client);
return NULL; return NULL;
@ -372,7 +455,6 @@ void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
{ {
pthread_t th; pthread_t th;
client->info = instance->info;
pthread_create(&th, 0, xf_peer_main_loop, client); pthread_create(&th, 0, xf_peer_main_loop, client);
pthread_detach(th); pthread_detach(th);
} }

View File

@ -24,13 +24,18 @@
#include <freerdp/listener.h> #include <freerdp/listener.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
struct xf_peer_info #include "xfreerdp.h"
struct xf_peer_context
{ {
rdpContext _p;
STREAM* s; STREAM* s;
xfInfo* info;
boolean activated; 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); void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);

View File

@ -27,83 +27,6 @@
char* xf_pcap_file = NULL; 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) void xf_server_main_loop(freerdp_listener* instance)
{ {
int i; int i;
@ -172,7 +95,6 @@ int main(int argc, char* argv[])
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
instance = freerdp_listener_new(); instance = freerdp_listener_new();
instance->info = (void*) xf_info_init();
instance->PeerAccepted = xf_peer_accepted; instance->PeerAccepted = xf_peer_accepted;
if (argc > 1) 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 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; STREAM* s;
uint8* icon_data; uint8* icon_data;
uint8* bg_data; uint8* bg_data;
@ -52,52 +54,57 @@ struct test_peer_info
int icon_y; int icon_y;
boolean activated; 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; *size = sizeof(testPeerContext);
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;
} }
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); stream_free(context->s);
xfree(info->icon_data); xfree(context->icon_data);
xfree(info->bg_data); xfree(context->bg_data);
rfx_context_free(info->context); rfx_context_free(context->rfx_context);
xfree(info); xfree(context);
} }
} }
static STREAM* test_peer_stream_init(testPeerInfo* info) static void test_peer_init(freerdp_peer* client)
{ {
stream_clear(info->s); client->ContextSize = (psPeerContextSize) test_peer_context_size;
stream_set_pos(info->s, 0); client->ContextNew = (psPeerContextNew) test_peer_context_new;
return info->s; 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) static void test_peer_draw_background(freerdp_peer* client)
{ {
testPeerInfo* info = (testPeerInfo*)client->param1; testPeerContext* context = (testPeerContext*) client->context;
rdpUpdate* update = client->update; rdpUpdate* update = client->update;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
STREAM* s; STREAM* s;
@ -108,7 +115,7 @@ static void test_peer_draw_background(freerdp_peer* client)
if (!client->settings->rfx_codec) if (!client->settings->rfx_codec)
return; return;
s = test_peer_stream_init(info); s = test_peer_stream_init(context);
rect.x = 0; rect.x = 0;
rect.y = 0; rect.y = 0;
@ -119,7 +126,7 @@ static void test_peer_draw_background(freerdp_peer* client)
rgb_data = xmalloc(size); rgb_data = xmalloc(size);
memset(rgb_data, 0xA0, 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); &rect, 1, rgb_data, rect.width, rect.height, rect.width * 3);
cmd->destLeft = 0; 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) static void test_peer_load_icon(freerdp_peer* client)
{ {
testPeerInfo* info = (testPeerInfo*)client->param1; testPeerContext* context = (testPeerContext*) client->context;
FILE* fp; FILE* fp;
int i; int i;
char line[50]; char line[50];
@ -158,13 +165,13 @@ static void test_peer_load_icon(freerdp_peer* client)
fgets(line, sizeof(line), fp); fgets(line, sizeof(line), fp);
/* width height */ /* width height */
fgets(line, sizeof(line), fp); 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 */ /* Max */
fgets(line, sizeof(line), fp); 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)) 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 */ /* 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); context->bg_data = xmalloc(context->icon_width * context->icon_height * 3);
memset(info->bg_data, 0xA0, info->icon_width * info->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) 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; rdpUpdate* update = client->update;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
RFX_RECT rect; 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) if (client->update->dump_rfx)
return; return;
if (!client->settings->rfx_codec || !info) if (!client->settings->rfx_codec || !context)
return; return;
if (info->icon_width < 1 || !info->activated) if (context->icon_width < 1 || !context->activated)
return; return;
rect.x = 0; rect.x = 0;
rect.y = 0; rect.y = 0;
rect.width = info->icon_width; rect.width = context->icon_width;
rect.height = info->icon_height; rect.height = context->icon_height;
if (info->icon_x >= 0) if (context->icon_x >= 0)
{ {
s = test_peer_stream_init(info); s = test_peer_stream_init(context);
rfx_compose_message(info->context, s, rfx_compose_message(context->rfx_context, s,
&rect, 1, info->bg_data, rect.width, rect.height, rect.width * 3); &rect, 1, context->bg_data, rect.width, rect.height, rect.width * 3);
cmd->destLeft = info->icon_x; cmd->destLeft = context->icon_x;
cmd->destTop = info->icon_y; cmd->destTop = context->icon_y;
cmd->destRight = info->icon_x + info->icon_width; cmd->destRight = context->icon_x + context->icon_width;
cmd->destBottom = info->icon_y + info->icon_height; cmd->destBottom = context->icon_y + context->icon_height;
cmd->bpp = 32; cmd->bpp = 32;
cmd->codecID = client->settings->rfx_codec_id; cmd->codecID = client->settings->rfx_codec_id;
cmd->width = info->icon_width; cmd->width = context->icon_width;
cmd->height = info->icon_height; cmd->height = context->icon_height;
cmd->bitmapDataLength = stream_get_length(s); cmd->bitmapDataLength = stream_get_length(s);
cmd->bitmapData = stream_get_head(s); cmd->bitmapData = stream_get_head(s);
update->SurfaceBits(update, cmd); update->SurfaceBits(update, cmd);
} }
s = test_peer_stream_init(info); s = test_peer_stream_init(context);
rfx_compose_message(info->context, s, rfx_compose_message(context->rfx_context, s,
&rect, 1, info->icon_data, rect.width, rect.height, rect.width * 3); &rect, 1, context->icon_data, rect.width, rect.height, rect.width * 3);
cmd->destLeft = x; cmd->destLeft = x;
cmd->destTop = y; cmd->destTop = y;
cmd->destRight = x + info->icon_width; cmd->destRight = x + context->icon_width;
cmd->destBottom = y + info->icon_height; cmd->destBottom = y + context->icon_height;
cmd->bpp = 32; cmd->bpp = 32;
cmd->codecID = client->settings->rfx_codec_id; cmd->codecID = client->settings->rfx_codec_id;
cmd->width = info->icon_width; cmd->width = context->icon_width;
cmd->height = info->icon_height; cmd->height = context->icon_height;
cmd->bitmapDataLength = stream_get_length(s); cmd->bitmapDataLength = stream_get_length(s);
cmd->bitmapData = stream_get_head(s); cmd->bitmapData = stream_get_head(s);
update->SurfaceBits(update, cmd); update->SurfaceBits(update, cmd);
info->icon_x = x; context->icon_x = x;
info->icon_y = y; context->icon_y = y;
} }
void tf_peer_dump_rfx(freerdp_peer* client) 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 * The server may start sending graphics output and receiving keyboard/mouse input after this
* callback returns. * callback returns.
*/ */
printf("Client %s is activated", client->settings->hostname); printf("Client %s is activated", client->hostname);
if (client->settings->autologon) if (client->settings->autologon)
{ {
printf(" and wants to login automatically as %s\\%s", 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); 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. */ /* 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); test_peer_load_icon(client);
/* Return False here would stop the execution of the peer mainloop. */ /* 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) boolean tf_peer_activate(freerdp_peer* client)
{ {
testPeerInfo* info = (testPeerInfo*)client->param1; testPeerContext* context = (testPeerContext*) client->context;
rfx_context_reset(info->context); rfx_context_reset(context->rfx_context);
info->activated = True; context->activated = True;
if (test_pcap_file != NULL) 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) 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; 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); 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; client->settings->height = 480;
} }
update->DesktopResize(update); 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); 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) 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)); 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 */ /* Initialize the real server settings here */
client->settings->cert_file = xstrdup("server.crt"); 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->PostConnect = tf_peer_post_connect;
client->Activate = tf_peer_activate; client->Activate = tf_peer_activate;
client->input->param1 = client;
client->input->SynchronizeEvent = tf_peer_synchronize_event; client->input->SynchronizeEvent = tf_peer_synchronize_event;
client->input->KeyboardEvent = tf_peer_keyboard_event; client->input->KeyboardEvent = tf_peer_keyboard_event;
client->input->UnicodeKeyboardEvent = tf_peer_unicode_keyboard_event; client->input->UnicodeKeyboardEvent = tf_peer_unicode_keyboard_event;
@ -408,6 +413,8 @@ static void* test_peer_mainloop(void* arg)
client->Initialize(client); client->Initialize(client);
printf("We've got a client %s\n", client->hostname);
while (1) while (1)
{ {
rcount = 0; rcount = 0;
@ -451,10 +458,10 @@ static void* test_peer_mainloop(void* arg)
break; break;
} }
printf("Client %s disconnected.\n", client->settings->hostname); printf("Client %s disconnected.\n", client->hostname);
client->Disconnect(client); client->Disconnect(client);
test_peer_uninit(client); freerdp_peer_context_free(client);
freerdp_peer_free(client); freerdp_peer_free(client);
return NULL; return NULL;