📄 native.c
字号:
/*
** $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 + -