Bug 500910. GTK2 test plugin should take window shapes into account when computing the effective clip region. r=karlt

This commit is contained in:
Robert O'Callahan 2009-07-22 12:44:50 +12:00
Родитель 309225cfa5
Коммит a5233fd2a0
2 изменённых файлов: 38 добавлений и 2 удалений

Просмотреть файл

@ -87,7 +87,7 @@ include $(topsrcdir)/config/rules.mk
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
CFLAGS += $(MOZ_GTK2_CFLAGS)
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS) $(XLDFLAGS) $(XLIBS)
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS) $(XLDFLAGS) $(XLIBS) $(XEXT_LIBS)
endif
install-plugin: $(SHARED_LIBRARY)

Просмотреть файл

@ -38,6 +38,7 @@
#include <gdk/gdk.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#include <X11/extensions/shape.h>
#endif
#include <gtk/gtk.h>
@ -334,6 +335,38 @@ int32_t pluginGetEdge(InstanceData* instanceData, RectEdge edge)
return NPTEST_INT32_ERROR;
}
#ifdef MOZ_X11
static void intersectWithShapeRects(Display* display, Window window,
int kind, GdkRegion* region)
{
int count = -1, order;
XRectangle* shapeRects =
XShapeGetRectangles(display, window, kind, &count, &order);
// The documentation says that shapeRects will be NULL when the
// extension is not supported. Unfortunately XShapeGetRectangles
// also returns NULL when the region is empty, so we can't treat
// NULL as failure. I hope this way is OK.
if (count < 0)
return;
GdkRegion* shapeRegion = gdk_region_new();
if (!shapeRegion) {
XFree(shapeRects);
return;
}
for (int i = 0; i < count; ++i) {
XRectangle* r = &shapeRects[i];
GdkRectangle rect = { r->x, r->y, r->width, r->height };
gdk_region_union_with_rect(shapeRegion, &rect);
}
XFree(shapeRects);
gdk_region_intersect(region, shapeRegion);
gdk_region_destroy(shapeRegion);
}
#endif
static GdkRegion* computeClipRegion(InstanceData* instanceData)
{
if (!instanceData->hasWidget)
@ -374,12 +407,15 @@ static GdkRegion* computeClipRegion(InstanceData* instanceData)
return 0;
}
GdkRectangle windowRect = { -pluginX, -pluginY, width, height };
GdkRectangle windowRect = { 0, 0, width, height };
GdkRegion* windowRgn = gdk_region_rectangle(&windowRect);
if (!windowRgn) {
gdk_region_destroy(region);
return 0;
}
intersectWithShapeRects(display, window, ShapeBounding, windowRgn);
intersectWithShapeRects(display, window, ShapeClip, windowRgn);
gdk_region_offset(windowRgn, -pluginX, -pluginY);
gdk_region_intersect(region, windowRgn);
gdk_region_destroy(windowRgn);