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