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 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 //------------------------------------------------------------------------- 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