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 <IconUtils.h> 44 #include <String.h> 45 #include <SupportDefs.h> 46 47 48 // #pragma mark - BImageResources 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 103 return B_OK; 104 } 105 106 107 const void* 108 BImageResources::LoadResource(type_code type, int32 id, 109 size_t* out_size) const 110 { 111 // Serialize execution. 112 // Looks like BResources is not really thread safe. We should 113 // clean that up in the future and remove the locking from here. 114 BAutolock lock(fLock); 115 if (!lock.IsLocked()) 116 return 0; 117 118 // Return the resource. Because we never change the BResources 119 // object, the returned data will not change until TTracker is 120 // destroyed. 121 return const_cast<BResources*>(&fResources)->LoadResource(type, id, 122 out_size); 123 } 124 125 126 const void* 127 BImageResources::LoadResource(type_code type, const char* name, 128 size_t* out_size) const 129 { 130 // Serialize execution. 131 BAutolock lock(fLock); 132 if (!lock.IsLocked()) 133 return NULL; 134 135 // Return the resource. Because we never change the BResources 136 // object, the returned data will not change until TTracker is 137 // destroyed. 138 return const_cast<BResources*>(&fResources)->LoadResource(type, name, 139 out_size); 140 } 141 142 143 status_t 144 BImageResources::GetIconResource(int32 id, icon_size size, 145 BBitmap* dest) const 146 { 147 size_t length = 0; 148 const void* data; 149 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 157 // fall back to R5 icon 158 if (size != B_LARGE_ICON && size != B_MINI_ICON) 159 return B_ERROR; 160 161 length = 0; 162 data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length); 163 164 if (data == NULL 165 || length != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) { 166 TRESPASS(); 167 return B_ERROR; 168 } 169 170 if (dest->ColorSpace() != B_CMAP8) { 171 return BIconUtils::ConvertFromCMAP8((uint8*)data, size, size, 172 size, dest); 173 } 174 175 dest->SetBits(data, (int32)length, 0, B_CMAP8); 176 return B_OK; 177 } 178 179 180 status_t 181 BImageResources::GetIconResource(int32 id, const uint8** iconData, 182 size_t* iconSize) const 183 { 184 // try to load vector icon data from resources 185 size_t length = 0; 186 const void* data = LoadResource(B_VECTOR_ICON_TYPE, id, &length); 187 if (data == NULL) 188 return B_ERROR; 189 190 *iconData = (const uint8*)data; 191 *iconSize = length; 192 193 return B_OK; 194 } 195 196 197 image_id 198 BImageResources::find_image(void* memAddr) const 199 { 200 image_info info; 201 int32 cookie = 0; 202 while (get_next_image_info(0, &cookie, &info) == B_OK) { 203 if ((info.text <= memAddr 204 && (((uint8*)info.text)+info.text_size) > memAddr) 205 || (info.data <= memAddr 206 && (((uint8*)info.data)+info.data_size) > memAddr)) { 207 // Found the image. 208 return info.id; 209 } 210 } 211 212 return -1; 213 } 214 215 216 status_t 217 BImageResources::GetBitmapResource(type_code type, int32 id, 218 BBitmap** out) const 219 { 220 *out = NULL; 221 222 size_t len = 0; 223 const void* data = LoadResource(type, id, &len); 224 225 if (data == NULL) { 226 TRESPASS(); 227 return B_ERROR; 228 } 229 230 BMemoryIO stream(data, len); 231 232 // Try to read as an archived bitmap. 233 stream.Seek(0, SEEK_SET); 234 BMessage archive; 235 status_t result = archive.Unflatten(&stream); 236 if (result != B_OK) 237 return result; 238 239 *out = new BBitmap(&archive); 240 if (*out == NULL) 241 return B_ERROR; 242 243 result = (*out)->InitCheck(); 244 if (result != B_OK) { 245 delete *out; 246 *out = NULL; 247 } 248 249 return result; 250 } 251 252 253 static BLocker resLock; 254 static BImageResources* resources = NULL; 255 256 // This class is used as a static instance to delete the resources 257 // global object when the image is getting unloaded. 258 class _TTrackerCleanupResources { 259 public: 260 _TTrackerCleanupResources() 261 { 262 } 263 264 ~_TTrackerCleanupResources() 265 { 266 delete resources; 267 resources = NULL; 268 } 269 }; 270 271 272 namespace BPrivate { 273 274 static _TTrackerCleanupResources CleanupResources; 275 276 BImageResources* GetTrackerResources() 277 { 278 if (!resources) { 279 BAutolock lock(&resLock); 280 resources = new BImageResources(&resources); 281 } 282 283 return resources; 284 } 285 286 } // namespace BPrivate 287