xref: /haiku/src/kits/bluetooth/DeviceClass.cpp (revision 19733b44fa2862d0629d5dbfff0389bba79007d7)
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