Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query the character under the current cursor position or anywhere on the screen in bash

I know that the following statement is a way to query the current cursor position:

echo -en '\033[6n'

Does anyone know how to query the character under the cursor or populate a array with the contents of the current screen/window? I've searched through the ANSI terminal commands however a lot of these are pretty abstract and it doesn't look like they would do this properly. I also looked into doing it with the tcup command with no luck.

Thank you for your help.

like image 330
Jeff82 Avatar asked Nov 18 '14 21:11

Jeff82


1 Answers

An ANSI terminal is not really required to be able to tell you what is on the screen. You're supposed to remember that yourself, if you need the information. The popular ncurses library does that, for example, although it only allows you to export the screen to a file, and the fileformat is not documented. In any event, bash doesn't use ncurses, so it really doesn't know anything about the state of the console.

Most probably, the screen you are talking about is actually an artifact of some terminal emulation program like xterm. Those programs run in userspace, and rarely (if ever) have an external query interface. However, linux does have a console (actually, a number of emulated consoles, but using the display's console mode) and it maintains the display memory for those consoles. And furthermore, it provides an interface for reading the console memory, usually available as /dev/vcsN (for values of N between 0 and the number of virtual consoles linux was compiled with). /dev/vcs0 is the "current" console (the one which is visible).

Most linux distributions restrict access to /dev/vcsN, so if you want to play around with them you'll either need special privileges or you'll need to use root privileges to change the access permissions on the device files. (Ubuntu appears to provide rw access to users in group tty; check ls -l /dev/vcs0 to see how your system does it.) (And, of course, you'll need to find the console :-) Try CtlAlt1; CtlAlt7 will probably give you back your GUI.)

Once you've worked out the access issues, you could do something like cp /dev/vcs0 console_memory to take a look at it. What you'll find is that it is just a 2D array of characters with no newlines, and no indication of what the dimensions are. (You can get the dimensions with an ioctl or by looking at the environment variables $LINES and $COLUMNS.)

You could use /dev/vcsa0 instead; it has a slightly different format using two bytes per character in order to store display attributes (foreground and background colours, mostly) as well as the character. Also, the first four bytes of /dev/vcsaN are the screen dimensions and cursor position (one byte per coordinate), which will save you the work of querying the cursor position.

Note that the console does not support a full Unicode character set. In fact, it can only display 512 different glyphs at once. In order to maximize the available glyph space, Linux may reassign some codes to needed symbols, and this mapping is not part of the console memory. So the code extracted from console memory might not have an obvious mapping to a Unicode code, but it should work fine for standard ANSI characters.

like image 148
rici Avatar answered Oct 18 '22 18:10

rici