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
190 uint32 SeededHashString(const char* string, uint32 seed);
191 uint32 AttrHashString(const char* string, uint32 type);
192
193
194 class OffscreenBitmap {
195 // a utility class for setting up offscreen bitmaps
196 public:
197 OffscreenBitmap(BRect bounds);
198 OffscreenBitmap();
199 ~OffscreenBitmap();
200
201 BView* BeginUsing(BRect bounds);
202 void DoneUsing();
203 BBitmap* Bitmap() const;
204 // blit this to your view when you are done rendering
205 BView* View() const;
206 // use this to render your image
207
208 private:
209 void NewBitmap(BRect frame);
210 BBitmap* fBitmap;
211 };
212
213
214 // bitmap functions
215 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height,
216 int32 from, int32 to);
217 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height,
218 int32 from, int32 to);
219
220
221 class FlickerFreeStringView : public BStringView {
222 // adds support for offscreen bitmap drawing for string views that update
223 // often this would be better implemented as an option of BStringView
224 public:
225 FlickerFreeStringView(BRect bounds, const char* name,
226 const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
227 uint32 flags = B_WILL_DRAW);
228 FlickerFreeStringView(BRect bounds, const char* name,
229 const char* text, BBitmap* existingOffscreen,
230 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
231 uint32 flags = B_WILL_DRAW);
232 virtual ~FlickerFreeStringView();
233 virtual void Draw(BRect);
234 virtual void AttachedToWindow();
235 virtual void SetViewColor(rgb_color);
236 virtual void SetLowColor(rgb_color);
237
238 private:
239 OffscreenBitmap* fBitmap;
240 rgb_color fViewColor;
241 rgb_color fLowColor;
242 BBitmap* fOriginalBitmap;
243
244 typedef BStringView _inherited;
245 };
246
247
248 class DraggableIcon : public BView {
249 // used to determine a save location for a file
250 public:
251 DraggableIcon(BRect rect, const char* name, const char* mimeType,
252 icon_size which, const BMessage* message, BMessenger target,
253 uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
254 uint32 flags = B_WILL_DRAW);
255 virtual ~DraggableIcon();
256
257 static BRect PreferredRect(BPoint offset, icon_size which);
258 void SetTarget(BMessenger);
259
260 protected:
261 virtual void AttachedToWindow();
262 virtual void MouseDown(BPoint);
263 virtual void Draw(BRect);
264
265 virtual bool DragStarted(BMessage* dragMessage);
266
267 protected:
268 BBitmap* fBitmap;
269 BMessage fMessage;
270 BMessenger fTarget;
271 };
272
273
274 class PositionPassingMenuItem : public BMenuItem {
275 public:
276 PositionPassingMenuItem(const char* title, BMessage*,
277 char shortcut = 0, uint32 modifiers = 0);
278 PositionPassingMenuItem(BMenu*, BMessage*);
279 PositionPassingMenuItem(BMessage* data);
280
281 static BArchivable* Instantiate(BMessage* data);
282
283 protected:
284 virtual status_t Invoke(BMessage* = 0);
285 // appends the invoke location for NewFolder, etc. to use
286
287 private:
288 typedef BMenuItem _inherited;
289 };
290
291
292 class Benaphore {
293 // aka benaphore
294 public:
295 Benaphore(const char* name = "Light Lock")
296 : fSemaphore(create_sem(0, name)),
297 fCount(1)
298 {
299 }
300
~Benaphore()301 ~Benaphore()
302 {
303 delete_sem(fSemaphore);
304 }
305
Lock()306 bool Lock()
307 {
308 if (atomic_add(&fCount, -1) <= 0)
309 return acquire_sem(fSemaphore) == B_OK;
310
311 return true;
312 }
313
Unlock()314 void Unlock()
315 {
316 if (atomic_add(&fCount, 1) < 0)
317 release_sem(fSemaphore);
318 }
319
IsLocked()320 bool IsLocked() const
321 {
322 return fCount <= 0;
323 }
324
325 private:
326 sem_id fSemaphore;
327 int32 fCount;
328 };
329
330
331 class SeparatorLine : public BView {
332 public:
333 SeparatorLine(BPoint, float, bool vertical, const char* name = "");
334 virtual void Draw(BRect bounds);
335 };
336
337
338 class TitledSeparatorItem : public BMenuItem {
339 public:
340 TitledSeparatorItem(const char*);
341 virtual ~TitledSeparatorItem();
342
343 virtual void SetEnabled(bool state);
344
345 protected:
346 virtual void GetContentSize(float* width, float* height);
347 virtual void Draw();
348
349 private:
350 typedef BMenuItem _inherited;
351 };
352
353
354 class ShortcutFilter : public BMessageFilter {
355 public:
356 ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
357 uint32 shortcutWhat, BHandler* target);
358
359 protected:
360 filter_result Filter(BMessage*, BHandler**);
361
362 private:
363 uint32 fShortcutKey;
364 uint32 fShortcutModifier;
365 uint32 fShortcutWhat;
366 BHandler* fTarget;
367 };
368
369
370 // iterates over all the refs in a message
371 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
372 void* passThru = 0);
373 const entry_ref* EachEntryRef(const BMessage*,
374 const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0);
375
376 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
377 void* passThru, int32 maxCount);
378 const entry_ref* EachEntryRef(const BMessage*,
379 const entry_ref* (*)(const entry_ref*, void*), void* passThru,
380 int32 maxCount);
381
382
383 bool ContainsEntryRef(const BMessage*, const entry_ref*);
384 int32 CountRefs(const BMessage*);
385
386 BMenuItem* EachMenuItem(BMenu* menu, bool recursive,
387 BMenuItem* (*func)(BMenuItem*));
388 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive,
389 BMenuItem* (*func)(const BMenuItem*));
390
391 int64 StringToScalar(const char* text);
392 // string to num, understands kB, MB, etc.
393
394 int32 ListIconSize();
395
396 // misc calls
397 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume);
398 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message,
399 int32 index = 0);
400 void TruncateLeaf(BString* string);
401
402 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false);
403 void StringToStream(const BString*, BMallocIO*);
404 int32 ArchiveSize(const BString*);
405
406 extern int CompareLabels(const BMenuItem*, const BMenuItem*);
407 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on);
408 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on);
409 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
410 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
411 extern void DeleteSubmenu(BMenuItem* submenuItem);
412
413 extern bool BootedInSafeMode();
414
415
416 void PrintToStream(rgb_color color);
417
418 template <class InitCheckable>
419 void
ThrowOnInitCheckError(InitCheckable * item)420 ThrowOnInitCheckError(InitCheckable* item)
421 {
422 if (item == NULL)
423 throw (status_t)B_ERROR;
424
425 status_t result = item->InitCheck();
426 if (result != B_OK)
427 throw (status_t)result;
428 }
429
430 #if DEBUG
431 # define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__)
432 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__)
433 # define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__)
434 #else
435 # define ThrowOnError(x) _ThrowOnError(x, NULL, 0)
436 # define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0)
437 # define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0)
438 #endif
439
440 void _ThrowOnError(status_t, const char*, int32);
441 void _ThrowIfNotSize(ssize_t, const char*, int32);
442 void _ThrowOnAssert(bool, const char*, int32);
443
444 // stub calls that work around BAppFile info inefficiency
445 status_t GetAppSignatureFromAttr(BFile*, char*);
446 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which);
447 status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which);
448
449 // debugging
450 void HexDump(const void* buffer, int32 length);
451
452 #if xDEBUG
453
454 inline void
455 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n")
456 {
457 if (ref == NULL) {
458 PRINT(("NULL entry_ref%s", trailer));
459 return;
460 }
461
462 BPath path;
463 BEntry entry(ref);
464 entry.GetPath(&path);
465 PRINT(("%s%s", path.Path(), trailer));
466 }
467
468
469 inline void
470 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n")
471 {
472 if (entry == NULL) {
473 PRINT(("NULL entry%s", trailer));
474 return;
475 }
476
477 BPath path;
478 entry->GetPath(&path);
479 PRINT(("%s%s", path.Path(), trailer));
480 }
481
482
483 inline void
484 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n")
485 {
486 if (dir == NULL) {
487 PRINT(("NULL entry_ref%s", trailer));
488 return;
489 }
490
491 BPath path;
492 BEntry entry;
493 dir->GetEntry(&entry);
494 entry.GetPath(&path);
495 PRINT(("%s%s", path.Path(), trailer));
496 }
497
498 #else
499
500 inline void PrintRefToStream(const entry_ref*, const char* = 0) {}
501 inline void PrintEntryToStream(const BEntry*, const char* = 0) {}
502 inline void PrintDirToStream(const BDirectory*, const char* = 0) {}
503
504 #endif
505
506 #ifdef xDEBUG
507
508 extern FILE* logFile;
509
PrintToLogFile(const char * format,...)510 inline void PrintToLogFile(const char* format, ...)
511 {
512 va_list ap;
513 va_start(ap, fmt);
514 vfprintf(logFile, fmt, ap);
515 va_end(ap);
516 }
517
518 #define WRITELOG(_ARGS_) \
519 if (logFile == 0) \
520 logFile = fopen("/var/log/tracker.log", "a+"); \
521 \
522 if (logFile != 0) { \
523 thread_info info; \
524 get_thread_info(find_thread(NULL), &info); \
525 PrintToLogFile("[t %lld] \"%s\" (%s:%i) ", system_time(), \
526 info.name, __FILE__, __LINE__); \
527 PrintToLogFile _ARGS_; \
528 PrintToLogFile("\n"); \
529 fflush(logFile); \
530 }
531
532 #else
533
534 #define WRITELOG(_ARGS_)
535
536 #endif
537
538 // fancy casting macros
539
540 template <typename NewType, typename OldType>
assert_cast(OldType castedPointer)541 inline NewType assert_cast(OldType castedPointer) {
542 ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
543 return static_cast<NewType>(castedPointer);
544 }
545
546 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
547 // should fix up in ByteOrder.h
548
SwapInt32(int32 value)549 inline int32 SwapInt32(int32 value)
550 { return (int32)B_SWAP_INT32((uint32)value); }
SwapUInt32(uint32 value)551 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
SwapInt64(int64 value)552 inline int64 SwapInt64(int64 value)
553 { return (int64)B_SWAP_INT64((uint64)value); }
SwapUInt64(uint64 value)554 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
555
556
557 extern const float kExactMatchScore;
558 float ComputeTypeAheadScore(const char* text, const char* match,
559 bool wordMode = false);
560
561
562 inline float
ActualFontHeight(const BView * view)563 ActualFontHeight(const BView* view)
564 {
565 font_height height;
566 view->GetFontHeight(&height);
567 return height.ascent + height.descent + 1;
568 }
569
570 } // namespace BPrivate
571
572
573 #endif // _UTILITIES_H
574