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
GetServiceClass(BString & serviceClass)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
GetMajorDeviceClass(BString & majorClass)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
GetMinorDeviceClass(BString & minorClass)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
DumpDeviceClass(BString & string)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
Draw(BView * view,const BPoint & point)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