Applied, thanks!

Damien Zammit, le lun. 28 oct. 2024 08:09:13 +0000, a ecrit:
> When bootloader sets a linear framebuffer mode and passes
> the required info to Hurd via multiboot info table, we
> can use this framebuffer as is.
> Otherwise, fall back to EGA text mode as before.
> 
> This is just the new framebuffer code as a separate commit.
> 
> ---
>  console-client/fb.c | 638 ++++++++++++++++++++++++++++++++++++++++++++
>  console-client/fb.h | 136 ++++++++++
>  2 files changed, 774 insertions(+)
>  create mode 100644 console-client/fb.c
>  create mode 100644 console-client/fb.h
> 
> diff --git a/console-client/fb.c b/console-client/fb.c
> new file mode 100644
> index 00000000..382b949b
> --- /dev/null
> +++ b/console-client/fb.c
> @@ -0,0 +1,638 @@
> +/* 
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +   This file is part of the GNU Hurd.
> +
> +   The GNU Hurd is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License as
> +   published by the Free Software Foundation; either version 2, or (at
> +   your option) any later version.
> +
> +   The GNU Hurd is distributed in the hope that it will be useful, but
> +   WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
> +
> +#include <assert-backtrace.h>
> +#include <errno.h>
> +#include <error.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <iconv.h>
> +#include <argp.h>
> +#include <string.h>
> +#include <stdint.h>
> +
> +#include <sys/io.h>
> +#include <sys/mman.h>
> +#include <sys/fcntl.h>
> +#include <pthread.h>
> +#include <hurd/console.h>
> +#include <device/device.h>
> +#include <hurd.h>
> +#include <mach.h>
> +
> +#include "driver.h"
> +
> +#include "fb.h"
> +#include "vga-hw.h"
> +#include "vga-support.h"
> +#include "bdf.h"
> +#include "unicode.h"
> +
> +/* The font file.  */
> +#define DEFAULT_VGA_FONT DEFAULT_VGA_FONT_DIR "vga-system.bdf"
> +static char *fb_display_font;
> +
> +off_t vga_fb;
> +int fb_type;
> +int fb_width;
> +int fb_height;
> +int fb_bpp;
> +int fb_wc;
> +int fb_hc;
> +
> +static unsigned char question_mark[32] = {
> +     0x7E,   /*  ******  */
> +     0xC3,   /* **    ** */
> +     0x99,   /* *  **  * */
> +     0x99,   /* *  **  * */
> +     0xF9,   /* *****  * */
> +     0xF3,   /* ****  ** */
> +     0xF3,   /* ***  *** */
> +     0xE7,   /* ***  *** */
> +     0xFF,   /* ******** */
> +     0xE7,   /* ***  *** */
> +     0xE7,   /* ***  *** */
> +     0x7E,   /*  ******  */
> +     0
> +};
> +
> +static struct bdf_glyph qmark = {
> +  .name = "missing",
> +  .encoding = 0,
> +  .internal_encoding = 0,
> +  .bbox = { 8, 12, 0, 0 },
> +  .bitmap = &question_mark[0],
> +}; 
> +
> +/* Is set to 1 if the cursor state should be hidden.  */
> +static int cursor_hidden;
> +static int cursor_state;
> +static int cursor_pos_x = 0;
> +static int cursor_pos_y = 0;
> +
> +static int current_width;
> +static int current_height;
> +
> +/* FIXME: inherit previous char colours */
> +static int current_fg = 7;
> +static int current_bg = 0;
> +
> +#define fb_pos(_col, _row) (vga_videomem + fb_bpp/8 * ( (_row) * fb_hc * 
> disp->width + (_col) * fb_wc ))
> +#define CURSOR_GLYPH 0x2581
> +#define CURSOR_COLOUR        7
> +
> +
> +
> +error_t
> +fb_get_multiboot_params (void)
> +{
> +  error_t ret = 0;
> +  mach_port_t master_device, mbinfo_dev;
> +  struct multiboot_raw_info mbi;
> +  char buf[sizeof(struct multiboot_raw_info)];
> +  char *bufptr = &buf[0];
> +  uint32_t bytes = sizeof(struct multiboot_raw_info);
> +  uint32_t bytes_read = 0;
> +
> +  ret = get_privileged_ports (NULL, &master_device);
> +  if (ret)
> +    goto fail;
> +
> +  ret = device_open (master_device, D_READ, "mbinfo", &mbinfo_dev);
> +  mach_port_deallocate (mach_task_self (), master_device);
> +  if (ret)
> +    goto fail;
> +
> +  ret = device_read (mbinfo_dev, D_READ, 0, bytes, &bufptr, &bytes_read);
> +  mach_port_deallocate (mach_task_self (), mbinfo_dev);
> +  if (ret)
> +    goto fail;
> +
> +  if (bytes_read != bytes)
> +    goto fail;
> +
> +  memcpy((void *)&mbi, (void *)bufptr, sizeof(struct multiboot_raw_info));
> +
> +  vga_fb = mbi.fb_info.framebuffer_addr;
> +  fb_type = mbi.fb_info.framebuffer_type;
> +  fb_width = mbi.fb_info.framebuffer_width;
> +  fb_height = mbi.fb_info.framebuffer_height;
> +  fb_bpp = mbi.fb_info.framebuffer_bpp;
> +  fb_wc = FONT_PIXELS_W;
> +  fb_hc = FONT_PIXELS_H;
> +  return ret;
> +
> +fail:
> +  /* Fall back to EGA text mode */
> +  fb_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
> +  return ret;
> +}
> +
> +static struct bdf_glyph *
> +always_find_glyph(bdf_font_t f, int ch)
> +{
> +  struct bdf_glyph *g;
> +
> +  g = bdf_find_glyph (f, ch, 0);
> +  if (!g)
> +    g = bdf_find_glyph (f, -1, ch);
> +  if (!g)
> +    g = &qmark;
> +
> +  return g;
> +}
> +
> +static void
> +blit_glyph(bdf_font_t f, char *mem, int ch, uint32_t fg, uint32_t bg, int 
> width, int bpp)
> +{
> +  int w, h;
> +
> +  struct bdf_glyph *gl = always_find_glyph(f, ch);
> +
> +  if (bg == -1)
> +    bg = current_bg;
> +  if (fg == -1)
> +    fg = current_fg;
> +
> +  for (h = 0; h < fb_hc; h++)
> +    {
> +      for (w = 0; w < fb_wc; w++)
> +        {
> +          char *pixel = mem + bpp/8 * (w + width * h);
> +          uint32_t colour = (gl->bitmap[h] & (1 << (7-w))) ? fg : bg;
> +          pixel[0] = (colour >> 16) & 0xff;
> +          pixel[1] = (colour >> 8) & 0xff;
> +          pixel[2] = colour & 0xff;
> +        }
> +    }
> +}
> +
> +static void
> +blit_glyph_xor(bdf_font_t f, char *mem, int ch, uint32_t fg, uint32_t bg, 
> int width, int bpp)
> +{
> +  int w, h;
> +
> +  struct bdf_glyph *gl = always_find_glyph(f, ch);
> +
> +  if (bg == -1)
> +    bg = current_bg;
> +  if (fg == -1)
> +    fg = current_fg;
> +
> +  for (h = 0; h < fb_hc; h++)
> +    {
> +      for (w = 0; w < fb_wc; w++)
> +        {
> +          char *pixel = mem + bpp/8 * (w + width * h);
> +          uint32_t colour = (gl->bitmap[h] & (1 << (7-w))) ? fg : bg;
> +          pixel[0] ^= (colour >> 16) & 0xff;
> +          pixel[1] ^= (colour >> 8) & 0xff;
> +          pixel[2] ^= colour & 0xff;
> +        }
> +    }
> +}
> +
> +static error_t
> +fb_init(void)
> +{
> +  error_t err;
> +  int fd;
> +
> +  fd = open ("/dev/mem", O_RDWR);
> +  if (fd < 0)
> +    return errno;
> +
> +  vga_videomem = mmap (0, fb_width * fb_height * fb_bpp/8, PROT_READ | 
> PROT_WRITE,
> +                    MAP_SHARED, fd, vga_fb);
> +  err = errno;
> +  close (fd);
> +  if (vga_videomem == MAP_FAILED)
> +    return err;
> +
> +  /* Clear screen */
> +  memset (vga_videomem, 0, fb_width * fb_height * fb_bpp/8);
> +  return 0;
> +}
> +
> +static void
> +fb_fini(void)
> +{
> +  munmap (vga_videomem, fb_width * fb_height * fb_bpp/8);
> +}
> +
> +/* Start the driver.  */
> +error_t
> +fb_display_start (void *handle)
> +{
> +  error_t err;
> +  struct fb_display *disp = handle;
> +  FILE *font_file;
> +
> +  err = fb_init ();
> +  if (err)
> +    return err;
> +
> +#define LOAD_FONT(x,y,z)                                             \
> +  do {                                                                       
> \
> +  font_file = fopen (fb_display_##x ?: DEFAULT_VGA_##y, "r");                
> \
> +  if (font_file)                                                     \
> +    {                                                                        
> \
> +      bdf_error_t bdferr = bdf_read (font_file, &z, NULL);           \
> +      if (bdferr)                                                    \
> +        {                                                            \
> +          z = NULL;                                                  \
> +       err = ENOSYS;                                                 \
> +     }                                                               \
> +      else                                                           \
> +     bdf_sort_glyphs (z);                                            \
> +      fclose (font_file);                                            \
> +    }                                                                        
> \
> +  else                                                                       
> \
> +    err = ENOSYS;                                                    \
> +  } while (0)
> +
> +  LOAD_FONT (font, FONT, disp->font);
> +  if (err)
> +    {
> +      fb_fini ();
> +      free (disp);
> +      return err;
> +    }
> +
> +  err = driver_add_display (&fb_display_ops, disp);
> +  if (err)
> +    {
> +      fb_fini ();
> +      free (disp);
> +    }
> +  return err;
> +}
> +
> +/* Destroy the display HANDLE.  */
> +error_t
> +fb_display_fini (void *handle, int force)
> +{
> +  struct fb_display *disp = handle;
> +
> +  driver_remove_display (&fb_display_ops, disp);
> +  bdf_destroy (disp->font);
> +  free (disp);
> +  fb_fini ();
> +  free (fb_display_font);
> +
> +  return 0;
> +}
> +
> +uint32_t ansi_colour[8] = {
> +  0x000000, /* black */
> +  0xaa0000, /* red */
> +  0x00aa00, /* green */
> +  0xaa5500, /* yellow */
> +  0x0000aa, /* blue */
> +  0xaa00aa, /* magenta */
> +  0x00aaaa, /* cyan */
> +  0xaaaaaa  /* white */
> +};
> +
> +uint32_t ansi_colour_bold[8] = {
> +  0x555555, /* bright black */
> +  0xff5555, /* bright red */
> +  0x55ff55, /* bright green */
> +  0xffff55, /* bright yellow */
> +  0x5555ff, /* bright blue */
> +  0xff55ff, /* bright magenta */
> +  0x55ffff, /* bright cyan */
> +  0xffffff, /* bright white */
> +};
> +
> +static void
> +hide_mousecursor (struct fb_display *disp)
> +{
> +  char *oldpos = fb_pos((int)disp->mousecursor.posx, 
> (int)disp->mousecursor.posy);
> +
> +  if (!disp->mousecursor.visible)
> +    return;
> +
> +  /* First remove the old cursor.  */
> +  blit_glyph_xor (disp->font, oldpos, 'X', 0x00ff00, -1, disp->width, 
> fb_bpp);
> +  disp->mousecursor.visible = 0;
> +}
> +
> +
> +static void
> +draw_mousecursor (struct fb_display *disp)
> +{
> +  char *newpos = fb_pos((int)disp->mousecursor.posx, 
> (int)disp->mousecursor.posy);
> +
> +  if (disp->mousecursor.visible)
> +    return;
> +
> +  /* Draw the new cursor.  */
> +  blit_glyph_xor (disp->font, newpos, 'X', 0x00ff00, -1, disp->width, 
> fb_bpp);
> +
> +  disp->mousecursor.visible = 1;
> +}
> +
> +
> +static void
> +hide_cursor(struct fb_display *disp)
> +{
> +  char *curpos;
> +
> +  if (cursor_hidden)
> +    return;
> +
> +  /* Remove old cursor */
> +  curpos = fb_pos(cursor_pos_x, cursor_pos_y);
> +  blit_glyph_xor (disp->font, curpos, CURSOR_GLYPH, 
> ansi_colour[CURSOR_COLOUR], -1, disp->width, fb_bpp);
> +  cursor_hidden = 1;
> +}
> +
> +static void
> +draw_cursor(struct fb_display *disp)
> +{
> +  char *curpos;
> +
> +  if (!cursor_hidden)
> +    return;
> +
> +  /* Add new cursor */
> +  curpos = fb_pos(cursor_pos_x, cursor_pos_y);
> +  blit_glyph_xor (disp->font, curpos, CURSOR_GLYPH, 
> ansi_colour[CURSOR_COLOUR], -1, disp->width, fb_bpp);
> +  cursor_hidden = 0;
> +}
> +
> +/* Set the cursor's state to STATE on display HANDLE.  */
> +static error_t
> +fb_display_set_cursor_status (void *handle, uint32_t state)
> +{
> +  struct fb_display *disp = handle;
> +
> +  cursor_state = state;
> +
> +  if (!state)
> +    hide_cursor (disp);
> +  else
> +    draw_cursor (disp);
> +
> +  return 0;
> +}
> +
> +
> +/* Set the cursor's position on display HANDLE to column COL and row
> +   ROW.  */
> +static error_t
> +fb_display_set_cursor_pos (void *handle, uint32_t col, uint32_t row)
> +{
> +  struct fb_display *disp = handle;
> +
> +  /* If the cursor did not move from the character position, don't
> +     bother about updating the cursor position.  */
> +  if (cursor_state && (col == cursor_pos_x) && (row == (cursor_pos_y)))
> +    return 0;
> +
> +  if (cursor_state)
> +    hide_cursor (disp);
> +
> +  cursor_pos_x = col;
> +  cursor_pos_y = row;
> +
> +  if (cursor_state)
> +    draw_cursor (disp);
> +
> +  return 0;
> +}
> +
> +/* Deallocate any scarce resources occupied by the LENGTH characters
> +   from column COL and row ROW.  */
> +static error_t
> +fb_display_clear (void *handle, size_t length, uint32_t col, uint32_t row)
> +{
> +  return 0;
> +}
> +
> +/* Scroll the display by the desired number of lines.  The area that becomes
> +   free will be filled in a subsequent write call.  */
> +static error_t
> +fb_display_scroll (void *handle, int delta)
> +{
> +  struct fb_display *disp = handle;
> +  int pixels, chars;
> +  uint32_t r;
> +
> +  if (abs(delta) > disp->height/fb_hc)
> +    return ENOTSUP;
> +
> +  pixels = abs(delta)*fb_hc * disp->width;
> +  chars = abs(delta) * disp->width/fb_wc;
> +
> +  hide_mousecursor (disp);
> +  hide_cursor (disp);
> +
> +  /* XXX: If the virtual console is bigger than the physical console it is
> +     impossible to scroll because the data to scroll is not in memory.  */
> +  if (current_height > disp->height/fb_hc)
> +    return ENOTSUP;
> +
> +  if (delta > 0)
> +    {
> +      memmove (vga_videomem, vga_videomem + fb_bpp/8 * pixels,
> +            fb_bpp/8 * disp->width * (disp->height - delta*fb_hc));
> +    }
> +  else
> +    {
> +      memmove (vga_videomem + fb_bpp/8 * pixels, vga_videomem,
> +            fb_bpp/8 * disp->width * (disp->height + delta*fb_hc));
> +    }
> +
> +  if (delta > 0)
> +    {
> +      r = disp->height/fb_hc - delta;
> +      memmove (&disp->refmatrix[0][0], &disp->refmatrix[0][0] + chars,
> +            sizeof (struct fbchr) * disp->width/fb_wc * r);
> +    }
> +  else
> +    {
> +      r = 0;
> +      memmove (&disp->refmatrix[0][0] + chars, &disp->refmatrix[0][0],
> +            sizeof (struct fbchr) * disp->width/fb_wc * (disp->height/fb_hc 
> + delta));
> +    }
> +
> +  return 0;
> +}
> +
> +
> +
> +/* Write the text STR with LENGTH characters to column COL and row
> +   ROW.  */
> +static error_t
> +fb_display_write (void *handle, conchar_t *str, size_t length,
> +                uint32_t col, uint32_t row)
> +{
> +  struct fb_display *disp = handle;
> +  char *pos;
> +  struct fbchr *refpos = &disp->refmatrix[row][col];
> +  char *mouse_cursor_pos;
> +
> +  hide_mousecursor (disp);
> +  hide_cursor (disp);
> +
> +  /* The starting column is outside the physical screen.  */
> +  if (disp->width/fb_wc < current_width && col >= disp->width/fb_wc)
> +    {
> +      size_t skip = current_width - disp->width/fb_wc;
> +      str += skip;
> +      length -= skip;
> +      col = 0;
> +      row += 1;
> +    }
> +
> +  mouse_cursor_pos = fb_pos((int)disp->mousecursor.posx, 
> (int)disp->mousecursor.posy);
> +
> +  while (length--)
> +    {
> +      int charval = str->chr;
> +      int fg, bg;
> +
> +      /* The virtual console is smaller than the physical screen.  */
> +      if (col >= current_width)
> +        {
> +          size_t skip = disp->width/fb_wc - current_width;
> +          refpos += skip;
> +          col = 0;
> +          row += 1;
> +        }
> +      /* The virtual console is bigger than the physical console.  */
> +      else if (disp->width/fb_wc < current_width && col == disp->width/fb_wc)
> +        {
> +          size_t skip = current_width - disp->width/fb_wc;
> +          str += skip;
> +          length -= skip;
> +          col = 0;
> +          row += 1;
> +        }
> +
> +      /* The screen is filled until the bottom of the screen.  */
> +      if (row >= disp->height/fb_hc)
> +        return 0;
> +
> +      pos = fb_pos(col, row);
> +
> +      /* blit glyph to screen */
> +      fg = (str->attr.intensity == CONS_ATTR_INTENSITY_BOLD)
> +         ? ansi_colour_bold[str->attr.fgcol]
> +         : ansi_colour[str->attr.fgcol];
> +      bg = ansi_colour[str->attr.bgcol];
> +      blit_glyph(disp->font, pos, charval, fg, bg, disp->width, fb_bpp);
> +
> +      if (pos == mouse_cursor_pos)
> +        disp->mousecursor.visible = 0;
> +
> +      refpos->used = 1;
> +      refpos->chr = charval;
> +      refpos->fgcol = fg;
> +      refpos->bgcol = bg;
> +      refpos++;
> +      col++;
> +
> +      /* Go to next character.  */
> +      str++;
> +    }
> +  return 0;
> +}
> +
> +static error_t
> +fb_set_dimension (void *handle, unsigned int width, unsigned int height)
> +{
> +  current_width = width;
> +  current_height = height;
> +
> +  return 0;
> +}
> +
> +
> +static error_t
> +fb_display_update (void *handle)
> +{
> +  struct fb_display *disp = handle;
> +
> +  if (disp->mousecursor.enabled)
> +    draw_mousecursor (disp);
> +
> +  if (cursor_state)
> +    draw_cursor (disp);
> +
> +  return 0;
> +}
> +
> +
> +static error_t
> +fb_set_mousecursor_pos (void *handle, float x, float y)
> +{
> +  struct fb_display *disp = handle;
> +
> +  /* If the mouse did not move from the character position, don't
> +     bother about updating the cursor position.  */
> +  if (disp->mousecursor.visible && x == (int) disp->mousecursor.posx 
> +      && y == (int) disp->mousecursor.posy)
> +    return 0;
> +
> +  if (disp->mousecursor.enabled)
> +    hide_mousecursor (disp);
> +
> +  disp->mousecursor.posx = x;
> +  disp->mousecursor.posy = y;
> +
> +  if (disp->mousecursor.enabled)
> +    draw_mousecursor (disp);
> +
> +  return 0;
> +}
> +
> +
> +static error_t
> +fb_set_mousecursor_status (void *handle, int status)
> +{
> +  struct fb_display *disp = handle;
> +
> +  disp->mousecursor.enabled = status;
> +  if (!status)
> +    hide_mousecursor (disp);
> +  else
> +    draw_mousecursor (disp);
> +
> +  return 0;
> +}
> +
> +
> +
> +struct display_ops fb_display_ops =
> +  {
> +    fb_display_set_cursor_pos,
> +    fb_display_set_cursor_status,
> +    fb_display_scroll,
> +    fb_display_clear,
> +    fb_display_write,
> +    fb_display_update,
> +    NULL,
> +    NULL,
> +    fb_set_dimension,
> +    fb_set_mousecursor_pos,
> +    fb_set_mousecursor_status
> +  };
> diff --git a/console-client/fb.h b/console-client/fb.h
> new file mode 100644
> index 00000000..3b100d50
> --- /dev/null
> +++ b/console-client/fb.h
> @@ -0,0 +1,136 @@
> +/* 
> +   Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +   This file is part of the GNU Hurd.
> +
> +   The GNU Hurd is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License as
> +   published by the Free Software Foundation; either version 2, or (at
> +   your option) any later version.
> +
> +   The GNU Hurd is distributed in the hope that it will be useful, but
> +   WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
> +
> +#ifndef _FB_H_
> +#define _FB_H_ 1
> +
> +#include <stdint.h>
> +#include "bdf.h"
> +#include "display.h"
> +#include "vga-hw.h"
> +
> +#define FB_VIDEO_MEM_MAX_W   1920
> +#define FB_VIDEO_MEM_MAX_H   1080
> +#define FB_VIDEO_MEM_MAX_BPP 32
> +
> +#define FONT_PIXELS_W                8
> +#define FONT_PIXELS_H                16
> +
> +extern struct display_ops fb_display_ops;
> +
> +extern off_t vga_fb;
> +extern int fb_type;
> +extern int fb_width;
> +extern int fb_height;
> +extern int fb_bpp;
> +extern int fb_wc;
> +extern int fb_hc;
> +
> +error_t fb_get_multiboot_params (void);
> +error_t fb_display_start (void *handle);
> +error_t fb_display_fini (void *handle, int force);
> +
> +struct multiboot_framebuffer_info {
> +    uint64_t framebuffer_addr;
> +    uint32_t framebuffer_pitch;
> +    uint32_t framebuffer_width;
> +    uint32_t framebuffer_height;
> +    uint8_t framebuffer_bpp;
> +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED      0
> +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB          1
> +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT     2
> +    uint8_t framebuffer_type;
> +    union
> +    {
> +        struct
> +        {
> +            uint32_t framebuffer_palette_addr;
> +            uint16_t framebuffer_palette_num_colors;
> +        };
> +        struct
> +        {
> +            uint8_t framebuffer_red_field_position;
> +            uint8_t framebuffer_red_mask_size;
> +            uint8_t framebuffer_green_field_position;
> +            uint8_t framebuffer_green_mask_size;
> +            uint8_t framebuffer_blue_field_position;
> +            uint8_t framebuffer_blue_mask_size;
> +        };
> +    };
> +} __attribute__((packed));
> +
> +/*
> + * Multiboot information structure as passed by the boot loader.
> + */
> +struct multiboot_raw_info {
> +    uint32_t flags;
> +    uint32_t mem_lower;
> +    uint32_t mem_upper;
> +    uint32_t unused0;
> +    uint32_t cmdline;
> +    uint32_t mods_count;
> +    uint32_t mods_addr;
> +    uint32_t shdr_num;
> +    uint32_t shdr_size;
> +    uint32_t shdr_addr;
> +    uint32_t shdr_strndx;
> +    uint32_t mmap_length;
> +    uint32_t mmap_addr;
> +    uint32_t unused1[9];
> +    struct multiboot_framebuffer_info fb_info;
> +} __attribute__((packed));
> +
> +struct fbchr
> +{
> +  unsigned int used : 1;
> +  wchar_t chr;
> +  unsigned int fgcol: 3;
> +  unsigned int bgcol: 3;
> +};
> +
> +typedef struct fb_mousecursor
> +{
> +  float posx;
> +  float posy;
> +  int visible;
> +  int enabled;
> +} fb_mousecursor_t;
> +
> +struct fb_display
> +{
> +  /* The font for this display.  */
> +  bdf_font_t font;
> +
> +  int width;
> +  int height;
> +
> +  /* The state of the mouse cursor.  */
> +  fb_mousecursor_t mousecursor;
> +
> +  /* The position of the cursor (in characters) */
> +  int cursor_pos_x;
> +  int cursor_pos_y;
> +
> +  /* Remember for each cell on the display the glyph written to it and
> +     the colours assigned.  0 means unassigned.  */
> +
> +  struct fbchr refmatrix[FB_VIDEO_MEM_MAX_H / 
> FONT_PIXELS_H][FB_VIDEO_MEM_MAX_W / FONT_PIXELS_W];
> +};
> +
> +#endif
> -- 
> 2.45.2
> 
> 
> 

-- 
Samuel
<O> Ça peut être une madeleine à sous munitions (avec des composants,
par exemple)
 -+- #runtime -+-

Reply via email to