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