MiniGUI采用linux的framebuffer进行显示,打开/dev/fb0取得设备描述符,通过mmap映射将设备内存映射到用户空间,直接访问映射出来的用户空间就可以实现,通过内存写,就可以实现显示。
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; };
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 }
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); ………… }
目前的窗口的绘制风格有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, };