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 if (size != B_LARGE_ICON && size != B_MINI_ICON ) 131 return B_ERROR; 132 133 size_t length = 0; 134 const void *data; 135 136 // try to load vector icon 137 data = LoadResource(B_RAW_TYPE, id, &length); 138 139 if (data && BIconUtils::GetVectorIcon((uint8*)data, length, dest) == B_OK) 140 return B_OK; 141 142 // fall back to R5 icon 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 image_id 164 BImageResources::find_image(void *memAddr) const 165 { 166 image_info info; 167 int32 cookie = 0; 168 while (get_next_image_info(0, &cookie, &info) == B_OK) 169 if ((info.text <= memAddr && (((uint8 *)info.text)+info.text_size) > memAddr) 170 ||(info.data <= memAddr && (((uint8 *)info.data)+info.data_size) > memAddr)) 171 // Found the image. 172 return info.id; 173 174 return -1; 175 } 176 177 status_t 178 BImageResources::GetBitmapResource(type_code type, int32 id, BBitmap **out) const 179 { 180 *out = NULL; 181 182 size_t len = 0; 183 const void *data = LoadResource(type, id, &len); 184 185 if (data == NULL) { 186 TRESPASS(); 187 return B_ERROR; 188 } 189 190 BMemoryIO stream(data, len); 191 192 // Try to read as an archived bitmap. 193 stream.Seek(0, SEEK_SET); 194 BMessage archive; 195 status_t err = archive.Unflatten(&stream); 196 if (err != B_OK) 197 return err; 198 199 *out = new BBitmap(&archive); 200 if (!*out) 201 return B_ERROR; 202 203 err = (*out)->InitCheck(); 204 if (err != B_OK) { 205 delete *out; 206 *out = NULL; 207 } 208 209 return err; 210 } 211 212 213 static BLocker resLock; 214 static BImageResources *resources = NULL; 215 216 // This class is used as a static instance to delete the resources 217 // global object when the image is getting unloaded. 218 class _TTrackerCleanupResources 219 { 220 public: 221 _TTrackerCleanupResources() { } 222 ~_TTrackerCleanupResources() 223 { 224 delete resources; 225 resources = NULL; 226 } 227 }; 228 229 230 namespace BPrivate { 231 232 static _TTrackerCleanupResources CleanupResources; 233 234 235 BImageResources *GetTrackerResources() 236 { 237 if (!resources) { 238 BAutolock lock(&resLock); 239 resources = new BImageResources(&resources); 240 } 241 return resources; 242 } 243 244 } 245