Подробности

[В начало]

Проблема в реализации № D0140

Краткое описание

Поведение функции gdk_window_merge_child_shapes() не соответствует требованиям стандарта LSB 3.2

Подробное описание

В документации сказано, что функция gdk_window_merge_child_shapes() должна установить форму window как обьединение всех форм window и всех форм его наследников

Раздел стандарта

Linux Standard Base Desktop Specification 3.2. Chapter 15. Libraries. 15.21.1.1. Interfaces for GTK Drawing toolkit, который ссылается на http://www.gtk.org/api/2.6/gdk/gdk-Windows.html#gdk-window-merge-child-shapes

Пример

#include <gdk/gdk.h>
#include <glib.h>
#include <stdio.h>

int main (int argc, char **argv)
{
	GdkWindowAttr parent_attr;
	GdkWindowAttr child1_attr;
	GdkWindowAttr child2_attr;
	GdkWindow *parent_window = NULL;
	GdkWindow *child1_window = NULL;
	GdkWindow *child2_window = NULL;
	GdkWindow *returned_window = NULL;
	GdkRegion *shape_region = NULL;
	GdkRegion *exp_region = NULL;
	GdkRectangle rect;
	GdkColormap *colormap = NULL;
	GdkColor color;
	GdkColor ret_color;
	GdkImage *image = NULL;
	int i;
	int j;

	gdk_init(&argc, &argv);
	
	colormap = gdk_colormap_get_system();
	if(colormap == NULL)
	{
		printf("The gdk_colormap_get_system function returned NULL, unable to create a GdkColormap.\n");
		return 0;
	}
	
	//creating three windows: one parent and two child windows
	parent_attr.title = "PARENT_WINDOW";
	parent_attr.x = 0;
	parent_attr.y = 0;
	parent_attr.width = 700;
	parent_attr.height = 800;
	parent_attr.wclass = GDK_INPUT_OUTPUT;
	parent_attr.window_type = GDK_WINDOW_TOPLEVEL;

	child1_attr.title = "CHILD1_WINDOW";
	child1_attr.x = 100;
	child1_attr.y = 200;
	child1_attr.width = 250;
	child1_attr.height = 300;
	child1_attr.wclass = GDK_INPUT_OUTPUT;
	child1_attr.window_type = GDK_WINDOW_TOPLEVEL;

	child2_attr.title = "CHILD2_WINDOW";
	child2_attr.x = 450;
	child2_attr.y = 100;
	child2_attr.width = 200;
	child2_attr.height = 600;
	child2_attr.wclass = GDK_INPUT_OUTPUT;
	child2_attr.window_type = GDK_WINDOW_TOPLEVEL;
	
	parent_window = gdk_window_new(NULL, &parent_attr, GDK_WA_X | GDK_WA_Y |GDK_WA_TITLE);
	child1_window = gdk_window_new(NULL, &child1_attr, GDK_WA_X | GDK_WA_Y |GDK_WA_TITLE);
	child2_window = gdk_window_new(NULL, &child2_attr, GDK_WA_X | GDK_WA_Y |GDK_WA_TITLE);
	if(parent_window == NULL || child1_window == NULL || child2_window == NULL)
	{
		printf("The gdk_window_new function returned NULL, unable to create a GdkWindow.\n");
		return 0;
	}
	
	gdk_window_reparent(child1_window, parent_window, 100, 200);
	gdk_window_reparent(child2_window, parent_window, 450, 100);

	gdk_window_show(parent_window);
	gdk_window_show(child1_window);
	gdk_window_show(child2_window);
	
	//setting background for windows
	color.red = 100 * (65535 / 255);
	color.green = 50 * (65535 / 255);
	color.blue = 100 * (65535 / 255);

	gdk_rgb_find_color(colormap, &color);
	gdk_window_set_background(child1_window, &color);
	gdk_window_set_background(child2_window, &color);
	gdk_window_set_background(parent_window, &color);
	
	//setting shapes for windows
	rect.x = 0;
	rect.y = 0;
	rect.width = 100;
	rect.height = 100;
	shape_region = gdk_region_rectangle(&rect);
	exp_region = gdk_region_copy(shape_region);

	gdk_window_shape_combine_region(parent_window, shape_region, 0, 0);
	gdk_window_shape_combine_region(child1_window, shape_region, 0, 0);
	gdk_window_shape_combine_region(child2_window, shape_region, 0, 0);

	gdk_window_merge_child_shapes(parent_window);

	//making of the region thet should be set on the window (parent window) after call of the function gdk_window_merge_child_shapes
	gdk_region_offset(shape_region, child1_attr.x, child1_attr.y);
	gdk_region_union(exp_region, shape_region);
	gdk_region_offset(shape_region, child2_attr.x - child1_attr.x, child2_attr.y - child1_attr.y);
	gdk_region_union(exp_region, shape_region);

	//making a GdkImage from the window (parent window)
	image = gdk_drawable_copy_to_image(parent_window, NULL, 0, 0, 0, 0, parent_attr.width, parent_attr.height);
	if(image == NULL)
	{
		printf("The gdk_drawable_copy_to_image function returned NULL, unable to create a GdkImage.\n");
		return 0;
	}
	
	//checking if the right shape was set on the window (parent window)
	for(i = 0; i < parent_attr.width; ++i)
	{
		for(j = 0; j < parent_attr.height; ++j)
		{
			gdk_colormap_query_color(colormap, gdk_image_get_pixel(image, i, j), &ret_color);
			if(gdk_region_point_in(exp_region, i, j))
			{
				if(!gdk_color_equal(&ret_color, &color))
				{
					printf("(%d, %d) pixel's color havn't been set. Therefore (%d, %d) pixel hadn't been visible, but it should.", i, j, i, j);
					return 0; 
				}
			}
			else
			{
				if(gdk_color_equal(&ret_color, &color))
				{
					printf("(%d, %d) pixel's color shouldn't been set, because it should be transparent, but it was.", i, j);
					return 0;
				}
			}
		}
	}


	if(parent_window != NULL)
	{
		gdk_window_destroy(parent_window);
	}

	if(child1_window != NULL)
	{
		gdk_window_destroy(child1_window);
	}

	if(child2_window != NULL)
	{
		gdk_window_destroy(child2_window);
	}

	if(image != NULL)
	{
		g_object_unref(image);
	}

	if(shape_region != NULL)
	{
		gdk_region_destroy(shape_region);
	}

	if(exp_region != NULL)
	{
		gdk_region_destroy(exp_region);
	}

	if(colormap != NULL)
	{
		g_object_unref(colormap);
	}

 	return 0;
}

Компонент

gtk+ 2.18 or early

Принято

Gnome Bugzilla, 596067

[В начало]