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