xref: /haiku/src/kits/app/Cursor.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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 BCursor::BCursor(const void *cursorData)
30 	:
31 	fServerToken(-1),
32 	fNeedToFree(false)
33 {
34 	const uint8 *data = (const uint8 *)cursorData;
35 
36 	if (data == B_HAND_CURSOR || data == B_I_BEAM_CURSOR) {
37 		// just use the default cursors from the app_server
38 		fServerToken = data == B_HAND_CURSOR ?
39 			B_CURSOR_ID_SYSTEM_DEFAULT : B_CURSOR_ID_I_BEAM;
40 		return;
41 	}
42 
43 	// Create a new cursor in the app_server
44 
45 	if (data == NULL
46 		|| data[0] != 16	// size
47 		|| data[1] != 1		// depth
48 		|| data[2] >= 16 || data[3] >= 16)	// hot-spot
49 		return;
50 
51 	// Send data directly to server
52 	BPrivate::AppServerLink link;
53 	link.StartMessage(AS_CREATE_CURSOR);
54 	link.Attach(cursorData, 68);
55 
56 	status_t status;
57 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
58 		link.Read<int32>(&fServerToken);
59 		fNeedToFree = true;
60 	}
61 }
62 
63 
64 BCursor::BCursor(BCursorID id)
65 	:
66 	fServerToken(id),
67 	fNeedToFree(false)
68 {
69 }
70 
71 
72 BCursor::BCursor(const BCursor& other)
73 	:
74 	fServerToken(-1),
75 	fNeedToFree(false)
76 {
77 	*this = other;
78 }
79 
80 
81 BCursor::BCursor(BMessage *data)
82 {
83 	// undefined on BeOS
84 	fServerToken = -1;
85 	fNeedToFree = false;
86 }
87 
88 
89 BCursor::~BCursor()
90 {
91 	_FreeCursorData();
92 }
93 
94 
95 status_t
96 BCursor::Archive(BMessage *into, bool deep) const
97 {
98 	// not implemented on BeOS
99 	return B_OK;
100 }
101 
102 
103 BArchivable	*
104 BCursor::Instantiate(BMessage *data)
105 {
106 	// not implemented on BeOS
107 	return NULL;
108 }
109 
110 
111 BCursor&
112 BCursor::operator=(const BCursor& other)
113 {
114 	if (&other != this && other != *this) {
115 		_FreeCursorData();
116 
117 		fServerToken = other.fServerToken;
118 		fNeedToFree = other.fNeedToFree;
119 
120 		if (fNeedToFree) {
121 			// Tell app_server that there is another reference for this
122 			// cursor data!
123 			BPrivate::AppServerLink link;
124 			link.StartMessage(AS_REFERENCE_CURSOR);
125 			link.Attach<int32>(fServerToken);
126 		}
127 	}
128 	return *this;
129 }
130 
131 
132 bool
133 BCursor::operator==(const BCursor& other) const
134 {
135 	return fServerToken == other.fServerToken;
136 }
137 
138 
139 bool
140 BCursor::operator!=(const BCursor& other) const
141 {
142 	return fServerToken != other.fServerToken;
143 }
144 
145 
146 status_t
147 BCursor::Perform(perform_code d, void *arg)
148 {
149 	return B_OK;
150 }
151 
152 
153 void BCursor::_ReservedCursor1() {}
154 void BCursor::_ReservedCursor2() {}
155 void BCursor::_ReservedCursor3() {}
156 void BCursor::_ReservedCursor4() {}
157 
158 
159 void
160 BCursor::_FreeCursorData()
161 {
162 	// Notify server to deallocate server-side objects for this cursor
163 	if (fNeedToFree) {
164 		BPrivate::AppServerLink link;
165 		link.StartMessage(AS_DELETE_CURSOR);
166 		link.Attach<int32>(fServerToken);
167 		link.Flush();
168 	}
169 }
170 
171