1/* Copyright (C) 2010 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10** GNU General Public License for more details.
11*/
12
13#include "user-events.h"
14#include "console.h"
15#include "android/looper.h"
16#include "android/async-utils.h"
17#include "android/utils/debug.h"
18#include "android/protocol/core-connection.h"
19#include "android/protocol/user-events-protocol.h"
20#include "android/protocol/user-events-proxy.h"
21
22/* Descriptor for the user events client. */
23typedef struct UserEventsProxy {
24    /* Core connection instance for the user events client. */
25    CoreConnection* core_connection;
26
27    /* Socket for the client. */
28    int             sock;
29
30    /* Writes user events to the socket. */
31    SyncSocket*     sync_writer;
32} UserEventsProxy;
33
34/* One and only one user events client instance. */
35static UserEventsProxy _userEventsProxy = { 0 };
36
37/* Sends an event to the core.
38 * Parameters:
39 *  event - Event type. Must be one of the AUSER_EVENT_XXX.
40 *  event_param - Event parameters.
41 *  size - Byte size of the event parameters buffer.
42 * Return:
43 *  0 on success, or -1 on failure.
44 */
45static int
46_userEventsProxy_send(uint8_t event, const void* event_param, size_t size)
47{
48    int res;
49    UserEventHeader header;
50
51    header.event_type = event;
52    res = syncsocket_start_write(_userEventsProxy.sync_writer);
53    if (!res) {
54        // Send event type first (event header)
55        res = syncsocket_write(_userEventsProxy.sync_writer, &header,
56                               sizeof(header),
57                               core_connection_get_timeout(sizeof(header)));
58        if (res > 0) {
59            // Send event param next.
60            res = syncsocket_write(_userEventsProxy.sync_writer, event_param,
61                                   size,
62                                   core_connection_get_timeout(sizeof(size)));
63        }
64        res = syncsocket_result(res);
65        syncsocket_stop_write(_userEventsProxy.sync_writer);
66    }
67    if (res < 0) {
68        derror("Unable to send user event: %s\n", errno_str);
69    }
70    return res;
71}
72
73int
74userEventsProxy_create(SockAddress* console_socket)
75{
76    char* handshake = NULL;
77
78    // Connect to the user-events service.
79    _userEventsProxy.core_connection =
80        core_connection_create_and_switch(console_socket, "user-events",
81                                          &handshake);
82    if (_userEventsProxy.core_connection == NULL) {
83        derror("Unable to connect to the user-events service: %s\n",
84               errno_str);
85        return -1;
86    }
87
88    // Initialze event writer.
89    _userEventsProxy.sock =
90        core_connection_get_socket(_userEventsProxy.core_connection);
91    _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock);
92    if (_userEventsProxy.sync_writer == NULL) {
93        derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str);
94        userEventsProxy_destroy();
95        return -1;
96    }
97
98    fprintf(stdout, "user-events is now connected to the core at %s.",
99            sock_address_to_string(console_socket));
100    if (handshake != NULL) {
101        if (handshake[0] != '\0') {
102            fprintf(stdout, " Handshake: %s", handshake);
103        }
104        free(handshake);
105    }
106    fprintf(stdout, "\n");
107
108    return 0;
109}
110
111void
112userEventsProxy_destroy(void)
113{
114    if (_userEventsProxy.sync_writer != NULL) {
115        syncsocket_close(_userEventsProxy.sync_writer);
116        syncsocket_free(_userEventsProxy.sync_writer);
117        _userEventsProxy.sync_writer = NULL;
118    }
119    if (_userEventsProxy.core_connection != NULL) {
120        core_connection_close(_userEventsProxy.core_connection);
121        core_connection_free(_userEventsProxy.core_connection);
122        _userEventsProxy.core_connection = NULL;
123    }
124}
125void
126user_event_keycodes(int *kcodes, int count)
127{
128    int nn;
129    for (nn = 0; nn < count; nn++)
130        user_event_keycode(kcodes[nn]);
131}
132
133void
134user_event_keycode(int  kcode)
135{
136    UserEventKeycode    message;
137    message.keycode = kcode;
138    _userEventsProxy_send(AUSER_EVENT_KEYCODE, &message, sizeof(message));
139}
140
141void
142user_event_key(unsigned code, unsigned down)
143{
144    if(code == 0) {
145        return;
146    }
147    if (VERBOSE_CHECK(keys))
148        printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " );
149
150    user_event_keycode((code & 0x1ff) | (down ? 0x200 : 0));
151}
152
153
154void
155user_event_mouse(int dx, int dy, int dz, unsigned buttons_state)
156{
157    UserEventMouse    message;
158    message.dx = dx;
159    message.dy = dy;
160    message.dz = dz;
161    message.buttons_state = buttons_state;
162    _userEventsProxy_send(AUSER_EVENT_MOUSE, &message, sizeof(message));
163}
164
165void
166user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback)
167{
168}
169
170void
171user_event_generic(int type, int code, int value)
172{
173    UserEventGeneric    message;
174    message.type = type;
175    message.code = code;
176    message.value = value;
177    _userEventsProxy_send(AUSER_EVENT_GENERIC, &message, sizeof(message));
178}
179