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