1/*
2 * Copyright 2002-2009, 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
13#include <AppMisc.h>
14#include <DataExchange.h>
15#include <MediaDebug.h>
16
17
18const char BMediaFiles::B_SOUNDS[] = "Sounds";
19
20
21BMediaFiles::BMediaFiles()
22	:
23	fTypeIndex(-1),
24	fItemIndex(-1)
25{
26
27}
28
29
30BMediaFiles::~BMediaFiles()
31{
32	_ClearTypes();
33	_ClearItems();
34}
35
36
37status_t
38BMediaFiles::RewindTypes()
39{
40	CALLED();
41
42	_ClearTypes();
43
44	server_get_media_types_request request;
45	request.team = BPrivate::current_team();
46
47	server_get_media_types_reply reply;
48	status_t status = QueryServer(SERVER_GET_MEDIA_FILE_TYPES, &request,
49		sizeof(request), &reply, sizeof(reply));
50	if (status != B_OK) {
51		ERROR("BMediaFiles::RewindTypes: failed to rewind types: %s\n",
52			strerror(status));
53		return status;
54	}
55
56	const char* types = (const char*)reply.address;
57	for (int32 i = 0; i < reply.count; i++)
58		fTypes.AddItem(new BString(types + i * B_MEDIA_NAME_LENGTH));
59
60	delete_area(reply.area);
61
62	fTypeIndex = 0;
63	return B_OK;
64}
65
66
67status_t
68BMediaFiles::GetNextType(BString* _type)
69{
70	CALLED();
71	if (fTypeIndex < 0 || fTypeIndex >= fTypes.CountItems()) {
72		_ClearTypes();
73		fTypeIndex = -1;
74		return B_BAD_INDEX;
75	}
76
77	*_type = *(BString*)fTypes.ItemAt(fTypeIndex);
78	fTypeIndex++;
79
80	return B_OK;
81}
82
83
84status_t
85BMediaFiles::RewindRefs(const char* type)
86{
87	CALLED();
88
89	_ClearItems();
90
91	TRACE("BMediaFiles::RewindRefs: sending SERVER_GET_MEDIA_FILE_ITEMS for "
92		"type %s\n", type);
93
94	server_get_media_items_request request;
95	request.team = BPrivate::current_team();
96	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
97
98	server_get_media_items_reply reply;
99	status_t status = QueryServer(SERVER_GET_MEDIA_FILE_ITEMS, &request,
100		sizeof(request), &reply, sizeof(reply));
101	if (status != B_OK) {
102		ERROR("BMediaFiles::RewindRefs: failed to rewind refs: %s\n",
103			strerror(status));
104		return status;
105	}
106
107	const char* items = (const char*)reply.address;
108	for (int32 i = 0; i < reply.count; i++) {
109		fItems.AddItem(new BString(items + i * B_MEDIA_NAME_LENGTH,
110			B_MEDIA_NAME_LENGTH));
111	}
112
113	delete_area(reply.area);
114
115	fCurrentType = type;
116	fItemIndex = 0;
117	return B_OK;
118}
119
120
121status_t
122BMediaFiles::GetNextRef(BString* _type, entry_ref* _ref)
123{
124	CALLED();
125	if (fItemIndex < 0 || fItemIndex >= fItems.CountItems()) {
126		_ClearItems();
127		fItemIndex = -1;
128		return B_BAD_INDEX;
129	}
130
131	*_type = *(BString*)fItems.ItemAt(fItemIndex);
132	GetRefFor(fCurrentType.String(), _type->String(), _ref);
133
134	fItemIndex++;
135	return B_OK;
136}
137
138
139status_t
140BMediaFiles::GetRefFor(const char* type, const char* item, entry_ref* _ref)
141{
142	CALLED();
143
144	if (type == NULL || item == NULL || _ref == NULL)
145		return B_BAD_VALUE;
146
147	server_get_ref_for_request request;
148	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
149	strlcpy(request.item, item, B_MEDIA_NAME_LENGTH);
150
151	server_get_ref_for_reply reply;
152	status_t status = QueryServer(SERVER_GET_REF_FOR, &request, sizeof(request),
153		&reply, sizeof(reply));
154	if (status != B_OK) {
155		ERROR("BMediaFiles::GetRefFor: failed: %s\n", strerror(status));
156		return status;
157	}
158
159	*_ref = reply.ref;
160	return B_OK;
161}
162
163
164status_t
165BMediaFiles::GetAudioGainFor(const char* type, const char* item, float* _gain)
166{
167	CALLED();
168
169	if (type == NULL || item == NULL || _gain == NULL)
170		return B_BAD_VALUE;
171
172	server_get_item_audio_gain_request request;
173	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
174	strlcpy(request.item, item, B_MEDIA_NAME_LENGTH);
175
176	server_get_item_audio_gain_reply reply;
177	status_t status = QueryServer(SERVER_GET_ITEM_AUDIO_GAIN, &request,
178		sizeof(request), &reply, sizeof(reply));
179	if (status != B_OK) {
180		ERROR("BMediaFiles::GetRefFor: failed: %s\n", strerror(status));
181		return status;
182	}
183
184	*_gain = reply.gain;
185	return B_OK;
186}
187
188
189status_t
190BMediaFiles::SetRefFor(const char* type, const char* item,
191	const entry_ref& ref)
192{
193	CALLED();
194
195	server_set_ref_for_request request;
196	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
197	strlcpy(request.item, item, B_MEDIA_NAME_LENGTH);
198	request.ref = ref;
199
200	server_set_ref_for_reply reply;
201	status_t status = QueryServer(SERVER_SET_REF_FOR, &request, sizeof(request),
202		&reply, sizeof(reply));
203	if (status != B_OK) {
204		ERROR("BMediaFiles::SetRefFor: failed: %s\n", strerror(status));
205		return status;
206	}
207
208	return B_OK;
209}
210
211
212status_t
213BMediaFiles::SetAudioGainFor(const char* type, const char* item, float gain)
214{
215	CALLED();
216
217	server_set_item_audio_gain_request request;
218	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
219	strlcpy(request.item, item, B_MEDIA_NAME_LENGTH);
220	request.gain = gain;
221
222	server_set_item_audio_gain_reply reply;
223	status_t status = QueryServer(SERVER_SET_ITEM_AUDIO_GAIN, &request,
224		sizeof(request), &reply, sizeof(reply));
225	if (status != B_OK) {
226		ERROR("BMediaFiles::SetAudioGainFor: failed: %s\n", strerror(status));
227		return status;
228	}
229
230	return B_OK;
231}
232
233
234status_t
235BMediaFiles::RemoveRefFor(const char* type, const char* item,
236	const entry_ref &ref)
237{
238	CALLED();
239
240	server_invalidate_item_request request;
241	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
242	strlcpy(request.item, item, B_MEDIA_NAME_LENGTH);
243
244	server_invalidate_item_reply reply;
245	status_t status = QueryServer(SERVER_INVALIDATE_MEDIA_ITEM, &request,
246		sizeof(request), &reply, sizeof(reply));
247	if (status != B_OK) {
248		ERROR("BMediaFiles::RemoveRefFor: failed: %s\n", strerror(status));
249		return status;
250	}
251
252	return B_OK;
253}
254
255
256status_t
257BMediaFiles::RemoveItem(const char* type, const char* item)
258{
259	CALLED();
260
261	server_remove_media_item_request request;
262	strlcpy(request.type, type, B_MEDIA_NAME_LENGTH);
263	strlcpy(request.item, item, B_MEDIA_NAME_LENGTH);
264
265	server_remove_media_item_reply reply;
266	status_t status = QueryServer(SERVER_REMOVE_MEDIA_ITEM, &request,
267		sizeof(request), &reply, sizeof(reply));
268	if (status != B_OK) {
269		ERROR("BMediaFiles::RemoveItem: failed: %s\n", strerror(status));
270		return status;
271	}
272
273	return B_OK;
274}
275
276
277// #pragma mark - private
278
279
280void
281BMediaFiles::_ClearTypes()
282{
283	for (int32 i = 0; i < fTypes.CountItems(); i++)
284		delete (BString*)fTypes.ItemAt(i);
285
286	fTypes.MakeEmpty();
287}
288
289
290void
291BMediaFiles::_ClearItems()
292{
293	for (int32 i = 0; i < fItems.CountItems(); i++)
294		delete (BString*)fItems.ItemAt(i);
295
296	fItems.MakeEmpty();
297}
298
299
300// #pragma mark - FBC padding
301
302
303status_t
304BMediaFiles::_Reserved_MediaFiles_0(void*,...)
305{
306	// TODO: Someone didn't understand FBC
307	return B_ERROR;
308}
309
310
311status_t BMediaFiles::_Reserved_MediaFiles_1(void*,...) { return B_ERROR; }
312status_t BMediaFiles::_Reserved_MediaFiles_2(void*,...) { return B_ERROR; }
313status_t BMediaFiles::_Reserved_MediaFiles_3(void*,...) { return B_ERROR; }
314status_t BMediaFiles::_Reserved_MediaFiles_4(void*,...) { return B_ERROR; }
315status_t BMediaFiles::_Reserved_MediaFiles_5(void*,...) { return B_ERROR; }
316status_t BMediaFiles::_Reserved_MediaFiles_6(void*,...) { return B_ERROR; }
317status_t BMediaFiles::_Reserved_MediaFiles_7(void*,...) { return B_ERROR; }
318
319