xref: /haiku/src/kits/app/Cursor.cpp (revision 03187b607b2b5eec7ee059f1ead09bdba14991fb)
1 /*
2  * Copyright 2001-2006, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Frans van Nispen (xlr8@tref.nl)
7  *		Gabe Yoder (gyoder@stny.rr.com)
8  *		Axel Dörfler, axeld@pinc-software.de
9  */
10 
11 /**	BCursor describes a view-wide or application-wide cursor. */
12 
13 /**
14 	@note:	As BeOS only supports 16x16 monochrome cursors, and I would like
15 			to see a nice shadowes one, we will need to extend this one.
16  */
17 
18 #include <AppDefs.h>
19 #include <Cursor.h>
20 
21 #include <AppServerLink.h>
22 #include <ServerProtocol.h>
23 
24 
25 const BCursor *B_CURSOR_SYSTEM_DEFAULT;
26 const BCursor *B_CURSOR_I_BEAM;
27 	// these are initialized in BApplication::InitData()
28 
29 
30 BCursor::BCursor(const void *cursorData)
31 	:
32 	fServerToken(-1),
33 	fNeedToFree(false)
34 {
35 	const uint8 *data = (const uint8 *)cursorData;
36 
37 	if (data == B_HAND_CURSOR || data == B_I_BEAM_CURSOR) {
38 		// just use the default cursors from the app_server
39 		fServerToken = data == B_HAND_CURSOR ?
40 			B_CURSOR_DEFAULT : B_CURSOR_TEXT;
41 		return;
42 	}
43 
44 	// Create a new cursor in the app_server
45 
46 	if (data == NULL
47 		|| data[0] != 16	// size
48 		|| data[1] != 1		// depth
49 		|| data[2] >= 16 || data[3] >= 16)	// hot-spot
50 		return;
51 
52 	// Send data directly to server
53 	BPrivate::AppServerLink link;
54 	link.StartMessage(AS_CREATE_CURSOR);
55 	link.Attach(cursorData, 68);
56 
57 	status_t status;
58 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
59 		link.Read<int32>(&fServerToken);
60 		fNeedToFree = true;
61 	}
62 }
63 
64 
65 BCursor::BCursor(const BCursor& other)
66 	:
67 	fServerToken(-1),
68 	fNeedToFree(false)
69 {
70 	*this = other;
71 }
72 
73 
74 BCursor::BCursor(BMessage *data)
75 {
76 	// undefined on BeOS
77 	fServerToken = -1;
78 	fNeedToFree = false;
79 }
80 
81 
82 BCursor::~BCursor()
83 {
84 	_FreeCursorData();
85 }
86 
87 
88 status_t
89 BCursor::Archive(BMessage *into, bool deep) const
90 {
91 	// not implemented on BeOS
92 	return B_OK;
93 }
94 
95 
96 BArchivable	*
97 BCursor::Instantiate(BMessage *data)
98 {
99 	// not implemented on BeOS
100 	return NULL;
101 }
102 
103 
104 BCursor&
105 BCursor::operator=(const BCursor& other)
106 {
107 	if (&other != this && other != *this) {
108 		_FreeCursorData();
109 
110 		fServerToken = other.fServerToken;
111 		fNeedToFree = other.fNeedToFree;
112 
113 		if (fNeedToFree) {
114 			// Tell app_server that there is another reference for this
115 			// cursor data!
116 			BPrivate::AppServerLink link;
117 			link.StartMessage(AS_REFERENCE_CURSOR);
118 			link.Attach<int32>(fServerToken);
119 		}
120 	}
121 	return *this;
122 }
123 
124 
125 bool
126 BCursor::operator==(const BCursor& other) const
127 {
128 	return fServerToken == other.fServerToken;
129 }
130 
131 
132 bool
133 BCursor::operator!=(const BCursor& other) const
134 {
135 	return fServerToken != other.fServerToken;
136 }
137 
138 
139 status_t
140 BCursor::Perform(perform_code d, void *arg)
141 {
142 	return B_OK;
143 }
144 
145 
146 void BCursor::_ReservedCursor1() {}
147 void BCursor::_ReservedCursor2() {}
148 void BCursor::_ReservedCursor3() {}
149 void BCursor::_ReservedCursor4() {}
150 
151 
152 void
153 BCursor::_FreeCursorData()
154 {
155 	// Notify server to deallocate server-side objects for this cursor
156 	if (fNeedToFree) {
157 		BPrivate::AppServerLink link;
158 		link.StartMessage(AS_DELETE_CURSOR);
159 		link.Attach<int32>(fServerToken);
160 		link.Flush();
161 	}
162 }
163 
164