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