Prerelease of Guis-1.3pre1 (a GTK widget server) for Ruby

Dear All,

I coded a programmable GTK2 widget server (opensource under GPL
license, for GTK2, notably under Linux) called Guis. It run with
Python (a year ago I started to make it for Lua) and an experimental
port is (tentative & incomplete) for Ruby.

The idea of Guis is that the application communicate with Guis: it
sends requests (for making GUI widgets etc…) in a scripting language
(Python or Ruby) and recieves arbitrary textual replies or events
(explicitly sent by scripts). An initial script defines the relevant
procedures to be used in further requests (sent by the
application).

[the idea of a programmable widget server is not new, the old NeWS
system from Sun did it about ten years ago]

Guis is announced on http://freshmeat.net/projects/guis and is
documented on on http://starynkevitch.net/Basile/guisdoc.html the
current released code (for Python only) is on
http://www.starynkevitch.net/Basile/guis-1.2.tar.gz

I am making a prerelease of it, using Ruby with the
ruby-gnome2-all-0.6.0 binding. You can fetch the prerelease code on
http://www.starynkevitch.net/Basile/guis-1.3.pre1.tar.gz and view its
temporary & incomplete documentation on
http://www.starynkevitch.net/Basile/guisdoc_ruby_beta.html - the demo
does work with Ruby (as it does in Python).

I left a few questions there

Is it possible to define virtual variables (in the sense of
rb_define_virtual_variable from Ruby C API) inside a module?

Can a built-in module be extended by scripts?

How to define hooks in Ruby?

I thought of writing in Ruby script

Guis::on_end_of_input do |timeout|
  # user end input hook
done

But I am not sure of how to implement it in C

How to print the current environment (ie the set of local variables
bindings) in C?

How to set the filename before rb_eval_string (it is hardwired to
"(eval)" and I would like to change it)?

Any remarks and suggestions are welcome. In particular, any design
suggestions are welcome…

Regards.

···

Basile STARYNKEVITCH http://starynkevitch.net/Basile/
email: basilestarynkevitchnet
aliases: basiletunesorg = bstarynknerimnet
8, rue de la Faïencerie, 92340 Bourg La Reine, France

Hi,

The idea of Guis is that the application communicate with Guis: it
sends requests (for making GUI widgets etc…) in a scripting language
(Python or Ruby) and recieves arbitrary textual replies or events
(explicitly sent by scripts). An initial script defines the relevant
procedures to be used in further requests (sent by the
application).

very nice idea, does it also work to have multiple apps sending
requests to one Guis?

[the idea of a programmable widget server is not new, the old NeWS
system from Sun did it about ten years ago]

just curious, how much programmable was NeWS? Did it have some
builtin interpreter language or something like this?

Can a built-in module be extended by scripts?

I would think it works exactly like extending builtin classes,
never tried though.

Richard

(citing me, Basile)

>> The idea of Guis is that the application communicate with Guis:
>> it sends requests (for making GUI widgets etc...) in a
>> scripting language (Python or Ruby) and recieves arbitrary
>> textual replies or events (explicitly sent by scripts). [...]

> very nice idea, does it also work to have multiple apps
> sending requests to one Guis?

No, not yet. The problem of having several apps sending requests to
the same Guis is “security”: what do you allow to flow from on app to
another (but you could use X selection mechanism to make different
Guis communicate, if you really want to). There might also be a minor
implementation problem. And why do you want to have several apps
sending to the same Guis? (If you really want a general higher level
graphical system, consider contributing to Fresco)

>> [the idea of a programmable widget server is not new, the old
>> NeWS system from Sun did it about ten years ago]

> just curious, how much programmable was NeWS? Did it have
> some builtin interpreter language or something like this?

many years ago (october 1993), I wrote a (hundred line) description of
NeWS under http://www.zendo.com/vsta/mail/1/0146.html. Unfortunately,
this mail archive is lost. Perhaps you might find it into google
cache?

NeWS was designed by some & same people (Gosling) who later designed
Java. It contained a PostScript interpreter with object oriented &
multi-threaded extensions.

>> Can a built-in module be extended by scripts?

> I would think it works exactly like extending builtin
> classes, never tried though.

Thanks. I suppose you are thinking about the following trick (found on
the rubycentral website):

