//------------------------------------------------------------------------- // Handy InputFilter that dumps all Messages to a file. //------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include extern "C" _EXPORT BInputServerFilter* instantiate_input_filter(); class MsgSpy : public BInputServerFilter { public: MsgSpy(); virtual ~MsgSpy(); virtual status_t InitCheck(void); virtual filter_result Filter(BMessage *message, BList *outList); private: const char* MapWhatToString(uint32 w); void OutputMsgField(const char* fieldName, const uint32 rawType, int rawCount, const void* rawData); status_t m_status; BFile* m_outfile; }; //------------------------------------------------------------------------- // Create a new MsgSpy instance and return it to the caller. //------------------------------------------------------------------------- BInputServerFilter* instantiate_input_filter() { return (new MsgSpy() ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- MsgSpy::MsgSpy() { // Create the output file and return its status. m_outfile = new BFile("/boot/home/MsgSpy.output", B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); //m_status = m_outfile->InitCheck(); m_status = B_OK; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- MsgSpy::~MsgSpy() { if (NULL != m_outfile) { // Close and destroy the output file. delete m_outfile; } } //------------------------------------------------------------------------- //------------------------------------------------------------------------- status_t MsgSpy::InitCheck(void) { return m_status; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- filter_result MsgSpy::Filter(BMessage *message, BList *outList) { char* field_name; uint32 field_type; int32 field_count; const void* field_data; ssize_t field_data_bytes; char msg_buffer [1024]; // Print out the message constant (what). sprintf(msg_buffer, "%s\n", MapWhatToString(message->what) ); m_outfile->Write(msg_buffer, strlen(msg_buffer) ); // Display each field in the message. sprintf(msg_buffer, "{\n"); m_outfile->Write(msg_buffer, strlen(msg_buffer) ); for (int32 i = 0; B_OK == message->GetInfo(B_ANY_TYPE, i, &field_name, &field_type, &field_count); i++) { message->FindData(field_name, field_type, &field_data, &field_data_bytes); OutputMsgField(field_name, field_type, field_count, field_data); } sprintf(msg_buffer, "}\n"); m_outfile->Write(msg_buffer, strlen(msg_buffer) ); return (B_DISPATCH_MESSAGE); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- const char* MsgSpy::MapWhatToString(uint32 w) { const char* s; switch (w) { // Pointing device event messages. case B_MOUSE_DOWN: s = "B_MOUSE_DOWN"; break; case B_MOUSE_UP: s = "B_MOUSE_UP"; break; case B_MOUSE_MOVED: s = "B_MOUSE_MOVED"; break; // Keyboard device event messages. case B_KEY_DOWN: s = "B_KEY_DOWN"; break; case B_UNMAPPED_KEY_DOWN: s = "B_UNMAPPED_KEY_DOWN"; break; case B_KEY_UP: s = "B_KEY_UP"; break; case B_UNMAPPED_KEY_UP: s = "B_UNMAPPED_KEY_UP"; break; case B_MODIFIERS_CHANGED: s = "B_MODIFIERS_CHANGED"; break; default: s = "UNKNOWN_MESSAGE"; break; } return s; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- void MsgSpy::OutputMsgField(const char* fieldName, const uint32 rawType, int rawCount, const void* rawData) { char msg_buffer [1024]; char value_buffer [256]; BString field_data; const char* field_type; const int field_count = rawCount; const char* separator; switch (rawType) { case B_CHAR_TYPE: { field_type = "B_CHAR_TYPE"; field_data << "{ "; for (const char* data_ptr = (const char*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_INT8_TYPE: { field_type = "B_INT8_TYPE"; field_data << "{ "; for (const int8* data_ptr = (const int8*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_INT16_TYPE: { field_type = "B_INT16_TYPE"; field_data << "{ "; for (const int16* data_ptr = (const int16*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_INT32_TYPE: { field_type = "B_INT32_TYPE"; field_data << "{ "; for (const int32* data_ptr = (const int32*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_INT64_TYPE: { field_type = "B_INT64_TYPE"; field_data << "{ "; for (const int64* data_ptr = (const int64*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_UINT8_TYPE: { field_type = "B_UINT8_TYPE"; field_data << "{ "; for (const uint8* data_ptr = (const uint8*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << (uint32)(*data_ptr) << separator; } break; } case B_UINT16_TYPE: { field_type = "B_UINT16_TYPE"; field_data << "{ "; for (const uint16* data_ptr = (const uint16*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << (uint32)(*data_ptr) << separator; } break; } case B_UINT32_TYPE: { field_type = "B_UINT32_TYPE"; field_data << "{ "; for (const uint32* data_ptr = (const uint32*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_UINT64_TYPE: { field_type = "B_UINT64_TYPE"; field_data << "{ "; for (const uint64* data_ptr = (const uint64*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_FLOAT_TYPE: { field_type = "B_FLOAT_TYPE"; field_data << "{ "; for (const float* data_ptr = (const float*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_DOUBLE_TYPE: { field_type = "B_DOUBLE_TYPE"; field_data << "{ "; for (const double* data_ptr = (const double*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; sprintf(value_buffer, "%f", *data_ptr); field_data << value_buffer << separator; } break; } case B_BOOL_TYPE: { field_type = "B_BOOL_TYPE"; field_data << "{ "; for (const bool* data_ptr = (const bool*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; sprintf(value_buffer, "%s", (true == *data_ptr) ? "true" : "false"); field_data << value_buffer << separator; } break; } case B_OFF_T_TYPE: { field_type = "B_OFF_T_TYPE"; field_data << "{ "; for (const off_t* data_ptr = (const off_t*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_SIZE_T_TYPE: { field_type = "B_SIZE_T_TYPE"; field_data << "{ "; for (const size_t* data_ptr = (const size_t*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_SSIZE_T_TYPE: { field_type = "B_SSIZE_T_TYPE"; field_data << "{ "; for (const ssize_t* data_ptr = (const ssize_t*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << *data_ptr << separator; } break; } case B_POINTER_TYPE: { field_type = "B_POINTER_TYPE"; break; } case B_OBJECT_TYPE: { field_type = "B_OBJECT_TYPE"; break; } case B_MESSAGE_TYPE: { field_type = "B_MESSAGE_TYPE"; break; } case B_MESSENGER_TYPE: { field_type = "B_MESSENGER_TYPE"; break; } case B_POINT_TYPE: { field_type = "B_POINT_TYPE"; field_data << "{ "; for (const BPoint* data_ptr = (const BPoint*)rawData; rawCount > 0; rawCount--, data_ptr++) { separator = (1 < rawCount) ? ", " : " }"; field_data << "(" << data_ptr->x << ", " << data_ptr->y << ")" << separator; } break; } case B_RECT_TYPE: { field_type = "B_RECT_TYPE"; break; } // case B_PATH_TYPE: s = "B_PATH_TYPE"; break; case B_REF_TYPE: { field_type = "B_REF_TYPE"; break; } case B_RGB_COLOR_TYPE: { field_type = "B_RGB_COLOR_TYPE"; break; } case B_PATTERN_TYPE: { field_type = "B_PATTERN_TYPE"; break; } case B_STRING_TYPE: { field_type = "B_STRING_TYPE"; field_data << "{ "; for (const char* data_ptr = (const char*)rawData; rawCount > 0; rawCount--, data_ptr+= strlen(data_ptr) ) { separator = (1 < rawCount) ? ", " : " }"; field_data << "\"" << data_ptr << "\"" << separator; } break; } case B_MONOCHROME_1_BIT_TYPE: { field_type = "B_MONOCHROME_1_BIT_TYPE"; break; } case B_GRAYSCALE_8_BIT_TYPE: { field_type = "B_GRAYSCALE_8_BIT_TYPE"; break; } case B_COLOR_8_BIT_TYPE: { field_type = "B_COLOR_8_BIT_TYPE"; break; } case B_RGB_32_BIT_TYPE: { field_type = "B_RGB_32_BIT_TYPE"; break; } case B_TIME_TYPE: { field_type = "B_TIME_TYPE"; break; } case B_MEDIA_PARAMETER_TYPE: { field_type = "B_MEDIA_PARAMETER_TYPE"; break; } case B_MEDIA_PARAMETER_WEB_TYPE: { field_type = "B_MEDIA_PARAMETER_WEB_TYPE"; break; } case B_MEDIA_PARAMETER_GROUP_TYPE: { field_type = "B_MEDIA_PARAMETER_GROUP_TYPE"; break; } case B_RAW_TYPE: { field_type = "B_RAW_TYPE"; break; } case B_MIME_TYPE: { field_type = "B_MIME_TYPE"; break; } case B_ANY_TYPE: { field_type = "B_ANY_TYPE"; break; } default: { field_type = "UNKNOWN_TYPE"; break; } } sprintf(msg_buffer, " %-18s %-18s [%2d] = %s\n", field_type, fieldName, field_count, field_data.String() ); m_outfile->Write(msg_buffer, strlen(msg_buffer) ); }