~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/msw/cursor.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/msw/cursor.cpp
 
3
// Purpose:     wxCursor class
 
4
// Author:      Julian Smart
 
5
// Modified by:
 
6
// Created:     01/02/97
 
7
// Copyright:   (c) 1997-2003 Julian Smart and Vadim Zeitlin
 
8
// Licence:     wxWindows licence
 
9
/////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
// ============================================================================
 
12
// declarations
 
13
// ============================================================================
 
14
 
 
15
// ----------------------------------------------------------------------------
 
16
// headers
 
17
// ----------------------------------------------------------------------------
 
18
 
 
19
// For compilers that support precompilation, includes "wx.h".
 
20
#include "wx/wxprec.h"
 
21
 
 
22
#ifdef __BORLANDC__
 
23
    #pragma hdrstop
 
24
#endif
 
25
 
 
26
#include "wx/cursor.h"
 
27
 
 
28
#ifndef WX_PRECOMP
 
29
    #include "wx/utils.h"
 
30
    #include "wx/app.h"
 
31
    #include "wx/bitmap.h"
 
32
    #include "wx/icon.h"
 
33
    #include "wx/settings.h"
 
34
    #include "wx/intl.h"
 
35
    #include "wx/image.h"
 
36
    #include "wx/module.h"
 
37
#endif
 
38
 
 
39
#include "wx/msw/private.h"
 
40
#include "wx/msw/missing.h" // IDC_HAND
 
41
 
 
42
// define functions missing in MicroWin
 
43
#ifdef __WXMICROWIN__
 
44
    static inline void DestroyCursor(HCURSOR) { }
 
45
    static inline void SetCursor(HCURSOR) { }
 
46
#endif // __WXMICROWIN__
 
47
 
 
48
// ----------------------------------------------------------------------------
 
49
// private classes
 
50
// ----------------------------------------------------------------------------
 
51
 
 
52
class WXDLLEXPORT wxCursorRefData : public wxGDIImageRefData
 
53
{
 
54
public:
 
55
    // the second parameter is used to tell us to delete the cursor when we're
 
56
    // done with it (normally we shouldn't call DestroyCursor() this is why it
 
57
    // doesn't happen by default)
 
58
    wxCursorRefData(HCURSOR hcursor = 0, bool takeOwnership = false);
 
59
 
 
60
    virtual ~wxCursorRefData() { Free(); }
 
61
 
 
62
    virtual void Free();
 
63
 
 
64
 
 
65
    // return the size of the standard cursor: notice that the system only
 
66
    // supports the cursors of this size
 
67
    static wxCoord GetStandardWidth();
 
68
    static wxCoord GetStandardHeight();
 
69
 
 
70
private:
 
71
    bool m_destroyCursor;
 
72
 
 
73
    // standard cursor size, computed on first use
 
74
    static wxSize ms_sizeStd;
 
75
};
 
76
 
 
77
// ----------------------------------------------------------------------------
 
78
// wxWin macros
 
79
// ----------------------------------------------------------------------------
 
80
 
 
81
IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxGDIObject)
 
82
 
 
83
// ----------------------------------------------------------------------------
 
84
// globals
 
85
// ----------------------------------------------------------------------------
 
86
 
 
87
// Current cursor, in order to hang on to cursor handle when setting the cursor
 
88
// globally
 
89
static wxCursor *gs_globalCursor = NULL;
 
90
 
 
91
// ----------------------------------------------------------------------------
 
92
// private classes
 
93
// ----------------------------------------------------------------------------
 
94
 
 
95
class wxCursorModule : public wxModule
 
96
{
 
97
public:
 
98
    virtual bool OnInit()
 
99
    {
 
100
        gs_globalCursor = new wxCursor;
 
101
 
 
102
        return true;
 
103
    }
 
104
 
 
105
    virtual void OnExit()
 
106
    {
 
107
        wxDELETE(gs_globalCursor);
 
108
    }
 
109
};
 
110
 
 
111
// ============================================================================
 
112
// implementation
 
113
// ============================================================================
 
114
 
 
115
// ----------------------------------------------------------------------------
 
116
// wxCursorRefData
 
117
// ----------------------------------------------------------------------------
 
118
 
 
119
wxSize wxCursorRefData::ms_sizeStd;
 
120
 
 
121
wxCoord wxCursorRefData::GetStandardWidth()
 
122
{
 
123
    if ( !ms_sizeStd.x )
 
124
        ms_sizeStd.x = wxSystemSettings::GetMetric(wxSYS_CURSOR_X);
 
125
 
 
126
    return ms_sizeStd.x;
 
127
}
 
128
 
 
129
wxCoord wxCursorRefData::GetStandardHeight()
 
