Blame client/Android/android_event.c

Packit Service fa4841
/**
Packit Service fa4841
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit Service fa4841
 * Android Event System
Packit Service fa4841
 *
Packit Service fa4841
 * Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit Service fa4841
 * Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
Packit Service fa4841
 *
Packit Service fa4841
 * This Source Code Form is subject to the terms of the Mozilla Public
Packit Service fa4841
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit Service fa4841
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_CONFIG_H
Packit Service fa4841
#include "config.h"
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <winpr/crt.h>
Packit Service fa4841
Packit Service fa4841
#include <freerdp/freerdp.h>
Packit Service fa4841
#include <freerdp/log.h>
Packit Service fa4841
Packit Service fa4841
#define TAG CLIENT_TAG("android")
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_UNISTD_H
Packit Service fa4841
#include <unistd.h>
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include "android_freerdp.h"
Packit Service fa4841
#include "android_cliprdr.h"
Packit Service fa4841
Packit Service fa4841
BOOL android_push_event(freerdp* inst, ANDROID_EVENT* event)
Packit Service fa4841
{
Packit Service fa4841
	androidContext* aCtx = (androidContext*)inst->context;
Packit Service fa4841
Packit Service fa4841
	if (aCtx->event_queue->count >= aCtx->event_queue->size)
Packit Service fa4841
	{
Packit Service fa4841
		int new_size;
Packit Service fa4841
		void* new_events;
Packit Service fa4841
		new_size = aCtx->event_queue->size * 2;
Packit Service fa4841
		new_events = realloc((void*)aCtx->event_queue->events, sizeof(ANDROID_EVENT*) * new_size);
Packit Service fa4841
Packit Service fa4841
		if (!new_events)
Packit Service fa4841
			return FALSE;
Packit Service fa4841
Packit Service fa4841
		aCtx->event_queue->events = new_events;
Packit Service fa4841
		aCtx->event_queue->size = new_size;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	aCtx->event_queue->events[(aCtx->event_queue->count)++] = event;
Packit Service fa4841
	return SetEvent(aCtx->event_queue->isSet);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static ANDROID_EVENT* android_peek_event(ANDROID_EVENT_QUEUE* queue)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT* event;
Packit Service fa4841
Packit Service fa4841
	if (queue->count < 1)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event = queue->events[0];
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static ANDROID_EVENT* android_pop_event(ANDROID_EVENT_QUEUE* queue)
Packit Service fa4841
{
Packit Service fa4841
	int i;
Packit Service fa4841
	ANDROID_EVENT* event;
Packit Service fa4841
Packit Service fa4841
	if (queue->count < 1)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event = queue->events[0];
Packit Service fa4841
	(queue->count)--;
Packit Service fa4841
Packit Service fa4841
	for (i = 0; i < queue->count; i++)
Packit Service fa4841
	{
Packit Service fa4841
		queue->events[i] = queue->events[i + 1];
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static BOOL android_process_event(ANDROID_EVENT_QUEUE* queue, freerdp* inst)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT* event;
Packit Service fa4841
	rdpContext* context = inst->context;
Packit Service fa4841
	androidContext* afc = (androidContext*)context;
Packit Service fa4841
Packit Service fa4841
	while (android_peek_event(queue))
Packit Service fa4841
	{
Packit Service fa4841
		event = android_pop_event(queue);
Packit Service fa4841
Packit Service fa4841
		if (event->type == EVENT_TYPE_KEY)
Packit Service fa4841
		{
Packit Service fa4841
			ANDROID_EVENT_KEY* key_event = (ANDROID_EVENT_KEY*)event;
Packit Service fa4841
			inst->input->KeyboardEvent(inst->input, key_event->flags, key_event->scancode);
Packit Service fa4841
			android_event_free((ANDROID_EVENT*)key_event);
Packit Service fa4841
		}
Packit Service fa4841
		else if (event->type == EVENT_TYPE_KEY_UNICODE)
Packit Service fa4841
		{
Packit Service fa4841
			ANDROID_EVENT_KEY* key_event = (ANDROID_EVENT_KEY*)event;
Packit Service fa4841
			inst->input->UnicodeKeyboardEvent(inst->input, key_event->flags, key_event->scancode);
Packit Service fa4841
			android_event_free((ANDROID_EVENT*)key_event);
Packit Service fa4841
		}
Packit Service fa4841
		else if (event->type == EVENT_TYPE_CURSOR)
Packit Service fa4841
		{
Packit Service fa4841
			ANDROID_EVENT_CURSOR* cursor_event = (ANDROID_EVENT_CURSOR*)event;
Packit Service fa4841
			inst->input->MouseEvent(inst->input, cursor_event->flags, cursor_event->x,
Packit Service fa4841
			                        cursor_event->y);
Packit Service fa4841
			android_event_free((ANDROID_EVENT*)cursor_event);
Packit Service fa4841
		}
Packit Service fa4841
		else if (event->type == EVENT_TYPE_CLIPBOARD)
Packit Service fa4841
		{
Packit Service fa4841
			UINT32 size;
Packit Service fa4841
			UINT32 formatId;
Packit Service fa4841
			ANDROID_EVENT_CLIPBOARD* clipboard_event = (ANDROID_EVENT_CLIPBOARD*)event;
Packit Service fa4841
			formatId = ClipboardRegisterFormat(afc->clipboard, "UTF8_STRING");
Packit Service fa4841
			size = clipboard_event->data_length;
Packit Service fa4841
Packit Service fa4841
			if (size)
Packit Service fa4841
				ClipboardSetData(afc->clipboard, formatId, clipboard_event->data, size);
Packit Service fa4841
			else
Packit Service fa4841
				ClipboardEmpty(afc->clipboard);
Packit Service fa4841
Packit Service fa4841
			android_cliprdr_send_client_format_list(afc->cliprdr);
Packit Service fa4841
			android_event_free((ANDROID_EVENT*)clipboard_event);
Packit Service fa4841
		}
Packit Service fa4841
		else if (event->type == EVENT_TYPE_DISCONNECT)
Packit Service fa4841
		{
Packit Service fa4841
			android_event_free(event);
Packit Service fa4841
			return FALSE;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
HANDLE android_get_handle(freerdp* inst)
Packit Service fa4841
{
Packit Service fa4841
	androidContext* aCtx;
Packit Service fa4841
Packit Service fa4841
	if (!inst || !inst->context)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	aCtx = (androidContext*)inst->context;
Packit Service fa4841
Packit Service fa4841
	if (!aCtx->event_queue || !aCtx->event_queue->isSet)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	return aCtx->event_queue->isSet;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL android_check_handle(freerdp* inst)
Packit Service fa4841
{
Packit Service fa4841
	androidContext* aCtx;
Packit Service fa4841
Packit Service fa4841
	if (!inst || !inst->context)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	aCtx = (androidContext*)inst->context;
Packit Service fa4841
Packit Service fa4841
	if (!aCtx->event_queue || !aCtx->event_queue->isSet)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (WaitForSingleObject(aCtx->event_queue->isSet, 0) == WAIT_OBJECT_0)
Packit Service fa4841
	{
Packit Service fa4841
		if (!ResetEvent(aCtx->event_queue->isSet))
Packit Service fa4841
			return FALSE;
Packit Service fa4841
Packit Service fa4841
		if (!android_process_event(aCtx->event_queue, inst))
Packit Service fa4841
			return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
ANDROID_EVENT_KEY* android_event_key_new(int flags, UINT16 scancode)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT_KEY* event;
Packit Service fa4841
	event = (ANDROID_EVENT_KEY*)calloc(1, sizeof(ANDROID_EVENT_KEY));
Packit Service fa4841
Packit Service fa4841
	if (!event)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event->type = EVENT_TYPE_KEY;
Packit Service fa4841
	event->flags = flags;
Packit Service fa4841
	event->scancode = scancode;
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void android_event_key_free(ANDROID_EVENT_KEY* event)
Packit Service fa4841
{
Packit Service fa4841
	free(event);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 flags, UINT16 key)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT_KEY* event;
Packit Service fa4841
	event = (ANDROID_EVENT_KEY*)calloc(1, sizeof(ANDROID_EVENT_KEY));
Packit Service fa4841
Packit Service fa4841
	if (!event)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event->type = EVENT_TYPE_KEY_UNICODE;
Packit Service fa4841
	event->flags = flags;
Packit Service fa4841
	event->scancode = key;
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void android_event_unicodekey_free(ANDROID_EVENT_KEY* event)
Packit Service fa4841
{
Packit Service fa4841
	free(event);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, UINT16 x, UINT16 y)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT_CURSOR* event;
Packit Service fa4841
	event = (ANDROID_EVENT_CURSOR*)calloc(1, sizeof(ANDROID_EVENT_CURSOR));
Packit Service fa4841
Packit Service fa4841
	if (!event)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event->type = EVENT_TYPE_CURSOR;
Packit Service fa4841
	event->x = x;
Packit Service fa4841
	event->y = y;
Packit Service fa4841
	event->flags = flags;
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void android_event_cursor_free(ANDROID_EVENT_CURSOR* event)
Packit Service fa4841
{
Packit Service fa4841
	free(event);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
ANDROID_EVENT* android_event_disconnect_new(void)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT* event;
Packit Service fa4841
	event = (ANDROID_EVENT*)calloc(1, sizeof(ANDROID_EVENT));
Packit Service fa4841
Packit Service fa4841
	if (!event)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event->type = EVENT_TYPE_DISCONNECT;
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void android_event_disconnect_free(ANDROID_EVENT* event)
Packit Service fa4841
{
Packit Service fa4841
	free(event);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
ANDROID_EVENT_CLIPBOARD* android_event_clipboard_new(void* data, int data_length)
Packit Service fa4841
{
Packit Service fa4841
	ANDROID_EVENT_CLIPBOARD* event;
Packit Service fa4841
	event = (ANDROID_EVENT_CLIPBOARD*)calloc(1, sizeof(ANDROID_EVENT_CLIPBOARD));
Packit Service fa4841
Packit Service fa4841
	if (!event)
Packit Service fa4841
		return NULL;
Packit Service fa4841
Packit Service fa4841
	event->type = EVENT_TYPE_CLIPBOARD;
Packit Service fa4841
Packit Service fa4841
	if (data)
Packit Service fa4841
	{
Packit Service fa4841
		event->data = malloc(data_length);
Packit Service fa4841
Packit Service fa4841
		if (!event->data)
Packit Service fa4841
		{
Packit Service fa4841
			free(event);
Packit Service fa4841
			return NULL;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		memcpy(event->data, data, data_length);
Packit Service fa4841
		event->data_length = data_length;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return event;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static void android_event_clipboard_free(ANDROID_EVENT_CLIPBOARD* event)
Packit Service fa4841
{
Packit Service fa4841
	if (event)
Packit Service fa4841
	{
Packit Service fa4841
		free(event->data);
Packit Service fa4841
		free(event);
Packit Service fa4841
	}
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL android_event_queue_init(freerdp* inst)
Packit Service fa4841
{
Packit Service fa4841
	androidContext* aCtx = (androidContext*)inst->context;
Packit Service fa4841
	ANDROID_EVENT_QUEUE* queue;
Packit Service fa4841
	queue = (ANDROID_EVENT_QUEUE*)calloc(1, sizeof(ANDROID_EVENT_QUEUE));
Packit Service fa4841
Packit Service fa4841
	if (!queue)
Packit Service fa4841
	{
Packit Service fa4841
		WLog_ERR(TAG, "android_event_queue_init: memory allocation failed");
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	queue->size = 16;
Packit Service fa4841
	queue->count = 0;
Packit Service fa4841
	queue->isSet = CreateEventA(NULL, TRUE, FALSE, NULL);
Packit Service fa4841
Packit Service fa4841
	if (!queue->isSet)
Packit Service fa4841
	{
Packit Service fa4841
		free(queue);
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	queue->events = (ANDROID_EVENT**)calloc(queue->size, sizeof(ANDROID_EVENT*));
Packit Service fa4841
Packit Service fa4841
	if (!queue->events)
Packit Service fa4841
	{
Packit Service fa4841
		WLog_ERR(TAG, "android_event_queue_init: memory allocation failed");
Packit Service fa4841
		CloseHandle(queue->isSet);
Packit Service fa4841
		free(queue);
Packit Service fa4841
		return FALSE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	aCtx->event_queue = queue;
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
void android_event_queue_uninit(freerdp* inst)
Packit Service fa4841
{
Packit Service fa4841
	androidContext* aCtx;
Packit Service fa4841
	ANDROID_EVENT_QUEUE* queue;
Packit Service fa4841
Packit Service fa4841
	if (!inst || !inst->context)
Packit Service fa4841
		return;
Packit Service fa4841
Packit Service fa4841
	aCtx = (androidContext*)inst->context;
Packit Service fa4841
	queue = aCtx->event_queue;
Packit Service fa4841
Packit Service fa4841
	if (queue)
Packit Service fa4841
	{
Packit Service fa4841
		if (queue->isSet)
Packit Service fa4841
		{
Packit Service fa4841
			CloseHandle(queue->isSet);
Packit Service fa4841
			queue->isSet = NULL;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (queue->events)
Packit Service fa4841
		{
Packit Service fa4841
			free(queue->events);
Packit Service fa4841
			queue->events = NULL;
Packit Service fa4841
			queue->size = 0;
Packit Service fa4841
			queue->count = 0;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		free(queue);
Packit Service fa4841
	}
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
void android_event_free(ANDROID_EVENT* event)
Packit Service fa4841
{
Packit Service fa4841
	if (!event)
Packit Service fa4841
		return;
Packit Service fa4841
Packit Service fa4841
	switch (event->type)
Packit Service fa4841
	{
Packit Service fa4841
		case EVENT_TYPE_KEY:
Packit Service fa4841
			android_event_key_free((ANDROID_EVENT_KEY*)event);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case EVENT_TYPE_KEY_UNICODE:
Packit Service fa4841
			android_event_unicodekey_free((ANDROID_EVENT_KEY*)event);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case EVENT_TYPE_CURSOR:
Packit Service fa4841
			android_event_cursor_free((ANDROID_EVENT_CURSOR*)event);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case EVENT_TYPE_DISCONNECT:
Packit Service fa4841
			android_event_disconnect_free((ANDROID_EVENT*)event);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case EVENT_TYPE_CLIPBOARD:
Packit Service fa4841
			android_event_clipboard_free((ANDROID_EVENT_CLIPBOARD*)event);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		default:
Packit Service fa4841
			break;
Packit Service fa4841
	}
Packit Service fa4841
}