Author: fireball Date: Fri Dec 24 17:34:14 2010 New Revision: 50127
URL: http://svn.reactos.org/svn/reactos?rev=50127&view=rev Log: - Support scenario when GetDC() is performed on an invisible window. Previously, this problem led to getting DC of a whole screen, but the proper solution is to restrict any drawing to such DC. This fixes drawing issues in GTK based apps. - Add get_device_rect (from Wine source code) and use it to map coordinates in Rectangle implementation. - Silence IsSelectionOwner() debug print.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/clipboard.c branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
Modified: branches/arwinss/reactos/dll/win32/winent.drv/clipboard.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/clipboard.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/clipboard.c [iso-8859-1] Fri Dec 24 17:34:14 2010 @@ -2437,7 +2437,7 @@ */ static BOOL NTDRV_CLIPBOARD_IsSelectionOwner(void) { - UNIMPLEMENTED; + //UNIMPLEMENTED; //return selectionAcquired; return TRUE; }
Modified: branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/gdidrv.c [iso-8859-1] Fri Dec 24 17:34:14 2010 @@ -31,6 +31,38 @@
BOOL CDECL RosDrv_PatBlt( NTDRV_PDEVICE *physDev, INT left, INT top, INT width, INT height, DWORD rop );
+/* get the rectangle in device coordinates, with optional mirroring */ +static RECT get_device_rect( HDC hdc, int left, int top, int right, int bottom ) +{ + RECT rect; + + rect.left = left; + rect.top = top; + rect.right = right; + rect.bottom = bottom; + if (GetLayout( hdc ) & LAYOUT_RTL) + { + /* shift the rectangle so that the right border is included after mirroring */ + /* it would be more correct to do this after LPtoDP but that's not what Windows does */ + rect.left--; + rect.right--; + } + LPtoDP( hdc, (POINT *)&rect, 2 ); + if (rect.left > rect.right) + { + int tmp = rect.left; + rect.left = rect.right; + rect.right = tmp; + } + if (rect.top > rect.bottom) + { + int tmp = rect.top; + rect.top = rect.bottom; + rect.bottom = tmp; + } + return rect; +} + BOOL CDECL RosDrv_AlphaBlend(NTDRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst, NTDRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, BLENDFUNCTION blendfn) @@ -317,8 +349,6 @@ INT CDECL RosDrv_ExtEscape( NTDRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID in_data, INT out_count, LPVOID out_data ) { - HWND hwnd; - switch(escape) { case NTDRV_ESCAPE: @@ -333,10 +363,8 @@
RosGdiSetDcRects(physDev->hKernelDC, (RECT*)&data->dc_rect, (RECT*)&data->drawable_rect);
- hwnd = GetAncestor(data->hwnd, GA_ROOT); - if (!data->release) - RosGdiGetDC(physDev->hKernelDC, hwnd, data->clip_children); + RosGdiGetDC(physDev->hKernelDC, data->hwnd, data->clip_children); else RosGdiReleaseDC(physDev->hKernelDC);
@@ -613,11 +641,7 @@ BOOL CDECL RosDrv_Rectangle(NTDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom) { POINT ptBrush; - RECT rc; - - /* Convert coordinates */ - SetRect(&rc, left, top, right, bottom); - LPtoDP(physDev->hUserDC, (POINT*)&rc, 2); + RECT rc = get_device_rect( physDev->hUserDC, left, top, right, bottom );
if ((rc.left == rc.right) || (rc.top == rc.bottom)) return TRUE;
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Fri Dec 24 17:34:14 2010 @@ -360,40 +360,13 @@ { struct ntdrv_escape_set_drawable escape; struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd ); + //HWND parent;
escape.code = NTDRV_SET_DRAWABLE; escape.clip_children = FALSE; escape.gl_copy = FALSE; - escape.hwnd = hwnd; + escape.hwnd = 0; escape.release = FALSE; - - if (top == hwnd && data && IsIconic( hwnd ) /*&& data->icon_window*/) - { - //escape.drawable = data->icon_window; - } - else if (top == hwnd) - { - //escape.fbconfig_id = data ? data->fbconfig_id : (XID)GetPropA( hwnd, fbconfig_id_prop ); - /* GL draws to the client area even for window DCs */ - /*escape.gl_drawable = data ? data->client_window : X11DRV_get_client_window( hwnd ); - if (flags & DCX_WINDOW) - escape.drawable = data ? data->whole_window : X11DRV_get_whole_window( hwnd ); - else - escape.drawable = escape.gl_drawable;*/ - } - else - { - //escape.drawable = X11DRV_get_client_window( top ); - //escape.fbconfig_id = data ? data->fbconfig_id : (XID)GetPropA( hwnd, fbconfig_id_prop ); - //escape.gl_drawable = data ? data->gl_drawable : (Drawable)GetPropA( hwnd, gl_drawable_prop ); - //escape.pixmap = data ? data->pixmap : (Pixmap)GetPropA( hwnd, pixmap_prop ); - //escape.gl_copy = (escape.gl_drawable != 0); - - if (flags & DCX_CLIPCHILDREN) escape.clip_children = TRUE; - } - - //FIXME("hdc %x, hwnd %x, top %x\n win_rect %s, top_rect %s\n", hdc, hwnd, top, - // wine_dbgstr_rect(win_rect), wine_dbgstr_rect(top_rect));
escape.dc_rect.left = win_rect->left - top_rect->left; escape.dc_rect.top = win_rect->top - top_rect->top; @@ -403,6 +376,69 @@ escape.drawable_rect.top = top_rect->top; escape.drawable_rect.right = top_rect->right; escape.drawable_rect.bottom = top_rect->bottom; + + if (top == hwnd) + { + //if (flags & DCX_WINDOW) + { + if (data) + { + /* SWM window already exists */ + escape.hwnd = hwnd; + } + else + { + /* There is no SWM window for this hwnd. + If this is desktop, it's fine otherwise reject any drawing operations */ + if (hwnd == GetDesktopWindow()) + escape.hwnd = hwnd; + else + escape.hwnd = 0; + } + } + } + else + { +#if 0 + /* find the first ancestor that has a drawable */ + if (data) escape.hwnd = hwnd; + + for (parent = hwnd; parent && parent != top; parent = GetAncestor( parent, GA_PARENT )) + { + data = NTDRV_get_win_data( parent ); + if (data) + { + escape.hwnd = parent; + break; + } + } +FIXME("Found hwnd %x backed by an SWM window\n", escape.hwnd); + if (escape.hwnd) + { + POINT pt = { 0, 0 }; + MapWindowPoints( top, parent, &pt, 1 ); + //OffsetRect( &escape.dc_rect, pt.x, pt.y ); + //OffsetRect( &escape.drawable_rect, -pt.x, -pt.y ); + + FIXME("Offset by (%d, %d)\n", pt.x, pt.y); + } + else + { + if (NTDRV_get_win_data(top) || (top == GetDesktopWindow())) + { + /* SWM window already exists */ + escape.hwnd = top; + } + } +#else + escape.hwnd = GetAncestor(hwnd, GA_ROOT); +#endif + + if (flags & DCX_CLIPCHILDREN) escape.clip_children = TRUE; + } + + TRACE("hdc %x, hwnd %x, top %x\n win_rect %s, top_rect %s\n", hdc, hwnd, top, + wine_dbgstr_rect(win_rect), wine_dbgstr_rect(top_rect));
ExtEscape( hdc, NTDRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); }