[Solved] Which device to open for FBIO_ADPINFO?

I'm trying to play with the vt(4) framebuffer console. To this end I want to query the adapter info with the mentioned ioctl(). The ultimate goal is to mmap the framebuffer's start address and then modify pixels. I've run into a brick wall and need your help. While some ioctls work when the file descriptor is from opening /dev/ttyv0, this does not work for FBIO_ADPINFO. I get the feeling I need to open a different device file, but nothing in my /dev directory looks or acts like a framebuffer device. Do I need to tune a sysctl first to see it? Anyway, here's my program:

C:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/fbio.h>

int main(int argc, char **argv) {
    int     sc;
    int     fd = 1;

    if (argv[1] != NULL)
        fd = open(argv[1], O_RDWR);

    /* This works for /dev/ttyv0 */
    struct fbtype fb;
    sc = ioctl(fd, FBIOGTYPE, &fb);
    if (sc != 0) {
        perror("ioctl FBIOGTYPE");
        exit(1);
    }
    printf("fb_type    %d\n", fb.fb_type);
    printf("fb_height  %d\n", fb.fb_height);
    printf("fb_width   %d\n", fb.fb_width);
    printf("fb_depth   %d\n", fb.fb_depth);
    printf("fb_cmsize  %d\n", fb.fb_cmsize);
    printf("fb_size    %d\n", fb.fb_size);

    /* This doesn't. */
    struct video_adapter_info info;
    sc = ioctl(fd, FBIO_ADPINFO, &info);
    if (sc != 0) {
        perror("ioctl FBIO_ADPINFO");
        exit(1);
    }
    printf("d = %p\n", (void *) info.va_window);
    return EXIT_SUCCESS;
}

Compile with "cc -o fb fb.c" and run with one argument for the device, "./fb /dev/ttyv0" (not under X11 but on the console). All I get is "ioctl FBIO_ADPINFO: Inappropriate ioctl for device".
What am I missing?
 
you may be able to mmap the /dev/ttyv0 fd and try write to it and see what happens.
not all vt implementations seem to support mmap / virtio_gpu does not for example.
 
this works
run it < 1.rgb (zipped) :)
console width should be >= 800px to display properly
C:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/fbio.h>
#include <sys/mman.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    int     sc;
    int     fd = 1;
    unsigned char *mfb;
    int i;
    unsigned char r, g, b;

    if (argv[1] != NULL)
        fd = open(argv[1], O_RDWR);

    /* This works for /dev/ttyv0 */
    struct fbtype fb;
    sc = ioctl(fd, FBIOGTYPE, &fb);
    if (sc != 0) {
        perror("ioctl FBIOGTYPE");
        exit(1);
    }
    printf("fb_type    %d\n", fb.fb_type);
    printf("fb_height  %d\n", fb.fb_height);
    printf("fb_width   %d\n", fb.fb_width);
    printf("fb_depth   %d\n", fb.fb_depth);
    printf("fb_cmsize  %d\n", fb.fb_cmsize);
    printf("fb_size    %d\n", fb.fb_size);
    mfb = mmap(NULL, fb.fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if(mfb == MAP_FAILED) {
     perror("mmap");
     exit(1);
    }
    printf("%p\n",mfb);
    for(i = 0; i < fb.fb_size;i += fb.fb_depth / 8) {
    if(((i / ( fb.fb_depth / 8)) % fb.fb_width ) >= 800)
    continue;
    r = getchar();
    g = getchar();
    b = getchar();
    mfb[i] = b;
    mfb[i + 1] = g;
    mfb[i + 2] = r;
    }
    return EXIT_SUCCESS;
}
 

Attachments

1758180430275.png
 
Should we wait for vt_ pacman?
:-) There's vt Lissajous for now. Assumes full color display with 32 bits per pixel. Link with -lm.

C:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
#include <sys/mman.h>
#include <sys/fbio.h>

uint32_t *gFramebuffer = NULL;
struct fbtype gFb = { 0 };

void    set_pixel(uint32_t aX, uint32_t aY, uint32_t aColor);

int main(int argc, char **argv) {
    int     sc;
    int     fd = 1;

    if (argv[1] != NULL)
        fd = open(argv[1], O_RDWR);

    /* This works for /dev/ttyv0 */
    sc = ioctl(fd, FBIOGTYPE, &gFb);
    if (sc != 0) {
        perror("ioctl FBIOGTYPE");
        exit(1);
    }
    printf("fb_type    %d\n", gFb.fb_type);
    printf("fb_height  %d\n", gFb.fb_height);
    printf("fb_width   %d\n", gFb.fb_width);
    printf("fb_depth   %d\n", gFb.fb_depth);
    printf("fb_cmsize  %d\n", gFb.fb_cmsize);
    printf("fb_size    %d\n", gFb.fb_size);

    gFramebuffer = mmap(NULL, gFb.fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (gFramebuffer == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    for (size_t i = 0; i < 100000; ++i) {
        double  a = 2 * 3.1415926 / 100000.0 * i;
        double xf = .5 * (1. + cos(7 * a));
        double yf = .5 * (1. + sin(13 * a));
        int     x = gFb.fb_width * xf;
        int     y = gFb.fb_height * yf;
        set_pixel(x, y, 0xFF00 * xf + 0xFF * yf);
    }
    return EXIT_SUCCESS;
}

void set_pixel(uint32_t aX, uint32_t aY, uint32_t aColor) {
    aX %= gFb.fb_width;
    aY %= gFb.fb_height;
    gFramebuffer[gFb.fb_width * aY + aX] = aColor;
}
 
Back
Top