示例#1
0
bool wxRegion::Intersect( const wxRegion& region )
{
#if 0
    if (region.IsNull())
        return FALSE;

    if (!m_refData)
    {
        m_refData = new wxRegionRefData();
        M_REGIONDATA->m_region = XCreateRegion();
        
        // leave here 
        return TRUE;
    }
    else
    {
        AllocExclusive();
    }

    XIntersectRegion( M_REGIONDATA->m_region,
                      M_REGIONDATA_OF(region)->m_region,
                      M_REGIONDATA->m_region );
#endif
    return TRUE;
}
示例#2
0
/* lpStruct - Destination Region */
DWORD
DrvRegionsIntersectRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	XIntersectRegion((Region)dwParm1, (Region)dwParm2, (Region)lpStruct);
	return (DWORD)(XEmptyRegion((Region)lpStruct)?
				NULLREGION:COMPLEXREGION);
}
static void
fxDodgeProcessSubject (CompWindow *wCur,
		       Region wRegion,
		       Region dodgeRegion,
		       Bool alwaysInclude)
{
    XRectangle rect;
    rect.x = WIN_X(wCur);
    rect.y = WIN_Y(wCur);
    rect.width = WIN_W(wCur);
    rect.height = WIN_H(wCur);
    Region wCurRegion = XCreateRegion();
    if (!wCurRegion)
	return;

    XUnionRectWithRegion(&rect, &emptyRegion, wCurRegion);
    if (!alwaysInclude)
    {
	Region intersectionRegion = XCreateRegion();
	if (intersectionRegion)
	{
	    XIntersectRegion(wRegion, wCurRegion,
			     intersectionRegion);
	    if (!XEmptyRegion(intersectionRegion))
		XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion);
	    XDestroyRegion (intersectionRegion);
	}
    }
    else
	XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion);

    XDestroyRegion (wCurRegion);
}
示例#4
0
static void
minSetShade (CompWindow *w,
             int        shade)
{
	REGION rect;
	int    h = w->attrib.height + w->attrib.border_width * 2;

	MIN_WINDOW (w);

	EMPTY_REGION (w->region);

	rect.rects = &rect.extents;
	rect.numRects = rect.size = 1;

	w->height = shade;

	rect.extents.x1 = 0;
	rect.extents.y1 = h - shade;
	rect.extents.x2 = w->width;
	rect.extents.y2 = h;

	XIntersectRegion (mw->region, &rect, w->region);
	XOffsetRegion (w->region, w->attrib.x, w->attrib.y - (h - shade));

	w->matrix = w->texture->matrix;
	w->matrix.x0 -= (w->attrib.x * w->matrix.xx);
	w->matrix.y0 -= ((w->attrib.y - (h - shade)) * w->matrix.yy);

	(*w->screen->windowResizeNotify) (w, 0, 0, 0, 0);
}
示例#5
0
// Intersect & push a new clip rectangle:
void Fl_Device::push_clip(int x, int y, int w, int h)
{
    Region r;
    if (w > 0 && h > 0)
    {
        fl_transform(x,y);
        r = XRectangleRegion(x, y, w, h);
        Region current = rstack[rstackptr];
        if (current)
        {
#ifndef _WIN32
            Region temp = XCreateRegion();
            XIntersectRegion(current, r, temp);
            XDestroyRegion(r);
            r = temp;
#else
            CombineRgn(r,r,current,RGN_AND);
#endif
        }
    }                            // make empty clip region:
    else
    {
#ifndef _WIN32
        r = XCreateRegion();
#else
        r = CreateRectRgn(0,0,0,0);
#endif
    }
    if (rstackptr < STACK_MAX) rstack[++rstackptr] = r;
    fl_restore_clip();
}
示例#6
0
void sClipRect(const sRect &r)
{
  sVERIFY(ClipIndex != 0);
  Region temp = sRectToRegion(r);
  XIntersectRegion(ClipStack[ClipIndex],temp,ClipStack[ClipIndex]);
  XDestroyRegion(temp);
  sChangedRegions();
}
示例#7
0
CompRegion
CompRegion::intersected (const CompRect &r) const
{
    CompRegion reg (r);
    reg.priv->makeReal ();
    XIntersectRegion (reg.handle (), handle (), reg.handle ());
    return reg;
}
示例#8
0
EAPI Eina_Bool
ecore_x_xregion_intersect(Ecore_X_XRegion *dst,
                          Ecore_X_XRegion *r1,
                          Ecore_X_XRegion *r2)
{
   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   return XIntersectRegion((Region)r1, (Region)r2, (Region)dst) ? EINA_TRUE : EINA_FALSE;
} /* ecore_x_xregion_intersect */
示例#9
0
void X11Factory::getMonitorInfo( const GenericWindow &rWindow,
                                 int* p_x, int* p_y,
                                 int* p_width, int* p_height ) const
{
    // initialize to default geometry
    *p_x = 0;
    *p_y = 0;
    *p_width = getScreenWidth();
    *p_height = getScreenHeight();

    // Use Xinerama to determine the monitor where the video
    // mostly resides (biggest surface)
    Display *pDisplay = m_pDisplay->getDisplay();
    Window wnd = (Window)rWindow.getOSHandle();
    Window root = DefaultRootWindow( pDisplay );
    Window child_wnd;

    int x, y;
    unsigned int w, h, border, depth;
    XGetGeometry( pDisplay, wnd, &root, &x, &y, &w, &h, &border, &depth );
    XTranslateCoordinates( pDisplay, wnd, root, 0, 0, &x, &y, &child_wnd );

    int num;
    XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
    if( info )
    {
        Region reg1 = XCreateRegion();
        XRectangle rect1 = { (short)x, (short)y, (unsigned short)w, (unsigned short)h };
        XUnionRectWithRegion( &rect1, reg1, reg1 );

        unsigned int surface = 0;
        for( int i = 0; i < num; i++ )
        {
            Region reg2 = XCreateRegion();
            XRectangle rect2 = { info[i].x_org, info[i].y_org,
                                 (unsigned short)info[i].width, (unsigned short)info[i].height };
            XUnionRectWithRegion( &rect2, reg2, reg2 );

            Region reg = XCreateRegion();
            XIntersectRegion( reg1, reg2, reg );
            XRectangle rect;
            XClipBox( reg, &rect );
            unsigned int surf = rect.width * rect.height;
            if( surf > surface )
            {
               surface = surf;
               *p_x = info[i].x_org;
               *p_y = info[i].y_org;
               *p_width = info[i].width;
               *p_height = info[i].height;
            }
            XDestroyRegion( reg );
            XDestroyRegion( reg2 );
        }
        XDestroyRegion( reg1 );
        XFree( info );
    }
}
示例#10
0
文件: apc_region.c 项目: dk/Prima
Bool
apc_gp_set_region( Handle self, Handle rgn)
{
	DEFXX;
	Region region;
	PRegionSysData r;

	if ( PObject( self)-> options. optInDrawInfo) return false;
	if ( !XF_IN_PAINT(XX)) return false;

	if (rgn == nilHandle) {
		Rect r;
		r. left   = 0;
		r. bottom = 0;
		r. right  = XX-> size. x - 1;
		r. top	  = XX-> size. y - 1;
		return apc_gp_set_clip_rect( self, r);
	}

	r = GET_REGION(rgn);

	XClipBox( r-> region, &XX-> clip_rect);
	XX-> clip_rect. y += XX-> size. y - r-> height;
	XX-> clip_mask_extent. x = XX-> clip_rect. width;
	XX-> clip_mask_extent. y = XX-> clip_rect. height;
	if ( XX-> clip_rect. width == 0 || XX-> clip_rect. height == 0) {
		Rect r;
		r. left   = -1;
		r. bottom = -1;
		r. right  = -1;
		r. top	  = -1;
		return apc_gp_set_clip_rect( self, r);
	}

	region = XCreateRegion();
	XUnionRegion( region, r-> region, region);
	/* offset region if drawable is buffered */
	XOffsetRegion( region, XX-> btransform. x, XX-> size.y - r-> height - XX-> btransform. y);
	/* otherwise ( and only otherwise ), and if there's a
		X11 clipping, intersect the region with it. X11 clipping
		must not mix with the buffer clipping */
	if (( !XX-> udrawable || XX-> udrawable == XX-> gdrawable) &&
		XX-> paint_region)
		XIntersectRegion( region, XX-> paint_region, region);
	XSetRegion( DISP, XX-> gc, region);
	if ( XX-> flags. kill_current_region)
		XDestroyRegion( XX-> current_region);
	XX-> flags. kill_current_region = 1;
	XX-> current_region = region;
	XX-> flags. xft_clip = 0;
#ifdef USE_XFT
	if ( XX-> xft_drawable) prima_xft_update_region( self);
#endif
#ifdef HAVE_X11_EXTENSIONS_XRENDER_H
	if ( XX-> argb_picture ) XRenderSetPictureClipRegion(DISP, XX->argb_picture, region);
#endif
	return true;
}
示例#11
0
// Intersect region r with this one
FXRegion FXRegion::operator*(const FXRegion& r) const {
  FXRegion res;
#ifdef WIN32
  CombineRgn((HRGN)res.region,(HRGN)region,(HRGN)r.region,RGN_AND);
#else
  XIntersectRegion((Region)region,(Region)r.region,(Region)res.region);
#endif
  return res;
  }
