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