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