RobTillaart / ANSI

Arduino library with basic ANSI display codes for simple terminal apps
MIT License
17 stars 6 forks source link

Detect terminal screen size #16

Closed chlordk closed 1 year ago

chlordk commented 1 year ago

New feature.

It has only been tested with Linux minicom.

By moving the cursor to right bottom and reading the cursor position, the screen size of the terminal can be detected.

Tested with two external screens where the size was 957x72 characters.

RobTillaart commented 1 year ago

Nice feature, if time permits I will check it on windows (10)

RobTillaart commented 1 year ago
RobTillaart commented 1 year ago

@chlordk did some tests on windows 10

UTF8 could fail because of a setting (putty/teraterm), not tested all possible combinations.

chlordk commented 1 year ago

Sounds good with the 3 terminal emulators. Screen size is the most important part. UTF8 would be handy to make various box drawings but it is not important. Here is some https://charcodes.netlify.app/#box_drawing

Currently I have some github problems so I can't push directly from a directory and thus I used the web interface to upload files where mkdir is not an option. It's a 2FA problem I have to sort out.

RobTillaart commented 1 year ago

@chlordk I will merge the PR, however there will be a rewrite as I want to keep the footprint as small as possible.

RobTillaart commented 1 year ago

@chlordk Merged, created an issue #17 to bring it to release level.

RobTillaart commented 1 year ago

@chlordk

ansi.print(" "); // some bug, first character written is missing

I could not confirm this with teraterm, mobaterm or putty

chlordk commented 1 year ago

I could not confirm this with teraterm, mobaterm or putty

OK you're right, I just tested it. It works now with minicom. I must have changed some other thing.

chlordk commented 1 year ago

I tried to write the detection code more compact. It's fewer lines and more readable but it takes up 232 bytes more program memory in this way. I guess it is because of »dead code elimination« so if sscanf() was used ones more it would not take more space.

  int count = 0;
  char buffer[10];
  print("\033[6n");
  Serial.setTimeout(timeout);
  if (7 <= Serial.readBytesUntil('R', buffer, sizeof(buffer)))
    count = sscanf(buffer, "\e[%d;%d", &screen->y, &screen->x);
  return count;
RobTillaart commented 1 year ago

Thanks for this addition/ investigation.

This "problem" of more memory for compacter code is a familiar one. Unfortunately one cannot assume what functions the library user will use.

The good part is a robustness gain as the sscanf() explicitly checks the esc[ sequence too, so you know you got all digits.

There is still a question about the minimal length of the buffer. Theoretically a screen could be just 9x9 resulting in e[9;9R which is correct and smaller than 7. Or even a 80x5 screen. Not tested those scenarios yet.

chlordk commented 12 months ago

Use of "String" requires more than 1000 bytes progmem extra, and even Serial.readBytesUntil() requires 450 bytes. So the equivalent you wrote is much smaller. As both deviceType() and readCursorPosition() uses "read to buffer" it might save some space with a function for that? In Stream.ccp there is a timedRead() which might be used in that function.

RobTillaart commented 12 months ago

@chlordk

I checked the device Type function and it should be fixed to. Thanks for pointing me to this (faulty) implementation.

Created #19

RobTillaart commented 12 months ago

@chlordk

Found that the eating of the character is a library bug. Will be fixed today (at least in develop branch)