• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. */
23 typedef 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. */
35 static 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  */
45 static int
_userEventsProxy_send(uint8_t event,const void * event_param,size_t size)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 
73 int
userEventsProxy_create(SockAddress * console_socket)74 userEventsProxy_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 
111 void
userEventsProxy_destroy(void)112 userEventsProxy_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 }
125 void
user_event_keycodes(int * kcodes,int count)126 user_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 
133 void
user_event_keycode(int kcode)134 user_event_keycode(int  kcode)
135 {
136     UserEventKeycode    message;
137     message.keycode = kcode;
138     _userEventsProxy_send(AUSER_EVENT_KEYCODE, &message, sizeof(message));
139 }
140 
141 void
user_event_key(unsigned code,unsigned down)142 user_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 
154 void
user_event_mouse(int dx,int dy,int dz,unsigned buttons_state)155 user_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 
165 void
user_event_register_generic(void * opaque,QEMUPutGenericEvent * callback)166 user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback)
167 {
168 }
169 
170 void
user_event_generic(int type,int code,int value)171 user_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