X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FWin32.cc;h=c2789984e6047594e3f9cbcc4e8a8db9361a3d37;hb=39c059dae76a46550b1aef86c77d40660ebe5c2f;hp=7f5799c2fc0203dc795da4acf5a81d22fdfb0428;hpb=3807f2066945114c7a278858cfe65a33904e16c0;p=org.ibex.core.git diff --git a/src/org/xwt/plat/Win32.cc b/src/org/xwt/plat/Win32.cc index 7f5799c..c278998 100644 --- a/src/org/xwt/plat/Win32.cc +++ b/src/org/xwt/plat/Win32.cc @@ -5,6 +5,7 @@ #define INT32 WIN32_INT32 // this has to precede the others so we don't get collisions on min/max +#include #include #include @@ -179,22 +180,31 @@ void org::xwt::plat::Win32::natInit() { sprintf(buf, "XWT_WINDOW_CLASS_%i", window_class_counter++); WNDCLASSEX wc; - wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.cbWndExtra = 0; wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = NULL; - wc.hIconSm = NULL; - wc.hCursor = NULL; - wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR + 1); - wc.lpszMenuName = NULL; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), + MAKEINTRESOURCE(5), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = "menu"; wc.lpszClassName = buf; RegisterClassEx(&wc); + + surface->hwnd = (jint)CreateWindow(wc.lpszClassName, TEXT(""), + msg.wParam ? WS_NORMAL : WS_POPUP, + 200, 200, 100, 100, + (HWND__*)NULL, (HMENU__*)NULL, + GetModuleHandle(NULL), (LPVOID)NULL); - surface->hwnd = (jint)CreateWindow(wc.lpszClassName, TEXT(""), msg.wParam ? WS_NORMAL : WS_POPUP, 200, 200, 100, 100, - (HWND__*)NULL, (HMENU__*)NULL, GetModuleHandle(NULL), (LPVOID)NULL); SetFocus((HWND)surface->hwnd); surface->hwndCreated->release(); @@ -353,24 +363,28 @@ static jint* scratch_bits = NULL; static jint scratch_w = 0; static jint scratch_h = 0; -#define BLT(dest, dx1, dy1, dx2, dy2, src, sx1, sy1, sx2, sy2, op) \ - if ((dx2 - dx1 == sx2 - sx1) && (dy2 - dy1 == sy2 - sy1)) \ - BitBlt(dest, dx1, dy1, dx2 - dx1, dy2 - dy1, src, sx1, sy1, op); \ - else \ - StretchBlt(dest, dx1, dy1, dx2 - dx1, dy2 - dy1, src, sx1, sy1, sx2 - sx1, sy2 - sy1, op); - +#define max(a,b) ((a)>(b)?(a):(b)) +#define min(a,b) ((a)<(b)?(a):(b)) + void org::xwt::plat::Win32$Win32PixelBuffer::drawPicture(org::xwt::Picture* source0, - jint dx1, jint dy1, jint dx2, jint dy2, - jint sx1, jint sy1, jint sx2, jint sy2) { + jint dx, jint dy, + jint cx1, jint cy1, jint cx2, jint cy2, + jint rgb, jboolean alphaOnly) { org::xwt::plat::Win32$Win32Picture* source = (org::xwt::plat::Win32$Win32Picture*)source0; + cx1 = max(dx, cx1); + cy1 = max(dy, cy1); + cx2 = min(dx + source->getWidth(), cx2); + cy2 = min(dy + source->getHeight(), cy2); + if (cx1 >= cx2 || cy1 >= cy2) return; + if (source->hasalpha) { - if (scratch == NULL || scratch_w < dx2 - dx1 || scratch_h < dy2 - dy1) { + if (scratch == NULL || scratch_w < cx2 - cx1 || scratch_h < cy2 - cy1) { if (scratch_dc != NULL) DeleteDC(scratch_dc); if (scratch != NULL) DeleteObject(scratch); - scratch_w = max(dx2 - dx1, scratch_w); - scratch_h = max(dy2 - dy1, scratch_h); + scratch_w = max(cx2 - cx1, scratch_w); + scratch_h = max(cy2 - cy1, scratch_h); BITMAPINFO bitmapinfo; memset(&bitmapinfo, 0, sizeof(BITMAPINFO)); @@ -388,33 +402,35 @@ void org::xwt::plat::Win32$Win32PixelBuffer::drawPicture(org::xwt::Picture* sour } // copy from screen to scratch - BitBlt((HDC)scratch_dc, 0, 0, dx2 - dx1, dy2 - dy1, (HDC)hdc, dx1, dy1, SRCCOPY); + BitBlt((HDC)scratch_dc, 0, 0, cx2 - cx1, cy2 - cy1, (HDC)hdc, cx1, cy1, SRCCOPY); // apply alpha-blending to scratch jint* dat = elements(source->data); - for(int x = max(clipx1, dx1) - dx1; x < min(clipx2, dx2) - dx1; x++) - for(int y = max(clipy1, dy1) - dy1; y < min(clipy2, dy2) - dy1; y++) { - int sx = (x * (sx2 - sx1)) / (dx2 - dx1) + sx1; - int sy = (y * (sy2 - sy1)) / (dy2 - dy1) + sy1; - jint dst = scratch_bits[y * scratch_w + x]; - jint src = dat[sy * source->getWidth() + sx]; - jint alpha = (src & 0xFF000000) >> 24; + for(int x = cx1; x < cx2; x++) + for(int y = cy1; y < cy2; y++) { + jint dst = scratch_bits[(y - dy) * scratch_w + (x - dx)]; + + // FEATURE: see if we can leverage GDI to do something more clever here with alphaOnly + jint src = alphaOnly ? rgb : dat[(y - dy) * source->getWidth() + x - dx]; + jint alpha = (dat[(y - dy) * source->getWidth() + x - dx] & 0xFF000000) >> 24; jint r = (((src & 0x00FF0000) >> 16) * alpha + ((dst & 0x00FF0000) >> 16) * (0xFF - alpha)) / 0xFF; jint g = (((src & 0x0000FF00) >> 8) * alpha + ((dst & 0x0000FF00) >> 8) * (0xFF - alpha)) / 0xFF; jint b = (((src & 0x000000FF)) * alpha + ((dst & 0x000000FF)) * (0xFF - alpha)) / 0xFF; - scratch_bits[y * scratch_w + x] = (r << 16) | (g << 8) | b; + scratch_bits[(y - dy) * scratch_w + (x - dx)] = (r << 16) | (g << 8) | b; } // copy back from scratch to screen - BitBlt((HDC)hdc, dx1, dy1, dx2 - dx1, dy2 - dy1, (HDC)scratch_dc, 0, 0, SRCCOPY); + BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)scratch_dc, 0, 0, SRCCOPY); } else { + + // FIXME: support alphaOnly case here if (source->hasmask) { - BLT((HDC)hdc, dx1, dy1, dx2, dy2, (HDC)source->maskdc, sx1, sy1, sx2, sy2, SRCAND); - BLT((HDC)hdc, dx1, dy1, dx2, dy2, (HDC)source->hdc, sx1, sy1, sx2, sy2, SRCPAINT); + BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->maskdc, cx1 - dx, cy1 - dy, SRCAND); + BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCPAINT); } else { - BLT((HDC)hdc, dx1, dy1, dx2, dy2, (HDC)source->hdc, sx1, sy1, sx2, sy2, SRCCOPY); + BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCCOPY); } } @@ -446,13 +462,6 @@ void org::xwt::plat::Win32$Win32PixelBuffer::natInit() { SelectObject((HDC)hdc, (HBITMAP)hbitmap); } -void org::xwt::plat::Win32$Win32PixelBuffer::setClip(jint x, jint y, jint x2, jint y2) { - clipx1 = x; clipx2 = x2; clipy1 = y; clipy2 = y2; - HRGN hrgn = CreateRectRgn(x, y, x2, y2); - SelectClipRgn((HDC)hdc, hrgn); - DeleteObject(hrgn); -} - void org::xwt::plat::Win32$Win32PixelBuffer::finalize() { DeleteObject((void*)hdc); DeleteObject((void*)hbitmap); @@ -467,18 +476,18 @@ void org::xwt::plat::Win32$Win32Picture::natInit() { BITMAPINFO bitmapinfo; memset(&bitmapinfo, 0, sizeof(BITMAPINFO)); bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bitmapinfo.bmiHeader.biWidth = w; - bitmapinfo.bmiHeader.biHeight = -1 * h; + bitmapinfo.bmiHeader.biWidth = width; + bitmapinfo.bmiHeader.biHeight = -1 * height; bitmapinfo.bmiHeader.biPlanes = 1; bitmapinfo.bmiHeader.biBitCount = 32; bitmapinfo.bmiHeader.biCompression = BI_RGB; - hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h); + hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, width, height); hdc = (jint)CreateCompatibleDC((HDC)org::xwt::plat::Win32::desktop_dc); SelectObject((HDC)hdc, (HBITMAP)hbitmap); uint32_t* dat = (uint32_t*)elements(data); for(int i=0; ilength; i++) if ((dat[i] & 0xFF000000) == 0x00000000) dat[i] = 0x00000000; - StretchDIBits((HDC)hdc, 0, 0, w, h, 0, 0, w, h, elements(data), &bitmapinfo, DIB_RGB_COLORS, SRCCOPY); + StretchDIBits((HDC)hdc, 0, 0, width, height, 0, 0, width, height, elements(data), &bitmapinfo, DIB_RGB_COLORS, SRCCOPY); jint _copy[min(1024, data->length)]; jint* copy = data->length > 1024 ? (jint*)malloc(data->length * 4) : _copy; @@ -503,10 +512,10 @@ void org::xwt::plat::Win32$Win32Picture::natInit() { } // hmask = (jint)CreateBitmap(w, h, 1, 1, NULL); - hmask = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h); + hmask = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, width, height); maskdc = (jint)CreateCompatibleDC(NULL); SelectObject((HDC)maskdc, (HBITMAP)hmask); - StretchDIBits((HDC)maskdc, 0, 0, w, h, 0, 0, w, h, copy, &bitmapinfo, DIB_RGB_COLORS, SRCCOPY); + StretchDIBits((HDC)maskdc, 0, 0, width, height, 0, 0, width, height, copy, &bitmapinfo, DIB_RGB_COLORS, SRCCOPY); if (data->length > 1024) free(copy); } @@ -546,7 +555,7 @@ void org::xwt::plat::Win32$Win32Surface::setLocation() { SetWindowPos((HWND)hwnd, NULL, root->x - (point.x - rect.left), root->y - (point.y - rect.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE); } -void org::xwt::plat::Win32$Win32Surface::setSize(jint w, jint h) { +void org::xwt::plat::Win32$Win32Surface::_setSize(jint w, jint h) { RECT client_rect, window_rect; GetClientRect((HWND)hwnd, &client_rect); GetWindowRect((HWND)hwnd, &window_rect); @@ -576,7 +585,7 @@ void org::xwt::plat::Win32$Win32Surface::setIcon(org::xwt::Picture* p0) { HBITMAP bit = CreateCompatibleBitmap((HDC)hdc, icon_width, icon_height); HDC memdc = CreateCompatibleDC((HDC)hdc); SelectObject(memdc, bit); - BLT((HDC)memdc, 0, 0, icon_width, icon_height, (HDC)(p->hdc), 0, 0, p->getWidth(), p->getHeight(), SRCCOPY); + BitBlt((HDC)memdc, 0, 0, icon_width, icon_height, (HDC)(p->hdc), 0, 0, SRCCOPY); // create the mask jint* dat = elements(p->data); @@ -609,6 +618,7 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w int oldmousex, oldmousey; MINMAXINFO* mmi; + int resizable; POINT point; HWND hwnd2; RECT rect, rect2; @@ -729,8 +739,9 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w mmi = (MINMAXINFO*)lParam; mmi->ptMinTrackSize.x = ((uint32_t)root->minwidth) + addwidth; mmi->ptMinTrackSize.y = ((uint32_t)root->minheight) + addheight; - mmi->ptMaxTrackSize.x = min(org::xwt::plat::Win32::getScreenWidth(), ((uint32_t)root->maxwidth) + addwidth); - mmi->ptMaxTrackSize.y = min(org::xwt::plat::Win32::getScreenHeight(), ((uint32_t)root->maxheight) + addheight); + resizable = !((root->minwidth == root->maxwidth) && (root->minheight == root->maxheight)); + mmi->ptMaxTrackSize.x = resizable ? org::xwt::plat::Win32::getScreenWidth() : mmi->ptMinTrackSize.x; + mmi->ptMaxTrackSize.y = resizable ? org::xwt::plat::Win32::getScreenHeight() : mmi->ptMinTrackSize.y; return 0; case WM_PAINT: