161d7deeeSJérôme Duval /*****************************************************************************/ 261d7deeeSJérôme Duval // Mouse input server device addon 361d7deeeSJérôme Duval // Written by Stefano Ceccherini 461d7deeeSJérôme Duval // 561d7deeeSJérôme Duval // MouseInputDevice.cpp 661d7deeeSJérôme Duval // 761d7deeeSJérôme Duval // Copyright (c) 2004 Haiku Project 861d7deeeSJérôme Duval // 961d7deeeSJérôme Duval // Permission is hereby granted, free of charge, to any person obtaining a 1061d7deeeSJérôme Duval // copy of this software and associated documentation files (the "Software"), 1161d7deeeSJérôme Duval // to deal in the Software without restriction, including without limitation 1261d7deeeSJérôme Duval // the rights to use, copy, modify, merge, publish, distribute, sublicense, 1361d7deeeSJérôme Duval // and/or sell copies of the Software, and to permit persons to whom the 1461d7deeeSJérôme Duval // Software is furnished to do so, subject to the following conditions: 1561d7deeeSJérôme Duval // 1661d7deeeSJérôme Duval // The above copyright notice and this permission notice shall be included 1761d7deeeSJérôme Duval // in all copies or substantial portions of the Software. 1861d7deeeSJérôme Duval // 1961d7deeeSJérôme Duval // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2061d7deeeSJérôme Duval // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2161d7deeeSJérôme Duval // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2261d7deeeSJérôme Duval // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2361d7deeeSJérôme Duval // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2461d7deeeSJérôme Duval // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2561d7deeeSJérôme Duval // DEALINGS IN THE SOFTWARE. 2661d7deeeSJérôme Duval /*****************************************************************************/ 2761d7deeeSJérôme Duval #include "MouseInputDevice.h" 2861d7deeeSJérôme Duval 2961d7deeeSJérôme Duval #include <stdlib.h> 3061d7deeeSJérôme Duval #include <unistd.h> 3161d7deeeSJérôme Duval 3261d7deeeSJérôme Duval const static uint32 kGetMouseMovements = 10099; 33*53d77642SJérôme Duval const static uint32 kGetMouseAccel = 10101; 34*53d77642SJérôme Duval const static uint32 kSetMouseAccel = 10102; 35*53d77642SJérôme Duval const static uint32 kSetMouseType = 10104; 36*53d77642SJérôme Duval const static uint32 kSetMouseMap = 10106; 37*53d77642SJérôme Duval const static uint32 kSetClickSpeed = 10108; 3861d7deeeSJérôme Duval 3961d7deeeSJérôme Duval struct mouse_movement { 4061d7deeeSJérôme Duval int32 ser_fd_index; 4161d7deeeSJérôme Duval int32 buttons; 4261d7deeeSJérôme Duval int32 xdelta; 4361d7deeeSJérôme Duval int32 ydelta; 4461d7deeeSJérôme Duval int32 click_count; 4561d7deeeSJérôme Duval int32 mouse_mods; 4661d7deeeSJérôme Duval int64 mouse_time; 4761d7deeeSJérôme Duval }; 4861d7deeeSJérôme Duval 4961d7deeeSJérôme Duval 5061d7deeeSJérôme Duval extern "C" 5161d7deeeSJérôme Duval BInputServerDevice * 5261d7deeeSJérôme Duval instantiate_input_device() 5361d7deeeSJérôme Duval { 5461d7deeeSJérôme Duval return new MouseInputDevice(); 5561d7deeeSJérôme Duval } 5661d7deeeSJérôme Duval 5761d7deeeSJérôme Duval 5861d7deeeSJérôme Duval MouseInputDevice::MouseInputDevice() 59*53d77642SJérôme Duval : fThread(-1), 60*53d77642SJérôme Duval fQuit(false) 6161d7deeeSJérôme Duval { 6261d7deeeSJérôme Duval fFd = open("dev/input/mouse/ps2/0", O_RDWR); 6361d7deeeSJérôme Duval if (fFd >= 0) 6461d7deeeSJérôme Duval fThread = spawn_thread(DeviceWatcher, "mouse watcher thread", 6561d7deeeSJérôme Duval B_NORMAL_PRIORITY, this); 6661d7deeeSJérôme Duval 6761d7deeeSJérôme Duval fLogFile = fopen("/boot/home/device_log.log", "w"); 6861d7deeeSJérôme Duval } 6961d7deeeSJérôme Duval 7061d7deeeSJérôme Duval 7161d7deeeSJérôme Duval MouseInputDevice::~MouseInputDevice() 7261d7deeeSJérôme Duval { 7361d7deeeSJérôme Duval if (fThread >= 0) { 7461d7deeeSJérôme Duval status_t dummy; 7561d7deeeSJérôme Duval wait_for_thread(fThread, &dummy); 7661d7deeeSJérôme Duval } 7761d7deeeSJérôme Duval 7861d7deeeSJérôme Duval if (fFd >= 0) 7961d7deeeSJérôme Duval close(fFd); 8061d7deeeSJérôme Duval 8161d7deeeSJérôme Duval fclose(fLogFile); 8261d7deeeSJérôme Duval } 8361d7deeeSJérôme Duval 8461d7deeeSJérôme Duval 8561d7deeeSJérôme Duval status_t 86*53d77642SJérôme Duval MouseInputDevice::InitFromSettings(uint32 opcode) 87*53d77642SJérôme Duval { 88*53d77642SJérôme Duval // retrieve current values 89*53d77642SJérôme Duval 90*53d77642SJérôme Duval if (get_mouse_map(&fSettings.map)!=B_OK) 91*53d77642SJérôme Duval fprintf(stderr, "error when get_mouse_map\n"); 92*53d77642SJérôme Duval else 93*53d77642SJérôme Duval ioctl(fFd, kSetMouseMap, &fSettings.map); 94*53d77642SJérôme Duval 95*53d77642SJérôme Duval if (get_click_speed(&fSettings.click_speed)!=B_OK) 96*53d77642SJérôme Duval fprintf(stderr, "error when get_click_speed\n"); 97*53d77642SJérôme Duval else 98*53d77642SJérôme Duval ioctl(fFd, kSetClickSpeed, &fSettings.click_speed); 99*53d77642SJérôme Duval 100*53d77642SJérôme Duval if (get_mouse_speed(&fSettings.accel.speed)!=B_OK) 101*53d77642SJérôme Duval fprintf(stderr, "error when get_mouse_speed\n"); 102*53d77642SJérôme Duval else { 103*53d77642SJérôme Duval if (get_mouse_acceleration(&fSettings.accel.accel_factor)!=B_OK) 104*53d77642SJérôme Duval fprintf(stderr, "error when get_mouse_acceleration\n"); 105*53d77642SJérôme Duval else { 106*53d77642SJérôme Duval mouse_accel accel; 107*53d77642SJérôme Duval ioctl(fFd, kGetMouseAccel, &accel); 108*53d77642SJérôme Duval accel.speed = fSettings.accel.speed; 109*53d77642SJérôme Duval accel.accel_factor = fSettings.accel.accel_factor; 110*53d77642SJérôme Duval ioctl(fFd, kSetMouseAccel, &fSettings.accel); 111*53d77642SJérôme Duval } 112*53d77642SJérôme Duval } 113*53d77642SJérôme Duval 114*53d77642SJérôme Duval if (get_mouse_type(&fSettings.type)!=B_OK) 115*53d77642SJérôme Duval fprintf(stderr, "error when get_mouse_type\n"); 116*53d77642SJérôme Duval else 117*53d77642SJérôme Duval ioctl(fFd, kSetMouseType, &fSettings.type); 118*53d77642SJérôme Duval 119*53d77642SJérôme Duval return B_OK; 120*53d77642SJérôme Duval } 121*53d77642SJérôme Duval 122*53d77642SJérôme Duval 123*53d77642SJérôme Duval status_t 12461d7deeeSJérôme Duval MouseInputDevice::InitCheck() 12561d7deeeSJérôme Duval { 126*53d77642SJérôme Duval InitFromSettings(); 127*53d77642SJérôme Duval 12861d7deeeSJérôme Duval input_device_ref mouse1 = { "Mouse 1", B_POINTING_DEVICE, (void *)this }; 12961d7deeeSJérôme Duval 13061d7deeeSJérôme Duval input_device_ref *devices[2] = { &mouse1, NULL }; 13161d7deeeSJérôme Duval 13261d7deeeSJérôme Duval if (fFd >= 0 && fThread >= 0) { 13361d7deeeSJérôme Duval RegisterDevices(devices); 13461d7deeeSJérôme Duval return BInputServerDevice::InitCheck(); 13561d7deeeSJérôme Duval } 13661d7deeeSJérôme Duval return B_ERROR; 13761d7deeeSJérôme Duval } 13861d7deeeSJérôme Duval 13961d7deeeSJérôme Duval 14061d7deeeSJérôme Duval status_t 14161d7deeeSJérôme Duval MouseInputDevice::Start(const char *name, void *cookie) 14261d7deeeSJérôme Duval { 14361d7deeeSJérôme Duval fputs("Start(", fLogFile); 14461d7deeeSJérôme Duval fputs(name, fLogFile); 14561d7deeeSJérôme Duval fputs(")\n", fLogFile); 14661d7deeeSJérôme Duval resume_thread(fThread); 14761d7deeeSJérôme Duval 14861d7deeeSJérôme Duval return B_OK; 14961d7deeeSJérôme Duval } 15061d7deeeSJérôme Duval 15161d7deeeSJérôme Duval 15261d7deeeSJérôme Duval status_t 15361d7deeeSJérôme Duval MouseInputDevice::Stop(const char *device, void *cookie) 15461d7deeeSJérôme Duval { 15561d7deeeSJérôme Duval fputs("Stop()\n", fLogFile); 15661d7deeeSJérôme Duval 15761d7deeeSJérôme Duval suspend_thread(fThread); 15861d7deeeSJérôme Duval 15961d7deeeSJérôme Duval return B_OK; 16061d7deeeSJérôme Duval } 16161d7deeeSJérôme Duval 16261d7deeeSJérôme Duval 16361d7deeeSJérôme Duval status_t 16461d7deeeSJérôme Duval MouseInputDevice::Control(const char *name, void *cookie, 16561d7deeeSJérôme Duval uint32 command, BMessage *message) 16661d7deeeSJérôme Duval { 16761d7deeeSJérôme Duval fputs("Control()\n", fLogFile); 168*53d77642SJérôme Duval 169*53d77642SJérôme Duval if (command == B_NODE_MONITOR) 170*53d77642SJérôme Duval HandleMonitor(message); 171*53d77642SJérôme Duval else if (command >= B_MOUSE_TYPE_CHANGED 172*53d77642SJérôme Duval && command <= B_MOUSE_ACCELERATION_CHANGED) { 173*53d77642SJérôme Duval InitFromSettings(command); 174*53d77642SJérôme Duval } 175*53d77642SJérôme Duval return B_OK; 176*53d77642SJérôme Duval } 177*53d77642SJérôme Duval 178*53d77642SJérôme Duval 179*53d77642SJérôme Duval status_t 180*53d77642SJérôme Duval MouseInputDevice::HandleMonitor(BMessage *message) 181*53d77642SJérôme Duval { 18261d7deeeSJérôme Duval return B_OK; 18361d7deeeSJérôme Duval } 18461d7deeeSJérôme Duval 18561d7deeeSJérôme Duval 18661d7deeeSJérôme Duval int32 18761d7deeeSJérôme Duval MouseInputDevice::DeviceWatcher(void *arg) 18861d7deeeSJérôme Duval { 18961d7deeeSJérôme Duval MouseInputDevice *dev = (MouseInputDevice *)arg; 19061d7deeeSJérôme Duval mouse_movement movements; 19161d7deeeSJérôme Duval BMessage *message; 19261d7deeeSJérôme Duval char log[128]; 19361d7deeeSJérôme Duval while (!dev->fQuit) { 19461d7deeeSJérôme Duval ioctl(dev->fFd, kGetMouseMovements, &movements); 19561d7deeeSJérôme Duval 19661d7deeeSJérôme Duval // TODO: send B_MOUSE_UP/B_MOUSE_DOWN messages 19761d7deeeSJérôme Duval 19861d7deeeSJérôme Duval message = new BMessage(B_MOUSE_MOVED); 19961d7deeeSJérôme Duval if (message) { 20061d7deeeSJérôme Duval message->AddInt32("buttons", movements.buttons); 20161d7deeeSJérôme Duval message->AddInt32("x", movements.xdelta); 20261d7deeeSJérôme Duval message->AddInt32("y", movements.ydelta); 20361d7deeeSJérôme Duval snprintf(log, 128, "buttons: %ld, x: %ld, y: %ld\n", 20461d7deeeSJérôme Duval movements.buttons, movements.xdelta, movements.ydelta); 20561d7deeeSJérôme Duval 20661d7deeeSJérôme Duval fputs(log, dev->fLogFile); 20761d7deeeSJérôme Duval 20861d7deeeSJérôme Duval dev->EnqueueMessage(message); 20961d7deeeSJérôme Duval } 21061d7deeeSJérôme Duval snooze(1000); 21161d7deeeSJérôme Duval } 21261d7deeeSJérôme Duval 21361d7deeeSJérôme Duval return 0; 21461d7deeeSJérôme Duval } 21561d7deeeSJérôme Duval 21661d7deeeSJérôme Duval 217