blob: d35012f6590e25bfddbda63a3ac592015e9e4535 [file] [log] [blame]
Vladimir Chtchetkine250b2e02011-01-28 10:56:16 -08001/* 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/core-connection.h"
18#include "android/utils/debug.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/* Destroys CoreCmdProxy instance. */
38static void
39_userEventsProxy_destroy(void)
40{
41 if (_userEventsProxy.sync_writer != NULL) {
42 syncsocket_close(_userEventsProxy.sync_writer);
43 syncsocket_free(_userEventsProxy.sync_writer);
44 _userEventsProxy.sync_writer = NULL;
45 }
46 if (_userEventsProxy.core_connection != NULL) {
47 core_connection_close(_userEventsProxy.core_connection);
48 core_connection_free(_userEventsProxy.core_connection);
49 _userEventsProxy.core_connection = NULL;
50 }
51}
52
53/* Sends an event to the core.
54 * Parameters:
55 * event - Event type. Must be one of the AUSER_EVENT_XXX.
56 * event_param - Event parameters.
57 * size - Byte size of the event parameters buffer.
58 * Return:
59 * 0 on success, or -1 on failure.
60 */
61static int
62_userEventsProxy_send(uint8_t event, const void* event_param, size_t size)
63{
64 int res;
65 UserEventHeader header;
66
67 header.event_type = event;
68 res = syncsocket_start_write(_userEventsProxy.sync_writer);
69 if (!res) {
70 // Send event type first (event header)
71 res = syncsocket_write(_userEventsProxy.sync_writer, &header,
72 sizeof(header),
73 core_connection_get_timeout(sizeof(header)));
74 if (res > 0) {
75 // Send event param next.
76 res = syncsocket_write(_userEventsProxy.sync_writer, event_param,
77 size,
78 core_connection_get_timeout(sizeof(size)));
79 }
80 res = syncsocket_result(res);
81 syncsocket_stop_write(_userEventsProxy.sync_writer);
82 }
83 if (res < 0) {
84 derror("Unable to send user event: %s\n", errno_str);
85 }
86 return res;
87}
88
89int
90userEventsProxy_create(SockAddress* console_socket)
91{
92 char* handshake = NULL;
93
94 // Connect to the user-events service.
95 _userEventsProxy.core_connection =
96 core_connection_create_and_switch(console_socket, "user-events",
97 &handshake);
98 if (_userEventsProxy.core_connection == NULL) {
99 derror("Unable to connect to the user-events service: %s\n",
100 errno_str);
101 return -1;
102 }
103
104 // Initialze event writer.
105 _userEventsProxy.sock =
106 core_connection_get_socket(_userEventsProxy.core_connection);
107 _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock);
108 if (_userEventsProxy.sync_writer == NULL) {
109 derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str);
110 _userEventsProxy_destroy();
111 return -1;
112 }
113
114 fprintf(stdout, "user-events is now connected to the core at %s.",
115 sock_address_to_string(console_socket));
116 if (handshake != NULL) {
117 if (handshake[0] != '\0') {
118 fprintf(stdout, " Handshake: %s", handshake);
119 }
120 free(handshake);
121 }
122 fprintf(stdout, "\n");
123
124 return 0;
125}
126
127void
128user_event_keycodes(int *kcodes, int count)
129{
130 int nn;
131 for (nn = 0; nn < count; nn++)
132 user_event_keycode(kcodes[nn]);
133}
134
135void
136user_event_keycode(int kcode)
137{
138 UserEventKeycode message;
139 message.keycode = kcode;
140 _userEventsProxy_send(AUSER_EVENT_KEYCODE, &message, sizeof(message));
141}
142
143void
144user_event_key(unsigned code, unsigned down)
145{
146 if(code == 0) {
147 return;
148 }
149 if (VERBOSE_CHECK(keys))
150 printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " );
151
152 user_event_keycode((code & 0x1ff) | (down ? 0x200 : 0));
153}
154
155
156void
157user_event_mouse(int dx, int dy, int dz, unsigned buttons_state)
158{
159 UserEventMouse message;
160 message.dx = dx;
161 message.dy = dy;
162 message.dz = dz;
163 message.buttons_state = buttons_state;
164 _userEventsProxy_send(AUSER_EVENT_MOUSE, &message, sizeof(message));
165}
166
167void
168user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback)
169{
170}
171
172void
173user_event_generic(int type, int code, int value)
174{
175 UserEventGeneric message;
176 message.type = type;
177 message.code = code;
178 message.value = value;
179 _userEventsProxy_send(AUSER_EVENT_GENERIC, &message, sizeof(message));
180}