Recent

Author Topic: Simple mouse solution for terminal with Linux  (Read 10300 times)

Lauriet

  • New Member
  • *
  • Posts: 20
Simple mouse solution for terminal with Linux
« on: December 29, 2024, 07:34:45 am »
This has probably been asked before but after searching and trying various solutions, I have nothing that works and is simple.
I just want the mouse unit to work in a terminal box. I think maybe the terminal emulator maybe be interfering but when I use it, it does not return any info.
I know there is GPM and nCursors, but they don't work or are too complicated for my liking.
Shouldn't I be able to just read /dev/input/mice as a file.....but this doesnt seem to work ???
I come form using the mouse unit in Turbo Pascal in Dos, or even just doing the system calls to query the mouse. I would have thought that the mouse unit provided would work ???
Any help ???
« Last Edit: December 29, 2024, 07:36:38 am by Lauriet »

Seenkao

  • Hero Member
  • *****
  • Posts: 674
    • New ZenGL.
Re: Simple mouse solution for terminal with Linux
« Reply #1 on: December 29, 2024, 09:47:52 am »
Лично я не понял чего вы хотите.
Если я запускаю терминал, то у меня работает там мышка.
Вы делаете свой собственный терминал? Если да, то вам самому надо реализовать функциональность клавиатуры и мыши (обычно всё предоставляется LCL, если вы использовали LCL, просто надо зайдествовать эту функциональность).

---------------------------------------
Google translate:
Personally, I don't understand what you want.
If I launch the terminal, then my mouse works there.
Are you making your own terminal? If so, then you need to implement the keyboard and mouse functionality yourself (usually everything is provided by LCL, if you used LCL, you just need to add this functionality).
Rus: Стремлюсь к созданию минимальных и достаточно быстрых приложений.

Eng: I strive to create applications that are minimal and reasonably fast.
Working on ZenGL

AlexTP

  • Hero Member
  • *****
  • Posts: 2541
    • UVviewsoft
Re: Simple mouse solution for terminal with Linux
« Reply #2 on: December 29, 2024, 11:01:18 am »
User wants to read mouse events + coords in a textmode application without LCL.

Lauriet

  • New Member
  • *
  • Posts: 20
Re: Simple mouse solution for terminal with Linux
« Reply #3 on: December 30, 2024, 01:49:57 am »
This detects the mouse as a 2 button mouse, but does not write out the co-ordinance.

program test;
uses
  crt, mouse;


var
  Buttons : Byte;


begin
  ClrScr;

  InitMouse;
  Buttons := DetectMouse;

  repeat
    Writeln(GetMouseX : 5, GetMouseY : 5);
    Delay(1000);
  until KeyPressed;

end.

I would hope this worked, since that is why there is a UNIT mouse.

Any clues ???

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Simple mouse solution for terminal with Linux
« Reply #4 on: December 30, 2024, 03:30:45 am »
When using ANSI escape sequences, you can quite easily enable mouse support, then mouse events are written into stdin as escape sequences.

I did not yet come around to implement this in my LazTermUtils, because it requires bridging the gap between input and output, which by now is very separated. But implementing this manually is relatively straightforward. You can take a look at the xterm documentation for further information: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking

Lauriet

  • New Member
  • *
  • Posts: 20
Re: Simple mouse solution for terminal with Linux
« Reply #5 on: December 30, 2024, 10:03:52 am »
OK, but how do I enable mouse support ?
And why doesn't the mouse unit just work ?

Warfley

  • Hero Member
  • *****
  • Posts: 1870
Re: Simple mouse solution for terminal with Linux
« Reply #6 on: December 30, 2024, 03:07:02 pm »
As stated in the xterm documentation you just need to print out the control sequence to activate mouse tracking (e.g. via writeln)  and then you can read the mouse positions from the input (e.g. via readln)

tetrastes

  • Hero Member
  • *****
  • Posts: 636
Re: Simple mouse solution for terminal with Linux
« Reply #7 on: December 30, 2024, 10:14:39 pm »
OK, but how do I enable mouse support ?
And why doesn't the mouse unit just work ?

