Private fields for structures



Hello, hackers

First, a bit of introductory material...
----------------------------------------

In its present state, the GNOME Canvas is buggy, especially when you
run it in antialiased mode.  This is largely because the canvas itself
and the stock items do not follow the "correct" steps when queueing
updates and redraws.  The correct way to do this is mentioned in the
Canvas white paper.

To finish implementing the queued update/redraw process, I would need
to add some class-specific flags to canvas items.  This would mean
breaking binary compatibility.  This is unfortunate, since people are
using the canvas for Real Work, and it cannot be fixed without
breaking binary compatibility.

Some other widgets in GNOME are in the same situation.


Second, what the Right Thing To Do may be...
--------------------------------------------

I think a lot of the object structures in GNOME are good candidates
for being split into public and private parts.  Xt does this, Motif
does this, Unix kernels do this as well.  The idea is to have

	typedef struct {
		GtkObject *parent;

		int public_field_1;
		char *public_field_2;

		gpointer private;
	} SomeObject;

in the public header files.  And in the private .c implementation
files, we could have

	typedef struct {
		int private_field_1;
		int private_field_2;
		char private_field_3;
	} SomeObjectP;

The implementation functions would cast SomeObject->private into a
SomeObjectP and use the private fields there.


Third, a proposed solution...
-----------------------------

Doing this in the trivial way would break binary compatibility.  For
example, some of the fields in the canvas item structures are really
private data that should go into private structures.  However, I
cannot just yank them and put them somewhere else, since the public
structures would change size and thus break compatibility.

Miguel had the idea of replacing these slots with padding instead, and
moving the private fields to private structures.  For example, right
now we have this:

typedef struct {
	GnomeCanvasItem item;

	double x1, y1, x2, y2;
	double width;

	guint fill_color;
	guint outline_color;

	gulong fill_pixel;
	gulong outline_pixel;

	GdkBitmap *fill_stipple;
	GdkBitmap *outline_stipple;

	GdkGC *fill_gc;
	GdkGC *outline_gc;

	/* Antialiased specific stuff follows */

	ArtSVP *fill_svp;
	ArtSVP *outline_svp;

	/* Configuration flags */

	unsigned int fill_set : 1;
	unsigned int outline_set : 1;
	unsigned int width_pixels : 1;
} GnomeCanvasRE;

The idea is to move it to something like this:

typedef struct {
	GnomeCanvasItem item;

	double x1, y1, x2, y2;
	double width;

	guint fill_color;
	guint outline_color;

	gulong pad1;
	gulong pad2;

	GdkBitmap *fill_stipple;
	GdkBitmap *outline_stipple;

	gpointer private;

	gpointer pad3;
	gpointer pad4;
	gpointer pad5;

	unsigned int fill_set : 1;
	unsigned int outline_set : 1;
	unsigned int width_pixels : 1;
} GnomeCanvasRE;

Please note that this preserves the size of the structure (if it
doesn't for all compilers/platforms, please tell me!), and we can
sneak in a private pointer as well.  The private structure inside
gnome-canvas-rect-ellipse.c would look more or less like this:

typedef struct {
	GdkGC *fill_gc;
	GdkGC *outline_gc;

	ArtSVP *fill_svp;
	ArtSVP *outline_svp;

	unsigned int need_svp_recalc : 1;
	unsigned int need_fill_color_set : 1;
	unsigned int need_outline_color_set : 1;
	... bla bla ...
} REPrivate;

This allows the private fields to go into the private structure.  It
also allows the implementation of several flags that are missing to
perform the correct queued update/redraw sequence.

This would let us:

	1. Fix the canvas.  This is very important, since it is buggy,
           and is especially broken in antialiased mode.

	2. Make the code cleaner and easier to extend in the future,
           since private stuff can be kept private, and we can change
           the private structures without breaking binary
           compatibility.

Comments?  I would like to begin doing this as soon as possible.

  Federico



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]