1 /* 2 * Copyright 2007-2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include <bluetooth/DeviceClass.h> 7 8 #include <Catalog.h> 9 #include <Locale.h> 10 11 12 #undef B_TRANSLATION_CONTEXT 13 #define B_TRANSLATION_CONTEXT "DeviceClass" 14 15 16 namespace Bluetooth { 17 18 void 19 DeviceClass::GetServiceClass(BString& serviceClass) 20 { 21 static const char *services[] = { B_TRANSLATE_MARK("Positioning"), 22 B_TRANSLATE_MARK("Networking"), B_TRANSLATE_MARK("Rendering"), 23 B_TRANSLATE_MARK("Capturing"), B_TRANSLATE_MARK("Object transfer"), 24 B_TRANSLATE_MARK("Audio"), B_TRANSLATE_MARK("Telephony"), 25 B_TRANSLATE_MARK("Information") }; 26 27 if (ServiceClass() != 0) { 28 bool first = true; 29 30 for (uint s = 0; s < (sizeof(services) / sizeof(*services)); s++) { 31 if (ServiceClass() & (1 << s)) { 32 if (first) { 33 first = false; 34 serviceClass << services[s]; 35 } else { 36 serviceClass << ", " << services[s]; 37 } 38 39 } 40 } 41 42 } else 43 serviceClass << B_TRANSLATE("Unspecified"); 44 45 } 46 47 48 void 49 DeviceClass::GetMajorDeviceClass(BString& majorClass) 50 { 51 static const char *major_devices[] = { B_TRANSLATE_MARK("Miscellaneous"), 52 B_TRANSLATE_MARK("Computer"), B_TRANSLATE_MARK("Phone"), 53 B_TRANSLATE_MARK("LAN access"), B_TRANSLATE_MARK("Audio/Video"), 54 B_TRANSLATE_MARK("Peripheral"), B_TRANSLATE_MARK("Imaging"), 55 B_TRANSLATE_MARK("Uncategorized") }; 56 57 if (MajorDeviceClass() >= sizeof(major_devices) / sizeof(*major_devices)) 58 majorClass << B_TRANSLATE("Invalid device class!\n"); 59 else 60 majorClass << major_devices[MajorDeviceClass()]; 61 62 } 63 64 65 void 66 DeviceClass::GetMinorDeviceClass(BString& minorClass) 67 { 68 uint major = MajorDeviceClass(); 69 uint minor = MinorDeviceClass(); 70 71 switch (major) { 72 case 0: /* misc */ 73 minorClass << " -"; 74 break; 75 case 1: /* computer */ 76 switch(minor) { 77 case 0: 78 minorClass << B_TRANSLATE("Uncategorized"); 79 break; 80 case 1: 81 minorClass << B_TRANSLATE("Desktop workstation"); 82 break; 83 case 2: 84 minorClass << B_TRANSLATE("Server"); 85 break; 86 case 3: 87 minorClass << B_TRANSLATE("Laptop"); 88 break; 89 case 4: 90 minorClass << B_TRANSLATE("Handheld"); 91 break; 92 case 5: 93 minorClass << B_TRANSLATE_COMMENT("Palm", 94 "A palm-held device"); 95 break; 96 case 6: 97 minorClass << B_TRANSLATE_COMMENT("Wearable", 98 "A wearable computer"); 99 break; 100 } 101 break; 102 case 2: /* phone */ 103 switch(minor) { 104 case 0: 105 minorClass << B_TRANSLATE("Uncategorized"); 106 break; 107 case 1: 108 minorClass << B_TRANSLATE("Cellular"); 109 break; 110 case 2: 111 minorClass << B_TRANSLATE("Cordless"); 112 break; 113 case 3: 114 minorClass << B_TRANSLATE("Smart phone"); 115 break; 116 case 4: 117 minorClass << B_TRANSLATE("Wired modem or voice gateway"); 118 break; 119 case 5: 120 minorClass << B_TRANSLATE("Common ISDN access"); 121 break; 122 case 6: 123 minorClass << B_TRANSLATE("SIM card reader"); 124 break; 125 } 126 break; 127 case 3: /* lan access */ 128 if (minor == 0) { 129 minorClass << B_TRANSLATE("Uncategorized"); 130 break; 131 } 132 switch(minor / 8) { 133 case 0: 134 minorClass << B_TRANSLATE("Fully available"); 135 break; 136 case 1: 137 minorClass << B_TRANSLATE("1-17% utilized"); 138 break; 139 case 2: 140 minorClass << B_TRANSLATE("17-33% utilized"); 141 break; 142 case 3: 143 minorClass << B_TRANSLATE("33-50% utilized"); 144 break; 145 case 4: 146 minorClass << B_TRANSLATE("50-67% utilized"); 147 break; 148 case 5: 149 minorClass << B_TRANSLATE("67-83% utilized"); 150 break; 151 case 6: 152 minorClass << B_TRANSLATE("83-99% utilized"); 153 break; 154 case 7: 155 minorClass << B_TRANSLATE("No service available"); 156 break; 157 } 158 break; 159 case 4: /* audio/video */ 160 switch(minor) { 161 case 0: 162 minorClass << B_TRANSLATE("Uncategorized"); 163 break; 164 case 1: 165 minorClass << B_TRANSLATE("Device conforms to the headset profile"); 166 break; 167 case 2: 168 minorClass << B_TRANSLATE("Hands-free"); 169 break; 170 /* 3 is reserved */ 171 case 4: 172 minorClass << B_TRANSLATE("Microphone"); 173 break; 174 case 5: 175 minorClass << B_TRANSLATE("Loudspeaker"); 176 break; 177 case 6: 178 minorClass << B_TRANSLATE("Headphones"); 179 break; 180 case 7: 181 minorClass << B_TRANSLATE("Portable audio"); 182 break; 183 case 8: 184 minorClass << B_TRANSLATE("Car audio"); 185 break; 186 case 9: 187 minorClass << B_TRANSLATE("Set-top box"); 188 break; 189 case 10: 190 minorClass << B_TRANSLATE("HiFi audio device"); 191 break; 192 case 11: 193 minorClass << B_TRANSLATE("VCR"); 194 break; 195 case 12: 196 minorClass << B_TRANSLATE("Video camera"); 197 break; 198 case 13: 199 minorClass << B_TRANSLATE("Camcorder"); 200 break; 201 case 14: 202 minorClass << B_TRANSLATE("Video monitor"); 203 break; 204 case 15: 205 minorClass << B_TRANSLATE("Video display and loudspeaker"); 206 break; 207 case 16: 208 minorClass << B_TRANSLATE("Video conferencing"); 209 break; 210 /* 17 is reserved */ 211 case 18: 212 minorClass << B_TRANSLATE("Gaming/Toy"); 213 break; 214 } 215 break; 216 case 5: /* peripheral */ 217 { 218 switch(minor & 48) { 219 case 16: 220 minorClass << B_TRANSLATE("Keyboard"); 221 if (minor & 15) 222 minorClass << "/"; 223 break; 224 case 32: 225 minorClass << B_TRANSLATE("Pointing device"); 226 if (minor & 15) 227 minorClass << "/"; 228 break; 229 case 48: 230 minorClass << B_TRANSLATE("Combo keyboard/pointing device"); 231 if (minor & 15) 232 minorClass << "/"; 233 break; 234 } 235 236 switch(minor & 15) { 237 case 0: 238 break; 239 case 1: 240 minorClass << B_TRANSLATE("Joystick"); 241 break; 242 case 2: 243 minorClass << B_TRANSLATE("Gamepad"); 244 break; 245 case 3: 246 minorClass << B_TRANSLATE("Remote control"); 247 break; 248 case 4: 249 minorClass << B_TRANSLATE("Sensing device"); 250 break; 251 case 5: 252 minorClass << B_TRANSLATE("Digitizer tablet"); 253 break; 254 case 6: 255 minorClass << B_TRANSLATE("Card reader"); 256 break; 257 default: 258 minorClass << B_TRANSLATE("(reserved)"); 259 break; 260 } 261 break; 262 } 263 case 6: /* imaging */ 264 if (minor & 4) 265 minorClass << B_TRANSLATE("Display"); 266 if (minor & 8) 267 minorClass << B_TRANSLATE("Camera"); 268 if (minor & 16) 269 minorClass << B_TRANSLATE("Scanner"); 270 if (minor & 32) 271 minorClass << B_TRANSLATE("Printer"); 272 break; 273 case 7: /* wearable */ 274 switch(minor) { 275 case 1: 276 minorClass << B_TRANSLATE("Wrist watch"); 277 break; 278 case 2: 279 minorClass << B_TRANSLATE_COMMENT("Pager", 280 "A small radio device to receive short text messages"); 281 break; 282 case 3: 283 minorClass << B_TRANSLATE("Jacket"); 284 break; 285 case 4: 286 minorClass << B_TRANSLATE("Helmet"); 287 break; 288 case 5: 289 minorClass << B_TRANSLATE("Glasses"); 290 break; 291 } 292 break; 293 case 8: /* toy */ 294 switch(minor) { 295 case 1: 296 minorClass << B_TRANSLATE("Robot"); 297 break; 298 case 2: 299 minorClass << B_TRANSLATE("Vehicle"); 300 break; 301 case 3: 302 minorClass << B_TRANSLATE("Doll/Action figure"); 303 break; 304 case 4: 305 minorClass << B_TRANSLATE("Controller"); 306 break; 307 case 5: 308 minorClass << B_TRANSLATE("Game"); 309 break; 310 } 311 break; 312 case 63: /* uncategorised */ 313 minorClass << ""; 314 break; 315 default: 316 minorClass << B_TRANSLATE("Unknown (reserved) minor device class"); 317 break; 318 } 319 } 320 321 322 void 323 DeviceClass::DumpDeviceClass(BString& string) 324 { 325 string << B_TRANSLATE("Service classes: "); 326 GetServiceClass(string); 327 string << " | "; 328 string << B_TRANSLATE("Major class: "); 329 GetMajorDeviceClass(string); 330 string << " | "; 331 string << B_TRANSLATE("Minor class: "); 332 GetMinorDeviceClass(string); 333 string << "."; 334 } 335 336 337 void 338 DeviceClass::Draw(BView* view, const BPoint& point) 339 { 340 rgb_color kBlack = { 0,0,0,0 }; 341 rgb_color kBlue = { 28,110,157,0 }; 342 rgb_color kWhite = { 255,255,255,0 }; 343 344 345 view->SetHighColor(kBlue); 346 view->FillRoundRect(BRect(point.x + IconInsets, point.y + IconInsets, 347 point.x + IconInsets + PixelsForIcon, point.y + IconInsets + PixelsForIcon), 5, 5); 348 349 view->SetHighColor(kWhite); 350 351 switch (MajorDeviceClass()) { 352 353 case 2: // phone 354 view->StrokeRoundRect(BRect(point.x + IconInsets + uint(PixelsForIcon/4), 355 point.y + IconInsets + 6, 356 point.x + IconInsets + uint(PixelsForIcon*3/4), 357 point.y + IconInsets + PixelsForIcon - 2), 2, 2); 358 view->StrokeRect(BRect(point.x + IconInsets + uint(PixelsForIcon/4) + 4, 359 point.y + IconInsets + 10, 360 point.x + IconInsets + uint(PixelsForIcon*3/4) - 4, 361 point.y + IconInsets + uint(PixelsForIcon*3/4))); 362 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/4) + 4, 363 point.y + IconInsets + PixelsForIcon - 6), 364 BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4) - 4, 365 point.y + IconInsets + PixelsForIcon - 6)); 366 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/4) + 4, 367 point.y + IconInsets + PixelsForIcon - 4), 368 BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4) - 4, 369 point.y + IconInsets + PixelsForIcon - 4)); 370 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/4) + 4, 371 point.y + IconInsets + 2), 372 BPoint(point.x + IconInsets + uint(PixelsForIcon/4) + 4, 373 point.y + IconInsets + 6)); 374 break; 375 case 3: // LAN 376 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/4), 377 point.y + IconInsets + uint(PixelsForIcon*3/8)), 378 BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4), 379 point.y + IconInsets + uint(PixelsForIcon*3/8))); 380 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*5/8), 381 point.y + IconInsets + uint(PixelsForIcon/8))); 382 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4), 383 point.y + IconInsets + uint(PixelsForIcon*5/8)), 384 BPoint(point.x + IconInsets + uint(PixelsForIcon/4), 385 point.y + IconInsets + uint(PixelsForIcon*5/8))); 386 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*3/8), 387 point.y + IconInsets + uint(PixelsForIcon*7/8))); 388 break; 389 case 4: // audio/video 390 view->StrokeRect(BRect(point.x + IconInsets + uint(PixelsForIcon/4), 391 point.y + IconInsets + uint(PixelsForIcon*3/8), 392 point.x + IconInsets + uint(PixelsForIcon*3/8), 393 point.y + IconInsets + uint(PixelsForIcon*5/8))); 394 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*3/8), 395 point.y + IconInsets + uint(PixelsForIcon*3/8)), 396 BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4), 397 point.y + IconInsets + uint(PixelsForIcon/8))); 398 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4), 399 point.y + IconInsets + uint(PixelsForIcon*7/8))); 400 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*3/8), 401 point.y + IconInsets + uint(PixelsForIcon*5/8))); 402 break; 403 default: // Bluetooth Logo 404 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/4), 405 point.y + IconInsets + uint(PixelsForIcon*3/4)), 406 BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4), 407 point.y + IconInsets + uint(PixelsForIcon/4))); 408 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/2), 409 point.y + IconInsets +2)); 410 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/2), 411 point.y + IconInsets + PixelsForIcon - 2)); 412 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon*3/4), 413 point.y + IconInsets + uint(PixelsForIcon*3/4))); 414 view->StrokeLine(BPoint(point.x + IconInsets + uint(PixelsForIcon/4), 415 point.y + IconInsets + uint(PixelsForIcon/4))); 416 break; 417 } 418 419 view->SetHighColor(kBlack); 420 } 421 422 423 } 424