1 #include "win32\win32guts.h"
2 #ifndef _APRICOT_H_
3 #include "apricot.h"
4 #endif
5 #include "guts.h"
6 #include "Window.h"
7 #include "Icon.h"
8 #include "Application.h"
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14
15 #define sys (( PDrawableData)(( PComponent) self)-> sysData)->
16 #define dsys( view) (( PDrawableData)(( PComponent) view)-> sysData)->
17 #define var (( PWidget) self)->
18 #define HANDLE sys handle
19 #define DHANDLE(x) dsys(x) handle
20
21 static unsigned char cursor_dnd_move[] = {
22 0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
23 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
24 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
25 0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
26 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
27 0x15,0x54,0x00,0x00,0x2A,0xAA,0x00,0x00,0x10,0x04,0x00,0x00,0x20,0x02,0x00,0x00,
28 0x10,0x04,0x00,0x00,0x20,0x02,0x00,0x00,0x10,0x04,0x00,0x00,0x29,0xAA,0x00,0x00,
29 0x15,0x94,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
30 0x46,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,
31 0x7F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
32 0x70,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
33 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
34 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
35 0xC0,0x01,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0xCF,0xF9,0xFF,0xFF,0xCF,0xF9,0xFF,0xFF,
36 0xCF,0xF9,0xFF,0xFF,0xCF,0xF9,0xFF,0xFF,0xCE,0x39,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,
37 0xC0,0x01,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0x78,0x7F,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
38 0x10,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,
39 0x00,0x7F,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
40 0x07,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,
41 0x7F,0xFF,0xFF,0xFF
42 };
43
44 static unsigned char cursor_dnd_copy[] = {
45 0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
46 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
47 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
48 0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,
49 0x00,0x1F,0xF0,0x00,0x00,0x1E,0xF0,0x00,0x00,0x1E,0xF0,0x00,0x00,0x18,0x30,0x00,
50 0x15,0x5E,0xF0,0x00,0x2A,0x9E,0xF0,0x00,0x10,0x1F,0xF0,0x00,0x20,0x1F,0xF0,0x00,
51 0x10,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x10,0x04,0x00,0x00,0x29,0xAA,0x00,0x00,
52 0x15,0x94,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
53 0x46,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,
54 0x7F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
55 0x70,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
56 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
57 0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
58 0xC0,0x00,0x07,0xFF,0xC0,0x00,0x07,0xFF,0xCF,0xC0,0x07,0xFF,0xCF,0xC0,0x07,0xFF,
59 0xCF,0xC0,0x07,0xFF,0xCF,0xF9,0xFF,0xFF,0xCE,0x39,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,
60 0xC0,0x01,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0x78,0x7F,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
61 0x10,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,
62 0x00,0x7F,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
63 0x07,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,
64 0x7F,0xFF,0xFF,0xFF
65 };
66
67 static unsigned char cursor_dnd_link[] = {
68 0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
69 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
70 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
71 0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,
72 0x00,0x1D,0xF0,0x00,0x00,0x1B,0xF0,0x00,0x00,0x19,0xF0,0x00,0x00,0x18,0xB0,0x00,
73 0x15,0x5C,0x30,0x00,0x2A,0x9E,0x30,0x00,0x10,0x1C,0x30,0x00,0x20,0x1F,0xF0,0x00,
74 0x10,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x10,0x04,0x00,0x00,0x29,0xAA,0x00,0x00,
75 0x15,0x94,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
76 0x46,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,
77 0x7F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
78 0x70,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
79 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
80 0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
81 0xC0,0x00,0x07,0xFF,0xC0,0x00,0x07,0xFF,0xCF,0xC0,0x07,0xFF,0xCF,0xC0,0x07,0xFF,
82 0xCF,0xC0,0x07,0xFF,0xCF,0xF9,0xFF,0xFF,0xCE,0x39,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,
83 0xC0,0x01,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0x78,0x7F,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
84 0x10,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,
85 0x00,0x7F,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
86 0x07,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,
87 0x7F,0xFF,0xFF,0xFF
88 };
89
90 static HCURSOR drag_cursors[crDragLink - crDragCopy + 1] = { NULL, NULL, NULL };
91
92 static HCURSOR
create_drag_cursor(int cr)93 create_drag_cursor( int cr )
94 {
95 unsigned char * bits = NULL;
96 unsigned int size = 0;
97 int index = cr - crDragCopy;
98
99 if ( cr < crDragCopy || cr > crDragLink)
100 return NULL;
101
102 if ( drag_cursors[index] != NULL )
103 return drag_cursors[index];
104
105 switch (cr) {
106 case crDragCopy:
107 bits = cursor_dnd_copy;
108 size = sizeof(cursor_dnd_copy);
109 break;
110 case crDragMove:
111 bits = cursor_dnd_move;
112 size = sizeof(cursor_dnd_move);
113 break;
114 case crDragLink:
115 bits = cursor_dnd_link;
116 size = sizeof(cursor_dnd_link);
117 break;
118 }
119
120 if (( drag_cursors[index] = CreateIconFromResourceEx(
121 bits, size,
122 false, 0x30000,
123 32, 32,
124 LR_MONOCHROME | LR_SHARED /* LR_SHARED to release these automatically */
125 )) == NULL )
126 apiErr;
127
128 return drag_cursors[index];
129 }
130
131 Bool
cursor_update(Handle self)132 cursor_update( Handle self)
133 {
134 if ( !is_apt( aptFocused))
135 return true;
136 DestroyCaret();
137 if ( is_apt( aptCursorVis)) {
138 if ( !CreateCaret(( HWND) var handle, NULL, sys cursorSize. x, sys cursorSize. y)) apiErrRet;
139 if ( !SetCaretPos( sys cursorPos. x, sys lastSize. y - sys cursorPos. y - sys cursorSize. y)) apiErrRet;
140 if ( !ShowCaret(( HWND) var handle)) apiErrRet;
141 }
142 return true;
143 }
144
145 Bool
apc_cursor_set_pos(Handle self,int x,int y)146 apc_cursor_set_pos( Handle self, int x, int y)
147 {
148 objCheck false;
149 if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
150 sys cursorPos. x = x;
151 sys cursorPos. y = y;
152 return cursor_update( self);
153 }
154
155 Bool
apc_cursor_set_size(Handle self,int x,int y)156 apc_cursor_set_size( Handle self, int x, int y)
157 {
158 objCheck false;
159 if ( !hwnd_check_limits( x, y, false)) apcErrRet( errInvParams);
160 sys cursorSize. x = x;
161 sys cursorSize. y = y;
162 return cursor_update( self);
163 }
164
165 Bool
apc_cursor_set_visible(Handle self,Bool visible)166 apc_cursor_set_visible( Handle self, Bool visible)
167 {
168 objCheck false;
169 apt_assign( aptCursorVis, visible);
170 return cursor_update( self);
171 }
172
173 Point
apc_cursor_get_pos(Handle self)174 apc_cursor_get_pos( Handle self)
175 {
176 Point p = {0,0};
177 objCheck p;
178 return sys cursorPos;
179 }
180
181 Point
apc_cursor_get_size(Handle self)182 apc_cursor_get_size( Handle self)
183 {
184 Point p = {0,0};
185 objCheck p;
186 return sys cursorSize;
187 }
188
189 Bool
apc_cursor_get_visible(Handle self)190 apc_cursor_get_visible( Handle self)
191 {
192 objCheck false;
193 return is_apt( aptCursorVis);
194 }
195
196 Point
apc_pointer_get_hot_spot(Handle self)197 apc_pointer_get_hot_spot( Handle self)
198 {
199 Point r = {0,0};
200 ICONINFO ii;
201 objCheck r;
202 if ( !GetIconInfo( sys pointer, &ii))
203 apiErr
204 else {
205 int y;
206 BITMAP bitmap;
207 if ( ii.hbmColor && GetObject( ii.hbmColor, sizeof( BITMAP), ( LPSTR) &bitmap))
208 y = bitmap.bmHeight;
209 else if ( GetObject( ii.hbmMask, sizeof( BITMAP), ( LPSTR) &bitmap))
210 y = bitmap.bmHeight / 2;
211 else
212 y = guts. pointerSize. y;
213 r. x = ii. xHotspot;
214 r. y = y - ii. yHotspot - 1;
215 DeleteObject( ii. hbmMask);
216 DeleteObject( ii. hbmColor);
217 }
218 return r;
219 }
220
221 Point
apc_pointer_get_pos(Handle self)222 apc_pointer_get_pos( Handle self)
223 {
224 Point p = {0,0};
225 RECT r;
226 objCheck p;
227 if ( !GetCursorPos(( POINT*) &p)) apiErr;
228 GetWindowRect( HWND_DESKTOP, &r);
229 p. y = r. bottom - p. y - 1;
230 return p;
231 }
232
233 int
apc_pointer_get_shape(Handle self)234 apc_pointer_get_shape( Handle self)
235 {
236 objCheck 0;
237 return sys pointerId;
238 }
239
240 Point
apc_pointer_get_size(Handle self)241 apc_pointer_get_size( Handle self)
242 {
243 return guts. pointerSize;
244 }
245
246 Bool
apc_pointer_get_bitmap(Handle self,Handle icon)247 apc_pointer_get_bitmap( Handle self, Handle icon)
248 {
249 ICONINFO ii;
250 PIcon i = ( PIcon) icon;
251 HDC dc;
252 XBITMAPINFO bi = {{
253 sizeof( BITMAPINFOHEADER), 0, 0, 1, 1
254 }};
255 BITMAP bitmap;
256
257 bi. bmiHeader. biWidth = guts. pointerSize. x;
258 bi. bmiHeader. biHeight = guts. pointerSize. y;
259
260 if ( icon == NULL_HANDLE)
261 apcErrRet( errInvParams);
262 objCheck false;
263 dobjCheck( icon) false;
264 if ( !GetIconInfo( sys pointer, &ii))
265 apiErrRet;
266 if ( ii.hbmColor && GetObject( ii.hbmColor, sizeof( BITMAP), ( LPSTR) &bitmap))
267 i-> self-> create_empty( icon, bitmap.bmWidth, bitmap.bmHeight, 1);
268 else if ( GetObject( ii.hbmMask, sizeof( BITMAP), ( LPSTR) &bitmap))
269 i-> self-> create_empty( icon, bitmap.bmWidth, bitmap.bmHeight / 2, 1);
270 else
271 i-> self-> create_empty( icon, guts. pointerSize. x, guts. pointerSize. y, 1);
272 if (!( dc = dc_alloc())) return false;
273 if ( ii. hbmColor) {
274 HDC ops = dsys( icon) ps;
275 HBITMAP obm = dsys( icon) bm;
276 dsys( icon) ps = dc;
277 dsys( icon) bm = ii. hbmColor;
278 image_query_bits( icon, false);
279 if ( !GetDIBits( dc, ii. hbmMask, 0, i-> h, i-> mask, ( BITMAPINFO*) &bi, DIB_RGB_COLORS)) apiErr;
280 dsys( icon) ps = ops;
281 dsys( icon) bm = obm;
282 } else {
283 bi. bmiHeader. biHeight *= 2;
284 if ( !GetDIBits( dc, ii. hbmMask, 0, i-> h, i-> data, ( BITMAPINFO*) &bi, DIB_RGB_COLORS)) apiErr;
285 if ( !GetDIBits( dc, ii. hbmMask, i-> h, i-> h, i-> mask, ( BITMAPINFO*) &bi, DIB_RGB_COLORS)) apiErr;
286 }
287 dc_free();
288 DeleteObject( ii. hbmMask);
289 DeleteObject( ii. hbmColor);
290 return true;
291 }
292
293 Bool
apc_pointer_get_visible(Handle self)294 apc_pointer_get_visible( Handle self)
295 {
296 objCheck false;
297 return !guts. pointerInvisible;
298 }
299
300 Bool
apc_pointer_set_pos(Handle self,int x,int y)301 apc_pointer_set_pos( Handle self, int x, int y)
302 {
303 RECT r;
304 if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
305 GetWindowRect( HWND_DESKTOP, &r);
306 if ( !SetCursorPos( x, r. bottom - y - 1)) apiErrRet;
307 return true;
308 }
309
310 Handle ctx_cr2IDC[] =
311 {
312 crArrow, ( Handle) IDC_ARROW,
313 crText, ( Handle) IDC_IBEAM,
314 crWait, ( Handle) IDC_WAIT,
315 crSize, ( Handle) IDC_SIZEALL,
316 crMove, ( Handle) IDC_SIZEALL,
317 crSizeWest, ( Handle) IDC_SIZEWE,
318 crSizeEast, ( Handle) IDC_SIZEWE,
319 crSizeWE, ( Handle) IDC_SIZEWE,
320 crSizeNorth, ( Handle) IDC_SIZENS,
321 crSizeSouth, ( Handle) IDC_SIZENS,
322 crSizeNS, ( Handle) IDC_SIZENS,
323 crSizeNW, ( Handle) IDC_SIZENWSE,
324 crSizeSE, ( Handle) IDC_SIZENWSE,
325 crSizeNE, ( Handle) IDC_SIZENESW,
326 crSizeSW, ( Handle) IDC_SIZENESW,
327 crInvalid, ( Handle) IDC_NO,
328 crDragNone, ( Handle) IDC_NO,
329 crDragCopy, ( Handle) IDC_HAND,
330 crDragMove, ( Handle) IDC_HAND,
331 crDragLink, ( Handle) IDC_HAND,
332 crCrosshair, ( Handle) IDC_CROSS,
333 crUpArrow, ( Handle) IDC_UPARROW,
334 crQuestionArrow,( Handle) IDC_HELP,
335 crHand, ( Handle) IDC_HAND,
336 endCtx
337 };
338
339 static Bool
direct_pointer_change(Handle self)340 direct_pointer_change( Handle self)
341 {
342 Point p;
343 if ( var stage != csNormal) return false;
344 if ( guts.dragSource != NULL ) return true;
345 if ( !IsWindowVisible( HANDLE)) return false;
346 p = apc_pointer_get_pos( application);
347 return self == apc_application_get_widget_from_point( application, p);
348 }
349
350 Bool
apc_pointer_set_shape(Handle self,int sysPtrId)351 apc_pointer_set_shape( Handle self, int sysPtrId)
352 {
353 HCURSOR user;
354
355 objCheck false;
356 user = sys pointer2;
357 if ( sysPtrId < crDefault || sysPtrId > crUser) return false;
358 sys pointerId = sysPtrId;
359 if ( sysPtrId == crDefault)
360 {
361 Handle owner = var owner;
362 while( owner)
363 {
364 sysPtrId = dsys( owner) pointerId;
365 if ( sysPtrId != crDefault) break;
366 owner = (( PComponent) owner)-> owner;
367 }
368 if ( sysPtrId == crDefault) sysPtrId = crArrow;
369 if ( sysPtrId == crUser) user = dsys( owner) pointer2;
370 }
371 sys pointer = ( sysPtrId == crUser) ? user :
372 LoadCursor( NULL, MAKEINTRESOURCE(
373 ctx_remap_def( sysPtrId, ctx_cr2IDC, true, ( Handle)IDC_ARROW)));
374
375 if ( sysPtrId >= crDragCopy && sysPtrId <= crDragLink) {
376 HCURSOR cursor = create_drag_cursor(sysPtrId);
377 if ( cursor != NULL ) sys pointer = cursor;
378 }
379
380 if ( direct_pointer_change( self)) {
381 SetCursor( sys pointer);
382 }
383 return true;
384 }
385
386 Bool
apc_pointer_set_user(Handle self,Handle icon,Point hotSpot)387 apc_pointer_set_user( Handle self, Handle icon, Point hotSpot)
388 {
389 Bool direct;
390 HCURSOR cursor;
391 objCheck false;
392
393 apcErrClear;
394 direct = direct_pointer_change( self);
395 if (icon) {
396 Point sz = { PImage(icon)->w, PImage(icon)-> h };
397 hotSpot. y = sz.y - hotSpot. y - 1;
398 cursor = image_make_icon_handle( icon, sz, &hotSpot);
399 if ( apcError) return false;
400 } else
401 cursor = NULL;
402
403 if ( sys pointer2) {
404 if ( direct) SetCursor( NULL);
405 if ( !DestroyCursor( sys pointer2)) apiErr;
406 }
407 sys pointer2 = cursor;
408
409 if ( sys pointerId == crUser)
410 {
411 sys pointer = sys pointer2;
412 if ( direct) SetCursor( sys pointer);
413 }
414 return true;
415 }
416
417 Bool
apc_pointer_set_visible(Handle self,Bool visible)418 apc_pointer_set_visible( Handle self, Bool visible)
419 {
420 if ( var stage == csNormal) {
421 guts. pointerInvisible = !visible;
422 ShowCursor( visible);
423 guts. pointerLock += visible ? 1 : -1;
424 }
425 return true;
426 }
427
428 int
apc_pointer_get_state(Handle self)429 apc_pointer_get_state( Handle self)
430 {
431 return
432 (( GetKeyState( VK_LBUTTON) < 0) ? mbLeft : 0) |
433 (( GetKeyState( VK_RBUTTON) < 0) ? mbRight : 0) |
434 (( GetKeyState( VK_MBUTTON) < 0) ? mbMiddle : 0) |
435 (( GetKeyState( VK_XBUTTON1) < 0) ? mb4 : 0) |
436 (( GetKeyState( VK_XBUTTON2) < 0) ? mb5 : 0);
437 }
438
439 #ifdef __cplusplus
440 }
441 #endif
442