📄 scr_quasarosd.c
字号:
/* * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com> * * Microwindows Screen Driver for Linux kernel framebuffers * * Portions used from Ben Pfaff's BOGL <pfaffben@debian.org> * * Note: modify select_fb_driver() to add new framebuffer subdrivers */#define _GNU_SOURCE 1#include <assert.h>#include <fcntl.h>#include <limits.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>//#ifndef ARCH_LINUX_POWERPPC//#ifdef __GLIBC__//#include <sys/io.h>//#else//#include <asm/io.h>//#endif//#endif#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#define ALLOW_OS_CODE 1#include <unistd.h>#include "device.h"#include "genfont.h"#include "genmem.h"#define ALLOW_OS_CODE 1#include "rmdef.h"#include "realmagichwl_uk.h"#define TRACE//#define TRACE printf("In %s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);//#define OSD_WIDTH 640//#define OSD_HEIGHT 480//#define OSD_SIZE (OSD_WIDTH*OSD_HEIGHT + 256*4 + 8)//#define OSD_BPP 8//XXX#define DRAWON while(0)#define DRAWOFF while(0)typedef unsigned char * ADDR8;typedef unsigned short * ADDR16;typedef unsigned long * ADDR32;static RUA_handle h;static PSD qosd_open(PSD psd);static void qosd_close(PSD psd);static void qosd_setpalette(PSD psd,int first, int count, MWPALENTRY *palette);static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi);static void qosd_unimplemented(void);static void qosd_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c);static MWPIXELVAL qosd_readpixel(PSD psd, MWCOORD x, MWCOORD y);static void qosd_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);static void qosd_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);static void qosd_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op);static void qosd_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw, MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw, MWCOORD srch, long op);/* genmem.c*/void gen_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2, MWPIXELVAL c);void set_palette(RUA_handle h, int i, char r, char g, char b, char alpha);SCREENDEVICE scrdev = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, qosd_open, qosd_close, gen_getscreeninfo, qosd_setpalette, qosd_drawpixel, /* DrawPixel subdriver*/ qosd_readpixel, /* ReadPixel subdriver*/ qosd_drawhorzline, /* DrawHorzLine subdriver*/ qosd_drawvertline, /* DrawVertLine subdriver*/ gen_fillrect, /* FillRect subdriver*/ gen_fonts, qosd_blit, /* Blit subdriver*/ NULL, /* PreSelect*/ NULL, /* DrawArea subdriver*/ NULL, /* SetIOPermissions*/ gen_allocatememgc, NULL, // qosd_mapmemgc, gen_freememgc, NULL, /* StretchBlit subdriver*/ NULL /* SetPortrait*/};void applyOp(char *addr, int mode, MWCOORD x, MWCOORD y, MWPIXELVAL c){ RMuint8 pix; RMKERNELOSDBUFDimensions_type dim; kernelproperty Kp; Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer dimension\n"); return; } pix = OSD_GetPixel((RMuint8*)addr, &dim,(RMuint32)x,(RMuint32)y); switch (mode) { case MWMODE_XOR: pix ^= c; break; case MWMODE_AND: pix &= c; break; case MWMODE_OR: pix |= c; break; case MWMODE_CLEAR: pix = 0; break; case MWMODE_SETTO1: pix = -1; break; case MWMODE_EQUIV: pix = ~(pix ^ c); break; case MWMODE_NOR: pix = ~(pix | c); break; case MWMODE_NAND: pix = ~(pix & c); break; case MWMODE_INVERT: pix = ~pix; break; case MWMODE_COPYINVERTED: pix = ~c; break; case MWMODE_ORINVERTED: pix |= ~c; break; case MWMODE_ANDINVERTED: pix &= ~c; break; case MWMODE_ORREVERSE: pix = ~pix | c; break; case MWMODE_ANDREVERSE: pix = ~pix & c; break; case MWMODE_COPY: pix = c; break; default: return; } OSD_SetPixel((RMuint8*)addr, &dim, x, y, pix);}extern int gr_mode;/* static variables*/static int status; /* 0=never inited, 1=once inited, 2=inited. */static char *osd_buffer_addr;static void qosd_unimplemented(void){ printf("*** CALL TO UNIMPLEMENTED FONCTION ***\n");}/* init framebuffer*/static PSD qosd_open(PSD psd){// unsigned long flicker; kernelproperty Kp; RMKERNELOSDBUFDimensions_type dim; TRACE assert(status < 2); psd->portrait = MWPORTRAIT_NONE; psd->planes = 1; psd->flags = PSF_SCREEN | PSF_HAVEBLIT; /* set pixel format*/ psd->pixtype = MWPF_PALETTE; /*DPRINTF("%dx%dx%d linelen %d type %d visual %d bpp %d\n", psd->xres, psd->yres, psd->ncolors, psd->linelen, type, visual, psd->bpp);*/// XXX If we need to we can mmap the osdbuf from the device h = RUA_OpenDevice(0, FALSE); Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer\n"); goto fail; } else { Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Map; Kp.PropTypeLength = sizeof(char); Kp.pValue = &osd_buffer_addr; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer dimension\n"); goto fail; } psd->bpp = dim.color_depth; psd->xres = psd->xvirtres = dim.width; psd->yres = psd->yvirtres = dim.height; /* set linelen to byte length, possibly converted later*/ psd->linelen = dim.width; /* force subdriver init of size*/ psd->size = dim.width*dim.height/(8/dim.color_depth); psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp); printf("OSD Buffer of size %d allocated @ %p\n", psd->size, osd_buffer_addr); } psd->addr = osd_buffer_addr; /* save original palette ??? */ /* Setup the flicker filter *//* // XXX - its also set in the kernel module, but it seems not to work very well // We reset it here, so that the microcode as already seen an osd frame. // 0 <= flicker <= 15 flicker = 15; RUA_DECODER_SET_PROPERTY (h, DECODER_SET, edecOsdFlicker, sizeof(flicker), &flicker);*/ DPRINTF("End of qosd_open\n"); status = 2; return psd; /* success*/fail: return NULL;}/* close framebuffer*/static voidqosd_close(PSD psd){ /* if not opened, return*/ TRACE if(status != 2) return; status = 1; RUA_ReleaseDevice(h); /* unmap framebuffer*/// free(osd_buffer_addr);}void set_palette(RUA_handle h, int i, char r, char g, char b, char alpha){ kernelproperty Kp; RMKERNELOSDBUFPaletteEntry_type color; color.i = i; color.R = r; color.G = g; color.B = b; color.alpha = alpha; Kp.kernelpropid_value=PROPID_KERNEL_OSDBUF_PaletteEntry; Kp.PropTypeLength=sizeof(RMKERNELOSDBUFPaletteEntry_type); Kp.pValue=&color; RUA_KERNEL_SET_PROPERTY(h,&Kp);}static void qosd_setpalette(PSD psd,int first, int count, MWPALENTRY *palette){ char alpha; int i; for (i=first; i<count; i++){ if (i==0) alpha = 0x00; else if (i == 6) alpha = 0x66; else if (i == 15) alpha = 0x80; else if (i == 242) alpha = 0x80; else alpha = 0xff; set_palette(h, i, palette[i].r, palette[i].g, palette[i].b, alpha); }}static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi){ TRACE psi->rows = psd->yvirtres; psi->cols = psd->xvirtres; psi->planes = psd->planes; psi->bpp = psd->bpp; psi->ncolors = psd->ncolors; psi->fonts = NUMBER_FONTS; psi->portrait = psd->portrait; psi->fbdriver = FALSE; /* not running fb driver, can direct map*/ psi->pixtype = psd->pixtype; switch (psd->pixtype) { case MWPF_TRUECOLOR0888: case MWPF_TRUECOLOR888: psi->rmask = 0xff0000; psi->gmask = 0x00ff00; psi->bmask = 0x0000ff; break; case MWPF_TRUECOLOR565: psi->rmask = 0xf800; psi->gmask = 0x07e0; psi->bmask = 0x001f; break; case MWPF_TRUECOLOR555: psi->rmask = 0x7c00; psi->gmask = 0x03e0; psi->bmask = 0x001f; break; case MWPF_TRUECOLOR332: psi->rmask = 0xe0; psi->gmask = 0x1c; psi->bmask = 0x03; break; case MWPF_PALETTE: default: psi->rmask = 0xff; psi->gmask = 0xff; psi->bmask = 0xff; break; } if(psd->yvirtres > 480) { /* SVGA 800x600*/ psi->xdpcm = 33; /* assumes screen width of 24 cm*/ psi->ydpcm = 33; /* assumes screen height of 18 cm*/ } else if(psd->yvirtres > 350) { /* VGA 640x480*/ psi->xdpcm = 27; /* assumes screen width of 24 cm*/ psi->ydpcm = 27; /* assumes screen height of 18 cm*/ } else if(psd->yvirtres <= 240) { /* half VGA 640x240 */ psi->xdpcm = 14; /* assumes screen width of 24 cm*/ psi->ydpcm = 5; } else { /* EGA 640x350*/ psi->xdpcm = 27; /* assumes screen width of 24 cm*/ psi->ydpcm = 19; /* assumes screen height of 18 cm*/ }}static void qosd_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c){ RMKERNELOSDBUFDimensions_type dim; kernelproperty Kp; TRACE assert (x >= 0 && x < psd->xres); assert (y >= 0 && y < psd->yres); assert (c < psd->ncolors); Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer\n"); return; } DRAWON; if(gr_mode == MWMODE_COPY) OSD_SetPixel((RMuint8*)psd->addr, &dim, (RMuint32)x, (RMuint32)y, (RMuint8)c); else applyOp(psd->addr, gr_mode, x, y, c); DRAWOFF;}/* Read pixel at x, y*/static MWPIXELVAL qosd_readpixel(PSD psd, MWCOORD x, MWCOORD y){ RMKERNELOSDBUFDimensions_type dim; kernelproperty Kp; TRACE Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer dimension\n"); return 0; } assert (x >= 0 && x < psd->xres); assert (y >= 0 && y < psd->yres); return (MWPIXELVAL) OSD_GetPixel((RMuint8*)psd->addr, &dim, (RMuint32)x, (RMuint32)y);}/* Draw horizontal line from x1,y to x2,y including final point*/static void qosd_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c){ int i; RMKERNELOSDBUFDimensions_type dim; kernelproperty Kp; TRACE assert (x1 >= 0 && x1 < psd->xres); assert (x2 >= 0 && x2 < psd->xres); assert (x2 >= x1); assert (y >= 0 && y < psd->yres); assert (c < psd->ncolors); Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer dimension\n"); return; } DRAWON; if(gr_mode == MWMODE_COPY) for (i=x1; i<=x2; i++){ OSD_SetPixel((RMuint8*)psd->addr, &dim, (RMuint32)i, (RMuint32)y, (RMuint8)c); } else { for (i=x1; i<=x2; i++){ applyOp(psd->addr, gr_mode, (MWCOORD)i, y, c); } } DRAWOFF;}/* Draw a vertical line from x,y1 to x,y2 including final point*/static void qosd_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c){ RMKERNELOSDBUFDimensions_type dim; kernelproperty Kp; int i; TRACE assert (x >= 0 && x < psd->xres); assert (y1 >= 0 && y1 < psd->yres); assert (y2 >= 0 && y2 < psd->yres); assert (y2 >= y1); assert (c < psd->ncolors); Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY(h,&Kp)!=0) { EPRINTF("Error getting the osd buffer dimension\n"); return; } DRAWON; if(gr_mode == MWMODE_COPY) { for (i=y1; i<=y2; i++){ OSD_SetPixel((RMuint8*)psd->addr, &dim, (RMuint32)x, (RMuint32)i, (RMuint8)c); } } else { for (i=y1; i<=y2; i++){ applyOp(psd->addr, gr_mode, x, (MWCOORD)i, c); } } DRAWOFF;}/* srccopy bitblt*/static void qosd_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op){ MWPIXELVAL pix; MWCOORD destinationX, destinationY, sourceX, sourceY; RMKERNELOSDBUFDimensions_type dim; kernelproperty Kp; int i, j; TRACE assert (dstpsd->addr != 0); assert (dstx >= 0 && dstx < dstpsd->xres); assert (dsty >= 0 && dsty < dstpsd->yres); assert (w > 0); assert (h > 0); assert (srcpsd->addr != 0); assert (srcx >= 0 && srcx < srcpsd->xres); assert (srcy >= 0 && srcy < srcpsd->yres); assert (dstx+w <= dstpsd->xres); assert (dsty+h <= dstpsd->yres); assert (srcx+w <= srcpsd->xres); assert (srcy+h <= srcpsd->yres); Kp.kernelpropid_value = PROPID_KERNEL_OSDBUF_Dimensions; Kp.PropTypeLength = sizeof(RMKERNELOSDBUFDimensions_type); Kp.pValue = &dim; if (RUA_KERNEL_GET_PROPERTY((void*)h,&Kp)!=0) { EPRINTF("Error getting the osd buffer dimension\n"); return; } destinationX = dstx; destinationY = dsty; sourceX = srcx; sourceY = srcy; DRAWON; if (op == MWROP_COPY) { for(i=h; i>0; i--){ for(j=w; j>0; j--){ pix = OSD_GetPixel((RMuint8*)srcpsd->addr, &dim, (RMuint32)sourceX, (RMuint32)sourceY); OSD_SetPixel((RMuint8*)dstpsd->addr, &dim, (RMuint32)destinationX, (RMuint32)destinationY, (RMuint8)pix); sourceX++; destinationX++; } destinationY++; sourceY++; } } else { for(i=h; i>0; i--){ for(j=w; j>0; j--){ pix = OSD_GetPixel((RMuint8*)srcpsd->addr, &dim, (RMuint32)sourceX, (RMuint32)sourceY); applyOp(dstpsd->addr, MWROP_TO_MODE(op), destinationX, destinationY, pix); sourceX++; destinationX++; } destinationY++; sourceY++; } } DRAWOFF;}/* srccopy stretchblt*/static void qosd_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw, MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw, MWCOORD srch, long op){/* ADDR8 dst; ADDR8 src; int dlinelen = dstpsd->linelen; int slinelen = srcpsd->linelen; int i, ymax; int row_pos, row_inc; int col_pos, col_inc; unsigned char pixel = 0; TRACE assert (dstpsd->addr != 0); assert (dstx >= 0 && dstx < dstpsd->xres); assert (dsty >= 0 && dsty < dstpsd->yres); assert (dstw > 0); assert (dsth > 0); assert (srcpsd->addr != 0); assert (srcx >= 0 && srcx < srcpsd->xres); assert (srcy >= 0 && srcy < srcpsd->yres); assert (srcw > 0); assert (srch > 0); assert (dstx+dstw <= dstpsd->xres); assert (dsty+dsth <= dstpsd->yres); assert (srcx+srcw <= srcpsd->xres); assert (srcy+srch <= srcpsd->yres); DRAWON; row_pos = 0x10000; row_inc = (srch << 16) / dsth; // stretch blit using integer ratio between src/dst height/width for (ymax = dsty+dsth; dsty<ymax; ++dsty) { // find source y position while (row_pos >= 0x10000L) { ++srcy; row_pos -= 0x10000L; } dst = dstpsd->addr + dstx + dsty*dlinelen; src = srcpsd->addr + srcx + (srcy-1)*slinelen; // copy a row of pixels col_pos = 0x10000; col_inc = (srcw << 16) / dstw; for (i=0; i<dstw; ++i) { // get source x pixel while (col_pos >= 0x10000L) { pixel = *src++; col_pos -= 0x10000L; } *dst++ = pixel; col_pos += col_inc; } row_pos += row_inc; } DRAWOFF;*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -