Re: gamma-bind infinite loops in 0.67

Matto Marjanovic (
Tue, 4 Nov 1997 02:56:13 -0500

Well, I don't know what changed in xscanimage/gtkglue/gtk, but herein lies
a patch, and explanation of what was happening.

But, before that, I think that in light of all this, a good programming
policy should be:

For backend writers: Be careful not to set RELOAD_PARAMS or RELOAD_OPTIONS
if nothing has really changed, i.e. if some option
just gets set to the value it already had.
(This is what that umax patch fixed, and this is
something I need to fix in the microtek backend.)

For frontend writers: Be careful not to unnecessarily set options that
are already set to the intended value.
Kind of pedantic, I guess, but maybe there's a use
for options with non-stationary side-effects, or
something like that.

The backend suggestion is actually directly counter to what is written in
the API documentation for sane_control_option:


.....When this happens, the SANE backend sets this member in *i to
indicate that the application should reload all options. __Note that this
member may be set even if no other option changed.__ However, it is
guaranteed that other options never change without this member being set.

Perhaps the API spec should be modified; either way, one of the two above
needs to be put in effect.

Anyhow, the problem with xscanimage is this loop:

o xscanimage sets some Boolean option which returns a RELOAD_OPTIONS.
o In doing RELOAD_OPTIONS, xscanimage rebuilds dialog box from scratch.
o So, the checkbox for the Boolean option is regenerated:
o The checkbox widget is created
o The `toggle' signal is connected to the callback function
o The initial value is set, but this triggers the callback...
o so xscanimage sets the Boolean option again... etc.

The following patch breaks this loop, by having the initial value of a
Boolean Checkbox set before the callback signal is attached. This actually
seems to follow in the model of the other new widget functions, so it's
probably not a bad thing after all.

You can apply the patch as follows:

cd xxxxxx/sane-0.67/frontend
patch < gtkglue.patch [or, whatever file you put it in]

_Matt M._

--- gtkglue.c.orig Tue Nov 4 02:28:54 1997
+++ gtkglue.c Tue Nov 4 02:26:36 1997
@@ -376,12 +376,13 @@

static void
-button_new (GtkWidget * parent, const char *name, GSGDialogElement * elem,
- GtkTooltips *tooltips, const char *desc)
+button_new (GtkWidget * parent, const char *name, SANE_Word val,
+ GSGDialogElement * elem, GtkTooltips *tooltips, const char *desc)
GtkWidget *button;

button = gtk_check_button_new_with_label ((char *) name);
+ gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), val);
gtk_signal_connect (GTK_OBJECT (button), "toggled",
(GtkSignalFunc) button_update,
@@ -935,14 +936,12 @@

assert (opt->size == sizeof (SANE_Word));
- button_new (parent, title, elem, dialog->tooltips, opt->desc);
status = sane_control_option (dialog->dev, i, SANE_ACTION_GET_VALUE,
&val, 0);
if (status != SANE_STATUS_GOOD)
goto get_value_failed;

- gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (elem->widget), val);
+ button_new (parent, title, val, elem, dialog->tooltips, opt->desc);
gtk_widget_show (parent->parent);

Source code, list archive, and docs:
To unsubscribe: echo unsubscribe sane-devel | mail