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