示例#12
0
static PyObject *
region_IntersectRegion(PaxRegionObject *self, PyObject *args)
{
    PaxRegionObject *r;
    if (!PyArg_ParseTuple(args, "O!", &PaxRegionType, &r))
	return NULL;
    XIntersectRegion(self->region, r->region, self->region);
    Py_INCREF(Py_None);
    return Py_None;
}
示例#13
0
// Intersect region r with this one
FXRegion& FXRegion::operator*=(const FXRegion& r){
#ifdef WIN32
  CombineRgn((HRGN)region,(HRGN)region,(HRGN)r.region,RGN_AND);
#else
  Region res=XCreateRegion();
  XIntersectRegion((Region)region,(Region)r.region,res);
  XDestroyRegion((Region)region);
  region=res;
#endif
  return *this;
  }
示例#14
0
void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
                                int ySrc, int xDest, int yDest, int width,
                                int height )
{
    const X11Graphics& rGraph = (X11Graphics&)rGraphics;

    // check and adapt to source if needed
    if( !checkBoundaries( 0, 0, rGraph.getWidth(), rGraph.getHeight(),
                          xSrc, ySrc, width, height ) )
    {
        msg_Err( getIntf(), "nothing to draw from graphics source" );
        return;
    }

    // check destination
    if( !checkBoundaries( 0, 0, m_width, m_height,
                          xDest, yDest, width, height ) )
    {
        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
        return;
    }

    // Source drawable
    Drawable src = rGraph.getDrawable();

    // Create the mask for transparency
    Region voidMask = XCreateRegion();
    XRectangle rect;
    rect.x = xSrc;
    rect.y = ySrc;
    rect.width = width;
    rect.height = height;
    Region clipMask = XCreateRegion();
    XUnionRectWithRegion( &rect, voidMask, clipMask );
    Region mask = XCreateRegion();
    XIntersectRegion( rGraph.getMask(), clipMask, mask );
    XDestroyRegion( clipMask );
    XDestroyRegion( voidMask );
    XOffsetRegion( mask, xDest - xSrc, yDest - ySrc );

    // Copy the pixmap
    XSetRegion( XDISPLAY, m_gc, mask );
    XCopyArea( XDISPLAY, src, m_pixmap, m_gc, xSrc, ySrc, width, height,
               xDest, yDest );

    // Add the source mask to the mask of the graphics
    Region newMask = XCreateRegion();
    XUnionRegion( m_mask, mask, newMask );
    XDestroyRegion( mask );
    XDestroyRegion( m_mask );
    m_mask = newMask;
}
示例#15
0
文件: apc_region.c 项目: dk/Prima
Bool
apc_region_combine( Handle self, Handle other_region, int rgnop)
{
	PRegionSysData r2;
	int d;
	Bool ok = true;

	r2 = GET_REGION(other_region);

	if ( rgnop == rgnopCopy ) {
		if ( REGION ) XDestroyRegion( REGION );
		REGION = XCreateRegion();
		XUnionRegion( REGION, r2->region, REGION);
		HEIGHT = r2-> height;
		return true;
	}

	d = HEIGHT - r2-> height;
	if ( d > 0 )
		XOffsetRegion( r2-> region, 0, d);
	else
		XOffsetRegion( REGION, 0, -d);

	switch (rgnop) {
	case rgnopIntersect:
		XIntersectRegion( REGION, r2->region, REGION);
		break;
	case rgnopUnion:
		XUnionRegion( REGION, r2->region, REGION);
		break;
	case rgnopXor:
		XXorRegion( REGION, r2->region, REGION);
		break;
	case rgnopDiff:
		XSubtractRegion( REGION, r2->region, REGION);
		break;
	default:
		ok = false;
	}
	if ( d > 0 )
		XOffsetRegion( r2-> region, 0, -d);
	else
		HEIGHT = r2-> height;

	return ok;
}
示例#16
0
void X11Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,
                                int ySrc, int xDest, int yDest, int width,
                                int height )
{
    if( width == -1 )
    {
        width = rGraphics.getWidth();
    }
    if( height == -1 )
    {
        height = rGraphics.getHeight();
    }

    // Source drawable
    Drawable src = ((X11Graphics&)rGraphics).getDrawable();

    // Create the mask for transparency
    Region voidMask = XCreateRegion();
    XRectangle rect;
    rect.x = xSrc;
    rect.y = ySrc;
    rect.width = width;
    rect.height = height;
    Region clipMask = XCreateRegion();
    XUnionRectWithRegion( &rect, voidMask, clipMask );
    Region mask = XCreateRegion();
    XIntersectRegion( ((X11Graphics&)rGraphics).getMask(), clipMask, mask );
    XDestroyRegion( clipMask );
    XDestroyRegion( voidMask );
    XOffsetRegion( mask, xDest - xSrc, yDest - ySrc );

    // Copy the pixmap
    XSetRegion( XDISPLAY, m_gc, mask );
    XCopyArea( XDISPLAY, src, m_pixmap, m_gc, xSrc, ySrc, width, height,
               xDest, yDest );

    // Add the source mask to the mask of the graphics
    Region newMask = XCreateRegion();
    XUnionRegion( m_mask, mask, newMask );
    XDestroyRegion( mask );
    XDestroyRegion( m_mask );
    m_mask = newMask;
}
示例#17
0
文件: apc_region.c 项目: dk/Prima
Bool
apc_gp_set_clip_rect( Handle self, Rect clipRect)
{
	DEFXX;
	Region region;
	XRectangle r;

	if ( !XF_IN_PAINT(XX))
		return false;

	SORT( clipRect. left, clipRect. right);
	SORT( clipRect. bottom, clipRect. top);
	r. x = clipRect. left;
	r. y = REVERT( clipRect. top);
	r. width = clipRect. right - clipRect. left+1;
	r. height = clipRect. top - clipRect. bottom+1;
	XX-> clip_rect = r;
	XX-> clip_mask_extent. x = r. width;
	XX-> clip_mask_extent. y = r. height;
	region = XCreateRegion();
	XUnionRectWithRegion( &r, region, region);
	if ( XX-> paint_region)
		XIntersectRegion( region, XX-> paint_region, region);
	if ( XX-> btransform. x != 0 || XX-> btransform. y != 0) {
		XOffsetRegion( region, XX-> btransform. x, -XX-> btransform. y);
	}
	XSetRegion( DISP, XX-> gc, region);
	if ( XX-> flags. kill_current_region)
		XDestroyRegion( XX-> current_region);
	XX-> flags. kill_current_region = 1;
	XX-> current_region = region;
	XX-> flags. xft_clip = 0;
#ifdef USE_XFT
	if ( XX-> xft_drawable) prima_xft_update_region( self);
#endif
#ifdef HAVE_X11_EXTENSIONS_XRENDER_H
	if ( XX-> argb_picture ) XRenderSetPictureClipRegion(DISP, XX->argb_picture, region);
#endif
	return true;
}
示例#18
0
bool wxRegion::DoIntersect( const wxRegion& region )
{
    wxCHECK_MSG( region.Ok(), false, wxT("invalid region") );

    if (!m_refData)
    {
        m_refData = new wxRegionRefData();
        M_REGIONDATA->m_region = XCreateRegion();

        // leave here
        return true;
    }
    else
    {
        AllocExclusive();
    }

    XIntersectRegion( M_REGIONDATA->m_region,
                      M_REGIONDATA_OF(region)->m_region,
                      M_REGIONDATA->m_region );

    return true;
}
示例#19
0
文件: opacify.c 项目: jordigh/fusilli
/* Walk through all windows, skip until we've passed the active
 * window, skip if it's invisible, hidden or minimized, skip if
 * it's not a window type we're looking for.
 * Dim it if it intersects.
 *
 * Returns number of changed windows.
 */
