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