1 |
Index: ./ide/fpkeys.pas |
2 |
=================================================================== |
3 |
--- ./ide/fpkeys.pas (revision 40849) |
4 |
+++ ./ide/fpkeys.pas (working copy) |
5 |
@@ -19,7 +19,7 @@ |
6 |
|
7 |
uses |
8 |
keyboard, Objects, Drivers, Dialogs, App, |
9 |
- FPViews, WViews; |
10 |
+ WViews; |
11 |
|
12 |
procedure LearnKeysDialog; |
13 |
|
14 |
@@ -39,10 +39,11 @@ |
15 |
PSTL : Array [1..NumWantedKeys] of PLabel; |
16 |
PL : Array [1..NumWantedKeys] of PInputLine; |
17 |
KeyOK : Array [1..NumWantedKeys] of boolean; |
18 |
+ FKeyEscape : Array[1..NumWantedKeys] of String[10]; |
19 |
PST,PST2 : PAdvancedStaticText; |
20 |
Constructor Init(Const ATitle : String); |
21 |
- {Procedure HandleEvent(var E : TEvent);virtual;} |
22 |
- function Execute : Word;Virtual; |
23 |
+ procedure HandleEvent(var E : TEvent);virtual; |
24 |
+ function Execute : Word;Virtual; |
25 |
end; |
26 |
|
27 |
Procedure LoadKeys(var S : TStream); |
28 |
@@ -53,7 +54,7 @@ |
29 |
|
30 |
uses |
31 |
FVConsts, |
32 |
- WUtils; |
33 |
+ WUtils, mouse; |
34 |
|
35 |
{$ifndef NotUseTree} |
36 |
function GetKey(Const St : String) : word; |
37 |
@@ -75,6 +76,205 @@ |
38 |
AddSequence(St,AChar,Ascan); |
39 |
end; |
40 |
|
41 |
+{ procedure is modified copy from keyboard unit } |
42 |
+procedure GenMouseEvent_Ext ( buttonval, X, Y : LongInt; ch : char); |
43 |
+var MouseEvent: TMouseEvent; |
44 |
+ ButtonMask: Word; |
45 |
+ LastMouseEvent : TMouseEvent; |
46 |
+begin |
47 |
+ LastMouseEvent:=GetLastMouseEvent; |
48 |
+ { let's range check X and Y just in case } |
49 |
+ if (X<(Low(MouseEvent.X)+1)) or (X>(High(MouseEvent.X)+1)) then |
50 |
+ exit; |
51 |
+ if (Y<(Low(MouseEvent.Y)+1)) or (Y>(High(MouseEvent.Y)+1)) then |
52 |
+ exit; |
53 |
+ case buttonval and 67 of |
54 |
+ 0 : {left button press} |
55 |
+ ButtonMask:=1; |
56 |
+ 1 : {middle button pressed } |
57 |
+ ButtonMask:=2; |
58 |
+ 2 : { right button pressed } |
59 |
+ ButtonMask:=4; |
60 |
+ 3 : { no button pressed } |
61 |
+ ButtonMask:=0; |
62 |
+ 64: { button 4 pressed } |
63 |
+ ButtonMask:=8; |
64 |
+ 65: { button 5 pressed } |
65 |
+ ButtonMask:=16; |
66 |
+ end; |
67 |
+ MouseEvent.X:=X-1; |
68 |
+ MouseEvent.Y:=Y-1; |
69 |
+ if (buttonval and 32)<>0 then |
70 |
+ begin |
71 |
+ MouseEvent.Action:=MouseActionMove; |
72 |
+ MouseEvent.Buttons:=LastMouseEvent.Buttons; |
73 |
+ end |
74 |
+ else |
75 |
+ begin |
76 |
+ if ch='M' then |
77 |
+ begin |
78 |
+ MouseEvent.Action:=MouseActionDown; |
79 |
+ MouseEvent.Buttons:=LastMouseEvent.Buttons or ButtonMask; |
80 |
+ end |
81 |
+ else |
82 |
+ begin |
83 |
+ MouseEvent.Action:=MouseActionUp; |
84 |
+ MouseEvent.Buttons:=LastMouseEvent.Buttons and not ButtonMask; |
85 |
+ end; |
86 |
+ end; |
87 |
+ PutMouseEvent(MouseEvent); |
88 |
+ if (ButtonMask and (8+16)) <> 0 then // 'M' escape sequence cannot map button 4&5 release, so fake one. |
89 |
+ begin |
90 |
+ MouseEvent.Action:=MouseActionUp; |
91 |
+ MouseEvent.Buttons:=LastMouseEvent.Buttons and not ButtonMask; |
92 |
+ PutMouseEvent(MouseEvent); |
93 |
+ end; |
94 |
+ LastMouseEvent:=MouseEvent; |
95 |
+ UpdateLastMouseEvent(MouseEvent); |
96 |
+end; |
97 |
+ |
98 |
+procedure ParseMouseSequence_Ext(const St : string); |
99 |
+var ch : char; |
100 |
+ buttonval: LongInt; |
101 |
+ tempstr: string; |
102 |
+ code: LongInt; |
103 |
+ X, Y: LongInt; |
104 |
+ pos, len : longint; |
105 |
+begin |
106 |
+ pos:=4; len:=length(st); |
107 |
+ { read buttonval } |
108 |
+ tempstr:=''; |
109 |
+ repeat |
110 |
+ if pos > len then exit; |
111 |
+ ch:=st[pos]; |
112 |
+ inc(pos); |
113 |
+ if (ch>='0') and (ch<='9') then |
114 |
+ tempstr:=tempstr+ch |
115 |
+ else if ch<>';' then |
116 |
+ exit; |
117 |
+ until ch=';'; |
118 |
+ Val(tempstr,buttonval,code); |
119 |
+ |
120 |
+ { read X } |
121 |
+ tempstr:=''; |
122 |
+ repeat |
123 |
+ if pos > len then exit; |
124 |
+ ch:=st[pos]; |
125 |
+ inc(pos); |
126 |
+ if (ch>='0') and (ch<='9') then |
127 |
+ tempstr:=tempstr+ch |
128 |
+ else if ch<>';' then |
129 |
+ exit; |
130 |
+ until ch=';'; |
131 |
+ Val(tempstr,X,code); |
132 |
+ |
133 |
+ { read Y } |
134 |
+ tempstr:=''; |
135 |
+ repeat |
136 |
+ if pos > len then exit; |
137 |
+ ch:=st[pos]; |
138 |
+ inc(pos); |
139 |
+ if (ch>='0') and (ch<='9') then |
140 |
+ tempstr:=tempstr+ch |
141 |
+ else if (ch<>'M') and (ch<>'m') then |
142 |
+ exit; |
143 |
+ until (ch='M') or (ch='m'); |
144 |
+ Val(tempstr,Y,code); |
145 |
+ |
146 |
+ GenMouseEvent_Ext ( buttonval, X, Y, ch ); |
147 |
+end; |
148 |
+ |
149 |
+procedure GenFakeReleaseEvent(MouseEvent : TMouseEvent); |
150 |
+begin |
151 |
+ MouseEvent.action := MouseActionUp; |
152 |
+ MouseEvent.buttons := 0; |
153 |
+ PutMouseEvent(MouseEvent); |
154 |
+end; |
155 |
+ |
156 |
+procedure GenMouseEvent(const st :string); |
157 |
+var MouseEvent: TMouseEvent; |
158 |
+ ch : char; |
159 |
+ buttonval:byte; |
160 |
+ pos, len : longint; |
161 |
+ LastMouseEvent : TMouseEvent; |
162 |
+begin |
163 |
+ LastMouseEvent:=GetLastMouseEvent; |
164 |
+ pos:=4; len:=length(st); |
165 |
+ |
166 |
+ MouseEvent.action:=0; |
167 |
+ if pos > len then exit; |
168 |
+ ch:=st[pos]; |
169 |
+ inc(pos); |
170 |
+ { Other bits are used for Shift, Meta and Ctrl modifiers PM } |
171 |
+ buttonval:=byte(ch)-byte(' '); |
172 |
+ {bits 0..1: button status |
173 |
+ bit 5 : mouse movement while button down. |
174 |
+ bit 6 : interpret button 1 as button 4 |
175 |
+ interpret button 2 as button 5} |
176 |
+ case buttonval and 67 of |
177 |
+ 0 : {left button press} |
178 |
+ MouseEvent.buttons:=1; |
179 |
+ 1 : {middle button pressed } |
180 |
+ MouseEvent.buttons:=2; |
181 |
+ 2 : { right button pressed } |
182 |
+ MouseEvent.buttons:=4; |
183 |
+ 3 : { no button pressed } |
184 |
+ MouseEvent.buttons:=0; |
185 |
+ 64: { button 4 pressed } |
186 |
+ MouseEvent.buttons:=8; |
187 |
+ 65: { button 5 pressed } |
188 |
+ MouseEvent.buttons:=16; |
189 |
+ end; |
190 |
+ if pos > len then exit; |
191 |
+ ch:=st[pos]; |
192 |
+ inc(pos); |
193 |
+ MouseEvent.x:=Ord(ch)-ord(' ')-1; |
194 |
+ if pos > len then exit; |
195 |
+ ch:=st[pos]; |
196 |
+ MouseEvent.y:=Ord(ch)-ord(' ')-1; |
197 |
+ mouseevent.action:=MouseActionMove; |
198 |
+ if (lastmouseevent.buttons=0) and (mouseevent.buttons<>0) then |
199 |
+ MouseEvent.action:=MouseActionDown; |
200 |
+ if (lastmouseevent.buttons<>0) and (mouseevent.buttons=0) then |
201 |
+ MouseEvent.action:=MouseActionUp; |
202 |
+ |
203 |
+ PutMouseEvent(MouseEvent); |
204 |
+ if (MouseEvent.buttons and (8+16)) <> 0 then // 'M' escape sequence cannot map button 4&5 release, so fake one. |
205 |
+ GenFakeReleaseEvent(MouseEvent); |
206 |
+ LastMouseEvent:=MouseEvent; |
207 |
+ UpdateLastMouseEvent(MouseEvent); |
208 |
+end; |
209 |
+ |
210 |
+procedure MouseSequence(const St : string); |
211 |
+var pos, len : longint; |
212 |
+begin |
213 |
+ pos:=3; len:=length(st); |
214 |
+ if pos >= len then exit; |
215 |
+ if (st[1]=#27) and (st[2]='[') then |
216 |
+ begin |
217 |
+ if (st[3]='<') then ParseMouseSequence_Ext(st) else |
218 |
+ if (st[3]='M') then GenMouseEvent(st); |
219 |
+ end; |
220 |
+end; |
221 |
+ |
222 |
+procedure LookForMouseSequence(const St : string); |
223 |
+var pos, len : longint; |
224 |
+var zSt : string; |
225 |
+ ch : char; |
226 |
+begin |
227 |
+ pos:=1; len:=length(st); |
228 |
+ while pos < len do |
229 |
+ begin |
230 |
+ ch:=st[pos]; |
231 |
+ if ch=#27 then |
232 |
+ begin |
233 |
+ zSt:=copy(st,pos,len-pos+1); |
234 |
+ MouseSequence(zSt); |
235 |
+ end; |
236 |
+ inc(pos); |
237 |
+ end; |
238 |
+end; |
239 |
+ |
240 |
{$endif not NotUseTree} |
241 |
|
242 |
Const |
243 |
@@ -177,6 +377,7 @@ |
244 |
R.B.X:=R.B.X+11; |
245 |
New(PL[i],Init(R,20)); |
246 |
St:=NiceEscape(KeyEscape[i]); |
247 |
+ FKeyEscape[i]:=KeyEscape[i]; |
248 |
PL[i]^.SetData(St); |
249 |
Insert(PL[i]); |
250 |
PSTL[i]^.Link:=PL[i]; |
251 |
@@ -205,6 +406,7 @@ |
252 |
E : TEvent; |
253 |
OldKey : word; |
254 |
keyfound : boolean; |
255 |
+ eMouseEvent : TMouseEvent; |
256 |
begin |
257 |
{$ifndef NotUseTree} |
258 |
repeat |
259 |
@@ -232,6 +434,8 @@ |
260 |
begin |
261 |
E.What:=evKeyDown; |
262 |
E.KeyCode:=GetKey(St); |
263 |
+ if E.KeyCode=$0008 then |
264 |
+ E.KeyCode:=kbBack; { recognize key BackSpace } |
265 |
end |
266 |
else if St=#9 then |
267 |
begin |
268 |
@@ -260,7 +464,7 @@ |
269 |
PSTL[i]^.Text:=NewStr(WantedKeysLabels[i]+' OK '); |
270 |
keyFound:=true; |
271 |
keyOK[i]:=true; |
272 |
- KeyEscape[i]:=St; |
273 |
+ FKeyEscape[i]:=St; |
274 |
St:=NiceEscape(St); |
275 |
PL[i]^.SetData(St); |
276 |
ClearEvent(E); |
277 |
@@ -267,9 +471,16 @@ |
278 |
ReDraw; |
279 |
end; |
280 |
end; |
281 |
+ if (E.What= evNothing) and not(keyFound) then |
282 |
+ if St<>'' then |
283 |
+ begin |
284 |
+ LookForMouseSequence(st); |
285 |
+ if pollMouseEvent(eMouseEvent) then |
286 |
+ St:=''; { have found mouse escape string, don't try to match with keyboard keys } |
287 |
+ end; |
288 |
if (St<>'') and not keyfound and |
289 |
- ((E.What<>evKeyDown) or |
290 |
- ((E.KeyCode<>kbTab) and (E.Keycode<>kbEnter) and (E.Keycode<>kbEsc))) then |
291 |
+ ((E.What=evNothing) or |
292 |
+ ((E.What=evKeyDown) and (E.KeyCode<>kbTab) and (E.Keycode<>kbEnter) and (E.Keycode<>kbEsc))) then |
293 |
begin |
294 |
PST^.SetText('"'+NiceEscape(St)+'"'); |
295 |
if Assigned(APL) then |
296 |
@@ -283,6 +494,7 @@ |
297 |
OldKey:=GetKey(St); |
298 |
if OldKey<>0 then |
299 |
begin |
300 |
+ if oldKey=$0008 then oldkey:=kbBack; { recognize as BackSpace } |
301 |
for i:=1 to NumWantedKeys do |
302 |
if (OldKey=WantedKeys[i]) and (i<>j) then |
303 |
begin |
304 |
@@ -290,8 +502,8 @@ |
305 |
'key $'+hexstr(oldKey,4)+' '+WantedKeysLabels[i]+#13+ |
306 |
'Change it to '+WantedKeysLabels[j],nil,true)=cmYes then |
307 |
begin |
308 |
- KeyEscape[i]:=''; |
309 |
- PL[i]^.SetData(KeyEscape[i]); |
310 |
+ FKeyEscape[i]:=''; |
311 |
+ PL[i]^.SetData(FKeyEscape[i]); |
312 |
end |
313 |
else |
314 |
begin |
315 |
@@ -301,10 +513,12 @@ |
316 |
end; |
317 |
if St<>'' then |
318 |
Begin |
319 |
- SetKey(St,WantedKeys[j]); |
320 |
- KeyEscape[j]:=St; |
321 |
+ DisposeStr(PSTL[j]^.Text); { Ok - learned this one } |
322 |
+ PSTL[j]^.Text:=NewStr(WantedKeysLabels[j]+' OK '); |
323 |
+ FKeyEscape[j]:=St; |
324 |
St:=NiceEscape(St); |
325 |
APL^.SetData(St); |
326 |
+ PSTL[j]^.Draw; |
327 |
end; |
328 |
end; |
329 |
ClearEvent(E); |
330 |
@@ -321,6 +535,22 @@ |
331 |
{$endif NotUseTree} |
332 |
end; |
333 |
|
334 |
+Procedure TKeyDialog.HandleEvent(var E : TEvent); |
335 |
+var k : longint; |
336 |
+begin |
337 |
+ case E.What of |
338 |
+ evCommand : |
339 |
+ case E.Command of |
340 |
+ cmOk : begin |
341 |
+ { accept learned keys } |
342 |
+ for k:=1 to NumWantedKeys do KeyEscape[k]:=FKeyEscape[k]; |
343 |
+ SetKnownKeys; |
344 |
+ end; |
345 |
+ cmCancel : ; { do nothing - discard learned keys } |
346 |
+ end; |
347 |
+ end; |
348 |
+ inherited HandleEvent(E); |
349 |
+end; |
350 |
|
351 |
procedure LearnKeysDialog; |
352 |
|
353 |
Index: packages/rtl-console/src/unix/keyboard.pp |
354 |
=================================================================== |
355 |
--- packages/rtl-console/src/unix/keyboard.pp (revision 40849) |
356 |
+++ packages/rtl-console/src/unix/keyboard.pp (working copy) |
357 |
@@ -21,6 +21,7 @@ |
358 |
interface |
359 |
{*****************************************************************************} |
360 |
|
361 |
+uses mouse; |
362 |
{$i keybrdh.inc} |
363 |
|
364 |
const |
365 |
@@ -49,6 +50,8 @@ |
366 |
procedure RestoreStartMode; |
367 |
|
368 |
function AddSpecialSequence(const St : string;Proc : Tprocedure) : PTreeElement; platform; |
369 |
+procedure UpdateLastMouseEvent(E:TMouseEvent); |
370 |
+function GetLastMouseEvent:TMouseEvent; |
371 |
|
372 |
|
373 |
{*****************************************************************************} |
374 |
@@ -56,10 +59,9 @@ |
375 |
{*****************************************************************************} |
376 |
|
377 |
uses |
378 |
- Mouse, Strings, |
379 |
+ Strings, |
380 |
termio,baseUnix |
381 |
{$ifdef linux},linuxvcs{$endif}; |
382 |
- |
383 |
{$i keyboard.inc} |
384 |
|
385 |
var OldIO,StartTio : TermIos; |
386 |
@@ -494,6 +496,16 @@ |
387 |
Action : 0; |
388 |
); |
389 |
|
390 |
+procedure UpdateLastMouseEvent(E:TMouseEvent); |
391 |
+begin |
392 |
+ LastMouseEvent:=E; |
393 |
+end; |
394 |
+ |
395 |
+function GetLastMouseEvent:TMouseEvent; |
396 |
+begin |
397 |
+ GetLastMouseEvent:=LastMouseEvent; |
398 |
+end; |
399 |
+ |
400 |
procedure GenFakeReleaseEvent(MouseEvent : TMouseEvent); |
401 |
begin |
402 |
MouseEvent.action := MouseActionUp; |