Beispiel #1
0
/* mirror a region relative to a window client rect */
void mirror_region( const rectangle_t *client_rect, struct region *region )
{
    int start, end, i, j;

    for (start = 0; start < region->num_rects; start = end + 1)
    {
        for (end = start; end < region->num_rects - 1; end++)
            if (region->rects[end + 1].top != region->rects[end].top) break;
        for (i = start, j = end; i < j; i++, j--)
        {
            rectangle_t rect = region->rects[j];
            region->rects[i] = region->rects[j];
            region->rects[j] = rect;
            mirror_rect( client_rect, &region->rects[j] );
            mirror_rect( client_rect, &region->rects[i] );
        }
        if (i == j) mirror_rect( client_rect, &region->rects[i] );
    }
    mirror_rect( client_rect, &region->extents );
}
Beispiel #2
0
/**********************************************************************
 *           ExtEscape  (X11DRV.@)
 */
static INT X11DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
                      INT out_count, LPVOID out_data )
{
    X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );

    switch(escape)
    {
    case QUERYESCSUPPORT:
        if (in_data && in_count >= sizeof(DWORD))
        {
            switch (*(const INT *)in_data)
            {
            case X11DRV_ESCAPE:
                return TRUE;
            }
        }
        break;

    case X11DRV_ESCAPE:
        if (in_data && in_count >= sizeof(enum x11drv_escape_codes))
        {
            switch(*(const enum x11drv_escape_codes *)in_data)
            {
            case X11DRV_SET_DRAWABLE:
                if (in_count >= sizeof(struct x11drv_escape_set_drawable))
                {
                    const struct x11drv_escape_set_drawable *data = in_data;
                    physDev->dc_rect = data->dc_rect;
                    physDev->drawable = data->drawable;
                    XFreeGC( gdi_display, physDev->gc );
                    physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
                    XSetGraphicsExposures( gdi_display, physDev->gc, False );
                    XSetSubwindowMode( gdi_display, physDev->gc, data->mode );
                    TRACE( "SET_DRAWABLE hdc %p drawable %lx dc_rect %s\n",
                           dev->hdc, physDev->drawable, wine_dbgstr_rect(&physDev->dc_rect) );
                    return TRUE;
                }
                break;
            case X11DRV_GET_DRAWABLE:
                if (out_count >= sizeof(struct x11drv_escape_get_drawable))
                {
                    struct x11drv_escape_get_drawable *data = out_data;
                    data->drawable = physDev->drawable;
                    data->dc_rect = physDev->dc_rect;
                    return TRUE;
                }
                break;
            case X11DRV_FLUSH_GL_DRAWABLE:
                if (in_count >= sizeof(struct x11drv_escape_flush_gl_drawable))
                {
                    const struct x11drv_escape_flush_gl_drawable *data = in_data;
                    RECT rect = physDev->dc_rect;

                    OffsetRect( &rect, -physDev->dc_rect.left, -physDev->dc_rect.top );
                    /* The GL drawable may be lagged behind if we don't flush first, so
                     * flush the display make sure we copy up-to-date data */
                    XFlush( gdi_display );
                    XSetFunction( gdi_display, physDev->gc, GXcopy );
                    XCopyArea( gdi_display, data->gl_drawable, physDev->drawable, physDev->gc,
                               0, 0, rect.right, rect.bottom,
                               physDev->dc_rect.left, physDev->dc_rect.top );
                    add_device_bounds( physDev, &rect );
                    return TRUE;
                }
                break;
            case X11DRV_START_EXPOSURES:
                XSetGraphicsExposures( gdi_display, physDev->gc, True );
                physDev->exposures = 0;
                return TRUE;
            case X11DRV_END_EXPOSURES:
                if (out_count >= sizeof(HRGN))
                {
                    HRGN hrgn = 0, tmp = 0;

                    XSetGraphicsExposures( gdi_display, physDev->gc, False );
                    if (physDev->exposures)
                    {
                        for (;;)
                        {
                            XEvent event;

                            XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
                            if (event.type == NoExpose) break;
                            if (event.type == GraphicsExpose)
                            {
                                RECT rect;

                                rect.left   = event.xgraphicsexpose.x - physDev->dc_rect.left;
                                rect.top    = event.xgraphicsexpose.y - physDev->dc_rect.top;
                                rect.right  = rect.left + event.xgraphicsexpose.width;
                                rect.bottom = rect.top + event.xgraphicsexpose.height;
                                if (GetLayout( dev->hdc ) & LAYOUT_RTL)
                                    mirror_rect( &physDev->dc_rect, &rect );

                                TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect),
                                       event.xgraphicsexpose.count );

                                if (!tmp) tmp = CreateRectRgnIndirect( &rect );
                                else SetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom );
                                if (hrgn) CombineRgn( hrgn, hrgn, tmp, RGN_OR );
                                else
                                {
                                    hrgn = tmp;
                                    tmp = 0;
                                }
                                if (!event.xgraphicsexpose.count) break;
                            }
                            else
                            {
                                ERR( "got unexpected event %d\n", event.type );
                                break;
                            }
                        }
                        if (tmp) DeleteObject( tmp );
                    }
                    *(HRGN *)out_data = hrgn;
                    return TRUE;
                }
                break;
            default:
                break;
            }
        }
        break;
    }
    return 0;
}
Beispiel #3
0
/**********************************************************************
 *           ExtEscape  (X11DRV.@)
 */
