四. GAL分析
MiniGUI采用linux的framebuffer进行显示,打开/dev/fb0取得设备描述符,通过mmap映射将设备内存映射到用户空间,直接访问映射出来的用户空间就可以实现,通过内存写,就可以实现显示。
4.1 宏_MGGAL_FBCON的定义
static VideoBootStrap *bootstrap[] =
{
#ifdef _MGGAL_FBCON
&FBCON_bootstrap,
#endif
}
VideoBootStrap FBCON_bootstrap = {
"fbcon",
"Linux Framebuffer Console",
FB_Available,
FB_CreateDevice //初始化结构GAL_VideoDevice *this;
//包括this->VideoInit = FB_VideoInit;,
//也包括this->SetVideoMode = FB_SetVideoMode;
};
4.2 GAL的初始化
GAL_Surface* __gal_screen;
int mg_InitGAL (void)//系统初始化GAL
{
……
if (GAL_VideoInit (engine, 0))
//即内部有上面提到的FB_VideoInit()
……
if (!(__gal_screen = GAL_SetVideoMode (w, h, depth, GAL_HWPALETTE))
//即内部有上面提到的FB_SetVideoMode()
……
}
FB_VideoInit()//打开fb,实现内存映射
{
……
console_fd = open(GAL_fbdev, O_RDWR, 0);
……
mapped_mem = mmap(NULL, mapped_memlen,
PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0);
……
}
GAL_Surface *FB_SetVideoMode(_THIS, GAL_Surface *current,
int width, int height, int bpp, Uint32 flags)
//映射内存地址到GAL_Surface*的转变
{
……
current->flags = (GAL_FULLSCREEN|GAL_HWSURFACE);
current->w = vinfo.xres;
current->h = vinfo.yres;
current->pitch = finfo.line_length;
current->pixels = mapped_mem+mapped_offset;
……
return current; 即为__gal_screen
}
4.3设备上下文Device Context
struct tagDC
{
short DataType; /* the data type, always be TYPE_HDC */
short DCType; /* the dc type */
BOOL inuse;
HWND hwnd;
/* surface of this DC */
GAL_Surface* surface;//此处即初始化为__gal_screen,通过GetClientDC或者GetDC
/* background color */
gal_pixel bkcolor;
/* pen color */
gal_pixel pencolor;
/* solid brush color */
gal_pixel brushcolor;
/* text color */
gal_pixel textcolor;
int bkmode;
int tabstop;
int cExtra; /* Character extra */
int alExtra; /* Above line extra */
int blExtra; /* Bellow line extra */
int mapmode; /* mappping mode */
int ta_flags; /* Text alignment flags */
#ifdef _MGHAVE_ADV_2DAPI
/* pen attributes */
int pen_type;
int pen_cap_style;
int pen_join_style;
unsigned int pen_width;
/* brush attributes */
int brush_type;
POINT brush_orig;
const BITMAP* brush_tile;
const STIPPLE* brush_stipple;
/* custom dash info */
int dash_offset;
const unsigned char* dash_list;
size_t dash_list_len;
#endif
PLOGFONT pLogFont;
POINT CurPenPos;
POINT CurTextPos;
POINT ViewOrig;
POINT ViewExtent;
POINT WindowOrig;
POINT WindowExtent;
/* raster operation */
int rop;
/* used by the text rendering for anti-aliasing fonts. */
gal_pixel gray_pixels [17];
/* used by the text rendering for low-pass filtering. */
gal_pixel filter_pixels [17];
GAL_PixelFormat* alpha_pixel_format;
/* pixel and line operation */
CB_COMP_SETPIXEL draw_pixel;
CB_COMP_SETHLINE draw_pixel_span;
CB_COMP_PUTHLINE draw_src_span;
DC_MOVE_TO move_to;
DC_STEP_X step_x;
/* === context information. ============================================= */
/* DK[01/22/10]:This segment is binary compatible with _COMP_CTXT struct */
int step;
gal_uint8* cur_dst;
gal_pixel skip_pixel;
gal_pixel cur_pixel;
void * user_comp_ctxt;
/* ====================================================================== */
CLIPRECT* cur_ban;
RECT rc_output;
/* local clip region information */
CLIPRGN lcrgn;
/* effective clip region information */
CLIPRGN ecrgn;
/* device rect */
BOOL bIsClient;
RECT DevRC;
PGCRINFO pGCRInfo;
unsigned int oldage;
CB_BITMAP_SCALER_FUNC bitmap_scaler;
};
static void dc_InitDC (PDC pdc, HWND hWnd, BOOL bIsClient)
该函数负责初始化DC的各个成员变量,具体如下所示:
static void dc_InitDC (PDC pdc, HWND hWnd, BOOL bIsClient)
{
……
pdc->bkcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF);
pdc->bkmode = 0;
pdc->pencolor = GAL_MapRGB (pdc->surface->format, 0x00, 0x00, 0x00);
pdc->brushcolor = GAL_MapRGB (pdc->surface->format, 0xFF, 0xFF, 0xFF);
pdc->textcolor = GAL_MapRGB (pdc->surface->format, 0x00, 0x00, 0x00);
if (!(pdc->pLogFont = GetWindowFont (hWnd)))
pdc->pLogFont = GetSystemFont (SYSLOGFONT_WCHAR_DEF);
pdc->tabstop = 8;
pdc->CurTextPos.x = pdc->CurTextPos.y = 0;
pdc->cExtra = pdc->alExtra = pdc->blExtra = 0;
pdc->mapmode = MM_TEXT;
pdc->ta_flags = TA_LEFT | TA_TOP | TA_NOUPDATECP;
pdc->ViewOrig.x = pdc->ViewOrig.y = 0;
pdc->ViewExtent.x = pdc->ViewExtent.y = 1;
pdc->WindowOrig.x = pdc->WindowOrig.y = 0;
pdc->WindowExtent.x = pdc->WindowExtent.y = 1;
…………
pdc->draw_pixel = draw_pixel_ops [pdc->rop]
[pdc->surface->format->BytesPerPixel - 1];
pdc->draw_pixel_span = draw_pixel_span_ops [pdc->rop]
[pdc->surface->format->BytesPerPixel - 1];
pdc->draw_src_span = draw_src_span_ops [pdc->rop]
[pdc->surface->format->BytesPerPixel - 1];
pdc->cur_dst = (BYTE*)pdc->surface->pixels + pdc->surface->pitch * pdc->DevRC.top
+ pdc->surface->format->BytesPerPixel * pdc->DevRC.left;
pdc->move_to = move_to_ops [pdc->surface->format->BytesPerPixel - 1];
pdc->step_x = step_x_ops [pdc->surface->format->BytesPerPixel - 1];
pdc->alpha_pixel_format = NULL;
SetBitmapScalerType((HDC)pdc, BITMAP_SCALER_DDA);
…………
}
4.4 窗口的绘制风格
目前的窗口的绘制风格有classic, flat, skin, 该结构的功能实现各个小的窗口部分的绘制,组合起来即成为控件,以 classic风格的代码为例:
WINDOW_ELEMENT_RENDERER __mg_wnd_rdr_classic = {
"classic",
init,
deinit,
calc_3dbox_color,
draw_3dbox,
draw_radio,
draw_checkbox,
draw_checkmark,
draw_arrow,
draw_fold,
draw_focus_frame,
draw_normal_item,
draw_hilite_item,
draw_disabled_item,
draw_significant_item,
draw_push_button,
draw_radio_button,
draw_check_button,
draw_border,
draw_caption,
draw_caption_button,
draw_scrollbar,
calc_trackbar_rect,
draw_trackbar,
calc_we_area,
calc_we_metrics,
hit_test,
NULL,
NULL,
calc_thumb_area,
disabled_text_out,
draw_tab,
draw_progress,
draw_header,
NULL,
NULL,
erase_bkgnd,
draw_normal_menu_item,
draw_hilite_menu_item,
draw_disabled_menu_item,
};