-
Notifications
You must be signed in to change notification settings - Fork 0
/
mouse_rescue.ew
147 lines (133 loc) · 4.26 KB
/
mouse_rescue.ew
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
include std/machine.e
without warning
global constant
MOVE = 1,
LEFT_DOWN = 2,
LEFT_UP = 4,
RIGHT_DOWN = 8,
RIGHT_UP = 16,
MIDDLE_DOWN = 32,
MIDDLE_UP = 64,
WHEEL_DOWN = 128,
WHEEL_UP = 256,
WHEEL = WHEEL_DOWN + WHEEL_UP
constant
WM_MOUSEMOVE = 512,
WM_LBUTTONDOWN = 513,
WM_LBUTTONUP = 514,
WM_LBUTTONDBLCLK = 515,
WM_RBUTTONDOWN = 516,
WM_RBUTTONUP = 517,
WM_RBUTTONDBLCLK = 518,
WM_MBUTTONDOWN = 519,
WM_MBUTTONUP = 520,
WM_MBUTTONDBLCLK = 521,
WM_MOUSEWHEEL = 522
constant
WM_NCLBUTTONUP = 162
-- constant WHEEL_DELTA = 120
sequence mouse_buff -- buffer for mouse events
mouse_buff = {}
global function get_mouse()
-- report mouse events,
-- returns -1 if no mouse event,
-- otherwise returns {event#, x-coord, y-coord}
sequence event
task_yield()
if length(mouse_buff) = 0 then
return -1
else
event = mouse_buff[1]
mouse_buff = mouse_buff[2..$]
return event
end if
end function
integer handle_events
handle_events = MOVE + LEFT_DOWN + LEFT_UP + RIGHT_DOWN + RIGHT_UP
+ MIDDLE_DOWN + MIDDLE_UP + WHEEL_DOWN + WHEEL_UP
global procedure mouse_events(integer events)
-- select the mouse events to be reported by get_mouse()
-- e.g. mouse_events(LEFT_UP + LEFT_DOWN + RIGHT_DOWN)
handle_events = events
end procedure
global procedure mouse_pointer(integer show_it)
-- show (1) or hide (0) the mouse pointer
-- stub
end procedure
constant point = allocate(8)
function extend_sign(integer n)
if and_bits(n,#8000) then -- extend sign bit
n -= #10000
end if
return n
end function
integer captured
captured = 0
function mouse_event_handler(atom hwnd, atom iMsg, atom wParam, atom lParam, sequence handlers)
integer xPos,yPos,zDelta
sequence event
xPos = extend_sign(LOWORD(lParam))
yPos = extend_sign(HIWORD(lParam))
if iMsg = WM_MOUSEMOVE and and_bits(handle_events,MOVE) then
event = {MOVE,xPos,yPos}
elsif (iMsg = WM_LBUTTONDOWN ) and and_bits(handle_events,LEFT_DOWN) then
event = {LEFT_DOWN,xPos,yPos}
if and_bits(handle_events,LEFT_UP) then
if not captured then
c_proc(SetCapture,{hwnd})
end if
captured += 1
end if
elsif iMsg = WM_LBUTTONUP and and_bits(handle_events,LEFT_UP) then
event = {LEFT_UP,xPos,yPos}
captured -= 1
if not captured then
c_proc(ReleaseCapture,{})
end if
elsif iMsg = WM_MBUTTONDOWN and and_bits(handle_events,MIDDLE_DOWN) then
event = {MIDDLE_DOWN,xPos,yPos}
if and_bits(handle_events,MIDDLE_UP) then
if not captured then
c_proc(SetCapture,{hwnd})
end if
captured += 1
end if
elsif iMsg = WM_MBUTTONUP and and_bits(handle_events,MIDDLE_UP) then
event = {MIDDLE_UP,xPos,yPos}
captured -= 1
if not captured then
c_proc(ReleaseCapture,{})
end if
elsif iMsg = WM_RBUTTONDOWN and and_bits(handle_events,RIGHT_DOWN) then
event = {RIGHT_DOWN,xPos,yPos}
if and_bits(handle_events,RIGHT_UP) then
if not captured then
c_proc(SetCapture,{hwnd})
end if
captured += 1
end if
elsif iMsg = WM_RBUTTONUP and and_bits(handle_events,RIGHT_UP) then
event = {RIGHT_UP,xPos,yPos}
captured -= 1
if not captured then
c_proc(ReleaseCapture,{})
end if
elsif iMsg = WM_MOUSEWHEEL and and_bits(handle_events,WHEEL) then
zDelta = extend_sign(HIWORD(wParam))
poke4(point,{xPos,yPos})
c_proc(ScreenToClient,{hwnd,point})
xPos = peek4s(point+0)
yPos = peek4s(point+4)
if zDelta > 0 then
event = {WHEEL_UP,xPos,yPos}
else
event = {WHEEL_DOWN,xPos,yPos}
end if
else
return call_func(handlers[$],{hwnd,iMsg,wParam,lParam,handlers[1..$-1]})
end if
event[2..3] = floor(event[2..3]/scale)
mouse_buff = append(mouse_buff,event)
return 0
end function
add_custom_handler(routine_id("mouse_event_handler"))