static INT X11DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
                      INT out_count, LPVOID out_data )
{
    X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );

    switch(escape)
    {
    case QUERYESCSUPPORT:
        if (in_data)
        {
            switch (*(const INT *)in_data)
            {
            case DCICOMMAND:
                return DD_HAL_VERSION;
            case X11DRV_ESCAPE:
                return TRUE;
            }
        }
        break;

    case X11DRV_ESCAPE:
        if (in_data && in_count >= sizeof(enum x11drv_escape_codes))
        {
            switch(*(const enum x11drv_escape_codes *)in_data)
            {
            case X11DRV_SET_DRAWABLE:
                if (in_count >= sizeof(struct x11drv_escape_set_drawable))
                {
                    const struct x11drv_escape_set_drawable *data = in_data;
                    physDev->dc_rect = data->dc_rect;
                    physDev->drawable = data->drawable;
                    wine_tsx11_lock();
                    XSetSubwindowMode( gdi_display, physDev->gc, data->mode );
                    wine_tsx11_unlock();
                    TRACE( "SET_DRAWABLE hdc %p drawable %lx dc_rect %s\n",
                           dev->hdc, physDev->drawable, wine_dbgstr_rect(&physDev->dc_rect) );
                    return TRUE;
                }
                break;
            case X11DRV_GET_DRAWABLE:
                if (out_count >= sizeof(struct x11drv_escape_get_drawable))
                {
                    struct x11drv_escape_get_drawable *data = out_data;
                    data->drawable = physDev->drawable;
                    return TRUE;
                }
                break;
            case X11DRV_START_EXPOSURES:
                wine_tsx11_lock();
                XSetGraphicsExposures( gdi_display, physDev->gc, True );
                wine_tsx11_unlock();
                physDev->exposures = 0;
                return TRUE;
            case X11DRV_END_EXPOSURES:
                if (out_count >= sizeof(HRGN))
                {
                    HRGN hrgn = 0, tmp = 0;

                    wine_tsx11_lock();
                    XSetGraphicsExposures( gdi_display, physDev->gc, False );
                    wine_tsx11_unlock();
                    if (physDev->exposures)
                    {
                        for (;;)
                        {
                            XEvent event;

                            wine_tsx11_lock();
                            XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
                            wine_tsx11_unlock();
                            if (event.type == NoExpose) break;
                            if (event.type == GraphicsExpose)
                            {
                                RECT rect;

                                rect.left   = event.xgraphicsexpose.x - physDev->dc_rect.left;
                                rect.top    = event.xgraphicsexpose.y - physDev->dc_rect.top;
                                rect.right  = rect.left + event.xgraphicsexpose.width;
                                rect.bottom = rect.top + event.xgraphicsexpose.height;
                                if (GetLayout( dev->hdc ) & LAYOUT_RTL)
                                    mirror_rect( &physDev->dc_rect, &rect );

                                TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect),
                                       event.xgraphicsexpose.count );

                                if (!tmp) tmp = CreateRectRgnIndirect( &rect );
                                else SetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom );
                                if (hrgn) CombineRgn( hrgn, hrgn, tmp, RGN_OR );
                                else
                                {
                                    hrgn = tmp;
                                    tmp = 0;
                                }
                                if (!event.xgraphicsexpose.count) break;
                            }
                            else
                            {
                                ERR( "got unexpected event %d\n", event.type );
                                break;
                            }
                        }
                        if (tmp) DeleteObject( tmp );
                    }
                    *(HRGN *)out_data = hrgn;
                    return TRUE;
                }
                break;
            default:
                break;
            }
        }
        break;
    }
    return 0;
}
Beispiel #4
0
BOOL FASTCALL
IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect)
{
   BOOL vertical;
   *lprect = Wnd->rcClient;

   RECTL_vOffsetRect( lprect, -Wnd->rcWindow.left, -Wnd->rcWindow.top );
   if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
      mirror_rect( &Wnd->rcWindow, lprect );

   switch (nBar)
   {
      case SB_HORZ:
         lprect->top = lprect->bottom;
         lprect->bottom += UserGetSystemMetrics (SM_CYHSCROLL);
         if (Wnd->style & WS_BORDER)
         {
            lprect->left--;
            lprect->right++;
         }
         else if (Wnd->style & WS_VSCROLL)
         {
            lprect->right++;
         }
         vertical = FALSE;
         break;

      case SB_VERT:
         if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR)
         {
            lprect->right = lprect->left;
            lprect->left -= UserGetSystemMetrics(SM_CXVSCROLL);
         }
         else
         {
            lprect->left = lprect->right;
            lprect->right += UserGetSystemMetrics(SM_CXVSCROLL);
         }
         if (Wnd->style & WS_BORDER)
         {
            lprect->top--;
            lprect->bottom++;
         }
         else if (Wnd->style & WS_HSCROLL)
         {
            lprect->bottom++;
         }
         vertical = TRUE;
         break;

      case SB_CTL:
         IntGetClientRect (Wnd, lprect);
         vertical = !!(Wnd->style & SBS_VERT);
         break;

      default:
         return FALSE;
   }

   return vertical;
}
Beispiel #5
0
/***********************************************************************
 *           IntScrollGetScrollBarRect
 *
 * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
 * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
 * 'arrowSize' returns the width or height of an arrow (depending on
 * the orientation of the scrollbar), 'thumbSize' returns the size of
 * the thumb, and 'thumbPos' returns the position of the thumb
 * relative to the left or to the top.
 * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
 */
