xref: /haiku/src/kits/media/MediaFiles.cpp (revision 03187b607b2b5eec7ee059f1ead09bdba14991fb)
1 /*
2  * Copyright 2002-2008, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Marcus Overhagen
7  *		Jérôme Duval
8  */
9 
10 
11 #include <MediaFiles.h>
12 #include "DataExchange.h"
13 #include "debug.h"
14 
15 
16 const char BMediaFiles::B_SOUNDS[] = "Sounds";
17 
18 
19 BMediaFiles::BMediaFiles()
20 	:
21 	fTypeIndex(-1),
22 	fCurrentType(""),
23 	fItemIndex(-1)
24 {
25 
26 }
27 
28 
29 BMediaFiles::~BMediaFiles()
30 {
31 	// TODO: Cleanup!
32 }
33 
34 
35 status_t
36 BMediaFiles::RewindTypes()
37 {
38 	CALLED();
39 	status_t rv;
40 	server_rewindtypes_request request;
41 	server_rewindtypes_reply reply;
42 
43 	for (int32 i = 0; i < fTypes.CountItems(); i++)
44 		delete (BString*)fTypes.ItemAt(i);
45 
46 	fTypes.MakeEmpty();
47 
48 	TRACE("BMediaFiles::RewindTypes: sending SERVER_REWINDTYPES\n");
49 
50 	rv = QueryServer(SERVER_REWINDTYPES, &request, sizeof(request), &reply,
51 		sizeof(reply));
52 	if (rv != B_OK) {
53 		ERROR("BMediaFiles::RewindTypes: failed to rewindtypes "
54 			"(error %#lx)\n", rv);
55 		return rv;
56 	}
57 
58 	char *types;
59 	area_id clone;
60 
61 	clone = clone_area("rewind types clone", reinterpret_cast<void **>(&types),
62 		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.area);
63 	if (clone < B_OK) {
64 		ERROR("BMediaFiles::RewindTypes failed to clone area, %#lx\n", clone);
65 		delete_area(reply.area);
66 		return B_ERROR;
67 	}
68 
69 	for (int32 i = 0; i < reply.count; i++)
70 		fTypes.AddItem(new BString(types + i * B_MEDIA_NAME_LENGTH));
71 
72 	delete_area(clone);
73 	delete_area(reply.area);
74 
75 	fTypeIndex = 0;
76 
77 	return B_OK;
78 }
79 
80 
81 status_t
82 BMediaFiles::GetNextType(BString *out_type)
83 {
84 	CALLED();
85 	if (fTypeIndex < 0 || fTypeIndex >= fTypes.CountItems()) {
86 		fTypeIndex = -1;
87 		return B_BAD_INDEX;
88 	}
89 
90 	*out_type = *(BString*)fTypes.ItemAt(fTypeIndex);
91 	fTypeIndex++;
92 
93 	return B_OK;
94 }
95 
96 
97 status_t
98 BMediaFiles::RewindRefs(const char *type)
99 {
100 	CALLED();
101 	status_t rv;
102 	server_rewindrefs_request request;
103 	server_rewindrefs_reply reply;
104 
105 	for (int32 i = 0; i < fItems.CountItems(); i++)
106 		delete (BString*)fItems.ItemAt(i);
107 
108 	fItems.MakeEmpty();
109 
110 	TRACE("BMediaFiles::RewindRefs: sending SERVER_REWINDREFS for type %s\n",
111 		type);
112 	strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
113 
114 	rv = QueryServer(SERVER_REWINDREFS, &request, sizeof(request), &reply,
115 		sizeof(reply));
116 	if (rv != B_OK) {
117 		ERROR("BMediaFiles::RewindRefs: failed to rewindrefs (error %#lx)\n",
118 			rv);
119 		return rv;
120 	}
121 
122 	if (reply.count>0) {
123 		char *items;
124 		area_id clone;
125 
126 		clone = clone_area("rewind refs clone",
127 			reinterpret_cast<void **>(&items), B_ANY_ADDRESS, B_READ_AREA
128 				| B_WRITE_AREA, reply.area);
129 		if (clone < B_OK) {
130 			ERROR("BMediaFiles::RewindRefs failed to clone area, %#lx\n",
131 				clone);
132 			delete_area(reply.area);
133 			return B_ERROR;
134 		}
135 
136 		for (int32 i = 0; i < reply.count; i++) {
137 			fItems.AddItem(new BString(items + i * B_MEDIA_NAME_LENGTH));
138 		}
139 
140 		delete_area(clone);
141 		delete_area(reply.area);
142 	}
143 
144 	fCurrentType = BString(type);
145 	fItemIndex = 0;
146 
147 	return B_OK;
148 }
149 
150 
151 status_t
152 BMediaFiles::GetNextRef(BString *out_type, entry_ref *out_ref)
153 {
154 	CALLED();
155 	if (fItemIndex < 0 || fItemIndex >= fItems.CountItems()) {
156 		fItemIndex = -1;
157 		return B_BAD_INDEX;
158 	}
159 
160 	*out_type = *(BString*)fItems.ItemAt(fItemIndex);
161 	fItemIndex++;
162 
163 	GetRefFor(fCurrentType.String(), out_type->String(), out_ref);
164 
165 	return B_OK;
166 }
167 
168 
169 status_t
170 BMediaFiles::GetRefFor(const char *type, const char *item, entry_ref *out_ref)
171 {
172 	CALLED();
173 	status_t rv;
174 	server_getreffor_request request;
175 	server_getreffor_reply reply;
176 
177 	strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
178 	strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
179 
180 	TRACE("BMediaFiles::GetRefFor: sending SERVER_GETREFFOR\n");
181 
182 	rv = QueryServer(SERVER_GETREFFOR, &request, sizeof(request), &reply,
183 		sizeof(reply));
184 	if (rv != B_OK) {
185 		entry_ref ref;
186 		*out_ref = ref;
187 		ERROR("BMediaFiles::GetRefFor: failed to getreffor (error %#lx)\n",
188 			rv);
189 		return rv;
190 	}
191 
192 	*out_ref = reply.ref;
193 
194 	return B_OK;
195 }
196 
197 
198 status_t
199 BMediaFiles::GetAudioGainFor(const char * type, const char * item,
200 	float * out_audio_gain)
201 {
202 	UNIMPLEMENTED();
203 	*out_audio_gain = 1.0f;
204 	return B_OK;
205 }
206 
207 
208 status_t
209 BMediaFiles::SetRefFor(const char *type, const char *item,
210 	const entry_ref &ref)
211 {
212 	CALLED();
213 	status_t rv;
214 	server_setreffor_request request;
215 	server_setreffor_reply reply;
216 
217 	strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
218 	strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
219 	request.ref = ref;
220 
221 	TRACE("BMediaFiles::SetRefFor: sending SERVER_SETREFFOR\n");
222 
223 	rv = QueryServer(SERVER_SETREFFOR, &request, sizeof(request), &reply,
224 		sizeof(reply));
225 	if (rv != B_OK) {
226 		ERROR("BMediaFiles::SetRefFor: failed to setreffor (error %#lx)\n",
227 			rv);
228 		return rv;
229 	}
230 
231 	return B_OK;
232 }
233 
234 
235 status_t
236 BMediaFiles::SetAudioGainFor(const char * type, const char * item,
237 	float audio_gain)
238 {
239 	UNIMPLEMENTED();
240 	return B_OK;
241 }
242 
243 
244 status_t
245 BMediaFiles::RemoveRefFor(const char *type, const char *item,
246 	const entry_ref &ref)
247 {
248 	status_t rv;
249 	server_removereffor_request request;
250 	server_removereffor_reply reply;
251 
252 	strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
253 	strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
254 	request.ref = ref;
255 
256 	TRACE("BMediaFiles::RemoveRefFor: sending SERVER_REMOVEREFFOR\n");
257 
258 	rv = QueryServer(SERVER_REMOVEREFFOR, &request, sizeof(request), &reply,
259 		sizeof(reply));
260 	if (rv != B_OK) {
261 		ERROR("BMediaFiles::RemoveRefFor: failed to removereffor "
262 			"(error %#lx)\n", rv);
263 		return rv;
264 	}
265 
266 	return B_OK;
267 }
268 
269 
270 status_t
271 BMediaFiles::RemoveItem(const char *type, const char *item)
272 {
273 	status_t rv;
274 	server_removeitem_request request;
275 	server_removeitem_reply reply;
276 
277 	strncpy(request.type, type, B_MEDIA_NAME_LENGTH);
278 	strncpy(request.item, item, B_MEDIA_NAME_LENGTH);
279 
280 	TRACE("BMediaFiles::RemoveItem: sending SERVER_REMOVEITEM\n");
281 
282 	rv = QueryServer(SERVER_REMOVEITEM, &request, sizeof(request), &reply,
283 		sizeof(reply));
284 	if (rv != B_OK) {
285 		ERROR("BMediaFiles::RemoveItem: failed to removeitem (error %#lx)\n",
286 			rv);
287 		return rv;
288 	}
289 
290 	return B_OK;
291 }
292 
293 
294 // #pragma mark - FBC padding
295 
296 status_t BMediaFiles::_Reserved_MediaFiles_0(void *,...)
297 {
298 	// TODO: Someone didn't understand FBC
299 	return B_ERROR;
300 }
301 
302 status_t BMediaFiles::_Reserved_MediaFiles_1(void *,...) { return B_ERROR; }
303 status_t BMediaFiles::_Reserved_MediaFiles_2(void *,...) { return B_ERROR; }
304 status_t BMediaFiles::_Reserved_MediaFiles_3(void *,...) { return B_ERROR; }
305 status_t BMediaFiles::_Reserved_MediaFiles_4(void *,...) { return B_ERROR; }
306 status_t BMediaFiles::_Reserved_MediaFiles_5(void *,...) { return B_ERROR; }
307 status_t BMediaFiles::_Reserved_MediaFiles_6(void *,...) { return B_ERROR; }
308 status_t BMediaFiles::_Reserved_MediaFiles_7(void *,...) { return B_ERROR; }
309 
310