static int
passiveWindows (CompScreen *s,
                Region     region)
{
	CompWindow *w;
	Bool flag = FALSE;
	int i = 0;

	OPACIFY_SCREEN (s);

	for (w = s->windows; w; w = w->next)
	{
		if (w->id == os->active)
		{
			flag = TRUE;
			continue;
		}

		if (!flag)
			continue;

		if (!matchEval (&os->window_match, w))
			continue;

		if (w->invisible || w->hidden || w->minimized)
			continue;

		XIntersectRegion (w->region, region, os->intersect);
		if (!XEmptyRegion (os->intersect))
		{
			dimWindow (w);
			i++;
		}
	}

	return i;
}
示例#20
0
int _zbar_window_draw_logo (zbar_window_t *w)
{
    window_state_t *x = w->state;
    int screen = DefaultScreen(w->display);

    /* clear to white */
    XSetForeground(w->display, x->gc, WhitePixel(w->display, screen));
    XFillRectangle(w->display, w->xwin, x->gc, 0, 0, w->width, w->height);

    if(!x->logo_scale || !x->logo_zbars)
        return(0);

    XSetForeground(w->display, x->gc, BlackPixel(w->display, screen));
    XFillRectangles(w->display, w->xwin, x->gc, x->logo_bars, 5);

    XSetLineAttributes(w->display, x->gc, 2 * x->logo_scale,
                       LineSolid, CapRound, JoinRound);

    XSetForeground(w->display, x->gc, x->logo_colors[0]);
    XDrawLines(w->display, w->xwin, x->gc, x->logo_z, 4, CoordModeOrigin);

    if(x->exposed) {
        XIntersectRegion(x->logo_zbars, x->exposed, x->exposed);
        XSetRegion(w->display, x->gc, x->exposed);
    }
    else
        XSetRegion(w->display, x->gc, x->logo_zbars);

    XSetForeground(w->display, x->gc, x->logo_colors[1]);
    XDrawLines(w->display, w->xwin, x->gc, x->logo_z, 4, CoordModeOrigin);

    /* reset GC */
    XSetLineAttributes(w->display, x->gc, 0,
                       LineSolid, CapButt, JoinMiter);
    return(0);
}
示例#21
0
// return rectangle surrounding intersection of this rectangle and clip,
int Fl_Device::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H)
{
    Region r = rstack[rstackptr];
    if (!r) {X = x; Y = y; W = w; H = h; return 0;}
    // Test against the window to get 16-bit values (this is only done if
    // a clip region exists as otherwise it breaks fl_push_no_clip()):
    int ret = 1;
    int dx = x; 
	int dy = y; 
	fl_transform(x,y); 
	dx = x-dx; 
	dy = y-dy;
    if (x < 0) { w += x; x = 0; ret = 2; }
    int t = Fl_Window::current()->w(); 
	if (x+w > t) { w = t-x; ret = 2; }
    if (y < 0) { h += y; y = 0; ret = 2; }
    t = Fl_Window::current()->h(); 
	if (y+h > t) { h = t-y; ret = 2; }
    
	// check for total clip (or for empty rectangle):
    if (w <= 0 || h <= 0) { W = H = 0; return 0; }

#ifndef _WIN32
    switch (XRectInRegion(r, x, y, w, h))
    {
        case 0:                  // completely outside
            W = H = 0;
            return 0;
        case 1:                  // completely inside:
            X = x-dx;
            Y = y-dy;
            W = w; H = h;
            return ret;
        default:                 // partial:
        {
            Region rr = XRectangleRegion(x,y,w,h);
            Region temp = XCreateRegion();
            XIntersectRegion(r, rr, temp);
            XRectangle rect;
            XClipBox(temp, &rect);
            X = rect.x-dx; Y = rect.y-dy; W = rect.width; H = rect.height;
            XDestroyRegion(temp);
            XDestroyRegion(rr);
            return 2;
        }
    }
#else
    // The win32 API makes no distinction between partial and complete
    // intersection, so we have to check for partial intersection ourselves.
    // However, given that the regions may be composite, we have to do
    // some voodoo stuff...
    Region rr = XRectangleRegion(x,y,w,h);
    Region temp = CreateRectRgn(0,0,0,0);
	
    if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) {
		// disjoint
        W = H = 0;
        ret = 0;
    }
    else if (EqualRgn(temp, rr)) {
		// complete
        X = x-dx;
        Y = y-dy;
        W = w; H = h;
        // ret = ret
    } else {
		// parital intersection
        RECT rect;
        GetRgnBox(temp, &rect);
        X = rect.left-dx; Y = rect.top-dy;
        W = rect.right - rect.left; H = rect.bottom - rect.top;
        ret = 2;
    }
    DeleteObject(temp);
    DeleteObject(rr);
    return ret;