static BOOL FASTCALL
IntScrollGetScrollBarRect(HWND Wnd, INT Bar, RECT *Rect,
                          INT *ArrowSize, INT *ThumbSize,
                          INT *ThumbPos)
{
  INT Pixels;
  BOOL Vertical;
  PWND pWnd;
  PSBINFO pSBInfo;
  PSBDATA pSBData;
  PSBWND pSBWnd;

  pWnd = ValidateHwnd( Wnd );
  if (!pWnd) return FALSE;
  pSBInfo = DesktopPtrToUser(pWnd->pSBInfo);

  *Rect = pWnd->rcClient;
  OffsetRect( Rect, -pWnd->rcWindow.left, -pWnd->rcWindow.top );
  if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
     mirror_rect( &pWnd->rcWindow, Rect );

  switch (Bar)
    {
      case SB_HORZ:
//        WIN_GetRectangles( Wnd, COORDS_WINDOW, NULL, Rect );
        Rect->top = Rect->bottom;
        Rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
	if (pWnd->style & WS_BORDER)
        {
            Rect->left--;
            Rect->right++;
	}
        else if (pWnd->style & WS_VSCROLL)
        {
            Rect->right++;
        }
        Vertical = FALSE;
        pSBData = &pSBInfo->Horz;
	break;

      case SB_VERT:
//        WIN_GetRectangles( Wnd, COORDS_WINDOW, NULL, Rect );
        if (pWnd->ExStyle & WS_EX_LEFTSCROLLBAR)
        {
            Rect->right = Rect->left;
            Rect->left -= GetSystemMetrics(SM_CXVSCROLL);
        }
        else
        {
            Rect->left = Rect->right;
            Rect->right += GetSystemMetrics(SM_CXVSCROLL);
        }
	if (pWnd->style & WS_BORDER)
        {
            Rect->top--;
            Rect->bottom++;
        }
        else if (pWnd->style & WS_HSCROLL)
        {
            Rect->bottom++;
        }
        Vertical = TRUE;
        pSBData = &pSBInfo->Vert;
	break;

      case SB_CTL:
        GetClientRect( Wnd, Rect );
        Vertical = (pWnd->style & SBS_VERT);
        pSBWnd = (PSBWND)pWnd;
        pSBData = (PSBDATA)&pSBWnd->SBCalc;
	break;

      default:
        return FALSE;
    }

  if (Vertical) Pixels = Rect->bottom - Rect->top;
  else Pixels = Rect->right - Rect->left;

  if (Pixels <= 2 * GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT)
  {
      if (SCROLL_MIN_RECT < Pixels)
          *ArrowSize = (Pixels - SCROLL_MIN_RECT) / 2;
      else
          *ArrowSize = 0;
      *ThumbPos = *ThumbSize = 0;
  }
  else
  {
      *ArrowSize = GetSystemMetrics(SM_CXVSCROLL);
      Pixels -= (2 * (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP));
      if (pSBData->page)
      {
          *ThumbSize = MulDiv(Pixels, pSBData->page, (pSBData->posMax - pSBData->posMin + 1));
          if (*ThumbSize < SCROLL_MIN_THUMB) *ThumbSize = SCROLL_MIN_THUMB;
      }
      else *ThumbSize = GetSystemMetrics(SM_CXVSCROLL);

      if (((Pixels -= *ThumbSize ) < 0) ||
          (( pSBInfo->WSBflags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
      {
          /* Rectangle too small or scrollbar disabled -> no thumb */
          *ThumbPos = *ThumbSize = 0;
      }
      else
      {
          INT Max = pSBData->posMax - max(pSBData->page - 1, 0);
          if (pSBData->posMin >= Max)
              *ThumbPos = *ArrowSize - SCROLL_ARROW_THUMB_OVERLAP;
          else
              *ThumbPos = *ArrowSize - SCROLL_ARROW_THUMB_OVERLAP
              + MulDiv(Pixels, (pSBData->pos - pSBData->posMin),(Max - pSBData->posMin));
      }
  }
  return Vertical;
}