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 <debug.h> 16 17 18 const char BMediaFiles::B_SOUNDS[] = "Sounds"; 19 20 21 BMediaFiles::BMediaFiles() 22 : 23 fTypeIndex(-1), 24 fItemIndex(-1) 25 { 26 27 } 28 29 30 BMediaFiles::~BMediaFiles() 31 { 32 _ClearTypes(); 33 _ClearItems(); 34 } 35 36 37 status_t 38 BMediaFiles::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 67 status_t 68 BMediaFiles::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 84 status_t 85 BMediaFiles::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 121 status_t 122 BMediaFiles::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 139 status_t 140 BMediaFiles::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 164 status_t 165 BMediaFiles::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 189 status_t 190 BMediaFiles::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 212 status_t 213 BMediaFiles::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 234 status_t 235 BMediaFiles::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 256 status_t 257 BMediaFiles::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 280 void 281 BMediaFiles::_ClearTypes() 282 { 283 for (int32 i = 0; i < fTypes.CountItems(); i++) 284 delete (BString*)fTypes.ItemAt(i); 285 286 fTypes.MakeEmpty(); 287 } 288 289 290 void 291 BMediaFiles::_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 303 status_t 304 BMediaFiles::_Reserved_MediaFiles_0(void*,...) 305 { 306 // TODO: Someone didn't understand FBC 307 return B_ERROR; 308 } 309 310 311 status_t BMediaFiles::_Reserved_MediaFiles_1(void*,...) { return B_ERROR; } 312 status_t BMediaFiles::_Reserved_MediaFiles_2(void*,...) { return B_ERROR; } 313 status_t BMediaFiles::_Reserved_MediaFiles_3(void*,...) { return B_ERROR; } 314 status_t BMediaFiles::_Reserved_MediaFiles_4(void*,...) { return B_ERROR; } 315 status_t BMediaFiles::_Reserved_MediaFiles_5(void*,...) { return B_ERROR; } 316 status_t BMediaFiles::_Reserved_MediaFiles_6(void*,...) { return B_ERROR; } 317 status_t BMediaFiles::_Reserved_MediaFiles_7(void*,...) { return B_ERROR; } 318 319