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

📄 vga16.c

📁 libminigui-1.3.0.tar.gz。 miniGUI的库函数源代码!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** $Id: vga16.c,v 1.21 2003/11/21 12:44:01 weiym Exp $**** vga16.c: VGA 16-color GAL engine built on SVGALib**** Copyright (C) 2003 Feynman Software.** Copyright (C) 2001, 2002 Wei Yongming.**** Create by Wei Yongming, 2001/09/21*//*** 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 <signal.h>#include <unistd.h>#include <fcntl.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "gal.h"#ifdef _VGA16_GAL#include <sys/io.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <vga.h>#include "vga16.h"#ifdef _LITE_VERSION#include "ourhdr.h"#include "client.h"#include "sharedres.h"static int __mg_saved_clip_minx, __mg_saved_clip_miny, __mg_saved_clip_maxx, __mg_saved_clip_maxy;static int set_effective_clip_rect (GC_VGA16* gc){    if (__mg_saved_clip_minx < SHAREDRES_CLI_SCR_LX)        gc->clipminx = SHAREDRES_CLI_SCR_LX;    else        gc->clipminx = __mg_saved_clip_minx;    if (__mg_saved_clip_miny < SHAREDRES_CLI_SCR_TY)        gc->clipminy = SHAREDRES_CLI_SCR_TY;    else        gc->clipminy = __mg_saved_clip_miny;        if (__mg_saved_clip_maxx > (SHAREDRES_CLI_SCR_RX + 1))        gc->clipmaxx = SHAREDRES_CLI_SCR_RX;    else        gc->clipmaxx = __mg_saved_clip_maxx;    if (__mg_saved_clip_maxy > (SHAREDRES_CLI_SCR_BY + 1))        gc->clipmaxy = SHAREDRES_CLI_SCR_BY;    else        gc->clipmaxy = __mg_saved_clip_maxy;    if (gc->clipmaxx < gc->clipminx)        return -1;    else if (gc->clipmaxy < gc->clipminy)        return -1;    gc->clipmaxx ++;    gc->clipmaxy ++;    return 0;}#define BLOCK_DRAW_SEM                                          \    if (!mgIsServer && cur_gfx->phygc.gc_vga16 == gc.gc_vga16)  \        lock_draw_sem ();                                       \    if (((!mgIsServer && (SHAREDRES_TOPMOST_LAYER != __mg_layer)) || __mg_switch_away)) \        goto leave_drawing;                                     \    if (!mgIsServer && cur_gfx->phygc.gc_vga16 == gc.gc_vga16)  \        if (set_effective_clip_rect (gc.gc_vga16))              \            goto leave_drawing;#define UNBLOCK_DRAW_SEM                                        \    if (!mgIsServer && cur_gfx->phygc.gc_vga16 == gc.gc_vga16)  \leave_drawing:                                                  \        unlock_draw_sem ()#else#define BLOCK_DRAW_SEM#define UNBLOCK_DRAW_SEM#endif/* * Low Level Graphics Operations */static int bytesperpixel (GAL_GC gc) {     return 1;}static int bitsperpixel (GAL_GC gc) {     return 4;}static int width (GAL_GC gc) {     return gc.gc_vga16->xres; }static int height (GAL_GC gc) {     return gc.gc_vga16->yres; }static int colors (GAL_GC gc) {        return 16;}static int setclipping (GAL_GC gc, int x1, int y1, int x2, int y2){    GC_VGA16* mygc;    mygc = gc.gc_vga16;    if (x1 < 0) x1 = 0;    if (y1 < 0) y1 = 0;    if (x2 > mygc->xres - 1) x2 = mygc->xres - 1;    if (y2 > mygc->yres - 1) y2 = mygc->yres - 1;    mygc->doclip = 1;#ifdef _LITE_VERSION    if (!mgIsServer && mygc == cur_gfx->phygc.gc_vga16) {        __mg_saved_clip_minx = x1;        __mg_saved_clip_miny = y1;        __mg_saved_clip_maxx = x2;        __mg_saved_clip_maxy = y2;    }    else {#endif        mygc->clipminx = x1;        mygc->clipminy = y1;        mygc->clipmaxx = x2 + 1;        mygc->clipmaxy = y2 + 1;#ifdef _LITE_VERSION    }#endif    return 0;}static void enableclipping (GAL_GC gc){    GC_VGA16* mygc = gc.gc_vga16;    setclipping (gc, 0, 0, mygc->xres - 1, mygc->yres - 1);}static void disableclipping (GAL_GC gc){    gc.gc_vga16->doclip = 0;}static int getclipping (GAL_GC gc, int* x1, int* y1, int* x2, int* y2){    GC_VGA16* mygc;    mygc = gc.gc_vga16;#ifdef _LITE_VERSION    if (!mgIsServer && mygc == cur_gfx->phygc.gc_vga16) {        *x1 = __mg_saved_clip_minx;        *y1 = __mg_saved_clip_miny;        *x2 = __mg_saved_clip_maxx;        *y2 = __mg_saved_clip_maxy;    }    else {#endif        *x1 = mygc->clipminx;        *y1 = mygc->clipminy;        *x2 = mygc->clipmaxx - 1;        *y2 = mygc->clipmaxy - 1;    #ifdef _LITE_VERSION    }#endif    return 0;}/* * Allocation and release of graphics context */static int allocategc (GAL_GC gc, int width, int height, int depth, GAL_GC* newgc){    GC_VGA16* mygc;    if (!(newgc->gc_vga16 = (GC_VGA16*)malloc (sizeof (GC_VGA16))))        return -1;    mygc = newgc->gc_vga16;    mygc->xres = width;    mygc->yres = height;    mygc->pitch = width;    mygc->gr_background = 0;    mygc->gr_foreground = 15;    enableclipping (*newgc);    if (!(mygc->fb_buff = calloc (1, mygc->pitch * height))) {        free (mygc);        return -1;    }    return 0;}static void freegc (GAL_GC gc){    GC_VGA16* mygc;    mygc = gc.gc_vga16;    free (mygc->fb_buff);    free (mygc);}/* * Background and foreground colors */static int getbgcolor (GAL_GC gc, gal_pixel* color){    GC_VGA16* mygc = gc.gc_vga16;    *color = mygc->gr_background;    return 0;}static int setbgcolor (GAL_GC gc, gal_pixel color){    GC_VGA16* mygc = gc.gc_vga16;    mygc->gr_background = color;        return 0;}static int getfgcolor (GAL_GC gc, gal_pixel* color){    GC_VGA16* mygc = gc.gc_vga16;    *color = mygc->gr_foreground;        return 0;}static int setfgcolor (GAL_GC gc, gal_pixel color){    GC_VGA16* mygc = gc.gc_vga16;    mygc->gr_foreground = color;        if (mygc->fb_buff == 0) {        vga_setcolor (color & 0x0F);    }    return 0;}/* * Convertion between GAL_Color and gal_pixel * borrowed  from gl lib. */static gal_pixel mapcolor (GAL_GC gc, GAL_Color *color){    unsigned int v;    /* Now this is real fun. Map to standard EGA palette. */    v = 0;    if (color->b >= 64)        v += 1;    if (color->g >= 64)        v += 2;    if (color->r >= 64)        v += 4;    if (color->b >= 192 || color->g >= 192 || color->r >= 192)        v += 8;    return v;}static int unmappixel (GAL_GC gc, gal_pixel pixel, GAL_Color* color){    color->r = SysPixelColor [pixel].r;    color->g = SysPixelColor [pixel].g;    color->b = SysPixelColor [pixel].b;    return 0;}/* * Palette operations */static int getpalette (GAL_GC gc, int s, int len, GAL_Color* cmap){    int i;    int r, g, b;    if (gc.gc_vga16 != cur_gfx->phygc.gc_vga16)        return 0;        for (i = 0; i < len; i++) {        vga_getpalette (i + s, &r, &g, &b);        cmap [i].r = r << 2;        cmap [i].g = g << 2;        cmap [i].b = b << 2;    }        return 0;}static int setpalette (GAL_GC gc, int s, int len, GAL_Color* cmap){    int i;    if (gc.gc_vga16 != cur_gfx->phygc.gc_vga16)        return 0;        for (i = s; i < s + len; i++) {        vga_setpalette (i, cmap->r >> 2, cmap->g >> 2, cmap->b >> 2);        cmap ++;    }    return 0;}/* * Specical functions work for <=8 bit color mode. */static int setcolorfulpalette (GAL_GC gc){    int i;    if (gc.gc_vga16 != cur_gfx->phygc.gc_vga16)        return 0;    for (i = 0; i < 16; i++) {        vga_setpalette (i, SysPixelColor[i].r >> 2,                         SysPixelColor[i].g >> 2,                         SysPixelColor[i].b >> 2);    }    return 0;}/* * Box operations */static size_t boxsize (GAL_GC gc, int w, int h){    if ((w <= 0) || (h <= 0)) return -1;    return w * h;}#define CLIP_INVISIBLE  0#define CLIP_VISIBLE    1#define CLIP_PARTIAL    2static int vga16_clippoint (PGC_VGA16 gc, int x ,int y){    if (gc->doclip) {        if ((x >= gc->clipminx) && (x < gc->clipmaxx) &&            (y >= gc->clipminy) && (y < gc->clipmaxy))             return CLIP_VISIBLE;    } else {        if ((x >= 0) && (x < gc->xres) && (y >= 0) && (y < gc->yres))             return CLIP_VISIBLE;    }    return CLIP_INVISIBLE;}static int vga16_cliphline (PGC_VGA16 gc,int * px,int * py, int * pw){    if (gc->doclip) {        if ( (*px >= gc->clipmaxx) || (*py >= gc->clipmaxy) ||              (*px + *pw - 1 < gc->clipminx) || (*py < gc->clipminy) )                return CLIP_INVISIBLE;        if ( (*px >= gc->clipminx) && (*py >= gc->clipminy) &&              (*px + *pw -1 < gc->clipmaxx) && (*py < gc->clipmaxy) )                return CLIP_VISIBLE;                    if (*px < gc->clipminx) {            *pw -= gc->clipminx - *px;            *px = gc->clipminx;        }        if (*px + *pw - 1 >= gc->clipmaxx)                *pw = gc->clipmaxx - *px;    } else {        if ( (*px >= gc->xres) || (*py >= gc->yres) || (*px + *pw - 1 < 0) || (*py < 0) )                return CLIP_INVISIBLE;        if ( (*px >= 0) && (*py >= 0) && (*px + *pw -1 < gc->xres) && (*py < gc->yres) )                return CLIP_VISIBLE;                    if (*px < 0) {            *pw += *px;                *px = 0;        }        if (*px + *pw - 1 >= gc->xres)                *pw = gc->xres - *px;    }    if (*pw <= 0)        return CLIP_INVISIBLE;    return CLIP_PARTIAL;        }static int vga16_clipvline(PGC_VGA16 gc,int * px,int * py, int *ph){    if (gc->doclip) {        if ( (*px >= gc->clipmaxx) || (*py >= gc->clipmaxy) ||              (*px < gc->clipminx) || (*py + *ph - 1 < gc->clipminy) )                return CLIP_INVISIBLE;        if ( (*px >= gc->clipminx) && (*py >= gc->clipminy) &&              (*px < gc->clipmaxx) && (*py + *ph - 1 < gc->clipmaxy) )                return CLIP_VISIBLE;                    if (*py < gc->clipminy) {            *ph -= gc->clipminy - *py;            *py = gc->clipminy;        }        if (*py + *ph - 1 >= gc->clipmaxy)                *ph = gc->clipmaxy - *py;    } else {        if ( (*py >= gc->yres) || (*px >= gc->xres) || (*py + *ph - 1 < 0) || (*px < 0) )                return CLIP_INVISIBLE;        if ( (*py >= 0) && (*px >= 0) && (*py + *ph -1 < gc->yres) && (*px < gc->xres) )                return CLIP_VISIBLE;                    if (*py < 0) {            *ph += *py;                *py = 0;        }        if (*py + *ph - 1 >= gc->yres)                *ph = gc->yres - *py;    }    if (*ph <= 0)        return CLIP_INVISIBLE;    return CLIP_PARTIAL;        }#define OC_LEFT 1#define OC_RIGHT 2#define OC_TOP 4#define OC_BOTTOM 8/* Outcodes:+-> x|       |      | V  0101 | 0100 | 0110y ---------------------   0001 | 0000 | 0010  ---------------------   1001 | 1000 | 1010        |      |  */#define outcode(code, xx, yy) \{\  code = 0;\ if (xx < tempclipminx)\    code |= OC_LEFT;\  else if (xx > tempclipmaxx)\    code |= OC_RIGHT;\  if (yy < tempclipminy)\    code |= OC_TOP;\  else if (yy>tempclipmaxy)\    code |= OC_BOTTOM;\}/*  Calculates |_ a/b _| with mathematically correct floor  */static int FloorDiv(int a, int b){    int floor;    if (b>0) {        if (a>0) {            return a /b;        } else {            floor = -((-a)/b);            if ((-a)%b != 0)                floor--;        }        return floor;    } else {        if (a>0) {            floor = -(a/(-b));            if (a%(-b) != 0)                floor--;            return floor;        } else {            return (-a)/(-b);        }    }}/*  Calculates |^ a/b ^| with mathamatically correct floor  */static int CeilDiv(int a,int b){    if (b>0)        return FloorDiv(a-1,b)+1;    else        return FloorDiv(-a-1,-b)+1;}static int cs_clipline (PGC_VGA16 gc,int *_x0, int *_y0, int *_x1, int *_y1,               int *clip_first, int *clip_last){    int first,last, code;    int x0,y0,x1,y1;    int x,y;    int dx,dy;    int xmajor;    int slope;        int tempclipminx,tempclipminy,tempclipmaxx,tempclipmaxy;    if (gc->doclip) {        tempclipminx = gc->clipminx;        tempclipminy = gc->clipminy;        tempclipmaxx = gc->clipmaxx;        tempclipmaxy = gc->clipmaxy;    } else {        tempclipminx = 0;        tempclipminy = 0;        tempclipmaxx = gc->xres - 1;        tempclipmaxy = gc->yres - 1;    }        first = 0;    last = 0;    outcode(first,*_x0,*_y0);    outcode(last,*_x1,*_y1);    if ((first | last) == 0) {        return CLIP_VISIBLE; /* Trivially accepted! */    }    if ((first & last) != 0) {        return CLIP_INVISIBLE; /* Trivially rejected! */    }    x0=*_x0; y0=*_y0;    x1=*_x1; y1=*_y1;    dx = x1 - x0;    dy = y1 - y0;      xmajor = (abs(dx) > abs(dy));    slope = ((dx>=0) && (dy>=0)) || ((dx<0) && (dy<0));      for (;;) {        code = first;        if (first==0)            code = last;        if (code&OC_LEFT) {            x = tempclipminx;            if (xmajor) {                y = *_y0 +  FloorDiv(dy*(x - *_x0)*2 + dx,                              2*dx);

⌨️ 快捷键说明

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