Blame client/Android/android_event.c

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