From 250b2e00af04f8407dea564e643dad4ef08b8a88 Mon Sep 17 00:00:00 2001 From: Vladimir Chtchetkine Date: Fri, 28 Jan 2011 10:56:16 -0800 Subject: Refactored user-events protocol Change-Id: I08afb96ef17a52c3795f5029acfc244a93ab57c7 --- android/console.c | 12 +- android/main-ui.c | 6 +- android/protocol/core-commands-proxy.c | 2 + android/protocol/user-events-impl.c | 206 ++++++++++++++++++++++++++++++++ android/protocol/user-events-impl.h | 33 +++++ android/protocol/user-events-protocol.h | 58 +++++++++ android/protocol/user-events-proxy.c | 180 ++++++++++++++++++++++++++++ android/protocol/user-events-proxy.h | 30 +++++ android/user-events-common.h | 57 --------- android/user-events-core.c | 178 --------------------------- android/user-events-core.h | 37 ------ 11 files changed, 515 insertions(+), 284 deletions(-) create mode 100644 android/protocol/user-events-impl.c create mode 100644 android/protocol/user-events-impl.h create mode 100644 android/protocol/user-events-protocol.h create mode 100644 android/protocol/user-events-proxy.c create mode 100644 android/protocol/user-events-proxy.h delete mode 100644 android/user-events-common.h delete mode 100644 android/user-events-core.c delete mode 100644 android/user-events-core.h (limited to 'android') diff --git a/android/console.c b/android/console.c index 42c3eb6..59610eb 100644 --- a/android/console.c +++ b/android/console.c @@ -52,7 +52,7 @@ #include "android/charmap.h" #include "android/display-core.h" #include "android/framebuffer-core.h" -#include "android/user-events-core.h" +#include "android/protocol/user-events-impl.h" #include "android/protocol/ui-commands-api.h" #include "android/protocol/core-commands-impl.h" #include "android/protocol/ui-commands-proxy.h" @@ -126,9 +126,6 @@ ControlClient framebuffer_client = NULL; /* User events service client. */ ControlClient user_events_client = NULL; -/* User events service. */ -CoreUserEvents* core_ue = NULL; - /* UI control service client (UI -> Core). */ ControlClient ui_core_ctl_client = NULL; @@ -259,7 +256,7 @@ control_client_destroy( ControlClient client ) } if (client == user_events_client) { - coreue_destroy(core_ue); + userEventsImpl_destroy(); user_events_client = NULL; } @@ -2592,8 +2589,7 @@ do_create_user_events_service( ControlClient client, char* args ) return -1; } - core_ue = coreue_create(client->sock); - if (core_ue != NULL) { + if (!userEventsImpl_create(client->sock)) { char reply_buf[4096]; user_events_client = client; snprintf(reply_buf, sizeof(reply_buf), "OK\r\n"); @@ -2608,7 +2604,7 @@ do_create_user_events_service( ControlClient client, char* args ) } void -destroy_control_ue_client(void) +destroy_user_events_client(void) { if (user_events_client != NULL) { control_client_destroy(user_events_client); diff --git a/android/main-ui.c b/android/main-ui.c index 9ab87de..4b86ad1 100644 --- a/android/main-ui.c +++ b/android/main-ui.c @@ -61,6 +61,7 @@ #include "android/snapshot.h" #include "android/core-connection.h" #include "android/framebuffer-ui.h" +#include "android/protocol/user-events-proxy.h" #include "android/protocol/core-commands-proxy.h" #include "android/protocol/ui-commands-impl.h" @@ -857,9 +858,6 @@ list_running_cores(const char* host) } } -/* Implemented in user-events-ui.c */ -extern int clientue_create(SockAddress* console_socket); - /* Attaches starting UI to a running core process. * This routine is called from main() when -attach-core parameter is set, * indicating that this UI instance should attach to a running core, rather than @@ -969,7 +967,7 @@ attach_to_core(AndroidOptions* opts) { } // Connect to the core's user events service. - if (clientue_create(&console_socket)) { + if (userEventsProxy_create(&console_socket)) { return -1; } diff --git a/android/protocol/core-commands-proxy.c b/android/protocol/core-commands-proxy.c index 6bd3d4e..1bd0937 100644 --- a/android/protocol/core-commands-proxy.c +++ b/android/protocol/core-commands-proxy.c @@ -127,10 +127,12 @@ _coreCmdProxy_destroy(void) if (_coreCmdProxy.sync_writer != NULL) { syncsocket_close(_coreCmdProxy.sync_writer); syncsocket_free(_coreCmdProxy.sync_writer); + _coreCmdProxy.sync_writer = NULL; } if (_coreCmdProxy.sync_reader != NULL) { syncsocket_close(_coreCmdProxy.sync_reader); syncsocket_free(_coreCmdProxy.sync_reader); + _coreCmdProxy.sync_reader = NULL; } if (_coreCmdProxy.core_connection != NULL) { core_connection_close(_coreCmdProxy.core_connection); diff --git a/android/protocol/user-events-impl.c b/android/protocol/user-events-impl.c new file mode 100644 index 0000000..5c9525e --- /dev/null +++ b/android/protocol/user-events-impl.c @@ -0,0 +1,206 @@ +/* Copyright (C) 2010 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +/* + * Contains the Core-side of the "user events" service. Here we receive and + * handle user events sent from the UI. + */ + +#include "user-events.h" +#include "android/globals.h" +#include "android/android.h" +#include "android/looper.h" +#include "android/async-utils.h" +#include "android/sync-utils.h" +#include "android/utils/system.h" +#include "android/utils/debug.h" +#include "android/protocol/user-events-protocol.h" +#include "android/protocol/user-events-impl.h" + +/* Enumerates state values for the event reader in the UserEventsImpl descriptor. + */ +typedef enum UserEventsImplState { + /* The reader is waiting on event header. */ + EXPECTS_HEADER, + + /* The reader is waiting on event parameters. */ + EXPECTS_PARAMETERS, +} UserEventsImplState; + + +/* Core user events service descriptor. */ +typedef struct UserEventsImpl { + /* Reader to receive user events. */ + AsyncReader user_events_reader; + + /* I/O associated with this descriptor. */ + LoopIo io; + + /* Looper used to communicate user events. */ + Looper* looper; + + /* Socket for this service. */ + int sock; + + /* State of the service (see UE_STATE_XXX for possible values). */ + UserEventsImplState state; + + /* Current event header. */ + UserEventHeader event_header; + + /* Current event parameters. */ + union { + UserEventGeneric generic_event; + UserEventMouse mouse_event; + UserEventKeycode keycode_event; + }; +} UserEventsImpl; + +/* Implemented in android/console.c */ +extern void destroy_user_events_client(void); + +/* One and only one UserEventsImpl instance. */ +static UserEventsImpl _UserEventsImpl; + +/* Asynchronous I/O callback reading user events. + * Param: + * opaque - UserEventsImpl instance. + */ +static void +_userEventsImpl_io_func(void* opaque, int fd, unsigned events) +{ + UserEventsImpl* ueimpl; + AsyncStatus status; + + if (events & LOOP_IO_WRITE) { + // We don't use async writer here, so we don't expect + // any write callbacks. + derror("Unexpected LOOP_IO_WRITE in _userEventsImpl_io_func\n"); + return; + } + + ueimpl = (UserEventsImpl*)opaque; + // Read whatever is expected from the socket. + status = asyncReader_read(&ueimpl->user_events_reader, &ueimpl->io); + + + switch (status) { + case ASYNC_COMPLETE: + switch (ueimpl->state) { + case EXPECTS_HEADER: + // We just read event header. Now we expect event parameters. + ueimpl->state = EXPECTS_PARAMETERS; + // Setup the reader depending on the event type. + switch (ueimpl->event_header.event_type) { + case AUSER_EVENT_MOUSE: + asyncReader_init(&ueimpl->user_events_reader, + &ueimpl->mouse_event, + sizeof(ueimpl->mouse_event), + &ueimpl->io); + break; + + case AUSER_EVENT_KEYCODE: + asyncReader_init(&ueimpl->user_events_reader, + &ueimpl->keycode_event, + sizeof(ueimpl->keycode_event), + &ueimpl->io); + break; + + case AUSER_EVENT_GENERIC: + asyncReader_init(&ueimpl->user_events_reader, + &ueimpl->generic_event, + sizeof(ueimpl->generic_event), + &ueimpl->io); + break; + + default: + derror("Unexpected user event type %d\n", + ueimpl->event_header.event_type); + break; + } + break; + + case EXPECTS_PARAMETERS: + // We just read event parameters. Lets fire the event. + switch (ueimpl->event_header.event_type) { + case AUSER_EVENT_MOUSE: + user_event_mouse(ueimpl->mouse_event.dx, + ueimpl->mouse_event.dy, + ueimpl->mouse_event.dz, + ueimpl->mouse_event.buttons_state); + break; + + case AUSER_EVENT_KEYCODE: + user_event_keycode(ueimpl->keycode_event.keycode); + break; + + case AUSER_EVENT_GENERIC: + user_event_generic(ueimpl->generic_event.type, + ueimpl->generic_event.code, + ueimpl->generic_event.value); + break; + + default: + derror("Unexpected user event type %d\n", + ueimpl->event_header.event_type); + break; + } + // Prepare to receive the next event header. + ueimpl->event_header.event_type = -1; + ueimpl->state = EXPECTS_HEADER; + asyncReader_init(&ueimpl->user_events_reader, + &ueimpl->event_header, + sizeof(ueimpl->event_header), &ueimpl->io); + break; + } + break; + case ASYNC_ERROR: + loopIo_dontWantRead(&ueimpl->io); + if (errno == ECONNRESET) { + // UI has exited. We need to destroy user event service. + destroy_user_events_client(); + } else { + derror("User event read error %d -> %s\n", errno, errno_str); + } + break; + + case ASYNC_NEED_MORE: + // Transfer will eventually come back into this routine. + return; + } +} + +int +userEventsImpl_create(int fd) +{ + _UserEventsImpl.sock = fd; + _UserEventsImpl.event_header.event_type = -1; + _UserEventsImpl.state = EXPECTS_HEADER; + _UserEventsImpl.looper = looper_newCore(); + loopIo_init(&_UserEventsImpl.io, _UserEventsImpl.looper, _UserEventsImpl.sock, + _userEventsImpl_io_func, &_UserEventsImpl); + asyncReader_init(&_UserEventsImpl.user_events_reader, + &_UserEventsImpl.event_header, + sizeof(_UserEventsImpl.event_header), &_UserEventsImpl.io); + return 0; +} + +void +userEventsImpl_destroy(void) +{ + if (_UserEventsImpl.looper != NULL) { + // Stop all I/O that may still be going on. + loopIo_done(&_UserEventsImpl.io); + looper_free(_UserEventsImpl.looper); + _UserEventsImpl.looper = NULL; + } +} diff --git a/android/protocol/user-events-impl.h b/android/protocol/user-events-impl.h new file mode 100644 index 0000000..af5d5a4 --- /dev/null +++ b/android/protocol/user-events-impl.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2010 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +/* + * Contains the Core-side of the "user events" service. Here we receive and + * handle user events sent from the UI. + */ + +#ifndef _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H +#define _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H + +/* Creates and initializes descriptor for the Core-side of the "user-events" + * service. Note that there can be only one instance of this service in the core. + * Param: + * fd - Socket descriptor for the service. + * Return: + * 0 on success, or < 0 on failure. + */ +extern int userEventsImpl_create(int fd); + +/* Destroys the descriptor for the Core-side of the "user-events" service. */ +extern void userEventsImpl_destroy(void); + +#endif /* _ANDROID_PROTOCOL_USER_EVENTS_IMPL_H */ diff --git a/android/protocol/user-events-protocol.h b/android/protocol/user-events-protocol.h new file mode 100644 index 0000000..c1e64e2 --- /dev/null +++ b/android/protocol/user-events-protocol.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2010 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +#ifndef _ANDROID_PROTOCOL_USER_EVENTS_H +#define _ANDROID_PROTOCOL_USER_EVENTS_H + +/* + * Contains declarations related to the UI events handled by the Core. + */ + +#include "android/globals.h" + +/* Mouse event. */ +#define AUSER_EVENT_MOUSE 0 +/* Keycode event. */ +#define AUSER_EVENT_KEYCODE 1 +/* Generic event. */ +#define AUSER_EVENT_GENERIC 2 + +/* Header for user event message sent from the UI to the Core. + * Every user event sent by the UI begins with this header, immediately followed + * by the event parameters (if there are any). + */ +typedef struct UserEventHeader { + /* Event type. See AUSER_EVENT_XXX for possible values. */ + uint8_t event_type; +} UserEventHeader; + +/* Formats mouse event message (AUSER_EVENT_MOUSE) */ +typedef struct UserEventMouse { + int dx; + int dy; + int dz; + unsigned buttons_state; +} UserEventMouse; + +/* Formats keycode event message (AUSER_EVENT_KEYCODE) */ +typedef struct UserEventKeycode { + int keycode; +} UserEventKeycode; + +/* Formats generic event message (AUSER_EVENT_GENERIC) */ +typedef struct UserEventGeneric { + int type; + int code; + int value; +} UserEventGeneric; + +#endif /* _ANDROID_PROTOCOL_USER_EVENTS_H */ diff --git a/android/protocol/user-events-proxy.c b/android/protocol/user-events-proxy.c new file mode 100644 index 0000000..d35012f --- /dev/null +++ b/android/protocol/user-events-proxy.c @@ -0,0 +1,180 @@ +/* Copyright (C) 2010 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +#include "user-events.h" +#include "console.h" +#include "android/looper.h" +#include "android/async-utils.h" +#include "android/core-connection.h" +#include "android/utils/debug.h" +#include "android/protocol/user-events-protocol.h" +#include "android/protocol/user-events-proxy.h" + +/* Descriptor for the user events client. */ +typedef struct UserEventsProxy { + /* Core connection instance for the user events client. */ + CoreConnection* core_connection; + + /* Socket for the client. */ + int sock; + + /* Writes user events to the socket. */ + SyncSocket* sync_writer; +} UserEventsProxy; + +/* One and only one user events client instance. */ +static UserEventsProxy _userEventsProxy = { 0 }; + +/* Destroys CoreCmdProxy instance. */ +static void +_userEventsProxy_destroy(void) +{ + if (_userEventsProxy.sync_writer != NULL) { + syncsocket_close(_userEventsProxy.sync_writer); + syncsocket_free(_userEventsProxy.sync_writer); + _userEventsProxy.sync_writer = NULL; + } + if (_userEventsProxy.core_connection != NULL) { + core_connection_close(_userEventsProxy.core_connection); + core_connection_free(_userEventsProxy.core_connection); + _userEventsProxy.core_connection = NULL; + } +} + +/* Sends an event to the core. + * Parameters: + * event - Event type. Must be one of the AUSER_EVENT_XXX. + * event_param - Event parameters. + * size - Byte size of the event parameters buffer. + * Return: + * 0 on success, or -1 on failure. + */ +static int +_userEventsProxy_send(uint8_t event, const void* event_param, size_t size) +{ + int res; + UserEventHeader header; + + header.event_type = event; + res = syncsocket_start_write(_userEventsProxy.sync_writer); + if (!res) { + // Send event type first (event header) + res = syncsocket_write(_userEventsProxy.sync_writer, &header, + sizeof(header), + core_connection_get_timeout(sizeof(header))); + if (res > 0) { + // Send event param next. + res = syncsocket_write(_userEventsProxy.sync_writer, event_param, + size, + core_connection_get_timeout(sizeof(size))); + } + res = syncsocket_result(res); + syncsocket_stop_write(_userEventsProxy.sync_writer); + } + if (res < 0) { + derror("Unable to send user event: %s\n", errno_str); + } + return res; +} + +int +userEventsProxy_create(SockAddress* console_socket) +{ + char* handshake = NULL; + + // Connect to the user-events service. + _userEventsProxy.core_connection = + core_connection_create_and_switch(console_socket, "user-events", + &handshake); + if (_userEventsProxy.core_connection == NULL) { + derror("Unable to connect to the user-events service: %s\n", + errno_str); + return -1; + } + + // Initialze event writer. + _userEventsProxy.sock = + core_connection_get_socket(_userEventsProxy.core_connection); + _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock); + if (_userEventsProxy.sync_writer == NULL) { + derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str); + _userEventsProxy_destroy(); + return -1; + } + + fprintf(stdout, "user-events is now connected to the core at %s.", + sock_address_to_string(console_socket)); + if (handshake != NULL) { + if (handshake[0] != '\0') { + fprintf(stdout, " Handshake: %s", handshake); + } + free(handshake); + } + fprintf(stdout, "\n"); + + return 0; +} + +void +user_event_keycodes(int *kcodes, int count) +{ + int nn; + for (nn = 0; nn < count; nn++) + user_event_keycode(kcodes[nn]); +} + +void +user_event_keycode(int kcode) +{ + UserEventKeycode message; + message.keycode = kcode; + _userEventsProxy_send(AUSER_EVENT_KEYCODE, &message, sizeof(message)); +} + +void +user_event_key(unsigned code, unsigned down) +{ + if(code == 0) { + return; + } + if (VERBOSE_CHECK(keys)) + printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " ); + + user_event_keycode((code & 0x1ff) | (down ? 0x200 : 0)); +} + + +void +user_event_mouse(int dx, int dy, int dz, unsigned buttons_state) +{ + UserEventMouse message; + message.dx = dx; + message.dy = dy; + message.dz = dz; + message.buttons_state = buttons_state; + _userEventsProxy_send(AUSER_EVENT_MOUSE, &message, sizeof(message)); +} + +void +user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback) +{ +} + +void +user_event_generic(int type, int code, int value) +{ + UserEventGeneric message; + message.type = type; + message.code = code; + message.value = value; + _userEventsProxy_send(AUSER_EVENT_GENERIC, &message, sizeof(message)); +} diff --git a/android/protocol/user-events-proxy.h b/android/protocol/user-events-proxy.h new file mode 100644 index 0000000..95f6614 --- /dev/null +++ b/android/protocol/user-events-proxy.h @@ -0,0 +1,30 @@ +/* Copyright (C) 2010 The Android Open Source Project +** +** This software is licensed under the terms of the GNU General Public +** License version 2, as published by the Free Software Foundation, and +** may be copied, distributed, and modified under those terms. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +*/ + +/* + * Contains the UI-side of the "user events" service. Here we send user events + * to the Core. + */ + +#ifndef _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H +#define _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H + +/* Creates and initializes descriptor for the UI-side of the "user-events" + * service. Note that there can be only one instance of this service in the UI. + * Param: + * console_socket - Addresses Core's console. + * Return: + * 0 on success, or < 0 on failure. + */ +extern int userEventsProxy_create(SockAddress* console_socket); + +#endif /* _ANDROID_PROTOCOL_USER_EVENTS_PROXY_H */ diff --git a/android/user-events-common.h b/android/user-events-common.h deleted file mode 100644 index 4d02c09..0000000 --- a/android/user-events-common.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2010 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ - -#ifndef _ANDROID_USER_EVENTS_COMMON_H -#define _ANDROID_USER_EVENTS_COMMON_H - -#include "globals.h" - -/* Mouse event. */ -#define AUSER_EVENT_MOUSE 0 -/* Keycode event. */ -#define AUSER_EVENT_KEYCODE 1 -/* Generic event. */ -#define AUSER_EVENT_GENERIC 2 - -/* Header for user event message sent from UI to the core. */ -typedef struct UserEventHeader { - /* Event type. See AUSER_EVENT_XXX for possible values. */ - uint8_t event_type; -} UserEventHeader; - -/* Formats mouse event message (AUSER_EVENT_MOUSE) sent from - * UI to the core. - */ -typedef struct UserEventMouse { - int dx; - int dy; - int dz; - unsigned buttons_state; -} UserEventMouse; - -/* Formats keycode event message (AUSER_EVENT_KEYCODE) sent from - * UI to the core. - */ -typedef struct UserEventKeycode { - int keycode; -} UserEventKeycode; - -/* Formats generic event message (AUSER_EVENT_GENERIC) sent from - * UI to the core. - */ -typedef struct UserEventGeneric { - int type; - int code; - int value; -} UserEventGeneric; - -#endif /* _ANDROID_USER_EVENTS_COMMON_H */ diff --git a/android/user-events-core.c b/android/user-events-core.c deleted file mode 100644 index 3b97c00..0000000 --- a/android/user-events-core.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright (C) 2010 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ - -#include "user-events.h" -#include "android/globals.h" -#include "android/android.h" -#include "android/looper.h" -#include "android/async-utils.h" -#include "android/utils/system.h" -#include "android/utils/debug.h" -#include "android/user-events-common.h" -#include "android/user-events-core.h" -#include "android/sync-utils.h" - -/* States of the core user events service. - */ - -/* Event header is expected in the pipe. */ -#define UE_STATE_EVENT_HEADER 0 -/* Event parameters are expected in the pipe. */ -#define UE_STATE_EVENT_PARAM 1 - -/* Core user events service descriptor. */ -struct CoreUserEvents { - /* Reader to receive user events. */ - AsyncReader user_events_reader; - - /* I/O associated with this descriptor. */ - LoopIo io; - - /* Looper used to communicate user events. */ - Looper* looper; - - /* Socket for this service. */ - int sock; - - /* State of the service (see UE_STATE_XXX for possible values). */ - int state; - - /* Current event header. */ - UserEventHeader event_header; - - /* Current event parameters. */ - union { - UserEventGeneric generic_event; - UserEventMouse mouse_event; - UserEventKeycode keycode_event; - }; -}; - -/* Implemented in android/console.c */ -extern void destroy_control_ue_client(void); - -/* - * Asynchronous I/O callback launched when reading user events from the socket. - * Param: - * opaque - CoreUserEvents instance. - */ -static void -coreue_io_func(void* opaque, int fd, unsigned events) -{ - CoreUserEvents* ue = opaque; - // Read whatever is expected from the socket. - const AsyncStatus status = asyncReader_read(&ue->user_events_reader, &ue->io); - - switch (status) { - case ASYNC_COMPLETE: - switch (ue->state) { - case UE_STATE_EVENT_HEADER: - // We just read event header. Now we expect event parameters. - ue->state = UE_STATE_EVENT_PARAM; - // Setup the reader depending on the event type. - switch (ue->event_header.event_type) { - case AUSER_EVENT_MOUSE: - asyncReader_init(&ue->user_events_reader, - &ue->mouse_event, - sizeof(ue->mouse_event), - &ue->io); - break; - case AUSER_EVENT_KEYCODE: - asyncReader_init(&ue->user_events_reader, - &ue->keycode_event, - sizeof(ue->keycode_event), - &ue->io); - break; - case AUSER_EVENT_GENERIC: - asyncReader_init(&ue->user_events_reader, - &ue->generic_event, - sizeof(ue->generic_event), - &ue->io); - break; - default: - derror("Unexpected event type %d\n", - ue->event_header.event_type); - break; - } - break; - - case UE_STATE_EVENT_PARAM: - // We just read event parameters. Lets fire the event. - switch (ue->event_header.event_type) { - case AUSER_EVENT_MOUSE: - user_event_mouse(ue->mouse_event.dx, - ue->mouse_event.dy, - ue->mouse_event.dz, - ue->mouse_event.buttons_state); - break; - case AUSER_EVENT_KEYCODE: - user_event_keycode(ue->keycode_event.keycode); - break; - case AUSER_EVENT_GENERIC: - user_event_generic(ue->generic_event.type, - ue->generic_event.code, - ue->generic_event.value); - break; - default: - derror("Unexpected event type %d\n", - ue->event_header.event_type); - break; - } - // Now we expect event header. - ue->event_header.event_type = -1; - ue->state = UE_STATE_EVENT_HEADER; - asyncReader_init(&ue->user_events_reader, &ue->event_header, - sizeof(ue->event_header), &ue->io); - break; - } - break; - case ASYNC_ERROR: - loopIo_dontWantRead(&ue->io); - if (errno == ECONNRESET) { - // UI has exited. We need to destroy user event service. - destroy_control_ue_client(); - } - break; - - case ASYNC_NEED_MORE: - // Transfer will eventually come back into this routine. - return; - } -} - -CoreUserEvents* -coreue_create(int fd) -{ - CoreUserEvents* ue; - ANEW0(ue); - ue->sock = fd; - ue->state = UE_STATE_EVENT_HEADER; - ue->looper = looper_newCore(); - loopIo_init(&ue->io, ue->looper, ue->sock, coreue_io_func, ue); - asyncReader_init(&ue->user_events_reader, &ue->event_header, - sizeof(ue->event_header), &ue->io); - return ue; -} - -void -coreue_destroy(CoreUserEvents* ue) -{ - if (ue != NULL) { - if (ue->looper != NULL) { - // Stop all I/O that may still be going on. - loopIo_done(&ue->io); - looper_free(ue->looper); - ue->looper = NULL; - } - free(ue); - } -} diff --git a/android/user-events-core.h b/android/user-events-core.h deleted file mode 100644 index 04bab6c..0000000 --- a/android/user-events-core.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2010 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ - -/* - * Contains recepient of user events sent from the UI. - */ - -#ifndef _ANDROID_USER_EVENTS_CORE_H -#define _ANDROID_USER_EVENTS_CORE_H - -/* Descriptor for a core user events instance */ -typedef struct CoreUserEvents CoreUserEvents; - -/* - * Creates and initializes core user events instance. - * Param: - * fd - Socket descriptor for the service. - */ -extern CoreUserEvents* coreue_create(int fd); - -/* - * Destroys core user events service. - * Param: - * ue - User event service descriptor to destroy. - */ -extern void coreue_destroy(CoreUserEvents* ue); - -#endif /* _ANDROID_USER_EVENTS_CORE_H */ -- cgit v1.1