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