lowgdi.c

来自「做为linux下图形用户界面支持系统之一的MicroWindows采用C++设计」· C语言 代码 · 共 943 行 · 第 1/2 页

C
943
字号
    _lgResetClipping();

    _lgOutportb (0x3ce, 3);
    _lgOutportb (0x3cf, 0x08);          /* AND pen */
    _lgSetColor (LG_WHITE);
    _lgSetBgColor (LG_BLACK);
    _lgPutFont (_lgMScreenMask, _lgMLastX, _lgMLastY, 16, 16);
    _lgOutportb (0x3ce, 3);
    _lgOutportb (0x3cf, 0x10);          /* OR pen */
    _lgPutFont (_lgMCursorMask, _lgMLastX, _lgMLastY, 16, 16);
    _lgSetColor   (bc);
    _lgSetBgColor (bgc);
    _lgSetXOR (_lgXOR);                 /* restore pen mode */

    _lgClipX1=bcx1; _lgClipY1=bcy1;
    _lgClipX2=bcx2; _lgClipY2=bcy2;
}

BYTE _lgGetMouseButton ()
{
    _lgUpdateMouse();

    if (_lgMLButtonHitted == TRUE && _lgMButton == LGM_BUTTONUP)
    {
        _lgMLButtonHitted = FALSE;
    }

    return (_lgMButton);
}

int  _lgGetMouseX ()
{
    _lgUpdateMouse();
    return (_lgMLastX);
}

int  _lgGetMouseY ()
{
    _lgUpdateMouse();
    return (_lgMLastY);
}

void _lgMouseTempHide(int x1, int y1, int x2, int y2)
{
    int bcx1=_lgClipX1, bcx2=_lgClipX2, bcy1=_lgClipY1, bcy2=_lgClipY2;
    int oca, ocb;
    BOOL hide = FALSE;

    if (_lgMouseActive == FALSE) return;
    if (_lgCursorTempHide || _lgMouseHided) return;

    if (x1==-1 && y1==-1)
    {
        hide = TRUE;
    }
    else
    {
        _lgClipX1=x1-8;
        _lgClipY1=y1-4;
        _lgClipX2=x2+8;
        _lgClipY2=y2+4;

        oca=_lgClipOutcode (_lgMLastX, _lgMLastY);
        ocb=_lgClipOutcode (_lgMLastX+16, _lgMLastY+16);

        if (_lgClipAccept(oca, ocb))
        {
            if (!_lgClipReject (oca, ocb)) hide = TRUE;
        }
        else
        {
            hide = TRUE;
        }
    }

    if (hide == TRUE)
    {
        _lgMRestoreBack();
        _lgCursorTempHide=TRUE;
    }

    _lgClipX1=bcx1;
    _lgClipY1=bcy1;
    _lgClipX2=bcx2;
    _lgClipY2=bcy2;
}

void _lgMouseTempShow()
{
    if (_lgMouseHided) return;

    if (_lgCursorTempHide==TRUE)
    {
        _lgCursorTempHide=FALSE;
        _lgMSaveBack();
        _lgDisplayCursor();
    }
}

void _lgUpdateMouse ()
{
    int     x, y, state;

    if (_lgMouseActive == FALSE) return;

    _lgMouseCall (3, 0, 0, 0);
    x     = _lgCX;
    y     = _lgDX;
    state = _lgBX;

    if (x!=_lgMLastX || y!=_lgMLastY)   /* mouse moved */
    {
        _lgMRestoreBack();
        _lgMLastX  = x;
        _lgMLastY  = y;
        _lgMSaveBack();
        _lgDisplayCursor();
    }

    _lgMButton = LGM_MOVE;

    if (state & 1)          /* 1 = LBUTTON_DOWN */
    {
        if (_lgMLButtonHitted == TRUE)
        {
            _lgMButton = LGM_DRAG;
        }
        else
        {
            _lgMButton = LGM_BUTTONDOWN;
        }

        _lgMLButtonHitted = TRUE;
    }
    else
    {
        if (_lgMLButtonHitted == TRUE)
        {
            _lgMButton = LGM_BUTTONUP;
        }
    }
}

