1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 30 of Be Incorporated in the United States and other countries. Other brand product 31 names are registered trademarks or trademarks of their respective holders. 32 All rights reserved. 33 */ 34 35 #include "Bitmaps.h" 36 #include "Utilities.h" 37 38 #include <Autolock.h> 39 #include <Bitmap.h> 40 #include <Debug.h> 41 #include <DataIO.h> 42 #include <File.h> 43 #include <String.h> 44 #include <SupportDefs.h> 45 46 #ifdef __HAIKU__ 47 # include <IconUtils.h> 48 #endif 49 50 51 // #pragma mark - BImageResources 52 53 54 BImageResources::BImageResources(void* memAddr) 55 { 56 image_id image = find_image(memAddr); 57 image_info info; 58 if (get_image_info(image, &info) == B_OK) { 59 #if _SUPPORTS_RESOURCES 60 BFile file(&info.name[0], B_READ_ONLY); 61 #else 62 BString name(&info.name[0]); 63 name += ".rsrc"; 64 BFile file(name.String(), B_READ_ONLY); 65 #endif 66 if (file.InitCheck() == B_OK) 67 fResources.SetTo(&file); 68 } 69 } 70 71 72 BImageResources::~BImageResources() 73 { 74 } 75 76 77 const BResources* 78 BImageResources::ViewResources() const 79 { 80 if (fLock.Lock() != B_OK) 81 return NULL; 82 83 return &fResources; 84 } 85 86 87 BResources* 88 BImageResources::ViewResources() 89 { 90 if (fLock.Lock() != B_OK) 91 return NULL; 92 93 return &fResources; 94 } 95 96 97 status_t 98 BImageResources::FinishResources(BResources* res) const 99 { 100 ASSERT(res == &fResources); 101 if (res != &fResources) 102 return B_BAD_VALUE; 103 104 fLock.Unlock(); 105 106 return B_OK; 107 } 108 109 110 const void* 111 BImageResources::LoadResource(type_code type, int32 id, 112 size_t* out_size) const 113 { 114 // Serialize execution. 115 // Looks like BResources is not really thread safe. We should 116 // clean that up in the future and remove the locking from here. 117 BAutolock lock(fLock); 118 if (!lock.IsLocked()) 119 return 0; 120 121 // Return the resource. Because we never change the BResources 122 // object, the returned data will not change until TTracker is 123 // destroyed. 124 return const_cast<BResources*>(&fResources)->LoadResource(type, id, 125 out_size); 126 } 127 128 129 const void* 130 BImageResources::LoadResource(type_code type, const char* name, 131 size_t* out_size) const 132 { 133 // Serialize execution. 134 BAutolock lock(fLock); 135 if (!lock.IsLocked()) 136 return NULL; 137 138 // Return the resource. Because we never change the BResources 139 // object, the returned data will not change until TTracker is 140 // destroyed. 141 return const_cast<BResources*>(&fResources)->LoadResource(type, name, 142 out_size); 143 } 144 145 146 status_t 147 BImageResources::GetIconResource(int32 id, icon_size size, 148 BBitmap* dest) const 149 { 150 size_t length = 0; 151 const void* data; 152 153 #ifdef __HAIKU__ 154 // try to load vector icon 155 data = LoadResource(B_VECTOR_ICON_TYPE, id, &length); 156 if (data != NULL 157 && BIconUtils::GetVectorIcon((uint8*)data, length, dest) == B_OK) { 158 return B_OK; 159 } 160 #endif 161 162 // fall back to R5 icon 163 if (size != B_LARGE_ICON && size != B_MINI_ICON) 164 return B_ERROR; 165 166 length = 0; 167 data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length); 168 169 if (data == NULL 170 || length != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) { 171 TRESPASS(); 172 return B_ERROR; 173 } 174 175 #ifdef __HAIKU__ 176 if (dest->ColorSpace() != B_CMAP8) { 177 return BIconUtils::ConvertFromCMAP8((uint8*)data, size, size, 178 size, dest); 179 } 180 #endif 181 182 dest->SetBits(data, (int32)length, 0, B_CMAP8); 183 return B_OK; 184 } 185 186 187 status_t 188 BImageResources::GetIconResource(int32 id, const uint8** iconData, 189 size_t* iconSize) const 190 { 191 #ifdef __HAIKU__ 192 // try to load vector icon data from resources 193 size_t length = 0; 194 const void* data = LoadResource(B_VECTOR_ICON_TYPE, id, &length); 195 if (data == NULL) 196 return B_ERROR; 197 198 *iconData = (const uint8*)data; 199 *iconSize = length; 200 201 return B_OK; 202 #else 203 return B_ERROR; 204 #endif 205 } 206 207 208 image_id 209 BImageResources::find_image(void* memAddr) const 210 { 211 image_info info; 212 int32 cookie = 0; 213 while (get_next_image_info(0, &cookie, &info) == B_OK) { 214 if ((info.text <= memAddr 215 && (((uint8*)info.text)+info.text_size) > memAddr) 216 || (info.data <= memAddr 217 && (((uint8*)info.data)+info.data_size) > memAddr)) { 218 // Found the image. 219 return info.id; 220 } 221 } 222 223 return -1; 224 } 225 226 227 status_t 228 BImageResources::GetBitmapResource(type_code type, int32 id, 229 BBitmap** out) const 230 { 231 *out = NULL; 232 233 size_t len = 0; 234 const void* data = LoadResource(type, id, &len); 235 236 if (data == NULL) { 237 TRESPASS(); 238 return B_ERROR; 239 } 240 241 BMemoryIO stream(data, len); 242 243 // Try to read as an archived bitmap. 244 stream.Seek(0, SEEK_SET); 245 BMessage archive; 246 status_t result = archive.Unflatten(&stream); 247 if (result != B_OK) 248 return result; 249 250 *out = new BBitmap(&archive); 251 if (*out == NULL) 252 return B_ERROR; 253 254 result = (*out)->InitCheck(); 255 if (result != B_OK) { 256 delete *out; 257 *out = NULL; 258 } 259 260 return result; 261 } 262 263 264 static BLocker resLock; 265 static BImageResources* resources = NULL; 266 267 // This class is used as a static instance to delete the resources 268 // global object when the image is getting unloaded. 269 class _TTrackerCleanupResources { 270 public: 271 _TTrackerCleanupResources() 272 { 273 } 274 275 ~_TTrackerCleanupResources() 276 { 277 delete resources; 278 resources = NULL; 279 } 280 }; 281 282 283 namespace BPrivate { 284 285 static _TTrackerCleanupResources CleanupResources; 286 287 BImageResources* GetTrackerResources() 288 { 289 if (!resources) { 290 BAutolock lock(&resLock); 291 resources = new BImageResources(&resources); 292 } 293 294 return resources; 295 } 296 297 } // namespace BPrivate 298