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