X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fplat%2FWin32.cc;h=248d55588224a0a48f57b49f9945fedd4d5d43f8;hb=b213eae7072297f9121511fa671062f9b07fcc59;hp=3bb342e75c5293618594756ad662221548ad9e0a;hpb=36c7cba0672b0b0ac61f484a918a34969100ca92;p=org.ibex.core.git diff --git a/src/org/xwt/plat/Win32.cc b/src/org/xwt/plat/Win32.cc index 3bb342e..248d555 100644 --- a/src/org/xwt/plat/Win32.cc +++ b/src/org/xwt/plat/Win32.cc @@ -1,9 +1,11 @@ // Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL] +#include "GCJ.cc" -// kinda ugly; we use -DCOMPILE_DLL to combine two .cc files into one -#ifndef COMPILE_DLL +// we have to do this because the jpeg libraries use the symbol 'INT32' +#define INT32 WIN32_INT32 // this has to precede the others so we don't get collisions on min/max +#include #include #include @@ -23,15 +25,14 @@ #include #include #include -#include +#include #include #include -#include #include -#include #include -#include +#include #include +#include #include // for debugging @@ -61,25 +62,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { } } -// This function iterates over each family (lparam == 0), and then over each size (lparam == 1) -int CALLBACK fontproc(const LOGFONTA* enumlogfont, const TEXTMETRICA* tm, long unsigned int type, LPARAM lparam) { - - if (lparam == 0) { - LOGFONT lf; - lf.lfCharSet = ANSI_CHARSET; - strncpy(lf.lfFaceName, enumlogfont->lfFaceName, 32); - lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx((HDC)org::xwt::plat::Win32::desktop_dc, &lf, fontproc, 1, 0); - - } else { - org::xwt::plat::Win32::addFont(JvNewStringLatin1(enumlogfont->lfFaceName), - ((type & RASTER_FONTTYPE) == 0) ? 0 : tm->tmHeight, - tm->tmItalic == 0 ? 0 : 1, - tm->tmWeight <= 400 ? 0 : 1); - } - return 1; -} - // Initialization //////////////////////////////////////////////////////////////////// @@ -183,13 +165,6 @@ void org::xwt::plat::Win32::natInit() { org::xwt::plat::Win32::sizewe_cursor = (jint)LoadCursor(NULL, IDC_SIZEWE); org::xwt::plat::Win32::hand_cursor = (jint)CreateCursor(GetModuleHandle(NULL), 14, 1, 32, 32, hand_cursor_and, hand_cursor_xor); - // enumerate fonts - LOGFONT lf; - lf.lfCharSet = ANSI_CHARSET; - lf.lfFaceName[0] = 0; - lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx((HDC)desktop_dc, &lf, fontproc, 0, 0); - messagePumpThread = (jint)GetCurrentThreadId(); messagePumpStarted->release(); @@ -205,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(); @@ -237,6 +221,39 @@ void org::xwt::plat::Win32::natInit() { // Platform Methods /////////////////////////////////////////////////////////////////// +jstring org::xwt::plat::Win32::_getEnv(jstring key) { + int len = JvGetStringUTFLength(key); + char buf[len + 1]; + JvGetStringUTFRegion(key, 0, len, buf); + buf[len] = '\0'; + char buf2[1024]; + DWORD ret = GetEnvironmentVariable(buf, buf2, 1024); + if (ret > 0 && ret < 1024) return JvNewStringLatin1(buf2); + return NULL; +} + +jstring org::xwt::plat::Win32::_fileDialog(jstring suggestedFileName, jboolean write) { + + char buf[1024]; + OPENFILENAME ofn; + memset(buf, 0, 1024); + memset(&ofn, 0, sizeof(OPENFILENAME)); + + if (suggestedFileName != NULL) + JvGetStringUTFRegion(suggestedFileName, 0, min(1023, JvGetStringUTFLength(suggestedFileName)), buf); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.nMaxCustFilter = 0; + ofn.lpstrFile = buf; + ofn.nMaxFile = 1024; + + if (write) ofn.Flags |= OFN_OVERWRITEPROMPT; + ofn.Flags |= OFN_HIDEREADONLY; + + int ret = write ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn); + return ret == 0 ? NULL : JvNewStringLatin1(buf); +} + void org::xwt::plat::Win32::__detectProxy(JArray* container) { HKEY hkey; @@ -301,7 +318,7 @@ void org::xwt::plat::Win32::_criticalAbort(jstring message) { char buf[JvGetStringUTFLength(message) + 1]; buf[JvGetStringUTFLength(message)] = '\0'; JvGetStringUTFRegion(message, 0, JvGetStringUTFLength(message), buf); - MessageBox (NULL, buf, "XWT Critical Abort", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND); + MessageBox (NULL, buf, "XWT Cannot Continue", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND); java::lang::System::exit(-1); } @@ -317,50 +334,6 @@ jint org::xwt::plat::Win32::_getScreenHeight() { return rect.bottom - rect.top; } -org::xwt::plat::Win32$Win32Font* org::xwt::plat::Win32::mapFont(org::xwt::Platform$ParsedFont* pf) { - org::xwt::plat::Win32$Win32Font* ret = new org::xwt::plat::Win32$Win32Font(); - LOGFONT logfont; - memset(&logfont, 0, sizeof(LOGFONT)); - logfont.lfHeight = -MulDiv(pf->size, GetDeviceCaps((HDC)org::xwt::plat::Win32::desktop_dc, LOGPIXELSY), 72); - if (pf->italic) logfont.lfItalic = 1; - if (pf->bold) logfont.lfWeight = FW_BOLD; - logfont.lfCharSet = ANSI_CHARSET; - - JvGetStringUTFRegion(pf->name, 0, min(31, JvGetStringUTFLength(pf->name)), logfont.lfFaceName); - logfont.lfFaceName[min(31, JvGetStringUTFLength(pf->name))] = 0; - - ret->hfont = (jint)CreateFontIndirect(&logfont); - SelectObject((HDC)desktop_dc, (HFONT)(ret->hfont)); - - TEXTMETRIC tm; - GetTextMetrics((HDC)desktop_dc, &tm); - POINT p; - p.x = 0; p.y = tm.tmAscent; - LPtoDP((HDC)desktop_dc, &p, 1); - ret->maxAscent = p.y; - - p.x = 0; p.y = tm.tmDescent; - LPtoDP((HDC)desktop_dc, &p, 1); - ret->maxDescent = p.y; - - return ret; -} - -jint org::xwt::plat::Win32::_stringWidth(jstring font, jstring text) { - - HFONT hfont = (HFONT)(getFont(font)->hfont); - SelectObject((HDC)org::xwt::plat::Win32::desktop_dc, hfont); - - int len = min(1024, JvGetStringUTFLength(text)); - char buf[len + 1]; - buf[len] = '\0'; - JvGetStringUTFRegion(text, 0, len, buf); - - SIZE size; - GetTextExtentPoint32((HDC)org::xwt::plat::Win32::desktop_dc, buf, len, &size); - return size.cx; -} - jboolean org::xwt::plat::Win32::_newBrowserWindow_(jstring url) { int len = min(2048, JvGetStringUTFLength(url)); @@ -380,7 +353,7 @@ jboolean org::xwt::plat::Win32::_newBrowserWindow_(jstring url) { } -// Win32DoubleBuffer ///////////////////////////////////////////////////////////////////////// +// Win32PixelBuffer ///////////////////////////////////////////////////////////////////////// // This is a scratch area; when blitting a translucent image, we copy the underlying data here first. // Since all drawing operations are single-threaded, it's safe to use a global here. @@ -390,25 +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); - -void org::xwt::plat::Win32$Win32DoubleBuffer::drawPicture(org::xwt::Picture* source0, - jint dx1, jint dy1, jint dx2, jint dy2, - jint sx1, jint sy1, jint sx2, jint sy2) { +#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 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)); @@ -426,57 +402,42 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::drawPicture(org::xwt::Picture* sou } // 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); } } } -void org::xwt::plat::Win32$Win32DoubleBuffer::drawString(jstring font, jstring text, jint x, jint y, jint color) { - - org::xwt::plat::Win32$Win32Font* wf = org::xwt::plat::Win32::getFont(font); - SelectObject((HDC)hdc, (HFONT)(wf->hfont)); - - // Platform API passes us the y-pos of the bottom of the text; we need the top - y -= wf->maxAscent; - - int len = min(1024, JvGetStringUTFLength(text)); - char buf[len + 1]; - buf[len] = '\0'; - JvGetStringUTFRegion(text, 0, len, buf); - - SetTextColor((HDC)hdc, PALETTERGB((color & 0xFF0000) >> 16, (color & 0xFF00) >> 8, color & 0xFF)); - TextOut((HDC)hdc, x, y, buf, len); -} - -void org::xwt::plat::Win32$Win32DoubleBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) { +void org::xwt::plat::Win32$Win32PixelBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) { jint w = x2 - x; jint h = y2 - y; @@ -488,25 +449,20 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::fillRect(jint x, jint y, jint x2, DeleteObject(brush); } -void org::xwt::plat::Win32$Win32Surface::blit(org::xwt::DoubleBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) { - BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::xwt::plat::Win32$Win32DoubleBuffer*)s)->hdc), sx, sy, SRCCOPY); +void org::xwt::plat::Win32$Win32Surface::blit(org::xwt::PixelBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) { + // we create the DC lazily to get around some strange race condition in WinXP + if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd); + BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::xwt::plat::Win32$Win32PixelBuffer*)s)->hdc), sx, sy, SRCCOPY); } -void org::xwt::plat::Win32$Win32DoubleBuffer::natInit() { +void org::xwt::plat::Win32$Win32PixelBuffer::natInit() { hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h); hdc = (jint)CreateCompatibleDC((HDC)org::xwt::plat::Win32::desktop_dc); SetBkMode((HDC)hdc, TRANSPARENT); SelectObject((HDC)hdc, (HBITMAP)hbitmap); } -void org::xwt::plat::Win32$Win32DoubleBuffer::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$Win32DoubleBuffer::finalize() { +void org::xwt::plat::Win32$Win32PixelBuffer::finalize() { DeleteObject((void*)hdc); DeleteObject((void*)hbitmap); } @@ -520,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; @@ -556,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); } @@ -578,7 +534,6 @@ void org::xwt::plat::Win32$Win32Surface::natInit(jboolean framed) { // GC_enable_incremental(); ShowWindow ((HWND)hwnd, SW_SHOWDEFAULT); - hdc = (jint)GetDC((HWND)hwnd); } void org::xwt::plat::Win32$Win32Surface::finalize() { /* DeleteObject((void*)hwnd); */ } @@ -590,23 +545,23 @@ void org::xwt::plat::Win32$Win32Surface::_setMinimized(jboolean m) { ShowWindow( void org::xwt::plat::Win32$Win32Surface::_setMaximized(jboolean m) { ShowWindow((HWND)hwnd, m ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); } void org::xwt::plat::Win32$Win32Surface::postCursorChange() { PostMessage((HWND)hwnd, WM_USER_SETCURSOR, 0, 0); } -void org::xwt::plat::Win32$Win32Surface::setLocation(jint x, jint y) { +void org::xwt::plat::Win32$Win32Surface::setLocation() { POINT point; RECT rect; point.x = 0; point.y = 0; ClientToScreen((HWND)hwnd, &point); GetWindowRect((HWND)hwnd, &rect); - SetWindowPos((HWND)hwnd, NULL, x - (point.x - rect.left), y - (point.y - rect.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE); + 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); - int addwidth = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left); - int addheight = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top); - SetWindowPos((HWND)hwnd, NULL, 0, 0, w + addwidth, h + addheight, SWP_NOZORDER | SWP_NOMOVE); + int width = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left) + w; + int height = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top) + h; + SetWindowPos((HWND)hwnd, NULL, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE); } void org::xwt::plat::Win32$Win32Surface::setTitleBarText(java::lang::String* title) { @@ -623,11 +578,14 @@ void org::xwt::plat::Win32$Win32Surface::setIcon(org::xwt::Picture* p0) { int icon_width = GetSystemMetrics(SM_CXSMICON); int icon_height = GetSystemMetrics(SM_CYSMICON); + // we create the DC lazily to get around some strange race condition in WinXP + if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd); + // create the bitmap 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); @@ -663,14 +621,15 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w POINT point; HWND hwnd2; RECT rect, rect2; + RECT client_rect, window_rect; jboolean newinside; int16_t mouse_x; int16_t mouse_y; + int addwidth, addheight; switch(iMsg) { case WM_DEVMODECHANGE: break; // FEATURE: color depth changed case WM_DISPLAYCHANGE: break; // FEATURE: screen size changed - case WM_FONTCHANGE: break; // FEATURE: set of fonts changed case WM_MOUSEWHEEL: break; // FEATURE: Mouse Wheel case WM_SYSKEYDOWN: if (GetKeyState(VK_MENU) >> (sizeof(SHORT) * 8 - 1) == 0) return 0; @@ -772,11 +731,15 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w return 0; case WM_GETMINMAXINFO: + GetClientRect((HWND)hwnd, &client_rect); + GetWindowRect((HWND)hwnd, &window_rect); + addwidth = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left); + addheight = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top); mmi = (MINMAXINFO*)lParam; - mmi->ptMinTrackSize.x = root->dmin(0); - mmi->ptMinTrackSize.y = root->dmin(1); - mmi->ptMaxTrackSize.x = root->dmax(0); - mmi->ptMaxTrackSize.y = root->dmax(1); + mmi->ptMinTrackSize.x = ((uint32_t)root->minwidth) + addwidth; + mmi->ptMinTrackSize.y = ((uint32_t)root->minheight) + addheight; + mmi->ptMaxTrackSize.x = org::xwt::plat::Win32::getScreenWidth(); + mmi->ptMaxTrackSize.y = org::xwt::plat::Win32::getScreenHeight(); return 0; case WM_PAINT: @@ -797,13 +760,13 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w static char keyarr [256] = { 0 }; static jstring keyToString(WPARAM wParam) { - char arr[4]; + char arr[8]; keyarr[VK_CAPITAL] = GetKeyState(VK_CAPITAL); keyarr[VK_LSHIFT] = GetKeyState(VK_LSHIFT); keyarr[VK_RSHIFT] = GetKeyState(VK_RSHIFT); keyarr[VK_SHIFT] = GetKeyState(VK_SHIFT); - - if (ToAscii(wParam, 0, (BYTE*)keyarr, (WORD*)arr, 0) == 1) { + + if (ToAsciiEx(wParam, 0, (BYTE*)keyarr, (WORD*)arr, 0, GetKeyboardLayout(0)) == 1) { switch (arr[0]) { case '\t': return JvNewStringLatin1("tab"); case 0x1b: return JvNewStringLatin1("escape"); @@ -861,317 +824,3 @@ static jstring keyToString(WPARAM wParam) { } return NULL; } - - - - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// - -#else /* COMPILE_DLL */ - - -// -// A simple DLL to invoke xwt.exe and pass it any arguments found in the tag -// - -#include -#include -#include -#include -#include -#include - - -// Globals //////////////////////////////////////////////////////////////////////// - -using namespace std; - -#define CLSID_STRING_SIZE 39 - -const char XWT_friendlyName[] = "XWT ActiveX Control (build " BUILDID ")"; -const char XWT_versionIndependantProgramID[] = "XWT.ActiveX"; -const char XWT_programID[] = "XWT.ActiveX (build " BUILDID ")"; -extern "C" const CLSID XWT_clsid = CLSID_STRUCT; -static HMODULE g_hModule = NULL; //DLL handle - - - - -// Superclasses //////////////////////////////////////////////////////////////////////// - -// Option bit definitions for IObjectSafety: -#define INTERFACESAFE_FOR_UNTRUSTED_CALLER 0x00000001 // Caller of interface may be untrusted -#define INTERFACESAFE_FOR_UNTRUSTED_DATA 0x00000002 // Data passed into interface may be untrusted - -// {CB5BDC81-93C1-11cf-8F20-00805F2CD064} -DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f, 0x20, 0x0, 0x80, 0x5f, 0x2c, 0xd0, 0x64); - -interface IObjectSafety : public IUnknown { - public: - virtual HRESULT __stdcall GetInterfaceSafetyOptions(REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions) = 0; - virtual HRESULT __stdcall SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) = 0; -}; - -interface IShoeHorn : IPersistPropertyBag, IObjectSafety { }; - - - -// Entry Points //////////////////////////////////////////////////////////////////////// - -// to get mingw to stop nagging me -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { } - -// determines whether or not the DLL can be unloaded; always allow this since we don't do too much -STDAPI __declspec(dllexport) DllCanUnloadNow(void) { return S_OK; } - -extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID /*lpReserved*/) { - if (dwReason == DLL_PROCESS_ATTACH) g_hModule = (HINSTANCE)hModule; - return TRUE; -} - - - -// Other /////////////////////////////////////////////////////////////////////////////////// - -// simple assert() replacement that pops open a message box if there are errors -void check(int val, char* message) { - if (!val) { - MessageBox (NULL, message, "XWT Critical Abort", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND); - exit(-1); - } -} - -void clsidToString(const CLSID& clsid, char* str, int length) { - check(length >= CLSID_STRING_SIZE, "clsidToString(): string too short"); - LPOLESTR wide_str = NULL; - HRESULT hr = StringFromCLSID(clsid, &wide_str); - check(SUCCEEDED(hr), "StringFromCLSID() failed in clsidToString()"); - wcstombs(str, wide_str, length); - CoTaskMemFree(wide_str); -} - -void setRegistryKey(const char* key, const char* subkey, const char* value) { - HKEY hKey; - char keyBuf[1024]; - strcpy(keyBuf, key); - if (subkey != NULL) { - strcat(keyBuf, "\\"); - strcat(keyBuf, subkey ); - } - long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, keyBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL); - if (value != NULL) - check(RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)value, strlen(value) + 1) == ERROR_SUCCESS, - "RegSetValueEx() failed in setRegistryKey()"); - RegCloseKey(hKey); -} - -void deleteRegistryKey(HKEY parent, const char* target) { - HKEY hKeyChild; - RegOpenKeyEx(parent, target, 0, KEY_ALL_ACCESS, &hKeyChild); - - // Iterate over children, deleting them - FILETIME time; - char szBuffer[256]; - DWORD dwSize = 256; - while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == S_OK) { - deleteRegistryKey(hKeyChild, szBuffer); - dwSize = 256; - } - - RegCloseKey(hKeyChild); - RegDeleteKey(parent, target); -} - -STDAPI __declspec(dllexport) DllRegisterServer(void) { - char moduleName[512]; - HRESULT result = GetModuleFileName(g_hModule, moduleName, sizeof(moduleName)/sizeof(char)); - check(result, "GetModuleFileName() failed in RegisterServer()"); - - char clsidString[CLSID_STRING_SIZE]; - clsidToString(XWT_clsid, clsidString, sizeof(clsidString)); - - // build the key - char key[64]; - strcpy(key, "CLSID\\"); - strcat(key, clsidString); - - setRegistryKey(key, NULL, XWT_friendlyName); - setRegistryKey(key, "InprocServer32", moduleName); - setRegistryKey(key, "ProgID", XWT_programID); - setRegistryKey(key, "VersionIndependentProgID", XWT_versionIndependantProgramID); - setRegistryKey(XWT_versionIndependantProgramID, NULL, XWT_friendlyName); - setRegistryKey(XWT_versionIndependantProgramID, "CLSID", clsidString); - setRegistryKey(XWT_versionIndependantProgramID, "CurVer", XWT_programID); - setRegistryKey(XWT_programID, NULL, XWT_friendlyName); - setRegistryKey(XWT_programID, "CLSID", clsidString); - return S_OK; -} - -STDAPI __declspec(dllexport) DllUnregisterServer(void) { - char clsidString[CLSID_STRING_SIZE]; - clsidToString(XWT_clsid, clsidString, sizeof(clsidString)); - - // build the key - char key[64]; - strcpy(key, "CLSID\\"); - strcat(key, clsidString); - - deleteRegistryKey(HKEY_CLASSES_ROOT, key); - deleteRegistryKey(HKEY_CLASSES_ROOT, XWT_versionIndependantProgramID); - deleteRegistryKey(HKEY_CLASSES_ROOT, XWT_programID); - return S_OK; -} - - - -// ShoeHorn ////////////////////////////////////////////////////////////////////////////////// - -class ShoeHorn : public IShoeHorn { - public: - virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) { - if(iid == IID_IUnknown) *ppv = static_cast(this); - else if(iid == XWT_clsid) *ppv = static_cast(this); - else if(iid == IID_IPersistPropertyBag) *ppv = static_cast(this); - else if(iid == IID_IObjectSafety) *ppv = static_cast(this); - else { *ppv = NULL; return E_NOINTERFACE; } - reinterpret_cast(*ppv)->AddRef(); - return S_OK; - } - virtual ULONG __stdcall AddRef() { return InterlockedIncrement(&m_cRef); } - virtual ULONG __stdcall Release() { - if(InterlockedDecrement(&m_cRef) == 0) { delete this; return 0; } - return m_cRef; - } - virtual HRESULT __stdcall GetClassID(CLSID*) { return S_OK; } - virtual HRESULT __stdcall InitNew() { return S_OK; } - virtual HRESULT __stdcall Save(IPropertyBag*, int, int) { return S_OK; } - virtual HRESULT __stdcall SetInterfaceSafetyOptions(REFIID riid, DWORD pdwSupportedOptions, DWORD pdwEnabledOptions) { return S_OK; } - virtual HRESULT __stdcall GetInterfaceSafetyOptions(REFIID riid, DWORD* pdwSupportedOptions, DWORD* pdwEnabledOptions) { - if (pdwSupportedOptions != NULL) *pdwSupportedOptions |= INTERFACESAFE_FOR_UNTRUSTED_DATA; - if (pdwEnabledOptions != NULL) *pdwSupportedOptions |= INTERFACESAFE_FOR_UNTRUSTED_DATA; - return S_OK; - } - - virtual HRESULT __stdcall Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog) { - VARIANT v; - v.vt = VT_BSTR; - HRESULT hrRead; - - WCHAR wc[100]; - char url[100]; - - MultiByteToWideChar(CP_ACP, 0, "initial-xwar-url", -1, wc, 100); - pPropBag->Read(wc, &v, pErrorLog); - check(WideCharToMultiByte(CP_ACP, 0, v.bstrVal, -1, url, 100, NULL, NULL), - "WideCharToMultiByte() failed in ShoeHorn::Load()"); - - HKEY hkey; - LONG result = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ActiveX Cache", &hkey); - check(result == ERROR_SUCCESS, "RegOpenKey() failed in ShoeHorn::Load()"); - - // iterate over all the activex cache locations until we find ourselves - for(int i=0; i<9; i++) { - DWORD buflen = 999; - char buf[1000]; - VALENT valents[20]; - DWORD type; - char which[2]; - - which[0] = '0' + i; - which[1] = '\0'; - result = RegQueryValueEx(hkey, which, NULL, &type, (BYTE*)buf, &buflen); - if (result != ERROR_SUCCESS) - if (i == 0) { - check(0, "RegQueryValueEx() failed in ShoeHorn::Load()"); - } else { - break; - } - buf[buflen] = '\0'; - - char cmdline[200]; - for(int i=0; i<200; i++) cmdline[i] = '\0'; - strncpy(cmdline, buf, 200); - strncpy(cmdline + strlen(cmdline), "\\xwt-" BUILDID ".exe", 200 - strlen(cmdline)); - strncpy(cmdline + strlen(cmdline), " ", 200 - strlen(cmdline)); - strncpy(cmdline + strlen(cmdline), url, 200 - strlen(cmdline)); - - PROCESS_INFORMATION pInfo; - STARTUPINFO sInfo; - sInfo.cb = sizeof(STARTUPINFO); - sInfo.lpReserved = NULL; - sInfo.lpReserved2 = NULL; - sInfo.cbReserved2 = 0; - sInfo.lpDesktop = NULL; - sInfo.lpTitle = NULL; - sInfo.dwFlags = 0; - sInfo.dwX = 0; - sInfo.dwY = 0; - sInfo.dwFillAttribute = 0; - sInfo.wShowWindow = SW_SHOW; - BOOL b = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &sInfo, &pInfo); - if (b) return S_OK; - } - - check(0, "unable to locate xwt-" BUILDID ".exe in ActiveX cache folders"); - } - - ShoeHorn() : m_cRef(1) { }; - ~ShoeHorn() { }; - private: long m_cRef; -}; - - - - -// ClassFactory ////////////////////////////////////////////////////////////////////////// - -class ClassFactory : public IClassFactory { - public: - virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) { - if(iid == IID_IUnknown) *ppv = static_cast(this); - else if(iid == IID_IClassFactory) *ppv = static_cast(this); - else { - *ppv = NULL; - return E_NOINTERFACE; - } - reinterpret_cast(*ppv)->AddRef(); - return S_OK; - } - - ClassFactory() : m_cRef(1) { } - ~ClassFactory() { } - virtual HRESULT __stdcall LockServer(BOOL bLock) { return S_OK; } - virtual ULONG __stdcall AddRef() { return InterlockedIncrement(&m_cRef); } - virtual ULONG __stdcall Release() { - if(InterlockedDecrement(&m_cRef) == 0) { - delete this; - return 0; - } - return m_cRef; - } - - virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) { - if(pUnknownOuter != NULL) return CLASS_E_NOAGGREGATION; - ShoeHorn* s = new ShoeHorn; - if(s == NULL) return E_OUTOFMEMORY; - HRESULT hr = s->QueryInterface(iid, ppv); - s->Release(); - return hr; - } - - private: long m_cRef; -}; - - -extern "C" __stdcall HRESULT DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppv) { - if(clsid != XWT_clsid) return CLASS_E_CLASSNOTAVAILABLE; - ClassFactory* pFactory = new ClassFactory; - if(pFactory == NULL) return E_OUTOFMEMORY; - HRESULT hr = pFactory->QueryInterface(iid, ppv); - pFactory->Release(); - return hr; -} - -#endif