comp.lang.ada
 help / color / mirror / Atom feed
* GTK and tasking (GNAT)
@ 2014-05-03 20:30 hreba
  2014-05-03 21:23 ` Simon Wright
  2014-05-04  7:31 ` Dmitry A. Kazakov
  0 siblings, 2 replies; 15+ messages in thread
From: hreba @ 2014-05-03 20:30 UTC (permalink / raw)


I guess the following reveals my ignorance about GTK as well as about 
tasking, but anyway, still beginner.

I made a GTK window with a button and a text box. Upon pressing the 
button, the text box shall count to 10 in 0.5 s intervals.

Here follows my callback package (for the button callback function 
'Start', 'with'-clauses omitted):

-------------------------------------------------------------------
package Callback is

    type UserType is record
       txtBox:	Gtk.GEntry.Gtk_Entry;
    end record;

    package Handlers is new Gtk.Handlers.User_Callback
      (Widget_Type => Gtk.Widget.Gtk_Widget_Record,
       User_Type	=> UserType);

    procedure Start
      (widget: access Gtk.Widget.Gtk_Widget_Record'Class;
       event: Gdk.Event.Gdk_Event;
       ud: UserType);

end Callback;


package body Callback is

    procedure Start
      (widget: access Gtk.Widget.Gtk_Widget_Record'Class;
       event: Gdk.Event.Gdk_Event;
       ud: UserType) is

    begin
       for i in 1..10 loop
          Gtk.GEntry.Set_Text (ud.txtBox, Integer'Image(i));
          --Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(ud.txtBox));
          delay 0.5;
       end loop;
    end Start;

end Callback;

------------------------------------------------------------------

Now when I press the button nothing happens at first, and after 5 
seconds a "1" appears in the text box.
Uncommenting the QueueDraw line didn't change anything.

Searching for an explication, I thought perhaps somehow some 
display-update mechanism of GTK is suspended together with my main task 
during the delays. So I wrote a version using Ada tasks (for the first 
time in my life). Well, it didn't work either, exactly the same behavior.

Can somebody tell me what is wrong and how to do it right?

The source of the tasked version follows. The other callback function, 
'Quit' is connected to the 'delete' event of the main window.


---------------------------------------------------------------------
package Callback is

    type UserType is record
       txtBox:	Gtk.GEntry.Gtk_Entry;
    end record;


    package Handlers is new Gtk.Handlers.User_Callback
      (Widget_Type => Gtk.Widget.Gtk_Widget_Record,
       User_Type	=> UserType);

    package Return_Handlers is new Gtk.Handlers.Return_Callback
       (Widget_Type => Gtk.Widget.Gtk_Widget_Record,
        Return_Type => Boolean);

    function Quit (
        widget: access Gtk.Widget.Gtk_Widget_Record'Class;
        event: Gdk.Event.Gdk_Event) return Boolean;

    procedure Start
      (widget: access Gtk.Widget.Gtk_Widget_Record'Class;
       event: Gdk.Event.Gdk_Event;
       ud: UserType);

end Callback;



package body Callback is

    goon:	Boolean:= true;

    task Task2 is
       entry StartCounter (txtBox: Gtk.GEntry.Gtk_Entry);
       entry TermTask;		-- terminate task
    end Task2;

    task body Task2 is
    begin
       while goon loop
          select
             accept StartCounter (txtBox: Gtk.GEntry.Gtk_Entry) do
                for i in 1..10 loop
                   Gtk.GEntry.Set_Text (txtBox, Integer'Image(i));
                   Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(txtBox));
                   delay 0.5;
                end loop;
             end StartCounter;
          or
             accept TermTask do
                goon:= false;
             end TermTask;
          end select;
       end loop;
       Ada.Text_IO.Put_Line("Task2 terminating");
    end Task2;


    function Quit (
        widget: access Gtk.Widget.Gtk_Widget_Record'Class;
        event: Gdk.Event.Gdk_Event) return Boolean is
       --pragma Unreferenced (widget);
       pragma Unreferenced (event);
    begin
       Task2.TermTask;
       Gtk.Main.Main_Quit;
       return False;
    end Quit;


    procedure Start
      (widget: access Gtk.Widget.Gtk_Widget_Record'Class;
       event: Gdk.Event.Gdk_Event;
       ud: UserType) is
    begin
       Task2.StartCounter (ud.txtBox);
    end Start;

