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