]> git.saurik.com Git - wxWidgets.git/blame - src/msw/cursor.cpp
unapplied part of Dimitri's patch at his request
[wxWidgets.git] / src / msw / cursor.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: cursor.cpp
3// Purpose: wxCursor class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
6bf57206 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
0d0512bd
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17 20#ifdef __GNUG__
0d0512bd 21 #pragma implementation "cursor.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
0d0512bd 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
0d0512bd
VZ
32 #include "wx/list.h"
33 #include "wx/utils.h"
34 #include "wx/app.h"
fef15b42 35 #include "wx/bitmap.h"
0d0512bd 36 #include "wx/icon.h"
fef15b42 37 #include "wx/cursor.h"
2bda0e17
KB
38#endif
39
2b0b4c55 40#include "wx/module.h"
2bda0e17 41#include "wx/msw/private.h"
04ef50df 42#ifndef __WXMICROWIN__
2bda0e17 43#include "wx/msw/dib.h"
04ef50df 44#endif
2bda0e17 45
47d67540 46#if wxUSE_RESOURCE_LOADING_IN_MSW
0d0512bd
VZ
47 #include "wx/msw/curico.h"
48 #include "wx/msw/curicop.h"
2bda0e17
KB
49#endif
50
0d0512bd
VZ
51// ----------------------------------------------------------------------------
52// wxWin macros
53// ----------------------------------------------------------------------------
54
621b3e21 55IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxGDIObject)
bfbd6dc1
VZ
56
57// ----------------------------------------------------------------------------
58// globals
59// ----------------------------------------------------------------------------
60
61// Current cursor, in order to hang on to cursor handle when setting the cursor
62// globally
63static wxCursor *gs_globalCursor = NULL;
64
65// ----------------------------------------------------------------------------
66// private classes
67// ----------------------------------------------------------------------------
68
69class wxCursorModule : public wxModule
70{
71public:
72 virtual bool OnInit()
73 {
74 gs_globalCursor = new wxCursor;
75
76 return TRUE;
77 }
78
79 virtual void OnExit()
80 {
81 delete gs_globalCursor;
82 gs_globalCursor = (wxCursor *)NULL;
83 }
84};
85
86// ============================================================================
87// implementation
88// ============================================================================
2bda0e17 89
0d0512bd
VZ
90// ----------------------------------------------------------------------------
91// wxCursorRefData
92// ----------------------------------------------------------------------------
93
94wxCursorRefData::wxCursorRefData()
2bda0e17 95{
0d0512bd
VZ
96 m_width = 32;
97 m_height = 32;
98
f20ad12c 99 m_destroyCursor = TRUE;
2bda0e17
KB
100}
101
0d0512bd 102void wxCursorRefData::Free()
2bda0e17 103{
032af30f
VZ
104 if ( m_hCursor )
105 {
04ef50df 106#ifndef __WXMICROWIN__
032af30f
VZ
107 if ( m_destroyCursor )
108 ::DestroyCursor((HCURSOR)m_hCursor);
04ef50df 109#endif
032af30f
VZ
110
111 m_hCursor = 0;
112 }
2bda0e17
KB
113}
114
0d0512bd 115// ----------------------------------------------------------------------------
2bda0e17 116// Cursors
0d0512bd
VZ
117// ----------------------------------------------------------------------------
118
119wxCursor::wxCursor()
2bda0e17
KB
120{
121}
122
bff4ec63
VZ
123wxCursor::wxCursor( const wxImage & image )
124{
125 //image has to be 32x32
126 wxImage image32 = image.Scale(32,32);
127 unsigned char * rgbBits = image32.GetData();
128 int w = image32.GetWidth() ;
129 int h = image32.GetHeight() ;
130 bool bHasMask = image32.HasMask() ;
131 int imagebitcount = (w*h)/8;
132
133 unsigned char r, g, b ;
134 unsigned char * bits = new unsigned char [imagebitcount];
135 unsigned char * maskBits = new unsigned char [imagebitcount];
136
137 int i,j, i8; unsigned char c, cMask;
138 for (i=0; i<imagebitcount; i++)
139 {
140 bits[i] = 0;
141 i8 = i * 8;
142//unlike gtk, the pixels go in the opposite order in the bytes
143 cMask = 128;
144 for (j=0; j<8; j++)
145 {
146 // possible overflow if we do the summation first ?
147 c = rgbBits[(i8+j)*3]/3 + rgbBits[(i8+j)*3+1]/3 + rgbBits[(i8+j)*3+2]/3 ;
148 //if average value is > mid grey
149 if (c>127)
150 bits[i] = bits[i] | cMask ;
151 cMask = cMask / 2 ;
152 }
153 }
154 if (bHasMask)
155 {
156 r = image32.GetMaskRed() ;
157 g = image32.GetMaskGreen() ;
158 b = image32.GetMaskBlue() ;
159
160 for (i=0; i<imagebitcount; i++)
161 {
162 maskBits[i] = 0x0;
163 i8 = i * 8;
164
165 cMask = 128;
166 for (j=0; j<8; j++)
167 {
168 if (rgbBits[(i8+j)*3] == r && rgbBits[(i8+j)*3+1] == g && rgbBits[(i8+j)*3+2] == b)
169 maskBits[i] = maskBits[i] | cMask ;
170 cMask = cMask / 2 ;
171 }
172 }
173 }
174 else
175 {
176 for (i=0; i<imagebitcount; i++)
177 maskBits[i]= 0x0 ;
178 }
179
180 int hotSpotX = image32.GetOptionInt(wxCUR_HOTSPOT_X);
181 int hotSpotY = image32.GetOptionInt(wxCUR_HOTSPOT_Y);
182 if (hotSpotX < 0 || hotSpotX >= w)
183 hotSpotX = 0;
184 if (hotSpotY < 0 || hotSpotY >= h)
185 hotSpotY = 0;
186
187 wxCursorRefData *refData = new wxCursorRefData;
188 m_refData = refData;
189 refData->m_hCursor = (WXHCURSOR) CreateCursor ( wxGetInstance(), hotSpotX, hotSpotY, w, h, /*AND*/ maskBits, /*XOR*/ bits );
15dadf31 190
bff4ec63
VZ
191 delete [] bits ;
192 delete [] maskBits;
193
194}
195
0d0512bd
VZ
196wxCursor::wxCursor(const char WXUNUSED(bits)[],
197 int WXUNUSED(width),
198 int WXUNUSED(height),
199 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY),
200 const char WXUNUSED(maskBits)[])
2bda0e17
KB
201{
202}
203
0d0512bd
VZ
204wxCursor::wxCursor(const wxString& cursor_file,
205 long flags,
206 int hotSpotX, int hotSpotY)
2bda0e17 207{
04ef50df
JS
208#ifdef __WXMICROWIN__
209 m_refData = NULL;
210#else
0d0512bd
VZ
211 wxCursorRefData *refData = new wxCursorRefData;
212 m_refData = refData;
2bda0e17 213
0d0512bd
VZ
214 if (flags == wxBITMAP_TYPE_CUR_RESOURCE)
215 {
2f851133 216#ifdef __WIN95__
0d0512bd 217 refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, 0);
2f851133 218#else
0d0512bd 219 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), cursor_file);
2f851133 220#endif
0d0512bd
VZ
221 }
222 else if (flags == wxBITMAP_TYPE_CUR)
223 {
2f851133 224#ifdef __WIN95__
0d0512bd 225 refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
2f851133 226#else
47d67540 227#if wxUSE_RESOURCE_LOADING_IN_MSW
0d0512bd 228 refData->m_hCursor = (WXHCURSOR) ReadCursorFile(WXSTRINGCAST cursor_file, wxGetInstance(), &refData->m_width, &refData->m_height);
2f851133 229#endif
2bda0e17 230#endif
0d0512bd
VZ
231 }
232 else if (flags == wxBITMAP_TYPE_ICO)
233 {
47d67540 234#if wxUSE_RESOURCE_LOADING_IN_MSW
0d0512bd 235 refData->m_hCursor = (WXHCURSOR) IconToCursor(WXSTRINGCAST cursor_file, wxGetInstance(), hotSpotX, hotSpotY, &refData->m_width, &refData->m_height);
2bda0e17 236#endif
0d0512bd
VZ
237 }
238 else if (flags == wxBITMAP_TYPE_BMP)
239 {
47d67540 240#if wxUSE_RESOURCE_LOADING_IN_MSW
0d0512bd
VZ
241 HBITMAP hBitmap = 0;
242 HPALETTE hPalette = 0;
243 bool success = wxReadDIB(WXSTRINGCAST cursor_file, &hBitmap, &hPalette) != 0;
244 if (!success)
245 return;
246 if (hPalette)
247 DeleteObject(hPalette);
248 POINT pnt;
249 pnt.x = hotSpotX;
250 pnt.y = hotSpotY;
251 refData->m_hCursor = (WXHCURSOR) MakeCursorFromBitmap(wxGetInstance(), hBitmap, &pnt);
0d0512bd 252 DeleteObject(hBitmap);
2bda0e17 253#endif
0d0512bd
VZ
254 }
255
256#if WXWIN_COMPATIBILITY_2
257 refData->SetOk();
258#endif // WXWIN_COMPATIBILITY_2
04ef50df
JS
259
260#endif
2bda0e17
KB
261}
262
263// Cursors by stock number
debe6624 264wxCursor::wxCursor(int cursor_type)
2bda0e17 265{
04ef50df
JS
266#ifdef __WXMICROWIN__
267 m_refData = NULL;
268#else
0d0512bd
VZ
269 wxCursorRefData *refData = new wxCursorRefData;
270 m_refData = refData;
2bda0e17
KB
271
272 switch (cursor_type)
273 {
83f96286 274 case wxCURSOR_ARROWWAIT:
788722ac 275#ifndef __WIN16__
83f96286
RD
276 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_APPSTARTING);
277 break;
788722ac 278#endif
2bda0e17 279 case wxCURSOR_WAIT:
0d0512bd 280 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_WAIT);
2bda0e17
KB
281 break;
282 case wxCURSOR_IBEAM:
0d0512bd 283 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_IBEAM);
2bda0e17
KB
284 break;
285 case wxCURSOR_CROSS:
0d0512bd 286 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_CROSS);
2bda0e17
KB
287 break;
288 case wxCURSOR_SIZENWSE:
0d0512bd 289 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENWSE);
2bda0e17
KB
290 break;
291 case wxCURSOR_SIZENESW:
0d0512bd 292 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENESW);
2bda0e17
KB
293 break;
294 case wxCURSOR_SIZEWE:
0d0512bd 295 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZEWE);
2bda0e17
KB
296 break;
297 case wxCURSOR_SIZENS:
0d0512bd 298 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENS);
2bda0e17
KB
299 break;
300 case wxCURSOR_CHAR:
301 {
0d0512bd 302 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
2bda0e17
KB
303 break;
304 }
305 case wxCURSOR_HAND:
306 {
0d0512bd 307 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_HAND"));
2bda0e17
KB
308 break;
309 }
310 case wxCURSOR_BULLSEYE:
311 {
0d0512bd 312 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BULLSEYE"));
2bda0e17
KB
313 break;
314 }
315 case wxCURSOR_PENCIL:
316 {
0d0512bd 317 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PENCIL"));
2bda0e17
KB
318 break;
319 }
320 case wxCURSOR_MAGNIFIER:
321 {
0d0512bd 322 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_MAGNIFIER"));
2bda0e17
KB
323 break;
324 }
325 case wxCURSOR_NO_ENTRY:
326 {
0d0512bd 327 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_NO_ENTRY"));
2bda0e17
KB
328 break;
329 }
330 case wxCURSOR_LEFT_BUTTON:
331 {
0d0512bd 332 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
2bda0e17
KB
333 break;
334 }
335 case wxCURSOR_RIGHT_BUTTON:
336 {
0d0512bd 337 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
2bda0e17
KB
338 break;
339 }
340 case wxCURSOR_MIDDLE_BUTTON:
341 {
0d0512bd 342 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
2bda0e17
KB
343 break;
344 }
345 case wxCURSOR_SIZING:
346 {
0d0512bd 347 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_SIZING"));
2bda0e17
KB
348 break;
349 }
350 case wxCURSOR_WATCH:
351 {
0d0512bd 352 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_WATCH"));
2bda0e17
KB
353 break;
354 }
355 case wxCURSOR_SPRAYCAN:
356 {
0d0512bd 357 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_ROLLER"));
2bda0e17
KB
358 break;
359 }
360 case wxCURSOR_PAINT_BRUSH:
361 {
0d0512bd 362 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PBRUSH"));
2bda0e17
KB
363 break;
364 }
365 case wxCURSOR_POINT_LEFT:
366 {
0d0512bd 367 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PLEFT"));
2bda0e17
KB
368 break;
369 }
370 case wxCURSOR_POINT_RIGHT:
371 {
0d0512bd 372 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PRIGHT"));
2bda0e17
KB
373 break;
374 }
375 case wxCURSOR_QUESTION_ARROW:
376 {
b96340e6 377// refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), wxT("wxCURSOR_QARROW"), IMAGE_CURSOR, 16, 16, LR_MONOCHROME);
0d0512bd 378 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_QARROW"));
2bda0e17
KB
379 break;
380 }
381 case wxCURSOR_BLANK:
382 {
0d0512bd 383 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BLANK"));
2bda0e17
KB
384 break;
385 }
15dadf31
RD
386 case wxCURSOR_RIGHT_ARROW:
387 {
388 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_RIGHT_ARROW"));
389 break;
390 }
2bda0e17
KB
391 default:
392 case wxCURSOR_ARROW:
0d0512bd 393 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
2bda0e17
KB
394 break;
395 }
771a855f
VZ
396
397 // no need to destroy the stock cursors
d2913c40
JS
398 // TODO: check this
399 //m_refData->m_destroyCursor = FALSE;
400#endif
2bda0e17
KB
401}
402
0d0512bd 403wxCursor::~wxCursor()
2bda0e17 404{
2bda0e17
KB
405}
406
0d0512bd 407// ----------------------------------------------------------------------------
2bda0e17 408// Global cursor setting
0d0512bd
VZ
409// ----------------------------------------------------------------------------
410
bfbd6dc1 411const wxCursor *wxGetGlobalCursor()
2bda0e17 412{
bfbd6dc1
VZ
413 return gs_globalCursor;
414}
2bda0e17 415
bfbd6dc1
VZ
416void wxSetCursor(const wxCursor& cursor)
417{
418 if ( cursor.Ok() )
6bf57206 419 {
04ef50df 420#ifndef __WXMICROWIN__
bfbd6dc1 421 ::SetCursor(GetHcursorOf(cursor));
04ef50df 422#endif
6bf57206 423
bfbd6dc1
VZ
424 if ( gs_globalCursor )
425 *gs_globalCursor = cursor;
6bf57206 426 }
2bda0e17
KB
427}
428
429