pbsplash/include/tfblib.h
Caleb Connolly 3a71d0437b
drm working
Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
2023-11-21 02:49:38 +00:00

557 lines
17 KiB
C

/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file tfblib.h
* @brief Tfblib's main header file
*/
#pragma once
#define _TFBLIB_H_
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "pbsplash.h"
/// Convenience macro used to shorten the signatures. Undefined at the end.
#define u8 uint8_t
/// Convenience macro used to shorten the signatures. Undefined at the end.
#define u32 uint32_t
/*
* ----------------------------------------------------------------------------
*
* Initialization/setup functions and definitions
*
* ----------------------------------------------------------------------------
*/
/**
* \addtogroup flags Flags
* @{
*/
/**
* Do NOT put TTY in graphics mode.
*
* Passing this flag to tfb_acquire_fb() will
* allow to use the framebuffer and to see stdout on TTY as well. That usually
* is undesirable because the text written to TTY will overwrite the graphics.
*/
#define TFB_FL_NO_TTY_KD_GRAPHICS (1 << 0)
/**
* Do NOT write directly onto the framebuffer.
*
* Passing this flag to tfb_acquire_fb() will make it allocate a regular memory
* buffer where all the writes (while drawing) will be directed to. The changes
* will appear on-screen only after manually called tfb_flush_rect() or
* tfb_flush_rect(). This flag is useful for applications needing to clean and
* redraw the whole screen (or part of it) very often (e.g. games) in order to
* avoid the annoying flicker effect.
*/
#define TFB_FL_USE_DOUBLE_BUFFER (1 << 1)
/** @} */
/**
* Opens and maps the framebuffer device in the current address space
*
* A successful call to tfb_acquire_fb() is mandatory before calling any drawing
* functions, including the tfb_clear_* and tfb_flush_* functions.
*
* @param[in] flags One or more among: #TFB_FL_NO_TTY_KD_GRAPHICS,
* #TFB_FL_USE_DOUBLE_BUFFER.
*
* @param[in] fb_device The framebuffer device file. Can be NULL.
* Defaults to /dev/fb0.
*
* @param[in] tty_device The tty device file to use for setting tty in
* graphics mode. Can be NULL. Defaults to /dev/tty.
*
* @return #TFB_SUCCESS in case of success or one of the
* following errors:
* #TFB_ERR_OPEN_FB,
* #TFB_ERR_IOCTL_FB,
* #TFB_ERR_UNSUPPORTED_VIDEO_MODE,
* #TFB_ERR_TTY_GRAPHIC_MODE,
* #TFB_ERR_MMAP_FB,
* #TFB_ERR_OUT_OF_MEMORY.
*
* \note This function does not affect the kb mode. tfb_set_kb_raw_mode() can
* be called before or after tfb_acquire_fb().
*/
int tfb_acquire_fb(u32 flags, const char *fb_device, const char *tty_device);
int tfb_acquire_drm(uint32_t flags, const char *device);
/**
* Release the framebuffer device
*
* \note The function **must** be called before exiting, otherwise the TTY
* will remain in graphics mode and be unusable.
*
* \note This function does not affect the kb mode. If tfb_set_kb_raw_mode()
* has been used, tfb_restore_kb_mode() must be called to restore the
* kb mode to its original value.
*/
void tfb_release_fb(void);
/**
* Limit the drawing to a window having size (w, h) at the center of the screen
*
* tfb_set_center_window_size() is a wrapper of tfb_set_window() which just
* calculates the (x, y) coordinates of the window in order it to be at the
* center of the screen.
*
* @param[in] w Width of the window, in pixels
* @param[in] h Height of the window, in pixels
*
* @return #TFB_SUCCESS in case of success or #TFB_ERR_INVALID_WINDOW.
*/
int tfb_set_center_window_size(u32 w, u32 h);
/*
* ----------------------------------------------------------------------------
*
* Text-related functions and definitions
*
* ----------------------------------------------------------------------------
*/
/**
* \addtogroup flags Flags
* @{
*/
/**
* When passed to the 'w' param of tfb_set_font_by_size(), means that any font
* width is acceptable.
*/
#define TFB_FONT_ANY_WIDTH 0
/**
* When passed to the 'h' param of tfb_set_font_by_size(), means that any font
* height is acceptable.
*/
#define TFB_FONT_ANY_HEIGHT 0
/** @} */
/**
* Opaque font type
*/
typedef void *tfb_font_t;
/**
* Font info structure
*
* tfb_iterate_over_fonts() passes a pointer to a struct tfb_font_info * for
* each statically embedded font in the library to the callback function.
*/
struct tfb_font_info {
const char *name; /**< Font's file name */
u32 width; /**< Font's character width in pixels */
u32 height; /**< Font's character height in pixels */
u32 psf_version; /**< PSF version: either 1 or 2 */
tfb_font_t font_id; /**< An opaque identifier of the font */
};
/**
* Callback type accepted by tfb_iterate_over_fonts().
*/
typedef bool (*tfb_font_iter_func)(struct tfb_font_info *cb, void *user_arg);
/**
* Iterate over the fonts embedded in the library.
*
* tfb_iterate_over_fonts() calls 'cb' once for each embedded font passing to
* it a pointer a struct tfb_font_info structure and the user_arg until either
* the font list is over or the callback returned false.
*
* @param[in] cb An user callback function
* @param[in] user_arg An arbitrary user pointer that will be passed to the
* callback function.
*/
void tfb_iterate_over_fonts(tfb_font_iter_func cb, void *user_arg);
/**
* Set the font used by the functions for drawing text
*
* @param[in] font_id An opaque identifier provided by the library either
* as a member of struct tfb_font_info, or returned as
* an out parameter by tfb_dyn_load_font().
*
* @return #TFB_SUCCESS in case of success or
* #TFB_ERR_INVALID_FONT_ID otherwise.
*/
int tfb_set_current_font(tfb_font_t font_id);
/**
* Load dynamically a PSF font file
*
* @param[in] file File path
* @param[in,out] font_id Address of a tfb_font_t variable that will
* be set by the function in case of success.
*
* @return #TFB_SUCCESS in case of success or one of the
* following errors:
* #TFB_ERR_READ_FONT_FILE_FAILED,
* #TFB_ERR_OUT_OF_MEMORY.
*/
int tfb_dyn_load_font(const char *file, tfb_font_t *font_id);
/**
* Unload a dynamically-loaded font
*
* @param[in] font_id Opaque pointer returned by tfb_dyn_load_font()
*
* @return #TFB_SUCCESS in case of success or
* #TFB_ERR_NOT_A_DYN_LOADED_FONT if the caller passed
* to it the font_id of an embedded font.
*/
int tfb_dyn_unload_font(tfb_font_t font_id);
/**
* Select the first font matching the given (w, h) criteria
*
* The tfb_set_font_by_size() function iterates over the fonts embedded in the
* library and sets the first font having width = w and height = h.
*
* @param[in] w Desired width of the font.
* The caller may pass #TFB_FONT_ANY_WIDTH to tell the
* function that any font width is acceptable.
*
* @param[in] h Desired height of the font.
* The caller may pass #TFB_FONT_ANY_HEIGHT to tell the
* function that any font width is acceptable.
*
* @return #TFB_SUCCESS in case a font matching the given criteria has
* been found or #TFB_ERR_FONT_NOT_FOUND otherwise.
*/
int tfb_set_font_by_size(int w, int h);
/**
* Get current font's width
*
* @return the width (in pixels) of the current font or 0 in case there
* is no currently selected font.
*/
int tfb_get_curr_font_width(void);
/**
* Get current font's height
*
* @return the height (in pixels) of the current font or 0 in case there
* is no currently selected font.
*/
int tfb_get_curr_font_height(void);
/*
* ----------------------------------------------------------------------------
*
* Drawing functions
*
* ----------------------------------------------------------------------------
*/
/**
* Value for 1 degree (of 360) of hue, when passed to tfb_make_color_hsv()
*/
#define TFB_HUE_DEGREE 256
/**
* Get a representation of the RGB color (r, g, b) for the current video mode
*
* @param[in] r Red color component [0, 255]
* @param[in] g Green color component [0, 255]
* @param[in] b Blue color component [0, 255]
*
* @return A framebuffer-specific representation of the RGB color
* passed using the r, g, b parameters.
*/
inline u32 tfb_make_color(u8 r, u8 g, u8 b);
/**
* Get a representation of the HSV color (h, s, v) for the current video mode
*
* @param[in] h Hue [0, 360 * #TFB_HUE_DEGREE]
* @param[in] s Saturation [0, 255]
* @param[in] v Value (Brightness) [0, 255]
*
* @return A framebuffer-specific representation of the HSV color
* passed using the h, s, v parameters.
*
* \note 1 degree of hue is #TFB_HUE_DEGREE, not simply 1. This is necessary
* in order to increase the precision of the internal integer-only
* computations.
*/
u32 tfb_make_color_hsv(u32 h, u8 s, u8 v);
/**
* Set the color of the pixel at (x, y) to 'color'
*
* @param[in] x Window-relative X coordinate of the pixel
* @param[in] y Window-relative Y coordinate of the pixel
* @param[in] color A color returned by tfb_make_color()
*
* \note By default, the library uses as "window" the whole screen, therefore
* by default the point (x, y) corresponds to the pixel at (x, y) on the
* screen. But, after calling tfb_set_window() the origin of the
* coordinate system gets shifted.
*/
inline void tfb_draw_pixel(int x, int y, u32 color);
/**
* Draw a horizonal line on-screen
*
* @param[in] x Window-relative X coordinate of line's first point
* @param[in] y Window-relative Y coordinate of line's first point
* @param[in] len Length of the line, in pixels
* @param[in] color Color of the line. See tfb_make_color().
*
* Calling tfb_draw_hline(x, y, len, color) is equivalent to calling:
* tfb_draw_line(x, y, x + len, y, color)
*
* The only difference between the two functions is in the implementation: given
* the simpler task of tfb_draw_hline(), it can be implemented in much more
* efficient way.
*/
void tfb_draw_hline(int x, int y, int len, u32 color);
/**
* Draw a vertical line on-screen
*
* @param[in] x Window-relative X coordinate of line's first point
* @param[in] y Window-relative Y coordinate of line's first point
* @param[in] len Length of the line, in pixels
* @param[in] color Color of the line. See tfb_make_color().
*
* Calling tfb_draw_vline(x, y, len, color) is equivalent to calling:
* tfb_draw_line(x, y, x, y + len, color)
*
* The only difference between the two functions is in the implementation: given
* the simpler task of tfb_draw_vline(), it can be implemented in much more
* efficient way.
*/
void tfb_draw_vline(int x, int y, int len, u32 color);
/**
* Draw a line on-screen
*
* @param[in] x0 Window-relative X coordinate of line's first point
* @param[in] y0 Window-relative Y coordinate of line's first point
* @param[in] x1 Window-relative X coordinate of line's second point
* @param[in] y1 Window-relative Y coordinate of line's second point
* @param[in] color Color of the line. See tfb_make_color().
*/
void tfb_draw_line(int x0, int y0, int x1, int y1, u32 color);
/**
* Draw an empty rectangle on-screen
*
* @param[in] x Window-relative X coordinate of rect's top-left corner
* @param[in] y Window-relative Y coordinate of rect's top-left corner
* @param[in] w Width of the rectangle
* @param[in] h Height of the rectangle
* @param[in] color Color of the rectangle
*/
void tfb_draw_rect(int x, int y, int w, int h, u32 color);
/**
* Draw filled rectangle on-screen
*
* @param[in] x Window-relative X coordinate of rect's top-left corner
* @param[in] y Window-relative Y coordinate of rect's top-left corner
* @param[in] w Width of the rectangle
* @param[in] h Height of the rectangle
* @param[in] color Color of the rectangle
*/
void tfb_fill_rect(int x, int y, int w, int h, u32 color);
/**
* Draw an empty circle on-screen
*
* @param[in] cx X coordinate of circle's center
* @param[in] cy Y coordinate of circle's center
* @param[in] r Circle's radius
* @param[in] color Circle's color
*/
void tfb_draw_circle(int cx, int cy, int r, u32 color);
/**
* Draw a filled circle on-screen
*
* @param[in] cx X coordinate of circle's center
* @param[in] cy Y coordinate of circle's center
* @param[in] r Circle's radius
* @param[in] color Circle's color
*/
void tfb_fill_circle(int cx, int cy, int r, u32 color);
/**
* Blit a 32-bit RGBA buffer to the screen at the specified coordinates.
*
* @param[in] buf The buffer
* @param[in] x Window-relative X coordinate of the top-left corner of
* the buffer
* @param[in] y Window-relative Y coordinate of the top-left corner of
* the buffer
* @param[in] w Width of the buffer
* @param[in] h Height of the buffer
* @param[in] bg Background color. Pixels with this color are not
* blitted to the screen.
* @param[in] vflip If true, the buffer is flipped vertically
*/
void blit_buf(unsigned char *buf, int x, int y, int w, int h, struct col bg, bool vflip);
/**
* Set all the pixels of the screen to the supplied color
*
* @param[in] color The color. See tfb_make_color().
*/
void tfb_clear_screen(u32 color);
/**
* Set all the pixels of the current window to the supplied color
*
* @param[in] color The color. See tfb_make_color().
*
* \note Unless tfb_set_window() has been called, the current window is by
* default large as the whole screen.
*/
void tfb_clear_win(u32 color);
/**
* Get screen's physical width in mm
*
* @return the width of the screen in mm
*/
u32 tfb_screen_width_mm(void);
/**
* Get screen's physical height in mm
*
* @return the height of the screen in mm
*/
u32 tfb_screen_height_mm(void);
/**
* Get the screen's rotation as a multiple of 90 degrees
* 1: 90 degrees
* 2: 180 degrees
* 3: 270 degrees
*/
int tfb_get_rotation(void);
/**
* Flush a given region to the actual framebuffer
*
* @param[in] x Window-relative X coordinate of region's position
* @param[in] y Window-relative Y coordinate of region's position
* @param[in] w Width of the region (in pixels)
* @param[in] h Height of the region (in pixels)
*
* In case tfb_acquire_fb() has been called with #TFB_FL_USE_DOUBLE_BUFFER,
* this function copies the pixels in the specified region to actual
* framebuffer. By default double buffering is not used and this function has no
* effect.
*/
void tfb_flush_rect(int x, int y, int w, int h);
/**
* Flush the current window to the actual framebuffer
*
* A shortcut for tfb_flush_rect(0, 0, tfb_win_width(), tfb_win_height()).
*
* @see tfb_flush_rect
* @see tfb_set_window
*/
void tfb_flush_window(void);
/**
* Flush the framebuffer, causing it to update. This is different
* to tfb_flush_window() as it doesn't deal with double_buffering,
* rather it handles the case where the framebuffer has to be "ACTIVATED".
*
* @return #TFB_SUCCESS on success or #TFB_ERR_FB_FLUSH_IOCTL_FAILED
* on failure.
*
* @see tfb_flush_window
*/
int tfb_flush_fb(void);
/* Essential variables */
extern void *__fb_buffer;
extern void *__fb_real_buffer;
extern int __fb_screen_w;
extern int __fb_screen_h;
extern size_t __fb_size;
extern size_t __fb_pitch;
extern size_t __fb_pitch_div4; /* see the comment in drawing.c */
/* Window-related variables */
extern int __fb_win_w;
extern int __fb_win_h;
extern int __fb_off_x;
extern int __fb_off_y;
extern int __fb_win_end_x;
extern int __fb_win_end_y;
/* Color-related variables */
extern u32 __fb_r_mask;
extern u32 __fb_g_mask;
extern u32 __fb_b_mask;
extern u8 __fb_r_mask_size;
extern u8 __fb_g_mask_size;
extern u8 __fb_b_mask_size;
extern u8 __fb_r_pos;
extern u8 __fb_g_pos;
extern u8 __fb_b_pos;
extern uint32_t tfb_red;
extern uint32_t tfb_green;
extern uint32_t tfb_blue;
extern uint32_t tfb_white;
extern uint32_t tfb_gray;
extern uint32_t tfb_black;
inline u32 tfb_make_color(u8 r, u8 g, u8 b)
{
return ((r << __fb_r_pos) & __fb_r_mask) | ((g << __fb_g_pos) & __fb_g_mask) |
((b << __fb_b_pos) & __fb_b_mask);
}
inline void tfb_draw_pixel(int x, int y, u32 color)
{
x += __fb_off_x;
y += __fb_off_y;
if ((u32)x < (u32)__fb_win_end_x && (u32)y < (u32)__fb_win_end_y)
((volatile u32 *)__fb_buffer)[x + y * __fb_pitch_div4] = color;
}
inline u32 tfb_screen_width(void)
{
return __fb_screen_w;
}
inline u32 tfb_screen_height(void)
{
return __fb_screen_h;
}
inline u32 tfb_win_width(void)
{
return __fb_win_w;
}
inline u32 tfb_win_height(void)
{
return __fb_win_h;
}
/* undef the the convenience types defined above */
#undef u8
#undef u32