xref: /haiku/src/kits/tracker/Utilities.h (revision f23596149e0d173463f70629581aa10cc305d32e)
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