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 #ifdef __HAIKU__ 84 const color_space kDefaultIconDepth = B_RGBA32; 85 #else 86 const color_space kDefaultIconDepth = B_CMAP8; 87 #endif 88 89 90 extern bool gLocalizedNamePreferred; 91 92 93 // misc typedefs, constants and structs 94 95 class PeriodicUpdatePoses { 96 // Periodically updated poses (ones with a volume space bar) register 97 // themselfs in this global list. This way they can be iterated over instead 98 // of sending around update messages. 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 class PoseInfo { 127 // PoseInfo is the structure that gets saved as attributes for every node 128 // on disk, defining the node's position and visibility 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 136 // the inode of the items parent directory. This makes it 137 // impossible to for instance zip up files and extract them in 138 // the same location. This should probably be reworked. 139 // Tracker could strip the file location attributes when dropping 140 // files into a closed folder. 141 BPoint fLocation; 142 }; 143 144 145 class ExtendedPoseInfo { 146 // extends PoseInfo adding workspace support; used for desktop 147 // poses only 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 bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons); 190 uint32 HashString(const char* string, uint32 seed); 191 uint32 AttrHashString(const char* string, uint32 type); 192 193 194 class OffscreenBitmap { 195 // a utility class for setting up offscreen bitmaps 196 public: 197 OffscreenBitmap(BRect bounds); 198 OffscreenBitmap(); 199 ~OffscreenBitmap(); 200 201 BView* BeginUsing(BRect bounds); 202 void DoneUsing(); 203 BBitmap* Bitmap() const; 204 // blit this to your view when you are done rendering 205 BView* View() const; 206 // use this to render your image 207 208 private: 209 void NewBitmap(BRect frame); 210 BBitmap* fBitmap; 211 }; 212 213 214 // bitmap functions 215 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height, 216 int32 from, int32 to); 217 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height, 218 int32 from, int32 to); 219 220 221 class FlickerFreeStringView : public BStringView { 222 // adds support for offscreen bitmap drawing for string views that update 223 // often this would be better implemented as an option of BStringView 224 public: 225 FlickerFreeStringView(BRect bounds, const char* name, 226 const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 227 uint32 flags = B_WILL_DRAW); 228 FlickerFreeStringView(BRect bounds, const char* name, 229 const char* text, BBitmap* existingOffscreen, 230 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 231 uint32 flags = B_WILL_DRAW); 232 virtual ~FlickerFreeStringView(); 233 virtual void Draw(BRect); 234 virtual void AttachedToWindow(); 235 virtual void SetViewColor(rgb_color); 236 virtual void SetLowColor(rgb_color); 237 238 private: 239 OffscreenBitmap* fBitmap; 240 rgb_color fViewColor; 241 rgb_color fLowColor; 242 BBitmap* fOriginalBitmap; 243 244 typedef BStringView _inherited; 245 }; 246 247 248 class DraggableIcon : public BView { 249 // used to determine a save location for a file 250 public: 251 DraggableIcon(BRect rect, const char* name, const char* mimeType, 252 icon_size which, const BMessage* message, BMessenger target, 253 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 254 uint32 flags = B_WILL_DRAW); 255 virtual ~DraggableIcon(); 256 257 static BRect PreferredRect(BPoint offset, icon_size which); 258 void SetTarget(BMessenger); 259 260 protected: 261 virtual void AttachedToWindow(); 262 virtual void MouseDown(BPoint); 263 virtual void Draw(BRect); 264 265 virtual bool DragStarted(BMessage* dragMessage); 266 267 protected: 268 BBitmap* fBitmap; 269 BMessage fMessage; 270 BMessenger fTarget; 271 }; 272 273 274 class PositionPassingMenuItem : public BMenuItem { 275 public: 276 PositionPassingMenuItem(const char* title, BMessage*, 277 char shortcut = 0, uint32 modifiers = 0); 278 279 PositionPassingMenuItem(BMenu*, BMessage*); 280 281 protected: 282 virtual status_t Invoke(BMessage* = 0); 283 // appends the invoke location for NewFolder, etc. to use 284 285 private: 286 typedef BMenuItem _inherited; 287 }; 288 289 290 class Benaphore { 291 // aka benaphore 292 public: 293 Benaphore(const char* name = "Light Lock") 294 : fSemaphore(create_sem(0, name)), 295 fCount(1) 296 { 297 } 298 299 ~Benaphore() 300 { 301 delete_sem(fSemaphore); 302 } 303 304 bool Lock() 305 { 306 if (atomic_add(&fCount, -1) <= 0) 307 return acquire_sem(fSemaphore) == B_OK; 308 309 return true; 310 } 311 312 void Unlock() 313 { 314 if (atomic_add(&fCount, 1) < 0) 315 release_sem(fSemaphore); 316 } 317 318 bool IsLocked() const 319 { 320 return fCount <= 0; 321 } 322 323 private: 324 sem_id fSemaphore; 325 int32 fCount; 326 }; 327 328 329 class SeparatorLine : public BView { 330 public: 331 SeparatorLine(BPoint, float, bool vertical, const char* name = ""); 332 virtual void Draw(BRect bounds); 333 }; 334 335 336 class TitledSeparatorItem : public BMenuItem { 337 public: 338 TitledSeparatorItem(const char*); 339 virtual ~TitledSeparatorItem(); 340 341 virtual void SetEnabled(bool state); 342 343 protected: 344 virtual void GetContentSize(float* width, float* height); 345 virtual void Draw(); 346 347 private: 348 typedef BMenuItem _inherited; 349 }; 350 351 352 class LooperAutoLocker { 353 public: 354 LooperAutoLocker(BHandler* handler) 355 : fHandler(handler), 356 fHasLock(handler->LockLooper()) 357 { 358 } 359 360 ~LooperAutoLocker() 361 { 362 if (fHasLock) 363 fHandler->UnlockLooper(); 364 } 365 366 bool operator!() const 367 { 368 return !fHasLock; 369 } 370 371 bool IsLocked() const 372 { 373 return fHasLock; 374 } 375 376 private: 377 BHandler* fHandler; 378 bool fHasLock; 379 }; 380 381 382 class ShortcutFilter : public BMessageFilter { 383 public: 384 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier, 385 uint32 shortcutWhat, BHandler* target); 386 387 protected: 388 filter_result Filter(BMessage*, BHandler**); 389 390 private: 391 uint32 fShortcutKey; 392 uint32 fShortcutModifier; 393 uint32 fShortcutWhat; 394 BHandler* fTarget; 395 }; 396 397 398 // iterates over all the refs in a message 399 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 400 void* passThru = 0); 401 const entry_ref* EachEntryRef(const BMessage*, 402 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0); 403 404 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 405 void* passThru, int32 maxCount); 406 const entry_ref* EachEntryRef(const BMessage*, 407 const entry_ref* (*)(const entry_ref*, void*), void* passThru, 408 int32 maxCount); 409 410 411 bool ContainsEntryRef(const BMessage*, const entry_ref*); 412 int32 CountRefs(const BMessage*); 413 414 BMenuItem* EachMenuItem(BMenu* menu, bool recursive, 415 BMenuItem* (*func)(BMenuItem*)); 416 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive, 417 BMenuItem* (*func)(const BMenuItem*)); 418 419 int64 StringToScalar(const char* text); 420 // string to num, understands kB, MB, etc. 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 // Now is in kits 441 #if B_BEOS_VERSION <= B_BEOS_VERSION_MAUI && !defined(__HAIKU__) 442 443 // Should be in kits 444 bool operator==(const rgb_color&, const rgb_color&); 445 bool operator!=(const rgb_color&, const rgb_color&); 446 447 #endif 448 449 450 inline rgb_color 451 Color(int32 r, int32 g, int32 b, int32 alpha = 255) 452 { 453 rgb_color result; 454 result.red = (uchar)r; 455 result.green = (uchar)g; 456 result.blue = (uchar)b; 457 result.alpha = (uchar)alpha; 458 459 return result; 460 } 461 462 void PrintToStream(rgb_color color); 463 464 template <class InitCheckable> 465 void 466 ThrowOnInitCheckError(InitCheckable* item) 467 { 468 if (item == NULL) 469 throw (status_t)B_ERROR; 470 471 status_t result = item->InitCheck(); 472 if (result != B_OK) 473 throw (status_t)result; 474 } 475 476 #if DEBUG 477 # define ThrowOnError(result) _ThrowOnError(result, __FILE__, __LINE__) 478 # define ThrowIfNotSize(result) _ThrowIfNotSize(result, __FILE__, __LINE__) 479 # define ThrowOnErrorWithMessage(result, debugStr) \ 480 _ThrowOnError(result, debugStr, __FILE__, __LINE__) 481 #else 482 # define ThrowOnError(x) _ThrowOnError(x, 0, 0) 483 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, 0, 0) 484 # define ThrowOnErrorWithMessage(result, debugStr) \ 485 _ThrowOnError(result, debugStr, __FILE__, __LINE__) 486 #endif 487 488 void _ThrowOnError(status_t, const char*, int32); 489 void _ThrowIfNotSize(ssize_t, const char*, int32); 490 void _ThrowOnError(status_t, const char* debugStr, const char*, int32); 491 492 // stub calls that work around BAppFile info inefficiency 493 status_t GetAppSignatureFromAttr(BFile*, char*); 494 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which); 495 status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which); 496 497 // debugging 498 void HexDump(const void* buffer, int32 length); 499 500 #if xDEBUG 501 502 inline void 503 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 504 { 505 if (ref == NULL) { 506 PRINT(("NULL entry_ref%s", trailer)); 507 return; 508 } 509 510 BPath path; 511 BEntry entry(ref); 512 entry.GetPath(&path); 513 PRINT(("%s%s", path.Path(), trailer)); 514 } 515 516 517 inline void 518 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 519 { 520 if (entry == NULL) { 521 PRINT(("NULL entry%s", trailer)); 522 return; 523 } 524 525 BPath path; 526 entry->GetPath(&path); 527 PRINT(("%s%s", path.Path(), trailer)); 528 } 529 530 531 inline void 532 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 533 { 534 if (dir == NULL) { 535 PRINT(("NULL entry_ref%s", trailer)); 536 return; 537 } 538 539 BPath path; 540 BEntry entry; 541 dir->GetEntry(&entry); 542 entry.GetPath(&path); 543 PRINT(("%s%s", path.Path(), trailer)); 544 } 545 546 #else 547 548 inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 549 inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 550 inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 551 552 #endif 553 554 #ifdef xDEBUG 555 556 extern FILE* logFile; 557 558 inline void PrintToLogFile(const char* format, ...) 559 { 560 va_list ap; 561 va_start(ap, fmt); 562 vfprintf(logFile, fmt, ap); 563 va_end(ap); 564 } 565 566 #define WRITELOG(_ARGS_) \ 567 if (logFile == 0) \ 568 logFile = fopen("/var/log/tracker.log", "a+"); \ 569 \ 570 if (logFile != 0) { \ 571 thread_info info; \ 572 get_thread_info(find_thread(NULL), &info); \ 573 PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(), \ 574 info.name, __FILE__, __LINE__); \ 575 PrintToLogFile _ARGS_; \ 576 PrintToLogFile("\n"); \ 577 fflush(logFile); \ 578 } 579 580 #else 581 582 #define WRITELOG(_ARGS_) 583 584 #endif 585 586 // fancy casting macros 587 588 template <typename NewType, typename OldType> 589 inline NewType assert_cast(OldType castedPointer) { 590 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 591 return static_cast<NewType>(castedPointer); 592 } 593 594 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that 595 // should fix up in ByteOrder.h 596 597 inline int32 SwapInt32(int32 value) 598 { return (int32)B_SWAP_INT32((uint32)value); } 599 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 600 inline int64 SwapInt64(int64 value) 601 { return (int64)B_SWAP_INT64((uint64)value); } 602 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 603 604 605 extern const float kExactMatchScore; 606 float ComputeTypeAheadScore(const char* text, const char* match, 607 bool wordMode = false); 608 609 } // namespace BPrivate 610 611 612 #endif // _UTILITIES_H 613