#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <Application.h>
#include <Clipboard.h>
#include <Locker.h>
#include <Message.h>
#include <MessageRunner.h>
#include <OS.h>
#include <Path.h>
#include <Roster.h>
#include <String.h>
enum {
MSG_FILL_PORT = 'fill',
MSG_RUNNER = 'runn',
MSG_BROADCAST = 'brod',
};
static const uint32 sExpectedMessages[3] = {
B_CLIPBOARD_CHANGED,
MSG_RUNNER,
MSG_BROADCAST,
};
static const int32 sExpectedMessageCount = 3;
static int32 sExpectedMessageIndex = 0;
static
bool
check_expected_message(uint32 what)
{
if (sExpectedMessageIndex >= sExpectedMessageCount) {
printf("Unexpected message '%.4s'\n", (char*)&what);
exit(1);
}
uint32 expected = sExpectedMessages[sExpectedMessageIndex++];
if (what != expected) {
printf("Unexpected message '%.4s', expected was: '%.4s'\n",
(char*)&what, (char*)&expected);
exit(1);
}
return (sExpectedMessageIndex == sExpectedMessageCount);
}
class TestApp : public BApplication {
public:
TestApp()
: BApplication("application/x-vnd.haiku.message-deliverer-test")
{
}
virtual void MessageReceived(BMessage *message)
{
switch (message->what) {
case MSG_FILL_PORT:
return;
case MSG_RUNNER:
printf("MSG_RUNNER\n");
break;
case B_CLIPBOARD_CHANGED:
printf("B_CLIPBOARD_CHANGED\n");
break;
case MSG_BROADCAST:
printf("MSG_BROADCAST\n");
break;
default:
BApplication::MessageReceived(message);
return;
}
if (check_expected_message(message->what))
PostMessage(B_QUIT_REQUESTED);
}
};
int
main(int argc, const char *const *argv)
{
if (argc > 1 && strcmp(argv[1], "broadcast") == 0) {
BMessage message(MSG_BROADCAST);
status_t error = be_roster->Broadcast(&message);
if (error != B_OK) {
printf("Broadcast failed: %s\n", strerror(error));
exit(1);
}
exit(0);
}
TestApp app;
status_t error;
do {
BMessage message(MSG_FILL_PORT);
error = be_app_messenger.SendMessage(&message, (BHandler*)NULL, 0LL);
} while (error == B_OK);
if (error != B_WOULD_BLOCK) {
printf("sending fill message didn't fail with B_WOULD_BLOCK: %s\n",
strerror(error));
exit(1);
}
BClipboard clipboard("message deliverer test");
error = clipboard.StartWatching(be_app_messenger);
if (error != B_OK) {
printf("Failed to start clipboard watching: %s\n", strerror(error));
exit(1);
}
if (!clipboard.Lock()) {
printf("Failed to lock clipboard.\n");
exit(1);
}
clipboard.Clear();
clipboard.Data()->AddString("test", "test data");
error = clipboard.Commit();
if (error != B_OK) {
printf("Failed to commit clipboard data: %s\n", strerror(error));
exit(1);
}
clipboard.Unlock();
BMessage message(MSG_RUNNER);
bigtime_t interval = 100000LL;
BMessageRunner runner(be_app_messenger, &message, interval, 3);
error = runner.InitCheck();
if (error != B_OK) {
printf("Message runner initialization failed: %s\n", strerror(error));
exit(1);
}
snooze(5 * interval);
app_info appInfo;
error = app.GetAppInfo(&appInfo);
if (error != B_OK) {
printf("GetAppInfo() failed: %s\n", strerror(error));
exit(1);
}
BPath path;
error = path.SetTo(&appInfo.ref);
if (error != B_OK) {
printf("Failed to get app path: %s\n", strerror(error));
exit(1);
}
BString commandLine(path.Path());
commandLine << " broadcast";
if (system(commandLine.String()) < 0) {
printf("Failed re-launch app for broadcasting: %s\n", strerror(errno));
exit(1);
}
snooze(100000);
app.Run();
return 0;
}