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 <ByteOrder.h> 43 #include <Bitmap.h> 44 #include <DataIO.h> 45 #include <Directory.h> 46 #include <Entry.h> 47 #include <Font.h> 48 #include <GraphicsDefs.h> 49 #include <Looper.h> 50 #include <MenuItem.h> 51 #include <MessageFilter.h> 52 #include <Mime.h> 53 #include <NaturalCompare.h> 54 #include <ObjectList.h> 55 #include <Point.h> 56 #include <Path.h> 57 #include <String.h> 58 #include <StringView.h> 59 60 61 class BMessage; 62 class BVolume; 63 class BBitmap; 64 class BTextView; 65 class BView; 66 67 namespace BPrivate { 68 69 class Benaphore; 70 class BPose; 71 class BPoseView; 72 73 // global variables 74 static const rgb_color kBlack = {0, 0, 0, 255}; 75 static const rgb_color kWhite = {255, 255, 255 ,255}; 76 77 const int64 kHalfKBSize = 512; 78 const int64 kKBSize = 1024; 79 const int64 kMBSize = 1048576; 80 const int64 kGBSize = 1073741824; 81 const int64 kTBSize = kGBSize * kKBSize; 82 83 const int32 kMiniIconSeparator = 3; 84 85 #ifdef __HAIKU__ 86 const color_space kDefaultIconDepth = B_RGBA32; 87 #else 88 const color_space kDefaultIconDepth = B_CMAP8; 89 #endif 90 91 92 extern bool gLocalizedNamePreferred; 93 94 95 // misc typedefs, constants and structs 96 97 // Periodically updated poses (ones with a volume space bar) register 98 // themselfs in this global list. This way they can be iterated over instead 99 // of sending around update messages. 100 101 class PeriodicUpdatePoses { 102 public: 103 PeriodicUpdatePoses(); 104 ~PeriodicUpdatePoses(); 105 106 typedef bool (*PeriodicUpdateCallback)(BPose* pose, void* cookie); 107 108 void AddPose(BPose* pose, BPoseView* poseView, 109 PeriodicUpdateCallback callback, void* cookie); 110 bool RemovePose(BPose* pose, void** cookie); 111 112 void DoPeriodicUpdate(bool forceRedraw); 113 114 private: 115 struct periodic_pose { 116 BPose* pose; 117 BPoseView* pose_view; 118 PeriodicUpdateCallback callback; 119 void* cookie; 120 }; 121 122 Benaphore* fLock; 123 BObjectList<periodic_pose> fPoseList; 124 }; 125 126 extern PeriodicUpdatePoses gPeriodicUpdatePoses; 127 128 129 // PoseInfo is the structure that gets saved as attributes for every node on 130 // disk, defining the node's position and visibility 131 class PoseInfo { 132 public: 133 static void EndianSwap(void* castToThis); 134 void PrintToStream(); 135 136 bool fInvisible; 137 ino_t fInitedDirectory; 138 // For a location to be valid, fInitedDirectory has to contain 139 // the inode of the items parent directory. This makes it 140 // impossible to for instance zip up files and extract them in 141 // the same location. This should probably be reworked. 142 // Tracker could strip the file location attributes when dropping 143 // files into a closed folder. 144 BPoint fLocation; 145 }; 146 147 148 // extends PoseInfo adding workspace support; used for desktop 149 // poses only 150 class ExtendedPoseInfo { 151 public: 152 size_t Size() const; 153 static size_t Size(int32); 154 size_t SizeWithHeadroom() const; 155 static size_t SizeWithHeadroom(size_t); 156 bool HasLocationForFrame(BRect) const; 157 BPoint LocationForFrame(BRect) const; 158 bool SetLocationForFrame(BPoint, BRect); 159 160 static void EndianSwap(void* castToThis); 161 void PrintToStream(); 162 163 uint32 fWorkspaces; 164 bool fInvisible; 165 bool fShowFromBootOnly; 166 bool fReservedBool1; 167 bool fReservedBool2; 168 int32 fReservedInt1; 169 int32 fReservedInt2; 170 int32 fReservedInt3; 171 int32 fReservedInt4; 172 int32 fReservedInt5; 173 174 int32 fNumFrames; 175 struct FrameLocation { 176 BPoint fLocation; 177 BRect fFrame; 178 uint32 fWorkspaces; 179 }; 180 181 FrameLocation fLocations[0]; 182 }; 183 184 // misc functions 185 void DisallowMetaKeys(BTextView*); 186 void DisallowFilenameKeys(BTextView*); 187 188 189 bool ValidateStream(BMallocIO*, uint32, int32 version); 190 191 192 uint32 HashString(const char* string, uint32 seed); 193 uint32 AttrHashString(const char* string, uint32 type); 194 195 196 class OffscreenBitmap { 197 // a utility class for setting up offscreen bitmaps 198 public: 199 OffscreenBitmap(BRect bounds); 200 OffscreenBitmap(); 201 ~OffscreenBitmap(); 202 203 BView* BeginUsing(BRect bounds); 204 void DoneUsing(); 205 BBitmap* Bitmap() const; 206 // blit this to your view when you are done rendering 207 BView* View() const; 208 // use this to render your image 209 210 private: 211 void NewBitmap(BRect frame); 212 BBitmap* fBitmap; 213 }; 214 215 216 // bitmap functions 217 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height, 218 int32 from, int32 to); 219 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height, 220 int32 from, int32 to); 221 222 223 class FlickerFreeStringView : public BStringView { 224 // adds support for offscreen bitmap drawing for string views that update 225 // often this would be better implemented as an option of BStringView 226 public: 227 FlickerFreeStringView(BRect bounds, const char* name, 228 const char* text, uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP, 229 uint32 flags = B_WILL_DRAW); 230 FlickerFreeStringView(BRect bounds, const char* name, 231 const char* text, BBitmap* existingOffscreen, 232 uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP, 233 uint32 flags = B_WILL_DRAW); 234 virtual ~FlickerFreeStringView(); 235 virtual void Draw(BRect); 236 virtual void AttachedToWindow(); 237 virtual void SetViewColor(rgb_color); 238 virtual void SetLowColor(rgb_color); 239 240 private: 241 OffscreenBitmap* fBitmap; 242 rgb_color fViewColor; 243 rgb_color fLowColor; 244 BBitmap* fOrigBitmap; 245 246 typedef BStringView _inherited; 247 }; 248 249 250 class DraggableIcon : public BView { 251 // used to determine a save location for a file 252 public: 253 DraggableIcon(BRect, const char*, const char* mimeType, icon_size, 254 const BMessage*, BMessenger, 255 uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP, 256 uint32 flags = B_WILL_DRAW); 257 virtual ~DraggableIcon(); 258 259 static BRect PreferredRect(BPoint offset, icon_size); 260 void SetTarget(BMessenger); 261 262 protected: 263 virtual void AttachedToWindow(); 264 virtual void MouseDown(BPoint); 265 virtual void Draw(BRect); 266 267 virtual bool DragStarted(BMessage* dragMessage); 268 269 protected: 270 BBitmap* fBitmap; 271 BMessage fMessage; 272 BMessenger fTarget; 273 }; 274 275 276 class PositionPassingMenuItem : public BMenuItem { 277 public: 278 PositionPassingMenuItem(const char* title, BMessage*, 279 char shortcut = 0, uint32 modifiers = 0); 280 281 PositionPassingMenuItem(BMenu*, BMessage*); 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 LooperAutoLocker { 355 public: 356 LooperAutoLocker(BHandler* handler) 357 : fHandler(handler), 358 fHasLock(handler->LockLooper()) 359 { 360 } 361 362 ~LooperAutoLocker() 363 { 364 if (fHasLock) 365 fHandler->UnlockLooper(); 366 } 367 368 bool operator!() const 369 { 370 return !fHasLock; 371 } 372 373 bool IsLocked() const 374 { 375 return fHasLock; 376 } 377 378 private: 379 BHandler* fHandler; 380 bool fHasLock; 381 }; 382 383 384 class MessengerAutoLocker { 385 // move this into AutoLock.h 386 public: 387 MessengerAutoLocker(BMessenger* messenger) 388 : fMessenger(messenger), 389 fHasLock(messenger->LockTarget()) 390 {} 391 392 ~MessengerAutoLocker() 393 { 394 Unlock(); 395 } 396 397 bool operator!() const 398 { 399 return !fHasLock; 400 } 401 402 bool IsLocked() const 403 { 404 return fHasLock; 405 } 406 407 void Unlock() 408 { 409 if (fHasLock) { 410 BLooper* looper; 411 fMessenger->Target(&looper); 412 if (looper) 413 looper->Unlock(); 414 fHasLock = false; 415 } 416 } 417 418 private: 419 BMessenger* fMessenger; 420 bool fHasLock; 421 }; 422 423 424 class ShortcutFilter : public BMessageFilter { 425 public: 426 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier, 427 uint32 shortcutWhat, BHandler* target); 428 429 protected: 430 filter_result Filter(BMessage*, BHandler**); 431 432 private: 433 uint32 fShortcutKey; 434 uint32 fShortcutModifier; 435 uint32 fShortcutWhat; 436 BHandler* fTarget; 437 }; 438 439 // iterates over all the refs in a message 440 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 441 void* passThru = 0); 442 const entry_ref* EachEntryRef(const BMessage*, 443 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0); 444 445 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 446 void* passThru, int32 maxCount); 447 const entry_ref* EachEntryRef(const BMessage*, 448 const entry_ref* (*)(const entry_ref*, void*), void* passThru, 449 int32 maxCount); 450 451 452 bool ContainsEntryRef(const BMessage*, const entry_ref*); 453 int32 CountRefs(const BMessage*); 454 455 BMenuItem* EachMenuItem(BMenu* menu, bool recursive, 456 BMenuItem* (*func)(BMenuItem*)); 457 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive, 458 BMenuItem* (*func)(const BMenuItem*)); 459 460 int64 StringToScalar(const char* text); 461 // string to num, understands kB, MB, etc. 462 463 // misc calls 464 void EmbedUniqueVolumeInfo(BMessage*, const BVolume*); 465 status_t MatchArchivedVolume(BVolume*, const BMessage*, int32 index = 0); 466 void TruncateLeaf(BString* string); 467 468 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false); 469 void StringToStream(const BString*, BMallocIO*); 470 int32 ArchiveSize(const BString*); 471 472 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on); 473 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on); 474 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 475 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 476 extern void DeleteSubmenu(BMenuItem* submenuItem); 477 478 extern bool BootedInSafeMode(); 479 480 // Now is in kits 481 #if B_BEOS_VERSION <= B_BEOS_VERSION_MAUI && !defined(__HAIKU__) 482 483 // Should be in kits 484 bool operator==(const rgb_color&, const rgb_color&); 485 bool operator!=(const rgb_color&, const rgb_color&); 486 487 #endif 488 489 inline rgb_color 490 Color(int32 r, int32 g, int32 b, int32 alpha = 255) 491 { 492 rgb_color result; 493 result.red = (uchar)r; 494 result.green = (uchar)g; 495 result.blue = (uchar)b; 496 result.alpha = (uchar)alpha; 497 498 return result; 499 } 500 501 void PrintToStream(rgb_color color); 502 503 template <class InitCheckable> 504 void 505 ThrowOnInitCheckError(InitCheckable* item) 506 { 507 if (!item) 508 throw (status_t)B_ERROR; 509 510 status_t error = item->InitCheck(); 511 if (error != B_OK) 512 throw (status_t)error; 513 } 514 515 #if DEBUG 516 #define ThrowOnError(error) _ThrowOnError(error, __FILE__, __LINE__) 517 #define ThrowIfNotSize(error) _ThrowIfNotSize(error, __FILE__, __LINE__) 518 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__) 519 #else 520 #define ThrowOnError(x) _ThrowOnError(x, 0, 0) 521 #define ThrowIfNotSize(x) _ThrowIfNotSize(x, 0, 0) 522 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__) 523 #endif 524 525 void _ThrowOnError(status_t, const char*, int32); 526 void _ThrowIfNotSize(ssize_t, const char*, int32); 527 void _ThrowOnError(status_t, const char* debugStr, const char*, int32); 528 529 // stub calls that work around BAppFile info inefficiency 530 status_t GetAppSignatureFromAttr(BFile*, char*); 531 status_t GetAppIconFromAttr(BFile*, BBitmap*, icon_size); 532 status_t GetFileIconFromAttr(BNode*, BBitmap*, icon_size); 533 534 // debugging 535 void HexDump(const void* buffer, int32 length); 536 537 #if xDEBUG 538 539 inline void 540 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 541 { 542 if (ref == NULL) { 543 PRINT(("NULL entry_ref%s", trailer)); 544 return; 545 } 546 547 BPath path; 548 BEntry entry(ref); 549 entry.GetPath(&path); 550 PRINT(("%s%s", path.Path(), trailer)); 551 } 552 553 554 inline void 555 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 556 { 557 if (entry == NULL) { 558 PRINT(("NULL entry%s", trailer)); 559 return; 560 } 561 562 BPath path; 563 entry->GetPath(&path); 564 PRINT(("%s%s", path.Path(), trailer)); 565 } 566 567 568 inline void 569 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 570 { 571 if (dir == NULL) { 572 PRINT(("NULL entry_ref%s", trailer)); 573 return; 574 } 575 576 BPath path; 577 BEntry entry; 578 dir->GetEntry(&entry); 579 entry.GetPath(&path); 580 PRINT(("%s%s", path.Path(), trailer)); 581 } 582 583 #else 584 585 inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 586 inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 587 inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 588 589 #endif 590 591 #ifdef xDEBUG 592 593 extern FILE* logFile; 594 595 inline void PrintToLogFile(const char* format, ...) 596 { 597 va_list ap; 598 va_start(ap, fmt); 599 vfprintf(logFile, fmt, ap); 600 va_end(ap); 601 } 602 603 #define WRITELOG(_ARGS_) \ 604 if (logFile == 0) \ 605 logFile = fopen("/var/log/tracker.log", "a+"); \ 606 if (logFile != 0) { \ 607 thread_info info; \ 608 get_thread_info(find_thread(NULL), &info); \ 609 PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(), \ 610 info.name, __FILE__, __LINE__); \ 611 PrintToLogFile _ARGS_; \ 612 PrintToLogFile("\n"); \ 613 fflush(logFile); \ 614 } 615 616 #else 617 618 #define WRITELOG(_ARGS_) 619 620 #endif 621 622 // fancy casting macros 623 624 template <typename NewType, typename OldType> 625 inline NewType assert_cast(OldType castedPointer) { 626 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 627 return static_cast<NewType>(castedPointer); 628 } 629 630 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that 631 // should fix up in ByteOrder.h 632 633 inline int32 SwapInt32(int32 value) 634 { return (int32)B_SWAP_INT32((uint32)value); } 635 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 636 inline int64 SwapInt64(int64 value) 637 { return (int64)B_SWAP_INT64((uint64)value); } 638 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 639 640 641 extern const float kExactMatchScore; 642 float ComputeTypeAheadScore(const char* text, const char* match, 643 bool wordMode = false); 644 645 } // namespace BPrivate 646 647 #endif // _UTILITIES_H 648