⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libfbx-init.c

📁 libfxb是linux下只写操作framebuffer的一个轻量级的库。
💻 C
字号:
/* *  libfbx-init.c -- Main initilization file *  (C)opyright 2000-2001 U4X Labs * *  Written by: Paul Mundt     <lethal@stampede.org> *              Mike Bourgeous <nitrogen@u4x.org> *              Mon Jul 24 04:55:24 EDT 2000 * *  $Id: libfbx-init.c,v 1.35 2001/03/03 02:29:19 nitroglycerine Exp $ * *	Implementation of a number of basic drawing functions for *  the framebuffer system, to be used as a linked library in *  other programs using the libfbx API. Forked from the fbdev-init *  code to be a standalone library. * *  See ChangeLog for modifications, CREDITS for credits. * *  All source herein is copyright U4X Labs and its original author.  *  Any code modifications or additions are (C)opyright the original  *  author and U4X Labs respectively. * *  libfbx is free software; you can redistribute it and/or modify it  *  under the terms of the GNU Lesser General Public License as  *  published by the Free Software Foundation; either version 2.1 of  *  the License, or (at your option) any later version. * *  libfbx 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 Lesser General Public License for more details. * *  You should have received a copy of the GNU Lesser General Public *  License along with libfbx; if not, write to the Free Software  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *  USA */#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <signal.h>#include <time.h>#include <math.h>#include <linux/fb.h>#include <linux/kd.h>#include <linux/vt.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <sys/user.h>#include <termios.h>#include <ctype.h>#include <libfbx/libfbx.h>#include <libfbx/libfbx-drivers.h>#include <asm/page.h>fb_surface *fb_screen = NULL;char *fbptr, *fb_device = NULL;int fbfd, fbptr_off;struct fb_var_screeninfo old_vinfo;int kd_mode;struct vt_mode old_vtmode, vtmode;struct termios term;unsigned short old_red[256], old_green[256], old_blue[256];struct fb_cmap old_map = {0, 256, old_red, old_green, old_blue, NULL};unsigned short red[256], green[256], blue[256];struct fb_cmap map_332 = {0, 256, red, green, blue, NULL};int tty;/* * Function:	rand01() * Arguments:	None * Returns:	A random number * Description:	Returns a random number between 0 and 1 */float rand01(){       return ((float)(rand() % RAND_MAX) / (float)RAND_MAX);}/* * Function:    fb_setdev() * Arguments:   Device to set to * Returns:     0 on success, -1 on failure * Description: Takes the specified device and sets it as the *              global fb device to use. (Does not support *              multihead, just allows you to specify an *              alternate device). */int fb_setdev(char *setdev){	if (!setdev || setdev == NULL) 		return -1;	if (access(setdev, F_OK) < 0)		return -1;	fb_device = setdev;	return 0;}/* * Function:    fb_finddev() * Arguments:	None * Returns:     Full path to framebuffer device * Description: Looks for the location of the framebuffer device * 		in the FRAMEBUFFER environment variable, and the * 		relative path in /dev (DFLT_FB). */char *fb_finddev(){	char *dev;	if (fb_device != NULL)		return fb_device;	if ((dev = getenv("FRAMEBUFFER")) == NULL) {		if (access(DFLT_FB,F_OK) == 0) {			dev = DFLT_FB;			setenv("FRAMEBUFFER", DFLT_FB, 1);		} else if (access(DFLT_DEVFS_FB, F_OK) == 0) {			dev = DFLT_DEVFS_FB;			setenv("FRAMEBUFFER", DFLT_DEVFS_FB, 1);		}	}	return dev;}/* * Function:	fb_init() * Arguments:	None * Returns:	An fb_surface structure representing the screen. * Description:	Locates and initializes the fb device. */int fb_init(){	fb_module *fb_module = fb_modules;	char *dev, errstr[LEN];		if (fb_screen == NULL) {		fb_screen         = malloc(sizeof(fb_surface));		fb_screen->vinfo  = calloc(1, sizeof(struct fb_var_screeninfo));		fb_screen->finfo  = calloc(1, sizeof(struct fb_fix_screeninfo));		fb_screen->driver = calloc(1, sizeof(struct fb_driver));		fb_screen->driver->ops = calloc(1, sizeof(struct fb_driver_ops));	} else {		/* Screen is already initialized */		return 1;	}	srand(time(0));	fb_make_332_map(&map_332);	if ((dev = fb_finddev()) == NULL) {		fprintf(stderr,"Cannot open %s, make sure it exists.\n",			DFLT_FB);		exit(1);	}	fb_font_init();	if ((fbfd = open(dev, O_RDWR)) < 0) {		snprintf(errstr, LEN, "Error opening %s", dev);		perror(errstr);		exit(1);	}	if (ioctl(fbfd, FBIOGET_FSCREENINFO, fb_screen->finfo) < 0) {		perror("Error reading fixed information");		exit(1);	}	if (ioctl(fbfd, FBIOGET_VSCREENINFO, fb_screen->vinfo) < 0) {		perror("Error reading variable information");		exit(1);	}		if (ioctl(fbfd, FBIOGET_VSCREENINFO, &old_vinfo) < 0) {		perror("Error reading variable information");		exit(1);	}		if (ioctl(fbfd, FBIOGETCMAP, &old_map) < 0) {		perror("Error getting colormap");		exit(1);	}	if (fb_screen->finfo->visual == FB_VISUAL_DIRECTCOLOR ||             fb_screen->vinfo->bits_per_pixel == 8)		if (ioctl(fbfd, FBIOPUTCMAP, &map_332) < 0) {			perror("Error putting colormap");			exit(1);		}	if (ioctl(tty, KDGETMODE, &kd_mode) < 0) {		perror("ioctl KDGETMODE");		exit(1);	}		if (ioctl(tty, VT_GETMODE, &old_vtmode) < 0) {		perror("ioctl VT_GETMODE");		exit(1);	}	tcgetattr(tty, &term);			fbptr = (char *)mmap(0, fb_screen->finfo->smem_len,                                 PROT_READ | PROT_WRITE,                                 MAP_SHARED, fbfd, 0);	fbptr_off = (unsigned long)fb_screen->finfo->smem_start & ~PAGE_MASK;	fb_screen->width  = fb_screen->vinfo->xres;	fb_screen->height = fb_screen->vinfo->yres;	strcpy(fb_screen->driver->id, fb_screen->finfo->id);	fb_screen->driver->handle = NULL;	while (fb_module->id != NULL) {		if (strcmp(fb_screen->driver->id, fb_module->id) == 0)			fb_load_module(fb_module->name);			fb_module++;	}	switch (fb_screen->vinfo->bits_per_pixel) {		case 8:			fb_screen->pixel_size = 1;			fb_screen->make_color = fb_make_color_8;			break;		case 15:			fb_screen->pixel_size          = 2;			fb_screen->make_color          = fb_make_color_15;			fb_screen->vinfo->red.offset   = 10;			fb_screen->vinfo->red.length   = 5;			fb_screen->vinfo->green.offset = 5;			fb_screen->vinfo->green.length = 5;			fb_screen->vinfo->blue.offset  = 0;			fb_screen->vinfo->blue.length  = 5;			break;		case 16:			fb_screen->pixel_size          = 2;			fb_screen->make_color          = fb_make_color_16;			fb_screen->vinfo->red.offset   = 11;			fb_screen->vinfo->red.length   = 5;			fb_screen->vinfo->green.offset = 5;			fb_screen->vinfo->green.length = 6;			fb_screen->vinfo->blue.offset  = 0;			fb_screen->vinfo->blue.length  = 5;			break;		case 24:			fb_screen->pixel_size          = 3;			fb_screen->make_color          = fb_make_color_24;			fb_screen->vinfo->red.offset   = 16;			fb_screen->vinfo->red.length   = 8;			fb_screen->vinfo->green.offset = 8;			fb_screen->vinfo->green.length = 8;			fb_screen->vinfo->blue.offset  = 0;			fb_screen->vinfo->blue.length  = 8;			break;		case 32:			fb_screen->pixel_size          = 4;			fb_screen->make_color          = fb_make_color_24;			fb_screen->vinfo->red.offset   = 16;			fb_screen->vinfo->red.length   = 8;			fb_screen->vinfo->green.offset = 8;			fb_screen->vinfo->green.length = 8;			fb_screen->vinfo->blue.offset  = 0;			fb_screen->vinfo->blue.length  = 8;			break;		default:			fprintf(stderr, "Unknown color depth %d.\n"					"Attempting to generate color.\n", 					fb_screen->vinfo->bits_per_pixel);			fb_screen->pixel_size = 1;			fb_screen->make_color = fb_make_color_unknown;			break;	}		if (ioctl(fbfd, FBIOPUT_VSCREENINFO, fb_screen->vinfo) < 0) {		perror("Couldn't set ideal mode at FBIOPUT_VSCREENINFO");		exit(1);	}		if (ioctl(fbfd, FBIOGET_VSCREENINFO, fb_screen->vinfo) < 0) {		perror("ioctl FBIOGET_VSCREENINFO");		fb_cleanup();		exit(1);	}	fb_screen->bpp         = fb_screen->vinfo->bits_per_pixel;	fb_screen->line_size   = fb_screen->finfo->line_length;	fb_screen->buffer_size = fb_screen->finfo->smem_len;	fb_screen->mem_offset  = fbptr_off;	fb_screen->mem_pointer = fbptr;		fb_screen->red_size     = fb_screen->vinfo->red.length;	fb_screen->red_offset   = fb_screen->vinfo->red.offset;	fb_screen->green_size   = fb_screen->vinfo->green.length;	fb_screen->green_offset = fb_screen->vinfo->green.offset;	fb_screen->blue_size    = fb_screen->vinfo->blue.length;	fb_screen->blue_offset  = fb_screen->vinfo->blue.offset;		/* atexit(fb_cleanup); */	if (ioctl(tty, KDSETMODE, KD_GRAPHICS)) {		perror("ioctl KDSETMODE");		exit(1);	}		if (fb_screen->finfo->visual == FB_VISUAL_DIRECTCOLOR || 	    fb_screen->vinfo->bits_per_pixel == 8)		if (ioctl(fbfd, FBIOPUTCMAP, &map_332) < 0) {			perror("ioctl FBIOPUTCMAP");			exit(1);		}	fb_screen->text.tab_size = 8;	fb_screen->font.width    = 8;	fb_set_textcolor(fb_screen->make_color(0xff, 0xff, 0xff), 0x00);	fb_handle_signals();	fb_screen->switch_state = FB_CONSOLE_ACTIVE;	fb_switch_init();	if (fb_screen->driver->handle != NULL)		fb_screen->driver->init();	fb_driver_ops_init();	return 0;}void (*old_handlers[2])(int sig);/* * Function:    fb_cleanup() * Arguments:	None * Returns:     None * Description: unmaps memory and closes the *              file descriptor. */void fb_cleanup(){	if (fb_screen != NULL) {		if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &old_vinfo) < 0)			perror("ioctl FBIOPUT_VSCREENINFO");		if (ioctl(fbfd, FBIOGET_FSCREENINFO, fb_screen->finfo) < 0)			perror("ioctl FBIOGET_FSCREENINFO");				if (ioctl(fbfd, FBIOPUTCMAP, &old_map) < 0)			perror("ioctl FBIOPUTCMAP");				if (fb_screen->driver->handle != NULL) {			fb_screen->driver->exit();			fb_unload_module();		}		munmap(fb_screen->mem_pointer, 		       fb_screen->buffer_size);		fbptr = NULL;		fbptr_off = (int)NULL; /* shut up gcc */		close(fbfd);		cfree(fb_screen->finfo);		cfree(fb_screen->vinfo);		cfree(fb_screen->driver->ops);		cfree(fb_screen->driver);		free(fb_screen);		if (ioctl(tty, KDSETMODE, kd_mode) < 0)			perror("ioctl KDSETMODE");		if (ioctl(tty, VT_SETMODE, &old_vtmode) < 0)			perror("ioctl VT_SETMODE");		tcsetattr(tty, TCSANOW, &term);	}}/* * Function:    quit() * Arguments:   signal number * Returns:     None * Description: Function for use with signal() to *              exit cleanly out of fb land. */void quit(int signum){	fb_cleanup();        fprintf(stderr,"Recieved fatal signal %d, exiting...\n", signum);        exit(1);}/* * Function:    fb_handle_signals() * Arguments:   None * Returns:     None * Description: Handles any signals we recieve. */void fb_handle_signals(){        int i, signals[] = { SIGINT, SIGSEGV };        for (i = 0; i < (sizeof(signals) / sizeof(int)); i++)                if ((old_handlers[i] = signal(signals[i], quit)) == SIG_ERR) {                        fprintf(stderr,"Unable to set handler "                                       "for signal %d.\n",                                       signals[i]);                        exit(1);                }}/* * Function:    fb_driver_ops_init() * Arguments:   None * Returns:     None * Description: Determines which accelerated functions exist *              in the driver. */void fb_driver_ops_init(){	if (fb_screen->driver->ops->blank != NULL)		fb_screen->driver->ops->has_blank = 1;	if (fb_screen->driver->ops->line != NULL)		fb_screen->driver->ops->has_line = 1;	if (fb_screen->driver->ops->fill_rect != NULL)		fb_screen->driver->ops->has_fill_rect = 1;	if (fb_screen->driver->ops->writec != NULL)		fb_screen->driver->ops->has_writec = 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -