2013年9月3日 星期二

Gtk 2.17.2 drag and drop background bug fixed part 2

gdkdrawable-directfb.c

static void
gdk_directfb_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height)
{

gint i;
gint pitch;
GdkRegion clip;
GdkDrawableImplDirectFB *impl;
GdkGCDirectFB *gc_private = NULL;
IDirectFBSurface *surface = NULL;
guchar* ucbits;
//GdkWindowImplDirectFB* wimpl;
//GdkWindowObject* private;
GdkDrawableImplDirectFB* bgimpl;


g_return_if_fail (GDK_IS_DRAWABLE (drawable));

D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %s, %4d,%4d - %4dx%4d )\n", __FUNCTION__,
drawable, gc, filled ? " filled" : "outline", x, y, width, height );

impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);

if (!impl->surface)
return;

if (gc)
gc_private = GDK_GC_DIRECTFB (gc);

if (gc_private)
{
if (gdk_directfb_enable_color_keying &&
(gc_private->values.foreground.red >> 8) == gdk_directfb_bg_color_key.r &&
(gc_private->values.foreground.green >> 8) == gdk_directfb_bg_color_key.g &&
(gc_private->values.foreground.blue >> 8) == gdk_directfb_bg_color_key.b)
{
if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
impl->surface->SetColorIndex (impl->surface, 255);
else
impl->surface->SetColor (impl->surface,
gdk_directfb_bg_color.r,
gdk_directfb_bg_color.g,
gdk_directfb_bg_color.b,
gdk_directfb_bg_color.a);
}
else
{
if (!gdk_directfb_setup_for_drawing (impl, gc_private))
{
return;
}
}
}
else
{
GdkWindowObject *win = GDK_WINDOW_OBJECT (impl->wrapper);

if (gdk_directfb_enable_color_keying)
{
if (DFB_PIXELFORMAT_IS_INDEXED (impl->format))
impl->surface->SetColorIndex (impl->surface, 255);
else
impl->surface->SetColor (impl->surface,
gdk_directfb_bg_color.r,
gdk_directfb_bg_color.b,
gdk_directfb_bg_color.g,
gdk_directfb_bg_color.a);
}
else
{
gdk_directfb_set_color (impl, &win->bg_color, 0xFF);
}
}

if (filled)
{
GdkRectangle rect = { x, y, width, height };

gdk_directfb_clip_region (drawable, gc, &rect, &clip);

if (gc_private && gc_private->values_mask & GDK_GC_FILL)
{
if (gc_private->values.fill == GDK_STIPPLED &&
gc_private->values_mask & GDK_GC_STIPPLE &&
gc_private->values.stipple)
{
surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.stipple)->impl)->surface;

if (surface)
impl->surface->SetBlittingFlags (impl->surface,
(DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE));
}
else if (gc_private->values.fill == GDK_TILED &&
gc_private->values_mask & GDK_GC_TILE &&
gc_private->values.tile)
{
surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.tile)->impl)->surface;

impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
}
}

if (surface)
{
if (gc_private->values_mask & GDK_GC_TS_X_ORIGIN)
x = gc_private->values.ts_x_origin;
if (gc_private->values_mask & GDK_GC_TS_Y_ORIGIN)
y = gc_private->values.ts_y_origin;

/*for (i = 0; i < clip.numRects; i++)
{
DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
clip.rects[i].x2, clip.rects[i].y2 };

impl->surface->SetClip (impl->surface, ®);
impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
}*/

//wimpl = GDK_WINDOW_IMPL_DIRECTFB (drawable);
//private = GDK_WINDOW_OBJECT(wimpl->gdkWindow);
//bgimpl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(private->bg_pixmap)->impl);
bgimpl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(gc_private->values.tile)->impl);
if( bgimpl->paint_region.numRects > 0 )
{
//clear frame buffer
if( impl->surface->Lock( impl->surface, DSLF_WRITE, (void**)(&ucbits), &pitch ) == DFB_OK )
{
memset(ucbits,0,pitch*impl->height);
impl->surface->Unlock( impl->surface );
}

for (i = 0; i < bgimpl->paint_region.numRects; i++)
{
DFBRegion reg = { bgimpl->paint_region.rects[i].x1,
bgimpl->paint_region.rects[i].y1,
bgimpl->paint_region.rects[i].x2,
bgimpl->paint_region.rects[i].y2 };

impl->surface->SetClip (impl->surface, ®);
impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
}
}
else
{
for (i = 0; i < clip.numRects; i++)
{
DFBRegion reg = { clip.rects[i].x1, clip.rects[i].y1,
clip.rects[i].x2, clip.rects[i].y2 };

impl->surface->SetClip (impl->surface, ®);
impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
}
}
}
else /* normal rectangle filling */
{
DFBRectangle rects[clip.numRects];

impl->surface->SetClip (impl->surface, NULL);

for (i = 0; i < clip.numRects; i++)
{
GdkRegionBox *box = &clip.rects[i];

rects[i].x = box->x1;
rects[i].y = box->y1;
rects[i].w = box->x2 - box->x1;
rects[i].h = box->y2 - box->y1;
}

//from gdk_pixbuf_render_threshold_alpha special param
if( gc_private->values_mask & GDK_GC_TRANS_ENABLE )
{
gdk_directfb_set_color (impl, &gc_private->values.foreground, 0x00);
}

impl->surface->FillRectangles(impl->surface, rects, clip.numRects);
}