end Callback;

------------------------------------------------------------------------






-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-03 20:30 GTK and tasking (GNAT) hreba
@ 2014-05-03 21:23 ` Simon Wright
  2014-05-04 18:10   ` hreba
  2014-05-04 22:10   ` hreba
  2014-05-04  7:31 ` Dmitry A. Kazakov
  1 sibling, 2 replies; 15+ messages in thread
From: Simon Wright @ 2014-05-03 21:23 UTC (permalink / raw)


hreba <hreba@terra.com.br> writes:

>             accept StartCounter (txtBox: Gtk.GEntry.Gtk_Entry) do
>                for i in 1..10 loop
>                   Gtk.GEntry.Set_Text (txtBox, Integer'Image(i));
>                   Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(txtBox));
>                   delay 0.5;
>                end loop;
>             end StartCounter;

The calling task (probably the Gtk main loop) blocks while the body of
the accept statement is executed.

I don't know how this ought to be done in Gtk, though I strongly suspect
it's not like that! However, the way to deal with the task problem would
normally be to save the values passed with the accept and deal with them
afterward:

   accept StartCounter (txtBox: Gtk.GEntry.Gtk_Entry) do
      txtBoxCopy := txtBox;
   end StartCounter;
   --  Now the caller can carry on while we work with the passed value.
   for i in 1..10 loop
      Gtk.GEntry.Set_Text (txtBoxCopy, Integer'Image(i));
      Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(txtBoxCopy));
      delay 0.5;
   end loop;

Questions: is Gtk thread-safe? is Queue_Draw something that should only
be called from the Gtk event queue?


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-03 20:30 GTK and tasking (GNAT) hreba
  2014-05-03 21:23 ` Simon Wright
@ 2014-05-04  7:31 ` Dmitry A. Kazakov
  2014-05-04 18:36   ` hreba
  1 sibling, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-04  7:31 UTC (permalink / raw)


On Sat, 03 May 2014 17:30:08 -0300, hreba wrote:

> Can somebody tell me what is wrong and how to do it right?

1. Gtk is not task-safe, which also includes Glib, Cairo etc.

2. Gtk are synchronous calls, when performed between tasks this may lead to
deadlocking even in a task-safe environment, which Gtk is not.

If you want to call to Gtk operations from an independent Ada task you must
marshal it to the main task (the task running Gtk messages loop). An
implementation of this mechanism is here:

http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#1

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-03 21:23 ` Simon Wright
@ 2014-05-04 18:10   ` hreba
  2014-05-04 18:29     ` Simon Wright
  2014-05-04 22:10   ` hreba
  1 sibling, 1 reply; 15+ messages in thread
From: hreba @ 2014-05-04 18:10 UTC (permalink / raw)


On 05/03/2014 06:23 PM, Simon Wright wrote:
> hreba <hreba@terra.com.br> writes:
>
>>              accept StartCounter (txtBox: Gtk.GEntry.Gtk_Entry) do
>>                 for i in 1..10 loop
>>                    Gtk.GEntry.Set_Text (txtBox, Integer'Image(i));
>>                    Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(txtBox));
>>                    delay 0.5;
>>                 end loop;
>>              end StartCounter;
>
> The calling task (probably the Gtk main loop) blocks while the body of
> the accept statement is executed.
>
> I don't know how this ought to be done in Gtk, though I strongly suspect
> it's not like that! However, the way to deal with the task problem would
> normally be to save the values passed with the accept and deal with them
> afterward:
>
>     accept StartCounter (txtBox: Gtk.GEntry.Gtk_Entry) do
>        txtBoxCopy := txtBox;
>     end StartCounter;
>     --  Now the caller can carry on while we work with the passed value.
>     for i in 1..10 loop
>        Gtk.GEntry.Set_Text (txtBoxCopy, Integer'Image(i));
>        Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(txtBoxCopy));
>        delay 0.5;
>     end loop;
>
> Questions: is Gtk thread-safe? is Queue_Draw something that should only
> be called from the Gtk event queue?
>

I didn't expect that my first excursion into GUI programming (GTK) with 
Ada would confront me with tasking and lead me into the cliffs of 
thread-safety.

I am no software engineer, unfortunately I cannot answer these questions.

So I will have a look at Dimitry's library.

Thanks for the answer.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 18:10   ` hreba
@ 2014-05-04 18:29     ` Simon Wright
  0 siblings, 0 replies; 15+ messages in thread
From: Simon Wright @ 2014-05-04 18:29 UTC (permalink / raw)


hreba <hreba@terra.com.br> writes:

> On 05/03/2014 06:23 PM, Simon Wright wrote:

>> Questions: is Gtk thread-safe? is Queue_Draw something that should only
>> be called from the Gtk event queue?
>>
>
> I didn't expect that my first excursion into GUI programming (GTK)
> with Ada would confront me with tasking and lead me into the cliffs of
> thread-safety.

It's the same with X11, Tcl/Tk, and probably other such systems. At
least X11 came (comes?) with thread support if you need it.

> I am no software engineer, unfortunately I cannot answer these
> questions.
>
> So I will have a look at Dimitry's library.

A good plan!


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04  7:31 ` Dmitry A. Kazakov
@ 2014-05-04 18:36   ` hreba
  2014-05-04 19:26     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 15+ messages in thread
From: hreba @ 2014-05-04 18:36 UTC (permalink / raw)


On 05/04/2014 04:31 AM, Dmitry A. Kazakov wrote:
> On Sat, 03 May 2014 17:30:08 -0300, hreba wrote:
>
>> Can somebody tell me what is wrong and how to do it right?
>
> 1. Gtk is not task-safe, which also includes Glib, Cairo etc.
>
> 2. Gtk are synchronous calls, when performed between tasks this may lead to
> deadlocking even in a task-safe environment, which Gtk is not.
>
> If you want to call to Gtk operations from an independent Ada task you must
> marshal it to the main task (the task running Gtk messages loop). An
> implementation of this mechanism is here:
>
> http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#1
>

Is 'task-safe' more or less the same as 'thread-safe'?

I have a little experience with GTK programming using Oberon, which 
doesn't contain a task concept on the language level.

I am somewhat disappointed about the details you have to understand 
about GTK and tasking in order to use a GUI in an Ada program.

Given that what I want is

  - libraries available on Linux and Windows (as GTK)
  - a GUI builder for the layout (as Glade)
  - no fancy things, but:
     * buttons
     * text boxes
     * drawing areas
     * keyboard, mouse click and mouse movement events
  - basic tasking: life output (progress) during lengthy calculations

What GUI library would you recommend?

I would be happy and grateful to use your GtkAda contributions, I just 
want to be sure to use more or less common software.

Thanks for your answer.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 18:36   ` hreba
@ 2014-05-04 19:26     ` Dmitry A. Kazakov
  2014-05-04 20:40       ` hreba
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-04 19:26 UTC (permalink / raw)


