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