1/* 2 * Copyright (c) 2001-2008, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Marc Flerackers (mflerackers@androme.be) 7 */ 8 9//! Functions and class to manage input devices. 10 11#include <stdlib.h> 12#include <string.h> 13#include <new> 14 15#include <Input.h> 16#include <List.h> 17#include <Message.h> 18 19#include <input_globals.h> 20#include <InputServerTypes.h> 21 22 23static BMessenger *sInputServer = NULL; 24 25 26BInputDevice * 27find_input_device(const char *name) 28{ 29 BMessage command(IS_FIND_DEVICES); 30 BMessage reply; 31 32 command.AddString("device", name); 33 34 status_t err = _control_input_server_(&command, &reply); 35 36 if (err != B_OK) 37 return NULL; 38 39 BInputDevice *dev = new (std::nothrow) BInputDevice; 40 if (dev == NULL) 41 return NULL; 42 43 const char *device; 44 int32 type; 45 46 reply.FindString("device", &device); 47 reply.FindInt32("type", &type); 48 49 dev->_SetNameAndType(device, (input_device_type)type); 50 51 return dev; 52} 53 54 55status_t 56get_input_devices(BList *list) 57{ 58 list->MakeEmpty(); 59 60 BMessage command(IS_FIND_DEVICES); 61 BMessage reply; 62 63 status_t err = _control_input_server_(&command, &reply); 64 65 if (err != B_OK) 66 return err; 67 68 const char *name; 69 int32 type; 70 int32 i = 0; 71 72 while (reply.FindString("device", i, &name) == B_OK) { 73 reply.FindInt32("type", i++, &type); 74 75 BInputDevice *dev = new (std::nothrow) BInputDevice; 76 if (dev != NULL) { 77 dev->_SetNameAndType(name, (input_device_type)type); 78 list->AddItem(dev); 79 } 80 } 81 82 return err; 83} 84 85 86status_t 87watch_input_devices(BMessenger target, bool start) 88{ 89 BMessage command(IS_WATCH_DEVICES); 90 BMessage reply; 91 92 command.AddMessenger("target", target); 93 command.AddBool("start", start); 94 95 return _control_input_server_(&command, &reply); 96} 97 98 99BInputDevice::~BInputDevice() 100{ 101 free(fName); 102} 103 104 105const char * 106BInputDevice::Name() const 107{ 108 return fName; 109} 110 111 112input_device_type 113BInputDevice::Type() const 114{ 115 return fType; 116} 117 118 119bool 120BInputDevice::IsRunning() const 121{ 122 if (!fName) 123 return false; 124 125 BMessage command(IS_IS_DEVICE_RUNNING); 126 BMessage reply; 127 128 command.AddString("device", fName); 129 130 return _control_input_server_(&command, &reply) == B_OK; 131} 132 133 134status_t 135BInputDevice::Start() 136{ 137 if (!fName) 138 return B_ERROR; 139 140 BMessage command(IS_START_DEVICE); 141 BMessage reply; 142 143 command.AddString("device", fName); 144 145 return _control_input_server_(&command, &reply); 146} 147 148 149status_t 150BInputDevice::Stop() 151{ 152 if (!fName) 153 return B_ERROR; 154 155 BMessage command(IS_STOP_DEVICE); 156 BMessage reply; 157 158 command.AddString("device", fName); 159 160 return _control_input_server_(&command, &reply); 161} 162 163 164status_t 165BInputDevice::Control(uint32 code, BMessage *message) 166{ 167 if (!fName) 168 return B_ERROR; 169 170 BMessage command(IS_CONTROL_DEVICES); 171 BMessage reply; 172 173 command.AddString("device", fName); 174 command.AddInt32("code", code); 175 command.AddMessage("message", message); 176 177 message->MakeEmpty(); 178 179 status_t err = _control_input_server_(&command, &reply); 180 181 if (err == B_OK) 182 reply.FindMessage("message", message); 183 184 return err; 185} 186 187 188status_t 189BInputDevice::Start(input_device_type type) 190{ 191 BMessage command(IS_START_DEVICE); 192 BMessage reply; 193 194 command.AddInt32("type", type); 195 196 return _control_input_server_(&command, &reply); 197} 198 199 200status_t 201BInputDevice::Stop(input_device_type type) 202{ 203 BMessage command(IS_STOP_DEVICE); 204 BMessage reply; 205 206 command.AddInt32("type", type); 207 208 return _control_input_server_(&command, &reply); 209} 210 211 212status_t 213BInputDevice::Control(input_device_type type, uint32 code, BMessage *message) 214{ 215 BMessage command(IS_CONTROL_DEVICES); 216 BMessage reply; 217 218 command.AddInt32("type", type); 219 command.AddInt32("code", code); 220 command.AddMessage("message", message); 221 222 message->MakeEmpty(); 223 224 status_t err = _control_input_server_(&command, &reply); 225 226 if (err == B_OK) 227 reply.FindMessage("message", message); 228 229 return err; 230} 231 232 233BInputDevice::BInputDevice() 234 : 235 fName(NULL), 236 fType(B_UNDEFINED_DEVICE) 237{ 238} 239 240 241void 242BInputDevice::_SetNameAndType(const char *name, input_device_type type) 243{ 244 if (fName) { 245 free(fName); 246 fName = NULL; 247 } 248 249 if (name) 250 fName = strdup(name); 251 252 fType = type; 253} 254 255 256status_t 257_control_input_server_(BMessage *command, BMessage *reply) 258{ 259 if (!sInputServer) { 260 sInputServer = new (std::nothrow) BMessenger; 261 if (!sInputServer) 262 return B_NO_MEMORY; 263 } 264 265 if (!sInputServer->IsValid()) 266 *sInputServer = BMessenger("application/x-vnd.Be-input_server", -1, NULL); 267 268 status_t err = sInputServer->SendMessage(command, reply, 5000000LL, 5000000LL); 269 270 if (err != B_OK) 271 return err; 272 273 if (reply->FindInt32("status", &err) != B_OK) 274 return B_ERROR; 275 276 return err; 277} 278