1 //-------------------------------------------------------------------------
2 // Handy InputFilter that dumps all Messages to a file.
3 //-------------------------------------------------------------------------
4 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7
8 #include <Debug.h>
9 #include <List.h>
10 #include <File.h>
11 #include <Message.h>
12 #include <String.h>
13 #include <OS.h>
14
15 #include <add-ons/input_server/InputServerFilter.h>
16
17 extern "C" _EXPORT BInputServerFilter* instantiate_input_filter();
18
19 class MsgSpy : public BInputServerFilter
20 {
21 public:
22 MsgSpy();
23 virtual ~MsgSpy();
24
25 virtual status_t InitCheck(void);
26 virtual filter_result Filter(BMessage *message, BList *outList);
27 private:
28 const char* MapWhatToString(uint32 w);
29 void OutputMsgField(const char* fieldName,
30 const uint32 rawType,
31 int rawCount,
32 const void* rawData);
33
34 status_t m_status;
35 BFile* m_outfile;
36 };
37
38 //-------------------------------------------------------------------------
39 // Create a new MsgSpy instance and return it to the caller.
40 //-------------------------------------------------------------------------
instantiate_input_filter()41 BInputServerFilter* instantiate_input_filter()
42 {
43 return (new MsgSpy() );
44 }
45
46
47 //-------------------------------------------------------------------------
48 //-------------------------------------------------------------------------
MsgSpy()49 MsgSpy::MsgSpy()
50 {
51 // Create the output file and return its status.
52 m_outfile = new BFile("/boot/home/MsgSpy.output", B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
53 //m_status = m_outfile->InitCheck();
54 m_status = B_OK;
55 }
56
57 //-------------------------------------------------------------------------
58 //-------------------------------------------------------------------------
~MsgSpy()59 MsgSpy::~MsgSpy()
60 {
61 if (NULL != m_outfile)
62 {
63 // Close and destroy the output file.
64 delete m_outfile;
65 }
66 }
67
68 //-------------------------------------------------------------------------
69 //-------------------------------------------------------------------------
InitCheck(void)70 status_t MsgSpy::InitCheck(void)
71 {
72 return m_status;
73 }
74
75 //-------------------------------------------------------------------------
76 //-------------------------------------------------------------------------
Filter(BMessage * message,BList * outList)77 filter_result MsgSpy::Filter(BMessage *message, BList *outList)
78 {
79 char* field_name;
80 uint32 field_type;
81 int32 field_count;
82 const void* field_data;
83 ssize_t field_data_bytes;
84 char msg_buffer [1024];
85
86 // Print out the message constant (what).
87 sprintf(msg_buffer, "%s\n", MapWhatToString(message->what) );
88 m_outfile->Write(msg_buffer, strlen(msg_buffer) );
89
90 // Display each field in the message.
91 sprintf(msg_buffer, "{\n");
92 m_outfile->Write(msg_buffer, strlen(msg_buffer) );
93 for (int32 i = 0; B_OK == message->GetInfo(B_ANY_TYPE,
94 i,
95 &field_name,
96 &field_type,
97 &field_count); i++)
98 {
99 message->FindData(field_name, field_type, &field_data, &field_data_bytes);
100 OutputMsgField(field_name, field_type, field_count, field_data);
101 }
102 sprintf(msg_buffer, "}\n");
103 m_outfile->Write(msg_buffer, strlen(msg_buffer) );
104
105 return (B_DISPATCH_MESSAGE);
106 }
107
108 //-------------------------------------------------------------------------
109 //-------------------------------------------------------------------------
MapWhatToString(uint32 w)110 const char* MsgSpy::MapWhatToString(uint32 w)
111 {
112 const char* s;
113 switch (w)
114 {
115 // Pointing device event messages.
116 case B_MOUSE_DOWN: s = "B_MOUSE_DOWN"; break;
117 case B_MOUSE_UP: s = "B_MOUSE_UP"; break;
118 case B_MOUSE_MOVED: s = "B_MOUSE_MOVED"; break;
119 case B_MOUSE_WHEEL_CHANGED: s = "B_MOUSE_WHEEL_CHANGED"; break;
120
121 // Keyboard device event messages.
122 case B_KEY_DOWN: s = "B_KEY_DOWN"; break;
123 case B_UNMAPPED_KEY_DOWN: s = "B_UNMAPPED_KEY_DOWN"; break;
124 case B_KEY_UP: s = "B_KEY_UP"; break;
125 case B_UNMAPPED_KEY_UP: s = "B_UNMAPPED_KEY_UP"; break;
126 case B_MODIFIERS_CHANGED: s = "B_MODIFIERS_CHANGED"; break;
127
128 case B_INPUT_METHOD_EVENT: s = "B_INPUT_METHOD_EVENT"; break;
129 default: s = "UNKNOWN_MESSAGE"; break;
130 }
131 return s;
132 }
133
134 //-------------------------------------------------------------------------
135 //-------------------------------------------------------------------------
OutputMsgField(const char * fieldName,const uint32 rawType,int rawCount,const void * rawData)136 void MsgSpy::OutputMsgField(const char* fieldName,
137 const uint32 rawType,
138 int rawCount,
139 const void* rawData)
140 {
141 char msg_buffer [1024];
142 char value_buffer [256];
143 BString field_data;
144 const char* field_type;
145 const int field_count = rawCount;
146 const char* separator;
147
148 switch (rawType)
149 {
150 case B_CHAR_TYPE:
151 {
152 field_type = "B_CHAR_TYPE";
153 field_data << "{ ";
154 for (const char* data_ptr = (const char*)rawData;
155 rawCount > 0;
156 rawCount--, data_ptr++)
157 {
158 separator = (1 < rawCount) ? ", " : " }";
159 field_data << *data_ptr << separator;
160 }
161 break;
162 }
163
164 case B_INT8_TYPE:
165 {
166 field_type = "B_INT8_TYPE";
167 field_data << "{ ";
168 for (const int8* data_ptr = (const int8*)rawData;
169 rawCount > 0;
170 rawCount--, data_ptr++)
171 {
172 separator = (1 < rawCount) ? ", " : " }";
173 field_data << *data_ptr << separator;
174 }
175 break;
176 }
177
178 case B_INT16_TYPE:
179 {
180 field_type = "B_INT16_TYPE";
181 field_data << "{ ";
182 for (const int16* data_ptr = (const int16*)rawData;
183 rawCount > 0;
184 rawCount--, data_ptr++)
185 {
186 separator = (1 < rawCount) ? ", " : " }";
187 field_data << *data_ptr << separator;
188 }
189 break;
190 }
191
192 case B_INT32_TYPE:
193 {
194 field_type = "B_INT32_TYPE";
195 field_data << "{ ";
196 for (const int32* data_ptr = (const int32*)rawData;
197 rawCount > 0;
198 rawCount--, data_ptr++)
199 {
200 separator = (1 < rawCount) ? ", " : " }";
201 field_data << *data_ptr << separator;
202 }
203 break;
204 }
205
206 case B_INT64_TYPE:
207 {
208 field_type = "B_INT64_TYPE";
209 field_data << "{ ";
210 for (const int64* data_ptr = (const int64*)rawData;
211 rawCount > 0;
212 rawCount--, data_ptr++)
213 {
214 separator = (1 < rawCount) ? ", " : " }";
215 field_data << *data_ptr << separator;
216 }
217 break;
218 }
219
220 case B_UINT8_TYPE:
221 {
222 field_type = "B_UINT8_TYPE";
223 field_data << "{ ";
224 for (const uint8* data_ptr = (const uint8*)rawData;
225 rawCount > 0;
226 rawCount--, data_ptr++)
227 {
228 separator = (1 < rawCount) ? ", " : " }";
229 field_data << (uint32)(*data_ptr) << separator;
230 }
231 break;
232 }
233
234 case B_UINT16_TYPE:
235 {
236 field_type = "B_UINT16_TYPE";
237 field_data << "{ ";
238 for (const uint16* data_ptr = (const uint16*)rawData;
239 rawCount > 0;
240 rawCount--, data_ptr++)
241 {
242 separator = (1 < rawCount) ? ", " : " }";
243 field_data << (uint32)(*data_ptr) << separator;
244 }
245 break;
246 }
247
248 case B_UINT32_TYPE:
249 {
250 field_type = "B_UINT32_TYPE";
251 field_data << "{ ";
252 for (const uint32* data_ptr = (const uint32*)rawData;
253 rawCount > 0;
254 rawCount--, data_ptr++)
255 {
256 separator = (1 < rawCount) ? ", " : " }";
257 field_data << *data_ptr << separator;
258 }
259 break;
260 }
261
262 case B_UINT64_TYPE:
263 {
264 field_type = "B_UINT64_TYPE";
265 field_data << "{ ";
266 for (const uint64* data_ptr = (const uint64*)rawData;
267 rawCount > 0;
268 rawCount--, data_ptr++)
269 {
270 separator = (1 < rawCount) ? ", " : " }";
271 field_data << *data_ptr << separator;
272 }
273 break;
274 }
275
276 case B_FLOAT_TYPE:
277 {
278 field_type = "B_FLOAT_TYPE";
279 field_data << "{ ";
280 for (const float* data_ptr = (const float*)rawData;
281 rawCount > 0;
282 rawCount--, data_ptr++)
283 {
284 separator = (1 < rawCount) ? ", " : " }";
285 field_data << *data_ptr << separator;
286 }
287 break;
288 }
289
290 case B_DOUBLE_TYPE:
291 {
292 field_type = "B_DOUBLE_TYPE";
293 field_data << "{ ";
294 for (const double* data_ptr = (const double*)rawData;
295 rawCount > 0;
296 rawCount--, data_ptr++)
297 {
298 separator = (1 < rawCount) ? ", " : " }";
299 sprintf(value_buffer, "%f", *data_ptr);
300 field_data << value_buffer << separator;
301 }
302 break;
303 }
304
305 case B_BOOL_TYPE:
306 {
307 field_type = "B_BOOL_TYPE";
308 field_data << "{ ";
309 for (const bool* data_ptr = (const bool*)rawData;
310 rawCount > 0;
311 rawCount--, data_ptr++)
312 {
313 separator = (1 < rawCount) ? ", " : " }";
314 sprintf(value_buffer, "%s", (true == *data_ptr) ? "true" : "false");
315 field_data << value_buffer << separator;
316 }
317 break;
318 }
319
320 case B_OFF_T_TYPE:
321 {
322 field_type = "B_OFF_T_TYPE";
323 field_data << "{ ";
324 for (const off_t* data_ptr = (const off_t*)rawData;
325 rawCount > 0;
326 rawCount--, data_ptr++)
327 {
328 separator = (1 < rawCount) ? ", " : " }";
329 field_data << *data_ptr << separator;
330 }
331 break;
332 }
333
334 case B_SIZE_T_TYPE:
335 {
336 field_type = "B_SIZE_T_TYPE";
337 field_data << "{ ";
338 for (const size_t* data_ptr = (const size_t*)rawData;
339 rawCount > 0;
340 rawCount--, data_ptr++)
341 {
342 separator = (1 < rawCount) ? ", " : " }";
343 field_data << *data_ptr << separator;
344 }
345 break;
346 }
347
348 case B_SSIZE_T_TYPE:
349 {
350 field_type = "B_SSIZE_T_TYPE";
351 field_data << "{ ";
352 for (const ssize_t* data_ptr = (const ssize_t*)rawData;
353 rawCount > 0;
354 rawCount--, data_ptr++)
355 {
356 separator = (1 < rawCount) ? ", " : " }";
357 field_data << *data_ptr << separator;
358 }
359 break;
360 }
361
362 case B_POINTER_TYPE:
363 {
364 field_type = "B_POINTER_TYPE";
365 break;
366 }
367
368 case B_OBJECT_TYPE:
369 {
370 field_type = "B_OBJECT_TYPE";
371 break;
372 }
373
374 case B_MESSAGE_TYPE:
375 {
376 field_type = "B_MESSAGE_TYPE";
377 break;
378 }
379
380 case B_MESSENGER_TYPE:
381 {
382 field_type = "B_MESSENGER_TYPE";
383 break;
384 }
385
386 case B_POINT_TYPE:
387 {
388 field_type = "B_POINT_TYPE";
389 field_data << "{ ";
390 for (const BPoint* data_ptr = (const BPoint*)rawData;
391 rawCount > 0;
392 rawCount--, data_ptr++)
393 {
394 separator = (1 < rawCount) ? ", " : " }";
395 field_data << "(" << data_ptr->x << ", " << data_ptr->y << ")" << separator;
396 }
397 break;
398 }
399
400 case B_RECT_TYPE:
401 {
402 field_type = "B_RECT_TYPE";
403 break;
404 }
405
406 // case B_PATH_TYPE: s = "B_PATH_TYPE"; break;
407
408 case B_REF_TYPE:
409 {
410 field_type = "B_REF_TYPE";
411 break;
412 }
413
414 case B_RGB_COLOR_TYPE:
415 {
416 field_type = "B_RGB_COLOR_TYPE";
417 break;
418 }
419
420 case B_PATTERN_TYPE:
421 {
422 field_type = "B_PATTERN_TYPE";
423 break;
424 }
425
426 case B_STRING_TYPE:
427 {
428 field_type = "B_STRING_TYPE";
429 field_data << "{ ";
430 for (const char* data_ptr = (const char*)rawData;
431 rawCount > 0;
432 rawCount--, data_ptr+= strlen(data_ptr) )
433 {
434 separator = (1 < rawCount) ? ", " : " }";
435 field_data << "\"" << data_ptr << "\"" << separator;
436 }
437 break;
438 }
439
440 case B_MONOCHROME_1_BIT_TYPE:
441 {
442 field_type = "B_MONOCHROME_1_BIT_TYPE";
443 break;
444 }
445
446 case B_GRAYSCALE_8_BIT_TYPE:
447 {
448 field_type = "B_GRAYSCALE_8_BIT_TYPE";
449 break;
450 }
451
452 case B_COLOR_8_BIT_TYPE:
453 {
454 field_type = "B_COLOR_8_BIT_TYPE";
455 break;
456 }
457
458 case B_RGB_32_BIT_TYPE:
459 {
460 field_type = "B_RGB_32_BIT_TYPE";
461 break;
462 }
463
464 case B_TIME_TYPE:
465 {
466 field_type = "B_TIME_TYPE";
467 break;
468 }
469
470 case B_MEDIA_PARAMETER_TYPE:
471 {
472 field_type = "B_MEDIA_PARAMETER_TYPE";
473 break;
474 }
475
476 case B_MEDIA_PARAMETER_WEB_TYPE:
477 {
478 field_type = "B_MEDIA_PARAMETER_WEB_TYPE";
479 break;
480 }
481
482 case B_MEDIA_PARAMETER_GROUP_TYPE:
483 {
484 field_type = "B_MEDIA_PARAMETER_GROUP_TYPE";
485 break;
486 }
487
488 case B_RAW_TYPE:
489 {
490 field_type = "B_RAW_TYPE";
491 break;
492 }
493
494 case B_MIME_TYPE:
495 {
496 field_type = "B_MIME_TYPE";
497 break;
498 }
499
500 case B_ANY_TYPE:
501 {
502 field_type = "B_ANY_TYPE";
503 break;
504 }
505
506 default:
507 {
508 field_type = "UNKNOWN_TYPE";
509 break;
510 }
511 }
512
513 sprintf(msg_buffer,
514 " %-18s %-18s [%2d] = %s\n",
515 field_type,
516 fieldName,
517 field_count,
518 field_data.String() );
519
520 m_outfile->Write(msg_buffer, strlen(msg_buffer) );
521 }
522