How to get display devices name in Linux - c

I'd like to find linux analogs of EnumDisplayDevices and EnumDisplaySettingsEx WinAPI functions.
The info I need to get is display name and state (if it active or not), width, height, bits per pixel and frequency.
How can I get this info using C (C++)?
Thanks.

As mentioned by 'Some programmer dude' in the comments you can have to go through the X window system. Most specifically one option would be the RandR protocol. Here is the protocol specification as well as the source code of the command xrandr that invokes the XRR functions and outputs most of the info that you want on the terminal. Look for the place where the
XRRScreenResources *res
is populated and then how the modes are fetched from it using the find_mode() function.
other commands that might assist you and don't go over the RandR extensions could be xprop(1), xdpyinfo(1), xwininfo(1)

Some programmer dude and ramrunner are absolutely correct. For most Linux systems, the graphical "desktop" is based on X Windows. Command-line tools for querying your X "display" include xrandr and xdpyinfo. The C-language source code for both are freely available; you can find many example programs with a Google search.
... HOWEVER ...
X Windows is "client/server". Your Linux "desktop" need not be on your physical PC; your X "display" could just as easily be a Windows desktop. In this case - xrandr and xdpyinfo are still applicable: they refer to where you're displaying (e.g. an XMing client on Windows), and not the physical host Linux is running on.
If you want to query the graphics devicews on your physical server ... then you'll instead use commands like lshw -c display or get-edid

Related

Is there a way to get help for some C functions inside of vim/Neovim?

This question may be a little off topic. But I was wondering if there was a way for me to look at the descriptions of C functions using vim or neovim. Is it possible to look at their documentations by doing something like :help? This would really be helpful since I wouldn't need to lookup to my browser everytime.
I am unclear about these things:
Can :help be my friend here ?
Can I use LSPs to do something like this ?
I am using latest Neovim inside Ubunutu 20.04 in WSL. Is this helpful somehow ?
By pressing K, the keyword under the cursor is looked up using a configured keyword lookup program, the default being man. This works pretty much out of the box for the C standard library.
For C++, you might want to look at something like cppman.
Well yes, you can get the description of C functions by using a LSP (language server plugin)! Here is an image of me using clangd as my LSP:
You'd "just" need to install the LSP and start it. I don't know how familiar you're with neovim, but just in case if you don't know how to install a plugin or to be more specifique: If you don't know how you can install a LSP server, then you can do the following:
There're plenty videos how to set up a LSP-Server for your language. Here's an example.
If you don't want to set up on your own, you can pick up one of the preconfigured neovim setups (some of my friends are recommending lunarvim)
But yeah, that's it. If you have any further questions feel free to ask them in the comments.
Happy vimming c(^-^)c
Let's explain how "K" command works in more detail.
You can run external commands by prefixing them with :! command. So running man tool is as easy as
:!man <C-R><C-W>
Here <C-R><C-W> is a special key combination used to put word under cursor from text buffer down to command line.
Same for showing Vim's built-in help page
:help <C-R><C-W>
As it feels tedious to type that, Vim also defines K Normal mode command that does pretty much the same thing. Except the tool name is taken from value of an option named "keywordprg".
So doing set keywordprg=man (default for *nix systems) makes K to invoke !man tool; while set keywordprg=:help is for bultin help.
Also, the option :h 'keywordprg' is made global or local-to-buffer, so any Vim buffer is able to overwrite global setting. For example, this is already done by standard runtime for "vim" and "help" buffers, so they call ":help" instead of "man".
The problem with :!man command is that it shows "black console". It'd be nice if we could capture man's output and open it inside Vim just like a builtin help page. Then we could also apply some pretty highlighting, assign key macros and all such. This is a pretty common trick and it is already done by a standard plugin shipped with Vim/Neovim.
A command that the plugin provides is called :Man, so you can open :Man man instead of :!man man, for example. The plugin is preactivated in Neovim; for Vim you still need to source one file manually. So to make use of this plugin you'll need something like this
set keywordprg=:Man
if !has("nvim")
source $VIMRUNTIME/ftplugin/man.vim
endif
The previous answer recommending cppman is the way to go. There is no need to install a bulky language server just for the purpose of having the hover functionality. However, make sure you're caching the man pages via cppman -c. Otherwise, there will be a noticeable delay since cppman is fetching the page from cppreference.com on the fly.
If you like popups for displaying documentation, convert the uncompressed man pages (groff -t -e -mandoc -Tascii <man-page> | col -bx), and set keywordprg to your own wrapper to search for keywords according to your needs.

Get the vendor of an executable file on UNIX-LIKE systems

I am trying to collect the vendor of an executable file under differents UNIX-LIKE systems ( Red Hat, AIX, Solaris, Oracle Linux ...).
I would like to do the same as the following command on Windows :
WMIC /LOCALE:MS_409 DATAFILE WHERE (Name="C:\\Program Files\\Java\\jdk-10\\bin\\java.exe") GET manufacturer
I have looked at the file and strings command without success.
No clue how to achieve it.
Any help will be appreciated.
As pointed out UNIX files do not have a vendor, mostly because there is no standard for it, but RPM-based distributions like Red Hat provide a "vendor" that can be queried with a command like this:
rpm -qa --queryformat '%{NAME}TAB%{DISTRIBUTION}TAB%{VENDOR}\n'
(Use a TAB character for TAB in the code above if you want to load it into a spreadsheet program or similar)
rpmkeys --querytags lists all known query tags like NAME.

ACS characters not working in putty even with export NCURSES_NO_UTF8_ACS=1

