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 BImageResources::BImageResources(void* memAddr) 52 { 53 image_id image = find_image(memAddr); 54 image_info info; 55 if (get_image_info(image, &info) == B_OK) { 56 #if _SUPPORTS_RESOURCES 57 BFile file(&info.name[0], B_READ_ONLY); 58 #else 59 BString name(&info.name[0]); 60 name += ".rsrc"; 61 BFile file(name.String(), B_READ_ONLY); 62 #endif 63 if (file.InitCheck() == B_OK) 64 fResources.SetTo(&file); 65 } 66 } 67 68 69 BImageResources::~BImageResources() 70 { 71 } 72 73 74 const BResources* 75 BImageResources::ViewResources() const 76 { 77 if (fLock.Lock() != B_OK) 78 return NULL; 79 80 return &fResources; 81 } 82 83 84 BResources* 85 BImageResources::ViewResources() 86 { 87 if (fLock.Lock() != B_OK) 88 return NULL; 89 90 return &fResources; 91 } 92 93 94 status_t 95 BImageResources::FinishResources(BResources* res) const 96 { 97 ASSERT(res == &fResources); 98 if (res != &fResources) 99 return B_BAD_VALUE; 100 101 fLock.Unlock(); 102 return B_OK; 103 } 104 105 106 const void* 107 BImageResources::LoadResource(type_code type, int32 id, 108 size_t* out_size) const 109 { 110 // Serialize execution. 111 // Looks like BResources is not really thread safe. We should 112 // clean that up in the future and remove the locking from here. 113 BAutolock lock(fLock); 114 if (!lock.IsLocked()) 115 return 0; 116 117 // Return the resource. Because we never change the BResources 118 // object, the returned data will not change until TTracker is 119 // destroyed. 120 return const_cast<BResources*>(&fResources)->LoadResource(type, id, 121 out_size); 122 } 123 124 125 const void* 126 BImageResources::LoadResource(type_code type, const char* name, 127 size_t* out_size) const 128 { 129 // Serialize execution. 130 BAutolock lock(fLock); 131 if (!lock.IsLocked()) 132 return NULL; 133 134 // Return the resource. Because we never change the BResources 135 // object, the returned data will not change until TTracker is 136 // destroyed. 137 return const_cast<BResources*>(&fResources)->LoadResource(type, name, 138 out_size); 139 } 140 141 142 status_t 143 BImageResources::GetIconResource(int32 id, icon_size size, 144 BBitmap* dest) const 145 { 146 size_t length = 0; 147 const void* data; 148 149 #ifdef __HAIKU__ 150 // try to load vector icon 151 data = LoadResource(B_VECTOR_ICON_TYPE, id, &length); 152 if (data != NULL 153 && BIconUtils::GetVectorIcon((uint8*)data, length, dest) == B_OK) { 154 return B_OK; 155 } 156 #endif 157 158 // fall back to R5 icon 159 if (size != B_LARGE_ICON && size != B_MINI_ICON) 160 return B_ERROR; 161 162 length = 0; 163 data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length); 164 165 if (data == NULL 166 || length != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) { 167 TRESPASS(); 168 return B_ERROR; 169 } 170 171 #ifdef __HAIKU__ 172 if (dest->ColorSpace() != B_CMAP8) { 173 return BIconUtils::ConvertFromCMAP8((uint8*)data, size, size, 174 size, dest); 175 } 176 #endif 177 178 dest->SetBits(data, (int32)length, 0, B_CMAP8); 179 return B_OK; 180 } 181 182 183 status_t 184 BImageResources::GetIconResource(int32 id, const uint8** iconData, 185 size_t* iconSize) const 186 { 187 #ifdef __HAIKU__ 188 // try to load vector icon data from resources 189 size_t length = 0; 190 const void* data = LoadResource(B_VECTOR_ICON_TYPE, id, &length); 191 if (data == NULL) 192 return B_ERROR; 193 194 *iconData = (const uint8*)data; 195 *iconSize = length; 196 197 return B_OK; 198 #else 199 return B_ERROR; 200 #endif 201 } 202 203 204 image_id 205 BImageResources::find_image(void* memAddr) const 206 { 207 image_info info; 208 int32 cookie = 0; 209 while (get_next_image_info(0, &cookie, &info) == B_OK) 210 if ((info.text <= memAddr 211 && (((uint8*)info.text)+info.text_size) > memAddr) 212 || (info.data <= memAddr 213 && (((uint8*)info.data)+info.data_size) > memAddr)) { 214 // Found the image. 215 return info.id; 216 } 217 218 return -1; 219 } 220 221 222 status_t 223 BImageResources::GetBitmapResource(type_code type, int32 id, 224 BBitmap** out) const 225 { 226 *out = NULL; 227 228 size_t len = 0; 229 const void* data = LoadResource(type, id, &len); 230 231 if (data == NULL) { 232 TRESPASS(); 233 return B_ERROR; 234 } 235 236 BMemoryIO stream(data, len); 237 238 // Try to read as an archived bitmap. 239 stream.Seek(0, SEEK_SET); 240 BMessage archive; 241 status_t err = archive.Unflatten(&stream); 242 if (err != B_OK) 243 return err; 244 245 *out = new BBitmap(&archive); 246 if (!*out) 247 return B_ERROR; 248 249 err = (*out)->InitCheck(); 250 if (err != B_OK) { 251 delete *out; 252 *out = NULL; 253 } 254 255 return err; 256 } 257 258 259 static BLocker resLock; 260 static BImageResources* resources = NULL; 261 262 // This class is used as a static instance to delete the resources 263 // global object when the image is getting unloaded. 264 class _TTrackerCleanupResources { 265 public: 266 _TTrackerCleanupResources() { } 267 ~_TTrackerCleanupResources() 268 { 269 delete resources; 270 resources = NULL; 271 } 272 }; 273 274 275 namespace BPrivate { 276 277 static _TTrackerCleanupResources CleanupResources; 278 279 280 BImageResources* GetTrackerResources() 281 { 282 if (!resources) { 283 BAutolock lock(&resLock); 284 resources = new BImageResources(&resources); 285 } 286 return resources; 287 } 288 289 } 290