adb_mouse.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00041 #include <ipc/mouse.h>
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <async.h>
00045 #include <errno.h>
00046 #include <devmap.h>
00047 
00048 #include "adb_mouse.h"
00049 #include "adb_dev.h"
00050 
00051 static void client_connection(ipc_callid_t iid, ipc_call_t *icall);
00052 static void mouse_ev_btn(int button, int press);
00053 static void mouse_ev_move(int dx, int dy);
00054 
00055 static int client_phone = -1;
00056 static bool b1_pressed, b2_pressed;
00057 
00058 int main(int argc, char **argv)
00059 {
00060         printf(NAME ": Chardev mouse driver\n");
00061 
00062         /* Initialize device. */
00063         if (adb_dev_init() != 0)
00064                 return -1;
00065 
00066         b1_pressed = false;
00067         b2_pressed = false; 
00068 
00069         /* Register driver */
00070         int rc = devmap_driver_register(NAME, client_connection);
00071         if (rc < 0) {
00072                 printf(NAME ": Unable to register driver (%d)\n", rc);
00073                 return -1;
00074         }
00075 
00076         char dev_path[DEVMAP_NAME_MAXLEN + 1];
00077         snprintf(dev_path, DEVMAP_NAME_MAXLEN, "%s/mouse", NAMESPACE);
00078 
00079         devmap_handle_t devmap_handle;
00080         if (devmap_device_register(dev_path, &devmap_handle) != EOK) {
00081                 printf(NAME ": Unable to register device %s\n", dev_path);
00082                 return -1;
00083         }
00084 
00085         printf(NAME ": Accepting connections\n");
00086         task_retval(0);
00087         async_manager();
00088 
00089         /* Not reached. */
00090         return 0;
00091 }
00092 
00093 static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
00094 {
00095         ipc_callid_t callid;
00096         ipc_call_t call;
00097         int retval;
00098 
00099         async_answer_0(iid, EOK);
00100 
00101         while (1) {
00102                 callid = async_get_call(&call);
00103                 switch (IPC_GET_IMETHOD(call)) {
00104                 case IPC_M_PHONE_HUNGUP:
00105                         if (client_phone != -1) {
00106                                 async_hangup(client_phone);
00107                                 client_phone = -1;
00108                         }
00109 
00110                         async_answer_0(callid, EOK);
00111                         return;
00112                 case IPC_M_CONNECT_TO_ME:
00113                         if (client_phone != -1) {
00114                                 retval = ELIMIT;
00115                                 break;
00116                         }
00117                         client_phone = IPC_GET_ARG5(call);
00118                         retval = 0;
00119                         break;
00120                 default:
00121                         retval = EINVAL;
00122                 }
00123                 async_answer_0(callid, retval);
00124         }
00125 }
00126 
00127 void mouse_handle_data(uint16_t data)
00128 {
00129         bool b1, b2;
00130         uint16_t udx, udy;
00131         int dx, dy;
00132 
00133         /* Extract fields. */
00134         b1 = ((data >> 15) & 1) == 0;
00135         udy = (data >> 8) & 0x7f;
00136         b2 = ((data >> 7) & 1) == 0;
00137         udx = data & 0x7f;
00138 
00139         /* Decode 7-bit two's complement signed values. */
00140         dx = (udx & 0x40) ? (udx - 0x80) : udx;
00141         dy = (udy & 0x40) ? (udy - 0x80) : udy;
00142 
00143         if (b1 != b1_pressed) {
00144                 mouse_ev_btn(1, b1);
00145                 b1_pressed = b1;
00146         }
00147 
00148         if (b2 != b2_pressed) {
00149                 mouse_ev_btn(2, b2);
00150                 b1_pressed = b1;
00151         }
00152 
00153         if (dx != 0 || dy != 0)
00154                 mouse_ev_move(dx, dy);
00155 }
00156 
00157 static void mouse_ev_btn(int button, int press)
00158 {
00159         if (client_phone != -1) {
00160                 async_msg_2(client_phone, MEVENT_BUTTON, button, press);
00161         }
00162 }
00163 
00164 static void mouse_ev_move(int dx, int dy)
00165 {
00166         if (client_phone != -1)
00167                 async_msg_2(client_phone, MEVENT_MOVE, dx, dy);
00168 }
00169 

Generated on Thu Jun 2 07:45:49 2011 for HelenOS/USB by  doxygen 1.4.7