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

📄 native.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
** $Id: native.c,v 1.63 2004/08/02 03:00:03 snig Exp $
**
** native.c: Native Low Level Graphics Engine's interface file
**
** Copyright (C) 2002, 2003 Feynman Software.
** Copyright (C) 2000 ~ 2002 Song Lixin, Wei Yongming, and Chen Lei.
**
** Add code for MiniGUI-Lite by Wei Yongming, 2001/01/01
** Clean code for MiniGUI 1.1.x by Wei Yongming, 2001/09/18
** Coordinates transfering for iPAQ by Chen Lei, 2001/12/12
** Cleanup for coordinates transfering for iPAQ by Wei Yongming, 2003/05/21
**
** Created by Song Lixin, 2000/10/18
*/

/*
** 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 <string.h>

#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "gal.h"
#include "native.h"

#ifndef _COOR_TRANS
#define _COOR_TRANS     0
#define _ROT_DIR_CW    0
#endif

#if defined(_LITE_VERSION) && !(_STAND_ALONE)

#include "ourhdr.h"
#include "client.h"
#include "sharedres.h"
#include "drawsemop.h"

static void rotatecoor (int *x1, int *y1, int *x2, int *y2, int Tw, int dir);

#define BLOCK_DRAW_SEM                                  \
    if (!mgIsServer && cur_gfx->phygc.psd == gc.psd)    \
        lock_draw_sem ();                               \
    if (((!mgIsServer && (SHAREDRES_TOPMOST_LAYER != __mg_layer)) || __mg_switch_away)) \
        goto leave_drawing;

#define UNBLOCK_DRAW_SEM                                \
    if (!mgIsServer && cur_gfx->phygc.psd == gc.psd)    \
leave_drawing:                                          \
        unlock_draw_sem ()

#else

#define BLOCK_DRAW_SEM
#define UNBLOCK_DRAW_SEM

#endif

#ifdef _DEBUG
#define debug(fmt, args...)        fprintf(stderr, " <native>-%s\t" fmt, __FUNCTION__, ##args);
#else
#define debug(fmt, args...)
#endif

/*
 * leon -- the following drafts will help us
 */

#if 0

    Drafts:
    rects:

          -/-------------------  Tw  --------------------/-
    
    
          Porg                    Px1      Px2          Vorg
                                  Vy2      Vy1
        Vy <--------------------------------------------->  Px   -/-
           |                      |        |             |        |
           |                      |   Pw   |             |        |
      Py1  |---------------------------------------------|Vx1     |
           |                      |        |             |        |
           |                      |        |             |        |
           |                   Ph |        |Vw           |
           |                      |        |             |        Th
           |                      |        |             |
           |                      |  Vh    |             |        |
      Py2  |---------------------------------------------|Vx2     |
           |                                             |        |
           |                                             |        |
           |                                             |        |
           |                                             |       -/-
    
           Py                                            Vx


        Tw: Total width
        Th: Total height

        Porg:   Physical origal               Vorg:    Virtual origal
        Px1:    Physical x1                   Vx1:     Virtual x1
        Px2:    Physical x2                   Vx2:     Virtual x2
        Py1:    Physical y1                   Vy1:     Virtual y1
        Py2:    Physical y2                   Vy2:     Virtual y2
        Pw:     Physical width                Vw:      Virtual width
        Ph:     Physical height               Vh:      Virtual height

//////////////////////////////////////////////////////////////////////

    for the buffer refered by putbox, getbox:
        
       -/---      Tw     ---/-
              Px0
        Po    Vy0           Vo
    Vy    <-------------------> Px  -/-
        |     |             |        |
        |     |             |        |
        |     |             |        |
        |     | P0          |         
    Py0    |_____._____________| Vx0    Th
        |                   |         
        |-------------------|        |
        |                   |        |
        Py                  Vx      -/-

#endif

/*
 * help rutines for coordinate transfer begin
 */
static void swapval (int* v1, int* v2)
{
    int tmp;

    tmp = *v1;
    *v1 = *v2;
    *v2 = tmp;
}

