To save me reinventing the wheel, anyone know how (or if?) a program with no open CON channel can monitor the absolute pointer position on the screen?
Happy to be told it's not possible or if I'm a fool to even think of trying it.
It's for a little personal program which sits quietly in the background and reacts only when the pointer goes near the edges of the screen (beep when pointer nears edge of screen, to assist someone with poor eyesight who finds it hard to follow the pointer at the best of times). Because of what it does, it's important it has no open windows to affect pointer focus. Not even a con_0x0.
I've looked briefly at entries in the pointer device driver definition blocks. There are entries there such as pt_nxpos,pt_nypos,pt_xpos and pt_ypos but even when they do show data, it's usually only offsets within current windows, not the absolute position.
It is of course easy to do via an open CON channel using Easyptr PVAL or similar if there is an open channel. But that only works if there is an open window.
Don't want to spend too much time on it, if it's not possible or practical.
Pointer Absolute Position
Re: Pointer Absolute Position
The simplest might just be to open a tiny window, eg 0x0a0x0, and read the pointer with RDPT. If you really cant use an open channel for whatever reason there is my S\CRXY and GPT toolkit commands. SCRXY reads the size of the screen and GPT gets the current pointer position - both without the need for a channel.
Since Knoware.no is presently unavailable (Im working on restoring it shortly) I can post the toolkits here if you want.
Since Knoware.no is presently unavailable (Im working on restoring it shortly) I can post the toolkits here if you want.
Per
dont be happy. worry
- ?
dont be happy. worry
- ?
Re: Pointer Absolute Position
That would be very helpful if you could post them, thank you Per.pjw wrote: ↑Tue Apr 30, 2024 10:09 pm The simplest might just be to open a tiny window, eg 0x0a0x0, and read the pointer with RDPT. If you really cant use an open channel for whatever reason there is my S\CRXY and GPT toolkit commands. SCRXY reads the size of the screen and GPT gets the current pointer position - both without the need for a channel.
Since Knoware.no is presently unavailable (Im working on restoring it shortly) I can post the toolkits here if you want.
It is very easy with a CON_0x0 but even 0x0 keeps confusing the pointer focus for some reason, plus there are systems on which con_0x0 can't be used.
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html
Re: Pointer Absolute Position
Well, one of these routines requires the PI to be installed, but I guess that is implied since its the pointer position you want to read..
I just did a POC test. The metrics are just a rough guess:
Code: Select all
10 SCRXY x%, y%
15 x% = x% - 20: y% = y% - 20
20 REPeat
30 GPT xp%, yp%
40 IF xp% >= x% OR xp% <= 20 THEN
50 BEEP 2000,2
60 END IF
140 IF yp% >= y% OR yp% <= 20 THEN
150 BEEP 2000,2
160 END IF
165 SUSJB -1, 10
170 END REPeat
180 :
- Attachments
-
- gpt.zip
- GPT and SCRXY
- (2.36 KiB) Downloaded 28 times
Per
dont be happy. worry
- ?
dont be happy. worry
- ?
Re: Pointer Absolute Position
Thank you Per, saved me time writing an equivalent. Not tried it yet, looks a bit like what I would have done and straightforward enough.
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html
Re: Pointer Absolute Position
To explain a little how it's done, and preserve this information for the future, as this is a potentially useful technique for those very rare cases where you need to read the absolute pointer position, here's a small demo of it written in BASIC. It only works on systems with pointer environment - I tested it on QemuLator with JS ROM and QPC2 - the system variable and console data block don't exist on systems without pointer environment.
All it does is monitor the pt_xpos and pt_ypos entries in the CON device linkage block, which is pointed to by entry $C4 (dec. 196) in the system variables. Within this block, at offsets $3C and $3E (dec. 60 and 62) lie two words which hold the current pointer x and y position respectively. This works in pixel units from 0,0 at the top left of the screen to screen width and height -1 (i.e. 0-511 across a QL screen, 0 to 255 down a QL screen). You might not get readings at the absolute edge, it depends on the pointer sprite origin how close to the edges it actually gets. It just prints a continuous stream of pairs of numbers, the absolute pointer x and position.
This program just does a one-off read of system variables and pointers at the start and then treats it as a fixed location. Probably safer to check those with each call in case things move in memory. I only wrote it like this to make it easier to understand without too much code inside the REPeat loop.
All it does is monitor the pt_xpos and pt_ypos entries in the CON device linkage block, which is pointed to by entry $C4 (dec. 196) in the system variables. Within this block, at offsets $3C and $3E (dec. 60 and 62) lie two words which hold the current pointer x and y position respectively. This works in pixel units from 0,0 at the top left of the screen to screen width and height -1 (i.e. 0-511 across a QL screen, 0 to 255 down a QL screen). You might not get readings at the absolute edge, it depends on the pointer sprite origin how close to the edges it actually gets. It just prints a continuous stream of pairs of numbers, the absolute pointer x and position.
This program just does a one-off read of system variables and pointers at the start and then treats it as a fixed location. Probably safer to check those with each call in case things move in memory. I only wrote it like this to make it easier to understand without too much code inside the REPeat loop.
Code: Select all
100 REMark read absolute pointer position (0,0 = top left of screen)
110 REMark lowest and max readings may depend on pointer sprite origin
120 :
130 sysvars = 163840 : REMark system variables on BBQL
140 REMark are we on SBASIC or Minerva?
150 v$ = VER$ : IF v$ = 'HBA' OR v$ = 'JSL1' THEN sysvars = VER$(-2)
160 :
170 REMark get pointer to console linkage block
180 con_linkage = PEEK_L(sysvars+196) : REMark $C4 sys_clnk sys. variable
190 pt_xpos = con_linkage + 60 : REMark $3C pt_xpos (x position)
200 pt_ypos = con_linkage + 62 : REMark $3E pt_ypos (y position)
210 :
220 REPeat loop
230 ptrx% = PEEK_W(pt_xpos) : REMark pointer x position
240 ptry% = PEEK_W(pt_ypos) : REMark pointer y position
250 PRINT ptrx%!ptry%
260 IF INKEY$ = CHR$(27) THEN EXIT loop : REMark Esc to quit
270 END REPeat loop
280 STOP
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html
Re: Pointer Absolute Position
Nice, Dilwyn. INKEY$ need a channel, though, Better use a combination of SUSJB and KEYROW perhaps?
Per
dont be happy. worry
- ?
dont be happy. worry
- ?
Re: Pointer Absolute Position
Of course, if you close the channels. Only wrote that example to explain how to read absolute pointer positions from S*Basic without resorting to extensions. And your extension is perfect, much easier than my routine.
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html
Re: Pointer Absolute Position
To show how this could be used in a "real" program, I wrote a program called PtrPostn (pointer position), which both beeps when pointer is at the edges of the screen and when you press CTRL P it highlights the current pointer position by drawing some animated circles around the pointer origin (a bit like the equivalent ease of access facility in a certain operating system which starts with W), which is useful when the pointer goes missing on a busy high resolution screen, especially if your eyesight isn't as good as it used to be.
There are two versions, an SBASIC one for SMSQ/E users and a small Turbo compiled version for QDOS users. It'll generally be more useful on SMSQ/E systems which allow high resolution screens. Obviously, both need pointer environment.
Both versions can just be executed to quietly multi-task in the background until needed.
Being writeen in SBASIC, it's easy to amend to your requirements, e.g. change the key used.
https://dilwyn.qlforum.co.uk/misc/ptrpostn.zip
There are two versions, an SBASIC one for SMSQ/E users and a small Turbo compiled version for QDOS users. It'll generally be more useful on SMSQ/E systems which allow high resolution screens. Obviously, both need pointer environment.
Both versions can just be executed to quietly multi-task in the background until needed.
Being writeen in SBASIC, it's easy to amend to your requirements, e.g. change the key used.
https://dilwyn.qlforum.co.uk/misc/ptrpostn.zip
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html