3

I am coding an user interface with ncurses. I have a problem when my terminal width or height is beyond to 222 characters/rows, mouses coordinates return the -33 value, so when i click to beyond 222 characters mouse_x = -33 when i click to beyond 222 rows mouse_y = -33

Would it be possible to tell ncurses no to stop mouses events beyond 222 characters/rows ? This bug also occurs in vim, when you move the :vs separation bar beyond 222 characters, it goes back to x=0.

Maybe this bug has already been fixed ?

  1 #include <ncurses.h>
  2 
  3 void    treat_mouse(MEVENT* event);
  4 
  5 int     main(void)
  6 {
  7         bool    run;
  8         int     key;
  9         MEVENT  event;
 10 
 11         run = true;
 12         initscr();
 13         noecho();
 14         keypad(stdscr, TRUE);
 15         mousemask(BUTTON1_PRESSED, NULL);
 16         while (run == true)
 17         {
 18                 key = getch();
 19                 switch  (key)
 20                 {
 21                         case    'q':
 22                                 run = false;
 23                                 break;
 24                         case    KEY_MOUSE:
 25                                 treat_mouse(&event);
 26                                 break;
 27                         default:
 28                                 break;
 29                 }
 30         }
 31         endwin();
 32         return 0;
 33 }
 34 
 35 void    treat_mouse(MEVENT* event)
 36 {
 37         if (getmouse(event) == OK)
 38                 mvwprintw(stdscr, 0, 0, "click: x = %d, y = %d\n", event->x, event->y);
 39 } 

.

.

======================== EDIT =======================

.

.

Ok i have found.

I have downloaded ncurses code source here http://ftp.gnu.org/pub/gnu/ncurses/

And i have taken this link ncurses-5.9.tar.gz 04-Apr-2011 19:12 2.7M

I have searched getch().

getch() call wgetch().

wgetch() call _nc_wgetch().

_nc_wgetch() call _mouse_inline().

_mouse_inline() is a function pointer in struct screen who call _nc_mouse_inline() or no_mouse_inline() who is an empty function (when no mouse i think).

you can see _nc_mouse_inline() function in ncurses-5.9/ncurses/base/lib_mouse.c

She use unsigned char to calcul mouse coordinates, to see this litle example:

821 static bool
822 _nc_mouse_inline(SCREEN *sp)
823 /* mouse report received in the keyboard stream -- parse its info */
824 {
.
.
.
832         unsigned char kbuf[4];
.
.
.
970         eventp->x = (kbuf[1] - ' ') - 1;
971         eventp->y = (kbuf[2] - ' ') - 1;
.
.
.
984     return (result);
985 }

Finally I'll do anything.

Torx
  • 31
  • 3
  • 1
    This answers your question: [How to Build Curses Program That Supports More Than 223 Columns of Mouse Input](https://stackoverflow.com/questions/47256750/how-to-build-curses-program-that-supports-more-than-223-columns-of-mouse-input) – Thomas Dickey May 23 '22 at 08:08

1 Answers1

0

I think you've found the answer to your question.

unsigned char kbuf[4];
eventp->x = (kbuf[1] - ' ') - 1;
eventp->y = (kbuf[2] - ' ') - 1;

The mouse x and y are been received as unsigned char, so the maximum value they can hold is 255. ' ' (space) is ASCII 32, so the maximum value possible is 255 - 32 - 1 which equals 222.

The value then wraps to 0 giving 0 - 32 -1 which equals -33.

parkydr
  • 7,596
  • 3
  • 32
  • 42
  • This is a limitation of the xterm mouse protocol. There is an extension (SGR 1006), but the latest news about its support in ncurses were just: https://lists.gnu.org/archive/html/bug-ncurses/2013-01/msg00014.html – ninjalj Jul 17 '14 at 07:06