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 bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons); 193 uint32 HashString(const char* string, uint32 seed); 194 uint32 AttrHashString(const char* string, uint32 type); 195 196 197 class OffscreenBitmap { 198 // a utility class for setting up offscreen bitmaps 199 public: 200 OffscreenBitmap(BRect bounds); 201 OffscreenBitmap(); 202 ~OffscreenBitmap(); 203 204 BView* BeginUsing(BRect bounds); 205 void DoneUsing(); 206 BBitmap* Bitmap() const; 207 // blit this to your view when you are done rendering 208 BView* View() const; 209 // use this to render your image 210 211 private: 212 void NewBitmap(BRect frame); 213 BBitmap* fBitmap; 214 }; 215 216 217 // bitmap functions 218 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height, 219 int32 from, int32 to); 220 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height, 221 int32 from, int32 to); 222 223 224 class FlickerFreeStringView : public BStringView { 225 // adds support for offscreen bitmap drawing for string views that update 226 // often this would be better implemented as an option of BStringView 227 public: 228 FlickerFreeStringView(BRect bounds, const char* name, 229 const char* text, uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP, 230 uint32 flags = B_WILL_DRAW); 231 FlickerFreeStringView(BRect bounds, const char* name, 232 const char* text, BBitmap* existingOffscreen, 233 uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP, 234 uint32 flags = B_WILL_DRAW); 235 virtual ~FlickerFreeStringView(); 236 virtual void Draw(BRect); 237 virtual void AttachedToWindow(); 238 virtual void SetViewColor(rgb_color); 239 virtual void SetLowColor(rgb_color); 240 241 private: 242 OffscreenBitmap* fBitmap; 243 rgb_color fViewColor; 244 rgb_color fLowColor; 245 BBitmap* fOrigBitmap; 246 247 typedef BStringView _inherited; 248 }; 249 250 251 class DraggableIcon : public BView { 252 // used to determine a save location for a file 253 public: 254 DraggableIcon(BRect, const char*, const char* mimeType, icon_size, 255 const BMessage*, BMessenger, 256 uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP, 257 uint32 flags = B_WILL_DRAW); 258 virtual ~DraggableIcon(); 259 260 static BRect PreferredRect(BPoint offset, icon_size); 261 void SetTarget(BMessenger); 262 263 protected: 264 virtual void AttachedToWindow(); 265 virtual void MouseDown(BPoint); 266 virtual void Draw(BRect); 267 268 virtual bool DragStarted(BMessage* dragMessage); 269 270 protected: 271 BBitmap* fBitmap; 272 BMessage fMessage; 273 BMessenger fTarget; 274 }; 275 276 277 class PositionPassingMenuItem : public BMenuItem { 278 public: 279 PositionPassingMenuItem(const char* title, BMessage*, 280 char shortcut = 0, uint32 modifiers = 0); 281 282 PositionPassingMenuItem(BMenu*, BMessage*); 283 284 protected: 285 virtual status_t Invoke(BMessage* = 0); 286 // appends the invoke location for NewFolder, etc. to use 287 288 private: 289 typedef BMenuItem _inherited; 290 }; 291 292 293 class Benaphore { 294 // aka benaphore 295 public: 296 Benaphore(const char* name = "Light Lock") 297 : fSemaphore(create_sem(0, name)), 298 fCount(1) 299 { 300 } 301 302 ~Benaphore() 303 { 304 delete_sem(fSemaphore); 305 } 306 307 bool Lock() 308 { 309 if (atomic_add(&fCount, -1) <= 0) 310 return acquire_sem(fSemaphore) == B_OK; 311 312 return true; 313 } 314 315 void Unlock() 316 { 317 if (atomic_add(&fCount, 1) < 0) 318 release_sem(fSemaphore); 319 } 320 321 bool IsLocked() const 322 { 323 return fCount <= 0; 324 } 325 326 private: 327 sem_id fSemaphore; 328 int32 fCount; 329 }; 330 331 332 class SeparatorLine : public BView { 333 public: 334 SeparatorLine(BPoint, float, bool vertical, const char* name = ""); 335 virtual void Draw(BRect bounds); 336 }; 337 338 339 class TitledSeparatorItem : public BMenuItem { 340 public: 341 TitledSeparatorItem(const char*); 342 virtual ~TitledSeparatorItem(); 343 344 virtual void SetEnabled(bool state); 345 346 protected: 347 virtual void GetContentSize(float* width, float* height); 348 virtual void Draw(); 349 350 private: 351 typedef BMenuItem _inherited; 352 }; 353 354 355 class LooperAutoLocker { 356 public: 357 LooperAutoLocker(BHandler* handler) 358 : fHandler(handler), 359 fHasLock(handler->LockLooper()) 360 { 361 } 362 363 ~LooperAutoLocker() 364 { 365 if (fHasLock) 366 fHandler->UnlockLooper(); 367 } 368 369 bool operator!() const 370 { 371 return !fHasLock; 372 } 373 374 bool IsLocked() const 375 { 376 return fHasLock; 377 } 378 379 private: 380 BHandler* fHandler; 381 bool fHasLock; 382 }; 383 384 385 class ShortcutFilter : public BMessageFilter { 386 public: 387 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier, 388 uint32 shortcutWhat, BHandler* target); 389 390 protected: 391 filter_result Filter(BMessage*, BHandler**); 392 393 private: 394 uint32 fShortcutKey; 395 uint32 fShortcutModifier; 396 uint32 fShortcutWhat; 397 BHandler* fTarget; 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 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) 469 throw (status_t)B_ERROR; 470 471 status_t error = item->InitCheck(); 472 if (error != B_OK) 473 throw (status_t)error; 474 } 475 476 #if DEBUG 477 #define ThrowOnError(error) _ThrowOnError(error, __FILE__, __LINE__) 478 #define ThrowIfNotSize(error) _ThrowIfNotSize(error, __FILE__, __LINE__) 479 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__) 480 #else 481 #define ThrowOnError(x) _ThrowOnError(x, 0, 0) 482 #define ThrowIfNotSize(x) _ThrowIfNotSize(x, 0, 0) 483 #define ThrowOnErrorWithMessage(error, debugStr) _ThrowOnError(error, debugStr, __FILE__, __LINE__) 484 #endif 485 486 void _ThrowOnError(status_t, const char*, int32); 487 void _ThrowIfNotSize(ssize_t, const char*, int32); 488 void _ThrowOnError(status_t, const char* debugStr, const char*, int32); 489 490 // stub calls that work around BAppFile info inefficiency 491 status_t GetAppSignatureFromAttr(BFile*, char*); 492 status_t GetAppIconFromAttr(BFile*, BBitmap*, icon_size); 493 status_t GetFileIconFromAttr(BNode*, BBitmap*, icon_size); 494 495 // debugging 496 void HexDump(const void* buffer, int32 length); 497 498 #if xDEBUG 499 500 inline void 501 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 502 { 503 if (ref == NULL) { 504 PRINT(("NULL entry_ref%s", trailer)); 505 return; 506 } 507 508 BPath path; 509 BEntry entry(ref); 510 entry.GetPath(&path); 511 PRINT(("%s%s", path.Path(), trailer)); 512 } 513 514 515 inline void 516 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 517 { 518 if (entry == NULL) { 519 PRINT(("NULL entry%s", trailer)); 520 return; 521 } 522 523 BPath path; 524 entry->GetPath(&path); 525 PRINT(("%s%s", path.Path(), trailer)); 526 } 527 528 529 inline void 530 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 531 { 532 if (dir == NULL) { 533 PRINT(("NULL entry_ref%s", trailer)); 534 return; 535 } 536 537 BPath path; 538 BEntry entry; 539 dir->GetEntry(&entry); 540 entry.GetPath(&path); 541 PRINT(("%s%s", path.Path(), trailer)); 542 } 543 544 #else 545 546 inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 547 inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 548 inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 549 550 #endif 551 552 #ifdef xDEBUG 553 554 extern FILE* logFile; 555 556 inline void PrintToLogFile(const char* format, ...) 557 { 558 va_list ap; 559 va_start(ap, fmt); 560 vfprintf(logFile, fmt, ap); 561 va_end(ap); 562 } 563 564 #define WRITELOG(_ARGS_) \ 565 if (logFile == 0) \ 566 logFile = fopen("/var/log/tracker.log", "a+"); \ 567 if (logFile != 0) { \ 568 thread_info info; \ 569 get_thread_info(find_thread(NULL), &info); \ 570 PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(), \ 571 info.name, __FILE__, __LINE__); \ 572 PrintToLogFile _ARGS_; \ 573 PrintToLogFile("\n"); \ 574 fflush(logFile); \ 575 } 576 577 #else 578 579 #define WRITELOG(_ARGS_) 580 581 #endif 582 583 // fancy casting macros 584 585 template <typename NewType, typename OldType> 586 inline NewType assert_cast(OldType castedPointer) { 587 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 588 return static_cast<NewType>(castedPointer); 589 } 590 591 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that 592 // should fix up in ByteOrder.h 593 594 inline int32 SwapInt32(int32 value) 595 { return (int32)B_SWAP_INT32((uint32)value); } 596 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 597 inline int64 SwapInt64(int64 value) 598 { return (int64)B_SWAP_INT64((uint64)value); } 599 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 600 601 602 extern const float kExactMatchScore; 603 float ComputeTypeAheadScore(const char* text, const char* match, 604 bool wordMode = false); 605 606 } // namespace BPrivate 607 608 #endif // _UTILITIES_H 609