📄 qgfxsnap_qws.cpp
字号:
} } // Indicate that we have done an accelerated drawing function, so that // software rendering code will need to do a sync() before accessing // video memory. (*optype) = OPTYPE_ACCEL; // Clean up and exit GFX_END; QWSDisplay::ungrab();}/*!This is called to copy a bitmap from one place to another. We try and perform the blitin hardware if possible.// TODO: This function I believe will handle color bitmap blits of// different color depths from system memory!! Below are the variables that driver// this...srcbitssrclinestepsrcdepthsrcwidthsrcheight*/template<const int depth,const int type>inline void QGfxSNAP<depth,type>::blt( int left, int top, int width, int height, int srcLeft, int srcTop){ // Check that it is not trivially clipped if (ncliprect < 1) return; // Punt to the scroll function if the blit is within the same surface! if (srcbits == buffer) { QGfxRaster<depth,type>::scroll(left,top,width,height,srcLeft,srcTop); return; } // Punt to software for stuff we do not support if (alphatype != IgnoreAlpha || srctype == SourcePen) { QGfxRaster<depth,type>::blt(left,top,width,height,srcLeft,srcTop); return; } if (srcdepth != 8 && srcdepth != 16 && srcdepth != 24 && srcdepth != 32) { QGfxRaster<depth,type>::blt(left,top,width,height,srcLeft,srcTop); return; } // Check that the buffers are in hardware, punting to software if not if (!checkSourceDest()) { QGfxRaster<depth,type>::blt(left,top,width,height,srcLeft,srcTop); return; } // Setup pixel coordinates and loop variables left += xoffs; top += yoffs; srcLeft += srcwidgetoffs.x(); srcTop += srcwidgetoffs.y(); int right = left + width - 1; int bottom = top + height - 1; int mix = mixTable[myrop]; int i,numrects = ncliprect; // Get exclusive write access to the display and get ready for drawing QWSDisplay::grab(true); GFX_START(QRect(left, top, width+1, height+1)); // Set the required hardware state if is has changed if (memcmp(&cntState->drawBuf,&drawBuf,sizeof(drawBuf)) != 0) { cntState->drawBuf = drawBuf; state2d.SetDrawBuffer(&drawBuf); } // Now clip the blit to each clip rectangle do the blit for (i = 0; i < numrects; i++) { QRect clip(cliprect[i]); if (left <= clip.right() && top <= clip.bottom() && right >= clip.left() && bottom >= clip.top()) { int so = srcOffset; int sl = srclinestep; int clipLeft = clip.left() > left ? clip.left() : left; int clipTop = clip.top() > top ? clip.top() : top; int clipRight = clip.right() > right ? right : clip.right(); int clipBottom = clip.bottom() > bottom ? bottom : clip.bottom(); int clipSrcLeft = srcLeft + (clipLeft - left); int clipSrcTop = srcTop + (clipTop - top); draw2d.BitBltLin(so,sl,clipSrcLeft,clipSrcTop,(clipRight-clipLeft)+1,(clipBottom-clipTop)+1,clipLeft,clipTop,mix); } } // Indicate that we have done an accelerated drawing function, so that // software rendering code will need to do a sync() before accessing // video memory. (*optype) = OPTYPE_ACCEL; // Clean up and exit GFX_END; QWSDisplay::ungrab();}/*!Function to handle drawing a line from (x1,y1) to (x2,y2)*/template<const int depth,const int type>void QGfxSNAP<depth,type>::drawLine( int x1, int y1, int x2, int y2){ // Check to see if we can trivially reject the blit if (ncliprect < 1) return; // We only handle solid lines in here if (cpen.style() != SolidLine) { QGfxRaster<depth,type>::drawLine(x1,y1,x2,y2); return; } // Check that the buffer is a hardware buffer, punting to software if not if (!checkDest()) { QGfxRaster<depth,type>::drawLine(x1,y1,x2,y2); return; } // Compute line coordinates and deltas x1 += xoffs; y1 += yoffs; x2 += xoffs; y2 += yoffs; int dx = abs(x2-x1); int dy = abs(y2-y1); // Get exclusive write access to the display and get ready for drawing QWSDisplay::grab(true); GFX_START(QRect(x1, y1 < y2 ? y1 : y2, dx+1, QABS(dy)+1)); // Set the required hardware state if is has changed if (memcmp(&cntState->drawBuf,&drawBuf,sizeof(drawBuf)) != 0) { cntState->drawBuf = drawBuf; state2d.SetDrawBuffer(&drawBuf); } if (mixTable[myrop] != cntState->mix) state2d.SetMix(cntState->mix = mixTable[myrop]); usePen(); if (pixel != cntState->foreColor) state2d.SetForeColor(cntState->foreColor = pixel); // Draw the line clipped to all clip rectangles int i,numrects = ncliprect; for (i = 0; i < numrects; i++) { QRect *clip = &cliprect[i]; draw2d.DrawClippedLineInt(x1,y1,x2,y2,true,clip->left(),clip->top(),clip->right()+1,clip->bottom()+1); } // Indicate that we have done an accelerated drawing function, so that // software rendering code will need to do a sync() before accessing // video memory. (*optype) = OPTYPE_ACCEL; // Clean up and exit GFX_END; QWSDisplay::ungrab();}/*!This is called by the software renderer when it's about to drawsomething - it needs to be sure that the hardware engine has finisheddrawing since otherwise the two graphics operations could collide*/template<const int depth,const int type>void QGfxSNAP<depth,type>::sync(){ if (hwState2d.WaitTillIdle) hwState2d.WaitTillIdle();}/*!\fn QSNAPScreen::QSNAPScreen( int display_id )Constructs a QSNAPScreen; passes \a display_id to the QScreenconstructor.*/QSNAPScreen::QSNAPScreen( int display_id ) : QScreen( display_id ), stateBuf(NULL), dc(NULL), unloadRef2d(false){}/*!\fn QSNAPScreen::~QSNAPScreen()Destroys a QSNAPScreen.*/QSNAPScreen::~QSNAPScreen(){}/*!Internal function called to clean up on fatal errors so that the console anddisplay mode will be properly restored.*/void QSNAPScreen::fatalCleanup(){ if (stateBuf) { PM_restoreConsoleState(stateBuf,hwndConsole); PM_closeConsole(hwndConsole); free(stateBuf); } if (dc) GA_unloadDriver(dc);}/*!\fn N_uint16 QSNAPScreen::findMode()Internal function to search for a particular display mode to see if it issupported by the SNAP drivers.*/N_uint16 QSNAPScreen::findMode( int x, int y, int bits){ GA_modeInfo modeInfo; N_uint16 *modes; // Find the SNAP display mode that matches what we want for (modes = dc->AvailableModes; *modes != 0xFFFF; modes++) { modeInfo.dwSize = sizeof(modeInfo); if (init.GetVideoModeInfo(*modes,&modeInfo) != 0) continue; if (modeInfo.Attributes & gaIsTextMode) continue; if ((!modeInfo.Attributes & gaHaveLinearBuffer)) continue; if (modeInfo.BitsPerPixel == 15) { // Qt Embedded does not appear to support 15bpp modes!! continue; } if (modeInfo.XResolution == x && modeInfo.YResolution == y && modeInfo.BitsPerPixel == bits) return *modes | gaLinearBuffer; } return 0xFFFF;}/*!Main function to initialise the software rasteriser module and the internallibrary helper functions.*/int QSNAPScreen::initSoftwareRasterizer(void){ GA_buffer drawBuf; // Load and initialsie the software rasteriser module memset(&state2d,0,sizeof(state2d)); memset(&draw2d,0,sizeof(draw2d)); unloadRef2d = false; if ((ref2d = GA_getCurrentRef2d(dc->DeviceIndex)) == NULL) { unloadRef2d = true; if (!GA_loadRef2d(dc,true,&modeInfo,-1,&ref2d)) return false; } hwState2d.dwSize = sizeof(hwState2d); GA_queryFunctions(dc,GA_GET_2DSTATEFUNCS,&hwState2d); hwDraw2d.dwSize = sizeof(hwDraw2d); GA_queryFunctions(dc,GA_GET_2DRENDERFUNCS,&hwDraw2d); driver.dwSize = sizeof(driver); REF2D_queryFunctions(ref2d,GA_GET_DRIVERFUNCS,&driver); state2d.dwSize = sizeof(state2d); REF2D_queryFunctions(ref2d,GA_GET_2DSTATEFUNCS,&state2d); draw2d.dwSize = sizeof(draw2d); REF2D_queryFunctions(ref2d,GA_GET_2DRENDERFUNCS,&draw2d); // Make the primary display active for drawing for the server instance if (isServer) { drawBuf.dwSize = sizeof(drawBuf); drawBuf.Offset = 0; drawBuf.Stride = modeInfo.BytesPerScanLine; drawBuf.Width = modeInfo.XResolution; drawBuf.Height = modeInfo.YResolution; if (ref2d->SetDrawBuffer(&drawBuf,dc->LinearMem,modeInfo.BitsPerPixel,&modeInfo.PixelFormat,dc,false) != 0) return false; } return true;}/*!Sets the framebuffer to a new resolution and bit depth. The width isin \a nw, the height is in \a nh, and the depth is \a nd. After doingthis any currently-existing gfx's will be invalid and the screenshould be completely redrawn. In a multiple-process Embedded Qtsituation you will need to signal all other applications to do asetMode and then a redraw.*/void QSNAPScreen::setMode( int x, int y, int bits){ // Find the SNAP display mode that matches what we want if ((cntMode = findMode(x,y,bits)) == 0xFFFF) { fatalCleanup(); qFatal("Unable to find matching SNAP display mode (%dx%dx%d)!", x,y,bits); } // Now initialise the display mode, but only do this for the server instance! if (isServer) { N_int32 virtualX,virtualY,bytesPerLine; virtualX = virtualY = bytesPerLine = -1; if (init.SetVideoMode(cntMode,&virtualX,&virtualY,&bytesPerLine,&maxMem,0,NULL) != 0) { fatalCleanup(); qFatal("Unable to set SNAP display mode!"); } } // Get the current display mode information modeInfo.dwSize = sizeof(modeInfo); init.GetCurrentVideoModeInfo(&modeInfo); // Load and initialsie the software rasteriser module if (!initSoftwareRasterizer()) { fatalCleanup(); qFatal("Unable to initialise software rasteriser!"); } // Now read in current color palette and initialize the // Qt screen color lookup table. if (modeInfo.BitsPerPixel <= 8) { GA_palette pal[256]; screencols = (modeInfo.BitsPerPixel == 8) ? 256 : 16; driver.GetPaletteData(pal,screencols,0); for (int i = 0; i < screencols; i++) screenclut[i] = qRgb(pal[i].Red,pal[i].Green,pal[i].Blue); } else screencols = 0; // Tell QScreen where to find the framebuffer. We need to do this again // *after* the mode set, as this may well change on some cards. mapsize = dc->LinearSize; data = (uchar*)dc->LinearMem; // Setup internal QScreen variables that are needed dw = w = modeInfo.XResolution; dh = h = modeInfo.YResolution; d = modeInfo.BitsPerPixel; lstep = modeInfo.BytesPerScanLine; size = h * lstep;}/*!This is called by Qt/Embedded clients to connect to the shared SNAP Graphics driver.The \a displaySpec parameter is ignored for SNAP Graphics.This function actually gets called *before* the initDevice() function. For thatreason we do much in the initDevice() function but instead do nearly everythingin here. We first check to see if the shared driver is already loaded, andif so we just connect to it. If it is not, then we go ahead and do extrasetup stuff that is only done when the Qt Embedded server starts up.*/bool QSNAPScreen::connect( const QString &){ // If this is the first instance to be loaded, initialise the server and grab // the console etc. if ((isServer = !GA_isSharedDriverLoaded()) != 0) { hwndConsole = PM_openConsole(0,0,640,480,8,true); if ((stateBuf = malloc(PM_getConsoleStateSize())) == NULL) qFatal("Out of memory!"); PM_saveConsoleState(stateBuf,hwndConsole); } // Now attempt to load the SNAP Graphics driver. This will load a shared copy // for the second application that is connecting to the server. if ((dc = GA_loadDriver(0,true)) == NULL) { qDebug("Unable to load the SciTech SNAP driver (%s)", GA_errorMsg(GA_status())); return FALSE; } init.dwSize = sizeof(init); if (!GA_queryFunctions(dc,GA_GET_INITFUNCS,&init)) { fatalCleanup(); qFatal("Unable to get device driver functions!"); } driver.dwSize = sizeof(driver); if (!GA_queryFunctions(dc,GA_GET_DRIVERFUNCS,&driver)) { fatalCleanup(); qFatal("Unable to get device driver functions!"); } dpms.dwSize = sizeof(dpms); if (!GA_queryFunctions(dc,GA_GET_DPMSFUNCS,&dpms)) { fatalCleanup(); qFatal("Unable to get DPMS functions!"); } // Detect if we have DPMS capabilities DPMSStates = 0; if (dpms.DPMSdetect) { dpms.DPMSdetect(&DPMSStates); if (!(DPMSStates & DPMS_off)) DPMSStates = 0; } // Do extra initialisation specific to the first or server instance if (isServer) prevMode = init.GetVideoMode(); // Set the default mode to 1024x768x16, scaling back to 800x600x16 then // 640x480x16 and finally 640x480x8. If the size is specified by the // QWS_SIZE environment variable, we will use that size instead. if (findMode(w = 1024,h = 768,d = 16) == 0xFFFF) { if (findMode(w = 800,h = 600,d = 16) == 0xFFFF) { if (findMode(w = 640,h = 480,d = 16) == 0xFFFF) { if (findMode(w = 640,h = 480,d = 8) == 0xFFFF) { fatalCleanup(); qFatal("Unable to find default display mode!"); } } } } const char* qwssize; if ((qwssize = getenv("QWS_SIZE")) != NULL) { // First try to get the resolution and color depth, and if that fails // just try to get the resolution without the color depth if (sscanf(qwssize,"%dx%dx%d",&w,&h,&d) != 3) sscanf(qwssize,"%dx%d",&w,&h); } // Now set the display mode setMode(w,h,d); // Setup up access to offscreen memory management variables setupOffScreen(); // Return success! initted = true; return TRUE;}/*!\fn bool QSNAPScreen::initDevice()This is called by the Qt/Embedded server at startup time. We don't
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -