em85xxosd.c

来自「mini gui 1.6.8 lib and source」· C语言 代码 · 共 343 行

C
343
字号
/***  $Id: em85xxosd.c,v 1.9 2005/05/18 11:00:21 weiym Exp $****  em85xxosd.c: NEWGAL driver for EM85xx OSD.**  **  Copyright (C) 2003 Feynman Software.*//*** 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 <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <sched.h>#include "common.h"#include "newgal.h"#include "sysvideo.h"#include "pixels_c.h"#include "realmagichwl_userland/caribbean_plainc.h"#include "realmagichwl_kernelland/realmagichwl.h"#include "realmagichwl_userland/realmagichwl_userland_api.h"#include "realmagichwl_kernelland/include/rm84cmn.h"#include "em85xxosd.h"#define EM85XXOSDVID_DRIVER_NAME "em85xxosd"/* Initialization/Query functions */static int EM85XXOSD_VideoInit(_THIS, GAL_PixelFormat *vformat);static GAL_Rect **EM85XXOSD_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags);static GAL_Surface *EM85XXOSD_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags);static int EM85XXOSD_SetColors(_THIS, int first, int count, GAL_Color *palette);static void EM85XXOSD_VideoQuit(_THIS);/* Hardware surface functions */static int EM85XXOSD_AllocHWSurface(_THIS, GAL_Surface *surface);static void EM85XXOSD_FreeHWSurface(_THIS, GAL_Surface *surface);static void EM85XXOSD_UpdateRects (_THIS, int numrects, GAL_Rect *rects);/* EM85XXOSD driver bootstrap functions */static int EM85XXOSD_Available(void){    return(1);}static char stack_updater [512];static int task_do_update (void* data){    _THIS;    this = data;    while (this->hidden->status == 2) {        usleep (50000);    // 50 ms        if (this->hidden->dirty) {            asm ("mcr p15, 0, r0, c7, c10, 0\n");            RUA_OSDFB_REFRESH (this->hidden->handle, 0);   // manually refresh now            this->hidden->dirty = FALSE;        }    }    return 0;}static void EM85XXOSD_DeleteDevice(GAL_VideoDevice *device){    free(device->hidden);    free(device);}static GAL_VideoDevice *EM85XXOSD_CreateDevice(int devindex){    GAL_VideoDevice *device;    /* Initialize all variables that we clean on shutdown */    device = (GAL_VideoDevice *)malloc(sizeof(GAL_VideoDevice));    if ( device ) {        memset(device, 0, (sizeof *device));        device->hidden = (struct GAL_PrivateVideoData *)                malloc((sizeof *device->hidden));    }    if ( (device == NULL) || (device->hidden == NULL) ) {        GAL_OutOfMemory();        if ( device ) {            free(device);        }        return(0);    }    memset(device->hidden, 0, (sizeof *device->hidden));    /* Set the function pointers */    device->VideoInit = EM85XXOSD_VideoInit;    device->ListModes = EM85XXOSD_ListModes;    device->SetVideoMode = EM85XXOSD_SetVideoMode;    device->CreateYUVOverlay = NULL;    device->SetColors = EM85XXOSD_SetColors;    device->VideoQuit = EM85XXOSD_VideoQuit;#ifdef _LITE_VERSION    device->RequestHWSurface = NULL;#endif    device->AllocHWSurface = EM85XXOSD_AllocHWSurface;    device->CheckHWBlit = NULL;    device->FillHWRect = NULL;    device->SetHWColorKey = NULL;    device->SetHWAlpha = NULL;    device->FreeHWSurface = EM85XXOSD_FreeHWSurface;    device->UpdateRects = EM85XXOSD_UpdateRects;    device->free = EM85XXOSD_DeleteDevice;    return device;}VideoBootStrap EM85XXOSD_bootstrap = {    EM85XXOSDVID_DRIVER_NAME, "EM85xx OSD video driver",    EM85XXOSD_Available, EM85XXOSD_CreateDevice};static int EM85XXOSD_VideoInit(_THIS, GAL_PixelFormat *vformat){    unsigned long flicker;    RUA_handle h;    OSDBuffer osdbuffer;	Wnd_type Wnd;	evOutputDevice_type OutputDevice;	evTvStandard_type TvStandard;	evTvOutputFormat_type TvOutputFormat;    fprintf (stderr, "NEWGAL EM85xxOSD WARNING: You are using the EM85xx OSD video driver!\n");    if ((h = RUA_OpenDevice (0)) == -1) {        fprintf (stderr, "NEWGAL EM85xxOSD engine: Fatal error: can't open kernel module\n");        return -1;    }    /* set the tv output to be ntsc */	Wnd.x = 0;	Wnd.y = 0;	Wnd.w = 720;	Wnd.h = 480;	TvStandard = evTvStandard_NTSC;	TvOutputFormat = evTvOutputFormat_COMPOSITE;	OutputDevice = evOutputDevice_TV;	RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evTvOutputFormat, sizeof(TvOutputFormat), &TvOutputFormat);	RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evTvStandard, sizeof(TvStandard), &TvStandard);	RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evOutputDevice, sizeof(OutputDevice), &OutputDevice);	RUA_DECODER_SET_PROPERTY (h, VIDEO_SET, evDestinationWindow, sizeof(Wnd), &Wnd);    /* XXX If we need to we can mmap the osdbuf from the device */    this->hidden->handle = h;    if (RUA_OSDFB_REFRESH (this->hidden->handle, &osdbuffer) != 0) {        fprintf (stderr, "NEWGAL EM85xxOSD engine: Error getting the OSD buffer.\n");        goto fail;    } else {        this->hidden->osd_buffer = osdbuffer.framebuffer;        this->hidden->w = osdbuffer.width;        this->hidden->h = osdbuffer.height;        this->hidden->pitch = osdbuffer.width;        this->hidden->fb = osdbuffer.framebuffer + 8 + 1024;    }        if (osdbuffer.bpp != 8) {        GAL_SetError ("NEWGAL EM85xxOSD engine: Not supported depth: %d.\n", vformat->BitsPerPixel);        return -1;    }    /* 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 (this->hidden->handle, DECODER_SET, edecOsdFlicker, sizeof(flicker), &flicker);    /*      * set the osd window destination     * do not scale - just center the image     */    Wnd.x = (720 - osdbuffer.width) / 2;    Wnd.y = (480 - osdbuffer.height) / 2;    Wnd.w = osdbuffer.width;    Wnd.h = osdbuffer.height;    RUA_DECODER_SET_PROPERTY (h, OSD_SET, eOsdDestinationWindow, sizeof(Wnd), &Wnd);    vformat->BitsPerPixel = 8;    vformat->BytesPerPixel = 1;    vformat->Rmask = 0xE0;    vformat->Gmask = 0x1C;    vformat->Bmask = 0x03;    this->hidden->status = 2;    this->hidden->dirty = FALSE;    /* We're done! */    return(0);fail:    return -1;}static GAL_Rect **EM85XXOSD_ListModes(_THIS, GAL_PixelFormat *format, Uint32 flags){    return (GAL_Rect **) -1;}static GAL_Surface *EM85XXOSD_SetVideoMode(_THIS, GAL_Surface *current,                int width, int height, int bpp, Uint32 flags){    /* Set up the new mode framebuffer */    current->flags = GAL_HWSURFACE | GAL_FULLSCREEN | GAL_HWPALETTE;    current->w = this->hidden->w;    current->h = this->hidden->h;    current->pitch = this->hidden->pitch;    current->pixels = this->hidden->fb;    if (!GAL_ReallocFormat (current, 8, 0, 0, 0, 0) ) {        return (NULL);    }    clone (task_do_update, stack_updater + 512, CLONE_VM | CLONE_FS | CLONE_FILES, this);    /* We're done */    return (current);}/* We don't actually allow hardware surfaces other than the main one */static int EM85XXOSD_AllocHWSurface(_THIS, GAL_Surface *surface){    return(-1);}static void EM85XXOSD_FreeHWSurface(_THIS, GAL_Surface *surface){    surface->pixels = NULL;}#define START       0#define END         65536#define PRECISION   20/* This trick transform [0..255] range into [0..65535] range (instead of about 0..255*256) */#define RANGE8TO16(x) (((x)<<8)|(x))// see video demystified page 43static void gammacorrectedrgbtoyuv (Uint16 R, Uint16 G, Uint16 B, Uint16 *y, Uint16 *u, Uint16 *v){    long yraw, uraw, vraw;        yraw = ( 257*R  +504*G + 98*B)/1000 + RANGE8TO16(16);    uraw = (-148*R  -291*G +439*B)/1000 + RANGE8TO16(128);    vraw = ( 439*R  -368*G - 71*B)/1000 + RANGE8TO16(128);    /* Obviously the computation of yraw garantees >= RANGE8TO16(16) ;-)       This is also true for uraw and vraw */        *y = MAX(MIN(yraw,RANGE8TO16(235)),RANGE8TO16(16));     *u = MAX(MIN(uraw,RANGE8TO16(240)),RANGE8TO16(16));    *v = MAX(MIN(vraw,RANGE8TO16(240)),RANGE8TO16(16));}static int EM85XXOSD_SetColors(_THIS, int first, int count, GAL_Color *palette){    int         i;    Uint8*      pal = this->hidden->osd_buffer + 8;    GAL_Color*  p;    /* convert palette to quasar format*/    pal += first * 4;    p = palette;    for (i = first; i < (first + count); i++) {        Uint16 Y, U, V;        Uint16 R, G, B;        /* RGB->YUVe computation. */        R = RANGE8TO16 (p->r);        G = RANGE8TO16 (p->g);        B = RANGE8TO16 (p->b);        gammacorrectedrgbtoyuv (R, G, B, &Y, &U, &V);        /* hardcode alpha blending values */        if (i == 0)            pal[0] = 0x00;        else if (i == 6)            pal[0] = 0x66;        else if (i == 15)            pal[0] = 0x80;        else if (i == 242)            pal[0] = 0x80;        else            pal[0] = 0xff;        pal[1] = (Uint8)(Y >> 8);        pal[2] = (Uint8)(U >> 8);        pal[3] = (Uint8)(V >> 8);        pal += 4;        p ++;    }    return 0;}static void EM85XXOSD_UpdateRects (_THIS, int numrects, GAL_Rect *rects){    this->hidden->dirty = TRUE;}static void EM85XXOSD_VideoQuit(_THIS){    if (this->hidden->status != 2)        return;    this->hidden->status = 1;    RUA_ReleaseDevice (this->hidden->handle);    return;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?