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