130
{
 
131
    if ( !ms_sizeStd.y )
 
132
        ms_sizeStd.y = wxSystemSettings::GetMetric(wxSYS_CURSOR_Y);
 
133
 
 
134
    return ms_sizeStd.y;
 
135
}
 
136
 
 
137
wxCursorRefData::wxCursorRefData(HCURSOR hcursor, bool destroy)
 
138
{
 
139
    m_hCursor = (WXHCURSOR)hcursor;
 
140
 
 
141
    if ( m_hCursor )
 
142
    {
 
143
        m_width = GetStandardWidth();
 
144
        m_height = GetStandardHeight();
 
145
    }
 
146
 
 
147
    m_destroyCursor = destroy;
 
148
}
 
149
 
 
150
void wxCursorRefData::Free()
 
151
{
 
152
    if ( m_hCursor )
 
153
    {
 
154
#ifndef __WXWINCE__
 
155
        if ( m_destroyCursor )
 
156
            ::DestroyCursor((HCURSOR)m_hCursor);
 
157
#endif
 
158
 
 
159
        m_hCursor = 0;
 
160
    }
 
161
}
 
162
 
 
163
// ----------------------------------------------------------------------------
 
164
// Cursors
 
165
// ----------------------------------------------------------------------------
 
166
 
 
167
wxCursor::wxCursor()
 
168
{
 
169
}
 
170
 
 
171
#if wxUSE_IMAGE
 
172
wxCursor::wxCursor(const wxImage& image)
 
173
{
 
174
    // image has to be of the standard cursor size, otherwise we won't be able
 
175
    // to create it
 
176
    const int w = wxCursorRefData::GetStandardWidth();
 
177
    const int h = wxCursorRefData::GetStandardHeight();
 
178
 
 
179
    int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
 
180
    int hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
 
181
    int image_w = image.GetWidth();
 
182
    int image_h = image.GetHeight();
 
183
 
 
184
    wxASSERT_MSG( hotSpotX >= 0 && hotSpotX < image_w &&
 
185
                  hotSpotY >= 0 && hotSpotY < image_h,
 
186
                  wxT("invalid cursor hot spot coordinates") );
 
187
 
 
188
    wxImage imageSized(image); // final image of correct size
 
189
 
 
190
    // if image is too small then place it in the center, resize it if too big
 
191
    if ((w > image_w) && (h > image_h))
 
192
    {
 
193
        wxPoint offset((w - image_w)/2, (h - image_h)/2);
 
194
        hotSpotX = hotSpotX + offset.x;
 
195
        hotSpotY = hotSpotY + offset.y;
 
196
 
 
197
        imageSized = image.Size(wxSize(w, h), offset);
 
198
    }
 
199
    else if ((w != image_w) || (h != image_h))
 
200
    {
 
201
        hotSpotX = int(hotSpotX * double(w) / double(image_w));
 
202
        hotSpotY = int(hotSpotY * double(h) / double(image_h));
 
203
 
 
204
        imageSized = image.Scale(w, h);
 
205
    }
 
206
 
 
207
    HCURSOR hcursor = wxBitmapToHCURSOR( wxBitmap(imageSized),
 
208
                                         hotSpotX, hotSpotY );
 
209
 
 
210
    if ( !hcursor )
 
211
    {
 
212
        wxLogWarning(_("Failed to create cursor."));
 
213
        return;
 
214
    }
 
215
 
 
216
    m_refData = new wxCursorRefData(hcursor, true /* delete it later */);
 
217
}
 
218
#endif // wxUSE_IMAGE
 
219
 
 
220
// MicroWin doesn't have support needed for the other ctors
 
221
#ifdef __WXMICROWIN__
 
222
 
 
223
wxCursor::InitFromStock(wxStockCursor WXUNUSED(cursor_type))
 
224
{
 
225
}
 
226
 
 
227
#else // !__WXMICROWIN__
 
228
 
 
229
wxCursor::wxCursor(const wxString& filename,
 
230
                   wxBitmapType kind,
 
231
                   int hotSpotX,
 
232
                   int hotSpotY)
 
