📄 clientfb.c
字号:
/* * Microwindows direct client-side framebuffer mapping routines * * Copyright (c) 2001, 2002 by Greg Haerr <greg@censoft.com> */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#ifdef __ECOS# include <pkgconf/system.h>#include <pkgconf/microwindows.h> /* CYGBLD_MICROWINDOWS_VNC_DRIVERS */# ifndef CYGBLD_MICROWINDOWS_VNC_DRIVERS# ifdef CYGPKG_HAL_ARM# include <cyg/hal/lcd_support.h># endif# endif#else#include <sys/ioctl.h>#include <sys/mman.h>#include <asm/page.h> /* For definition of PAGE_SIZE */#include <linux/fb.h>#endif#include "nano-X.h"#include "device.h"/* globals: assumes use of non-shared libnano-X.a for now*/static int frame_fd; /* client side framebuffer fd*/static unsigned char * frame_map; /* client side framebuffer mmap'd addr*/static int frame_len; /* client side framebuffer length*/static unsigned char * physpixels; /* start address of pixels*/static GR_SCREEN_INFO sinfo;/* map framebuffer address into client memory*/unsigned char *GrOpenClientFramebuffer(void){#ifndef __ECOS int frame_offset; char * fbdev; struct fb_fix_screeninfo finfo;#endif /* if already open, return fb address*/ if (physpixels) return physpixels; /* * For now, we'll just check whether or not Microwindows * is running its framebuffer driver to determine whether * to allow direct client-side framebuffer mapping. In * the future, we could allow direct mapping for Microwindows * running on top of X, and finding the address of the * window within the Microwindows X window. */ GrGetScreenInfo(&sinfo); if (!sinfo.fbdriver) return NULL;#ifdef __ECOS# ifndef CYGBLD_MICROWINDOWS_VNC_DRIVERS# ifdef CYGPKG_HAL_ARM { struct lcd_info li; lcd_getinfo(&li); physpixels = li.fb; return physpixels; }# else /* This works for scr_ecospcsvga.c, at least */ { physpixels = scrdev.addr; return physpixels; }# endif # endif#else /* * Try to open the framebuffer directly. */ if (!(fbdev = getenv("FRAMEBUFFER"))) fbdev = "/dev/fb0"; frame_fd = open(fbdev, O_RDWR); if (frame_fd < 0) { printf("Can't open framebuffer device\n"); return NULL; } /* Get the type of video hardware */ if (ioctl(frame_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { printf("Couldn't get fb hardware info\n"); goto err; } // FIXME remove when mwin returns fb or X switch (finfo.visual) { case FB_VISUAL_TRUECOLOR: case FB_VISUAL_PSEUDOCOLOR: case FB_VISUAL_STATIC_PSEUDOCOLOR: case FB_VISUAL_DIRECTCOLOR: break; default: printf("Unsupported fb color map\n"); goto err; } /* Memory map the device, compensating for buggy PPC mmap() */ frame_offset = (((long)finfo.smem_start) - (((long)finfo.smem_start)&~(PAGE_SIZE-1))); frame_len = finfo.smem_len + frame_offset; frame_map = (unsigned char *)mmap(NULL, frame_len, PROT_READ|PROT_WRITE, MAP_SHARED, frame_fd, 0); if (frame_map == (unsigned char *)-1) { printf("Unable to memory map the video hardware\n"); frame_map = NULL; goto err; } physpixels = frame_map + frame_offset; return physpixels;err: close(frame_fd); return NULL;#endif // __ECOS}voidGrCloseClientFramebuffer(void){#ifndef __ECOS if (frame_fd >= 0) { if (frame_map) { munmap(frame_map, frame_len); frame_map = NULL; physpixels = NULL; } close(frame_fd); frame_fd = -1; /* reset sinfo struct*/ sinfo.cols = 0; }#endif}/* * Return client-side mapped framebuffer info for * passed window. If not running framebuffer, the * physpixel and winpixel members will be NULL, and * everything else correct. */voidGrGetWindowFBInfo(GR_WINDOW_ID wid, GR_WINDOW_FB_INFO *fbinfo){ int physoffset; GR_WINDOW_INFO info; static int last_portrait = -1; /* re-get screen info on auto-portrait switch*/ if (sinfo.cols == 0 || last_portrait != sinfo.portrait) GrGetScreenInfo(&sinfo); last_portrait = sinfo.portrait; /* must get window position anew each time*/ GrGetWindowInfo(wid, &info); fbinfo->bpp = sinfo.bpp; fbinfo->bytespp = (sinfo.bpp+7)/8; fbinfo->pixtype = sinfo.pixtype; fbinfo->x = info.x; fbinfo->y = info.y; fbinfo->portrait_mode = sinfo.portrait; switch (fbinfo->portrait_mode) { case MWPORTRAIT_RIGHT: case MWPORTRAIT_LEFT: /* * We reverse coords since Microwindows reports * back the virtual xres/yres, and we want * the physical xres/yres. */ // FIXME return xres and xvirtres in SCREENINFO? fbinfo->xres = sinfo.rows; /* reverse coords*/ fbinfo->yres = sinfo.cols; break; default: fbinfo->xres = sinfo.cols; fbinfo->yres = sinfo.rows; break; } fbinfo->xvirtres = sinfo.cols; fbinfo->yvirtres = sinfo.rows; fbinfo->pitch = fbinfo->xres * fbinfo->bytespp; /* fill in memory mapped addresses*/ fbinfo->physpixels = physpixels; /* winpixels only valid for non-portrait modes*/ physoffset = info.y*fbinfo->pitch + info.x*fbinfo->bytespp; fbinfo->winpixels = physpixels? (physpixels + physoffset): NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -