[gtkada] Heap corruption and other problems
Dmitry A. Kazakov
mailbox at dmitry-kazakov.de
Tue Aug 13 08:31:37 CEST 2013
On Mon, 12 Aug 2013 20:46:29 -0700, you wrote:
> Dmitry A. Kazakov wrote:
>> Glib.Main.Timeout_Add + Gtk.Widget.Queue_Draw from there. It should
>> not be tighter than 20ms, human eye cannot see any difference anyway.
>> This is exactly how the refresh engine from AICWL works. It is used
>> for animated widgets like the oscilloscope, clocks etc.
> I'd like to see an example of this. This new way of dealing with main
> loops is a bit daunting without an example.
It does not have to deal with that. Here is what it does:
procedure Set_Period
( Engine : in out Layered_Refresh_Engine;
Period : Duration
) is
begin
if Period /= Engine.Period then
declare
Interval : GUInt := GUInt (GDouble (Period) * 1_000.0);
begin
if Engine.Timer /= 0 then
if 0 = Remove (Engine.Timer) then
null;
end if;
Engine.Timer := 0;
end if;
Engine.Timer :=
Timeout_Add
( Interval,
Timer'Access,
Engine'Address
);
Engine.Period := Period;
end;
end if;
end Set_Period;
The timer goes through the list of widgets serviced by the engine and does
Queue_Draw for each. The list elements are weak references which are
automatically invalidated when the referenced widget disappears. Such
elements are removed from the list.
function Timer (Data : System.Address) return GBoolean is
Engine : Layered_Refresh_Engine renames
Conversions.To_Pointer (Data).all;
begin
if Engine.List /= null then
Engine.Active := True;
declare
This : not null access List_Element := Engine.List;
Next : not null access List_Element := This;
begin
loop
Next := This.Next;
if Is_Valid (This.Widget) then
Queue_Draw (Get (This.Widget));
else
Delete (Engine, This.all'Unchecked_Access);
exit when Engine.List = null;
end if;
exit when Next = Engine.List;
This := Next;
end loop;
end;
Engine.Active := False;
end if;
return 1;
end Timer;
Note that this is fully compatible with the event-controlled path of
updating widget. E.g. if you change the widget by some other means (resize
for example) it will get a draw notification independently on the timer.
>> I don't understand this. Your widget must be a descendant of at least
>> Gtk_Widget_Record.
> No. I create my own Widgets using Gdk.Window as a base and my own class
> hierarchy.
Which is the source of your problems. You are throwing overboard almost
everything Gtk has to offer.
>> I am waiting for other problems resolved and GtkAda packaged for
>> Linux. I can post code snippets from AICWL if you are interested.
> I would appreciate all the help I can get.
Let me know then.
>> Gdk_Window is unusable, IMO.
> That is all I use. It has become less useful because of Cairo but I
> wouldn't say it is unusable! :-)
So can see that from its declaration:
type Gdk_Window is new Glib.C_Proxy;
And from the design POV it does not make any sense to have your stuff as a
window rather than a widget. A widget can be put into a container and used
in thousand useful ways in which a window cannot (be themed, have
properties, styles and so on). You gain nothing by doing it window. A
widget can always be made a window by putting it into one. Since Gtk3
widgets can be transparent because Cairo uses alpha channel.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
More information about the gtkada
mailing list