1 /* 2 * Copyright 2001-2007, 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 #include <Entry.h> 12 #include <image.h> 13 #include <OS.h> 14 15 #include <string.h> 16 #include <sys/utsname.h> 17 18 19 namespace BPrivate { 20 21 // get_app_path 22 /*! \brief Returns the path to an application's executable. 23 \param team The application's team ID. 24 \param buffer A pointer to a pre-allocated character array of at least 25 size B_PATH_NAME_LENGTH to be filled in by this function. 26 \return 27 - \c B_OK: Everything went fine. 28 - \c B_BAD_VALUE: \c NULL \a buffer. 29 - another error code 30 */ 31 status_t 32 get_app_path(team_id team, char *buffer) 33 { 34 // The only way to get the path to the application's executable seems to 35 // be to get an image_info of its image, which also contains a path. 36 // Several images may belong to the team (libraries, add-ons), but only 37 // the one in question should be typed B_APP_IMAGE. 38 if (!buffer) 39 return B_BAD_VALUE; 40 41 image_info info; 42 int32 cookie = 0; 43 44 while (get_next_image_info(team, &cookie, &info) == B_OK) { 45 if (info.type == B_APP_IMAGE) { 46 strlcpy(buffer, info.name, B_PATH_NAME_LENGTH - 1); 47 return B_OK; 48 } 49 } 50 51 return B_ENTRY_NOT_FOUND; 52 } 53 54 // get_app_path 55 /*! \brief Returns the path to the application's executable. 56 \param buffer A pointer to a pre-allocated character array of at least 57 size B_PATH_NAME_LENGTH to be filled in by this function. 58 \return 59 - \c B_OK: Everything went fine. 60 - \c B_BAD_VALUE: \c NULL \a buffer. 61 - another error code 62 */ 63 status_t 64 get_app_path(char *buffer) 65 { 66 return get_app_path(B_CURRENT_TEAM, buffer); 67 } 68 69 // get_app_ref 70 /*! \brief Returns an entry_ref referring to an application's executable. 71 \param team The application's team ID. 72 \param ref A pointer to a pre-allocated entry_ref to be initialized 73 to an entry_ref referring to the application's executable. 74 \param traverse If \c true, the function traverses symbolic links. 75 \return 76 - \c B_OK: Everything went fine. 77 - \c B_BAD_VALUE: \c NULL \a ref. 78 - another error code 79 */ 80 status_t 81 get_app_ref(team_id team, entry_ref *ref, bool traverse) 82 { 83 status_t error = (ref ? B_OK : B_BAD_VALUE); 84 char appFilePath[B_PATH_NAME_LENGTH]; 85 86 if (error == B_OK) 87 error = get_app_path(team, appFilePath); 88 89 if (error == B_OK) { 90 BEntry entry(appFilePath, traverse); 91 error = entry.GetRef(ref); 92 } 93 94 return error; 95 } 96 97 // get_app_ref 98 /*! \brief Returns an entry_ref referring to the application's executable. 99 \param ref A pointer to a pre-allocated entry_ref to be initialized 100 to an entry_ref referring to the application's executable. 101 \param traverse If \c true, the function traverses symbolic links. 102 \return 103 - \c B_OK: Everything went fine. 104 - \c B_BAD_VALUE: \c NULL \a ref. 105 - another error code 106 */ 107 status_t 108 get_app_ref(entry_ref *ref, bool traverse) 109 { 110 return get_app_ref(B_CURRENT_TEAM, ref, traverse); 111 } 112 113 // current_team 114 /*! \brief Returns the ID of the current team. 115 \return The ID of the current team. 116 */ 117 team_id 118 current_team() 119 { 120 static team_id team = -1; 121 if (team < 0) { 122 thread_info info; 123 if (get_thread_info(find_thread(NULL), &info) == B_OK) 124 team = info.team; 125 } 126 return team; 127 } 128 129 // main_thread_for 130 /*! Returns the ID of the supplied team's main thread. 131 \param team The team. 132 \return 133 - The thread ID of the supplied team's main thread 134 - \c B_BAD_TEAM_ID: The supplied team ID does not identify a running team. 135 - another error code 136 */ 137 thread_id 138 main_thread_for(team_id team) 139 { 140 #ifdef __HAIKU__ 141 // Under Haiku the team ID is equal to it's main thread ID. We just get 142 // a team info to verify the existence of the team. 143 team_info info; 144 status_t error = get_team_info(team, &info); 145 return (error == B_OK ? team : error); 146 #else 147 // For I can't find any trace of how to explicitly get the main thread, 148 // I assume the main thread is the one with the least thread ID. 149 thread_id thread = B_BAD_TEAM_ID; 150 int32 cookie = 0; 151 thread_info info; 152 while (get_next_thread_info(team, &cookie, &info) == B_OK) { 153 if (thread < 0 || info.thread < thread) 154 thread = info.thread; 155 } 156 return thread; 157 #endif 158 } 159 160 // is_running_on_haiku 161 /*! Returns whether we're running under Haiku natively. 162 163 This is a runtime check for components compiled only once for both 164 BeOS and Haiku and nevertheless need to behave differently on the two 165 systems, like the registrar, which uses another MIME database directory 166 under BeOS. 167 168 \return \c true, if we're running under Haiku, \c false otherwise. 169 */ 170 bool 171 is_running_on_haiku() 172 { 173 struct utsname info; 174 return (uname(&info) == 0 && strcmp(info.sysname, "Haiku") == 0); 175 } 176 177 // is_app_showing_modal_window 178 /*! \brief Returns whether the application identified by the supplied 179 \c team_id is currently showing a modal window. 180 \param team the ID of the application in question. 181 \return \c true, if the application is showing a modal window, \c false 182 otherwise. 183 */ 184 bool 185 is_app_showing_modal_window(team_id team) 186 { 187 // TODO: Implement! 188 return true; 189 } 190 191 } // namespace BPrivate 192 193