linux_fbcon.c

来自「mini gui 1.6.8 lib and source」· C语言 代码 · 共 785 行 · 第 1/2 页

C
785
字号
/***  $Id: linux_fbcon.c,v 1.7 2005/07/06 12:47:31 wanglin Exp $**  **  linux_fbcon.c: A subdriver of shadow NEWGAL engine for Linux **      FrameBuffer console.****  Copyright (C) 2003 ~ 2005 Feynman Software.****  This subdriver can support packed-pixel 1bpp/4bpp/8bpp modes**  and can do the coordinate transformation.****  TODO:**      * add support for FB_TYPE_VGA_PLANES.**      * add support for PE_MSBRIGHT;*//*** This program 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 of the License, or** (at your option) any later version.**** This program 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-1307  USA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#ifdef _NEWGAL_ENGINE_SHADOW #if defined (__LINUX__) && defined (__TARGET_FBCON__)#include <unistd.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#include <fcntl.h>#include <limits.h>#include <linux/fb.h>#include <linux/kd.h>#include <linux/vt.h>#undef ROP_XOR#include "minigui.h"#include "newgal.h"#include "shadow.h"#define PF_PALETTE  1#define PF_DIRECT   2#define PE_MSBLEFT  1#define PE_MSBRIGHT 2static struct _fbcon_info{    int fd_fb;#ifdef _HAVE_TEXT_MODE    int fd_tty;#endif    gal_uint8 type;    gal_uint8 pixel_endiness;    gal_uint8 pixel_format;    gal_uint8 depth;    gal_uint8 bpp; /* bytes per pixel */    gal_uint8 planes;    gal_uint16 xres;    gal_uint16 yres;    gal_uint32 pitch;    gal_uint32 fb_size;    gal_uint8* fb;    gal_uint8* a_line;    void (*put_one_line) (const BYTE* src_line, BYTE* dst_line,                     int x, int width);} fbcon_info = {-1, -1};static unsigned char pixel_bit [] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};static void put_one_line_1bpp (const BYTE* src_bits, BYTE* dst_line,                int left, int width){    int x, i;    dst_line += left >> 3;    for (x = 0; x < width; x += 8) {        *dst_line = 0;        for (i = 0; i < 8; i++) {            if (*src_bits < 128)                *dst_line |= pixel_bit [i];            src_bits ++;        }        dst_line ++;    }}static void put_one_line_2bpp (const BYTE* src_bits, BYTE* dst_line,                int left, int width){    int x;    dst_line += left >> 2;    for (x = 0; x < width; x += 4) {        *dst_line = (*src_bits >> 6); src_bits ++;        *dst_line |= ((*src_bits >> 4) & 0x0C); src_bits ++;        *dst_line |= ((*src_bits >> 2) & 0x30); src_bits ++;        *dst_line |= ((*src_bits) & 0xC0); src_bits ++;        dst_line ++;    }}static void put_one_line_4bpp (const BYTE* src_bits, BYTE* dst_line,                int left, int width){    int x;    dst_line += left >> 1;    for (x = 0; x < width; x+=2) {        *dst_line = (src_bits [0] >> 4) | (src_bits [1] & 0xF0);        src_bits += 2;        dst_line ++;    }}static void put_one_line_8bpp (const BYTE* src_bits, BYTE* dst_line,                int left, int width){    dst_line += left * fbcon_info.bpp;    memcpy (dst_line, src_bits, width * fbcon_info.bpp);}#ifdef _COOR_TRANS#   if _ROT_DIR_CW == 1static void _get_dst_rect (RECT* dst_rect, const RECT* src_rect){    dst_rect->left = fbcon_info.xres - src_rect->bottom;    dst_rect->top = src_rect->left;    dst_rect->right = fbcon_info.xres - src_rect->top;    dst_rect->bottom = src_rect->right;}static void a_refresh_cw (_THIS, const RECT* update){    RECT src_update = *update;    RECT dst_update;    const BYTE* src_bits;    BYTE* dst_line;    int dst_width, dst_height;    int x, y;    _get_dst_rect (&dst_update, &src_update);    /* Round the update rectangle.  */    if (fbcon_info.depth == 1) {        /* round x to be 8-aligned */        dst_update.left = dst_update.left & ~0x07;        dst_update.right = (dst_update.right + 7) & ~0x07;    }    else if (fbcon_info.depth == 2) {        /* round x to be 4-aligned */        dst_update.left = dst_update.left & ~0x03;        dst_update.right = (dst_update.right + 3) & ~0x03;    }    else if (fbcon_info.depth == 4) {        /* round x to be 2-aligned */        dst_update.left = dst_update.left & ~0x01;        dst_update.right = (dst_update.right + 1) & ~0x01;    }    dst_width = RECTW (dst_update);    dst_height = RECTH (dst_update);    if (dst_width <= 0 || dst_height <= 0)        return;    /* Copy the bits from Shadow FrameBuffer to console FrameBuffer */    src_bits = this->hidden->fb;    src_bits += (src_update.bottom - 1) * this->hidden->pitch                 + src_update.left * fbcon_info.bpp;    dst_line = fbcon_info.fb + dst_update.top * fbcon_info.pitch;    for (x = 0; x < dst_height; x++) {        /* Copy the bits from vertical line to horizontal line */        const BYTE* ver_bits = src_bits;        BYTE* hor_bits = fbcon_info.a_line;        switch (fbcon_info.depth) {            case 32:                for (y = 0; y < dst_width; y++) {                    *(gal_uint32*) hor_bits = *(gal_uint32*) ver_bits;                    ver_bits -= this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;           case 24:                for (y = 0; y < dst_width; y++) {                    hor_bits [0] = ver_bits [0];                    hor_bits [1] = ver_bits [1];                    hor_bits [2] = ver_bits [2];                    ver_bits -= this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;           case 15:           case 16:                for (y = 0; y < dst_width; y++) {                    *(gal_uint16*) hor_bits = *(gal_uint16*) ver_bits;                    ver_bits -= this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;           default:                for (y = 0; y < dst_width; y++) {                    *hor_bits = *ver_bits;                    ver_bits -= this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;        }        fbcon_info.put_one_line (fbcon_info.a_line, dst_line,                         dst_update.left, dst_width);        src_bits += fbcon_info.bpp;        dst_line += fbcon_info.pitch;    }}#   else /* _ROT_DIR_CW == 1 */static void _get_dst_rect (RECT* dst_rect, const RECT* src_rect){    dst_rect->left = src_rect->top;    dst_rect->bottom = fbcon_info.yres - src_rect->left;    dst_rect->right = src_rect->bottom;    dst_rect->top = fbcon_info.yres - src_rect->right;}static void a_refresh_ccw (_THIS, const RECT* update){    RECT src_update = *update;    RECT dst_update;    const BYTE* src_bits;    BYTE* dst_line;    int dst_width, dst_height;    int x, y;    _get_dst_rect (&dst_update, &src_update);    /* Round the update rectangle.  */    if (fbcon_info.depth == 1) {        /* round x to be 8-aligned */        dst_update.left = dst_update.left & ~0x07;        dst_update.right = (dst_update.right + 7) & ~0x07;    }    else if (fbcon_info.depth == 2) {        /* round x to be 4-aligned */        dst_update.left = dst_update.left & ~0x03;        dst_update.right = (dst_update.right + 3) & ~0x03;    }    else if (fbcon_info.depth == 4) {        /* round x to be 2-aligned */        dst_update.left = dst_update.left & ~0x01;        dst_update.right = (dst_update.right + 1) & ~0x01;    }    dst_width = RECTW (dst_update);    dst_height = RECTH (dst_update);    if (dst_width <= 0 || dst_height <= 0)        return;    /* Copy the bits from Shadow FrameBuffer to console FrameBuffer */    src_bits = this->hidden->fb;    src_bits += src_update.top * this->hidden->pitch                 + src_update.left * fbcon_info.bpp;    dst_line = fbcon_info.fb + (dst_update.bottom - 1) * fbcon_info.pitch;    for (x = 0; x < dst_height; x++) {        /* Copy the bits from vertical line to horizontal line */        const BYTE* ver_bits = src_bits;        BYTE* hor_bits = fbcon_info.a_line;        switch (fbcon_info.depth) {            case 32:                for (y = 0; y < dst_width; y++) {                    *(gal_uint32*) hor_bits = *(gal_uint32*) ver_bits;                    ver_bits += this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;           case 24:                for (y = 0; y < dst_width; y++) {                    hor_bits [0] = ver_bits [0];                    hor_bits [1] = ver_bits [1];                    hor_bits [2] = ver_bits [2];                    ver_bits += this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;           case 15:           case 16:                for (y = 0; y < dst_width; y++) {                    *(gal_uint16*) hor_bits = *(gal_uint16*) ver_bits;                    ver_bits += this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;           default:                for (y = 0; y < dst_width; y++) {                    *hor_bits = *ver_bits;                    ver_bits += this->hidden->pitch;                    hor_bits += fbcon_info.bpp;                }                break;        }        fbcon_info.put_one_line (fbcon_info.a_line, dst_line,                         dst_update.left, dst_width);        src_bits += fbcon_info.bpp;        dst_line -= fbcon_info.pitch;    }}#   endif /* _ROT_DIR_CW == 0 */#else /* _COOR_TRANS */static void a_refresh_normal (_THIS, const RECT* update){    RECT src_update = *update;    const BYTE* src_bits;    BYTE* dst_line;    int width, height;    int y;    if (fbcon_info.depth >= 8) {        return;    }    /* Round the update rectangle.  */    if (fbcon_info.depth == 1) {        /* round x to be 8-aligned */        src_update.left = src_update.left & ~0x07;        src_update.right = (src_update.right + 7) & ~0x07;    }    else if (fbcon_info.depth == 2) {        /* round x to be 4-aligned */        src_update.left = src_update.left & ~0x03;        src_update.right = (src_update.right + 3) & ~0x03;    }    else if (fbcon_info.depth == 4) {        /* round x to be 2-aligned */        src_update.left = src_update.left & ~0x01;        src_update.right = (src_update.right + 1) & ~0x01;    }    width = RECTW (src_update);    height = RECTH (src_update);    if (width <= 0 || height <= 0)        return;    /* Copy the bits from Shadow FrameBuffer to console FrameBuffer */

⌨️ 快捷键说明

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