#define WIN32_LEAN_AND_MEAN #include #include #include #include #include "bmpconv.hpp" #include "filestrm.hpp" #include "npstrm.hpp" #include "nullstrm.hpp" #include "scrnview.hpp" #include "comp.hpp" static void fillRGBQUAD(RGBQUAD *rgbq) { uint32 v[6]={0,64,128,192,240,255}; int i=0; for(int r=0; r<6; r++) for(int g=0; g<6; g++) for(int b=0; b<6; b++) { rgbq[i].rgbBlue = (BYTE)v[b]; rgbq[i].rgbGreen = (BYTE)v[g]; rgbq[i].rgbRed = (BYTE)v[r]; rgbq[i].rgbReserved = 0; i++; } for(; i<256; i++) { rgbq[i].rgbBlue = 0; rgbq[i].rgbGreen = 0; rgbq[i].rgbRed = 0; rgbq[i].rgbReserved = 0; } } static void convertTmp2Current(BITMAPINFO *bi, const void *tmpbits, void *currentbits) { static uint32 dstpal[256]; static int dstpal_initialized=0; if(!dstpal_initialized) { uint32 v[6]={0,64,128,192,240,255}; int i=0; for(int r=0; r<6; r++) for(int g=0; g<6; g++) for(int b=0; b<6; b++) dstpal[i++] = ((v[r]<<16)|v[g]<<8)|v[b]; for(; i<256; i++) dstpal[i] = 0; dstpal_initialized=1; } if(bi->bmiHeader.biBitCount==8) ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 8, (uint32)bi->bmiColors, currentbits, 8, (uint32)dstpal ); else if(bi->bmiHeader.biBitCount==16) { //555 or 565 ? if(bi->bmiHeader.biCompression==BI_BITFIELDS && *(DWORD*)(&bi->bmiColors[0]) == 0xf800 && *(DWORD*)(&bi->bmiColors[1]) == 0x07e0 && *(DWORD*)(&bi->bmiColors[2]) == 0x001f) ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 16, 0x0565, currentbits, 8, (uint32)dstpal ); else ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 16, 0x0555, currentbits, 8, (uint32)dstpal ); } else if(bi->bmiHeader.biBitCount==24) { ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 24, 0, currentbits, 8, (uint32)dstpal ); } else if(bi->bmiHeader.biBitCount==32) { ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 32, 0, currentbits, 8, (uint32)dstpal ); } } static void snapscreen0(unsigned *w, unsigned *h, char **cb) { unsigned width=*w,height=*h; char *cbitbuf=*cb; HDC hdcScreen=CreateDC("DISPLAY",NULL,NULL,NULL); if(!hdcScreen) { fprintf(stderr,"snap(0): CreateDC(screen) failed\n"); return; } HBITMAP hbmCurrent = (HBITMAP)GetCurrentObject(hdcScreen,OBJ_BITMAP); if(!hbmCurrent) { fprintf(stderr,"snap(0): hbmCurrent==NULL\n"); return; } char bihbuf[sizeof(BITMAPINFO)+256*sizeof(RGBQUAD)]; BITMAPINFO &bih=*(BITMAPINFO*)bihbuf; memset(bihbuf,0,sizeof(bihbuf)); bih.bmiHeader.biSize=sizeof(bih); if(GetDIBits(hdcScreen,hbmCurrent, 0,height, NULL, &bih, DIB_RGB_COLORS ) ==0) { fprintf(stderr,"snap(0): GetDIBits(...NULL...) failed\n"); return; } if(*cb==0 || *w!=bih.bmiHeader.biWidth || *h!=bih.bmiHeader.biHeight) { delete[] *cb; *w = bih.bmiHeader.biWidth; *h = bih.bmiHeader.biHeight; *cb = new char[*w * *h]; } char *tmpbitbuf = new char[*w * *h]; if(tmpbitbuf==0) { fprintf(stderr,"snap(0): could not allocate tmpbitbuf\n"); return; } if(GetDIBits(hdcScreen, hbmCurrent, 0,*h, tmpbitbuf, &bih, DIB_RGB_COLORS ) ==0) { fprintf(stderr,"snap(0): GetDIBits failed, rc=%d\n",GetLastError()); return; } DeleteDC(hdcScreen); //convert to 8-bit with fixed palette convertTmp2Current(&bih, tmpbitbuf, *cb); delete[] tmpbitbuf; } static void snapscreen1(unsigned *w, unsigned *h, char **cb) { unsigned width=*w,height=*h; char *cbitbuf=*cb; HDC hdcScreen=CreateDC("DISPLAY",NULL,NULL,NULL); if(!hdcScreen) { fprintf(stderr,"Glup! CreateDC() failed\n"); return; } int sw = GetDeviceCaps(hdcScreen,DESKTOPHORZRES), sh = GetDeviceCaps(hdcScreen,DESKTOPVERTRES); if(sw<640 || sh<480) { fprintf(stderr,"snap(1): GetDeviceCaps failed, using GetSystemMetrics() instead\n"); sw = GetSystemMetrics(SM_CXSCREEN); sh = GetSystemMetrics(SM_CYSCREEN); return; } HDC hdcMem = CreateCompatibleDC(hdcScreen); if(!hdcMem) { fprintf(stderr,"snap(1): CreateCompatibleDC() failed\n"); return; } static HBITMAP hbmCurrent=0; static char bibuf[sizeof(BITMAPINFO)+256*sizeof(RGBQUAD)]; static BITMAPINFO &bi=*(BITMAPINFO*)bibuf; if(hbmCurrent==0) { memset(bibuf,0,sizeof(bibuf)); bi.bmiHeader.biSize=sizeof(bi); bi.bmiHeader.biWidth = sw; bi.bmiHeader.biHeight = sh; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 8; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = 0; bi.bmiHeader.biClrUsed = 6*6*6; bi.bmiHeader.biClrImportant = 6*6*6; fillRGBQUAD(bi.bmiColors); void *pvBits; hbmCurrent = CreateDIBSection(hdcMem, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0 ); if(!hbmCurrent) { fprintf(stderr,"snap(1): CreateDIBSection failed, error=%d\n",GetLastError()); return; } *w = sw; *h = sh; *cb = (char*)pvBits; } HGDIOBJ hbmOld=SelectObject(hdcMem,hbmCurrent); if(!hbmOld) { fprintf(stderr,"snap(1): SelectObject failed, error=%d\n",GetLastError()); return; } SetDIBColorTable(hdcMem,0,6*6*6,bi.bmiColors); if(!BitBlt(hdcMem,0,0,sw,sh, hdcScreen,0,0, SRCCOPY)) { fprintf(stderr,"snap(1): BitBlt failed, error=%d\n",GetLastError()); return; } DeleteDC(hdcScreen); SelectObject(hdcMem,hbmOld); DeleteDC(hdcMem); } void main(int argc, char **argv) { int snapmethod; OutStream *os; if(argc==4) { snapmethod=atoi(argv[1]); if(stricmp(argv[2],"np")==0) { os = new NPOutStream; os->open(argv[3]); } else if(stricmp(argv[2],"file")==0) { os = new FileOutStream; os->open(argv[3]); } else if(stricmp(argv[2],"null")==0) { os = new NullOutStream; os->open(argv[3]); } else { fprintf(stderr,"Unknown commtype: '%s'\n",argv[2]); return; } } else { os = new FileOutStream; os->open("snap.out"); } InitializeCompressor(os); unsigned width=0,height=0; char *cbitbuf=0; //DWORD starttime=GetTickCount(); // for(int r=0;r<10;r++) { while(!os->error()) { //printf("Snap! "); fflush(stdout); //get current screen image if(snapmethod==0) snapscreen0(&width,&height,&cbitbuf); else if(snapmethod==1) snapscreen1(&width,&height,&cbitbuf); //transmit it compress(width,height,cbitbuf); //and give the user some time Sleep(2000); } //DWORD endtime=GetTickCount(); //printf("Ticks: %d\n",endtime-starttime); os->close(); delete os; }