1 /*
2 * Copyright 2001-2009, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Stephan Aßmus <superstippi@gmx.de>
8 * Axel Dörfler, axeld@pinc-software.de
9 */
10
11
12 /*! Although descended from ServerBitmaps, ServerCursors are not handled by
13 the BitmapManager, but the CursorManager instead. Until they have been
14 attached to a CursorManager, you can delete cursors like any other object.
15
16 Unlike BeOS, cursors can be any size or color space, and this class
17 accomodates and expands the BeOS API.
18 */
19
20
21 #include "CursorManager.h"
22 #include "ServerCursor.h"
23
24 #include <ByteOrder.h>
25
26 #include <new>
27 #include <stdio.h>
28
29
30 using std::nothrow;
31
32
33 /*! \brief Constructor
34
35 \param r Size of the cursor
36 \param cspace Color space of the cursor
37 \param flags ServerBitmap flags. See Bitmap.h.
38 \param hotspot Hotspot of the cursor
39 \param bytesperline Bytes per row for the cursor. See
40 ServerBitmap::ServerBitmap()
41
42 */
ServerCursor(BRect r,color_space format,int32 flags,BPoint hotspot,int32 bytesPerRow,screen_id screen)43 ServerCursor::ServerCursor(BRect r, color_space format, int32 flags,
44 BPoint hotspot, int32 bytesPerRow, screen_id screen)
45 :
46 ServerBitmap(r, format, flags, bytesPerRow, screen),
47 fHotSpot(hotspot),
48 fOwningTeam(-1),
49 fCursorData(NULL),
50 fManager(NULL)
51 {
52 fHotSpot.ConstrainTo(Bounds());
53 AllocateBuffer();
54 }
55
56
57 /*! \brief Constructor
58 \param data Pointer to 68-byte cursor data array. See BeBook entry for
59 BCursor for details
60 */
ServerCursor(const uint8 * data)61 ServerCursor::ServerCursor(const uint8* data)
62 :
63 ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0),
64 fHotSpot(0, 0),
65 fOwningTeam(-1),
66 fCursorData(NULL),
67 fManager(NULL)
68 {
69 // 68-byte array used in BeOS for holding cursors.
70 // This API has serious problems and should be deprecated (but supported)
71 // in R2
72
73 // Now that we have all the setup, we're going to map (for now) the cursor
74 // to RGBA32 (little endian). Eventually, there will be support for 16 and
75 // 8-bit depths
76 // NOTE: review this once we have working PPC graphics cards (big endian).
77 if (data) {
78 AllocateBuffer();
79 uint8* buffer = Bits();
80 if (!buffer)
81 return;
82
83 uint16* cursorBits = (uint16*)(data + 4);
84 uint16* transparencyBits = (uint16*)(data + 36);
85 fHotSpot.Set(data[3], data[2]);
86
87 // for each row in the cursor data
88 for (int32 j = 0; j < 16; j++) {
89 uint32* bits = (uint32*)(buffer + (j * BytesPerRow()));
90
91 // On intel, our bytes end up swapped, so we must swap them back
92 uint16 cursorLine = __swap_int16(cursorBits[j]);
93 uint16 transparencyLine = __swap_int16(transparencyBits[j]);
94
95 uint16 mask = 1 << 15;
96
97 // for each column in each row of cursor data
98 for (int32 i = 0; i < 16; i++, mask >>= 1) {
99 // Get the values and dump them to the bitmap
100 if (cursorLine & mask)
101 bits[i] = 0xff000000; // black
102 else if (transparencyLine & mask)
103 bits[i] = 0xffffffff; // white
104 else
105 bits[i] = 0x00000000; // transparent
106 }
107 }
108
109 // remember cursor data for later
110 fCursorData = new (nothrow) uint8[68];
111 if (fCursorData)
112 memcpy(fCursorData, data, 68);
113
114 } else {
115 fWidth = 0;
116 fHeight = 0;
117 fBytesPerRow = 0;
118 fSpace = B_NO_COLOR_SPACE;
119 }
120 }
121
122
123 /*! \brief Constructor
124 \param data Pointer to bitmap data in memory,
125 the padding bytes should be contained when format less than 32 bpp.
126 */
ServerCursor(const uint8 * alreadyPaddedData,uint32 width,uint32 height,color_space format)127 ServerCursor::ServerCursor(const uint8* alreadyPaddedData, uint32 width,
128 uint32 height, color_space format)
129 :
130 ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0),
131 fHotSpot(0, 0),
132 fOwningTeam(-1),
133 fCursorData(NULL),
134 fManager(NULL)
135 {
136 AllocateBuffer();
137 if (Bits())
138 memcpy(Bits(), alreadyPaddedData, BitsLength());
139 }
140
141
142 /*! \brief Copy constructor
143 \param cursor cursor to copy
144 */
ServerCursor(const ServerCursor * cursor)145 ServerCursor::ServerCursor(const ServerCursor* cursor)
146 :
147 ServerBitmap(cursor),
148 fHotSpot(0, 0),
149 fOwningTeam(-1),
150 fCursorData(NULL),
151 fManager(NULL)
152 {
153 // TODO: Hm. I don't move this into the if clause,
154 // because it might break code elsewhere.
155 AllocateBuffer();
156
157 if (cursor) {
158 if (Bits() && cursor->Bits())
159 memcpy(Bits(), cursor->Bits(), BitsLength());
160 fHotSpot = cursor->fHotSpot;
161 if (cursor->fCursorData) {
162 fCursorData = new (nothrow) uint8[68];
163 if (fCursorData)
164 memcpy(fCursorData, cursor->fCursorData, 68);
165 }
166 }
167 }
168
169
170 //! Frees the heap space allocated for the cursor's image data
~ServerCursor()171 ServerCursor::~ServerCursor()
172 {
173 delete[] fCursorData;
174 }
175
176
177 /*! \brief Sets the cursor's hotspot
178 \param pt New location of hotspot, constrained to the cursor's boundaries.
179 */
180 void
SetHotSpot(BPoint hotSpot)181 ServerCursor::SetHotSpot(BPoint hotSpot)
182 {
183 fHotSpot = hotSpot;
184 fHotSpot.ConstrainTo(Bounds());
185 }
186
187
188 void
AttachedToManager(CursorManager * manager)189 ServerCursor::AttachedToManager(CursorManager* manager)
190 {
191 fManager = manager;
192 }
193