xref: /haiku/src/kits/app/AppMisc.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
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