Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
wcursor.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2012 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "precompiled.h"
24 #include "lib/sysdep/cursor.h"
25 
26 #include "lib/sysdep/gfx.h"
27 #include "lib/sysdep/os/win/win.h"
29 
30 static sys_cursor cursor_from_HICON(HICON hIcon)
31 {
32  return (sys_cursor)(uintptr_t)hIcon;
33 }
34 
35 static sys_cursor cursor_from_HCURSOR(HCURSOR hCursor)
36 {
37  return (sys_cursor)(uintptr_t)hCursor;
38 }
39 
40 static HICON HICON_from_cursor(sys_cursor cursor)
41 {
42  return (HICON)(uintptr_t)cursor;
43 }
44 
45 static HCURSOR HCURSOR_from_cursor(sys_cursor cursor)
46 {
47  return (HCURSOR)(uintptr_t)cursor;
48 }
49 
50 
51 static Status sys_cursor_create_common(int w, int h, void* bgra_img, void* mask_img, int hx, int hy, sys_cursor* cursor)
52 {
53  *cursor = 0;
54 
55  // MSDN says selecting this HBITMAP into a DC is slower since we use
56  // CreateBitmap; bpp/format must be checked against those of the DC.
57  // this is the simplest way and we don't care about slight performance
58  // differences because this is typically only called once.
59  HBITMAP hbmColour = CreateBitmap(w, h, 1, 32, bgra_img);
60 
61  // CreateIconIndirect doesn't access this; we just need to pass
62  // an empty bitmap.
63  HBITMAP hbmMask = CreateBitmap(w, h, 1, 1, mask_img);
64 
65  // create the cursor (really an icon; they differ only in
66  // fIcon and the hotspot definitions).
67  ICONINFO ii;
68  ii.fIcon = FALSE; // cursor
69  ii.xHotspot = (DWORD)hx;
70  ii.yHotspot = (DWORD)hy;
71  ii.hbmMask = hbmMask;
72  ii.hbmColor = hbmColour;
73  HICON hIcon = CreateIconIndirect(&ii);
74 
75  // CreateIconIndirect makes copies, so we no longer need these.
76  DeleteObject(hbmMask);
77  DeleteObject(hbmColour);
78 
79  if(!wutil_IsValidHandle(hIcon))
81 
82  *cursor = cursor_from_HICON(hIcon);
83  return INFO::OK;
84 }
85 
86 Status sys_cursor_create(int w, int h, void* bgra_img, int hx, int hy, sys_cursor* cursor)
87 {
88  // alpha-blended cursors do not work on a 16-bit display
89  // (they get drawn as a black square), so refuse to load the
90  // cursor in that case
91  int bpp = 0;
92  RETURN_STATUS_IF_ERR(gfx::GetVideoMode(NULL, NULL, &bpp, NULL));
93  if (bpp <= 16)
94  return ERR::FAIL;
95 
96  return sys_cursor_create_common(w, h, bgra_img, NULL, hx, hy, cursor);
97 }
98 
100 {
101  // the mask gets ignored on 32-bit displays, but is used on 16-bit displays;
102  // setting it to 0xFF makes the cursor invisible (though I'm not quite
103  // sure why it's that way round)
104  u8 bgra_img[] = {0, 0, 0, 0};
105  u8 mask_img[] = {0xFF};
106  return sys_cursor_create_common(1, 1, bgra_img, mask_img, 0, 0, cursor);
107 }
108 
109 
111 {
112  // restore default cursor.
113  if(!cursor)
114  cursor = cursor_from_HCURSOR(LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW)));
115 
116  (void)SetCursor(HCURSOR_from_cursor(cursor));
117  // return value (previous cursor) is useless.
118 
119  return INFO::OK;
120 }
121 
122 
124 {
125  // bail now to prevent potential confusion below; there's nothing to do.
126  if(!cursor)
127  return INFO::OK;
128 
129  // if the cursor being freed is active, restore the default arrow
130  // (just for safety).
131  if(cursor_from_HCURSOR(GetCursor()) == cursor)
133 
134  if(!DestroyIcon(HICON_from_cursor(cursor)))
136  return INFO::OK;
137 }
138 
140 {
141  return INFO::OK;
142 }
#define u8
Definition: types.h:39
JSBool SetCursor(JSContext *cx, uintN argc, jsval *vp)
Definition: ScriptGlue.cpp:203
#define WARN_IF_ERR(expression)
Definition: status.h:265
const Status OK
Definition: status.h:386
bool wutil_IsValidHandle(H h)
Definition: wutil.h:34
void * sys_cursor
Definition: cursor.h:30
Status sys_cursor_create(int w, int h, void *bgra_img, int hx, int hy, sys_cursor *cursor)
Create a cursor from the given color image.
Definition: android.cpp:72
Status sys_cursor_reset()
reset any cached cursor data.
Definition: android.cpp:116
LIB_API Status GetVideoMode(int *xres, int *yres, int *bpp, int *freq)
(useful for choosing a new video mode)
Definition: android.cpp:47
static sys_cursor cursor_from_HICON(HICON hIcon)
Definition: wcursor.cpp:30
Status sys_cursor_create_empty(sys_cursor *cursor)
Create a transparent cursor (used to hide the system cursor).
Definition: android.cpp:85
static sys_cursor cursor_from_HCURSOR(HCURSOR hCursor)
Definition: wcursor.cpp:35
static HICON HICON_from_cursor(sys_cursor cursor)
Definition: wcursor.cpp:40
unsigned long DWORD
Definition: wgl.h:56
static Status sys_cursor_create_common(int w, int h, void *bgra_img, void *mask_img, int hx, int hy, sys_cursor *cursor)
Definition: wcursor.cpp:51
Status StatusFromWin()
Definition: wutil.cpp:125
i64 Status
Error handling system.
Definition: status.h:171
static HCURSOR HCURSOR_from_cursor(sys_cursor cursor)
Definition: wcursor.cpp:45
#define WARN_RETURN(status)
Definition: status.h:255
Status sys_cursor_set(sys_cursor cursor)
override the current system cursor.
Definition: android.cpp:93
const Status FAIL
Definition: status.h:406
Status sys_cursor_free(sys_cursor cursor)
destroy the indicated cursor and frees its resources.
Definition: android.cpp:105
#define RETURN_STATUS_IF_ERR(expression)
Definition: status.h:276