Developing for the HDMI port on Linux

2024/10/12 18:19:58

How would it be possible to exclusively drive the HDMI output from an application, without allowing the OS to automatically configure it for display output?

For example, using the standard DVI/VGA as the primary display, but sending Mplayer video output to the HDMI using a device file.

It's a difficult question to answer via Google. Almost every result has to do with making audio work over HDMI.

(edited here)

A comment, below, mentioned using separate Xorg servers. Although this is a helpful idea, it doesn't answer one question that I asked, and one that I implied:

1) How do I keep Linux from wanting to put the console on that display, if it's loaded before the other display, or if it's the only display (when only SSH is used for login)? 2) What if there is no X? I want to drive graphics to the adapter directly. Can I do this from code using standard functionality, without interacting with the drivers directly (probably outdated, but using SVGALib or some other non-X graphics layer)?

(edited here)

I looked at SVGALib (which is old) and SDL. The latter works both in and outside of X, and even provides access to OpenGL. I found version 1.3 via a forum link, somewhere, but both the website and the FTP only seem to have up to 1.2 . SDL is a beautiful solution, in general, but it has the following two, specific disadvantages:

1) The general create-device call accepts a device index, but completely ignores it:

(src/video/bwindow/SDL_bvideo.cc)
BE_CreateDevice(int devindex)

The driver-specific call seems to have the same flaw. For example, DirectFB (which, I assume, provides graphics under the console):

(src/video/directfb/SDL_DirectFB_video.c)
DirectFB_CreateDevice(int devindex)

Neither of these functions' bodies seems to have an existing place to set the device-index either... No doubt due to lack of support in the standard interface that they're built for.

2) On whatever adapter happens to be elected, SDL seems to automatically attach all displays together. The example "testsprite2.c" (came with library), accepts a "--display" parameter, which is processed within "common.c" (common functionality for all examples). You can see that all it does with the "--display" parameter is calculates the X/Y coordinate of that screen within one large, combined canvas:

if (SDL_strcasecmp(argv[index], "--display") == 0) {++index;if (!argv[index]) {return -1;}state->display = SDL_atoi(argv[index]);if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);}if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);}return 2;
}

So, there's no way to isolate one display from a another if they're on the same adapter. SDL will not work.

Unless there's a comparable solution to SDL, or it turns out to be trivial to set the particular device (devindex) in the appropriate place (which is probably not the case, and, therefore, probably the reason that it was left unimplemented), it seems like the best option for exclusive and completely dedicated use of the screen is to write your own window manager under a separate Xorg instance assigned to your second device.

Answer

You can directly write into the framebuffer device /dev/fb (assuming that your console uses one, by default). To prevent a console from showing on it, just disable all of your virtual terminals (you will then only be able to log-in remotely). You should get more than one framebuffer device if you have multiple adapters (this needs to be confirmed).

A C example that draws a rectangle on the framebuffer is here:

Paint Pixels to Screen via Linux FrameBuffer

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>int main()
{int fbfd = 0;struct fb_var_screeninfo vinfo;struct fb_fix_screeninfo finfo;long int screensize = 0;char *fbp = 0;int x = 0, y = 0;long int location = 0;// Open the file for reading and writingfbfd = open("/dev/fb0", O_RDWR);if (fbfd == -1) {perror("Error: cannot open framebuffer device");exit(1);}printf("The framebuffer device was opened successfully.\n");// Get fixed screen informationif (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {perror("Error reading fixed information");exit(2);}// Get variable screen informationif (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {perror("Error reading variable information");exit(3);}printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);// Figure out the size of the screen in bytesscreensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;// Map the device to memoryfbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);if ((int)fbp == -1) {perror("Error: failed to map framebuffer device to memory");exit(4);}printf("The framebuffer device was mapped to memory successfully.\n");x = 100; y = 100;       // Where we are going to put the pixel// Figure out where in memory to put the pixelfor (y = 100; y < 300; y++)for (x = 100; x < 300; x++) {location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +(y+vinfo.yoffset) * finfo.line_length;if (vinfo.bits_per_pixel == 32) {*(fbp + location) = 100;        // Some blue*(fbp + location + 1) = 15+(x-100)/2;     // A little green*(fbp + location + 2) = 200-(y-100)/5;    // A lot of red*(fbp + location + 3) = 0;      // No transparency//location += 4;} else  { //assume 16bppint b = 10;int g = (x-100)/6;     // A little greenint r = 31-(y-100)/16;    // A lot of redunsigned short int t = r<<11 | g << 5 | b;*((unsigned short int*)(fbp + location)) = t;}}munmap(fbp, screensize);close(fbfd);return 0;
}

As long as you have the build tools available, along with the headers for your system, it should compile. For a thrill, run it from SSH and watch it draw on a physical screen that you haven't logged-in to.

It should be noted that there is a wide array of tools that work against the framebuffer, outside of X11, but they won't access the framebuffer directly. Instead, they work through an additional abstraction layer called DirectFB. DirectFB will allow the same applications to run both in and outside of X11... Including both MPlayer, GStreamer, any app that incorporates SDL (which calls DirectFB), as well as a light, popular fake-X11 container called XDirectFB (I believe that it should run X11 apps, but not be as overburdening as a typical window manager).

https://en.xdnf.cn/q/69620.html

Related Q&A

Hive client for Python 3.x

is it possible to connect to hadoop and run hive queries using Python 3.x? I am using Python 3.4.1.I found out that it can be done as written here: https://cwiki.apache.org/confluence/display/Hive/Hiv…

How to add a function call to a list?

I have a Python code that uses the following functions:def func1(arguments a, b, c):def func2(arguments d, e, f):def func3(arguments g, h, i):Each of the above functions configures a CLI command on a p…

How to do fuzzy string search without a heavy database?

I have a mapping of catalog numbers to product names:35 cozy comforter 35 warm blanket 67 pillowand need a search that would find misspelled, mixed names like "warm cmfrter".We have code u…

Logging while nbconvert execute

I have a Jupyter notebook that needs to run from the command line. For this I have the following command:jupyter nbconvert --execute my_jupyter_notebook.ipynb --to pythonThis command creates a python s…

How to provide input for a TensorFlow DNNRegressor in Java?

I managed to write a TensorFlow python program with a DNNRegressor. I have trained the model and is able to get a prediction from the model in Python by manually created input (constant tensors). I hav…

Adding breakpoint command lists in GDB controlled from Python script

Im using Python to control GDB via batch commands. Heres how Im calling GDB:$ gdb --batch --command=cmd.gdb myprogramThe cmd.gdb listing just contains the line calling the Python scriptsource cmd.pyAnd…

Getting the maximum accuracy for a binary probabilistic classifier in scikit-learn

Is there any built-in function to get the maximum accuracy for a binary probabilistic classifier in scikit-learn?E.g. to get the maximum F1-score I do:# AUCPR precision, recall, thresholds = sklearn.m…

Pydantic does not validate when assigning a number to a string

When assigning an incorrect attribute to a Pydantic model field, no validation error occurs. from pydantic import BaseModelclass pyUser(BaseModel):username: strclass Config:validate_all = Truevalidate_…

PyUsb USB Barcode Scanner

Im trying to output a string from a barcode or qrcode using a Honeywell USB 3310g scanner in Ubuntu. I have libusb and a library called metro-usb (http://gitorious.org/other/metro-usb) which are enabli…

Count unique dates in pandas dataframe

I have a dataframe of surface weather observations (fzraHrObs) organized by a station identifier code and date. fzraHrObs has several columns of weather data. The station code and date (datetime object…