Home | History | Annotate | Download | only in protocol
      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
     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
     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
    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
    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
    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
    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
    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
    166 user_event_register_generic(void* opaque, QEMUPutGenericEvent *callback)
    167 {
    168 }
    169 
    170 void
    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