1/* 2Open Tracker License 3 4Terms and Conditions 5 6Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a copy of 9this software and associated documentation files (the "Software"), to deal in 10the Software without restriction, including without limitation the rights to 11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12of the Software, and to permit persons to whom the Software is furnished to do 13so, subject to the following conditions: 14 15The above copyright notice and this permission notice applies to all licensees 16and shall be included in all copies or substantial portions of the Software. 17 18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25Except as contained in this notice, the name of Be Incorporated shall not be 26used in advertising or otherwise to promote the sale, use or other dealings in 27this Software without prior written authorization from Be Incorporated. 28 29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 30of Be Incorporated in the United States and other countries. Other brand product 31names are registered trademarks or trademarks of their respective holders. 32All 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 60class BMessage; 61class BTextView; 62class BView; 63class BVolume; 64 65namespace BPrivate { 66 67class Benaphore; 68class BPose; 69class BPoseView; 70class Model; 71 72// global variables 73static const rgb_color kBlack = make_color(0, 0, 0, 255); 74static const rgb_color kWhite = make_color(255, 255, 255 ,255); 75 76const int64 kHalfKBSize = 512; 77const int64 kKBSize = 1024; 78const int64 kMBSize = 1048576; 79const int64 kGBSize = 1073741824; 80const int64 kTBSize = kGBSize * kKBSize; 81 82const int32 kMiniIconSeparator = 3; 83 84const color_space kDefaultIconDepth = B_RGBA32; 85 86 87extern bool gLocalizedNamePreferred; 88 89 90// misc typedefs, constants and structs 91 92class 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. 96public: 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 108private: 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 120extern PeriodicUpdatePoses gPeriodicUpdatePoses; 121 122 123class PoseInfo { 124 // PoseInfo is the structure that gets saved as attributes for every node 125 // on disk, defining the node's position and visibility 126public: 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 142class ExtendedPoseInfo { 143 // extends PoseInfo adding workspace support; used for desktop 144 // poses only 145public: 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 179void DisallowMetaKeys(BTextView*); 180void DisallowFilenameKeys(BTextView*); 181 182bool ValidateStream(BMallocIO*, uint32, int32 version); 183 184float ReadOnlyTint(rgb_color base); 185 186bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons); 187uint32 HashString(const char* string, uint32 seed); 188uint32 AttrHashString(const char* string, uint32 type); 189 190 191class OffscreenBitmap { 192 // a utility class for setting up offscreen bitmaps 193 public: 194 OffscreenBitmap(BRect bounds); 195 OffscreenBitmap(); 196 ~OffscreenBitmap(); 197 198 BView* BeginUsing(BRect bounds); 199 void DoneUsing(); 200 BBitmap* Bitmap() const; 201 // blit this to your view when you are done rendering 202 BView* View() const; 203 // use this to render your image 204 205 private: 206 void NewBitmap(BRect frame); 207 BBitmap* fBitmap; 208}; 209 210 211// bitmap functions 212extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height, 213 int32 from, int32 to); 214extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height, 215 int32 from, int32 to); 216 217 218class FlickerFreeStringView : public BStringView { 219 // adds support for offscreen bitmap drawing for string views that update 220 // often this would be better implemented as an option of BStringView 221public: 222 FlickerFreeStringView(BRect bounds, const char* name, 223 const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 224 uint32 flags = B_WILL_DRAW); 225 FlickerFreeStringView(BRect bounds, const char* name, 226 const char* text, BBitmap* existingOffscreen, 227 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 228 uint32 flags = B_WILL_DRAW); 229 virtual ~FlickerFreeStringView(); 230 virtual void Draw(BRect); 231 virtual void AttachedToWindow(); 232 virtual void SetViewColor(rgb_color); 233 virtual void SetLowColor(rgb_color); 234 235private: 236 OffscreenBitmap* fBitmap; 237 rgb_color fViewColor; 238 rgb_color fLowColor; 239 BBitmap* fOriginalBitmap; 240 241 typedef BStringView _inherited; 242}; 243 244 245class DraggableIcon : public BView { 246 // used to determine a save location for a file 247public: 248 DraggableIcon(BRect rect, const char* name, const char* mimeType, 249 icon_size which, const BMessage* message, BMessenger target, 250 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, 251 uint32 flags = B_WILL_DRAW); 252 virtual ~DraggableIcon(); 253 254 static BRect PreferredRect(BPoint offset, icon_size which); 255 void SetTarget(BMessenger); 256 257protected: 258 virtual void AttachedToWindow(); 259 virtual void MouseDown(BPoint); 260 virtual void Draw(BRect); 261 262 virtual bool DragStarted(BMessage* dragMessage); 263 264protected: 265 BBitmap* fBitmap; 266 BMessage fMessage; 267 BMessenger fTarget; 268}; 269 270 271class PositionPassingMenuItem : public BMenuItem { 272public: 273 PositionPassingMenuItem(const char* title, BMessage*, 274 char shortcut = 0, uint32 modifiers = 0); 275 PositionPassingMenuItem(BMenu*, BMessage*); 276 PositionPassingMenuItem(BMessage* data); 277 278 static BArchivable* Instantiate(BMessage* data); 279 280protected: 281 virtual status_t Invoke(BMessage* = 0); 282 // appends the invoke location for NewFolder, etc. to use 283 284private: 285 typedef BMenuItem _inherited; 286}; 287 288 289class Benaphore { 290 // aka benaphore 291public: 292 Benaphore(const char* name = "Light Lock") 293 : fSemaphore(create_sem(0, name)), 294 fCount(1) 295 { 296 } 297 298 ~Benaphore() 299 { 300 delete_sem(fSemaphore); 301 } 302 303 bool Lock() 304 { 305 if (atomic_add(&fCount, -1) <= 0) 306 return acquire_sem(fSemaphore) == B_OK; 307 308 return true; 309 } 310 311 void Unlock() 312 { 313 if (atomic_add(&fCount, 1) < 0) 314 release_sem(fSemaphore); 315 } 316 317 bool IsLocked() const 318 { 319 return fCount <= 0; 320 } 321 322private: 323 sem_id fSemaphore; 324 int32 fCount; 325}; 326 327 328class SeparatorLine : public BView { 329public: 330 SeparatorLine(BPoint, float, bool vertical, const char* name = ""); 331 virtual void Draw(BRect bounds); 332}; 333 334 335class TitledSeparatorItem : public BMenuItem { 336public: 337 TitledSeparatorItem(const char*); 338 virtual ~TitledSeparatorItem(); 339 340 virtual void SetEnabled(bool state); 341 342protected: 343 virtual void GetContentSize(float* width, float* height); 344 virtual void Draw(); 345 346private: 347 typedef BMenuItem _inherited; 348}; 349 350 351class ShortcutFilter : public BMessageFilter { 352public: 353 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier, 354 uint32 shortcutWhat, BHandler* target); 355 356protected: 357 filter_result Filter(BMessage*, BHandler**); 358 359private: 360 uint32 fShortcutKey; 361 uint32 fShortcutModifier; 362 uint32 fShortcutWhat; 363 BHandler* fTarget; 364}; 365 366 367// iterates over all the refs in a message 368entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 369 void* passThru = 0); 370const entry_ref* EachEntryRef(const BMessage*, 371 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0); 372 373entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*), 374 void* passThru, int32 maxCount); 375const entry_ref* EachEntryRef(const BMessage*, 376 const entry_ref* (*)(const entry_ref*, void*), void* passThru, 377 int32 maxCount); 378 379 380bool ContainsEntryRef(const BMessage*, const entry_ref*); 381int32 CountRefs(const BMessage*); 382 383BMenuItem* EachMenuItem(BMenu* menu, bool recursive, 384 BMenuItem* (*func)(BMenuItem*)); 385const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive, 386 BMenuItem* (*func)(const BMenuItem*)); 387 388int64 StringToScalar(const char* text); 389 // string to num, understands kB, MB, etc. 390 391int32 ListIconSize(); 392 393// misc calls 394void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume); 395status_t MatchArchivedVolume(BVolume* volume, const BMessage* message, 396 int32 index = 0); 397void TruncateLeaf(BString* string); 398 399void StringFromStream(BString*, BMallocIO*, bool endianSwap = false); 400void StringToStream(const BString*, BMallocIO*); 401int32 ArchiveSize(const BString*); 402 403extern int CompareLabels(const BMenuItem*, const BMenuItem*); 404extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on); 405extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on); 406extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 407extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on); 408extern void DeleteSubmenu(BMenuItem* submenuItem); 409 410extern bool BootedInSafeMode(); 411 412 413void PrintToStream(rgb_color color); 414 415template <class InitCheckable> 416void 417ThrowOnInitCheckError(InitCheckable* item) 418{ 419 if (item == NULL) 420 throw (status_t)B_ERROR; 421 422 status_t result = item->InitCheck(); 423 if (result != B_OK) 424 throw (status_t)result; 425} 426 427#if DEBUG 428# define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__) 429# define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__) 430# define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__) 431#else 432# define ThrowOnError(x) _ThrowOnError(x, NULL, 0) 433# define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0) 434# define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0) 435#endif 436 437void _ThrowOnError(status_t, const char*, int32); 438void _ThrowIfNotSize(ssize_t, const char*, int32); 439void _ThrowOnAssert(bool, const char*, int32); 440 441// stub calls that work around BAppFile info inefficiency 442status_t GetAppSignatureFromAttr(BFile*, char*); 443status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which); 444status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which); 445 446// debugging 447void HexDump(const void* buffer, int32 length); 448 449#if xDEBUG 450 451inline void 452PrintRefToStream(const entry_ref* ref, const char* trailer = "\n") 453{ 454 if (ref == NULL) { 455 PRINT(("NULL entry_ref%s", trailer)); 456 return; 457 } 458 459 BPath path; 460 BEntry entry(ref); 461 entry.GetPath(&path); 462 PRINT(("%s%s", path.Path(), trailer)); 463} 464 465 466inline void 467PrintEntryToStream(const BEntry* entry, const char* trailer = "\n") 468{ 469 if (entry == NULL) { 470 PRINT(("NULL entry%s", trailer)); 471 return; 472 } 473 474 BPath path; 475 entry->GetPath(&path); 476 PRINT(("%s%s", path.Path(), trailer)); 477} 478 479 480inline void 481PrintDirToStream(const BDirectory* dir, const char* trailer = "\n") 482{ 483 if (dir == NULL) { 484 PRINT(("NULL entry_ref%s", trailer)); 485 return; 486 } 487 488 BPath path; 489 BEntry entry; 490 dir->GetEntry(&entry); 491 entry.GetPath(&path); 492 PRINT(("%s%s", path.Path(), trailer)); 493} 494 495#else 496 497inline void PrintRefToStream(const entry_ref*, const char* = 0) {} 498inline void PrintEntryToStream(const BEntry*, const char* = 0) {} 499inline void PrintDirToStream(const BDirectory*, const char* = 0) {} 500 501#endif 502 503#ifdef xDEBUG 504 505 extern FILE* logFile; 506 507 inline void PrintToLogFile(const char* format, ...) 508 { 509 va_list ap; 510 va_start(ap, fmt); 511 vfprintf(logFile, fmt, ap); 512 va_end(ap); 513 } 514 515#define WRITELOG(_ARGS_) \ 516 if (logFile == 0) \ 517 logFile = fopen("/var/log/tracker.log", "a+"); \ 518 \ 519 if (logFile != 0) { \ 520 thread_info info; \ 521 get_thread_info(find_thread(NULL), &info); \ 522 PrintToLogFile("[t %lld] \"%s\" (%s:%i) ", system_time(), \ 523 info.name, __FILE__, __LINE__); \ 524 PrintToLogFile _ARGS_; \ 525 PrintToLogFile("\n"); \ 526 fflush(logFile); \ 527 } 528 529#else 530 531#define WRITELOG(_ARGS_) 532 533#endif 534 535// fancy casting macros 536 537template <typename NewType, typename OldType> 538inline NewType assert_cast(OldType castedPointer) { 539 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL); 540 return static_cast<NewType>(castedPointer); 541} 542 543// B_SWAP_INT32 have broken signedness, simple cover calls to fix that 544// should fix up in ByteOrder.h 545 546inline int32 SwapInt32(int32 value) 547 { return (int32)B_SWAP_INT32((uint32)value); } 548inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); } 549inline int64 SwapInt64(int64 value) 550 { return (int64)B_SWAP_INT64((uint64)value); } 551inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); } 552 553 554extern const float kExactMatchScore; 555float ComputeTypeAheadScore(const char* text, const char* match, 556 bool wordMode = false); 557 558} // namespace BPrivate 559 560 561#endif // _UTILITIES_H 562