static void rotatecoor (int *x1, int *y1, int *x2, int *y2, int Tw, int dir /* 0: V->P, 1: P->V */)
{
    int tmp1, tmp2;

    switch (dir) {
        case 0:
            tmp1 = *x1;
            tmp2 = *x2;
            *x1 = Tw - 1 - *y2;
            *x2 = Tw - 1 - *y1;
            *y1 = tmp1;
            *y2 = tmp2;
            break;
        case 1:
            tmp1 = *y1;
            tmp2 = *y2;
            *y1 = Tw - 1 - *x2;
            *y2 = Tw - 1 - *x1;
            *x1 = tmp1;
            *x2 = tmp2;
            break;
    }
}

static void rotaterect (int* x, int* y, int* w, int* h, int Tw, int dir /* 0: V->P, 1: P->V */)
{
    int tmp;

    switch (dir) {
        case 0:
            tmp = *y;
            *y = *x;
            *x = Tw - (tmp + *h);
            swapval (w, h);
            break;
        case 1:
            tmp = *x;
            *x = *y;
            *y = Tw - (tmp + *w);
            swapval (w, h);
            break;
    }
}

static void rotatepoint (int* x, int* y, int Tw , int dir /* 0: V->P, 1: P->V */)
{
    int tmp;

    switch (dir) {
        case 0:
            tmp = *x;
            *x = Tw  - 1 - *y;
            *y = tmp;
            break;

        case 1:
            tmp = *y;
            *y = Tw - 1 - *x;
            *x = tmp;
            break;
    }
}

static void reverse_buff (char* dst, const char* src, int size, int Bpp)
{
    int i;

    switch (Bpp) {
    case 1:
        for (i = 0; i < size; i++)
            dst [i] = src [size - i - 1];
        break;
    case 2:
        {
            Uint16* _dst = (Uint16*)dst;
            Uint16* _src = (Uint16*)src;
            for (i = 0; i < size; i++)
                _dst [size - i - 1] = _src [i];
            break;
        }
    case 3:
        {
            for (i = 0; i < size * Bpp; i+=3) {
                dst [size - i - 1] = src [i];
                dst [size - i - 2] = src [i + 1];
                dst [size - i - 3] = src [i + 2];
            }
            break;
        }
    case 4:
        {
            Uint32* _dst = (Uint32*)dst;
            Uint32* _src = (Uint32*)src;
            for (i = 0; i < size; i++)
                _dst [size - i - 1] = _src [i];
            break;
        }
    default:
        return;
    }
}

/*
 * help rutines for coordinate transfer end
 */


/*
 * Low Level Graphics Operations
 */
static int bytesperpixel (GAL_GC gc) 
{ 
    return (gc.psd->bpp + 7) / 8; 
}

static int bitsperpixel (GAL_GC gc) 
{ 
    return gc.psd->bpp; 
}

static int width (GAL_GC gc) 
{ 
    if (_COOR_TRANS && gc.psd == cur_gfx->phygc.psd)
        return gc.psd->yres; 
    else
        return gc.psd->xres; 
}

static int height (GAL_GC gc) 
{ 
    if (_COOR_TRANS && gc.psd == cur_gfx->phygc.psd)
        return gc.psd->xres; 
    else
        return gc.psd->yres; 
}

static int colors (GAL_GC gc) 
{    
    return gc.psd->ncolors; 
}

static int setclipping (GAL_GC gc, int x1, int y1, int x2, int y2)
{

    PSD psd;
    psd = gc.psd;

    if (_COOR_TRANS && gc.psd == cur_gfx->phygc.psd) {
        if (x1 < 0) x1 = 0;
        if (y1 < 0) y1 = 0;
        if (x2 > psd->yres - 1) x2 = psd->yres - 1;
        if (y2 > psd->xres - 1) y2 = psd->xres - 1;
    }
    else {
        if (x1 < 0) x1 = 0;
        if (y1 < 0) y1 = 0;
        if (x2 > psd->xres - 1) x2 = psd->xres - 1;
        if (y2 > psd->yres - 1) y2 = psd->yres - 1;
    }

    psd->doclip = 1;

    if (_COOR_TRANS && gc.psd == cur_gfx->phygc.psd)
        rotatecoor (&x1, &y1, &x2, &y2, _ROT_DIR_CW?psd->xres:psd->yres, _ROT_DIR_CW?0:1);
        
    psd->clipminx = x1;
    psd->clipminy = y1;
    psd->clipmaxx = x2 + 1;
    psd->clipmaxy = y2 + 1;

    return 0;
}

static void enableclipping (GAL_GC gc)
{
    PSD psd;
    psd = gc.psd;

    if (_COOR_TRANS && gc.psd == cur_gfx->phygc.psd)
        setclipping (gc, 0, 0, psd->yres - 1, psd->xres - 1);
    else
        setclipping (gc, 0, 0, psd->xres - 1, psd->yres - 1);
}

static void disableclipping (GAL_GC gc)
{
    PSD psd;
    psd = gc.psd;
    psd->doclip = 0;
}

static int getclipping (GAL_GC gc, int* x1, int* y1, int* x2, int* y2)
{
    PSD psd;
    psd = gc.psd;

    *x1 = psd->clipminx;
    *y1 = psd->clipminy;
    *x2 = psd->clipmaxx - 1;
    *y2 = psd->clipmaxy - 1;    

    if (_COOR_TRANS && gc.psd == cur_gfx->phygc.psd)
        rotatecoor (x1, y1, x2, y2, _ROT_DIR_CW?gc.psd->xres:gc.psd->yres, _ROT_DIR_CW?1:0);

    return 0;
}

/*
 * Allocation and release of graphics context
 */
static int allocategc (GAL_GC gc, int width, int height, int depth, GAL_GC* newgc)
{
    int linelen, size;
    PSD newpsd;
    void* pixels;
    int bpp;

    bpp = gc.psd->bpp;

    newpsd = gc.psd->AllocateMemGC (gc.psd);
    if (!newpsd)
        return -1;
    
    if (!native_gen_calcmemgcalloc (newpsd, width, height, 0, bpp, &size, &linelen))
        goto fail;
    
    pixels = malloc(size);
    if (!pixels)
        goto fail;

    if (gc.psd->flags & PSF_MSBRIGHT)
        newpsd->flags |= PSF_MSBRIGHT;
    newpsd->flags |= PSF_ADDRMALLOC;

    if (!newpsd->MapMemGC (newpsd, width, height, gc.psd->planes, bpp, linelen, size, pixels))
        goto fail;

    newgc->psd = newpsd;

    setclipping (*newgc, 0, 0, width - 1, height - 1);
    return 0;

fail:
    newpsd->FreeMemGC (newpsd);
    return -1;
}

static void freegc (GAL_GC gc)
{
    PSD psd;
    psd = gc.psd;
    if(gc.psd->flags & PSF_ADDRMALLOC)
        free (gc.psd->addr);
    psd->FreeMemGC (psd);
}

/*
 * Background and foreground colors
 */
static int getbgcolor (GAL_GC gc, gal_pixel* color)
{
    PSD psd;
    psd = gc.psd;
    *color = psd->gr_background;    
    return 0;
}

static int setbgcolor (GAL_GC gc, gal_pixel color)
{
    PSD psd;
    psd = gc.psd;
    psd->gr_background = color;    
    return 0;
}

static int getfgcolor (GAL_GC gc, gal_pixel* color)
{
    PSD psd;
    psd = gc.psd;
    *color = psd->gr_foreground;    
    return 0;
}

static int setfgcolor (GAL_GC gc, gal_pixel color)
{
    PSD psd;
    psd = gc.psd;
    psd->gr_foreground = color;    
    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;

    switch (gc.psd->bpp) {
    case 1:
        if ((color->b + color->g + color->r) > 128*3)
            v = 1;
        else
            v = 0;
        return v;

    case 2:
        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;
        v>>=2;
        return v;

    case 4:
        /* 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;
    case 8:
        return RGB2PIXEL332 (color->r, color->g, color->b);
    case 15:

⌨️ 快捷键说明

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