#ifndef _UTILITIES_H
#define _UTILITIES_H
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <Bitmap.h>
#include <ByteOrder.h>
#include <DataIO.h>
#include <Directory.h>
#include <Entry.h>
#include <GraphicsDefs.h>
#include <Looper.h>
#include <MenuItem.h>
#include <MessageFilter.h>
#include <Mime.h>
#include <NaturalCompare.h>
#include <ObjectList.h>
#include <Point.h>
#include <Path.h>
#include <String.h>
#include <StringView.h>
class BMessage;
class BTextView;
class BView;
class BVolume;
namespace BPrivate {
class Benaphore;
class BPose;
class BPoseView;
class Model;
static const rgb_color kBlack = make_color(0, 0, 0, 255);
static const rgb_color kWhite = make_color(255, 255, 255 ,255);
const int64 kHalfKBSize = 512;
const int64 kKBSize = 1024;
const int64 kMBSize = 1048576;
const int64 kGBSize = 1073741824;
const int64 kTBSize = kGBSize * kKBSize;
const int32 kMiniIconSeparator = 3;
const color_space kDefaultIconDepth = B_RGBA32;
extern bool gLocalizedNamePreferred;
class PeriodicUpdatePoses {
public:
PeriodicUpdatePoses();
~PeriodicUpdatePoses();
typedef bool (*PeriodicUpdateCallback)(BPose* pose, void* cookie);
void AddPose(BPose* pose, BPoseView* poseView,
PeriodicUpdateCallback callback, void* cookie);
bool RemovePose(BPose* pose, void** cookie);
void DoPeriodicUpdate(bool forceRedraw);
private:
struct periodic_pose {
BPose* pose;
BPoseView* pose_view;
PeriodicUpdateCallback callback;
void* cookie;
};
Benaphore* fLock;
BObjectList<periodic_pose, true> fPoseList;
};
extern PeriodicUpdatePoses gPeriodicUpdatePoses;
class PoseInfo {
public:
static void EndianSwap(void* castToThis);
void PrintToStream();
bool fInvisible;
ino_t fInitedDirectory;
BPoint fLocation;
};
class ExtendedPoseInfo {
public:
size_t Size() const;
static size_t Size(int32);
size_t SizeWithHeadroom() const;
static size_t SizeWithHeadroom(size_t);
bool HasLocationForFrame(BRect) const;
BPoint LocationForFrame(BRect) const;
bool SetLocationForFrame(BPoint, BRect);
static void EndianSwap(void* castToThis);
void PrintToStream();
uint32 fWorkspaces;
bool fInvisible;
bool fShowFromBootOnly;
bool fReservedBool1;
bool fReservedBool2;
int32 fReservedInt1;
int32 fReservedInt2;
int32 fReservedInt3;
int32 fReservedInt4;
int32 fReservedInt5;
int32 fNumFrames;
struct FrameLocation {
BPoint fLocation;
BRect fFrame;
uint32 fWorkspaces;
};
FrameLocation fLocations[0];
};
void DisallowMetaKeys(BTextView*);
void DisallowFilenameKeys(BTextView*);
bool ValidateStream(BMallocIO*, uint32, int32 version);
float ReadOnlyTint(rgb_color base);
float ReadOnlyTint(color_which base);
rgb_color InvertColor(rgb_color color);
rgb_color InvertColorSmart(rgb_color color);
bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons);
uint32 SeededHashString(const char* string, uint32 seed);
uint32 AttrHashString(const char* string, uint32 type);
class OffscreenBitmap {
public:
OffscreenBitmap(BRect bounds);
OffscreenBitmap();
~OffscreenBitmap();
BView* BeginUsing(BRect bounds);
void DoneUsing();
BBitmap* Bitmap() const;
BView* View() const;
private:
void NewBitmap(BRect frame);
BBitmap* fBitmap;
};
extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height,
int32 from, int32 to);
extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height,
int32 from, int32 to);
class FlickerFreeStringView : public BStringView {
public:
FlickerFreeStringView(BRect bounds, const char* name,
const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW);
FlickerFreeStringView(BRect bounds, const char* name,
const char* text, BBitmap* existingOffscreen,
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW);
virtual ~FlickerFreeStringView();
virtual void Draw(BRect);
virtual void AttachedToWindow();
virtual void SetViewColor(rgb_color);
virtual void SetLowColor(rgb_color);
private:
OffscreenBitmap* fBitmap;
rgb_color fViewColor;
rgb_color fLowColor;
BBitmap* fOriginalBitmap;
typedef BStringView _inherited;
};
class DraggableIcon : public BView {
public:
DraggableIcon(BRect rect, const char* name, const char* mimeType,
icon_size which, const BMessage* message, BMessenger target,
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_WILL_DRAW);
virtual ~DraggableIcon();
static BRect PreferredRect(BPoint offset, icon_size which);
void SetTarget(BMessenger);
protected:
virtual void AttachedToWindow();
virtual void MouseDown(BPoint);
virtual void Draw(BRect);
virtual bool DragStarted(BMessage* dragMessage);
protected:
BBitmap* fBitmap;
BMessage fMessage;
BMessenger fTarget;
};
class PositionPassingMenuItem : public BMenuItem {
public:
PositionPassingMenuItem(const char* title, BMessage*,
char shortcut = 0, uint32 modifiers = 0);
PositionPassingMenuItem(BMenu*, BMessage*);
PositionPassingMenuItem(BMessage* data);
static BArchivable* Instantiate(BMessage* data);
protected:
virtual status_t Invoke(BMessage* = 0);
private:
typedef BMenuItem _inherited;
};
class Benaphore {
public:
Benaphore(const char* name = "Light Lock")
: fSemaphore(create_sem(0, name)),
fCount(1)
{
}
~Benaphore()
{
delete_sem(fSemaphore);
}
bool Lock()
{
if (atomic_add(&fCount, -1) <= 0)
return acquire_sem(fSemaphore) == B_OK;
return true;
}
void Unlock()
{
if (atomic_add(&fCount, 1) < 0)
release_sem(fSemaphore);
}
bool IsLocked() const
{
return fCount <= 0;
}
private:
sem_id fSemaphore;
int32 fCount;
};
class SeparatorLine : public BView {
public:
SeparatorLine(BPoint, float, bool vertical, const char* name = "");
virtual void Draw(BRect bounds);
};
class TitledSeparatorItem : public BMenuItem {
public:
TitledSeparatorItem(const char*);
virtual ~TitledSeparatorItem();
virtual void SetEnabled(bool state);
protected:
virtual void GetContentSize(float* width, float* height);
virtual void Draw();
private:
typedef BMenuItem _inherited;
};
class ShortcutFilter : public BMessageFilter {
public:
ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
uint32 shortcutWhat, BHandler* target);
protected:
filter_result Filter(BMessage*, BHandler**);
private:
uint32 fShortcutKey;
uint32 fShortcutModifier;
uint32 fShortcutWhat;
BHandler* fTarget;
};
entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
void* passThru = 0);
const entry_ref* EachEntryRef(const BMessage*,
const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0);
entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
void* passThru, int32 maxCount);
const entry_ref* EachEntryRef(const BMessage*,
const entry_ref* (*)(const entry_ref*, void*), void* passThru,
int32 maxCount);
bool ContainsEntryRef(const BMessage*, const entry_ref*);
int32 CountRefs(const BMessage*);
BMenuItem* EachMenuItem(BMenu* menu, bool recursive,
BMenuItem* (*func)(BMenuItem*));
const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive,
BMenuItem* (*func)(const BMenuItem*));
int64 StringToScalar(const char* text);
int32 ListIconSize();
void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume);
status_t MatchArchivedVolume(BVolume* volume, const BMessage* message,
int32 index = 0);
void TruncateLeaf(BString* string);
void StringFromStream(BString*, BMallocIO*, bool endianSwap = false);
void StringToStream(const BString*, BMallocIO*);
int32 ArchiveSize(const BString*);
extern int CompareLabels(const BMenuItem*, const BMenuItem*);
extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on);
extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on);
extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
extern void DeleteSubmenu(BMenuItem* submenuItem);
extern bool BootedInSafeMode();
void PrintToStream(rgb_color color);
template <class InitCheckable>
void
ThrowOnInitCheckError(InitCheckable* item)
{
if (item == NULL)
throw (status_t)B_ERROR;
status_t result = item->InitCheck();
if (result != B_OK)
throw (status_t)result;
}
#if DEBUG
# define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__)
# define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__)
# define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__)
#else
# define ThrowOnError(x) _ThrowOnError(x, NULL, 0)
# define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0)
# define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0)
#endif
void _ThrowOnError(status_t, const char*, int32);
void _ThrowIfNotSize(ssize_t, const char*, int32);
void _ThrowOnAssert(bool, const char*, int32);
status_t GetAppSignatureFromAttr(BFile*, char*);
status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which);
status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which);
void HexDump(const void* buffer, int32 length);
#if xDEBUG
inline void
PrintRefToStream(const entry_ref* ref, const char* trailer = "\n")
{
if (ref == NULL) {
PRINT(("NULL entry_ref%s", trailer));
return;
}
BPath path;
BEntry entry(ref);
entry.GetPath(&path);
PRINT(("%s%s", path.Path(), trailer));
}
inline void
PrintEntryToStream(const BEntry* entry, const char* trailer = "\n")
{
if (entry == NULL) {
PRINT(("NULL entry%s", trailer));
return;
}
BPath path;
entry->GetPath(&path);
PRINT(("%s%s", path.Path(), trailer));
}
inline void
PrintDirToStream(const BDirectory* dir, const char* trailer = "\n")
{
if (dir == NULL) {
PRINT(("NULL entry_ref%s", trailer));
return;
}
BPath path;
BEntry entry;
dir->GetEntry(&entry);
entry.GetPath(&path);
PRINT(("%s%s", path.Path(), trailer));
}
#else
inline void PrintRefToStream(const entry_ref*, const char* = 0) {}
inline void PrintEntryToStream(const BEntry*, const char* = 0) {}
inline void PrintDirToStream(const BDirectory*, const char* = 0) {}
#endif
#ifdef xDEBUG
extern FILE* logFile;
inline void PrintToLogFile(const char* format, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(logFile, fmt, ap);
va_end(ap);
}
#define WRITELOG(_ARGS_) \
if (logFile == 0) \
logFile = fopen("/var/log/tracker.log", "a+"); \
\
if (logFile != 0) { \
thread_info info; \
get_thread_info(find_thread(NULL), &info); \
PrintToLogFile("[t %lld] \"%s\" (%s:%i) ", system_time(), \
info.name, __FILE__, __LINE__); \
PrintToLogFile _ARGS_; \
PrintToLogFile("\n"); \
fflush(logFile); \
}
#else
#define WRITELOG(_ARGS_)
#endif
template <typename NewType, typename OldType>
inline NewType assert_cast(OldType castedPointer) {
ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
return static_cast<NewType>(castedPointer);
}
inline int32 SwapInt32(int32 value)
{ return (int32)B_SWAP_INT32((uint32)value); }
inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
inline int64 SwapInt64(int64 value)
{ return (int64)B_SWAP_INT64((uint64)value); }
inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
extern const float kExactMatchScore;
float ComputeTypeAheadScore(const char* text, const char* match,
bool wordMode = false);
inline float
ActualFontHeight(const BView* view)
{
font_height height;
view->GetFontHeight(&height);
return height.ascent + height.descent + 1;
}
}
#endif