233
{
 
234
    HCURSOR hcursor;
 
235
    switch ( kind )
 
236
    {
 
237
        case wxBITMAP_TYPE_CUR_RESOURCE:
 
238
            hcursor = ::LoadCursor(wxGetInstance(), filename.t_str());
 
239
            break;
 
240
 
 
241
#ifndef __WXWINCE__
 
242
        case wxBITMAP_TYPE_ANI:
 
243
        case wxBITMAP_TYPE_CUR:
 
244
            hcursor = ::LoadCursorFromFile(filename.t_str());
 
245
            break;
 
246
#endif
 
247
 
 
248
        case wxBITMAP_TYPE_ICO:
 
249
            hcursor = wxBitmapToHCURSOR
 
250
                      (
 
251
                       wxIcon(filename, wxBITMAP_TYPE_ICO),
 
252
                       hotSpotX,
 
253
                       hotSpotY
 
254
                      );
 
255
            break;
 
256
 
 
257
        case wxBITMAP_TYPE_BMP:
 
258
            hcursor = wxBitmapToHCURSOR
 
259
                      (
 
260
                       wxBitmap(filename, wxBITMAP_TYPE_BMP),
 
261
                       hotSpotX,
 
262
                       hotSpotY
 
263
                      );
 
264
            break;
 
265
 
 
266
        default:
 
267
            wxLogError( wxT("unknown cursor resource type '%d'"), kind );
 
268
 
 
269
            hcursor = NULL;
 
270
    }
 
271
 
 
272
    if ( hcursor )
 
273
    {
 
274
        m_refData = new wxCursorRefData(hcursor, true /* delete it later */);
 
275
    }
 
276
}
 
277
 
 
278
namespace
 
279
{
 
280
 
 
281
void ReverseBitmap(HBITMAP bitmap, int width, int height)
 
282
{
 
283
    MemoryHDC hdc;
 
284
    SelectInHDC selBitmap(hdc, bitmap);
 
285
    ::StretchBlt(hdc, width - 1, 0, -width, height,
 
286
                 hdc, 0, 0, width, height, SRCCOPY);
 
287
}
 
288
 
 
289
HCURSOR CreateReverseCursor(HCURSOR cursor)
 
290
{
 
291
    ICONINFO info;
 
292
    if ( !::GetIconInfo(cursor, &info) )
 
293
        return NULL;
 
294
 
 
295
    HCURSOR cursorRev = NULL;
 
296
 
 
297
    BITMAP bmp;
 
298
    if ( ::GetObject(info.hbmMask, sizeof(bmp), &bmp) )
 
299
    {
 
300
        ReverseBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight);
 
301
        if ( info.hbmColor )
 
302
            ReverseBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight);
 
303
        info.xHotspot = (DWORD)bmp.bmWidth - 1 - info.xHotspot;
 
304
 
 
305
        cursorRev = ::CreateIconIndirect(&info);
 
306
    }
 
307
 
 
308
    ::DeleteObject(info.hbmMask);
 
309
    if ( info.hbmColor )
 
310
        ::DeleteObject(info.hbmColor);
 
311
 
 
312
    return cursorRev;
 
313
}
 
314
 
 
315
} // anonymous namespace
 
316
 
 
317
// Cursors by stock number
 
318
void wxCursor::InitFromStock(wxStockCursor idCursor)
 