I am developing an ncurses application myself in C. The problem is that putty displays alternative character set characters like ACS_VLINE as letters. My locale is
LANG=en_US.UTF-8
and I have set
export NCURSES_NO_UTF8_ACS=1
I have also set putty to UTF-8 and tried different fonts. The characters display fine on the tty on the actual machine so I think the issue is with putty. I have also tried linking ncursesw instead of ncurses.
It is a combination of things. The recommended TERM for PuTTY is "putty", but due to inertia, most people use "xterm". The line-drawing support in the xterm terminal description is different from PuTTY's assumptions because xterm supports luit, which has some limitations with the way the alternate character set is managed (see Debian Bug report #254316:
ncurses-base: workaround for screen's handling of register sgr0 isn't quite right).
If you use infocmp to compare, you may see these lines which deal with the alternate character set:
acsc: '``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~', '``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~'.
enacs: NULL, '\E(B\E)0'.
rmacs: '\E(B', '^O'.
smacs: '\E(0', '^N'.
VT100s can have two character sets "designated", referred to as G0 and G1:
The "xterm" line-drawing works by changing the designation of G0 between the ASCII and line-drawing characters,
the "putty" line-drawing works by designating ASCII in G0 and line-drawing in G1 and switching between the two with the shift-in/shift-out control characters.
Although both are VT100-compatible, the xterm scheme does not work with PuTTY. Because of the tie-in with luit, the normal terminal description for xterm will not change (unless it proves possible to modify luit to solve the problem for its users), so a workaround is needed for users of PuTTY:
use a different terminal description as recommended, e.g., TERM=putty. PuTTY's settings dialog lets you set environment variables to pass to the remote machine.
This has the drawback that some systems do not have the full ncurses terminal database installed, due to "size" (it is 6.8Mb on my local machine). Also, TERM may not be on the list of allowed ssh environment variables.
you can compile your own terminfo entry with ncurses' tic, e.g.,
cat >foo <<"EOF"
xterm|my terminfo entry,
enacs=\E(B\E)0,
rmacs=^O,
smacs=^N,
use=xterm-new,
EOF
tic foo
use GNU screen. It does its own fixes, and happens to compensate for PuTTY's problems.
Further reading
SCS – Select Character Set (VT100 manual)
4.4 Character Set Selection (SCS) (VT220 manual)
The terminfo database is big—do I need all of that? (ncurses FAQ)
Putty: login, execute command/change environment variable, and do NOT close the session
I want to make some additions. I faced same issue: many ncurses-based tools like dialog, menuconfig and nconfig from Linux kenrel sources, even mc is broken when built with ncurses (although mc is built using Slang on many OSes and not affected).
Here is what happened
ncurses uses smacs record from terminfo to switch to "alternative charset" and then it uses acsc to draw boxes. It sends a which is box-drawing character in alternative charset (ACS).
This is VT100 graphics.
Some terminal emulators nowadays do not support ACS when in UTF-8 because apps have ability to send real box-drawing codepoints.
There is unofficial capability U8 (capital U!) in terminfo that tells ncurses: "Instead of ACS use real box-drawing codepoints."
I have this capability infocmp -x xterm-utf and for putty aswell, but not for xterm.
As you can read in ncurses(3) (https://invisible-island.net/ncurses/man/ncurses.3x.html), ncurses is aware of Linux console and GNU screen (and tmux, which also uses screen as TERM) and always behave like if U8 were set.
For other terminals that do not support ACS when in UTF, you can set NCURSES_NO_UTF8_ACS.
Unfortunatelly, ncurses is not aware of putty.
There is also luit that may convert ACS to Unicode points.
So, here is what we can do to run ncurses + putty in UTF-8:
Use terminal with U8#1 capability. This one is set for putty (btw, I suggest to use putty-256color instead). You can create your own entry with U8#1 and colors#256 and compile it with tic -x. Be carefull that mouse may not work on terminals that do not start with xterm (see mouseinterval(3), BUGS section). This is why I do not use putty terminal. I suggest to copy xterm-utf8, add colors#256, compile and stay with it: it works perfectly with putty, mouse and utf8.
You can set NCURSES_NO_UTF8_ACS in your profile.
You can run screen or tmux: it will set TERM to screen and fix ncurses
You can run luit: it will do all convertions for you.
Since putty 0.71 you can ask putty to support ACS drawings even in UTF-8

How can output be directed to specific coordinates in the linux terminal?

To be more specific, I am looking for an equivalent to the Windows API function: WriteConsoleOutputCharacter. I know this style of direct output is possible, as I have seen the behaviour used before in the time that I have used Linux. However, I am still a baby when it comes to Linux specific C libraries, and have not been able to ascertain any clues as to where I may find such functionality. Any assistance would be appreciated.
Check out ncurses library.
It allows you to create some text-based UI in terminal. It is more than you asked, but if you need more than only this one function it may be best option for you.
You can use the ANSI control sequence
Say, following will print 'ddd' string 3 lines above the prompt in bash
echo -e "\e[3Addd"
This line will put a clock in right upper conner of a terminal (from commandlinefu.com)
while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-29));date;tput rc;done

Programmatically capture X11 region with ffmpeg in C/whatever

There is an input format option to ffmpeg -- x11grab which allows one to capture specified region and output it to file/stream. I'm trying to do the same thing programmatically, but i haven't found any non-basic tutorials/reference for ffmpeg API.
I wonder, how it is possible to open x11 region with avformat_input_file or something like this. Or should i do it with XCopyArea/etc?
(Any programming language will satisfy)
There are many applications that take a screenshot. Major hint: it's open source, use the source. If you can't find the code in ffmpeg, any example application will do:
http://git.gnome.org/browse/gnome-screenshot/tree/src/screenshot-utils.c#n425
This is gnome-screenshot source code. This example uses gdk_get_default_root_window().

Resources