On Sun, 04 May 2014 15:36:55 -0300, hreba wrote:

> Is 'task-safe' more or less the same as 'thread-safe'?

Yes.
 
> I am somewhat disappointed about the details you have to understand 
> about GTK and tasking in order to use a GUI in an Ada program.

Tasking is not simple. Tasking in a GUI is always complicated.

> Given that what I want is
> 
>   - libraries available on Linux and Windows (as GTK)
>   - a GUI builder for the layout (as Glade)
>   - no fancy things, but:
>      * buttons
>      * text boxes
>      * drawing areas
>      * keyboard, mouse click and mouse movement events
>   - basic tasking: life output (progress) during lengthy calculations

Progress indicator is not tasking.

Tasking is when the job is done in a task independent on the main task
processing the messages loop.

> What GUI library would you recommend?

Gtk is no worse than anything else. [*]

P.S. Raw Windows API is largely task-safe. But Windows API is not portable
and it has other issues, like messages generators and deadlocks.

------
* Except that Gtk 3.x is very poorly supported. Gtk 2.24 is quite usable. I
hope that coming GNAT GPL 2014 will improve this.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 19:26     ` Dmitry A. Kazakov
@ 2014-05-04 20:40       ` hreba
  2014-05-04 21:07         ` Shark8
  0 siblings, 1 reply; 15+ messages in thread
From: hreba @ 2014-05-04 20:40 UTC (permalink / raw)


On 05/04/2014 04:26 PM, Dmitry A. Kazakov wrote:
>
> Progress indicator is not tasking.
>

After the experience with my small exercise here, without tasking, I 
would expect the progress bar to jump from 0 to 1 at the end of a 
lengthy calculation instead of increasing steadily.

This kind of life display is one reason for me to worry about tasking.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 20:40       ` hreba
@ 2014-05-04 21:07         ` Shark8
  2014-05-04 21:32           ` hreba
  0 siblings, 1 reply; 15+ messages in thread
