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