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