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