From 7679d2d4609ffa778ba0080c2089b0a77aac0248 Mon Sep 17 00:00:00 2001 From: dgis Date: Tue, 23 Apr 2019 23:30:48 +0200 Subject: [PATCH] - Update the Win32 layer. --- ReadMe.txt | 1 + app/src/main/cpp/emu48-jni.c | 33 ++- app/src/main/cpp/win32-layer.c | 413 +++++++++++++++++++++++++++------ app/src/main/cpp/win32-layer.h | 271 ++++++++++++--------- 4 files changed, 523 insertions(+), 195 deletions(-) diff --git a/ReadMe.txt b/ReadMe.txt index f2af204..5611c0f 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -46,6 +46,7 @@ Version 1.4 (2019-04-xx) - Fix the authentic speed issue at the first start. - Fix the non working Restore/Delete backup. +- Update the Win32 layer. Version 1.3 (2019-04-04) diff --git a/app/src/main/cpp/emu48-jni.c b/app/src/main/cpp/emu48-jni.c index cc6ee38..a5b49be 100644 --- a/app/src/main/cpp/emu48-jni.c +++ b/app/src/main/cpp/emu48-jni.c @@ -299,12 +299,16 @@ JNIEXPORT void JNICALL Java_org_emulator_forty_eight_NativeLib_start(JNIEnv *env _tcscpy(szRomDirectory, "assets/calculators/"); _tcscpy(szPort2Filename, ""); - hWindowDC = CreateCompatibleDC(NULL); - // initialization QueryPerformanceFrequency(&lFreq); // init high resolution counter QueryPerformanceCounter(&lAppStart); + hWnd = CreateWindow(); + //hWindowDC = CreateCompatibleDC(NULL); + hWindowDC = GetDC(hWnd); + + + szCurrentKml[0] = 0; // no KML file selected SetSpeed(bRealSpeed); // set speed //MruInit(4); // init MRU entries @@ -337,8 +341,11 @@ JNIEXPORT void JNICALL Java_org_emulator_forty_eight_NativeLib_start(JNIEnv *env JNIEXPORT void JNICALL Java_org_emulator_forty_eight_NativeLib_stop(JNIEnv *env, jobject thisz) { - if (hThread) SwitchToState(SM_RETURN); // exit emulation thread - //ReleaseDC(hWnd, hWindowDC); + if (hThread) + SwitchToState(SM_RETURN); // exit emulation thread + + ReleaseDC(hWnd, hWindowDC); + DestroyWindow(hWnd); hWindowDC = NULL; // hWindowDC isn't valid any more hWnd = NULL; @@ -476,6 +483,10 @@ JNIEXPORT jint JNICALL Java_org_emulator_forty_eight_NativeLib_onFileNew(JNIEnv chooseCurrentKmlMode = ChooseKmlMode_UNKNOWN; if(result) { + if(hLcdDC && hLcdDC->selectedBitmap) { + hLcdDC->selectedBitmap->bitmapInfoHeader->biHeight = -abs(hLcdDC->selectedBitmap->bitmapInfoHeader->biHeight); + } + mainViewResizeCallback(nBackgroundW, nBackgroundH); draw(); @@ -499,8 +510,13 @@ JNIEXPORT jint JNICALL Java_org_emulator_forty_eight_NativeLib_onFileOpen(JNIEnv chooseCurrentKmlMode = ChooseKmlMode_FILE_OPEN; lastKMLFilename[0] = '\0'; BOOL result = OpenDocument(szBufferFilename); - if (result) + if (result) { + if(hLcdDC && hLcdDC->selectedBitmap) { + hLcdDC->selectedBitmap->bitmapInfoHeader->biHeight = -abs(hLcdDC->selectedBitmap->bitmapInfoHeader->biHeight); + } + MruAdd(szBufferFilename); + } chooseCurrentKmlMode = ChooseKmlMode_UNKNOWN; mainViewResizeCallback(nBackgroundW, nBackgroundH); if(result) { @@ -852,7 +868,12 @@ JNIEXPORT int JNICALL Java_org_emulator_forty_eight_NativeLib_onViewScript(JNIEn if (bSucc) { + if(hLcdDC && hLcdDC->selectedBitmap) { + hLcdDC->selectedBitmap->bitmapInfoHeader->biHeight = -abs(hLcdDC->selectedBitmap->bitmapInfoHeader->biHeight); + } + mainViewResizeCallback(nBackgroundW, nBackgroundH); + draw(); if (Chipset.wRomCrc != wRomCrc) // ROM changed { CpuReset(); @@ -868,7 +889,7 @@ JNIEXPORT int JNICALL Java_org_emulator_forty_eight_NativeLib_onViewScript(JNIEn SetWindowTitle(NULL); } // mainViewResizeCallback(nBackgroundW, nBackgroundH); - draw(); + //draw(); //TODO CRASH return result; } diff --git a/app/src/main/cpp/win32-layer.c b/app/src/main/cpp/win32-layer.c index 5145dc6..f81bf83 100644 --- a/app/src/main/cpp/win32-layer.c +++ b/app/src/main/cpp/win32-layer.c @@ -52,6 +52,11 @@ void win32Init() { contentSchemeLength = _tcslen(contentScheme); } +int abs (int i) { + return i < 0 ? -i : i; +} + + VOID OutputDebugString(LPCSTR lpOutputString) { LOGD("%s", lpOutputString); } @@ -89,12 +94,12 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, { FILE_LOGD("CreateFile(lpFileName: \"%s\", dwDesiredAccess: 0x%08x)", lpFileName, dwShareMode); BOOL forceNormalFile = FALSE; - if(_tcscmp(lpFileName, szPort2Filename) == 0) { - // Special case for Port2 filename - forceNormalFile = TRUE; - if(!settingsPort2wr && (dwDesiredAccess & GENERIC_WRITE)) - return (HANDLE) INVALID_HANDLE_VALUE; - } +// if(_tcscmp(lpFileName, szPort2Filename) == 0) { +// // Special case for Port2 filename +// forceNormalFile = TRUE; +// if(!settingsPort2wr && (dwDesiredAccess & GENERIC_WRITE)) +// return (HANDLE) INVALID_HANDLE_VALUE; +// } TCHAR * foundDocumentScheme = _tcsstr(lpFileName, documentScheme); @@ -112,7 +117,7 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, if(filename) { *filename = _T('\0'); } - _tcscpy(szRomDirectory, szEmuDirectory); + //_tcscpy(szRomDirectory, szEmuDirectory); SetCurrentDirectory(szEmuDirectory); } else if(foundDocumentScheme) { // With a recorded "document:" scheme, extract the folder URL with content:// scheme @@ -121,11 +126,11 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, if(filename) { *filename = _T('\0'); } - _tcscpy(szRomDirectory, szEmuDirectory); + //_tcscpy(szRomDirectory, szEmuDirectory); SetCurrentDirectory(szEmuDirectory); } else { _tcscpy(szEmuDirectory, "assets/calculators/"); - _tcscpy(szRomDirectory, "assets/calculators/"); + //_tcscpy(szRomDirectory, "assets/calculators/"); SetCurrentDirectory(szEmuDirectory); } } @@ -1287,9 +1292,18 @@ BOOL PostThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam) { #endif } +HWND CreateWindow() { + HANDLE handle = malloc(sizeof(struct _HANDLE)); + memset(handle, 0, sizeof(struct _HANDLE)); + handle->handleType = HANDLE_TYPE_WINDOW; + handle->windowDC = CreateCompatibleDC(NULL); + return handle; +} + BOOL DestroyWindow(HWND hWnd) { - //TODO - return 0; + memset(hWnd, 0, sizeof(struct _HANDLE)); + free(hWnd); + return TRUE; } BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl) { @@ -1302,6 +1316,7 @@ BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl) { BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl) { return 0; } extern void draw(); BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase) { + // Update when switch the screen off draw(); //TODO Need a true WM_PAINT event! return 0; } @@ -1319,11 +1334,11 @@ BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, BOOL IsRectEmpty(CONST RECT *lprc) { return 0; } BOOL WINAPI SetWindowOrgEx(HDC hdc, int x, int y, LPPOINT lppt) { if(lppt) { - lppt->x = hdc->windowOrigineX; - lppt->y = hdc->windowOrigineY; + lppt->x = hdc->windowOriginX; + lppt->y = hdc->windowOriginY; } - hdc->windowOrigineX = x; - hdc->windowOrigineY = y; + hdc->windowOriginX = x; + hdc->windowOriginY = y; return TRUE; } @@ -1333,8 +1348,11 @@ HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h) { switch (h->handleType) { case HGDIOBJ_TYPE_PEN: break; - case HGDIOBJ_TYPE_BRUSH: - break; + case HGDIOBJ_TYPE_BRUSH: { + HBRUSH oldSelectedBrushColor = hdc->selectedBrushColor; + hdc->selectedBrushColor = h; + return oldSelectedBrushColor; //h; + } case HGDIOBJ_TYPE_FONT: break; case HGDIOBJ_TYPE_BITMAP: { @@ -1392,11 +1410,11 @@ HGDIOBJ GetCurrentObject(HDC hdc, UINT type) { return NULL; } BOOL DeleteObject(HGDIOBJ ho) { - PAINT_LOGD("Emu48-PAINT DeleteObject(ho: %p)", ho); + PAINT_LOGD("PAINT DeleteObject(ho: %p)", ho); if(ho) { switch(ho->handleType) { case HGDIOBJ_TYPE_PALETTE: { - PAINT_LOGD("Emu48-PAINT DeleteObject() HGDIOBJ_TYPE_PALETTE"); + PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_PALETTE"); ho->handleType = HGDIOBJ_TYPE_INVALID; if(ho->paletteLog) free(ho->paletteLog); @@ -1405,7 +1423,7 @@ BOOL DeleteObject(HGDIOBJ ho) { return TRUE; } case HGDIOBJ_TYPE_BITMAP: { - PAINT_LOGD("Emu48-PAINT DeleteObject() HGDIOBJ_TYPE_BITMAP"); + PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BITMAP"); ho->handleType = HGDIOBJ_TYPE_INVALID; if(ho->bitmapInfo) free((void *) ho->bitmapInfo); @@ -1456,6 +1474,13 @@ UINT RealizePalette(HDC hdc) { return 0; } +COLORREF SetBkColor(HDC hdc, COLORREF color) { + COLORREF backgroundColorBackup = hdc->backgroundColor; + hdc->backgroundColor = color; + hdc->isBackgroundColorSet = TRUE; + return backgroundColorBackup; +} + // DC HDC CreateCompatibleDC(HDC hdc) { @@ -1465,11 +1490,28 @@ HDC CreateCompatibleDC(HDC hdc) { handle->hdcCompatible = hdc; return handle; } +HDC GetDC(HWND hWnd) { + return hWnd->windowDC; +} +int ReleaseDC(HWND hWnd, HDC hDC) { + hWnd->windowDC = NULL; //? + return TRUE; +} + BOOL DeleteDC(HDC hdc) { memset(hdc, 0, sizeof(struct _HDC)); free(hdc); return TRUE; } + +HBRUSH WINAPI CreateSolidBrush(COLORREF color) { + HGDIOBJ handle = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); + memset(handle, 0, sizeof(_HGDIOBJ)); + handle->handleType = HGDIOBJ_TYPE_BRUSH; + handle->brushColor = color; + return handle; +} + BOOL MoveToEx(HDC hdc, int x, int y, LPPOINT lppt) { //TODO return 0; @@ -1479,14 +1521,13 @@ BOOL LineTo(HDC hdc, int x, int y) { return 0; } BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { - PAINT_LOGD("Emu48-PAINT PatBlt(hdcDest: %p, x: %d, y: %d, w: %d, h: %d, rop: 0x%08x)", hdcDest, x, y, w, h, rop); + PAINT_LOGD("PAINT PatBlt(hdcDest: %p, x: %d, y: %d, w: %d, h: %d, rop: 0x%08x)", hdcDest, x, y, w, h, rop); if((hdcDest->selectedBitmap || hdcDest->hdcCompatible == NULL) && w && h) { HBITMAP hBitmapDestination = NULL; void * pixelsDestination = NULL; int destinationWidth = 0; int destinationHeight = 0; - int destinationBytes = 0; float destinationStride = 0; JNIEnv * jniEnv = NULL; @@ -1508,7 +1549,6 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { destinationWidth = androidBitmapInfo.width; destinationHeight = androidBitmapInfo.height; - destinationBytes = 4; destinationStride = androidBitmapInfo.stride; if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) < 0) { @@ -1522,7 +1562,6 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth; destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight); - destinationBytes = hBitmapDestination->bitmapInfoHeader->biBitCount >> 3; destinationStride = (float)(4 * ((destinationWidth * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32)); } @@ -1532,6 +1571,11 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ? palette->paletteLog->palPalEntry : NULL; + COLORREF brushColor = 0xFF000000; // 0xAABBGGRR + if(hdcDest->selectedBrushColor) { + brushColor = hdcDest->selectedBrushColor->brushColor; + } + for (int currentY = y; currentY < y + h; currentY++) { for (int currentX = x; currentX < x + w; currentX++) { BYTE * destinationPixel = pixelsDestination + (int)(destinationStride * currentY + 4.0 * currentX); @@ -1550,6 +1594,10 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { destinationPixel[2] = palPalEntry[0].peBlue; destinationPixel[3] = 255; break; + case PATCOPY: + // 0xAABBGGRR + *((UINT *)destinationPixel) = brushColor; + break; default: break; } @@ -1561,6 +1609,8 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) { } return 0; } +#define ROP_PSDPxax 0x00B8074A // ternary ROP +#define ROP_PDSPxax 0x00D80745 BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) { if(hdcSrc && hdcSrc->selectedBitmap) { HBITMAP hBitmap = hdcSrc->selectedBitmap; @@ -1576,7 +1626,7 @@ int SetStretchBltMode(HDC hdc, int mode) { } BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop) { - PAINT_LOGD("Emu48-PAINT StretchBlt(hdcDest: %p, xDest: %d, yDest: %d, wDest: %d, hDest: %d, hdcSrc: %p, xSrc: %d, ySrc: %d, wSrc: %d, hSrc: %d, rop: 0x%08x)", + PAINT_LOGD("PAINT StretchBlt(hdcDest: %p, xDest: %d, yDest: %d, wDest: %d, hDest: %d, hdcSrc: %p, xSrc: %d, ySrc: %d, wSrc: %d, hSrc: %d, rop: 0x%08x)", hdcDest, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, rop); if(hdcDest && hdcSrc @@ -1588,6 +1638,7 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc HBITMAP hBitmapDestination = NULL; void * pixelsDestination = NULL; + int destinationBitCount = 8; BOOL reverseHeight = hBitmapSource->bitmapInfoHeader->biHeight < 0; @@ -1596,10 +1647,8 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc int destinationWidth = 0; int destinationHeight = 0; - int sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount; - int sourceBytes = sourceBitCount >> 3; + UINT sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount; int sourceStride = 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32); - int destinationBytes = 0; int destinationStride = 0; JNIEnv * jniEnv = NULL; @@ -1620,8 +1669,7 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc destinationWidth = androidBitmapInfo.width; destinationHeight = androidBitmapInfo.height; - - destinationBytes = 4; + destinationBitCount = 32; destinationStride = androidBitmapInfo.stride; if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) < 0) { @@ -1634,79 +1682,183 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth; destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight); - - destinationBytes = (hBitmapDestination->bitmapInfoHeader->biBitCount >> 3); - destinationStride = destinationBytes * ((destinationWidth * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32); + destinationBitCount = hBitmapDestination->bitmapInfoHeader->biBitCount; + destinationStride = 4 * ((destinationWidth * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32); } - xDest -= hdcDest->windowOrigineX; - yDest -= hdcDest->windowOrigineY; + xDest -= hdcDest->windowOriginX; + yDest -= hdcDest->windowOriginY; + + //LOGD("StretchBlt(%p, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBitCount: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBitCount); - //LOGD("StretchBlt(%p, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBytes: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBytesWithDecimal); HPALETTE palette = hdcSrc->realizedPalette; if(!palette) palette = hdcSrc->selectedPalette; PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ? palette->paletteLog->palPalEntry : NULL; + if(!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0) { + palPalEntry = (PALETTEENTRY *)hBitmapSource->bitmapInfo->bmiColors; + } + COLORREF brushColor = 0xFF000000; // 0xAABBGGRR + if(hdcDest->selectedBrushColor) { + brushColor = hdcDest->selectedBrushColor->brushColor; + } + COLORREF backgroundColor = 0xFF000000; // 0xAABBGGRR + if(hdcDest->isBackgroundColorSet) { + brushColor = hdcDest->backgroundColor; + } int dst_maxx = xDest + wDest; int dst_maxy = yDest + hDest; + + if(xDest < 0) { + wDest += xDest; + xDest = 0; + } + if(yDest < 0) { + hDest += yDest; + yDest = 0; + } + if(dst_maxx > destinationWidth) + dst_maxx = destinationWidth; + if(dst_maxy > destinationHeight) + dst_maxy = destinationHeight; + for (int y = yDest; y < dst_maxy; y++) { int src_cury = ySrc + (y - yDest) * hSrc / hDest; if(!reverseHeight) src_cury = sourceHeight - 1 - src_cury; + if (src_cury < 0 || src_cury >= sourceHeight) + continue; BYTE parity = (BYTE) xSrc; for (int x = xDest; x < dst_maxx; x++, parity++) { int src_curx = xSrc + (x - xDest) * wSrc / wDest; - if (src_curx < 0 || src_cury < 0 || src_curx >= sourceWidth || src_cury >= sourceHeight) + if (src_curx < 0 || src_curx >= sourceWidth) continue; - int currentXBytes = ((sourceBitCount >> 2) * src_curx) >> 1; - BYTE * sourcePixel = pixelsSource + sourceStride * src_cury + currentXBytes; - BYTE * destinationPixel = pixelsDestination + destinationStride * y + 4 * x; + BYTE * sourcePixelBase = pixelsSource + sourceStride * src_cury; + BYTE * destinationPixelBase = pixelsDestination + destinationStride * y; + + COLORREF sourceColor = 0xFF000000; + BYTE * sourceColorPointer = (BYTE *) &sourceColor; - // -> ARGB_8888 switch (sourceBitCount) { - case 4: { - BYTE colorIndex = (parity & 0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> 4); - //BYTE colorIndex = (parity & 0x1 ? sourcePixel[0] >> 4 : sourcePixel[0] & (BYTE)0x0F); - if (palPalEntry) { - destinationPixel[0] = palPalEntry[colorIndex].peBlue; - destinationPixel[1] = palPalEntry[colorIndex].peGreen; - destinationPixel[2] = palPalEntry[colorIndex].peRed; - destinationPixel[3] = 255; + case 1: { + //TODO https://devblogs.microsoft.com/oldnewthing/?p=29013 + // When blitting from a monochrome DC to a color DC, + // the color black in the source turns into the destination’s text color, + // and the color white in the source turns into the destination’s background + // color. + BYTE * sourcePixel = sourcePixelBase + ((UINT)src_curx >> (UINT)3); + UINT bitNumber = (UINT) (src_curx % 8); + if(*sourcePixel & ((UINT)1 << bitNumber)) { + sourceColorPointer[0] = 0; + sourceColorPointer[1] = 0; + sourceColorPointer[2] = 0; } else { - destinationPixel[0] = colorIndex; - destinationPixel[1] = colorIndex; - destinationPixel[2] = colorIndex; - destinationPixel[3] = 255; + sourceColorPointer[0] = 255; + sourceColorPointer[1] = 255; + sourceColorPointer[2] = 255; + } + sourceColorPointer[3] = 255; + break; + } + case 4: { + int currentXBytes = ((sourceBitCount >> (UINT)2) * src_curx) >> (UINT)1; + BYTE * sourcePixel = sourcePixelBase + currentXBytes; + BYTE colorIndex = (parity & (BYTE)0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> (UINT)4); + if (palPalEntry) { + sourceColorPointer[0] = palPalEntry[colorIndex].peBlue; + sourceColorPointer[1] = palPalEntry[colorIndex].peGreen; + sourceColorPointer[2] = palPalEntry[colorIndex].peRed; + sourceColorPointer[3] = 255; + } else { + sourceColorPointer[0] = colorIndex; + sourceColorPointer[1] = colorIndex; + sourceColorPointer[2] = colorIndex; + sourceColorPointer[3] = 255; } break; } case 8: { + BYTE * sourcePixel = sourcePixelBase + src_curx; BYTE colorIndex = sourcePixel[0]; if (palPalEntry) { - destinationPixel[0] = palPalEntry[colorIndex].peBlue; - destinationPixel[1] = palPalEntry[colorIndex].peGreen; - destinationPixel[2] = palPalEntry[colorIndex].peRed; - destinationPixel[3] = 255; + sourceColorPointer[0] = palPalEntry[colorIndex].peBlue; + sourceColorPointer[1] = palPalEntry[colorIndex].peGreen; + sourceColorPointer[2] = palPalEntry[colorIndex].peRed; + sourceColorPointer[3] = 255; } else { - destinationPixel[0] = sourcePixel[0]; - destinationPixel[1] = sourcePixel[0]; - destinationPixel[2] = sourcePixel[0]; - destinationPixel[3] = 255; + sourceColorPointer[0] = colorIndex; + sourceColorPointer[1] = colorIndex; + sourceColorPointer[2] = colorIndex; + sourceColorPointer[3] = 255; } break; } - case 24: - destinationPixel[0] = sourcePixel[2]; - destinationPixel[1] = sourcePixel[1]; - destinationPixel[2] = sourcePixel[0]; - destinationPixel[3] = 255; + case 24: { + BYTE * sourcePixel = sourcePixelBase + 3 * src_curx; + sourceColorPointer[0] = sourcePixel[2]; + sourceColorPointer[1] = sourcePixel[1]; + sourceColorPointer[2] = sourcePixel[0]; + sourceColorPointer[3] = 255; break; - case 32: - memcpy(destinationPixel, sourcePixel, (size_t) sourceBytes); + } + case 32: { + BYTE *sourcePixel = sourcePixelBase + 4 * src_curx; + memcpy(sourceColorPointer, sourcePixel, 4); break; + } + default: + break; + } + + switch (destinationBitCount) { + case 1: { + //TODO https://devblogs.microsoft.com/oldnewthing/?p=29013 + // If you blit from a color DC to a monochrome DC, + // then all pixels in the source that are equal to the background color + // will turn white, and all other pixels will turn black. + // In other words, GDI considers a monochrome bitmap to be + // black pixels on a white background. + BYTE * destinationPixel = destinationPixelBase + (x >> 3); + UINT bitNumber = x % 8; + if(brushColor == sourceColor) { + *destinationPixel |= (1 << bitNumber); + } else { + *destinationPixel &= ~(1 << bitNumber); + } + break; + } + case 4: { + //TODO + break; + } + case 8: { + //TODO + break; + } + case 24: { + BYTE * destinationPixel = destinationPixelBase + 3 * x; + destinationPixel[0] = sourceColorPointer[0]; + destinationPixel[1] = sourceColorPointer[1]; + destinationPixel[2] = sourceColorPointer[2]; + break; + } + case 32: { + BYTE * destinationPixel = destinationPixelBase + 4 * x; + // https://docs.microsoft.com/en-us/windows/desktop/gdi/ternary-raster-operations + // http://www.qnx.com/developers/docs/6.4.1/gf/dev_guide/api/gf_context_set_rop.html + if (rop == ROP_PDSPxax) { // P ^ (D & (S ^ P)) + UINT destination = *((UINT *) destinationPixel); + *((UINT *)destinationPixel) = (brushColor ^ (destination & (sourceColor ^ brushColor))) | 0xFF000000; + } else if (rop == ROP_PSDPxax) { // P ^ (S & (D ^ P)) + UINT destination = *((UINT *) destinationPixel); + *((UINT *)destinationPixel) = (brushColor ^ (sourceColor & (destination ^ brushColor))) | 0xFF000000; + } else + *((UINT *)destinationPixel) = sourceColor; + break; + } default: break; } @@ -1736,8 +1888,34 @@ UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq } return 0; } +HBITMAP CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, CONST VOID *lpBits) { + PAINT_LOGD("PAINT CreateBitmap()"); + + HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); + memset(newHBITMAP, 0, sizeof(_HGDIOBJ)); + newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP; + + BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO)); + memset(newBitmapInfo, 0, sizeof(BITMAPINFO)); + //newBitmapInfo->bmiHeader.biBitCount = 32; //TODO should be nBitCount + newBitmapInfo->bmiHeader.biBitCount = nBitCount; //TODO should be nBitCount + newBitmapInfo->bmiHeader.biClrUsed = 0; + newBitmapInfo->bmiHeader.biWidth = nWidth; + newBitmapInfo->bmiHeader.biHeight = -nHeight; + newBitmapInfo->bmiHeader.biPlanes = (WORD) nPlanes; + newHBITMAP->bitmapInfo = newBitmapInfo; + newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo; + + size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32)); + size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride; + newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size; + VOID * bitmapBits = malloc(size); + memset(bitmapBits, 0, size); + newHBITMAP->bitmapBits = bitmapBits; + return newHBITMAP; +} HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage) { - PAINT_LOGD("Emu48-PAINT CreateDIBitmap()"); + PAINT_LOGD("PAINT CreateDIBitmap()"); HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); memset(newHBITMAP, 0, sizeof(_HGDIOBJ)); @@ -1751,14 +1929,14 @@ HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CO size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32)); size_t size = newBitmapInfo->bmiHeader.biSizeImage ? newBitmapInfo->bmiHeader.biSizeImage : - newBitmapInfo->bmiHeader.biHeight * stride; + abs(newBitmapInfo->bmiHeader.biHeight) * stride; VOID * bitmapBits = malloc(size); memcpy(bitmapBits, pjBits, size); newHBITMAP->bitmapBits = bitmapBits; return newHBITMAP; } HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset) { - PAINT_LOGD("Emu48-PAINT CreateDIBitmap()"); + PAINT_LOGD("PAINT CreateDIBitmap()"); HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); memset(newHBITMAP, 0, sizeof(_HGDIOBJ)); @@ -1781,7 +1959,7 @@ HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppv return newHBITMAP; } HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy) { - PAINT_LOGD("Emu48-PAINT CreateDIBitmap()"); + PAINT_LOGD("PAINT CreateDIBitmap()"); HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); memset(newHBITMAP, 0, sizeof(_HGDIOBJ)); @@ -1798,7 +1976,7 @@ HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy) { newBitmapInfo->bmiHeader.biBitCount = 32; size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32)); - size_t size = newBitmapInfo->bmiHeader.biHeight * stride; + size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride; newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size; newHBITMAP->bitmapBits = malloc(size); memset((void *) newHBITMAP->bitmapBits, 0, size); @@ -1808,10 +1986,91 @@ int GetDIBits(HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPB //TODO return 0; } +COLORREF GetPixel(HDC hdc, int x ,int y) { + HBITMAP hBitmapSource = hdc->selectedBitmap; + void * pixelsSource = (void *) hBitmapSource->bitmapBits; + + BOOL reverseHeight = hBitmapSource->bitmapInfoHeader->biHeight < 0; + + int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth; + int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight); // Can be < 0 + + int sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount; + int sourceStride = 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32); + + jint ret; + + x -= hdc->windowOriginX; + y -= hdc->windowOriginY; + + HPALETTE palette = hdc->realizedPalette; + if(!palette) + palette = hdc->selectedPalette; + PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ? + palette->paletteLog->palPalEntry : NULL; + if(!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0) { + palPalEntry = (PALETTEENTRY *)hBitmapSource->bitmapInfo->bmiColors; + } + COLORREF brushColor = 0xFF000000; // 0xAABBGGRR + if(hdc->selectedBrushColor) { + brushColor = hdc->selectedBrushColor->brushColor; + } + + COLORREF resultColor = CLR_INVALID; // 0xAABBGGRR + + if(x >= 0 && y >= 0 && x < sourceWidth && y < sourceHeight) { + BYTE * sourcePixel = pixelsSource + sourceStride * y + 4 * x; + + // -> ARGB_8888 + switch (sourceBitCount) { + case 1: + //TODO + break; + case 4: { + BYTE colorIndex = (x & 0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> 4); + if (palPalEntry) { + resultColor = 0xFF000000 | RGB(palPalEntry[colorIndex].peRed, palPalEntry[colorIndex].peGreen, palPalEntry[colorIndex].peBlue); + } else { + resultColor = 0xFF000000 | RGB(colorIndex, colorIndex, colorIndex); + } + break; + } + case 8: { + BYTE colorIndex = sourcePixel[0]; + if (palPalEntry) { + resultColor = 0xFF000000 | RGB(palPalEntry[colorIndex].peRed, palPalEntry[colorIndex].peGreen, palPalEntry[colorIndex].peBlue); + } else { + resultColor = 0xFF000000 | RGB(sourcePixel[0], sourcePixel[0], sourcePixel[0]); + } + break; + } + case 24: + resultColor = 0xFF000000 | RGB(sourcePixel[2], sourcePixel[1], sourcePixel[0]); + break; + case 32: + resultColor = 0xFF000000 | RGB(sourcePixel[2], sourcePixel[1], sourcePixel[0]); + break; + default: + break; + } + } + + return resultColor; +} BOOL SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom) { //TODO return 0; } +BOOL SetRectEmpty(LPRECT lprc) { + if(lprc) { + lprc->top = 0; + lprc->bottom = 0; + lprc->left = 0; + lprc->right = 0; + return TRUE; + } + return FALSE; +} int SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw) { //TODO return 0; @@ -1828,14 +2087,16 @@ HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint) { if(lpPaint) { memset(lpPaint, 0, sizeof(PAINTSTRUCT)); lpPaint->fErase = TRUE; - lpPaint->hdc = hWindowDC; + lpPaint->hdc = CreateCompatibleDC(NULL); //hWnd->windowDC); lpPaint->rcPaint.right = (short) nBackgroundW; lpPaint->rcPaint.bottom = (short) nBackgroundH; + return lpPaint->hdc; } - return hWindowDC; + return NULL; } BOOL EndPaint(HWND hWnd, CONST PAINTSTRUCT *lpPaint) { - mainViewUpdateCallback(); + //mainViewUpdateCallback(); //TODO May be not needed + DeleteDC(lpPaint->hdc); return 0; } diff --git a/app/src/main/cpp/win32-layer.h b/app/src/main/cpp/win32-layer.h index ff3229e..30e2867 100644 --- a/app/src/main/cpp/win32-layer.h +++ b/app/src/main/cpp/win32-layer.h @@ -57,6 +57,13 @@ #define FAR #define NEAR +#define __forceinline __attribute__((always_inline)) + + +#undef abs +extern int abs(int i); + + typedef int BOOL; typedef unsigned long ULONG; typedef short SHORT; @@ -360,6 +367,132 @@ enum { #define FillMemory(p,n,v) memset(p,v,n*sizeof(*(p))) #define CopyMemory(d,src,s) memcpy(d,src,s) + +// GDI +typedef struct __attribute__((packed)) tagBITMAP +{ + LONG bmType; + LONG bmWidth; + LONG bmHeight; + LONG bmWidthBytes; + WORD bmPlanes; + WORD bmBitsPixel; + LPVOID bmBits; +} BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP; +/* constants for the biCompression field */ +#define BI_RGB 0L +#define BI_RLE8 1L +#define BI_RLE4 2L +#define BI_BITFIELDS 3L +#define BI_JPEG 4L +#define BI_PNG 5L +typedef struct __attribute__((packed)) tagBITMAPFILEHEADER { + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; +} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; +typedef struct __attribute__((packed)) tagBITMAPINFOHEADER{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; +typedef struct __attribute__((packed)) tagBITMAPINFO { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; +} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; +typedef struct __attribute__((packed)) tagPALETTEENTRY { + BYTE peRed; + BYTE peGreen; + BYTE peBlue; + BYTE peFlags; +} PALETTEENTRY, *PPALETTEENTRY, FAR *LPPALETTEENTRY; +typedef struct __attribute__((packed)) tagLOGPALETTE { + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY palPalEntry[1]; +} LOGPALETTE, *PLOGPALETTE, NEAR *NPLOGPALETTE, FAR *LPLOGPALETTE; +typedef DWORD COLORREF; +enum HGDIOBJ_TYPE { + HGDIOBJ_TYPE_INVALID = 0, + HGDIOBJ_TYPE_PEN, + HGDIOBJ_TYPE_BRUSH, + HGDIOBJ_TYPE_FONT, + HGDIOBJ_TYPE_BITMAP, + HGDIOBJ_TYPE_REGION, + HGDIOBJ_TYPE_PALETTE +}; +typedef struct { + enum HGDIOBJ_TYPE handleType; + + // HGDIOBJ_TYPE_PALETTE + PLOGPALETTE paletteLog; + + // HGDIOBJ_TYPE_BITMAP + CONST BITMAPINFO *bitmapInfo; + /*CONST*/ BITMAPINFOHEADER * bitmapInfoHeader; + CONST VOID *bitmapBits; + + // HGDIOBJ_TYPE_BRUSH + COLORREF brushColor; +} _HGDIOBJ; +typedef _HGDIOBJ * HGDIOBJ; +//typedef void * HGDIOBJ; +typedef HGDIOBJ HPALETTE; +typedef HGDIOBJ HBITMAP; +typedef HGDIOBJ HFONT; +typedef HGDIOBJ HBRUSH; + +extern int GetObject(HGDIOBJ h, int c, LPVOID pv); +extern BOOL DeleteObject(HGDIOBJ ho); + +#define OBJ_BITMAP 7 + +#define WHITE_PEN 6 +#define BLACK_PEN 7 +extern HGDIOBJ GetStockObject(int i); +extern HPALETTE CreatePalette(CONST LOGPALETTE * plpal); + + +// DC + +enum DC_TYPE { + DC_TYPE_INVALID = 0, + DC_TYPE_MEMORY, + DC_TYPE_DISPLAY +}; +enum HDC_TYPE { + HDC_TYPE_INVALID = 0, + HDC_TYPE_DC +}; +struct _HDC; +typedef struct _HDC * HDC; +struct _HDC { + enum HDC_TYPE handleType; + HDC hdcCompatible; + enum DC_TYPE dcType; + HBITMAP selectedBitmap; + HPALETTE selectedPalette; + HPALETTE realizedPalette; + HBRUSH selectedBrushColor; + BOOL isBackgroundColorSet; + COLORREF backgroundColor; + int windowOriginX; + int windowOriginY; +}; + + +// Handle + struct _HANDLE; typedef struct _HANDLE * HWND; @@ -390,7 +523,8 @@ enum HANDLE_TYPE { HANDLE_TYPE_FILE_MAPPING_CONTENT, HANDLE_TYPE_FILE_MAPPING_ASSET, HANDLE_TYPE_EVENT, - HANDLE_TYPE_THREAD, + HANDLE_TYPE_THREAD, + HANDLE_TYPE_WINDOW, }; struct _HANDLE { enum HANDLE_TYPE handleType; @@ -416,6 +550,8 @@ struct _HANDLE { pthread_mutex_t eventMutex; BOOL eventAutoReset; BOOL eventState; + + HDC windowDC; }; typedef struct _HANDLE * HANDLE; @@ -423,6 +559,7 @@ typedef HANDLE HMENU; typedef HANDLE HINSTANCE; //typedef HANDLE HWND; typedef HANDLE HCURSOR; +typedef HANDLE HLOCAL; //TODO typedef struct _OVERLAPPED { @@ -532,6 +669,13 @@ extern HANDLE LoadImage(HINSTANCE hInst, LPCSTR name, UINT type, int cx, int cy, #define TBM_SETRANGE (WM_USER+6) #define TBM_SETTICFREQ (WM_USER+20) #define BST_CHECKED 0x0001 +#define LB_ADDSTRING 0x0180 +#define LB_GETCOUNT 0x018B +#define LB_GETSEL 0x0187 +#define LB_GETSELCOUNT 0x0190 +#define LB_GETITEMDATA 0x0199 +#define LB_SETITEMDATA 0x019A + extern LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); extern BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); extern int MessageBox(HANDLE, LPCTSTR szMessage, LPCTSTR szTitle, int flags); @@ -571,130 +715,24 @@ extern void EnterCriticalSection(CRITICAL_SECTION *); extern void LeaveCriticalSection(CRITICAL_SECTION *); extern void DeleteCriticalSection(CRITICAL_SECTION * lpCriticalSection); -// GDI -typedef struct __attribute__((packed)) tagBITMAP -{ - LONG bmType; - LONG bmWidth; - LONG bmHeight; - LONG bmWidthBytes; - WORD bmPlanes; - WORD bmBitsPixel; - LPVOID bmBits; -} BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP; -/* constants for the biCompression field */ -#define BI_RGB 0L -#define BI_RLE8 1L -#define BI_RLE4 2L -#define BI_BITFIELDS 3L -#define BI_JPEG 4L -#define BI_PNG 5L -typedef struct __attribute__((packed)) tagBITMAPFILEHEADER { - WORD bfType; - DWORD bfSize; - WORD bfReserved1; - WORD bfReserved2; - DWORD bfOffBits; -} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; -typedef struct __attribute__((packed)) tagBITMAPINFOHEADER{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; -typedef struct __attribute__((packed)) tagBITMAPINFO { - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[1]; -} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO; -typedef struct __attribute__((packed)) tagPALETTEENTRY { - BYTE peRed; - BYTE peGreen; - BYTE peBlue; - BYTE peFlags; -} PALETTEENTRY, *PPALETTEENTRY, FAR *LPPALETTEENTRY; -typedef struct __attribute__((packed)) tagLOGPALETTE { - WORD palVersion; - WORD palNumEntries; - PALETTEENTRY palPalEntry[1]; -} LOGPALETTE, *PLOGPALETTE, NEAR *NPLOGPALETTE, FAR *LPLOGPALETTE; -enum HGDIOBJ_TYPE { - HGDIOBJ_TYPE_INVALID = 0, - HGDIOBJ_TYPE_PEN, - HGDIOBJ_TYPE_BRUSH, - HGDIOBJ_TYPE_FONT, - HGDIOBJ_TYPE_BITMAP, - HGDIOBJ_TYPE_REGION, - HGDIOBJ_TYPE_PALETTE -}; -typedef struct { - enum HGDIOBJ_TYPE handleType; - - // HGDIOBJ_TYPE_PALETTE - PLOGPALETTE paletteLog; - - // HGDIOBJ_TYPE_BITMAP - CONST BITMAPINFO *bitmapInfo; - CONST BITMAPINFOHEADER * bitmapInfoHeader; - CONST VOID *bitmapBits; -} _HGDIOBJ; -typedef _HGDIOBJ * HGDIOBJ; -//typedef void * HGDIOBJ; -typedef HGDIOBJ HPALETTE; -typedef HGDIOBJ HBITMAP; -typedef HGDIOBJ HFONT; - -extern int GetObject(HGDIOBJ h, int c, LPVOID pv); -extern BOOL DeleteObject(HGDIOBJ ho); - -#define OBJ_BITMAP 7 - -#define WHITE_PEN 6 -#define BLACK_PEN 7 -extern HGDIOBJ GetStockObject(int i); -extern HPALETTE CreatePalette(CONST LOGPALETTE * plpal); - // DC -enum DC_TYPE { - DC_TYPE_INVALID = 0, - DC_TYPE_MEMORY, - DC_TYPE_DISPLAY -}; -enum HDC_TYPE { - HDC_TYPE_INVALID = 0, - HDC_TYPE_DC -}; -struct _HDC; -typedef struct _HDC * HDC; -struct _HDC{ - enum HDC_TYPE handleType; - HDC hdcCompatible; - enum DC_TYPE dcType; - HBITMAP selectedBitmap; - HPALETTE selectedPalette; - HPALETTE realizedPalette; - int windowOrigineX; - int windowOrigineY; -}; -//typedef HANDLE HDC; - extern HDC CreateCompatibleDC(HDC hdc); +extern HDC GetDC(HWND hWnd); +extern int ReleaseDC(HWND hWnd, HDC hDC); extern BOOL DeleteDC(HDC hdc); extern HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h); extern HGDIOBJ GetCurrentObject(HDC hdc, UINT type); +HBRUSH CreateSolidBrush(COLORREF color); + extern BOOL MoveToEx(HDC hdc, int x, int y, LPPOINT lppt); extern BOOL LineTo(HDC hdc, int x, int y); #define SRCCOPY (DWORD)0x00CC0020 /* dest = source */ +#define PATCOPY (DWORD)0x00F00021 /* dest = pattern */ #define DSTINVERT (DWORD)0x00550009 /* dest = (NOT dest) */ #define BLACKNESS (DWORD)0x00000042 /* dest = BLACK */ +#define WHITENESS (DWORD)0x00FF0062 /* dest = WHITE */ extern BOOL PatBlt(HDC hdc, int x, int y, int w, int h, DWORD rop); extern BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop); #define HALFTONE 4 @@ -706,6 +744,7 @@ extern UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD /* DIB color table identifiers */ #define DIB_RGB_COLORS 0 /* color table in RGBs */ #define DIB_PAL_COLORS 1 /* color table in palette indices */ +extern HBITMAP CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, CONST VOID *lpBits); extern HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage); extern HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset); extern HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy); @@ -721,11 +760,14 @@ typedef struct _RGNDATA { char Buffer[1]; } RGNDATA, *PRGNDATA, NEAR *NPRGNDATA, FAR *LPRGNDATA; extern int GetDIBits(HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT usage); +extern COLORREF GetPixel(HDC hdc, int x ,int y); extern HPALETTE SelectPalette(HDC hdc, HPALETTE hPal, BOOL bForceBkgd); extern UINT RealizePalette(HDC hdc); +extern COLORREF SetBkColor(HDC hdc, COLORREF color); /* GetRegionData/ExtCreateRegion */ #define RDH_RECTANGLES 1 extern BOOL SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom); +extern BOOL SetRectEmpty(LPRECT lprc); struct HRGN__ { int unused; }; typedef struct HRGN__ *HRGN; @@ -877,6 +919,7 @@ typedef struct tagWINDOWPLACEMENT { } WINDOWPLACEMENT; typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT; +extern HWND CreateWindow(); extern BOOL DestroyWindow(HWND hWnd); extern BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl); extern BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl); @@ -925,6 +968,8 @@ extern BOOL GetClientRect(HWND hWnd, LPRECT lpRect); typedef char *PSZ; typedef DWORD COLORREF; +#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) +#define CLR_INVALID 0xFFFFFFFF extern BOOL MessageBeep(UINT uType);