void _lgLineClipper(int x1, int y1, int x2, int y2)
{
    int  tmp;
    int  outcode1=_lgClipOutcode(x1, y1), outcode2=_lgClipOutcode(x2, y2);
    int  x3, y3, x4, y4, swap=0;
    long buf, dx, dy;

    _lgClipOut=1;

    while (_lgClipAccept(outcode1, outcode2))
    {
        if (_lgClipReject (outcode1, outcode2)) break;
        if (outcode1==_lgClipInside)
        {
            tmp=x2; x2=x1; x1=tmp;
            tmp=y2; y2=y1; y1=tmp;
            tmp=outcode2; outcode2=outcode1; outcode1=tmp;
            swap=1;
        }

        dx=x2-x1;
        dy=y2-y1;

        if (outcode1 & _lgClipTop)
        {
            if (dy) buf=dx*(long)(_lgClipY1-y1)/dy;
            x1+=buf;
            y1 =_lgClipY1;
        }
        else if (outcode1 & _lgClipBottom)
        {
            if (dy) buf=dx*(long)(_lgClipY2-y1)/dy;
            x1+=buf;
            y1 =_lgClipY2;
        }
        else if (outcode1 & _lgClipRight)
        {
            if (dx) buf=dy*(long)(_lgClipX2-x1)/dx;
            y1+=buf;
            x1 =_lgClipX2;
        }
        else if (outcode1 & _lgClipLeft)
        {
            if (dx) buf=dy*(long)(_lgClipX1-x1)/dx;
            y1+=buf;
            x1 =_lgClipX1;
        }
        outcode1=_lgClipOutcode(x1, y1);
    }

    if (!_lgClipAccept(outcode1, outcode2))
    {
        if (swap)
        {
            _lgRX1=x2;
            _lgRY1=y2;
            _lgRX2=x1;
            _lgRY2=y1;
        }
        else
        {
            _lgRX1=x1;
            _lgRY1=y1;
            _lgRX2=x2;
            _lgRY2=y2;
        }
        _lgClipOut=0;   /* still a drawable line */
    }
}

void _lgRectClipper(int x1, int y1, int x2, int y2)
{
    int tmp;
    int outcode1=_lgClipOutcode(x1, y1), outcode2=_lgClipOutcode(x2, y2);
    int x3, y3, x4, y4;

    _lgClipOut=1;
    while (_lgClipAccept(outcode1, outcode2))
    {
        if (_lgClipReject (outcode1, outcode2)) break;
        if (outcode1==_lgClipInside)
        {
            tmp=x2; x2=x1; x1=tmp;
            tmp=y2; y2=y1; y1=tmp;
            tmp=outcode2; outcode2=outcode1; outcode1=tmp;
        }

        if (outcode1 & _lgClipTop)
        {
            y1 =_lgClipY1;
        }
        else if (outcode1 & _lgClipBottom)
        {
            y1 =_lgClipY2;
        }
        else if (outcode1 & _lgClipRight)
        {
            x1 =_lgClipX2;
        }
        else if (outcode1 & _lgClipLeft)
        {
            x1 =_lgClipX1;
        }
        outcode1=_lgClipOutcode(x1, y1);
    }

    if (!_lgClipAccept(outcode1, outcode2))
    {
        x3=x1; x4=x2; y3=y1; y4=y2;
        if (x1>x2)
        {
            x3=x2;
            x4=x1;
        }
        if (y1>y2)
        {
            y3=y2;
            y4=y1;
        }

        _lgRX1=x3;
        _lgRY1=y3;
        _lgRX2=x4;
        _lgRY2=y4;
        _lgClipOut=0;
    }
}

/**********************************************************
 *
 *      1001 | 1000 | 1010
 *     ------+------+------
 *      0001 | 0000 | 0010      Cohen-Sutherland's outcode
 *     ------+------+------
 *      0101 | 0100 | 0110
 *
 *********************************************************/

int  _lgClipOutcode(int x , int y)
{
    int out;
    if (y<_lgClipY1) out=_lgClipTop;
    else if (y>_lgClipY2) out=_lgClipBottom;
    else out=_lgClipInside;

    if (x<_lgClipX1) out|=_lgClipLeft;
    else if (x>_lgClipX2) out|=_lgClipRight;

    return (out);
}

void    _lgGetImage (char *image, int x1, int y1, int x2, int y2)
{
    register int xc, yc;
    int x3, x4;
    unsigned int yaddr, addr;
    char p;

    x3=x1 >> 3;
    x4=x2 >> 3;

    for (yc=y1; yc<=y2; yc++)
    {
        yaddr=_lgYaddr[yc];

        for (p=0; p<4; p++)
        {
            _lgOutportb (0x3ce, 4);
            _lgOutportb (0x3cf, p);

            for (xc=x3; xc<=x4; xc++)
            {
                addr=yaddr+xc;
                *image++ = *(_lgDBitmap + addr);
            }
        }
    }

}

void    _lgPutImage (char *image, int x1, int y1, int x2, int y2)
{
    register int xc, yc;
    int x3, x4;
    unsigned yaddr, addr;
    char p;

    x3=x1 >> 3;
    x4=x2 >> 3;

    _lgOutportb (0x3ce, 3);
    _lgOutportb (0x3cf, 0);
    _lgOutportb (0x3ce, 5);
    _lgOutportb (0x3cf, 0);
    _lgOutportb (0x3ce, 8);
    _lgOutportb (0x3cf, 0xff);

    for (yc=y1; yc<=y2; yc++)
    {
        yaddr=_lgYaddr[yc];

        for (p=0; p<4; p++)
        {
            _lgOutportb (0x3c4, 2);
            _lgOutportb (0x3c5, _lgBitPlane[p]);

            for (xc=x3; xc<=x4; xc++)
            {
                addr=yaddr+xc;
                *(_lgDBitmap+addr)=*image++;
            }
        }
    }

    _lgOutportb (0x3ce, 5);
    _lgOutportb (0x3cf, 2);
    _lgOutportb (0x3c4, 2);
    _lgOutportb (0x3c5, 0x0f);
    _lgSetXOR (_lgXOR);                 /* restore pen mode */
}

int     _lgImageSize (int x1, int y1, int x2, int y2)
{
    return (((((x2 - x1) << 3) + 1) * (y2 - y1 + 1)) >> 2);
}

void    _lgPutFont  (char *image, int x, int y, int width, int height)
{
    register int xc, yc;
    int  bkc=_lgColor, bytewidth, yaddr, addr;
    BYTE *data, next, offset, mask;
    static BYTE mmask;

    _lgRectClipper (x, y, x+width-1, y+height-1);
    if (_lgClipOut) return;

    if (width & 7) bytewidth=(width >> 3)+1;
    else           bytewidth=(width >> 3);

    _lgOutportb (0x3ce, 8);

    for (yc=_lgRY1; yc<=_lgRY2; yc++)
    {
        data = image + bytewidth * (yc - y);
        next = (*data++);
        offset = (_lgRX1 - x);
        yaddr = _lgYaddr[yc];

        for (xc=_lgRX1; xc<=_lgRX2; xc++)
        {
            addr=yaddr + (xc >> 3);
            if (next & (0x80 >> offset)) _lgColor=bkc;
            else _lgColor=_lgBgColor;

           _lgOutportb (0x3cf, _lgMask[xc & 7]);
            mmask=*(_lgDBitmap+addr);
            *(_lgDBitmap+addr)=_lgColor;

            offset++;

            if (offset & 8)     /* offset > 7 */
            {
                offset=0;
                next=*data++;
            }
        }

    }

    _lgColor=bkc;
}

void    _lgPutDIB   (char *image, int x, int y, int width, int height)
{
    register int xc, yc;
    int  bkc=_lgColor;
    char *data;

    _lgRectClipper (x, y, x+width-1, y+height-1);
    if (_lgClipOut) return;
    _lgMouseTempHide (_lgRX1, _lgRY1, _lgRX2, _lgRY2);

    for (yc=_lgRY1; yc<=_lgRY2; yc++)
    {
        data = image + ((yc - y) * width) + (_lgRX1 - x);

        for (xc=_lgRX1; xc<=_lgRX2; xc++)
        {
            _lgColor = *data++;
            _lgLowPoint (xc, yc);
        }
    }

    _lgColor = bkc;
    _lgMouseTempShow();
}

int _lgTextWidth  (char *text)
{
    return (strlen(text) * 8);
}

int _lgTextHeight (char *text)
{
    if (text) return (15);
    return (0);
}

void _lgHideMouse ()
{
    if (_lgMouseHided == TRUE) return;
    _lgMRestoreBack ();
    _lgMouseHided = TRUE;
}

void _lgShowMouse ()
{
    if (_lgMouseHided == FALSE) return;
    _lgMouseHided = FALSE;
    _lgMSaveBack ();
}

BOOL _lgIsMouseHide (void)
{
    return (_lgMouseHided);
}

⌨️ 快捷键说明

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