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 = {0, 0, 0, 255}; 74 static const rgb_color kWhite = {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 183 bool ValidateStream(BMallocIO*, uint32, int32 version); 184 185 186 bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons); 187 uint32 HashString(const char* string, uint32 seed); 188 uint32 AttrHashString(const char* string, uint32 type); 189 190 191 class OffscreenBitmap { 192 // a utility class for setting up offscreen bitmaps 193 public: 194 OffscreenBitmap(BRect bounds); 195 OffscreenBitmap(); 196 ~OffscreenBitmap(); 197 198 BView* BeginUsing(BRect bounds); 199 void DoneUsing(); 200 BBitmap* Bitmap() const; 201 // blit this to your view when you are done rendering 202 BView* View() const; 203 // use this to render your image 204 205 private: 206 void NewBitmap(BRect frame); 207 BBitmap* fBitmap; 208 }; 209 210 211 // bitmap functions 212 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height, 213 int32 from, int32 to); 214 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height, 215 int32 from, int32 to); 216 217 218 class FlickerFreeStringView : public BStringView { 219 // adds support for offscreen bitmap drawing for string views that update 220 // often this would be better implemented as an option of BStringView 221 public: 222 FlickerFreeStringView(BRect bounds, const char* name, 223 const char* text, uint32 resizingMode = 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 resizingMode = 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* fOriginalBitmap; 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 rect, const char* name, const char* mimeType, 249 icon_size which, const BMessage* message, BMessenger target, 250 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 251 uint32 flags = B_WILL_DRAW); 252 virtual ~DraggableIcon(); 253 254 static BRect PreferredRect(BPoint offset, icon_size which); 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*, 274 char shortcut = 0, uint32 modifiers = 0); 275 PositionPassingMenuItem(BMenu*, BMessage*); 276 PositionPassingMenuItem(BMessage* data); 277 278 static BArchivable* Instantiate(BMessage* data); 279 280 protected: 281 virtual status_t Invoke(BMessage* = 0); 282 // appends the invoke location for NewFolder, etc. to use 283 284 private: 285 typedef BMenuItem _inherited; 286 }; 287 288 289 class Benaphore { 290 // aka benaphore 291 public: 292 Benaphore(const char* name = "Light Lock") 293 : fSemaphore(create_sem(0, name)), 294 fCount(1) 295 { 296 } 297 298 ~Benaphore() 299 { 300 delete_sem(fSemaphore); 301 } 302 303 bool Lock() 304 { 305 if (atomic_add(&fCount, -1) <= 0) 306 return acquire_sem(fSemaphore) == B_OK; 307 308 return true; 309 } 310 311 void Unlock() 312 { 313 if (atomic_add(&fCount, 1) < 0) 314 release_sem(fSemaphore); 315 } 316 317 bool IsLocked() const 318 { 319 return fCount <= 0; 320 } 321 322 private: 323 sem_id fSemaphore; 324 int32 fCount; 325 }; 326 327 328 class SeparatorLine : public BView { 329 public: 330 SeparatorLine(BPoint, float, bool vertical, const char* name = ""); 331 virtual void Draw(BRect bounds); 332 }; 333 334 335 class TitledSeparatorItem : public BMenuItem { 336 public: 337 TitledSeparatorItem(const char*); 338 virtual ~TitledSeparatorItem(); 339 340 virtual void SetEnabled(bool state); 341 342 protected: 343 virtual void GetContentSize(float* width, float* height); 344 virtual void Draw(); 345 346 private: 347 typedef BMenuItem _inherited; 348 }; 349 350 351 class LooperAutoLocker { 352 public: 353 LooperAutoLocker(BHandler* handler) 354 : fHandler(handler), 355 fHasLock(handler->LockLooper()) 356 { 357 } 358 359 ~LooperAutoLocker() 360 { 361 if (fHasLock) 362 fHandler->UnlockLooper(); 363 } 364 365 bool operator!() const 366 { 367 return !fHasLock; 368 } 369 370 bool IsLocked() const 371 { 372 return fHasLock; 373 } 374 375 private: 376 BHandler* fHandler; 377 bool fHasLock; 378 }; 379 380 381 class ShortcutFilter : public BMessageFilter { 382 public: 383 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier, 384 uint32 shortcutWhat, BHandler* target); 385 386 protected: 387 filter_result Filter(BMessage*, BHandler**); 388 389 private: 390 uint32 fShortcutKey; 391 uint32 fShortcutModifier; 392 uint32 fShortcutWhat; 393 BHandler* fTarget; 394 }; 395 396 397 // iterates over all the refs in a message 398 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 399 void* passThru = 0); 400 const entry_ref* EachEntryRef(const BMessage*, 401 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0); 402 403 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 404 void* passThru, int32 maxCount); 405 const entry_ref* EachEntryRef(const BMessage*, 406 const entry_ref* (*)(const entry_ref*, void*), void* passThru, 407 int32 maxCount); 408 409 410 bool ContainsEntryRef(const BMessage*, const entry_ref*); 411 int32 CountRefs(const BMessage*); 412 413 BMenuItem* EachMenuItem(BMenu* menu, bool recursive, 414 BMenuItem* (*func)(BMenuItem*)); 415 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive, 416 BMenuItem* (*func)(const BMenuItem*)); 417 418 int64 StringToScalar(const char* text); 419 // string to num, understands kB, MB, etc. 420 421 int32 ListIconSize(); 422 423 // misc calls 424 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume); 425 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message, 426 int32 index = 0); 427 void TruncateLeaf(BString* string); 428 429 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false); 430 void StringToStream(const BString*, BMallocIO*); 431 int32 ArchiveSize(const BString*); 432 433 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on); 434 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on); 435 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 436 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 437 extern void DeleteSubmenu(BMenuItem* submenuItem); 438 439 extern bool BootedInSafeMode(); 440 441 442 inline rgb_color 443 Color(int32 r, int32 g, int32 b, int32 alpha = 255) 444 { 445 rgb_color result; 446 result.red = (uchar)r; 447 result.green = (uchar)g; 448 result.blue = (uchar)b; 449 result.alpha = (uchar)alpha; 450 451 return result; 452 } 453 454 void PrintToStream(rgb_color color); 455 456 template <class InitCheckable> 457 void 458 ThrowOnInitCheckError(InitCheckable* item) 459 { 460 if (item == NULL) 461 throw (status_t)B_ERROR; 462 463 status_t result = item->InitCheck(); 464 if (result != B_OK) 465 throw (status_t)result; 466 } 467 468 #if DEBUG 469 # define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__) 470 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__) 471 # define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__) 472 #else 473 # define ThrowOnError(x) _ThrowOnError(x, NULL, 0) 474 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0) 475 # define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0) 476 #endif 477 478 void _ThrowOnError(status_t, const char*, int32); 479 void _ThrowIfNotSize(ssize_t, const char*, int32); 480 void _ThrowOnAssert(bool, const char*, int32); 481 482 // stub calls that work around BAppFile info inefficiency 483 status_t GetAppSignatureFromAttr(BFile*, char*); 484 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which); 485 status_t GetFileIconFromAttr(Model* model, BBitmap* icon, icon_size which); 486 status_t GetThumbnailIcon(Model* model, BBitmap* icon, icon_size which); 487 488 // debugging 489 void HexDump(const void* buffer, int32 length); 490 491 #if xDEBUG 492 493 inline void 494 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 495 { 496 if (ref == NULL) { 497 PRINT(("NULL entry_ref%s", trailer)); 498 return; 499 } 500 501 BPath path; 502 BEntry entry(ref); 503 entry.GetPath(&path); 504 PRINT(("%s%s", path.Path(), trailer)); 505 } 506 507 508 inline void 509 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 510 { 511 if (entry == NULL) { 512 PRINT(("NULL entry%s", trailer)); 513 return; 514 } 515 516 BPath path; 517 entry->GetPath(&path); 518 PRINT(("%s%s", path.Path(), trailer)); 519 } 520 521 522 inline void 523 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 524 { 525 if (dir == NULL) { 526 PRINT(("NULL entry_ref%s", trailer)); 527 return; 528 } 529 530 BPath path; 531 BEntry entry; 532 dir->GetEntry(&entry); 533 entry.GetPath(&path); 534 PRINT(("%s%s", path.Path(), trailer)); 535 } 536 537 #else 538 539 inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 540 inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 541 inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 542 543 #endif 544 545 #ifdef xDEBUG 546 547 extern FILE* logFile; 548 549 inline void PrintToLogFile(const char* format, ...) 550 { 551 va_list ap; 552 va_start(ap, fmt); 553 vfprintf(logFile, fmt, ap); 554 va_end(ap); 555 } 556 557 #define WRITELOG(_ARGS_) \ 558 if (logFile == 0) \ 559 logFile = fopen("/var/log/tracker.log", "a+"); \ 560 \ 561 if (logFile != 0) { \ 562 thread_info info; \ 563 get_thread_info(find_thread(NULL), &info); \ 564 PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(), \ 565 info.name, __FILE__, __LINE__); \ 566 PrintToLogFile _ARGS_; \ 567 PrintToLogFile("\n"); \ 568 fflush(logFile); \ 569 } 570 571 #else 572 573 #define WRITELOG(_ARGS_) 574 575 #endif 576 577 // fancy casting macros 578 579 template <typename NewType, typename OldType> 580 inline NewType assert_cast(OldType castedPointer) { 581 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 582 return static_cast<NewType>(castedPointer); 583 } 584 585 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that 586 // should fix up in ByteOrder.h 587 588 inline int32 SwapInt32(int32 value) 589 { return (int32)B_SWAP_INT32((uint32)value); } 590 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 591 inline int64 SwapInt64(int64 value) 592 { return (int64)B_SWAP_INT64((uint64)value); } 593 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 594 595 596 extern const float kExactMatchScore; 597 float ComputeTypeAheadScore(const char* text, const char* match, 598 bool wordMode = false); 599 600 } // namespace BPrivate 601 602 603 #endif // _UTILITIES_H 604