1// RosterWatchingTestApp1.cpp 2 3#include <stdio.h> 4#include <string.h> 5 6#include <Application.h> 7#include <Entry.h> 8#include <File.h> 9#include <Message.h> 10#include <Messenger.h> 11#include <OS.h> 12#include <Resources.h> 13#include <Roster.h> 14#include <String.h> 15 16#include "RosterTestAppDefs.h" 17 18BMessenger unitTesterMessenger; 19 20static const char *kUnitTesterSignature 21 = "application/x-vnd.obos-roster-watching-test"; 22 23// init_unit_tester_messenger 24static 25status_t 26init_unit_tester_messenger() 27{ 28 // Unfortunately BeOS R5 doesn't update the roster-side information about 29 // the app looper's port ID once a BApplication has been created, and 30 // thus we can't construct a BMessenger targeting a BApplication created 31 // after the first one using the signature/team ID constructor. 32 // We need to do some hacking. 33 struct fake_messenger { 34 port_id fPort; 35 int32 fHandlerToken; 36 team_id fTeam; 37 int32 extra0; 38 int32 extra1; 39 bool fPreferredTarget; 40 bool extra2; 41 bool extra3; 42 bool extra4; 43 } &fake = *(fake_messenger*)&unitTesterMessenger; 44 // get team 45 status_t error = B_OK; 46 fake.fTeam = BRoster().TeamFor(kUnitTesterSignature); 47 if (fake.fTeam < 0) 48 error = fake.fTeam; 49 // find app looper port 50 bool found = false; 51 int32 cookie = 0; 52 port_info info; 53 while (error == B_OK && !found) { 54 error = get_next_port_info(fake.fTeam, &cookie, &info); 55 found = (error == B_OK && !strcmp("AppLooperPort", info.name)); 56 } 57 // init messenger 58 if (error == B_OK) { 59 fake.fPort = info.port; 60 fake.fHandlerToken = 0; 61 fake.fPreferredTarget = true; 62 } 63 return error; 64} 65 66// get_app_path 67status_t 68get_app_path(char *buffer) 69{ 70 status_t error = (buffer ? B_OK : B_BAD_VALUE); 71 image_info info; 72 int32 cookie = 0; 73 bool found = false; 74 if (error == B_OK) { 75 while (!found && get_next_image_info(0, &cookie, &info) == B_OK) { 76 if (info.type == B_APP_IMAGE) { 77 strncpy(buffer, info.name, B_PATH_NAME_LENGTH); 78 buffer[B_PATH_NAME_LENGTH] = 0; 79 found = true; 80 } 81 } 82 } 83 if (error == B_OK && !found) 84 error = B_ENTRY_NOT_FOUND; 85 return error; 86} 87 88// TestApp 89class TestApp : public BApplication { 90public: 91 TestApp(const char *signature) : BApplication(signature) 92 { 93 } 94 95 virtual void ArgvReceived(int32 argc, char **argv) 96 { 97 BMessage message(MSG_ARGV_RECEIVED); 98 message.AddInt32("argc", argc); 99 for (int32 i = 0; i < argc; i++) 100 message.AddString("argv", argv[i]); 101 unitTesterMessenger.SendMessage(&message); 102 } 103 104 virtual void RefsReceived(BMessage *_message) 105 { 106 BMessage message(*_message); 107 message.what = MSG_REFS_RECEIVED; 108 unitTesterMessenger.SendMessage(&message); 109 } 110 111 virtual void MessageReceived(BMessage *_message) 112 { 113 BMessage message(MSG_MESSAGE_RECEIVED); 114 message.AddMessage("message", _message); 115 message.AddInt32("sender", _message->ReturnAddress().Team()); 116 switch (_message->what) { 117 case B_SOME_APP_LAUNCHED: 118 case B_SOME_APP_QUIT: 119 case B_SOME_APP_ACTIVATED: 120 message.AddBool("don't ignore", true); 121 break; 122 } 123 unitTesterMessenger.SendMessage(&message); 124 } 125 126 virtual bool QuitRequested() 127 { 128 unitTesterMessenger.SendMessage(MSG_QUIT_REQUESTED); 129 return true; 130 } 131 132 virtual void ReadyToRun() 133 { 134 unitTesterMessenger.SendMessage(MSG_READY_TO_RUN); 135 } 136}; 137 138// main 139int 140main(int argc, char **argv) 141{ 142 // find app file and get signature from resources 143 char path[B_PATH_NAME_LENGTH]; 144 status_t error = get_app_path(path); 145 char signature[B_MIME_TYPE_LENGTH]; 146 if (error == B_OK) { 147 // init app file 148 BFile file; 149 error = file.SetTo(path, B_READ_ONLY); 150 // get signature 151 BString signatureString; 152 if (error == B_OK) { 153 if (file.ReadAttrString("signature", &signatureString) == B_OK 154 && signatureString.Length() > 0) { 155 strcpy(signature, signatureString.String()); 156 } else 157 strcpy(signature, kDefaultTestAppSignature); 158 } else 159 printf("ERROR: Couldn't init app file: %s\n", strerror(error)); 160 } else 161 printf("ERROR: Couldn't get app ref: %s\n", strerror(error)); 162 // create the app 163 TestApp *app = NULL; 164 if (error == B_OK) { 165 app = new TestApp(signature); 166// unitTesterMessenger = BMessenger(kUnitTesterSignature); 167 error = init_unit_tester_messenger(); 168 if (error != B_OK) 169 printf("ERROR: Couldn't init messenger: %s\n", strerror(error)); 170 // send started message 171 BMessage message(MSG_STARTED); 172 message.AddString("path", path); 173 unitTesterMessenger.SendMessage(&message); 174 // send main() args message 175 BMessage argsMessage(MSG_MAIN_ARGS); 176 argsMessage.AddInt32("argc", argc); 177 for (int i = 0; i < argc; i++) 178 argsMessage.AddString("argv", argv[i]); 179 unitTesterMessenger.SendMessage(&argsMessage); 180 // run the app 181 app->Run(); 182 delete app; 183 // send terminated message 184 unitTesterMessenger.SendMessage(MSG_TERMINATED); 185 } 186 return 0; 187} 188 189