#endif
}
示例#22
0
文件: Painter.c 项目: ekoeppen/kino-2
void drawBox (KinoWidget w, Element *box, int x, int y, LargeRegion r)
{
  Node *p;
  Region regExpose, regBox, empty, intersect;
  XRectangle re, rb;

  if (box != NULL && box->display != DISPLAY_NONE &&
    (box->display == DISPLAY_INLINE ||
    !(x + box->x + box->width < r.x || x + box->x > r.x + r.width ||
      y + box->y + box->height < r.y || y + box->y > r.y + r.height)))
  {
    x = x + box->x;
    y = y + box->y;

    if (box->display == DISPLAY_BLOCK)
    {
      if (box->background_color.alpha == 0)
      {
	changeGC (w, ((XFontStruct *) box->font)->fid,
	  box->background_color, box->background_color, 0);

	rb.x = x + ElementTotalLeft (box);
	rb.y = y + ElementTotalTop (box);
	rb.width = box->width -
	  ElementTotalLeft (box) - ElementTotalRight (box);
	rb.height = box->height -
	  ElementTotalTop (box) - ElementTotalBottom (box);

	re.x = r.x; re.y = r.y; re.width = r.width; re.height = r.height;

	empty = XCreateRegion ();
	regBox = XCreateRegion ();
	XUnionRectWithRegion (&rb, empty, regBox);
	regExpose = XCreateRegion ();
	XUnionRectWithRegion (&re, empty, regExpose);
	intersect = XCreateRegion ();
	XIntersectRegion (regBox, regExpose, intersect);

	XSetRegion (XtDisplay (w), w->kino.painter->gc, intersect);
	XFillRectangle (XtDisplay (w), XtWindow (w), w->kino.painter->gc,
	  r.x, r.y, r.width, r.height); 
	
	XDestroyRegion (regBox);
	XDestroyRegion (regExpose);
	XDestroyRegion (empty);
	XDestroyRegion (intersect);
      }

      if (box->border_top_color.alpha == 0 &&
	box->border_top_width.effective > 0)
      {
	changeGC (w, ((XFontStruct *) box->font)->fid,
	  box->border_top_color, box->background_color,
	  box->border_top_width.effective);
	XDrawLine (XtDisplay (w), XtWindow (w), w->kino.painter->gc,
	  x + box->margin_left.effective, 
	  y + box->margin_top.effective,
	  x + box->width - box->margin_right.effective,
	  y + box->margin_top.effective);
      }

      if (box->border_bottom_color.alpha == 0 &&
	box->border_bottom_width.effective > 0)
      {
	changeGC (w, ((XFontStruct *) box->font)->fid,
	  box->border_bottom_color, box->background_color,
	  box->border_bottom_width.effective);
	XDrawLine (XtDisplay (w), XtWindow (w), w->kino.painter->gc,
	  x + box->margin_left.effective, 
	  y + box->height - box->margin_bottom.effective,
	  x + box->width - box->margin_right.effective,
	  y + box->height - box->margin_bottom.effective);
      }

      if (box->border_left_color.alpha == 0 &&
	box->border_left_width.effective > 0)
      {
	changeGC (w, ((XFontStruct *) box->font)->fid,
	  box->border_left_color, box->background_color,
	  box->border_left_width.effective);
	XDrawLine (XtDisplay (w), XtWindow (w), w->kino.painter->gc,
	  x + box->margin_left.effective, 
	  y + box->margin_top.effective,
	  x + box->margin_left.effective, 
	  y + box->height - box->margin_bottom.effective);
      }

      if (box->border_right_color.alpha == 0 &&
	box->border_right_width.effective > 0)
      {
	changeGC (w, ((XFontStruct *) box->font)->fid,
	  box->border_right_color, box->background_color,
	  box->border_right_width.effective);
	XDrawLine (XtDisplay (w), XtWindow (w), w->kino.painter->gc,
	  x + box->width - box->margin_right.effective, 
	  y + box->margin_top.effective,
	  x + box->width - box->margin_right.effective, 
	  y + box->height - box->margin_bottom.effective);
      }
    }

    changeGC (w, ((XFontStruct *) box->font)->fid,
      box->color, box->background_color, 1);

    p = box->contents;
    while (p != NULL)
    {
      switch (p->type)
      {
	case TEXT_NODE:
	  drawWord (w, box, (Text *) p, x, y, r);
	  break;
	case ELEMENT_NODE:
	  drawBox (w, (Element *) p, x, y, r);
	  changeGC (w, ((XFontStruct *) box->font)->fid,
	    box->color, box->background_color, 1);
	  break;
	default: 
	  break;
      }
      p = p->next;
    }
  }
}
示例#23
0
*/ static void process_gobs(REBCMP_CTX* ctx, REBGOB* gob)
/*
**	Recursively process and compose gob and its children.
**
** NOTE: this function is used internally by rebcmp_compose() call only.
**
***********************************************************************/
{
	//RL_Print("process_gobs: %x\n", gob);

	REBINT x = ROUND_TO_INT(ctx->absOffset.x);
	REBINT y = ROUND_TO_INT(ctx->absOffset.y);
	REBYTE* color;
	Region saved_win_region = XCreateRegion();

	if (GET_GOB_STATE(gob, GOBS_NEW)){
		//reset old-offset and old-size if newly added
		GOB_XO(gob) = GOB_LOG_X(gob);
		GOB_YO(gob) = GOB_LOG_Y(gob);
		GOB_WO(gob) = GOB_LOG_W(gob);
		GOB_HO(gob) = GOB_LOG_H(gob);

		CLR_GOB_STATE(gob, GOBS_NEW);
	}

	//intersect gob dimensions with actual window clip region
	REBOOL valid_intersection = 1;

	
	//------------------------------
	//Put backend specific code here
	//------------------------------
	XRectangle rect;
	rect.x = x;
	rect.y = y;
	rect.width = GOB_LOG_W(gob);
	rect.height = GOB_LOG_H(gob);
	/*
	RL_Print("gob        , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 rect.x,
			 rect.y,
			 rect.x + rect.width,
			 rect.y + rect.height);
	*/

	Region reg = XCreateRegion();
	XUnionRectWithRegion(&rect, reg, reg);
	/*
	XClipBox(ctx->Win_Region, &rect);
	RL_Print("Win Region , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 rect.x,
			 rect.y,
			 rect.x + rect.width,
			 rect.y + rect.height);
	*/
	XUnionRegion(saved_win_region, ctx->Win_Region, saved_win_region);
	XIntersectRegion(reg, ctx->Win_Region, ctx->Win_Region);
	XClipBox(ctx->Win_Region, &rect);
	/*
	RL_Print("Win and Gob, left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 rect.x,
			 rect.y,
			 rect.x + rect.width,
			 rect.y + rect.height);
			 */

	//get the current Window clip box
	REBRECT gob_clip = {
		rect.x, //left
		rect.y, //top
		rect.width + rect.x, //right
		rect.height + rect.y //bottom
			/*
		GOB_LOG_X(gob), //left
		GOB_LOG_Y(gob), //top
		GOB_LOG_W(gob) + GOB_LOG_X(gob), //right
		GOB_LOG_H(gob) + GOB_LOG_Y(gob), //bottom
		*/
	};

	//RL_Print("Window_Buffer: 0x%x\n", ctx->Window_Buffer);
	/*
	RL_Print("gob clip   , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 gob_clip.left,
			 gob_clip.top,
			 gob_clip.right,
			 gob_clip.bottom);
			 */
	if (!XEmptyRegion(ctx->Win_Region))
	//if (valid_intersection)
	{
		//render GOB content
		switch (GOB_TYPE(gob)) {
			case GOBT_COLOR:
				//------------------------------
				//Put backend specific code here
				//------------------------------
				// or use the similar draw api call:
				//RL_Print("Draw Color at: %d, %d\n", x, y);
				rebdrw_gob_color(gob, ctx->Window_Buffer, ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				break;

			case GOBT_IMAGE:
				{
				//RL_Print("Draw Image\n");
					//------------------------------
					//Put backend specific code here
					//------------------------------
					// or use the similar draw api call:
					rebdrw_gob_image(gob, ctx->Window_Buffer, ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				}
				break;

			case GOBT_DRAW:
				{
				//RL_Print("Draw Draw at: %d, %d\n", x, y);
					//------------------------------
					//Put backend specific code here
					//------------------------------
					// or use the similar draw api call:
					rebdrw_gob_draw(gob, ctx->Window_Buffer ,ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				}
				break;

			case GOBT_TEXT:
			case GOBT_STRING:
				//RL_Print("Draw Text at: %d, %d\n", x, y);
				//------------------------------
				//Put backend specific code here
				//------------------------------
				// or use the similar draw api call:
				rt_gob_text(gob, ctx->Window_Buffer ,ctx->winBufSize,ctx->absOffset, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				break;

			case GOBT_EFFECT:
				//RL_Print("Draw Effect\n");
				//not yet implemented
				break;
		}


		//recursively process sub GOBs
		if (GOB_PANE(gob)) {
			REBINT n;
			REBINT len = GOB_TAIL(gob);
			REBGOB **gp = GOB_HEAD(gob);

			for (n = 0; n < len; n++, gp++) {
				REBINT g_x = GOB_LOG_X(*gp);
				REBINT g_y = GOB_LOG_Y(*gp);

				//restore the "parent gob" clip region
				//------------------------------
				//Put backend specific code here
				//------------------------------

				ctx->absOffset.x += g_x;
				ctx->absOffset.y += g_y;

				process_gobs(ctx, *gp);

				ctx->absOffset.x -= g_x;
				ctx->absOffset.y -= g_y;
			}
		}
	}
	XDestroyRegion(reg);
	XDestroyRegion(ctx->Win_Region);
	ctx->Win_Region = saved_win_region;
}
示例#24
0
void TkIntersectRegion(TkRegion a, TkRegion b, TkRegion c)
{
    XIntersectRegion((Region) a, (Region) b, (Region) c);
}
示例#25
0
void exposeCB (Widget w, 
	ExposeCD *cd,
	XtcwpAxesCallbackStruct *ca)
{
	Model *model=cd->model;
	char *edgecolor=cd->edgecolor;
	char *tricolor=cd->tricolor;
	float bclip=cd->bclip;
	float wclip=cd->wclip;
	Region region=ca->region;
	Position x=ca->x,y=ca->y;
	Dimension width=ca->width,height=ca->height;
	float x1beg=ca->x1beg,x1end=ca->x1end,
		x2beg=ca->x2beg,x2end=ca->x2end;
	int style=ca->style;
	Display *dpy=NULL;
	Window win;
	Region drawregion,tempregion;
	XWindowAttributes wa;
	Colormap cmap;
	XColor scolor,ecolor;
	XRectangle rect;
	long black=0;
	long white=0;
	GC gcedge,gctri;
	FGC fgcedge,fgctri,fgc;
	float x1,y1,x2,y2,x3,y3;
	Face *f;
	
	/* JG */
	dpy=XtDisplay(w);
	win=XtWindow(w);
	black=(long) BlackPixelOfScreen(XtScreen(w));
	white=(long) WhitePixelOfScreen(XtScreen(w));
	/* .. JG */

	/* determine current colormap */
	XGetWindowAttributes(dpy,win,&wa);
	cmap = wa.colormap;

	/* create GCs */
	gcedge = XCreateGC(dpy,win,0L,NULL);
	gctri = XCreateGC(dpy,win,0L,NULL);


	/* set line colors */
	if (XAllocNamedColor(dpy,cmap,edgecolor,&scolor,&ecolor))
		XSetForeground(dpy,gcedge,ecolor.pixel);
	else
		XSetForeground(dpy,gcedge,black);
	if (XAllocNamedColor(dpy,cmap,tricolor,&scolor,&ecolor))
		XSetForeground(dpy,gctri,ecolor.pixel);
	else
		XSetForeground(dpy,gctri,white);
	
	/* clip to intersection of axes rectangle and expose region */
	rect.x = x;  rect.y = y;  rect.width = width;  rect.height = height;
	tempregion = XCreateRegion();
	XUnionRectWithRegion(&rect,tempregion,tempregion);
	drawregion = XCreateRegion();
	XIntersectRegion(region,tempregion,drawregion);
	XSetRegion(dpy,gcedge,drawregion);
	XSetRegion(dpy,gctri,drawregion);
	
	/* create FGCs with clipping */
	if (style==XtcwpNORMAL) {
		fgcedge = FXCreateFGC(gcedge,x,y,width,height,
			x1beg,x2end,x1end-x1beg,x2beg-x2end);
		FSetClipRectangle(fgcedge,x1beg,x2end,x1end,x2beg);
		fgctri = FXCreateFGC(gctri,x,y,width,height,
			x1beg,x2end,x1end-x1beg,x2beg-x2end);
		FSetClipRectangle(fgctri,x1beg,x2end,x1end,x2beg);
	} else {
		fgcedge = FXCreateFGC(gcedge,x,y,width,height,
			x2beg,x1beg,x2end-x2beg,x1end-x1beg);
		FSetClipRectangle(fgcedge,x2beg,x1beg,x2end,x1end);
		fgctri = FXCreateFGC(gctri,x,y,width,height,
			x2beg,x1beg,x2end-x2beg,x1end-x1beg);
		FSetClipRectangle(fgctri,x2beg,x1beg,x2end,x1end);
	}
	
	/* draw image */
	drawimage(dpy,win,drawregion,fgctri,model,bclip,wclip,style);
	
	/* loop over triangles */
	f = model->f;
	do {
		/* get float coordinates of vertices */
		if (style==XtcwpNORMAL) {
			x1 = f->eu->vu->v->x;
			y1 = f->eu->vu->v->y;
			x2 = f->eu->euCW->vu->v->x;
			y2 = f->eu->euCW->vu->v->y;
			x3 = f->eu->euCCW->vu->v->x;
			y3 = f->eu->euCCW->vu->v->y;
		} else {
			x1 = f->eu->vu->v->y;
			y1 = f->eu->vu->v->x;
			x2 = f->eu->euCW->vu->v->y;
			y2 = f->eu->euCW->vu->v->x;
			x3 = f->eu->euCCW->vu->v->y;
			y3 = f->eu->euCCW->vu->v->x;
		}
		
		/* draw edges of triangle */
		fgc = f->eu->e->fixed ? fgcedge : fgctri;
		if (((fgc==fgcedge && !STREQ(edgecolor,"none")) ||
		     (fgc==fgctri && !STREQ(tricolor,"none"))))
			FXDrawLine(dpy,win,fgc,x1,y1,x2,y2);
		fgc = f->eu->euCW->e->fixed ? fgcedge : fgctri;
		if (((fgc==fgcedge && !STREQ(edgecolor,"none")) ||
		     (fgc==fgctri && !STREQ(tricolor,"none"))))
			FXDrawLine(dpy,win,fgc,x2,y2,x3,y3);
		fgc = f->eu->euCCW->e->fixed ? fgcedge : fgctri;
		if (((fgc==fgcedge && !STREQ(edgecolor,"none")) ||
		     (fgc==fgctri && !STREQ(tricolor,"none"))))
			FXDrawLine(dpy,win,fgc,x3,y3,x1,y1);
		f = f->fNext;
	} while (f!=model->f);

	/* free everything */
	FXFreeFGC(fgcedge);
	FXFreeFGC(fgctri);
	XFreeGC(dpy,gcedge);
	XFreeGC(dpy,gctri);
	XDestroyRegion(drawregion);
	XDestroyRegion(tempregion);
}
void
eventLoop (void)
{
    XEvent	   event;
    struct pollfd  ufd;
    int		   timeDiff;
    struct timeval tv;
    Region	   tmpRegion;
    CompDisplay    *display = compDisplays;
    CompScreen	   *s = display->screens;
    int		   timeToNextRedraw = 0;
    CompWindow	   *move = 0;
    int		   px = 0, py = 0;
    CompTimeout    *t;

    tmpRegion = XCreateRegion ();
    if (!tmpRegion)
    {
	fprintf (stderr, "%s: Couldn't create region\n", programName);
	return;
    }

    ufd.fd = ConnectionNumber (display->display);
    ufd.events = POLLIN;

    for (;;)
    {
	if (display->dirtyPluginList)
	    updatePlugins (display);

	if (restartSignal)
	{
	     execvp (programName, programArgv);
	     exit (1);
	}

	while (XPending (display->display))
	{
	    XNextEvent (display->display, &event);

	    /* translate root window */
	    if (testMode)
	    {
		Window root, child;

		switch (event.type) {
		case ButtonPress:
		    if (!move)
		    {
			px = event.xbutton.x;
			py = event.xbutton.y;

			move = findWindowAt (display, event.xbutton.window,
					     px, py);
			if (move)
			{
			    XRaiseWindow (display->display, move->id);
			    continue;
			}
		    }
		case ButtonRelease:
		    move = 0;

		    root = translateToRootWindow (display,
						  event.xbutton.window);
		    XTranslateCoordinates (display->display,
					   event.xbutton.root, root,
					   event.xbutton.x_root,
					   event.xbutton.y_root,
					   &event.xbutton.x_root,
					   &event.xbutton.y_root,
					   &child);
		    event.xbutton.root = root;
		    break;
		case KeyPress:
		case KeyRelease:
		    root = translateToRootWindow (display, event.xkey.window);
		    XTranslateCoordinates (display->display,
					   event.xkey.root, root,
					   event.xkey.x_root,
					   event.xkey.y_root,
					   &event.xkey.x_root,
					   &event.xkey.y_root,
					   &child);
		    event.xkey.root = root;
		    break;
		case MotionNotify:
		    if (move)
		    {
			XMoveWindow (display->display, move->id,
				     move->attrib.x + event.xbutton.x - px,
				     move->attrib.y + event.xbutton.y - py);

			px = event.xbutton.x;
			py = event.xbutton.y;
			continue;
		    }

		    root = translateToRootWindow (display,
						  event.xmotion.window);
		    XTranslateCoordinates (display->display,
					   event.xmotion.root, root,
					   event.xmotion.x_root,
					   event.xmotion.y_root,
					   &event.xmotion.x_root,
					   &event.xmotion.y_root,
					   &child);
		    event.xmotion.root = root;
		default:
		    break;
		}
	    }

	    /* add virtual modifiers */
	    switch (event.type) {
	    case ButtonPress:
		event.xbutton.state |= CompPressMask;
		event.xbutton.state =
		    realToVirtualModMask (display, event.xbutton.state);
		break;
	    case ButtonRelease:
		event.xbutton.state |= CompReleaseMask;
		event.xbutton.state =
		    realToVirtualModMask (display, event.xbutton.state);
		break;
	    case KeyPress:
		event.xkey.state |= CompPressMask;
		event.xkey.state = realToVirtualModMask (display,
							 event.xkey.state);
		break;
	    case KeyRelease:
		event.xkey.state |= CompReleaseMask;
		event.xkey.state = realToVirtualModMask (display,
							 event.xkey.state);
		break;
	    case MotionNotify:
		event.xmotion.state =
		    realToVirtualModMask (display, event.xmotion.state);
		break;
	    default:
		break;
	    }

	    (*display->handleEvent) (display, &event);
	}

	if (s->allDamaged || REGION_NOT_EMPTY (s->damage))
	{
	    if (timeToNextRedraw == 0)
	    {
		/* wait for X drawing requests to finish
		   glXWaitX (); */

		gettimeofday (&tv, 0);

		timeDiff = TIMEVALDIFF (&tv, &s->lastRedraw);

		(*s->preparePaintScreen) (s, timeDiff);

		if (s->allDamaged)
		{
		    EMPTY_REGION (s->damage);
		    s->allDamaged = 0;

		    (*s->paintScreen) (s,
				       &defaultScreenPaintAttrib,
				       &defaultWindowPaintAttrib,
				       &s->region,
				       PAINT_SCREEN_REGION_MASK |
				       PAINT_SCREEN_FULL_MASK);

		    glXSwapBuffers (s->display->display, s->root);
		}
		else
		{
		    XIntersectRegion (s->damage, &s->region, tmpRegion);

		    EMPTY_REGION (s->damage);

		    if ((*s->paintScreen) (s,
					   &defaultScreenPaintAttrib,
					   &defaultWindowPaintAttrib,
					   tmpRegion,
					   PAINT_SCREEN_REGION_MASK))
		    {
			BoxPtr pBox;
			int    nBox, y;

			glEnable (GL_SCISSOR_TEST);
			glDrawBuffer (GL_FRONT);

			pBox = tmpRegion->rects;
			nBox = tmpRegion->numRects;
			while (nBox--)
			{
			    y = s->height - pBox->y2;

			    glBitmap (0, 0, 0, 0,
				      pBox->x1 - s->rasterX, y - s->rasterY,
				      NULL);

			    s->rasterX = pBox->x1;
			    s->rasterY = y;

			    glScissor (pBox->x1, y,
				       pBox->x2 - pBox->x1,
				       pBox->y2 - pBox->y1);

			    glCopyPixels (pBox->x1, y,
					  pBox->x2 - pBox->x1,
					  pBox->y2 - pBox->y1,
					  GL_COLOR);

			    pBox++;
			}

			glDrawBuffer (GL_BACK);
			glDisable (GL_SCISSOR_TEST);
			glFlush ();
		    }
		    else
		    {
			(*s->paintScreen) (s,
					   &defaultScreenPaintAttrib,
					   &defaultWindowPaintAttrib,
					   &s->region,
					   PAINT_SCREEN_FULL_MASK);

			glXSwapBuffers (s->display->display, s->root);
		    }
		}

		s->lastRedraw = tv;

		(*s->donePaintScreen) (s);

		/* remove destroyed windows */
		while (s->pendingDestroys)
		{
		    CompWindow *w;

		    for (w = s->windows; w; w = w->next)
		    {
			if (w->destroyed)
			{
			    addWindowDamage (w);
			    removeWindow (w);
			    break;
			}
		    }

		    s->pendingDestroys--;
		}
	    }

	    timeToNextRedraw = getTimeToNextRedraw (s, &s->lastRedraw);
	    if (timeToNextRedraw)
		timeToNextRedraw = poll (&ufd, 1, timeToNextRedraw);
	}
	else
	{
	    if (timeouts)
	    {
		if (timeouts->left > 0)
		    poll (&ufd, 1, timeouts->left);

		gettimeofday (&tv, 0);

		timeDiff = TIMEVALDIFF (&tv, &lastTimeout);

		for (t = timeouts; t; t = t->next)
		    t->left -= timeDiff;

		while (timeouts && timeouts->left <= 0)
		{
		    t = timeouts;
		    if ((*t->callBack) (t->closure))
		    {
			timeouts = t->next;
			addTimeout (t);
		    }
		    else
		    {
			timeouts = t->next;
			free (t);
		    }
		}

		s->lastRedraw = lastTimeout = tv;
	    }
	    else
	    {
		poll (&ufd, 1, 1000);
		gettimeofday (&s->lastRedraw, 0);
	    }

	    /* just redraw immediately */
	    timeToNextRedraw = 0;
	}
    }
}
示例#27
0
/*
 * groupHandleButtonReleaseEvent
 *
 */
static void
groupHandleButtonReleaseEvent (CompScreen *s,
                               XEvent     *event)
{
	GroupSelection *group;
	int vx, vy;
	Region newRegion;
	Bool inserted = FALSE;
	Bool wasInTabBar = FALSE;

	GROUP_SCREEN (s);

	if (event->xbutton.button != 1)
		return;

	if (!gs->draggedSlot)
		return;

	if (!gs->dragged)
	{
		groupChangeTab (gs->draggedSlot, RotateUncertain);
		gs->draggedSlot = NULL;

		if (gs->grabState == ScreenGrabTabDrag)
			groupGrabScreen (s, ScreenGrabNone);

		return;
	}

	GROUP_WINDOW (gs->draggedSlot->window);

	newRegion = XCreateRegion ();
	if (!newRegion)
		return;

	XUnionRegion (newRegion, gs->draggedSlot->region, newRegion);

	groupGetDrawOffsetForSlot (gs->draggedSlot, &vx, &vy);
	XOffsetRegion (newRegion, vx, vy);

	for (group = gs->groups; group; group = group->next)
	{
		Bool inTabBar;
		Region clip, buf;
		GroupTabBarSlot *slot;

		if (!group->tabBar || !HAS_TOP_WIN (group))
			continue;

		/* create clipping region */
		clip = groupGetClippingRegion (TOP_TAB (group));
		if (!clip)
			continue;

		buf = XCreateRegion ();
		if (!buf)
		{
			XDestroyRegion (clip);
			continue;
		}

		XIntersectRegion (newRegion, group->tabBar->region, buf);
		XSubtractRegion (buf, clip, buf);
		XDestroyRegion (clip);

		inTabBar = !XEmptyRegion (buf);
		XDestroyRegion (buf);

		if (!inTabBar)
			continue;

		wasInTabBar = TRUE;

		for (slot = group->tabBar->slots; slot; slot = slot->next)
		{
			GroupTabBarSlot *tmpDraggedSlot;
			GroupSelection  *tmpGroup;
			Region slotRegion, buf;
			XRectangle rect;
			Bool inSlot;

			if (slot == gs->draggedSlot)
				continue;

			slotRegion = XCreateRegion ();
			if (!slotRegion)
				continue;

			if (slot->prev && slot->prev != gs->draggedSlot)
			{
				rect.x = slot->prev->region->extents.x2;
			}
			else if (slot->prev && slot->prev == gs->draggedSlot &&
			         gs->draggedSlot->prev)
			{
				rect.x = gs->draggedSlot->prev->region->extents.x2;
			}
			else
				rect.x = group->tabBar->region->extents.x1;

			rect.y = slot->region->extents.y1;

			if (slot->next && slot->next != gs->draggedSlot)
			{
				rect.width = slot->next->region->extents.x1 - rect.x;
			}
			else if (slot->next && slot->next == gs->draggedSlot &&
			         gs->draggedSlot->next)
			{
				rect.width = gs->draggedSlot->next->region->extents.x1 - rect.x;
			}
			else
				rect.width = group->tabBar->region->extents.x2;

			rect.height = slot->region->extents.y2 - slot->region->extents.y1;

			XUnionRectWithRegion (&rect, slotRegion, slotRegion);

			buf = XCreateRegion ();
			if (!buf)
				continue;

			XIntersectRegion (newRegion, slotRegion, buf);
			inSlot = !XEmptyRegion (buf);

			XDestroyRegion (buf);
			XDestroyRegion (slotRegion);

			if (!inSlot)
				continue;

			tmpDraggedSlot = gs->draggedSlot;

			if (group != gw->group)
			{
				CompWindow     *w = gs->draggedSlot->window;
				GroupSelection *tmpGroup = gw->group;
				int oldPosX = WIN_CENTER_X (w);
				int oldPosY = WIN_CENTER_Y (w);

				/* if the dragged window is not the top tab,
				   move it onscreen */
				if (tmpGroup->topTab && !IS_TOP_TAB (w, tmpGroup))
				{
					CompWindow *tw = TOP_TAB (tmpGroup);

					oldPosX = WIN_CENTER_X (tw) + gw->mainTabOffset.x;
					oldPosY = WIN_CENTER_Y (tw) + gw->mainTabOffset.y;

					groupSetWindowVisibility (w, TRUE);
				}

				/* Change the group. */
				groupDeleteGroupWindow (gs->draggedSlot->window);
				groupAddWindowToGroup (gs->draggedSlot->window, group, 0);

				/* we saved the original center position in oldPosX/Y before -
				   now we should apply that to the new main tab offset */
				if (HAS_TOP_WIN (group))
				{
					CompWindow *tw = TOP_TAB (group);
					gw->mainTabOffset.x = oldPosX - WIN_CENTER_X (tw);
					gw->mainTabOffset.y = oldPosY - WIN_CENTER_Y (tw);
				}
			}
			else
				groupUnhookTabBarSlot (group->tabBar, gs->draggedSlot, TRUE);

			gs->draggedSlot = NULL;
			gs->dragged = FALSE;
			inserted = TRUE;

			if ((tmpDraggedSlot->region->extents.x1 +
			     tmpDraggedSlot->region->extents.x2 + (2 * vx)) / 2 >
			    (slot->region->extents.x1 + slot->region->extents.x2) / 2)
			{
				groupInsertTabBarSlotAfter (group->tabBar,
				                            tmpDraggedSlot, slot);
			}
			else
				groupInsertTabBarSlotBefore (group->tabBar,
				                             tmpDraggedSlot, slot);

			groupDamageTabBarRegion (group);

			/* Hide tab-bars. */
			for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			{
				if (group == tmpGroup)
					groupTabSetVisibility (tmpGroup, TRUE, 0);
				else
					groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);
			}

			break;
		}

		if (inserted)
			break;
	}

	XDestroyRegion (newRegion);

	if (!inserted)
	{
		CompWindow     *draggedSlotWindow = gs->draggedSlot->window;
		GroupSelection *tmpGroup;

		for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);

		gs->draggedSlot = NULL;
		gs->dragged = FALSE;

		const BananaValue *
		option_dnd_ungroup_window = bananaGetOption (bananaIndex,
		                                             "dnd_ungroup_window",
		                                             s->screenNum);

		if (option_dnd_ungroup_window->b && !wasInTabBar)
		{
			groupRemoveWindowFromGroup (draggedSlotWindow);
		}
		else if (gw->group && gw->group->topTab)
		{
			groupRecalcTabBarPos (gw->group,
			                      (gw->group->tabBar->region->extents.x1 +
			                       gw->group->tabBar->region->extents.x2) / 2,
			                      gw->group->tabBar->region->extents.x1,
			                      gw->group->tabBar->region->extents.x2);
		}

		/* to remove the painted slot */
		damageScreen (s);
	}

	if (gs->grabState == ScreenGrabTabDrag)
		groupGrabScreen (s, ScreenGrabNone);

	if (gs->dragHoverTimeoutHandle)
	{
		compRemoveTimeout (gs->dragHoverTimeoutHandle);
		gs->dragHoverTimeoutHandle = 0;
	}
}