319
{
 
320
    // all wxWidgets standard cursors
 
321
    static const struct StdCursor
 
322
    {
 
323
        // is this a standard Windows cursor?
 
324
        bool isStd;
 
325
 
 
326
        // the cursor name or id
 
327
        LPCTSTR name;
 
328
    } stdCursors[] =
 
329
    {
 
330
        {  true, NULL                        }, // wxCURSOR_NONE
 
331
        {  true, IDC_ARROW                   }, // wxCURSOR_ARROW
 
332
        { false, wxT("WXCURSOR_RIGHT_ARROW")  }, // wxCURSOR_RIGHT_ARROW
 
333
        { false, wxT("WXCURSOR_BULLSEYE")     }, // wxCURSOR_BULLSEYE
 
334
        {  true, IDC_ARROW                   }, // WXCURSOR_CHAR
 
335
        {  true, IDC_CROSS                   }, // WXCURSOR_CROSS
 
336
        {  true, IDC_HAND                    }, // wxCURSOR_HAND
 
337
        {  true, IDC_IBEAM                   }, // WXCURSOR_IBEAM
 
338
        {  true, IDC_ARROW                   }, // WXCURSOR_LEFT_BUTTON
 
339
        { false, wxT("WXCURSOR_MAGNIFIER")    }, // wxCURSOR_MAGNIFIER
 
340
        {  true, IDC_ARROW                   }, // WXCURSOR_MIDDLE_BUTTON
 
341
        {  true, IDC_NO                      }, // WXCURSOR_NO_ENTRY
 
342
        { false, wxT("WXCURSOR_PBRUSH")       }, // wxCURSOR_PAINT_BRUSH
 
343
        { false, wxT("WXCURSOR_PENCIL")       }, // wxCURSOR_PENCIL
 
344
        { false, wxT("WXCURSOR_PLEFT")        }, // wxCURSOR_POINT_LEFT
 
345
        { false, wxT("WXCURSOR_PRIGHT")       }, // wxCURSOR_POINT_RIGHT
 
346
        {  true, IDC_HELP                    }, // WXCURSOR_QUESTION_ARROW
 
347
        {  true, IDC_ARROW                   }, // WXCURSOR_RIGHT_BUTTON
 
348
        {  true, IDC_SIZENESW                }, // WXCURSOR_SIZENESW
 
349
        {  true, IDC_SIZENS                  }, // WXCURSOR_SIZENS
 
350
        {  true, IDC_SIZENWSE                }, // WXCURSOR_SIZENWSE
 
351
        {  true, IDC_SIZEWE                  }, // WXCURSOR_SIZEWE
 
352
        {  true, IDC_SIZEALL                 }, // WXCURSOR_SIZING
 
353
        { false, wxT("WXCURSOR_PBRUSH")       }, // wxCURSOR_SPRAYCAN
 
354
        {  true, IDC_WAIT                    }, // WXCURSOR_WAIT
 
355
        {  true, IDC_WAIT                    }, // WXCURSOR_WATCH
 
356
        { false, wxT("WXCURSOR_BLANK")        }, // wxCURSOR_BLANK
 
357
        {  true, IDC_APPSTARTING             }, // wxCURSOR_ARROWWAIT
 
358
 
 
359
        // no entry for wxCURSOR_MAX
 
360
    };
 
361
 
 
362
    wxCOMPILE_TIME_ASSERT( WXSIZEOF(stdCursors) == wxCURSOR_MAX,
 
363
                           CursorsIdArrayMismatch );
 
364
 
 
365
    wxCHECK_RET( idCursor > 0 && (size_t)idCursor < WXSIZEOF(stdCursors),
 
366
                 wxT("invalid cursor id in wxCursor() ctor") );
 
367
 
 
368
    const StdCursor& stdCursor = stdCursors[idCursor];
 
369
    bool deleteLater = !stdCursor.isStd;
 
370
 
 
371
    HCURSOR hcursor = ::LoadCursor(stdCursor.isStd ? NULL : wxGetInstance(),
 
372
                                   stdCursor.name);
 
373
 
 
374
    // IDC_HAND may not be available on some versions of Windows.
 
375
    if ( !hcursor && idCursor == wxCURSOR_HAND)
 
376
    {
 
377
        hcursor = ::LoadCursor(wxGetInstance(), wxT("WXCURSOR_HAND"));
 
378
        deleteLater = true;
 
379
    }
 
380
 
 
381
    if ( !hcursor && idCursor == wxCURSOR_RIGHT_ARROW)
 
382
    {
 
383
        hcursor = ::LoadCursor(NULL, IDC_ARROW);
 
384
        if ( hcursor )
 
385
        {
 
386
            hcursor = CreateReverseCursor(hcursor);
 
387
            deleteLater = true;
 
388
        }
 
389
    }
 
390
 
 
391
    if ( !hcursor )
 
392
    {
 
393
        if ( !stdCursor.isStd )
 
394
        {
 
395
            // it may be not obvious to the programmer why did loading fail,
 
396
            // try to help by pointing to the by far the most probable reason
 
397
            wxFAIL_MSG(wxT("Loading a cursor defined by wxWidgets failed, ")
 
398
                       wxT("did you include include/wx/msw/wx.rc file from ")
 
399
                       wxT("your resource file?"));
 
400
        }
 
401
 
 
402
        wxLogLastError(wxT("LoadCursor"));
 
403
    }
 
404
    else
 
405
    {
 
406
        m_refData = new wxCursorRefData(hcursor, deleteLater);
 
407
    }
 
408
}
 
409
 
 
410
#endif // __WXMICROWIN__/!__WXMICROWIN__
 
411
 
 
412
wxCursor::~wxCursor()
 
413
{
 
414
}
 
415
 
 
416
// ----------------------------------------------------------------------------
 
417
// other wxCursor functions
 
418
// ----------------------------------------------------------------------------
 
419
 
 
420
wxGDIImageRefData *wxCursor::CreateData() const
 
421
{
 
422
    return new wxCursorRefData;
 
423
}
 
424
 
 
425
// ----------------------------------------------------------------------------
 
426
// Global cursor setting
 
427
// ----------------------------------------------------------------------------
 
428
 
 
429
const wxCursor *wxGetGlobalCursor()
 
430
{
 
431
    return gs_globalCursor;
 
432
}
 
433
 
 
434
void wxSetCursor(const wxCursor& cursor)
 
435
{
 
436
    if ( cursor.IsOk() )
 
437
    {
 
438
        ::SetCursor(GetHcursorOf(cursor));
 
439
 
 
440
        if ( gs_globalCursor )
 
441
            *gs_globalCursor = cursor;
 
442
    }
 
443
}