add a method to_guis to an ExistingClass

ExistingClass.class_eval {
def to_guis
return "result"
end
}

for information, the pre2 prelease of guis 1.3 is available:

http://www.starynkevitch.net/Basile/guis-1.3.pre2.tar.gz
http://www.starynkevitch.net/Basile/guisdoc_ruby_beta.html

I still am lacking of good design ideas on Guis. Could Ruby expert
have a look at the questions listed on
http://www.starynkevitch.net/Basile/guisdoc_ruby_beta.html#htoc21
please

Regards

···

Basile STARYNKEVITCH http://starynkevitch.net/Basile/
email: basilestarynkevitchnet
aliases: basiletunesorg = bstarynknerimnet
8, rue de la Faïencerie, 92340 Bourg La Reine, France

or possibly just

def ExistingClass.new_class_method

end

or

class ExistingClass
def new_instance_method
end
end

did I missed the point ?

···

il 02 Sep 2003 00:31:58 +0200, Basile STARYNKEVITCH basile-news@starynkevitch.net ha scritto::

add a method to_guis to an ExistingClass

ExistingClass.class_eval {
def to_guis
return “result”
end
}

No, not yet. The problem of having several apps sending requests to
the same Guis is “security”: what do you allow to flow from on app to
another (but you could use X selection mechanism to make different
Guis communicate, if you really want to).

this can be really hard depending on the language underlying Guis,
python would seem to make any control impossible.

And why do you want to have several apps
sending to the same Guis? (If you really want a general higher level
graphical system, consider contributing to Fresco)

would be nice to have on embeded systems that are short on memory
or don’t have shared libs or simply to cut startup times for some
apps.
I assume something like Guis with some really small lisp interpreter
(SIOD?) could be very small?

Fresco or PicoGUI are both very interesting, though Fresco will be
probably far too big for many applications.

> just curious, how much programmable was NeWS? Did it have
> some builtin interpreter language or something like this?

many years ago (october 1993), I wrote a (hundred line) description of
NeWS under http://www.zendo.com/vsta/mail/1/0146.html. Unfortunately,
this mail archive is lost. Perhaps you might find it into google
cache?

will try, although chances are slim if I don’t know many keywords.

>> Can a built-in module be extended by scripts?

> I would think it works exactly like extending builtin
> classes, never tried though.

Thanks. I suppose you are thinking about the following trick (found on
the rubycentral website):

add a method to_guis to an ExistingClass

ExistingClass.class_eval {
def to_guis
return “result”
end
}

I meant simply

class Object
def new_wb(*args)
if block_given?
res=new(*args)
yield res
else
raise SyntaxError, “new_wb method expects a block”
end
return res
end
end

will add a method new_wb to class Object and all derived classes.

Richard

···

On Tue, Sep 02, 2003 at 07:49:29AM +0900, Basile STARYNKEVITCH wrote:

Don’t work for an existing builtin class ; try
def String.to_basile
return self + “**”
end

“abc”.to_basile

···

il 02 Sep 2003 00:31:58 +0200, Basile STARYNKEVITCH > basile-news@starynkevitch.net ha scritto::

>> 
>> 
>> ## add a method to_guis to an ExistingClass
>> ExistingClass.class_eval { def to_guis return "result" end }
>> 

> or possibly just

> def ExistingClass.new_class_method ..  end

Basile STARYNKEVITCH Basile STARYNKEVITCH
email: basilestarynkevitchnet
aliases: basiletunesorg = bstarynknerimnet
8, rue de la Faïencerie, 92340 Bourg La Reine, France

Not really, since Guis requires a scripting language with a binding to
GTK, and GTK is not exactly small. Guis could use SIOD if it had a GTK
binding! Of course, Guis by itself is not very big: the gguis.c file
which provides most of the framework and is reused in pyguis [Guis for
python] and ruguis [Guis for ruby] is 1182 lines and 37366 chars; if
you compile it with -Os you get a 33124 byte gguis.o on my x86 with
gcc-3.3. Both py_gguis.c & ru_gguis.c are about 500 lines each.

You may have a look inside Guis - adding another scripting language
support is quite easy (a few routines to code, notably
interpret_request etc…) but it is useless if the scripting language
cannot call GTK to actually build the graphical user interface! GTK is
already big, and any binding of GTK to any scripting language is also
quite big.

I have a question to Ruby experts; I would like to make a primitive
(coded in C, callable from Ruby) on_end_of_input in my Ruby builtin
modules Guis to be able to code in Ruby script for Guis:

Guis::on_end_of_input do |timeout|

do something useful, for example

$stderr.printf(“goodbye world with timeout %d\n”, timeout)
end

Then I want my C routine end_of_input_hook(int timeout) to call the
block passed to on_end_of_input

But I can’t figure out:

  1. How to call (in C)
    rb_define_module_function (ru_guis_module, “on_eoi”, my_on_eoi, 1);
    (what is the number of arguments: 1 (the block) or more

  2. How to implement it in C
    static VALUE
    my_on_eoi(VALUE self,
    //other arguments needed??
    )
    {
    }

(I probably need to use the “call” method with rb_apply but I can’t figure how)

···

On Tue, Sep 02, 2003 at 07:49:29AM +0900, Basile > STARYNKEVITCH wrote:

No, not yet. The problem of having several apps sending
requests to the same Guis is “security”: what do you allow to
flow from on app to another (but you could use X selection
mechanism to make different Guis communicate, if you really
want to).

> this can be really hard depending on the language
> underlying Guis, python would seem to make any control
> impossible.

>> And why do you want to have several apps sending to the same
>> Guis? (If you really want a general higher level graphical
>> system, consider contributing to Fresco)

> would be nice to have on embeded systems that are short
> on memory or don't have shared libs or simply to cut
> startup times for some apps.  I assume something like
> Guis with some really small lisp interpreter (SIOD?)
> could be very small?

Basile STARYNKEVITCH Basile STARYNKEVITCH
email: basilestarynkevitchnet
aliases: basiletunesorg = bstarynknerimnet
8, rue de la Faïencerie, 92340 Bourg La Reine, France

> just curious, how much programmable was NeWS? Did it have
> some builtin interpreter language or something like this?

many years ago (october 1993), I wrote a (hundred line) description of
[…]

will try, although chances are slim if I don’t know many keywords.

IIRC NeWS from Sun used Display Postscript to produce what appeared
on the screen. I never used it, myself. This amy ease your search:
there are so many things called News… I remember being told that
one author achieved his goal of creating round windows with it, but
I can’t cite anything to support that memory.

    Hugh
···

On Tue, 2 Sep 2003, Richard Zidlicky wrote:

On Tue, Sep 02, 2003 at 07:49:29AM +0900, Basile STARYNKEVITCH wrote:

many years ago (october 1993), I wrote a (hundred line) description of
NeWS under http://www.zendo.com/vsta/mail/1/0146.html. Unfortunately,
this mail archive is lost. Perhaps you might find it into google
cache?

will try, although chances are slim if I don’t know many keywords.

Internet archive:

http://web.archive.org/web/19980702082642/http://www.zendo.com/vsta/mail/1/0146.html

you misunderstood me, sorry for being unclear:

irb(main):001:0> def String.class_method
irb(main):002:1> puts ‘class method’
irb(main):003:1> end
=> nil
irb(main):004:0> String.class_method
class method
=> nil
irb(main):005:0> class String
irb(main):006:1> def my_instance_method
irb(main):007:2> return self+‘blabla’
irb(main):008:2> end
irb(main):009:1> end
irb(main):010:0> ‘abc’.my_instance_method
=> “abcblabla”

···

il 02 Sep 2003 01:12:21 +0200, Basile STARYNKEVITCH basile-news@starynkevitch.net ha scritto::

or possibly just

def ExistingClass.new_class_method … end

Don’t work for an existing builtin class ; try
def String.to_basile
return self + “**”
end

“abc”.to_basile

Guis::on_end_of_input do |timeout|
  ## do something useful, for example
  $stderr.printf("goodbye world with timeout %d\n", timeout)
end

Well, I've well understood

   * Guis::on_end_of_input create a lambda() and store it as a variable
     (thread local, instance, global, ... it depend what you want to do)
   

Then I want my C routine end_of_input_hook(int timeout) to call the
block passed to on_end_of_input

  * end_of_input_hook(int timeout) retrieve this variable and call it with
    timeout as argument

Guy Decoux