temp_region_deinit( &clip );
}
else
{

DFBRegion region = { x, y, x + width, y + height };
impl->surface->SetClip (impl->surface, ®ion);

/* DirectFB does not draw rectangles the X way. Using DirectFB,
a filled Rectangle has the same size as a drawn one, while
X draws the rectangle one pixel taller and wider. */
impl->surface->DrawRectangle (impl->surface, x, y, width , height);
}
}
/////////////////////////////////////////////////////////
gdkwindow-directfb.c

typedef struct _RGNDATAHEADER
{
guint dwSize;
guint iType;
guint nCount;
guint nRgnSize;
GdkSegment rcBound;
} RGNDATAHEADER;

typedef struct _RGNDATA
{
RGNDATAHEADER rdh;
char* Buffer;
} RGNDATA;

static void
gdk_directfb_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *mask,
gint x,
gint y)
{
gint mx, my, x0;
guint maxRects;
int i,ALLOC_UNIT;
int pitch;
GdkRectangle rt;
guchar* p;
guchar* bits;
GdkSegment* pr;
GdkWindowObject* private;
//GdkDrawableImplDirectFB* dfbimpl;
GdkDrawableImplDirectFB* implbg;
GdkDrawableImplDirectFB* mask_impl;
IDirectFBSurface* surface;
GdkRegion* tmp_clip;
RGNDATA* pData = NULL;

if (GDK_WINDOW_DESTROYED (window))
return;

ALLOC_UNIT = 128;
private = GDK_WINDOW_OBJECT (window);
private->shaped = (mask != NULL);

if( private->shaped )
{
mask_impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(mask)->impl);

surface = mask_impl->surface;
if( surface->Lock( surface, DSLF_READ, (void**)(&bits), &pitch ) == DFB_OK )
{
maxRects = ALLOC_UNIT;
pData = g_malloc (sizeof (RGNDATA));
pData->Buffer = g_malloc (sizeof (GdkSegment) * maxRects);
pData->rdh.dwSize = sizeof (RGNDATAHEADER);
pData->rdh.iType = 1; //#define RDH_RECTANGLES 1
pData->rdh.nCount = 0;
pData->rdh.nRgnSize = 0;
//SetRect (&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
pData->rdh.rcBound.x1 = 0x7fffffff;
pData->rdh.rcBound.y1 = 0x7fffffff;
pData->rdh.rcBound.x2 = 0;
pData->rdh.rcBound.y2 = 0;

for (my = 0; my < mask_impl->height; my++)
{
//p = (guchar *) bits + my * bpl;
p = (guchar *) bits + my * pitch;

for (mx = 0; mx < mask_impl->width; mx++)
{
x0 = mx;

while (mx < mask_impl->width)
{
if ( p[mx] == 0x00 )
break;
mx++;
}

if (mx > x0)
{
if (pData->rdh.nCount >= maxRects)
{
maxRects += ALLOC_UNIT;
pData = g_realloc (pData->Buffer, sizeof(GdkSegment)*maxRects);
}

pr = (GdkSegment *) pData->Buffer;
//SetRect (&pr[pData->rdh.nCount], x0, my, mx, my+1);
pr[pData->rdh.nCount].x1 = x0;
pr[pData->rdh.nCount].y1 = my;
pr[pData->rdh.nCount].x2 = mx;
pr[pData->rdh.nCount].y2 = my+1;

if (x0 < pData->rdh.rcBound.x1)
pData->rdh.rcBound.x1 = x0;

if (my < pData->rdh.rcBound.y1)
pData->rdh.rcBound.y1 = my;

if (mx > pData->rdh.rcBound.x2)
pData->rdh.rcBound.x2 = mx;

if (my+1 > pData->rdh.rcBound.y2)
pData->rdh.rcBound.y2 = my+1;

pData->rdh.nCount++;
}// end if (mx > x0)

}// end for (mx = 0; mx < mask_impl->width; mx++)
}//end for (my = 0; my < mask_impl->height; my++)
surface->Unlock( surface );

tmp_clip = gdk_region_new ();

pr = (GdkSegment *) pData->Buffer;
for (i = 0; i < pData->rdh.nCount - 1; i++)
{
rt.x = pr[i].x1;
rt.y = pr[i].y1;
rt.width = (pr[i].x2 - 1) - pr[i].x1;
rt.height = pr[i].y2 - pr[i].y1;

gdk_region_union_with_rect (tmp_clip, &rt);
}

implbg = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(private->bg_pixmap)->impl);
implbg->paint_region.size = tmp_clip->size;
implbg->paint_region.numRects = tmp_clip->numRects;

if( implbg->paint_region.rects )
{
g_free(implbg->paint_region.rects);
implbg->paint_region.rects = NULL;
}

implbg->paint_region.rects = g_malloc( sizeof(GdkRegionBox) * ALLOC_UNIT * ((tmp_clip->numRects-1)/ALLOC_UNIT+1) );

for(i=0;i numRects;i++)
implbg->paint_region.rects[i] = tmp_clip->rects[i];

implbg->paint_region.extents = tmp_clip->extents;


gdk_region_destroy (tmp_clip);

if(pData)
{
if(pData->Buffer)
{
g_free (pData->Buffer);
pData->Buffer = NULL;
}

g_free (pData);
pData = NULL;
}
}//end if( surface->Lock
}
else
{
implbg = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT(private->bg_pixmap)->impl);
implbg->paint_region.size = 0;
implbg->paint_region.numRects = 0;

if( implbg->paint_region.rects )
{
g_free(implbg->paint_region.rects);
implbg->paint_region.rects = NULL;
}
}
}

沒有留言:

張貼留言