FreeRDP/server/shadow/shadow_encomsp.c
zihao.jiang 8485d866d4 This is originally to add audio support. Several fixes included:
1. Introduce message queue in shadow client. No longer use subsytem->MsgPipe->out to deliver message to clients.
We used to use subsytem->MsgPipe->out for messages which need to be sent to client. But it's not correct. Only one client would get the message if multiple client exists
This problem make the fix in PR #2643 incomplete.
Introduced reference count based solution to release resource taken by the message.
Also added APIs for client message delivery.
Also fixed msg pipe in subsystem to clean resource when destroyed.
2. Discard unused StopEvent in client. We actually use quit message instead.
3. Enhance disposal of channels.
Free context for remdesk and encomsp channels. The original fix only stop the threads, but doesn't release resource.
Dispose channels earlier. The channels are built on client->vcm. Disposing channels after client->vcm is closed cause unknown behavior.
Original fix is #2644
4. Start to add audio support.
2015-06-14 21:45:52 +08:00

120 lines
2.7 KiB
C

/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <freerdp/log.h>
#include "shadow.h"
#include "shadow_encomsp.h"
#define TAG SERVER_TAG("shadow")
static int encomsp_change_participant_control_level(EncomspServerContext* context,
ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
{
BOOL inLobby;
BOOL mayView;
BOOL mayInteract;
rdpShadowClient* client = (rdpShadowClient*) context->custom;
WLog_INFO(TAG, "ChangeParticipantControlLevel: ParticipantId: %d Flags: 0x%04X",
pdu->ParticipantId, pdu->Flags);
mayView = (pdu->Flags & ENCOMSP_MAY_VIEW) ? TRUE : FALSE;
mayInteract = (pdu->Flags & ENCOMSP_MAY_INTERACT) ? TRUE : FALSE;
if (mayInteract && !mayView)
mayView = TRUE; /* may interact implies may view */
if (mayInteract)
{
if (!client->mayInteract)
{
/* request interact + view */
client->mayInteract = TRUE;
client->mayView = TRUE;
}
}
else if (mayView)
{
if (client->mayInteract)
{
/* release interact */
client->mayInteract = FALSE;
}
else if (!client->mayView)
{
/* request view */
client->mayView = TRUE;
}
}
else
{
if (client->mayInteract)
{
/* release interact + view */
client->mayView = FALSE;
client->mayInteract = FALSE;
}
else if (client->mayView)
{
/* release view */
client->mayView = FALSE;
client->mayInteract = FALSE;
}
}
inLobby = client->mayView ? FALSE : TRUE;
if (inLobby != client->inLobby)
{
shadow_encoder_reset(client->encoder);
client->inLobby = inLobby;
}
return 1;
}
int shadow_client_encomsp_init(rdpShadowClient* client)
{
EncomspServerContext* encomsp;
encomsp = client->encomsp = encomsp_server_context_new(client->vcm);
encomsp->custom = (void*) client;
encomsp->ChangeParticipantControlLevel = encomsp_change_participant_control_level;
if (client->encomsp)
client->encomsp->Start(client->encomsp);
return 1;
}
void shadow_client_encomsp_uninit(rdpShadowClient* client)
{
if (client->encomsp) {
client->encomsp->Stop(client->encomsp);
encomsp_server_context_free(client->encomsp);
client->encomsp = NULL;
}
}