diff options
author | Vladimir Chtchetkine <vchtchetkine@google.com> | 2011-01-28 10:56:16 -0800 |
---|---|---|
committer | Vladimir Chtchetkine <vchtchetkine@google.com> | 2011-01-28 10:56:16 -0800 |
commit | 250b2e00af04f8407dea564e643dad4ef08b8a88 (patch) | |
tree | a9aac104fcd0752b3ba93246bf0fa98ac142ece0 | |
parent | 138f690b8c80a0d0e06a0549d4715243c12a0c96 (diff) | |
download | external_qemu-250b2e00af04f8407dea564e643dad4ef08b8a88.zip external_qemu-250b2e00af04f8407dea564e643dad4ef08b8a88.tar.gz external_qemu-250b2e00af04f8407dea564e643dad4ef08b8a88.tar.bz2 |
Refactored user-events protocol
Change-Id: I08afb96ef17a52c3795f5029acfc244a93ab57c7
-rw-r--r-- | Makefile.android | 4 | ||||
-rw-r--r-- | android/console.c | 12 | ||||
-rw-r--r-- | android/main-ui.c | 6 | ||||
-rw-r--r-- | android/protocol/core-commands-proxy.c | 2 | ||||
-rw-r--r-- | android/protocol/user-events-impl.c | 206 | ||||
-rw-r--r-- | android/protocol/user-events-impl.h | 33 | ||||
-rw-r--r-- | android/protocol/user-events-protocol.h (renamed from android/user-events-common.h) | 29 | ||||
-rw-r--r-- | android/protocol/user-events-proxy.c | 180 | ||||
-rw-r--r-- | android/protocol/user-events-proxy.h | 30 | ||||
-rw-r--r-- | android/user-events-core.c | 178 | ||||
-rw-r--r-- | android/user-events-core.h | 37 | ||||
-rw-r--r-- | user-events-ui.c | 172 |
12 files changed, 474 insertions, 415 deletions
diff --git a/Makefile.android b/Makefile.android index a5336aa..b681764 100644 --- a/Makefile.android +++ b/Makefile.android @@ -1057,7 +1057,7 @@ VL_SOURCES := framebuffer.c \ android/looper-generic.c \ android/display-core.c \ android/framebuffer-core.c \ - android/user-events-core.c \ + android/protocol/user-events-impl.c \ android/protocol/ui-commands-proxy.c \ android/protocol/core-commands-impl.c \ @@ -1204,7 +1204,6 @@ endif # include other sources # VL_SOURCES := framebuffer.c \ - user-events-ui.c \ android/cmdline-option.c \ android/config.c \ android/display.c \ @@ -1219,6 +1218,7 @@ VL_SOURCES := framebuffer.c \ android/framebuffer-ui.c \ android/protocol/ui-commands-impl.c \ android/protocol/core-commands-proxy.c \ + android/protocol/user-events-proxy.c \ # Add common system libraries # 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/user-events-common.h b/android/protocol/user-events-protocol.h index 4d02c09..c1e64e2 100644 --- a/android/user-events-common.h +++ b/android/protocol/user-events-protocol.h @@ -10,10 +10,14 @@ ** GNU General Public License for more details. */ -#ifndef _ANDROID_USER_EVENTS_COMMON_H -#define _ANDROID_USER_EVENTS_COMMON_H +#ifndef _ANDROID_PROTOCOL_USER_EVENTS_H +#define _ANDROID_PROTOCOL_USER_EVENTS_H -#include "globals.h" +/* + * Contains declarations related to the UI events handled by the Core. + */ + +#include "android/globals.h" /* Mouse event. */ #define AUSER_EVENT_MOUSE 0 @@ -22,15 +26,16 @@ /* Generic event. */ #define AUSER_EVENT_GENERIC 2 -/* Header for user event message sent from UI to the core. */ +/* 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) sent from - * UI to the core. - */ +/* Formats mouse event message (AUSER_EVENT_MOUSE) */ typedef struct UserEventMouse { int dx; int dy; @@ -38,20 +43,16 @@ typedef struct UserEventMouse { unsigned buttons_state; } UserEventMouse; -/* Formats keycode event message (AUSER_EVENT_KEYCODE) sent from - * UI to the core. - */ +/* Formats keycode event message (AUSER_EVENT_KEYCODE) */ typedef struct UserEventKeycode { int keycode; } UserEventKeycode; -/* Formats generic event message (AUSER_EVENT_GENERIC) sent from - * UI to the core. - */ +/* Formats generic event message (AUSER_EVENT_GENERIC) */ typedef struct UserEventGeneric { int type; int code; int value; } UserEventGeneric; -#endif /* _ANDROID_USER_EVENTS_COMMON_H */ +#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-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 */ diff --git a/user-events-ui.c b/user-events-ui.c deleted file mode 100644 index 67fafd6..0000000 --- a/user-events-ui.c +++ /dev/null @@ -1,172 +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/utils/debug.h" -#include "android/user-events-common.h" -#include "console.h" -#include <stdio.h> - -#include "android/looper.h" -#include "android/async-utils.h" -#include "android/core-connection.h" - -/* Descriptor for the user events client. */ -typedef struct ClientUserEvents { - /* Core connection instance for the user events client. */ - CoreConnection* core_connection; - - /* Socket for the client. */ - int sock; - - /* Socket wrapper for sync I/O. */ - SyncSocket* sync_socket; -} ClientUserEvents; - -/* One and only one user events client instance. */ -static ClientUserEvents _client_ue = { 0 }; - -int -clientue_create(SockAddress* console_socket) -{ - char* connect_message = NULL; - char switch_cmd[256]; - - // Connect to the framebuffer service. - _client_ue.core_connection = core_connection_create(console_socket); - if (_client_ue.core_connection == NULL) { - derror("User events client is unable to connect to the console: %s\n", - errno_str); - return -1; - } - if (core_connection_open(_client_ue.core_connection)) { - core_connection_free(_client_ue.core_connection); - _client_ue.core_connection = NULL; - derror("User events client is unable to open the console: %s\n", - errno_str); - return -1; - } - snprintf(switch_cmd, sizeof(switch_cmd), "user-events"); - if (core_connection_switch_stream(_client_ue.core_connection, switch_cmd, - &connect_message)) { - derror("Unable to connect to the user events service: %s\n", - connect_message ? connect_message : ""); - if (connect_message != NULL) { - free(connect_message); - } - core_connection_close(_client_ue.core_connection); - core_connection_free(_client_ue.core_connection); - _client_ue.core_connection = NULL; - return -1; - } - - // Now that we're connected lets initialize the descriptor. - _client_ue.sock = core_connection_get_socket(_client_ue.core_connection); - _client_ue.sync_socket = syncsocket_init(_client_ue.sock); - if (connect_message != NULL) { - free(connect_message); - } - - fprintf(stdout, "User events client is now attached to the core %s\n", - sock_address_to_string(console_socket)); - - return 0; -} - -/* Sends an event to the core. - * Parameters: - * ue - User events client instance. - * 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 -clientue_send(ClientUserEvents* ue, - uint8_t event, - const void* event_param, - size_t size) -{ - int res; - UserEventHeader header; - - header.event_type = event; - res = syncsocket_start_write(ue->sync_socket); - if (!res) { - // Send event type first (event header) - res = syncsocket_write(ue->sync_socket, &header, sizeof(header), 500); - if (res > 0) { - // Send event param next. - res = syncsocket_write(ue->sync_socket, event_param, size, 500); - } - res = syncsocket_result(res); - syncsocket_stop_write(ue->sync_socket); - } - if (res < 0) { - derror("Unable to send user event: %s\n", errno_str); - } - return res; -} - -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; - clientue_send(&_client_ue, 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; - clientue_send(&_client_ue, 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; - clientue_send(&_client_ue, AUSER_EVENT_GENERIC, &message, sizeof(message)); -} |