diff --git a/src/tools/MsgSpy/MsgSpy.cpp b/src/tools/MsgSpy/MsgSpy.cpp new file mode 100644 index 0000000000..d508c98530 --- /dev/null +++ b/src/tools/MsgSpy/MsgSpy.cpp @@ -0,0 +1,519 @@ +//------------------------------------------------------------------------- +// 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) ); +} diff --git a/src/tools/MsgSpy/start b/src/tools/MsgSpy/start new file mode 100644 index 0000000000..df3081873f --- /dev/null +++ b/src/tools/MsgSpy/start @@ -0,0 +1,2 @@ +cp ./obj.x86/MsgSpy /boot/home/config/add-ons/input_server/filters +/boot/beos/system/servers/input_server -q diff --git a/src/tools/MsgSpy/stop b/src/tools/MsgSpy/stop new file mode 100644 index 0000000000..320e8d5e5a --- /dev/null +++ b/src/tools/MsgSpy/stop @@ -0,0 +1,2 @@ +rm -f /boot/home/config/add-ons/input_server/filters/MsgSpy +/boot/beos/system/servers/input_server -q