#include "win32\win32guts.h"
#ifndef _APRICOT_H_
#include "apricot.h"
#endif
#include "guts.h"
#include "Window.h"
#include "Icon.h"
#include "Application.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sys (( PDrawableData)(( PComponent) self)-> sysData)->
#define dsys( view) (( PDrawableData)(( PComponent) view)-> sysData)->
#define var (( PWidget) self)->
#define HANDLE sys handle
#define DHANDLE(x) dsys(x) handle
static unsigned char cursor_dnd_move[] = {
0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x54,0x00,0x00,0x2A,0xAA,0x00,0x00,0x10,0x04,0x00,0x00,0x20,0x02,0x00,0x00,
0x10,0x04,0x00,0x00,0x20,0x02,0x00,0x00,0x10,0x04,0x00,0x00,0x29,0xAA,0x00,0x00,
0x15,0x94,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
0x46,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,
0x7F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
0x70,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xC0,0x01,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0xCF,0xF9,0xFF,0xFF,0xCF,0xF9,0xFF,0xFF,
0xCF,0xF9,0xFF,0xFF,0xCF,0xF9,0xFF,0xFF,0xCE,0x39,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,
0xC0,0x01,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0x78,0x7F,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
0x10,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,
0x00,0x7F,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
0x07,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,
0x7F,0xFF,0xFF,0xFF
};
static unsigned char cursor_dnd_copy[] = {
0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,
0x00,0x1F,0xF0,0x00,0x00,0x1E,0xF0,0x00,0x00,0x1E,0xF0,0x00,0x00,0x18,0x30,0x00,
0x15,0x5E,0xF0,0x00,0x2A,0x9E,0xF0,0x00,0x10,0x1F,0xF0,0x00,0x20,0x1F,0xF0,0x00,
0x10,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x10,0x04,0x00,0x00,0x29,0xAA,0x00,0x00,
0x15,0x94,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
0x46,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,
0x7F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
0x70,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
0xC0,0x00,0x07,0xFF,0xC0,0x00,0x07,0xFF,0xCF,0xC0,0x07,0xFF,0xCF,0xC0,0x07,0xFF,
0xCF,0xC0,0x07,0xFF,0xCF,0xF9,0xFF,0xFF,0xCE,0x39,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,
0xC0,0x01,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0x78,0x7F,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
0x10,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,
0x00,0x7F,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
0x07,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,
0x7F,0xFF,0xFF,0xFF
};
static unsigned char cursor_dnd_link[] = {
0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF0,0x00,
0x00,0x1D,0xF0,0x00,0x00,0x1B,0xF0,0x00,0x00,0x19,0xF0,0x00,0x00,0x18,0xB0,0x00,
0x15,0x5C,0x30,0x00,0x2A,0x9E,0x30,0x00,0x10,0x1C,0x30,0x00,0x20,0x1F,0xF0,0x00,
0x10,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x10,0x04,0x00,0x00,0x29,0xAA,0x00,0x00,
0x15,0x94,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
0x46,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,
0x7F,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
0x70,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0,0x07,0xFF,
0xC0,0x00,0x07,0xFF,0xC0,0x00,0x07,0xFF,0xCF,0xC0,0x07,0xFF,0xCF,0xC0,0x07,0xFF,
0xCF,0xC0,0x07,0xFF,0xCF,0xF9,0xFF,0xFF,0xCE,0x39,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,
0xC0,0x01,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0x78,0x7F,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
0x10,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,
0x00,0x7F,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,
0x07,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,
0x7F,0xFF,0xFF,0xFF
};
static HCURSOR drag_cursors[crDragLink - crDragCopy + 1] = { NULL, NULL, NULL };
static HCURSOR
create_drag_cursor( int cr )
{
unsigned char * bits = NULL;
unsigned int size = 0;
int index = cr - crDragCopy;
if ( cr < crDragCopy || cr > crDragLink)
return NULL;
if ( drag_cursors[index] != NULL )
return drag_cursors[index];
switch (cr) {
case crDragCopy:
bits = cursor_dnd_copy;
size = sizeof(cursor_dnd_copy);
break;
case crDragMove:
bits = cursor_dnd_move;
size = sizeof(cursor_dnd_move);
break;
case crDragLink:
bits = cursor_dnd_link;
size = sizeof(cursor_dnd_link);
break;
}
if (( drag_cursors[index] = CreateIconFromResourceEx(
bits, size,
false, 0x30000,
32, 32,
LR_MONOCHROME | LR_SHARED /* LR_SHARED to release these automatically */
)) == NULL )
apiErr;
return drag_cursors[index];
}
Bool
cursor_update( Handle self)
{
if ( !is_apt( aptFocused))
return true;
DestroyCaret();
if ( is_apt( aptCursorVis)) {
if ( !CreateCaret(( HWND) var handle, NULL, sys cursorSize. x, sys cursorSize. y)) apiErrRet;
if ( !SetCaretPos( sys cursorPos. x, sys lastSize. y - sys cursorPos. y - sys cursorSize. y)) apiErrRet;
if ( !ShowCaret(( HWND) var handle)) apiErrRet;
}
return true;
}
Bool
apc_cursor_set_pos( Handle self, int x, int y)
{
objCheck false;
if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
sys cursorPos. x = x;
sys cursorPos. y = y;
return cursor_update( self);
}
Bool
apc_cursor_set_size( Handle self, int x, int y)
{
objCheck false;
if ( !hwnd_check_limits( x, y, false)) apcErrRet( errInvParams);
sys cursorSize. x = x;
sys cursorSize. y = y;
return cursor_update( self);
}
Bool
apc_cursor_set_visible( Handle self, Bool visible)
{
objCheck false;
apt_assign( aptCursorVis, visible);
return cursor_update( self);
}
Point
apc_cursor_get_pos( Handle self)
{
Point p = {0,0};
objCheck p;
return sys cursorPos;
}
Point
apc_cursor_get_size( Handle self)
{
Point p = {0,0};
objCheck p;
return sys cursorSize;
}
Bool
apc_cursor_get_visible( Handle self)
{
objCheck false;
return is_apt( aptCursorVis);
}
Point
apc_pointer_get_hot_spot( Handle self)
{
Point r = {0,0};
ICONINFO ii;
objCheck r;
if ( !GetIconInfo( sys pointer, &ii))
apiErr
else {
int y;
BITMAP bitmap;
if ( ii.hbmColor && GetObject( ii.hbmColor, sizeof( BITMAP), ( LPSTR) &bitmap))
y = bitmap.bmHeight;
else if ( GetObject( ii.hbmMask, sizeof( BITMAP), ( LPSTR) &bitmap))
y = bitmap.bmHeight / 2;
else
y = guts. pointerSize. y;
r. x = ii. xHotspot;
r. y = y - ii. yHotspot - 1;
DeleteObject( ii. hbmMask);
DeleteObject( ii. hbmColor);
}
return r;
}
Point
apc_pointer_get_pos( Handle self)
{
Point p = {0,0};
RECT r;
objCheck p;
if ( !GetCursorPos(( POINT*) &p)) apiErr;
GetWindowRect( HWND_DESKTOP, &r);
p. y = r. bottom - p. y - 1;
return p;
}
int
apc_pointer_get_shape( Handle self)
{
objCheck 0;
return sys pointerId;
}
Point
apc_pointer_get_size( Handle self)
{
return guts. pointerSize;
}
Bool
apc_pointer_get_bitmap( Handle self, Handle icon)
{
ICONINFO ii;
PIcon i = ( PIcon) icon;
HDC dc;
XBITMAPINFO bi = {{
sizeof( BITMAPINFOHEADER), 0, 0, 1, 1
}};
BITMAP bitmap;
bi. bmiHeader. biWidth = guts. pointerSize. x;
bi. bmiHeader. biHeight = guts. pointerSize. y;
if ( icon == NULL_HANDLE)
apcErrRet( errInvParams);
objCheck false;
dobjCheck( icon) false;
if ( !GetIconInfo( sys pointer, &ii))
apiErrRet;
if ( ii.hbmColor && GetObject( ii.hbmColor, sizeof( BITMAP), ( LPSTR) &bitmap))
i-> self-> create_empty( icon, bitmap.bmWidth, bitmap.bmHeight, 1);
else if ( GetObject( ii.hbmMask, sizeof( BITMAP), ( LPSTR) &bitmap))
i-> self-> create_empty( icon, bitmap.bmWidth, bitmap.bmHeight / 2, 1);
else
i-> self-> create_empty( icon, guts. pointerSize. x, guts. pointerSize. y, 1);
if (!( dc = dc_alloc())) return false;
if ( ii. hbmColor) {
HDC ops = dsys( icon) ps;
HBITMAP obm = dsys( icon) bm;
dsys( icon) ps = dc;
dsys( icon) bm = ii. hbmColor;
image_query_bits( icon, false);
if ( !GetDIBits( dc, ii. hbmMask, 0, i-> h, i-> mask, ( BITMAPINFO*) &bi, DIB_RGB_COLORS)) apiErr;
dsys( icon) ps = ops;
dsys( icon) bm = obm;
} else {
bi. bmiHeader. biHeight *= 2;
if ( !GetDIBits( dc, ii. hbmMask, 0, i-> h, i-> data, ( BITMAPINFO*) &bi, DIB_RGB_COLORS)) apiErr;
if ( !GetDIBits( dc, ii. hbmMask, i-> h, i-> h, i-> mask, ( BITMAPINFO*) &bi, DIB_RGB_COLORS)) apiErr;
}
dc_free();
DeleteObject( ii. hbmMask);
DeleteObject( ii. hbmColor);
return true;
}
Bool
apc_pointer_get_visible( Handle self)
{
objCheck false;
return !guts. pointerInvisible;
}
Bool
apc_pointer_set_pos( Handle self, int x, int y)
{
RECT r;
if ( !hwnd_check_limits( x, y, true)) apcErrRet( errInvParams);
GetWindowRect( HWND_DESKTOP, &r);
if ( !SetCursorPos( x, r. bottom - y - 1)) apiErrRet;
return true;
}
Handle ctx_cr2IDC[] =
{
crArrow, ( Handle) IDC_ARROW,
crText, ( Handle) IDC_IBEAM,
crWait, ( Handle) IDC_WAIT,
crSize, ( Handle) IDC_SIZEALL,
crMove, ( Handle) IDC_SIZEALL,
crSizeWest, ( Handle) IDC_SIZEWE,
crSizeEast, ( Handle) IDC_SIZEWE,
crSizeWE, ( Handle) IDC_SIZEWE,
crSizeNorth, ( Handle) IDC_SIZENS,
crSizeSouth, ( Handle) IDC_SIZENS,
crSizeNS, ( Handle) IDC_SIZENS,
crSizeNW, ( Handle) IDC_SIZENWSE,
crSizeSE, ( Handle) IDC_SIZENWSE,
crSizeNE, ( Handle) IDC_SIZENESW,
crSizeSW, ( Handle) IDC_SIZENESW,
crInvalid, ( Handle) IDC_NO,
crDragNone, ( Handle) IDC_NO,
crDragCopy, ( Handle) IDC_HAND,
crDragMove, ( Handle) IDC_HAND,
crDragLink, ( Handle) IDC_HAND,
crCrosshair, ( Handle) IDC_CROSS,
crUpArrow, ( Handle) IDC_UPARROW,
crQuestionArrow,( Handle) IDC_HELP,
crHand, ( Handle) IDC_HAND,
endCtx
};
static Bool
direct_pointer_change( Handle self)
{
Point p;
if ( var stage != csNormal) return false;
if ( guts.dragSource != NULL ) return true;
if ( !IsWindowVisible( HANDLE)) return false;
p = apc_pointer_get_pos( application);
return self == apc_application_get_widget_from_point( application, p);
}
Bool
apc_pointer_set_shape( Handle self, int sysPtrId)
{
HCURSOR user;
objCheck false;
user = sys pointer2;
if ( sysPtrId < crDefault || sysPtrId > crUser) return false;
sys pointerId = sysPtrId;
if ( sysPtrId == crDefault)
{
Handle owner = var owner;
while( owner)
{
sysPtrId = dsys( owner) pointerId;
if ( sysPtrId != crDefault) break;
owner = (( PComponent) owner)-> owner;
}
if ( sysPtrId == crDefault) sysPtrId = crArrow;
if ( sysPtrId == crUser) user = dsys( owner) pointer2;
}
sys pointer = ( sysPtrId == crUser) ? user :
LoadCursor( NULL, MAKEINTRESOURCE(
ctx_remap_def( sysPtrId, ctx_cr2IDC, true, ( Handle)IDC_ARROW)));
if ( sysPtrId >= crDragCopy && sysPtrId <= crDragLink) {
HCURSOR cursor = create_drag_cursor(sysPtrId);
if ( cursor != NULL ) sys pointer = cursor;
}
if ( direct_pointer_change( self)) {
SetCursor( sys pointer);
}
return true;
}
Bool
apc_pointer_set_user( Handle self, Handle icon, Point hotSpot)
{
Bool direct;
HCURSOR cursor;
objCheck false;
apcErrClear;
direct = direct_pointer_change( self);
if (icon) {
Point sz = { PImage(icon)->w, PImage(icon)-> h };
hotSpot. y = sz.y - hotSpot. y - 1;
cursor = image_make_icon_handle( icon, sz, &hotSpot);
if ( guts.apcError) return false;
} else
cursor = NULL;
if ( sys pointer2) {
if ( direct) SetCursor( NULL);
if ( !DestroyCursor( sys pointer2)) apiErr;
}
sys pointer2 = cursor;
if ( sys pointerId == crUser)
{
sys pointer = sys pointer2;
if ( direct) SetCursor( sys pointer);
}
return true;
}
Bool
apc_pointer_set_visible( Handle self, Bool visible)
{
if ( var stage == csNormal) {
guts. pointerInvisible = !visible;
ShowCursor( visible);
guts. pointerLock += visible ? 1 : -1;
}
return true;
}
int
apc_pointer_get_state( Handle self)
{
return
(( GetKeyState( VK_LBUTTON) < 0) ? mbLeft : 0) |
(( GetKeyState( VK_RBUTTON) < 0) ? mbRight : 0) |
(( GetKeyState( VK_MBUTTON) < 0) ? mbMiddle : 0) |
(( GetKeyState( VK_XBUTTON1) < 0) ? mb4 : 0) |
(( GetKeyState( VK_XBUTTON2) < 0) ? mb5 : 0);
}
#ifdef __cplusplus
}
#endif