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