⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qscreenlinuxfb_qws.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                 malloc(sizeof(unsigned short int)*screencols);        startcmap.green=(unsigned short int *)                   malloc(sizeof(unsigned short int)*screencols);        startcmap.blue=(unsigned short int *)                  malloc(sizeof(unsigned short int)*screencols);        startcmap.transp=(unsigned short int *)                    malloc(sizeof(unsigned short int)*screencols);        if (d_ptr->fd == -1 || ioctl(d_ptr->fd, FBIOGETCMAP, &startcmap)) {            perror("QLinuxFbScreen::connect");            qWarning("Error reading palette from framebuffer, using default palette");            createPalette(startcmap, vinfo, finfo);        }        int bits_used = 0;        for(loopc=0;loopc<screencols;loopc++) {            screenclut[loopc]=qRgb(startcmap.red[loopc] >> 8,                                   startcmap.green[loopc] >> 8,                                   startcmap.blue[loopc] >> 8);            bits_used |= startcmap.red[loopc]                         | startcmap.green[loopc]                         | startcmap.blue[loopc];        }        // WORKAROUND: Some framebuffer drivers only return 8 bit        // color values, so we need to not bit shift them..        if ((bits_used & 0x00ff) && !(bits_used & 0xff00)) {            for(loopc=0;loopc<screencols;loopc++) {                screenclut[loopc] = qRgb(startcmap.red[loopc],                                         startcmap.green[loopc],                                         startcmap.blue[loopc]);            }            qWarning("8 bits cmap returned due to faulty FB driver, colors corrected");        }        free(startcmap.red);        free(startcmap.green);        free(startcmap.blue);        free(startcmap.transp);    } else {        screencols=0;    }    return true;}/*!    \reimp    This unmaps the framebuffer.    \sa connect()*/void QLinuxFbScreen::disconnect(){    data -= dataoffset;    if (data)        munmap((char*)data,mapsize);    close(d_ptr->fd);}// #define DEBUG_VINFOvoid QLinuxFbScreen::createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo){    if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) {        screencols= (vinfo.bits_per_pixel==8) ? 256 : 16;        cmap.start=0;        cmap.len=screencols;        cmap.red=(unsigned short int *)                 malloc(sizeof(unsigned short int)*screencols);        cmap.green=(unsigned short int *)                   malloc(sizeof(unsigned short int)*screencols);        cmap.blue=(unsigned short int *)                  malloc(sizeof(unsigned short int)*screencols);        cmap.transp=(unsigned short int *)                    malloc(sizeof(unsigned short int)*screencols);        if (screencols==16) {            if (finfo.type == FB_TYPE_PACKED_PIXELS) {                // We'll setup a grayscale cmap for 4bpp linear                int val = 0;                for (int idx = 0; idx < 16; ++idx, val += 17) {                    cmap.red[idx] = (val<<8)|val;                    cmap.green[idx] = (val<<8)|val;                    cmap.blue[idx] = (val<<8)|val;                    screenclut[idx]=qRgb(val, val, val);                }            } else {                // Default 16 colour palette                // Green is now trolltech green so certain images look nicer                //                             black  d_gray l_gray white  red  green  blue cyan magenta yellow                unsigned char reds[16]   = { 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xA2, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x82 };                unsigned char greens[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0xC5, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F };                unsigned char blues[16]  = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0x11, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x7F, 0x00, 0x00 };                for (int idx = 0; idx < 16; ++idx) {                    cmap.red[idx] = ((reds[idx]) << 8)|reds[idx];                    cmap.green[idx] = ((greens[idx]) << 8)|greens[idx];                    cmap.blue[idx] = ((blues[idx]) << 8)|blues[idx];                    cmap.transp[idx] = 0;                    screenclut[idx]=qRgb(reds[idx], greens[idx], blues[idx]);                }            }        } else {            if (grayscale) {                // Build grayscale palette                int i;                for(i=0;i<screencols;++i) {                    int bval = screencols == 256 ? i : (i << 4);                    ushort val = (bval << 8) | bval;                    cmap.red[i] = val;                    cmap.green[i] = val;                    cmap.blue[i] = val;                    cmap.transp[i] = 0;                    screenclut[i] = qRgb(bval,bval,bval);                }            } else {                // 6x6x6 216 color cube                int idx = 0;                for(int ir = 0x0; ir <= 0xff; ir+=0x33) {                    for(int ig = 0x0; ig <= 0xff; ig+=0x33) {                        for(int ib = 0x0; ib <= 0xff; ib+=0x33) {                            cmap.red[idx] = (ir << 8)|ir;                            cmap.green[idx] = (ig << 8)|ig;                            cmap.blue[idx] = (ib << 8)|ib;                            cmap.transp[idx] = 0;                            screenclut[idx]=qRgb(ir, ig, ib);                            ++idx;                        }                    }                }                // Fill in rest with 0                for (int loopc=0; loopc<40; ++loopc) {                    screenclut[idx]=0;                    ++idx;                }                screencols=idx;            }        }    } else if(finfo.visual==FB_VISUAL_DIRECTCOLOR) {        cmap.start=0;        int rbits=0,gbits=0,bbits=0;        switch (vinfo.bits_per_pixel) {        case 8:            rbits=vinfo.red.length;            gbits=vinfo.green.length;            bbits=vinfo.blue.length;            if(rbits==0 && gbits==0 && bbits==0) {                // cyber2000 driver bug hack                rbits=3;                gbits=3;                bbits=2;            }            break;        case 15:            rbits=5;            gbits=5;            bbits=5;            break;        case 16:            rbits=5;            gbits=6;            bbits=5;            break;        case 18:        case 19:            rbits=6;            gbits=6;            bbits=6;            break;        case 24: case 32:            rbits=gbits=bbits=8;            break;        }        screencols=cmap.len=1<<qMax(rbits,qMax(gbits,bbits));        cmap.red=(unsigned short int *)                 malloc(sizeof(unsigned short int)*256);        cmap.green=(unsigned short int *)                   malloc(sizeof(unsigned short int)*256);        cmap.blue=(unsigned short int *)                  malloc(sizeof(unsigned short int)*256);        cmap.transp=(unsigned short int *)                    malloc(sizeof(unsigned short int)*256);        for(unsigned int i = 0x0; i < cmap.len; i++) {            cmap.red[i] = i*65535/((1<<rbits)-1);            cmap.green[i] = i*65535/((1<<gbits)-1);            cmap.blue[i] = i*65535/((1<<bbits)-1);            cmap.transp[i] = 0;        }    }}/*!    \reimp    This is called by the \l {Qtopia Core} server at startup time. It turns    off console blinking, sets up the color palette, enables write    combining on the framebuffer and initialises the off-screen memory    manager.*/bool QLinuxFbScreen::initDevice(){    d_ptr->openTty();    // Grab current mode so we can reset it    fb_var_screeninfo vinfo;    fb_fix_screeninfo finfo;    //#######################    // Shut up Valgrind    memset(&vinfo, 0, sizeof(vinfo));    memset(&finfo, 0, sizeof(finfo));    //#######################    if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {        perror("QLinuxFbScreen::initDevice");        qFatal("Error reading variable information in card init");        return false;    }#ifdef DEBUG_VINFO    qDebug("Greyscale %d",vinfo.grayscale);    qDebug("Nonstd %d",vinfo.nonstd);    qDebug("Red %d %d %d",vinfo.red.offset,vinfo.red.length,           vinfo.red.msb_right);    qDebug("Green %d %d %d",vinfo.green.offset,vinfo.green.length,           vinfo.green.msb_right);    qDebug("Blue %d %d %d",vinfo.blue.offset,vinfo.blue.length,           vinfo.blue.msb_right);    qDebug("Transparent %d %d %d",vinfo.transp.offset,vinfo.transp.length,           vinfo.transp.msb_right);#endif    d_ptr->startupw=vinfo.xres;    d_ptr->startuph=vinfo.yres;    d_ptr->startupd=vinfo.bits_per_pixel;    grayscale = vinfo.grayscale;    if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) {        perror("QLinuxFbScreen::initDevice");        qCritical("Error reading fixed information in card init");        // It's not an /error/ as such, though definitely a bad sign        // so we return true        return true;    }#ifdef __i386__    // Now init mtrr    if(!::getenv("QWS_NOMTRR")) {        int mfd=open("/proc/mtrr",O_WRONLY,0);        // MTRR entry goes away when file is closed - i.e.        // hopefully when QWS is killed        if(mfd != -1) {            mtrr_sentry sentry;            sentry.base=(unsigned long int)finfo.smem_start;            //qDebug("Physical framebuffer address %p",(void*)finfo.smem_start);            // Size needs to be in 4k chunks, but that's not always            // what we get thanks to graphics card registers. Write combining            // these is Not Good, so we write combine what we can            // (which is not much - 4 megs on an 8 meg card, it seems)            unsigned int size=finfo.smem_len;            size=size >> 22;            size=size << 22;            sentry.size=size;            sentry.type=MTRR_TYPE_WRCOMB;            if(ioctl(mfd,MTRRIOC_ADD_ENTRY,&sentry)==-1) {                //printf("Couldn't add mtrr entry for %lx %lx, %s\n",                //sentry.base,sentry.size,strerror(errno));            }        }    }#endif    if ((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4) || (finfo.visual==FB_VISUAL_DIRECTCOLOR))    {        fb_cmap cmap;        createPalette(cmap, vinfo, finfo);        if (ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap)) {            perror("QLinuxFbScreen::initDevice");            qWarning("Error writing palette to framebuffer");        }        free(cmap.red);        free(cmap.green);        free(cmap.blue);        free(cmap.transp);    }    canaccel=useOffscreen();    if(mapsize-size<16384) {        canaccel=false;    }    if(canaccel) {        setupOffScreen();        *entryp=0;        *lowest=mapsize;        insert_entry(*entryp,*lowest,*lowest);  // dummy entry to mark start    }    shared->fifocount=0;    shared->buffer_offset=0xffffffff;  // 0 would be a sensible offset (screen)    shared->linestep=0;    shared->cliptop=0xffffffff;    shared->clipleft=0xffffffff;    shared->clipright=0xffffffff;    shared->clipbottom=0xffffffff;    shared->rop=0xffffffff;#ifdef QT_QWS_DEPTH_GENERIC    if (pixelFormat() == QImage::Format_Invalid && screencols == 0        && d_ptr->doGenericColors)    {        qt_set_generic_blit(this, vinfo.bits_per_pixel,                            vinfo.red.length, vinfo.green.length,                            vinfo.blue.length, vinfo.transp.length,                            vinfo.red.offset, vinfo.green.offset,                            vinfo.blue.offset, vinfo.transp.offset);    }#endif#ifndef QT_NO_QWS_CURSOR    QScreenCursor::initSoftwareCursor();#endif    return true;}/*  The offscreen memory manager's list of entries is stored at the bottom  of the offscreen memory area and consistes of a series of QPoolEntry's,  each of which keep track of a block of allocated memory. Unallocated memory  is implicitly indicated by the gap between blocks indicated by QPoolEntry's.  The memory manager looks through any unallocated memory before the end  of currently-allocated memory to see if a new block will fit in the gap;  if it doesn't it allocated it from the end of currently-allocated memory.  Memory is allocated from the top of the framebuffer downwards; if it hits  the list of entries then offscreen memory is full and further allocations  are made from main RAM (and hence unaccelerated). Allocated memory can  be seen as a sort of upside-down stack; lowest keeps track of the  bottom of the stack.*/void QLinuxFbScreen::delete_entry(int pos){    if (pos>*entryp || pos<0) {        qDebug("Attempt to delete odd pos! %d %d",pos,*entryp);        return;    }#ifdef DEBUG_CACHE    qDebug("Remove entry: %d", pos);#endif    QPoolEntry *qpe = &entries[pos];    if (qpe->start <= *lowest) {        // Lowest goes up again        *lowest = entries[pos-1].start;#ifdef DEBUG_CACHE        qDebug("   moved lowest to %d", *lowest);#endif    }    (*entryp)--;    if (pos == *entryp)        return;    int size = (*entryp)-pos;    memmove(&entries[pos], &entries[pos+1], size*sizeof(QPoolEntry));}void QLinuxFbScreen::insert_entry(int pos,int start,int end){    if (pos > *entryp) {        qDebug("Attempt to insert odd pos! %d %d",pos,*entryp);        return;    }#ifdef DEBUG_CACHE    qDebug("Insert entry: %d, %d -> %d", pos, start, end);#endif    if (start < (int)*lowest) {        *lowest = start;#ifdef DEBUG_CACHE        qDebug("    moved lowest to %d", *lowest);#endif    }    if (pos==*entryp) {        entries[pos].start=start;        entries[pos].end=end;        entries[pos].clientId=qws_client_id;        (*entryp)++;        return;    }    int size=(*entryp)-pos;    memmove(&entries[pos+1],&entries[pos],size*sizeof(QPoolEntry));    entries[pos].start=start;    entries[pos].end=end;    entries[pos].clientId=qws_client_id;    (*entryp)++;}/*!    \fn uchar * QLinuxFbScreen::cache(int amount)    Requests the specified \a amount of offscreen graphics card memory    from the memory manager, and returns a pointer to the data within    the framebuffer (or 0 if there is no free memory).    Note that the display is locked while memory is allocated in order to    preserve the memory pool's integrity.    Use the QScreen::onCard() function to retrieve an offset (in    bytes) from the start of graphics card memory for the returned    pointer.

⌨️ 快捷键说明

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