From: Shark8 @ 2014-05-04 21:07 UTC (permalink / raw)


On 04-May-14 14:40, hreba wrote:
>
> After the experience with my small exercise here, without tasking, I
> would expect the progress bar to jump from 0 to 1 at the end of a
> lengthy calculation instead of increasing steadily.
>
> This kind of life display is one reason for me to worry about tasking.

The problem isn't tasking, it's decomposition.
If the "lengthy function" cannot be broken down then there are only two 
points that we can really know: start, and finished. (i.e 0.0 & 1.0)

If, on the other hand, we can break it down, say into eighths, we get:
0.0, 0.125, 0.250, 0.375, 0.500, 0.625, 0.75, 0.875, 1.000
Which is n+1 states, where n is the cardinality of the resolution of 
"breaking it down". ( As an example regarding DB-access/-processing 
being so decomposed, watch this: 
https://www.youtube.com/watch?v=mD4GJ36Npqk )


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 21:07         ` Shark8
@ 2014-05-04 21:32           ` hreba
  2014-05-04 21:44             ` Shark8
  2014-05-05  7:33             ` Dmitry A. Kazakov
  0 siblings, 2 replies; 15+ messages in thread
From: hreba @ 2014-05-04 21:32 UTC (permalink / raw)


On 05/04/2014 06:07 PM, Shark8 wrote:
> On 04-May-14 14:40, hreba wrote:
>>
>> After the experience with my small exercise here, without tasking, I
>> would expect the progress bar to jump from 0 to 1 at the end of a
>> lengthy calculation instead of increasing steadily.
>>
>> This kind of life display is one reason for me to worry about tasking.
>
> The problem isn't tasking, it's decomposition.
> If the "lengthy function" cannot be broken down then there are only two
> points that we can really know: start, and finished. (i.e 0.0 & 1.0)
>
> If, on the other hand, we can break it down, say into eighths, we get:
> 0.0, 0.125, 0.250, 0.375, 0.500, 0.625, 0.75, 0.875, 1.000
> Which is n+1 states, where n is the cardinality of the resolution of
> "breaking it down". ( As an example regarding DB-access/-processing
> being so decomposed, watch this:
> https://www.youtube.com/watch?v=mD4GJ36Npqk )

I am talking about calculations that can be broken down, as in my 
example at the beginning of this thread: I count from 1 to 10, update a 
text box and call delay at each iteration, but the display changes only 
after the termination of the loop.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 21:32           ` hreba
@ 2014-05-04 21:44             ` Shark8
  2014-05-04 21:57               ` hreba
  2014-05-05  7:33             ` Dmitry A. Kazakov
  1 sibling, 1 reply; 15+ messages in thread
From: Shark8 @ 2014-05-04 21:44 UTC (permalink / raw)


On 04-May-14 15:32, hreba wrote:
>
> I am talking about calculations that can be broken down, as in my
> example at the beginning of this thread: I count from 1 to 10, update a
> text box and call delay at each iteration, but the display changes only
> after the termination of the loop.

Then it may be a weakness of GTK*; I would expect it to have a 
progress-bar object w/ such parameters as Minimum, Maximum, and Current.

* -- I haven't ever used GTK though, so I don't know if it does or not.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 21:44             ` Shark8
@ 2014-05-04 21:57               ` hreba
  0 siblings, 0 replies; 15+ messages in thread
From: hreba @ 2014-05-04 21:57 UTC (permalink / raw)


On 05/04/2014 06:44 PM, Shark8 wrote:
> On 04-May-14 15:32, hreba wrote:
>>
>> I am talking about calculations that can be broken down, as in my
>> example at the beginning of this thread: I count from 1 to 10, update a
>> text box and call delay at each iteration, but the display changes only
>> after the termination of the loop.
>
> Then it may be a weakness of GTK*; I would expect it to have a
> progress-bar object w/ such parameters as Minimum, Maximum, and Current.
>
> * -- I haven't ever used GTK though, so I don't know if it does or not.

GTK has a progress bar, but this is not my point.

I want to give feedback to the user during lengthy processing, as in my 
example, by updating a display element of the GUI. One choice is 
updating the contents of a text box. If this doesn't work then I am 
pretty sure that updating a progress bar wouldn't work either.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-03 21:23 ` Simon Wright
  2014-05-04 18:10   ` hreba
@ 2014-05-04 22:10   ` hreba
  1 sibling, 0 replies; 15+ messages in thread
From: hreba @ 2014-05-04 22:10 UTC (permalink / raw)


On 05/03/2014 06:23 PM, Simon Wright wrote:
>
> I don't know how this ought to be done in Gtk, though I strongly suspect
> it's not like that! However, the way to deal with the task problem would
> normally be to save the values passed with the accept and deal with them
> afterward:
>
>     accept StartCounter (txtBox: Gtk.GEntry.Gtk_Entry) do
>        txtBoxCopy := txtBox;
>     end StartCounter;
>     --  Now the caller can carry on while we work with the passed value.
>     for i in 1..10 loop
>        Gtk.GEntry.Set_Text (txtBoxCopy, Integer'Image(i));
>        Gtk.Widget.Queue_Draw (Gtk.Widget.Gtk_Widget(txtBoxCopy));
>        delay 0.5;
>     end loop;
>

Read your reply again. This is the crucial hint. It works now.

Thanks a lot!
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-04 21:32           ` hreba
  2014-05-04 21:44             ` Shark8
@ 2014-05-05  7:33             ` Dmitry A. Kazakov
  2014-05-06 12:43               ` hreba
  1 sibling, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2014-05-05  7:33 UTC (permalink / raw)


On Sun, 04 May 2014 18:32:45 -0300, hreba wrote:

> I am talking about calculations that can be broken down, as in my 
> example at the beginning of this thread: I count from 1 to 10, update a 
> text box and call delay at each iteration, but the display changes only 
> after the termination of the loop.

You can find an example of how to do this in GtkAda here:

http://www.dmitry-kazakov.de/ada/aicwl.htm#12.6

The example performs a very lengthy calculation in an independent task and
among other updates a progress bar.

The method is still the one I described.

http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#1

You post data (e.g. the bar position) to the main loop from where the
action is performed.

So the plotter in the example is based on this technique as well. Its
refresh engine, which periodically updates the curves, is an Ada task that
posts Queue_Draw to the main loop.

There is no simple way of doing tasking in GUI.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: GTK and tasking (GNAT)
  2014-05-05  7:33             ` Dmitry A. Kazakov
@ 2014-05-06 12:43               ` hreba
  0 siblings, 0 replies; 15+ messages in thread
From: hreba @ 2014-05-06 12:43 UTC (permalink / raw)


On 05/05/2014 04:33 AM, Dmitry A. Kazakov wrote:
> On Sun, 04 May 2014 18:32:45 -0300, hreba wrote:
>
>> I am talking about calculations that can be broken down, as in my
>> example at the beginning of this thread: I count from 1 to 10, update a
>> text box and call delay at each iteration, but the display changes only
>> after the termination of the loop.
>
> You can find an example of how to do this in GtkAda here:
>
> http://www.dmitry-kazakov.de/ada/aicwl.htm#12.6
>
> The example performs a very lengthy calculation in an independent task and
> among other updates a progress bar.
>
> The method is still the one I described.
>
> http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#1
>
> You post data (e.g. the bar position) to the main loop from where the
> action is performed.
>
> So the plotter in the example is based on this technique as well. Its
> refresh engine, which periodically updates the curves, is an Ada task that
> posts Queue_Draw to the main loop.
>
> There is no simple way of doing tasking in GUI.
>

Thanks a lot for the wealth of information.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-05-06 12:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-03 20:30 GTK and tasking (GNAT) hreba
2014-05-03 21:23 ` Simon Wright
2014-05-04 18:10   ` hreba
2014-05-04 18:29     ` Simon Wright
2014-05-04 22:10   ` hreba
2014-05-04  7:31 ` Dmitry A. Kazakov
2014-05-04 18:36   ` hreba
2014-05-04 19:26     ` Dmitry A. Kazakov
2014-05-04 20:40       ` hreba
2014-05-04 21:07         ` Shark8
2014-05-04 21:32           ` hreba
2014-05-04 21:44             ` Shark8
2014-05-04 21:57               ` hreba
2014-05-05  7:33             ` Dmitry A. Kazakov
2014-05-06 12:43               ` hreba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox