1 /* 2 * Copyright 2001-2009, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold, bonefish@@users.sf.net 7 */ 8 9 10 #include <AppMisc.h> 11 12 #include <stdlib.h> 13 #include <string.h> 14 #include <sys/utsname.h> 15 16 #include <Entry.h> 17 #include <image.h> 18 #include <OS.h> 19 20 #include <ServerLink.h> 21 #include <ServerProtocol.h> 22 23 24 namespace BPrivate { 25 26 27 /*! \brief Returns the path to an application's executable. 28 \param team The application's team ID. 29 \param buffer A pointer to a pre-allocated character array of at least 30 size B_PATH_NAME_LENGTH to be filled in by this function. 31 \return 32 - \c B_OK: Everything went fine. 33 - \c B_BAD_VALUE: \c NULL \a buffer. 34 - another error code 35 */ 36 status_t 37 get_app_path(team_id team, char *buffer) 38 { 39 // The only way to get the path to the application's executable seems to 40 // be to get an image_info of its image, which also contains a path. 41 // Several images may belong to the team (libraries, add-ons), but only 42 // the one in question should be typed B_APP_IMAGE. 43 if (!buffer) 44 return B_BAD_VALUE; 45 46 image_info info; 47 int32 cookie = 0; 48 49 while (get_next_image_info(team, &cookie, &info) == B_OK) { 50 if (info.type == B_APP_IMAGE) { 51 strlcpy(buffer, info.name, B_PATH_NAME_LENGTH - 1); 52 return B_OK; 53 } 54 } 55 56 return B_ENTRY_NOT_FOUND; 57 } 58 59 60 /*! \brief Returns the path to the application's executable. 61 \param buffer A pointer to a pre-allocated character array of at least 62 size B_PATH_NAME_LENGTH to be filled in by this function. 63 \return 64 - \c B_OK: Everything went fine. 65 - \c B_BAD_VALUE: \c NULL \a buffer. 66 - another error code 67 */ 68 status_t 69 get_app_path(char *buffer) 70 { 71 return get_app_path(B_CURRENT_TEAM, buffer); 72 } 73 74 75 /*! \brief Returns an entry_ref referring to an application's executable. 76 \param team The application's team ID. 77 \param ref A pointer to a pre-allocated entry_ref to be initialized 78 to an entry_ref referring to the application's executable. 79 \param traverse If \c true, the function traverses symbolic links. 80 \return 81 - \c B_OK: Everything went fine. 82 - \c B_BAD_VALUE: \c NULL \a ref. 83 - another error code 84 */ 85 status_t 86 get_app_ref(team_id team, entry_ref *ref, bool traverse) 87 { 88 status_t error = (ref ? B_OK : B_BAD_VALUE); 89 char appFilePath[B_PATH_NAME_LENGTH]; 90 91 if (error == B_OK) 92 error = get_app_path(team, appFilePath); 93 94 if (error == B_OK) { 95 BEntry entry(appFilePath, traverse); 96 error = entry.GetRef(ref); 97 } 98 99 return error; 100 } 101 102 103 /*! \brief Returns an entry_ref referring to the application's executable. 104 \param ref A pointer to a pre-allocated entry_ref to be initialized 105 to an entry_ref referring to the application's executable. 106 \param traverse If \c true, the function traverses symbolic links. 107 \return 108 - \c B_OK: Everything went fine. 109 - \c B_BAD_VALUE: \c NULL \a ref. 110 - another error code 111 */ 112 status_t 113 get_app_ref(entry_ref *ref, bool traverse) 114 { 115 return get_app_ref(B_CURRENT_TEAM, ref, traverse); 116 } 117 118 119 /*! \brief Returns the ID of the current team. 120 \return The ID of the current team. 121 */ 122 team_id 123 current_team() 124 { 125 static team_id team = -1; 126 if (team < 0) { 127 thread_info info; 128 if (get_thread_info(find_thread(NULL), &info) == B_OK) 129 team = info.team; 130 } 131 return team; 132 } 133 134 135 /*! Returns the ID of the supplied team's main thread. 136 \param team The team. 137 \return 138 - The thread ID of the supplied team's main thread 139 - \c B_BAD_TEAM_ID: The supplied team ID does not identify a running team. 140 - another error code 141 */ 142 thread_id 143 main_thread_for(team_id team) 144 { 145 // Under Haiku the team ID is equal to it's main thread ID. We just get 146 // a team info to verify the existence of the team. 147 team_info info; 148 status_t error = get_team_info(team, &info); 149 return (error == B_OK ? team : error); 150 } 151 152 153 /*! \brief Returns whether the application identified by the supplied 154 \c team_id is currently showing a modal window. 155 \param team the ID of the application in question. 156 \return \c true, if the application is showing a modal window, \c false 157 otherwise. 158 */ 159 bool 160 is_app_showing_modal_window(team_id team) 161 { 162 // TODO: Implement! 163 return true; 164 } 165 166 167 port_id 168 get_app_server_port() 169 { 170 static port_id sServerPort = -1; 171 172 if (sServerPort < 0) { 173 // No need for synchronization - in the worst case, we'll call 174 // find_port() twice. 175 sServerPort = find_port(SERVER_PORT_NAME); 176 } 177 178 return sServerPort; 179 } 180 181 182 /*! Creates a connection with the desktop. 183 */ 184 status_t 185 create_desktop_connection(ServerLink* link, const char* name, int32 capacity) 186 { 187 port_id serverPort = get_app_server_port(); 188 if (serverPort < 0) 189 return serverPort; 190 191 // Create the port so that the app_server knows where to send messages 192 port_id clientPort = create_port(capacity, name); 193 if (clientPort < 0) 194 return clientPort; 195 196 link->SetTo(serverPort, clientPort); 197 198 link->StartMessage(AS_GET_DESKTOP); 199 link->Attach<port_id>(clientPort); 200 link->Attach<int32>(getuid()); 201 link->AttachString(getenv("TARGET_SCREEN")); 202 link->Attach<int32>(AS_PROTOCOL_VERSION); 203 204 int32 code; 205 if (link->FlushWithReply(code) != B_OK || code != B_OK) { 206 link->SetSenderPort(-1); 207 return B_ERROR; 208 } 209 210 link->Read<port_id>(&serverPort); 211 link->SetSenderPort(serverPort); 212 213 return B_OK; 214 } 215 216 217 } // namespace BPrivate 218