| /* 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/utils/debug.h" |
| #include "android/protocol/core-connection.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 }; |
| |
| /* 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 |
| 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; |
| } |
| } |
| 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)); |
| } |