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 23 static BMessenger *sInputServer = NULL; 24 25 26 BInputDevice * 27 find_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 55 status_t 56 get_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 86 status_t 87 watch_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 99 BInputDevice::~BInputDevice() 100 { 101 free(fName); 102 } 103 104 105 const char * 106 BInputDevice::Name() const 107 { 108 return fName; 109 } 110 111 112 input_device_type 113 BInputDevice::Type() const 114 { 115 return fType; 116 } 117 118 119 bool 120 BInputDevice::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 134 status_t 135 BInputDevice::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 149 status_t 150 BInputDevice::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 164 status_t 165 BInputDevice::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 188 status_t 189 BInputDevice::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 200 status_t 201 BInputDevice::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 212 status_t 213 BInputDevice::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 233 BInputDevice::BInputDevice() 234 : 235 fName(NULL), 236 fType(B_UNDEFINED_DEVICE) 237 { 238 } 239 240 241 void 242 BInputDevice::_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 256 status_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