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