"Use the source, Luke!".  :D
If you read unix/mouse.pp, you would know. This unit (and your code) works at "true" text-mode console with GPM, but for X-terminals it does almost nothing, only enables xterm mouse (tracking and printing escape sequences). All other work you have to do yourself.
For example, keyboard unit has code for parsing escape sequences and imitate mouse events as keyboard ones. The following is rather ugly, but works:
Code: Pascal  [Select][+][-]
  1. uses
  2.   keyboard, mouse;
  3.  
  4. var
  5.   e: TMouseEvent;
  6.   c: char;
  7.  
  8. begin
  9.   InitMouse;
  10.   InitKeyboard;
  11.  
  12.   repeat
  13.     if KeyPressed then
  14.     begin
  15.         GetKeyEvent;
  16.         if PollMouseEvent(e) then
  17.           while PollMouseEvent(e) do
  18.           begin
  19.             GetMouseEvent(e);
  20.             Writeln(e.X,',',e.Y);
  21.           end
  22.         else
  23.           c := RawReadKey;
  24.     end;
  25.   until c = 'q';
  26.  
  27.   DoneKeyboard;
  28.   DoneMouse;
  29. end.
  30.  
Of course, this does not work properly at text console with GPM.

Free Vision also uses mouse unit, and works properly both at X-terminals and text console, but it is more complex and I did not dig into it.

Lauriet

  • New Member
  • *
  • Posts: 20
Re: Simple mouse solution for terminal with Linux
« Reply #8 on: December 31, 2024, 06:14:01 am »
OK, Thanks. This works and will help me out. :D

I would also be curious as to how to do it with ansi control characters, but after reading the doc I'm not completely sure how to use the CSI stuff. (I'm not very bright really)
Can anyone show code that does it ???

tetrastes

  • Hero Member
  • *****
  • Posts: 636
Re: Simple mouse solution for terminal with Linux
« Reply #9 on: December 31, 2024, 12:55:15 pm »
unix/keyboard.pp

Lauriet

  • New Member
  • *
  • Posts: 20
Re: Simple mouse solution for terminal with Linux
« Reply #10 on: January 01, 2025, 08:40:47 am »
Just in case anyone is interested, this now works as I would expect.


program test;
uses
  Video, MyMouse;


begin
  InitVideo;
  ClearScreen;
  InitMyMouse;

  repeat
    ReadMyMouse;
    WriteLn(MyMouseX : 4, MyMouseY : 4, MyMouseButtons : 4);
  until MyMouseButtons in [1,4];

  CloseMyMouse;
end.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

UNIT MyMouse;

interface


procedure InitMyMouse;

procedure CloseMyMouse;

function MyMouseButtons : Byte;

function MyMouseX : Byte;

function MyMouseY : Byte;

procedure ReadMyMouse;



implementation
uses
  keyboard, mouse;

var
  e  : TMouseEvent;
  MM : Record
         x, y, b : Byte;
       end;


procedure InitMyMouse;
begin
  InitMouse;
  InitKeyBoard;
end;


procedure CloseMyMouse;
begin
  DoneKeyboard;
  DoneMouse;
end;


function MyMouseButtons : Byte;
begin
  MyMouseButtons := MM.b;
end;


function MyMouseX : Byte;
begin
  MyMouseX := MM.X;
end;


function MyMouseY : Byte;
begin
  MyMouseY := MM.Y;
end;


procedure ReadMyMouse;
{-- waits for a button press and then returns mouse info }
var
  Ch : Char;
begin
  repeat
    if KeyBoard.KeyPressed then
      begin
        GetKeyEvent;
        if PollMouseEvent(e) then
          while PollMouseEvent(e) do
             begin
               GetMouseEvent(e);
               MM.x := e.x;
               MM.y := e.y;
               MM.b := e.Buttons;
             end
           else
            Ch := RawReadKey;
      end;
  until MM.b > 0;
end;


begin
end.




PascalDragon

  • Hero Member
  • *****
  • Posts: 5904
  • Compiler Developer
Re: Simple mouse solution for terminal with Linux
« Reply #11 on: January 03, 2025, 03:26:19 pm »
Just in case anyone is interested, this now works as I would expect.

Please use [code][/code]-tags to avoid the forum software interpreting your code and to have better readability.

Thaddy

  • Hero Member
  • *****
  • Posts: 16653
  • Kallstadt seems a good place to evict Trump to.
Re: Simple mouse solution for terminal with Linux
« Reply #12 on: January 03, 2025, 10:50:26 pm »
 '
Code: Pascal  [Select][+][-]
  1. ^//use code=pascal
'
In general I'd recommend to use the ptc* units: ptcgraph, ptccrt, ptckvm and some more.
These are native freepascal and very powerful. cross-platform too.
keyboard handling
Console handling
Video handling
Mouse handling
Font support

From the ptc series, I am not quite sure if ptckvm is already in the standard distribution, but it is in trunk.
« Last Edit: January 04, 2025, 08:43:18 am by Thaddy »
But I am sure they don't want the Trumps back...

Lauriet

  • New Member
  • *
  • Posts: 20
Re: Simple mouse solution for terminal with Linux
« Reply #13 on: February 09, 2025, 08:15:34 am »
WharWho!!

I got it how I wanted it. A simple self contained solution that does require lots of other units.
Since its just a terminal app, it does not need event loops or buffering or stuff.
Thanks for the suggestion of just using ansii thingies.
I'm now a little bit more knowledgable about xterm things.

Just in case any one is interested:

Code: Pascal  [Select][+][-]
  1.  
UNIT MyMouse;

interface


procedure InitMyMouse;

function MyMouseButtons : Boolean;

function MyMouseX : Byte;

function MyMouseY : Byte;

procedure ReadMyMouse;

procedure ClearMyMouse;



implementation
uses
  BaseUnix, Termio;

Type
  Stype = String[16];  {-- should be plenty }

var
  MM : Record
         x, y : Byte;
         b    : Boolean;
       end;


procedure InitMyMouse;
var
  Tio : Termios;
begin
   {-- set console to raw mode }
  TcGetAttr(1, Tio);
  SetTextLineEnding(OutPut, #13#10);
  CFMakeRaw(Tio);
  TcSetAttr(1, TCSANOW, Tio);

  write(#27'[?1036s'#27'[?1036h');   {-- tell keyboard to send escape sequences }
  write(#27'[?1006h');               { try to enable Extended/SGH 1006 mouse tracking }
  Write(#27'[?9h');                  {-- x10 mouse mode.....only reports when a mouse button is pressed }
end;


function MyMouseButtons : Boolean;
begin
  MyMouseButtons := MM.b;
end;


function MyMouseX : Byte;
begin
  MyMouseX := MM.X;
end;


function MyMouseY : Byte;
begin
  MyMouseY := MM.Y;
end;


procedure ClearMyMouse;
begin
  MM.x := 0;
  MM.y := 0;
  MM.b := False;
end;


function KeyPressed : Boolean;
var
  fdsin : tfdSet;
begin
  fpFD_ZERO(fdsin);
  fpFD_SET(StdInputHandle, fdsin);
  Keypressed := (fpSelect(StdInputHandle+1, @fdsin, nil, nil, 0) > 0);
end;


function StrToInt(S : Stype) : Byte;
begin
  case Length(s) of
    1 : StrToInt := Ord(S[1]) - 48;
    2 : StrToInt := 10*(Ord(S[1]) - 48) + (Ord(S[2]) - 48);
  else
    StrToInt := 0;
  end;
end;


procedure ReadMyMouse;
{-- waits for a button press and then returns mouse info }
var
  S       : Stype;
  ChStr   : String[2];
  x       : byte;
  NumRead : LongInt;
begin
  S := '';

  repeat
    ClearMyMouse;
    if KeyPressed then                  {-- waits for a key event, which include mouse events }
      begin
        repeat
          NumRead := fpRead(StdInputHandle, S, 16);
        until Numread <> -1;

        {-- pull apart the ansi string returned by the terminal }
        {-- get button press info }
        Delete(S, 1, 2);
        MM.b := s[1] = '0';
        Delete(s, 1, 2);

        {-- get X coord }
        x     := Pos(';', s)-1;
        ChStr := Copy(s, 1, x);
        MM.X  := StrToInt(ChStr);
        Delete(s, 1, x + 1);

        {-- get Y coord }
        x     := Pos('M', s) -1;
        ChStr := Copy(s, 1, x);
        MM.Y  := StrToInt(ChStr);

     end;
  until MM.b;
end;


begin
end.
« Last Edit: February 11, 2025, 03:18:22 am by Lauriet »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5904
  • Compiler Developer
Re: Simple mouse solution for terminal with Linux
« Reply #14 on: February 10, 2025, 11:34:29 pm »
Just in case any one is interested:

Again: please use [code=pascal][/code]-tags!

 

TinyPortal © 2005-2018