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 #ifndef _UTILITIES_H 35 #define _UTILITIES_H 36 37 38 #include <ctype.h> 39 #include <stdarg.h> 40 #include <stdlib.h> 41 42 #include <Bitmap.h> 43 #include <ByteOrder.h> 44 #include <DataIO.h> 45 #include <Directory.h> 46 #include <Entry.h> 47 #include <GraphicsDefs.h> 48 #include <Looper.h> 49 #include <MenuItem.h> 50 #include <MessageFilter.h> 51 #include <Mime.h> 52 #include <NaturalCompare.h> 53 #include <ObjectList.h> 54 #include <Point.h> 55 #include <Path.h> 56 #include <String.h> 57 #include <StringView.h> 58 59 60 class BMessage; 61 class BTextView; 62 class BView; 63 class BVolume; 64 65 namespace BPrivate { 66 67 class Benaphore; 68 class BPose; 69 class BPoseView; 70 class Model; 71 72 // global variables 73 static const rgb_color kBlack = make_color(0, 0, 0, 255); 74 static const rgb_color kWhite = make_color(255, 255, 255 ,255); 75 76 const int64 kHalfKBSize = 512; 77 const int64 kKBSize = 1024; 78 const int64 kMBSize = 1048576; 79 const int64 kGBSize = 1073741824; 80 const int64 kTBSize = kGBSize * kKBSize; 81 82 const int32 kMiniIconSeparator = 3; 83 84 const color_space kDefaultIconDepth = B_RGBA32; 85 86 87 extern bool gLocalizedNamePreferred; 88 89 90 // misc typedefs, constants and structs 91 92 class PeriodicUpdatePoses { 93 // Periodically updated poses (ones with a volume space bar) register 94 // themselfs in this global list. This way they can be iterated over instead 95 // of sending around update messages. 96 public: 97 PeriodicUpdatePoses(); 98 ~PeriodicUpdatePoses(); 99 100 typedef bool (*PeriodicUpdateCallback)(BPose* pose, void* cookie); 101 102 void AddPose(BPose* pose, BPoseView* poseView, 103 PeriodicUpdateCallback callback, void* cookie); 104 bool RemovePose(BPose* pose, void** cookie); 105 106 void DoPeriodicUpdate(bool forceRedraw); 107 108 private: 109 struct periodic_pose { 110 BPose* pose; 111 BPoseView* pose_view; 112 PeriodicUpdateCallback callback; 113 void* cookie; 114 }; 115 116 Benaphore* fLock; 117 BObjectList<periodic_pose> fPoseList; 118 }; 119 120 extern PeriodicUpdatePoses gPeriodicUpdatePoses; 121 122 123 class PoseInfo { 124 // PoseInfo is the structure that gets saved as attributes for every node 125 // on disk, defining the node's position and visibility 126 public: 127 static void EndianSwap(void* castToThis); 128 void PrintToStream(); 129 130 bool fInvisible; 131 ino_t fInitedDirectory; 132 // For a location to be valid, fInitedDirectory has to contain 133 // the inode of the items parent directory. This makes it 134 // impossible to for instance zip up files and extract them in 135 // the same location. This should probably be reworked. 136 // Tracker could strip the file location attributes when dropping 137 // files into a closed folder. 138 BPoint fLocation; 139 }; 140 141 142 class ExtendedPoseInfo { 143 // extends PoseInfo adding workspace support; used for desktop 144 // poses only 145 public: 146 size_t Size() const; 147 static size_t Size(int32); 148 size_t SizeWithHeadroom() const; 149 static size_t SizeWithHeadroom(size_t); 150 bool HasLocationForFrame(BRect) const; 151 BPoint LocationForFrame(BRect) const; 152 bool SetLocationForFrame(BPoint, BRect); 153 154 static void EndianSwap(void* castToThis); 155 void PrintToStream(); 156 157 uint32 fWorkspaces; 158 bool fInvisible; 159 bool fShowFromBootOnly; 160 bool fReservedBool1; 161 bool fReservedBool2; 162 int32 fReservedInt1; 163 int32 fReservedInt2; 164 int32 fReservedInt3; 165 int32 fReservedInt4; 166 int32 fReservedInt5; 167 168 int32 fNumFrames; 169 struct FrameLocation { 170 BPoint fLocation; 171 BRect fFrame; 172 uint32 fWorkspaces; 173 }; 174 175 FrameLocation fLocations[0]; 176 }; 177 178 // misc functions 179 void DisallowMetaKeys(BTextView*); 180 void DisallowFilenameKeys(BTextView*); 181 182 bool ValidateStream(BMallocIO*, uint32, int32 version); 183 184 float ReadOnlyTint(rgb_color base); 185 rgb_color InvertColor(rgb_color color); 186 rgb_color InvertedBackColor(rgb_color background); 187 188 bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons); 189 190 uint32 SeededHashString(const char* string, uint32 seed); 191 uint32 AttrHashString(const char* string, uint32 type); 192 193 194 class OffscreenBitmap { 195 // a utility class for setting up offscreen bitmaps 196 public: 197 OffscreenBitmap(BRect bounds); 198 OffscreenBitmap(); 199 ~OffscreenBitmap(); 200 201 BView* BeginUsing(BRect bounds); 202 void DoneUsing(); 203 BBitmap* Bitmap() const; 204 // blit this to your view when you are done rendering 205 BView* View() const; 206 // use this to render your image 207 208 private: 209 void NewBitmap(BRect frame); 210 BBitmap* fBitmap; 211 }; 212 213 214 // bitmap functions 215 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height, 216 int32 from, int32 to); 217 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height, 218 int32 from, int32 to); 219 220 221 class FlickerFreeStringView : public BStringView { 222 // adds support for offscreen bitmap drawing for string views that update 223 // often this would be better implemented as an option of BStringView 224 public: 225 FlickerFreeStringView(BRect bounds, const char* name, 226 const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 227 uint32 flags = B_WILL_DRAW); 228 FlickerFreeStringView(BRect bounds, const char* name, 229 const char* text, BBitmap* existingOffscreen, 230 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 231 uint32 flags = B_WILL_DRAW); 232 virtual ~FlickerFreeStringView(); 233 virtual void Draw(BRect); 234 virtual void AttachedToWindow(); 235 virtual void SetViewColor(rgb_color); 236 virtual void SetLowColor(rgb_color); 237 238 private: 239 OffscreenBitmap* fBitmap; 240 rgb_color fViewColor; 241 rgb_color fLowColor; 242 BBitmap* fOriginalBitmap; 243 244 typedef BStringView _inherited; 245 }; 246 247 248 class DraggableIcon : public BView { 249 // used to determine a save location for a file 250 public: 251 DraggableIcon(BRect rect, const char* name, const char* mimeType, 252 icon_size which, const BMessage* message, BMessenger target, 253 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 254 uint32 flags = B_WILL_DRAW); 255 virtual ~DraggableIcon(); 256 257 static BRect PreferredRect(BPoint offset, icon_size which); 258 void SetTarget(BMessenger); 259 260 protected: 261 virtual void AttachedToWindow(); 262 virtual void MouseDown(BPoint); 263 virtual void Draw(BRect); 264 265 virtual bool DragStarted(BMessage* dragMessage); 266 267 protected: 268 BBitmap* fBitmap; 269 BMessage fMessage; 270 BMessenger fTarget; 271 }; 272 273 274 class PositionPassingMenuItem : public BMenuItem { 275 public: 276 PositionPassingMenuItem(const char* title, BMessage*, 277 char shortcut = 0, uint32 modifiers = 0); 278 PositionPassingMenuItem(BMenu*, BMessage*); 279 PositionPassingMenuItem(BMessage* data); 280 281 static BArchivable* Instantiate(BMessage* data); 282 283 protected: 284 virtual status_t Invoke(BMessage* = 0); 285 // appends the invoke location for NewFolder, etc. to use 286 287 private: 288 typedef BMenuItem _inherited; 289 }; 290 291 292 class Benaphore { 293 // aka benaphore 294 public: 295 Benaphore(const char* name = "Light Lock") 296 : fSemaphore(create_sem(0, name)), 297 fCount(1) 298 { 299 } 300 301 ~Benaphore() 302 { 303 delete_sem(fSemaphore); 304 } 305 306 bool Lock() 307 { 308 if (atomic_add(&fCount, -1) <= 0) 309 return acquire_sem(fSemaphore) == B_OK; 310 311 return true; 312 } 313 314 void Unlock() 315 { 316 if (atomic_add(&fCount, 1) < 0) 317 release_sem(fSemaphore); 318 } 319 320 bool IsLocked() const 321 { 322 return fCount <= 0; 323 } 324 325 private: 326 sem_id fSemaphore; 327 int32 fCount; 328 }; 329 330 331 class SeparatorLine : public BView { 332 public: 333 SeparatorLine(BPoint, float, bool vertical, const char* name = ""); 334 virtual void Draw(BRect bounds); 335 }; 336 337 338 class TitledSeparatorItem : public BMenuItem { 339 public: 340 TitledSeparatorItem(const char*); 341 virtual ~TitledSeparatorItem(); 342 343 virtual void SetEnabled(bool state); 344 345 protected: 346 virtual void GetContentSize(float* width, float* height); 347 virtual void Draw(); 348 349 private: 350 typedef BMenuItem _inherited; 351 }; 352 353 354 class ShortcutFilter : public BMessageFilter { 355 public: 356 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier, 357 uint32 shortcutWhat, BHandler* target); 358 359 protected: 360 filter_result Filter(BMessage*, BHandler**); 361 362 private: 363 uint32 fShortcutKey; 364 uint32 fShortcutModifier; 365 uint32 fShortcutWhat; 366 BHandler* fTarget; 367 }; 368 369 370 // iterates over all the refs in a message 371 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 372 void* passThru = 0); 373 const entry_ref* EachEntryRef(const BMessage*, 374 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0); 375 376 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 377 void* passThru, int32 maxCount); 378 const entry_ref* EachEntryRef(const BMessage*, 379 const entry_ref* (*)(const entry_ref*, void*), void* passThru, 380 int32 maxCount); 381 382 383 bool ContainsEntryRef(const BMessage*, const entry_ref*); 384 int32 CountRefs(const BMessage*); 385 386 BMenuItem* EachMenuItem(BMenu* menu, bool recursive, 387 BMenuItem* (*func)(BMenuItem*)); 388 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive, 389 BMenuItem* (*func)(const BMenuItem*)); 390 391 int64 StringToScalar(const char* text); 392 // string to num, understands kB, MB, etc. 393 394 int32 ListIconSize(); 395 396 // misc calls 397 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume); 398 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message, 399 int32 index = 0); 400 void TruncateLeaf(BString* string); 401 402 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false); 403 void StringToStream(const BString*, BMallocIO*); 404 int32 ArchiveSize(const BString*); 405 406 extern int CompareLabels(const BMenuItem*, const BMenuItem*); 407 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on); 408 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on); 409 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 410 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 411 extern void DeleteSubmenu(BMenuItem* submenuItem); 412 413 extern bool BootedInSafeMode(); 414 415 416 void PrintToStream(rgb_color color); 417 418 template <class InitCheckable> 419 void 420 ThrowOnInitCheckError(InitCheckable* item) 421 { 422 if (item == NULL) 423 throw (status_t)B_ERROR; 424 425 status_t result = item->InitCheck(); 426 if (result != B_OK) 427 throw (status_t)result; 428 } 429 430 #if DEBUG 431 # define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__) 432 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__) 433 # define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__) 434 #else 435 # define ThrowOnError(x) _ThrowOnError(x, NULL, 0) 436 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0) 437 # define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0) 438 #endif 439 440 void _ThrowOnError(status_t, const char*, int32); 441 void _ThrowIfNotSize(ssize_t, const char*, int32); 442 void _ThrowOnAssert(bool, const char*, int32); 443 444 // stub calls that work around BAppFile info inefficiency 445 status_t GetAppSignatureFromAttr(BFile*, char*); 446 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which); 447 status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which); 448 449 // debugging 450 void HexDump(const void* buffer, int32 length); 451 452 #if xDEBUG 453 454 inline void 455 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 456 { 457 if (ref == NULL) { 458 PRINT(("NULL entry_ref%s", trailer)); 459 return; 460 } 461 462 BPath path; 463 BEntry entry(ref); 464 entry.GetPath(&path); 465 PRINT(("%s%s", path.Path(), trailer)); 466 } 467 468 469 inline void 470 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 471 { 472 if (entry == NULL) { 473 PRINT(("NULL entry%s", trailer)); 474 return; 475 } 476 477 BPath path; 478 entry->GetPath(&path); 479 PRINT(("%s%s", path.Path(), trailer)); 480 } 481 482 483 inline void 484 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 485 { 486 if (dir == NULL) { 487 PRINT(("NULL entry_ref%s", trailer)); 488 return; 489 } 490 491 BPath path; 492 BEntry entry; 493 dir->GetEntry(&entry); 494 entry.GetPath(&path); 495 PRINT(("%s%s", path.Path(), trailer)); 496 } 497 498 #else 499 500 inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 501 inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 502 inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 503 504 #endif 505 506 #ifdef xDEBUG 507 508 extern FILE* logFile; 509 510 inline void PrintToLogFile(const char* format, ...) 511 { 512 va_list ap; 513 va_start(ap, fmt); 514 vfprintf(logFile, fmt, ap); 515 va_end(ap); 516 } 517 518 #define WRITELOG(_ARGS_) \ 519 if (logFile == 0) \ 520 logFile = fopen("/var/log/tracker.log", "a+"); \ 521 \ 522 if (logFile != 0) { \ 523 thread_info info; \ 524 get_thread_info(find_thread(NULL), &info); \ 525 PrintToLogFile("[t %lld] \"%s\" (%s:%i) ", system_time(), \ 526 info.name, __FILE__, __LINE__); \ 527 PrintToLogFile _ARGS_; \ 528 PrintToLogFile("\n"); \ 529 fflush(logFile); \ 530 } 531 532 #else 533 534 #define WRITELOG(_ARGS_) 535 536 #endif 537 538 // fancy casting macros 539 540 template <typename NewType, typename OldType> 541 inline NewType assert_cast(OldType castedPointer) { 542 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 543 return static_cast<NewType>(castedPointer); 544 } 545 546 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that 547 // should fix up in ByteOrder.h 548 549 inline int32 SwapInt32(int32 value) 550 { return (int32)B_SWAP_INT32((uint32)value); } 551 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 552 inline int64 SwapInt64(int64 value) 553 { return (int64)B_SWAP_INT64((uint64)value); } 554 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 555 556 557 extern const float kExactMatchScore; 558 float ComputeTypeAheadScore(const char* text, const char* match, 559 bool wordMode = false); 560 561 562 inline float 563 ActualFontHeight(const BView* view) 564 { 565 font_height height; 566 view->GetFontHeight(&height); 567 return height.ascent + height.descent + 1; 568 } 569 570 } // namespace BPrivate 571 572 573 #endif // _UTILITIES_H 574