OpenCPN Partial API docs
Loading...
Searching...
No Matches
ocp_cursor.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2013 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
24#include "ocp_cursor.h"
25
26#ifdef __WXX11__
27
28#include <wx/x11/private.h>
29
30class ocpCursorRefData : public wxObjectRefData {
31public:
32 ocpCursorRefData();
33 ~ocpCursorRefData();
34
35 WXCursor m_cursor;
36 WXDisplay* m_display;
37};
38
39ocpCursorRefData::ocpCursorRefData() {
40 m_cursor = NULL;
41 m_display = NULL;
42}
43
44ocpCursorRefData::~ocpCursorRefData() {
45 if (m_cursor) XFreeCursor((Display*)m_display, (Cursor)m_cursor);
46}
47
48//-----------------------------------------------------------------------------
49
50#define M_CURSORDATA ((ocpCursorRefData*)m_refData)
51
52ocpCursor::ocpCursor(const wxString& cursorName, long type, int hotSpotX,
53 int hotSpotY)
54 : wxCursor(wxCURSOR_CROSS) {
55 wxImage cImage;
56
57 if (!cImage.CanRead(cursorName)) ::wxInitAllImageHandlers();
58
59 cImage.LoadFile(cursorName);
60
61 int width = cImage.GetWidth();
62 int height = cImage.GetHeight();
63
64 // m_refData = new wxCursorRefData();
65
66 // Get some X parameters
67 int xscreen = DefaultScreen((Display*)wxGlobalDisplay());
68 Window xroot = RootWindow((Display*)wxGlobalDisplay(), xscreen);
69 Visual* xvisual = DefaultVisual((Display*)wxGlobalDisplay(), xscreen);
70
71 M_CURSORDATA->m_display = wxGlobalDisplay();
72 wxASSERT_MSG(M_CURSORDATA->m_display, "No display");
73
74 // Make a pixmap
75 Pixmap cpixmap =
76 XCreatePixmap((Display*)wxGlobalDisplay(), xroot, width, height, 1);
77
78 // Make an Ximage
79 XImage* data_image = XCreateImage((Display*)wxGlobalDisplay(), xvisual, 1,
80 ZPixmap, 0, 0, width, height, 32, 0);
81 data_image->data =
82 (char*)malloc(data_image->bytes_per_line * data_image->height);
83
84 int index = 0;
85 int pixel = 0;
86 unsigned char* data = cImage.GetData();
87
88 // Create mask
89
90 Pixmap cmask;
91 unsigned char mr, mg, mb;
92
93 if (cImage.HasMask()) {
94 XImage* mask_image = XCreateImage((Display*)wxGlobalDisplay(), xvisual, 1,
95 ZPixmap, 0, 0, width, height, 32, 0);
96 mask_image->data =
97 (char*)malloc(mask_image->bytes_per_line * mask_image->height);
98
99 cImage.GetOrFindMaskColour(&mr, &mg, &mb);
100
101 int rit = (mr << 16) + (mg << 8) + mb;
102 for (int y = 0; y < height; y++) {
103 for (int x = 0; x < width; x++) {
104 int ri = (int)data[index++];
105 ri += data[index++] << 8;
106 ri += data[index++] << 16;
107
108 /*
109 int ri = *(int *)(&data[index]);
110 ri &= 0x00ffffff;
111 index++;
112 index++;
113 index++;
114 */
115 pixel = 1;
116 if (ri == rit) // if data is mask value, mask pixel gets 0
117 pixel = 0;
118
119 XPutPixel(mask_image, x, y, pixel);
120 }
121 }
122
123 cmask = XCreatePixmap((Display*)wxGlobalDisplay(), xroot, width, height, 1);
124
125 GC gc = XCreateGC((Display*)wxGlobalDisplay(), cmask, 0, NULL);
126 XPutImage((Display*)wxGlobalDisplay(), cmask, gc, mask_image, 0, 0, 0, 0,
127 width, height);
128
129 XDestroyImage(mask_image);
130 XFreeGC((Display*)wxGlobalDisplay(), gc);
131 }
132
133 // Render the wxImage cImage onto the Ximage
134 // Simple black/white cursors only, please
135
136 index = 0;
137
138 for (int y = 0; y < height; y++) {
139 for (int x = 0; x < width; x++) {
140 int ri = (int)data[index++];
141 ri += data[index++] << 8;
142 ri += data[index++] << 16;
143
144 /*
145 int ri = *(int *)(&data[index]);
146 ri &= 0x00ffffff;
147 index++;
148 index++;
149 index++;
150 */
151
152 pixel = 0;
153 if (ri) pixel = 1;
154
155 XPutPixel(data_image, x, y, pixel);
156 }
157 }
158
159 // Put the Ximage into the pixmap
160
161 GC gc = XCreateGC((Display*)wxGlobalDisplay(), cpixmap, 0, NULL);
162 XPutImage((Display*)wxGlobalDisplay(), cpixmap, gc, data_image, 0, 0, 0, 0,
163 width, height);
164
165 // Free the Ximage stuff
166 XDestroyImage(data_image);
167 XFreeGC((Display*)wxGlobalDisplay(), gc);
168
169 // Make a X cursor from the pixmap
170
171 XColor fg, bg;
172 fg.red = fg.blue = fg.green = 0xffff;
173 bg.red = bg.blue = bg.green = 0;
174
175 M_CURSORDATA->m_cursor =
176 (WXCursor)XCreatePixmapCursor((Display*)wxGlobalDisplay(), cpixmap, cmask,
177 &fg, &bg, hotSpotX, hotSpotY);
178}
179
180ocpCursor::ocpCursor(const char** xpm_data, long type, int hotSpotX,
181 int hotSpotY)
182 : wxCursor(wxCURSOR_CROSS) {
183 wxImage cImage(xpm_data);
184
185 int width = cImage.GetWidth();
186 int height = cImage.GetHeight();
187
188 // m_refData = new wxCursorRefData();
189
190 // Get some X parameters
191 int xscreen = DefaultScreen((Display*)wxGlobalDisplay());
192 Window xroot = RootWindow((Display*)wxGlobalDisplay(), xscreen);
193 Visual* xvisual = DefaultVisual((Display*)wxGlobalDisplay(), xscreen);
194
195 M_CURSORDATA->m_display = wxGlobalDisplay();
196 wxASSERT_MSG(M_CURSORDATA->m_display, "No display");
197
198 // Make a pixmap
199 Pixmap cpixmap =
200 XCreatePixmap((Display*)wxGlobalDisplay(), xroot, width, height, 1);
201
202 // Make an Ximage
203 XImage* data_image = XCreateImage((Display*)wxGlobalDisplay(), xvisual, 1,
204 ZPixmap, 0, 0, width, height, 32, 0);
205 data_image->data =
206 (char*)malloc(data_image->bytes_per_line * data_image->height);
207
208 int index = 0;
209 int pixel = 0;
210 unsigned char* data = cImage.GetData();
211
212 // Create mask
213
214 Pixmap cmask;
215 unsigned char mr, mg, mb;
216
217 if (cImage.HasMask()) {
218 XImage* mask_image = XCreateImage((Display*)wxGlobalDisplay(), xvisual, 1,
219 ZPixmap, 0, 0, width, height, 32, 0);
220 mask_image->data =
221 (char*)malloc(mask_image->bytes_per_line * mask_image->height);
222
223 cImage.GetOrFindMaskColour(&mr, &mg, &mb);
224
225 int rit = (mr << 16) + (mg << 8) + mb;
226 for (int y = 0; y < height; y++) {
227 for (int x = 0; x < width; x++) {
228 int ri = (int)data[index++];
229 ri += data[index++] << 8;
230 ri += data[index++] << 16;
231
232 /*
233 int ri = *(int *)(&data[index]);
234 ri &= 0x00ffffff;
235 index++;
236 index++;
237 index++;
238 */
239 pixel = 1;
240 if (ri == rit) // if data is mask value, mask pixel gets 0
241 pixel = 0;
242
243 XPutPixel(mask_image, x, y, pixel);
244 }
245 }
246
247 cmask = XCreatePixmap((Display*)wxGlobalDisplay(), xroot, width, height, 1);
248
249 GC gc = XCreateGC((Display*)wxGlobalDisplay(), cmask, 0, NULL);
250 XPutImage((Display*)wxGlobalDisplay(), cmask, gc, mask_image, 0, 0, 0, 0,
251 width, height);
252
253 XDestroyImage(mask_image);
254 XFreeGC((Display*)wxGlobalDisplay(), gc);
255 }
256
257 // Render the wxImage cImage onto the Ximage
258 // Simple black/white cursors only, please
259
260 index = 0;
261
262 for (int y = 0; y < height; y++) {
263 for (int x = 0; x < width; x++) {
264 int ri = (int)data[index++];
265 ri += data[index++] << 8;
266 ri += data[index++] << 16;
267
268 /*
269 int ri = *(int *)(&data[index]);
270 ri &= 0x00ffffff;
271 index++;
272 index++;
273 index++;
274 */
275
276 pixel = 0;
277 if (ri) pixel = 1;
278
279 XPutPixel(data_image, x, y, pixel);
280 }
281 }
282
283 // Put the Ximage into the pixmap
284
285 GC gc = XCreateGC((Display*)wxGlobalDisplay(), cpixmap, 0, NULL);
286 XPutImage((Display*)wxGlobalDisplay(), cpixmap, gc, data_image, 0, 0, 0, 0,
287 width, height);
288
289 // Free the Ximage stuff
290 XDestroyImage(data_image);
291 XFreeGC((Display*)wxGlobalDisplay(), gc);
292
293 // Make a X cursor from the pixmap
294
295 XColor fg, bg;
296 fg.red = fg.blue = fg.green = 0xffff;
297 bg.red = bg.blue = bg.green = 0;
298
299 M_CURSORDATA->m_cursor =
300 (WXCursor)XCreatePixmapCursor((Display*)wxGlobalDisplay(), cpixmap, cmask,
301 &fg, &bg, hotSpotX, hotSpotY);
302}
303
304#endif // __WXX11__
305
306// We derive a class from wxCursor to create ocpCursor
307// Specifically to fix a bug in wxImage-wxBitmap conversions
308
309#ifdef __WXMSW__
310
311ocpCursor::ocpCursor(const wxString& cursorName, long type, int hotSpotX,
312 int hotSpotY)
313 : wxCursor(wxCURSOR_ARROW)
314
315{
316 wxImage cImage;
317
318 if (!cImage.CanRead(cursorName)) ::wxInitAllImageHandlers();
319
320 cImage.LoadFile(cursorName);
321
322 // wxMSW Bug???
323 // On Windows XP, conversion from wxImage to wxBitmap fails at the
324 // ::CreateDIBitmap() call unless a "compatible" dc is provided. Why??
325 // As a workaround, just make a simple wxDC for temporary use
326
327 wxBitmap tbmp(cImage.GetWidth(), cImage.GetHeight(), -1);
328 wxMemoryDC dwxdc;
329 dwxdc.SelectObject(tbmp);
330
331 // HCURSOR hcursor = wxBitmapToHCURSOR ( wxBitmap ( cImage, ( wxDC & )
332 // dwxdc ),
333 // hotSpotX, hotSpotY );
334 HCURSOR hcursor = NULL;
335
336 if (!hcursor) {
337 wxLogWarning(_T( "Failed to create ocpCursor." ));
338 return;
339 }
340
341 // Replace the HANDLE created in the base class constructor
342 // Probably leaks....
343 GetGDIImageData()->m_handle = hcursor;
344}
345
346ocpCursor::ocpCursor(const char** xpm_data, long type, int hotSpotX,
347 int hotSpotY)
348 : wxCursor(wxCURSOR_ARROW)
349
350{
351 wxImage cImage(xpm_data);
352
353 // wxMSW Bug???
354 // On Windows XP, conversion from wxImage to wxBitmap fails at the
355 // ::CreateDIBitmap() call unless a "compatible" dc is provided. Why??
356 // As a workaround, just make a simple wxDC for temporary use
357
358 wxBitmap tbmp(cImage.GetWidth(), cImage.GetHeight(), -1);
359 wxMemoryDC dwxdc;
360 dwxdc.SelectObject(tbmp);
361
362 // HCURSOR hcursor = wxBitmapToHCURSOR ( wxBitmap ( cImage, ( wxDC & )
363 // dwxdc ),
364 // hotSpotX, hotSpotY );
365
366 HCURSOR hcursor = NULL;
367
368 if (!hcursor) {
369 wxLogWarning(_T( "Failed to create ocpCursor." ));
370 return;
371 }
372
373 // Replace the HANDLE created in the base class constructor
374 // Probably leaks....
375 GetGDIImageData()->m_handle = hcursor;
376}
377#endif // __MSW
378
379#ifdef __WXOSX__ // begin rms
380ocpCursor::ocpCursor(const wxString& cursorName, long type, int hotSpotX,
381 int hotSpotY)
382 : wxCursor(wxCURSOR_ARROW)
383
384{
385 wxImage cImage;
386
387 if (!cImage.CanRead(cursorName)) ::wxInitAllImageHandlers();
388
389 cImage.LoadFile(cursorName);
390
391 // wxMSW Bug???
392 // On Windows XP, conversion from wxImage to wxBitmap fails at the
393 // ::CreateDIBitmap() call unless a "compatible" dc is provided. Why??
394 // As a workaround, just make a simple wxDC for temporary use
395
396 wxBitmap tbmp(cImage.GetWidth(), cImage.GetHeight(), -1);
397}
398
399//----------------------------------------------------------------------------------------------
400// A new constructor taking a static char ** of XPM data and assign as a
401// cursor
402//----------------------------------------------------------------------------------------------
403
404ocpCursor::ocpCursor(const char** xpm_data, long type, int hotSpotX,
405 int hotSpotY)
406 : wxCursor(wxCURSOR_ARROW)
407
408{
409 wxImage cImage(xpm_data);
410
411 wxBitmap tbmp(cImage.GetWidth(), cImage.GetHeight(), -1);
412}
413
414#endif // __WXOSX__ end rms
Platform specific wxCursor extension.