Skip to main content
The freerdp_peer API is the low-level foundation for writing an RDP server in C. The sample server in server/Sample/sfreerdp.c is the canonical reference implementation.

Core lifecycle functions

The listener

Use freerdp_listener to accept incoming connections. For each accepted connection the library calls your PeerAccepted callback with a ready-to-configure freerdp_peer*.
Key freerdp_listener function pointers:

Extending rdpContext

Store per-connection application state by embedding rdpContext as the first member of a larger struct:
Tell FreeRDP how to allocate and free this extended struct:

Key peer callbacks

Set these function pointers on the freerdp_peer* before calling peer->Initialize(peer).

Connection lifecycle

PostConnect is the right place to open virtual channels and load resources. Return FALSE from any callback to abort the connection.

Channel and redirection

Virtual channels (dynamic)

Authentication

peer->settings configuration

Configure settings through peer->context->settings using freerdp_settings_set_* before calling peer->Initialize(peer). Common settings from the sample server:

The peer event loop

After peer->Initialize(peer) succeeds, run a standard Windows-style wait loop:
Run each peer’s event loop in its own thread. The PeerAccepted callback in the sample server spawns a CreateThread for each new connection.

Input callbacks

Register input handlers on client->context->input to receive keyboard and mouse events from the client:
Example keyboard handler:

Sending graphics updates

Use client->context->update to push graphics to the client. Always bracket updates with surface frame markers:
Other useful update callbacks:

Complete minimal server example

The following skeleton combines all the pieces above.
The full production-quality example is server/Sample/sfreerdp.c. It adds RemoteFX/NSCodec rendering, virtual channel management, audio, and PCAP replay support.