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 // Periodically updated poses (ones with a volume space bar) register 98 // themselfs in this global list. This way they can be iterated over instead 99 // of sending around update messages. 100 101 class PeriodicUpdatePoses { 102 public: 103 PeriodicUpdatePoses(); 104 ~PeriodicUpdatePoses(); 105 106 typedef bool (*PeriodicUpdateCallback)(BPose* pose, void* cookie); 107 108 void AddPose(BPose* pose, BPoseView* poseView, 109 PeriodicUpdateCallback callback, void* cookie); 110 bool RemovePose(BPose* pose, void** cookie); 111 112 void DoPeriodicUpdate(bool forceRedraw); 113 114 private: 115 struct periodic_pose { 116 BPose* pose; 117 BPoseView* pose_view; 118 PeriodicUpdateCallback callback; 119 void* cookie; 120 }; 121 122 Benaphore* fLock; 123 BObjectList<periodic_pose> fPoseList; 124 }; 125 126 extern PeriodicUpdatePoses gPeriodicUpdatePoses; 127 128 129 // PoseInfo is the structure that gets saved as attributes for every node on 130 // disk, defining the node's position and visibility 131 class PoseInfo { 132 public: 133 static void EndianSwap(void* castToThis); 134 void PrintToStream(); 135 136 bool fInvisible; 137 ino_t fInitedDirectory; 138 // For a location to be valid, fInitedDirectory has to contain 139 // the inode of the items parent directory. This makes it 140 // impossible to for instance zip up files and extract them in 141 // the same location. This should probably be reworked. 142 // Tracker could strip the file location attributes when dropping 143 // files into a closed folder. 144 BPoint fLocation; 145 }; 146 147 148 // extends PoseInfo adding workspace support; used for desktop 149 // poses only 150 class ExtendedPoseInfo { 151 public: 152 size_t Size() const; 153 static size_t Size(int32); 154 size_t SizeWithHeadroom() const; 155 static size_t SizeWithHeadroom(size_t); 156 bool HasLocationForFrame(BRect) const; 157 BPoint LocationForFrame(BRect) const; 158 bool SetLocationForFrame(BPoint, BRect); 159 160 static void EndianSwap(void* castToThis); 161 void PrintToStream(); 162 163 uint32 fWorkspaces; 164 bool fInvisible; 165 bool fShowFromBootOnly; 166 bool fReservedBool1; 167 bool fReservedBool2; 168 int32 fReservedInt1; 169 int32 fReservedInt2; 170 int32 fReservedInt3; 171 int32 fReservedInt4; 172 int32 fReservedInt5; 173 174 int32 fNumFrames; 175 struct FrameLocation { 176 BPoint fLocation; 177 BRect fFrame; 178 uint32 fWorkspaces; 179 }; 180 181 FrameLocation fLocations[0]; 182 }; 183 184 // misc functions 185 void DisallowMetaKeys(BTextView*); 186 void DisallowFilenameKeys(BTextView*); 187 188 189 bool ValidateStream(BMallocIO*, uint32, int32 version); 190 191 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 // iterates over all the refs in a message 400 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 401 void* passThru = 0); 402 const entry_ref* EachEntryRef(const BMessage*, 403 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0); 404 405 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 406 void* passThru, int32 maxCount); 407 const entry_ref* EachEntryRef(const BMessage*, 408 const entry_ref* (*)(const entry_ref*, void*), void* passThru, 409 int32 maxCount); 410 411 412 bool ContainsEntryRef(const BMessage*, const entry_ref*); 413 int32 CountRefs(const BMessage*); 414 415 BMenuItem* EachMenuItem(BMenu* menu, bool recursive, 416 BMenuItem* (*func)(BMenuItem*)); 417 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive, 418 BMenuItem* (*func)(const BMenuItem*)); 419 420 int64 StringToScalar(const char* text); 421 // string to num, understands kB, MB, etc. 422 423 // misc calls 424 void EmbedUniqueVolumeInfo(BMessage*, const BVolume*); 425 status_t MatchArchivedVolume(BVolume*, const BMessage*, 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 inline rgb_color 450 Color(int32 r, int32 g, int32 b, int32 alpha = 255) 451 { 452 rgb_color result; 453 result.red = (uchar)r; 454 result.green = (uchar)g; 455 result.blue = (uchar)b; 456 result.alpha = (uchar)alpha; 457 458 return result; 459 } 460 461 void PrintToStream(rgb_color color); 462 463 template <class InitCheckable> 464 void 465 ThrowOnInitCheckError(InitCheckable* item) 466 { 467 if (!item) 468 throw (status_t)B_ERROR; 469 470 status_t error = item->InitCheck(); 471 if (error != B_OK) 472 throw (status_t)error; 473 } 474 475 #if DEBUG 476 #define ThrowOnError(error) _ThrowOnError(error, __FILE__, __LINE__) 477 #define ThrowIfNotSize(error) _ThrowIfNotSize(error, __FILE__, __LINE__) 478 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__) 479 #else 480 #define ThrowOnError(x) _ThrowOnError(x, 0, 0) 481 #define ThrowIfNotSize(x) _ThrowIfNotSize(x, 0, 0) 482 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__) 483 #endif 484 485 void _ThrowOnError(status_t, const char*, int32); 486 void _ThrowIfNotSize(ssize_t, const char*, int32); 487 void _ThrowOnError(status_t, const char* debugStr, const char*, int32); 488 489 // stub calls that work around BAppFile info inefficiency 490 status_t GetAppSignatureFromAttr(BFile*, char*); 491 status_t GetAppIconFromAttr(BFile*, BBitmap*, icon_size); 492 status_t GetFileIconFromAttr(BNode*, BBitmap*, icon_size); 493 494 // debugging 495 void HexDump(const void* buffer, int32 length); 496 497 #if xDEBUG 498 499 inline void 500 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 501 { 502 if (ref == NULL) { 503 PRINT(("NULL entry_ref%s", trailer)); 504 return; 505 } 506 507 BPath path; 508 BEntry entry(ref); 509 entry.GetPath(&path); 510 PRINT(("%s%s", path.Path(), trailer)); 511 } 512 513 514 inline void 515 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 516 { 517 if (entry == NULL) { 518 PRINT(("NULL entry%s", trailer)); 519 return; 520 } 521 522 BPath path; 523 entry->GetPath(&path); 524 PRINT(("%s%s", path.Path(), trailer)); 525 } 526 527 528 inline void 529 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 530 { 531 if (dir == NULL) { 532 PRINT(("NULL entry_ref%s", trailer)); 533 return; 534 } 535 536 BPath path; 537 BEntry entry; 538 dir->GetEntry(&entry); 539 entry.GetPath(&path); 540 PRINT(("%s%s", path.Path(), trailer)); 541 } 542 543 #else 544 545 inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 546 inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 547 inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 548 549 #endif 550 551 #ifdef xDEBUG 552 553 extern FILE* logFile; 554 555 inline void PrintToLogFile(const char* format, ...) 556 { 557 va_list ap; 558 va_start(ap, fmt); 559 vfprintf(logFile, fmt, ap); 560 va_end(ap); 561 } 562 563 #define WRITELOG(_ARGS_) \ 564 if (logFile == 0) \ 565 logFile = fopen("/var/log/tracker.log", "a+"); \ 566 if (logFile != 0) { \ 567 thread_info info; \ 568 get_thread_info(find_thread(NULL), &info); \ 569 PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(), \ 570 info.name, __FILE__, __LINE__); \ 571 PrintToLogFile _ARGS_; \ 572 PrintToLogFile("\n"); \ 573 fflush(logFile); \ 574 } 575 576 #else 577 578 #define WRITELOG(_ARGS_) 579 580 #endif 581 582 // fancy casting macros 583 584 template <typename NewType, typename OldType> 585 inline NewType assert_cast(OldType castedPointer) { 586 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 587 return static_cast<NewType>(castedPointer); 588 } 589 590 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that 591 // should fix up in ByteOrder.h 592 593 inline int32 SwapInt32(int32 value) 594 { return (int32)B_SWAP_INT32((uint32)value); } 595 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 596 inline int64 SwapInt64(int64 value) 597 { return (int64)B_SWAP_INT64((uint64)value); } 598 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 599 600 601 extern const float kExactMatchScore; 602 float ComputeTypeAheadScore(const char* text, const char* match, 603 bool wordMode = false); 604 605 } // namespace BPrivate 606 607 #endif // _UTILITIES_H 608