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 //------------------------------------------------------------------------- 41 BInputServerFilter* instantiate_input_filter() 42 { 43 return (new MsgSpy() ); 44 } 45 46 47 //------------------------------------------------------------------------- 48 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 70 status_t MsgSpy::InitCheck(void) 71 { 72 return m_status; 73 } 74 75 //------------------------------------------------------------------------- 76 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 120 // Keyboard device event messages. 121 case B_KEY_DOWN: s = "B_KEY_DOWN"; break; 122 case B_UNMAPPED_KEY_DOWN: s = "B_UNMAPPED_KEY_DOWN"; break; 123 case B_KEY_UP: s = "B_KEY_UP"; break; 124 case B_UNMAPPED_KEY_UP: s = "B_UNMAPPED_KEY_UP"; break; 125 case B_MODIFIERS_CHANGED: s = "B_MODIFIERS_CHANGED"; break; 126 127 default: s = "UNKNOWN_MESSAGE"; break; 128 } 129 return s; 130 } 131 132 //------------------------------------------------------------------------- 133 //------------------------------------------------------------------------- 134 void MsgSpy::OutputMsgField(const char* fieldName, 135 const uint32 rawType, 136 int rawCount, 137 const void* rawData) 138 { 139 char msg_buffer [1024]; 140 char value_buffer [256]; 141 BString field_data; 142 const char* field_type; 143 const int field_count = rawCount; 144 const char* separator; 145 146 switch (rawType) 147 { 148 case B_CHAR_TYPE: 149 { 150 field_type = "B_CHAR_TYPE"; 151 field_data << "{ "; 152 for (const char* data_ptr = (const char*)rawData; 153 rawCount > 0; 154 rawCount--, data_ptr++) 155 { 156 separator = (1 < rawCount) ? ", " : " }"; 157 field_data << *data_ptr << separator; 158 } 159 break; 160 } 161 162 case B_INT8_TYPE: 163 { 164 field_type = "B_INT8_TYPE"; 165 field_data << "{ "; 166 for (const int8* data_ptr = (const int8*)rawData; 167 rawCount > 0; 168 rawCount--, data_ptr++) 169 { 170 separator = (1 < rawCount) ? ", " : " }"; 171 field_data << *data_ptr << separator; 172 } 173 break; 174 } 175 176 case B_INT16_TYPE: 177 { 178 field_type = "B_INT16_TYPE"; 179 field_data << "{ "; 180 for (const int16* data_ptr = (const int16*)rawData; 181 rawCount > 0; 182 rawCount--, data_ptr++) 183 { 184 separator = (1 < rawCount) ? ", " : " }"; 185 field_data << *data_ptr << separator; 186 } 187 break; 188 } 189 190 case B_INT32_TYPE: 191 { 192 field_type = "B_INT32_TYPE"; 193 field_data << "{ "; 194 for (const int32* data_ptr = (const int32*)rawData; 195 rawCount > 0; 196 rawCount--, data_ptr++) 197 { 198 separator = (1 < rawCount) ? ", " : " }"; 199 field_data << *data_ptr << separator; 200 } 201 break; 202 } 203 204 case B_INT64_TYPE: 205 { 206 field_type = "B_INT64_TYPE"; 207 field_data << "{ "; 208 for (const int64* data_ptr = (const int64*)rawData; 209 rawCount > 0; 210 rawCount--, data_ptr++) 211 { 212 separator = (1 < rawCount) ? ", " : " }"; 213 field_data << *data_ptr << separator; 214 } 215 break; 216 } 217 218 case B_UINT8_TYPE: 219 { 220 field_type = "B_UINT8_TYPE"; 221 field_data << "{ "; 222 for (const uint8* data_ptr = (const uint8*)rawData; 223 rawCount > 0; 224 rawCount--, data_ptr++) 225 { 226 separator = (1 < rawCount) ? ", " : " }"; 227 field_data << (uint32)(*data_ptr) << separator; 228 } 229 break; 230 } 231 232 case B_UINT16_TYPE: 233 { 234 field_type = "B_UINT16_TYPE"; 235 field_data << "{ "; 236 for (const uint16* data_ptr = (const uint16*)rawData; 237 rawCount > 0; 238 rawCount--, data_ptr++) 239 { 240 separator = (1 < rawCount) ? ", " : " }"; 241 field_data << (uint32)(*data_ptr) << separator; 242 } 243 break; 244 } 245 246 case B_UINT32_TYPE: 247 { 248 field_type = "B_UINT32_TYPE"; 249 field_data << "{ "; 250 for (const uint32* data_ptr = (const uint32*)rawData; 251 rawCount > 0; 252 rawCount--, data_ptr++) 253 { 254 separator = (1 < rawCount) ? ", " : " }"; 255 field_data << *data_ptr << separator; 256 } 257 break; 258 } 259 260 case B_UINT64_TYPE: 261 { 262 field_type = "B_UINT64_TYPE"; 263 field_data << "{ "; 264 for (const uint64* data_ptr = (const uint64*)rawData; 265 rawCount > 0; 266 rawCount--, data_ptr++) 267 { 268 separator = (1 < rawCount) ? ", " : " }"; 269 field_data << *data_ptr << separator; 270 } 271 break; 272 } 273 274 case B_FLOAT_TYPE: 275 { 276 field_type = "B_FLOAT_TYPE"; 277 field_data << "{ "; 278 for (const float* data_ptr = (const float*)rawData; 279 rawCount > 0; 280 rawCount--, data_ptr++) 281 { 282 separator = (1 < rawCount) ? ", " : " }"; 283 field_data << *data_ptr << separator; 284 } 285 break; 286 } 287 288 case B_DOUBLE_TYPE: 289 { 290 field_type = "B_DOUBLE_TYPE"; 291 field_data << "{ "; 292 for (const double* data_ptr = (const double*)rawData; 293 rawCount > 0; 294 rawCount--, data_ptr++) 295 { 296 separator = (1 < rawCount) ? ", " : " }"; 297 sprintf(value_buffer, "%f", *data_ptr); 298 field_data << value_buffer << separator; 299 } 300 break; 301 } 302 303 case B_BOOL_TYPE: 304 { 305 field_type = "B_BOOL_TYPE"; 306 field_data << "{ "; 307 for (const bool* data_ptr = (const bool*)rawData; 308 rawCount > 0; 309 rawCount--, data_ptr++) 310 { 311 separator = (1 < rawCount) ? ", " : " }"; 312 sprintf(value_buffer, "%s", (true == *data_ptr) ? "true" : "false"); 313 field_data << value_buffer << separator; 314 } 315 break; 316 } 317 318 case B_OFF_T_TYPE: 319 { 320 field_type = "B_OFF_T_TYPE"; 321 field_data << "{ "; 322 for (const off_t* data_ptr = (const off_t*)rawData; 323 rawCount > 0; 324 rawCount--, data_ptr++) 325 { 326 separator = (1 < rawCount) ? ", " : " }"; 327 field_data << *data_ptr << separator; 328 } 329 break; 330 } 331 332 case B_SIZE_T_TYPE: 333 { 334 field_type = "B_SIZE_T_TYPE"; 335 field_data << "{ "; 336 for (const size_t* data_ptr = (const size_t*)rawData; 337 rawCount > 0; 338 rawCount--, data_ptr++) 339 { 340 separator = (1 < rawCount) ? ", " : " }"; 341 field_data << *data_ptr << separator; 342 } 343 break; 344 } 345 346 case B_SSIZE_T_TYPE: 347 { 348 field_type = "B_SSIZE_T_TYPE"; 349 field_data << "{ "; 350 for (const ssize_t* data_ptr = (const ssize_t*)rawData; 351 rawCount > 0; 352 rawCount--, data_ptr++) 353 { 354 separator = (1 < rawCount) ? ", " : " }"; 355 field_data << *data_ptr << separator; 356 } 357 break; 358 } 359 360 case B_POINTER_TYPE: 361 { 362 field_type = "B_POINTER_TYPE"; 363 break; 364 } 365 366 case B_OBJECT_TYPE: 367 { 368 field_type = "B_OBJECT_TYPE"; 369 break; 370 } 371 372 case B_MESSAGE_TYPE: 373 { 374 field_type = "B_MESSAGE_TYPE"; 375 break; 376 } 377 378 case B_MESSENGER_TYPE: 379 { 380 field_type = "B_MESSENGER_TYPE"; 381 break; 382 } 383 384 case B_POINT_TYPE: 385 { 386 field_type = "B_POINT_TYPE"; 387 field_data << "{ "; 388 for (const BPoint* data_ptr = (const BPoint*)rawData; 389 rawCount > 0; 390 rawCount--, data_ptr++) 391 { 392 separator = (1 < rawCount) ? ", " : " }"; 393 field_data << "(" << data_ptr->x << ", " << data_ptr->y << ")" << separator; 394 } 395 break; 396 } 397 398 case B_RECT_TYPE: 399 { 400 field_type = "B_RECT_TYPE"; 401 break; 402 } 403 404 // case B_PATH_TYPE: s = "B_PATH_TYPE"; break; 405 406 case B_REF_TYPE: 407 { 408 field_type = "B_REF_TYPE"; 409 break; 410 } 411 412 case B_RGB_COLOR_TYPE: 413 { 414 field_type = "B_RGB_COLOR_TYPE"; 415 break; 416 } 417 418 case B_PATTERN_TYPE: 419 { 420 field_type = "B_PATTERN_TYPE"; 421 break; 422 } 423 424 case B_STRING_TYPE: 425 { 426 field_type = "B_STRING_TYPE"; 427 field_data << "{ "; 428 for (const char* data_ptr = (const char*)rawData; 429 rawCount > 0; 430 rawCount--, data_ptr+= strlen(data_ptr) ) 431 { 432 separator = (1 < rawCount) ? ", " : " }"; 433 field_data << "\"" << data_ptr << "\"" << separator; 434 } 435 break; 436 } 437 438 case B_MONOCHROME_1_BIT_TYPE: 439 { 440 field_type = "B_MONOCHROME_1_BIT_TYPE"; 441 break; 442 } 443 444 case B_GRAYSCALE_8_BIT_TYPE: 445 { 446 field_type = "B_GRAYSCALE_8_BIT_TYPE"; 447 break; 448 } 449 450 case B_COLOR_8_BIT_TYPE: 451 { 452 field_type = "B_COLOR_8_BIT_TYPE"; 453 break; 454 } 455 456 case B_RGB_32_BIT_TYPE: 457 { 458 field_type = "B_RGB_32_BIT_TYPE"; 459 break; 460 } 461 462 case B_TIME_TYPE: 463 { 464 field_type = "B_TIME_TYPE"; 465 break; 466 } 467 468 case B_MEDIA_PARAMETER_TYPE: 469 { 470 field_type = "B_MEDIA_PARAMETER_TYPE"; 471 break; 472 } 473 474 case B_MEDIA_PARAMETER_WEB_TYPE: 475 { 476 field_type = "B_MEDIA_PARAMETER_WEB_TYPE"; 477 break; 478 } 479 480 case B_MEDIA_PARAMETER_GROUP_TYPE: 481 { 482 field_type = "B_MEDIA_PARAMETER_GROUP_TYPE"; 483 break; 484 } 485 486 case B_RAW_TYPE: 487 { 488 field_type = "B_RAW_TYPE"; 489 break; 490 } 491 492 case B_MIME_TYPE: 493 { 494 field_type = "B_MIME_TYPE"; 495 break; 496 } 497 498 case B_ANY_TYPE: 499 { 500 field_type = "B_ANY_TYPE"; 501 break; 502 } 503 504 default: 505 { 506 field_type = "UNKNOWN_TYPE"; 507 break; 508 } 509 } 510 511 sprintf(msg_buffer, 512 " %-18s %-18s [%2d] = %s\n", 513 field_type, 514 fieldName, 515 field_count, 516 field_data.String() ); 517 518 m_outfile->Write(msg_buffer, strlen(msg_buffer) ); 519 } 520