void ResourceResponse::platformLazyInit(InitLevel initLevel) { if (m_initLevel > initLevel) return; if (m_isNull || !m_cfResponse.get()) return; if (m_initLevel < CommonFieldsOnly && initLevel >= CommonFieldsOnly) { m_url = CFURLResponseGetURL(m_cfResponse.get()); m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get()); m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get()); m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get()); // Workaround for <rdar://problem/8757088>, can be removed once that is fixed. unsigned textEncodingNameLength = m_textEncodingName.length(); if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"') m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2); m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get())); CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get()); if (httpResponse) { m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse); RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse)); for (int i = 0; i < numCommonHeaderFields; i++) { CFStringRef value; if (CFDictionaryGetValueIfPresent(headers.get(), commonHeaderFields[i], (const void **)&value)) m_httpHeaderFields.set(commonHeaderFields[i], value); } } else m_httpStatusCode = 0; } if (m_initLevel < CommonAndUncommonFields && initLevel >= CommonAndUncommonFields) { CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get()); if (httpResponse) { RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse)); m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(statusLine.get()); RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse)); CFIndex headerCount = CFDictionaryGetCount(headers.get()); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); } } if (m_initLevel < AllFields && initLevel >= AllFields) { RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get())); m_suggestedFilename = suggestedFilename.get(); } m_initLevel = initLevel; }
/**************************************************************************** PARAMETERS: dc - Display dc trans - Turn on/off transparent blitting REMARKS: Demo showing how to use memory dc's to store sprites and to use blit them from the memory dc to the display dc. ****************************************************************************/ ibool systemBlit( MGLDC *dc, ibool trans) { color_t transparent; palette_t pal[256]; int oldCheckId; MGLDC *memdc; /* Display title message at the top of the window. */ if (trans) mainWindow(dc,"System Memory 8bpp Transparent Blit Demo"); else mainWindow(dc,"System Memory 8bpp Blit Demo"); statusLine("Press any key to continue, ESC to Abort"); /* Create a memory device context */ if ((memdc = MGL_createMemoryDC(bmpWidth,bmpHeight,bmpDepth,&bmpPF)) == NULL) MGL_fatalError(MGL_errorMsg(MGL_result())); /* Load a bitmap into the memory device context. The palette gets * loaded into the memory device context as well. */ if (!MGL_loadBitmapIntoDC(memdc,IMAGE_NAME,0,0,true)) MGL_fatalError(MGL_errorMsg(MGL_result())); /* Set the display device context with the palette from the * memory device context. */ MGL_getPalette(memdc,pal,MGL_getPaletteSize(memdc),0); MGL_setPalette(dc,pal,MGL_getPaletteSize(memdc),0); MGL_realizePalette(dc,MGL_getPaletteSize(memdc),0,true); oldCheckId = MGL_checkIdentityPalette(false); /* Get transparent color from pixel (0,0) */ MGL_makeCurrentDC(memdc); transparent = MGL_realColor(dc,MGL_getPixelCoord(0,0)); MGL_makeCurrentDC(dc); /* Copy image from image in memory to the screen. */ while (!checkEvent()) { if (trans) MGL_srcTransBltCoord(dc,memdc,0,0,bmpWidth,bmpHeight,MGL_random(maxx-bmpWidth),MGL_random(maxy-bmpHeight),transparent,MGL_REPLACE_MODE); else MGL_bitBltCoord(dc,memdc,0,0,bmpWidth,bmpHeight,MGL_random(maxx-bmpWidth),MGL_random(maxy-bmpHeight),MGL_REPLACE_MODE); } /* Remove all device contexts from memory. */ MGL_destroyDC(memdc); MGL_checkIdentityPalette(oldCheckId); MGL_setDefaultPalette(dc); return pause(); }
bool SignalHandler::handleProcessExit(EventRecord &ev, bool &continueHint) { bool ret = false; process *proc = ev.proc; if (ev.status == statusNormal) { sprintf(errorLine, "Process %d has terminated with code 0x%x\n", proc->getPid(), (int) ev.what); statusLine(errorLine); #if defined(os_windows) // on the unixes we do this at syscall exit() proc->triggerNormalExitCallback(ev.what); #endif ret = proc->handleProcessExit(); } else if (ev.status == statusSignalled) { sprintf(errorLine, "process %d has terminated on signal %d\n", proc->getPid(), (int) ev.what); logLine(errorLine); statusLine(errorLine); printDyninstStats(); // The process is gone at this point; we just have a return code. // So handle the exit _before_ we do the user-level callback, as // it sets state appropriately. ret = proc->handleProcessExit(); proc->triggerSignalExitCallback(ev.what); } else { sprintf(errorLine, "process %d has terminated for unknown reason\n", proc->getPid()); logLine(errorLine); ret = proc->handleProcessExit(); //ret = true; // maybe this should be false? (this case is an error) } handleProcessExitPlat(ev, continueHint); flagBPatchStatusChange(); continueHint = false; return ret; }
ibool polyDemo(MGLDC *dc) /**************************************************************************** * * Function: polyDemo * Parameters: dc - Device context * * Description: Display a random pattern of polygons on the screen with * random fill styles. * ****************************************************************************/ { int i,maxx,maxy,val; fxpoint_t poly[MAXPTS]; /* Space to hold polygon data */ mainWindow(dc,"MGL_fillPolygon Demonstration"); statusLine("Press any key to continue, ESC to Abort"); maxx = MGL_maxx(); maxy = MGL_maxy(); while (!checkEvent()) { /* Define a random polygon */ for (i = 0; i < MAXPTS; i++) { poly[i].x = MGL_randoml(MGL_TOFIX(maxx)); poly[i].y = MGL_randoml(MGL_TOFIX(maxy)); } MGL_setColor(randomColor()); MGL_setBackColor(randomColor()); if ((val = MGL_random(3)) == 0) { MGL_setPenStyle(MGL_BITMAP_TRANSPARENT); MGL_setPenBitmapPattern(0,&bitpat[MGL_random(NUMPATS)+1]); MGL_usePenBitmapPattern(0); } else if (val == 1) { MGL_setPenStyle(MGL_BITMAP_OPAQUE); MGL_setPenBitmapPattern(0,&bitpat[MGL_random(NUMPATS)+1]); MGL_usePenBitmapPattern(0); } else { MGL_setPenStyle(MGL_BITMAP_SOLID); } MGL_fillPolygonFX(MAXPTS,poly,sizeof(fxpoint_t),0,0); } defaultAttributes(dc); return pause(); }
/**************************************************************************** PARAMETERS: dc - Display dc trans - Turn on/off transparent blitting REMARKS: Demo showing how to use offscreen dc's to store sprites and to use hardware acceleration to blt them from the offscreen dc to the display dc. ****************************************************************************/ ibool offscreenBlit( MGLDC *dc, ibool trans) { MGLDC *offdc; color_t transparent; palette_t pal[256]; /* Display title message at the top of the window. */ if (trans) mainWindow(dc,"Offscreen Memory Accelerated Transparent Blit Demo"); else mainWindow(dc,"Offscreen Memory Accelerated Blit Demo"); statusLine("Press any key to continue, ESC to Abort"); if ((offdc = MGL_createOffscreenDC(dc,bmpWidth,bmpHeight)) == NULL) { gprintf("Hardware accelerated blit not available."); } else { /* Load a bitmap into the offscreen device context */ if (!MGL_loadBitmapIntoDC(offdc,IMAGE_NAME,0,0,true)) MGL_fatalError(MGL_errorMsg(MGL_result())); /* Set the display device context with the palette from the * offscreen device context. */ if (MGL_getBitsPerPixel(dc) <= 8) { MGL_getPalette(offdc,pal,MGL_getPaletteSize(offdc),0); MGL_setPalette(dc,pal,MGL_getPaletteSize(offdc),0); MGL_realizePalette(dc,MGL_getPaletteSize(offdc),0,true); } /* Get transparent color from pixel (0,0) */ MGL_makeCurrentDC(offdc); transparent = MGL_getPixelCoord(0,0); MGL_makeCurrentDC(dc); /* Copy image from offscreen video memory to the screen. */ while (!checkEvent()) { if (trans) MGL_srcTransBltCoord(dc,offdc,0,0,bmpWidth,bmpHeight,MGL_random(maxx-bmpWidth),MGL_random(maxy-bmpHeight),transparent,MGL_REPLACE_MODE); else MGL_bitBltCoord(dc,offdc,0,0,bmpWidth,bmpHeight,MGL_random(maxx-bmpWidth),MGL_random(maxy-bmpHeight),MGL_REPLACE_MODE); } } /* Remove all device contexts from memory. */ MGL_destroyDC(offdc); return pause(); }
void ResourceResponse::platformLazyInit() { if (m_isUpToDate) return; m_isUpToDate = true; if (m_isNull) { ASSERT(!m_cfResponse.get()); return; } // FIXME: We may need to do MIME type sniffing here (unless that is done in CFURLResponseGetMIMEType). m_url = CFURLResponseGetURL(m_cfResponse.get()); m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get()); m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get()); m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get()); m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get())); RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get())); m_suggestedFilename = suggestedFilename.get(); CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get()); if (httpResponse) { m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse); RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse)); String statusText(statusLine.get()); int spacePos = statusText.find(' '); // Remove the status code from the status text. spacePos = statusText.find(' ', spacePos + 1); statusText = statusText.substring(spacePos + 1); m_httpStatusText = statusText; RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse)); CFIndex headerCount = CFDictionaryGetCount(headers.get()); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); } else m_httpStatusCode = 0; }
void ResourceResponse::platformLazyInit() { if (m_isUpToDate) return; m_isUpToDate = true; if (m_isNull) { ASSERT(!m_cfResponse.get()); return; } // FIXME: We may need to do MIME type sniffing here (unless that is done in CFURLResponseGetMIMEType). m_url = CFURLResponseGetURL(m_cfResponse.get()); m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get()); m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get()); m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get()); // Workaround for <rdar://problem/8757088>, can be removed once that is fixed. unsigned textEncodingNameLength = m_textEncodingName.length(); if (textEncodingNameLength >= 2 && m_textEncodingName[0U] == '"' && m_textEncodingName[textEncodingNameLength - 1] == '"') m_textEncodingName = m_textEncodingName.substring(1, textEncodingNameLength - 2); m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get())); RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get())); m_suggestedFilename = suggestedFilename.get(); CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get()); if (httpResponse) { m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse); RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse)); m_httpStatusText = extractReasonPhraseFromHTTPStatusLine(statusLine.get()); RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse)); CFIndex headerCount = CFDictionaryGetCount(headers.get()); Vector<const void*, 128> keys(headerCount); Vector<const void*, 128> values(headerCount); CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data()); for (int i = 0; i < headerCount; ++i) m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]); } else m_httpStatusCode = 0; }
ibool fastPolyDemo(MGLDC *dc) /**************************************************************************** * * Function: fastPolyDemo * Parameters: dc - Device context * * Description: Display a random pattern of convex triangular polygons * in replace mode at full speed. * ****************************************************************************/ { int maxx,maxy; fxpoint_t poly[4]; /* Space to hold polygon data */ mainWindow(dc,"MGL_fillPolygonFast Demonstration"); statusLine("Press any key to continue, ESC to Abort"); maxx = MGL_maxx(); maxy = MGL_maxy(); while (!checkEvent()) { /* Define a random polygon */ poly[0].x = MGL_randoml(MGL_TOFIX(maxx)); poly[0].y = MGL_randoml(MGL_TOFIX(maxy)); poly[1].x = MGL_randoml(MGL_TOFIX(maxx)); poly[1].y = MGL_randoml(MGL_TOFIX(maxy)); poly[2].x = MGL_randoml(MGL_TOFIX(maxx)); poly[2].y = MGL_randoml(MGL_TOFIX(maxy)); MGL_setColor(randomColor()); MGL_fillPolygonFX(3,poly,sizeof(fxpoint_t),0,0); } defaultAttributes(dc); return pause(); }
bool SignalHandler::handleEvent(EventRecord &ev) { signal_printf("%s[%d]: got event: %s\n", FILE__, __LINE__, eventType2str(ev.type)); if (ev.type == evtShutDown) { stop_request = true; return true; } process *proc = ev.proc; // Do we run the process or not? Well, that's a tricky question... // user control can override anything we do here (frex, a "run when // done" iRPC conflicting with a user "pause"). So we have the lowlevel // code suggest whether to continue or not, and we have logic here // to see if we do it or not. bool continueHint = false; bool ret = false; Frame activeFrame; assert(proc); // One big switch statement switch(ev.type) { // First the platform-independent stuff // (/proc and waitpid) case evtProcessExit: ret = handleProcessExit(ev, continueHint); break; case evtProcessCreate: ret = handleProcessCreate(ev, continueHint); break; case evtThreadCreate: ret = handleThreadCreate(ev, continueHint); break; case evtThreadExit: ret = handleLwpExit(ev, continueHint); break; case evtLwpAttach: ret = handleLwpAttach(ev, continueHint); break; case evtProcessAttach: ret = handleProcessAttach(ev, continueHint); break; case evtProcessInit: proc->handleTrapAtEntryPointOfMain(ev.lwp); proc->setBootstrapState(initialized_bs); // If we were execing, we now know we finished if (proc->execing()) { proc->finishExec(); } continueHint = false; ret = true; break; case evtProcessLoadedRT: { pdstring buffer = pdstring("PID=") + pdstring(proc->getPid()); buffer += pdstring(", loaded dyninst library"); statusLine(buffer.c_str()); startup_printf("%s[%]: trapDueToDyninstLib returned tru, trying to handle\n", FILE__, __LINE__); startup_cerr << "trapDueToDyninstLib returned true, trying to handle\n"; proc->loadDYNINSTlibCleanup(ev.lwp); proc->setBootstrapState(loadedRT_bs); ret = true; continueHint = false; break; } case evtInstPointTrap: { // Linux inst via traps // First, we scream... this is undesired behavior. signal_printf("%s[%d]: WARNING: inst point trap detected at 0x%lx, trap to 0x%lx\n", FILE__, __LINE__, ev.address, proc->trampTrapMapping[ev.address]); ev.lwp->changePC(proc->trampTrapMapping[ev.address], NULL); continueHint = true; ret = true; break; } case evtLoadLibrary: case evtUnloadLibrary: ret = handleLoadLibrary(ev, continueHint); continueHint = true; break; case evtPreFork: // If we ever want to callback this guy, put it here. ret = true; continueHint = true; break; case evtSignalled: { ret = forwardSigToProcess(ev, continueHint); break; } case evtProcessStop: ret = handleProcessStop(ev, continueHint); if (!ret) { fprintf(stderr, "%s[%d]: handleProcessStop failed\n", FILE__, __LINE__); } break; // Now the /proc only // AIX clones some of these (because of fork/exec/load notification) case evtRPCSignal: ret = proc->getRpcMgr()->handleRPCEvent(ev, continueHint); signal_printf("%s[%d]: handled RPC event, continueHint %d\n", FILE__, __LINE__, continueHint); break; case evtSyscallEntry: ret = handleSyscallEntry(ev, continueHint); if (!ret) cerr << "handleSyscallEntry failed!" << endl; break; case evtSyscallExit: ret = handleSyscallExit(ev, continueHint); if (!ret) fprintf(stderr, "%s[%d]: handlesyscallExit failed! ", __FILE__, __LINE__); ; break; case evtSuspended: continueHint = true; ret = true; flagBPatchStatusChange(); break; case evtDebugStep: handleSingleStep(ev, continueHint); ret = 1; break; case evtUndefined: // Do nothing cerr << "Undefined event!" << endl; continueHint = true; break; case evtCritical: ret = handleCritical(ev, continueHint); break; case evtRequestedStop: // /proc-age. We asked for a stop and the process did, and the signalGenerator // saw it. continueHint = false; ret = true; break; case evtTimeout: case evtThreadDetect: continueHint = true; ret = true; break; case evtNullEvent: ret = true; continueHint = true; break; default: fprintf(stderr, "%s[%d]: cannot handle signal %s\n", FILE__, __LINE__, eventType2str(ev.type)); assert(0 && "Undefined"); } if (stop_request) { // Someone deleted us in place. return true; } if (ret == false) { // if ret is false, complain, but return true anyways, since the handler threads // should be shut down by the SignalGenerator. char buf[128]; fprintf(stderr, "%s[%d]: failed to handle event %s\n", FILE__, __LINE__, ev.sprint_event(buf)); ret = true; } // Process continue hint... if (continueHint) { signal_printf("%s[%d]: requesting continue\n", FILE__, __LINE__); wait_flag = true; sg->continueProcessAsync(-1, // No signal... ev.lwp); // But give the LWP wait_flag = false; } // Should always be the last thing we do... sg->signalEvent(ev); return ret; }
int mainloop() { unsigned cmd; nodep myLine; extern int phys_pcode; extern int row, scol, ecol; int curserr; for (;;) { here(1); checkfar(1); printt5("mainloop, cursor %x, ocursor %x, srch_row %d, srch_real %d, look.=%x\n", cursor, ocursor, srch_row, srch_real, lookaheadchar); hist_mark(); printt0("back from hist_mark()\n"); if (lookaheadchar == AL_NOP || lookaheadchar == ' ') lookaheadchar = 0; /* * Redisplay unconditionally, not just when there's no * typeahead, because often there is typeahead of the * terminating character, like comma or right paren. * Ideally the redisplay should be done only if dirty * from the keyboard driver when we are ready for real * input. */ newrange(FALSE); display(FALSE); /* * ocursor is set by arrow keys to indicate that that's * where the arrow keys left the cursor. Only if it * was set (possibly in them middle of a token) and * hasn't moved since do we want to leave it alone. */ here(2); checkfar(2); if (cursor != ocursor) { /* don't do if moves are in type-ahead */ find_phys_cursor( curr_window, cursor,anywflag); anywflag = FALSE; phys_pcode = kcget( -1, cursor ); flusht(); } here(3); ocursor = NIL; CheckAt = NIL; CodeChanged = FALSE; if( autsave && ascount++ > autsave ) { ascount = 0; if( work_fname( curr_workspace ) ) { save(0); statusLine(); } else warning( ER(220,"autosave`Automatic Save is engaged but there is no file name.") ); } here(4); cmd = topcmd( srch_row, srch_real, srch_real+srch_width, cursnode ); printt2("mainloop: topcmd returns %s (%d)\n", tokname(cmd), cmd); mark_line( cursor, SMALL_CHANGE ); do_command(cmd); here(5); checkfar(3); /* never leave the cursor on a list or below hide */ cursor = hidebound(realcp( cursor )); mark_line( cursor, SMALL_CHANGE ); curserr = node_flag(cursor) & NF_ERROR; if( curserr && !WhereDeclsChanged ) { NodeNum cltype = ntype( t_up_to_line(cursor)); if( ntype_info(cltype) & F_DECLARE||highType( cltype ) ) { WhereDeclsChanged = my_block(cursor); printt1("mainloop: WhereDeclsChanged=%x\n", WhereDeclsChanged); } } /* * Whenever a graft, etc takes place we check to see * if changes are being made to a declaration. If they * are then we set WhereDeclsChanged. If it has been * set when we get back here we recompile its declaration * block. */ if (CheckSpeed && WhereDeclsChanged && (CheckSpeed >= 4 || CodeChanged || WhereDeclsChanged != OldDeclsChanged) ) { if( CheckSpeed < 4 && WhereDeclsChanged != OldDeclsChanged ) { nodep decswap; decswap = OldDeclsChanged; OldDeclsChanged = WhereDeclsChanged; WhereDeclsChanged = decswap; printt1("mainloop: WhereDeclsChanged=%x (2)\n", WhereDeclsChanged); } if( WhereDeclsChanged ) { clr_node_flag(WhereDeclsChanged, NF_TCHECKED); here(4); checkfar(4); c_comp_decls(my_scope(WhereDeclsChanged), WhereDeclsChanged, CheckSpeed < 6 ? TC_NOSTUBS : (TC_DESCEND | TC_FULL) ); here(5); checkfar(5); WhereDeclsChanged = NIL; } } /* * Typecheck the current line. This was added late in the * game, and isn't really the best way of doing things. * Every time we return from a command, we typecheck * the current line (or if CheckAt has already been set * by a skip down routine, we typecheck there). We * don't typecheck declarations. */ printt2("CheckAt=%x, cursor=%x\n", CheckAt, cursor); if (!CheckAt && (curserr||is_undid(cursor))) CheckAt = cursor; if( CheckAt && CheckSpeed ) { myLine = t_up_to_line(CheckAt); if (!( highType(ntype(myLine)) || (ntype_info(ntype(myLine)) & F_DECLARE)) ) { printt2("mainloop: c_typecheck(%x, 0, %x)\n", (int)myLine, TC_NOSTUBS|TC_ONERROR); c_typecheck(myLine, 0, TC_NOSTUBS|TC_ONERROR ); here(6); checkfar(6); } } /* if code was changed, clear chance at resuming */ if( CodeChanged ) clear_resume(); #ifdef CHECKSUM cscheck(); #endif } }
void demo(MGLDC *dc) { int numpages,aPage,vPage; int sizex,sizey,bits; rect_t fullView,oldView; pixel_format_t pf; palette_t pal[256]; MGLDC *memdc; /* The first way to do simple page flipping is using two display * pages for 'double' buffering. The MGL has functions to set the * system into double buffered modes and flip pages for you, so * this method is very easy. We use MGL_doubleBuffer() to change * to double buffered mode and MGL_swapBuffers() to change display * pages. */ if (!MGL_doubleBuffer(dc)) MGL_fatalError("Double buffereing not available!"); mainWindow(dc,"Page Flip Demo"); statusLine("Method 1: Double buffering with two pages"); MGL_swapBuffers(dc,true); /* Draw to the hidden page */ mainWindow(dc,"Page Flip Demo"); statusLine("Method 1: Double buffering with two pages"); initAnimation(); do { /* Clear the entire display device before drawing the next frame */ MGL_clearViewport(); /* Draw the clock at the current location and move it */ drawClock(); moveClock(); /* Swap the display buffers */ MGL_swapBuffers(dc,true); } while (!checkEvent()); waitEvent(); /* Return to single buffered mode */ MGL_singleBuffer(dc); /* The second way to use page flipping is with multiple display * pages (3+) to do multi-buffering. Because we are using multiple * display pages, we can turn off the wait for retrace flag when we * swap visual pages. In order for triple buffering to work properly, * we need to be doing a complete re-paint of the screen each frame * without doing a screen clear (otherwise you will see flicker). * Games like Quake and Duke3D repaint the entire frame from top to * bottom without any overdraw, which allows them to use triple * buffering techniques like this. We simulate this here by rendering * to a system buffer and blitting to the screen constantly to achieve * a similar effect for this sample program. * * Note that VBE/Core 3.0 and VBE/AF 2.0 include full support for * hardware triple buffering that can be used to eliminate this problem. * When these standards are ratified, the MGL will be updated to support * this and you will be able to do 'real' triple buffering without * any flicker on the screen. */ numpages = MGL_maxPage(dc)+1; if (numpages < 3) return; /* Get the display device size, color depth and pixel format so that we * can create a compatible memory device context. Note that we also * need to copy the palette from the display DC to the memory DC. */ sizex = MGL_sizex(dc); sizey = MGL_sizey(dc); bits = MGL_getBitsPerPixel(dc); MGL_getPixelFormat(dc,&pf); if ((memdc = MGL_createMemoryDC(sizex+1,sizey+1,bits,&pf)) == NULL) MGL_fatalError(MGL_errorMsg(MGL_result())); if (bits == 8) { MGL_getPalette(dc,pal,256,0); MGL_setPalette(memdc,pal,256,0); MGL_realizePalette(memdc,256,0,true); } MGL_makeCurrentDC(memdc); /* Make the fullViewport for the display DC the full screen, as the * above code has changed it to a smaller value. */ fullView.left = 0; fullView.top = 0; fullView.right = sizex+1; fullView.bottom = sizey+1; MGL_setViewportDC(dc,fullView); /* Draw the main window display on the memory buffer */ mainWindow(memdc,"Page Flip Demo"); statusLine("Method 2: Multi-buffering with 3+ pages"); initAnimation(); MGL_setActivePage(dc,aPage = 1); MGL_setVisualPage(dc,vPage = 0,false); MGL_getViewport(&oldView); do { /* Clear the fullViewport before drawing the next frame */ MGL_clearViewport(); /* Draw the clock at the current location and move it */ drawClock(); moveClock(); /* Copy the memory device to the display device */ MGL_setViewport(fullView); MGL_bitBlt(dc,memdc,fullView,0,0,MGL_REPLACE_MODE); MGL_setViewport(oldView); /* Swap the hardware display buffers */ aPage = (aPage+1) % numpages; vPage = (vPage+1) % numpages; MGL_setActivePage(dc,aPage); MGL_setVisualPage(dc,vPage,false); } while (!checkEvent()); waitEvent(); }
/**************************************************************************** PARAMETERS: dc - Display dc trans - Turn on/off transparent blitting REMARKS: Demo showing how to use offscreen buffers to store sprites and to use hardware acceleration to blt them to the display dc. ****************************************************************************/ ibool bufferBlit( MGLDC *dc, ibool trans) { MGLBUF *buf = NULL; color_t transparent; palette_t pal[256]; pixel_format_t pf; MGLDC *memdc; /* Display title message at the top of the window. */ if (trans) mainWindow(dc,"Offscreen Buffer Accelerated Transparent Blit Demo"); else mainWindow(dc,"Offscreen Buffer Accelerated Blit Demo"); statusLine("Press any key to continue, ESC to Abort"); if ((buf = MGL_createBuffer(dc,bmpWidth,bmpHeight,MGL_BUF_CACHED | MGL_BUF_MOVEABLE)) == NULL) { gprintf("Hardware accelerated buffer not available."); } else { /* Create a memory device context */ MGL_getPixelFormat(dc,&pf); if ((memdc = MGL_createMemoryDC(bmpWidth,bmpHeight,MGL_getBitsPerPixel(dc),&pf)) == NULL) MGL_fatalError(MGL_errorMsg(MGL_result())); /* Load a bitmap into the memory device context. The palette gets * loaded into the memory device context as well. */ if (!MGL_loadBitmapIntoDC(memdc,IMAGE_NAME,0,0,true)) MGL_fatalError(MGL_errorMsg(MGL_result())); MGL_copyToBuffer(memdc,0,0,bmpWidth,bmpHeight,0,0,buf); /* Set the display device context with the palette from the * memory device context. */ if (MGL_getBitsPerPixel(dc) <= 8) { MGL_getPalette(memdc,pal,MGL_getPaletteSize(memdc),0); MGL_setPalette(dc,pal,MGL_getPaletteSize(memdc),0); MGL_realizePalette(dc,MGL_getPaletteSize(memdc),0,true); } /* Get transparent color from pixel (0,0) */ MGL_makeCurrentDC(memdc); transparent = MGL_getPixelCoord(0,0); MGL_makeCurrentDC(dc); /* Copy image from offscreen video memory to the screen. */ while (!checkEvent()) { if (trans) MGL_putBufferSrcTrans(dc,MGL_random(maxx-bmpWidth),MGL_random(maxy-bmpHeight),buf,transparent,MGL_REPLACE_MODE); else MGL_putBuffer(dc,MGL_random(maxx-bmpWidth),MGL_random(maxy-bmpHeight),buf,MGL_REPLACE_MODE); } MGL_destroyDC(memdc); } /* Destroy the buffer */ MGL_destroyBuffer(buf); return pause(); }