Discussion:
ANNOUNCE - graphics package
(too old to reply)
unknown
2004-01-12 11:00:21 UTC
Permalink
ex11

This is to announce that a pre-alpha release of ex11 is now available.

ex11 is a 100% pure Erlang graphics package, which works only with
X-windows.

ex11 talks *directly* to the X-server, no C is linked in.

The ex11 release contains a library to talk to the server (This is
similar to XLib) and a widget set.

The widget set is very powerful and very simple.

ex11 with programming examples and screen shots can be found
at.

http://www.sics.se/~joe/ex11

At this stage I'd ask as many people as possible to test this release and
report any bugs or problems encountered in starting the system.

Later I'd like volunteers to write new widgets and tools.

I will support the widget infrastructure and the low level X library.

Have fun

/Joe

PS - Thanks to Tobbe (who started this long ago) - and Vlad and Tony
who have also hacked this at various times in the past.
unknown
2004-01-12 12:39:38 UTC
Permalink
Excellent!!

I've tested it and it works now, even for me :-)

I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.

best regards,
Vlad
unknown
2004-01-12 13:14:25 UTC
Permalink
For those who may have difficulties with X11, do the following after make all:

xhost +localhost
erl -pa ./lib -pa ./widget.

Pete.

P.s. thanks Joe :-)


On Mon, 12 Jan 2004 13:39:38 +0100
Post by unknown
Excellent!!
I've tested it and it works now, even for me :-)
I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.
best regards,
Vlad
--
Peter-Henry Mander
BSc hons. Comp Sci & Cyb
Software Engineer
Newport Networks Limited

Tel: + 44 (0) 1494 470 681
unknown
2004-01-12 13:45:19 UTC
Permalink
This should not be necessary - I'd really like to know those cases
where the start procedure fails.

If authentication fails it is because

ex11_lib_driver:get_cookie

Has not been able to figure out what cookie to use

If authentication fails then give the commands
xauth
list

To see what cookies you have, then stare at the code in ex11_lib_driver
and ex11_lib_xauth to figure out what when wrong.

/Joe
xhost +localhost
erl -pa ./lib -pa ./widget.
Pete.
P.s. thanks Joe :-)
On Mon, 12 Jan 2004 13:39:38 +0100
Post by unknown
Excellent!!
I've tested it and it works now, even for me :-)
I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.
best regards,
Vlad
unknown
2004-01-12 16:23:31 UTC
Permalink
Hi Joe,

In my case with SuSE 8.2 the .Xauthority list simply doesn't contain localhost. There's 127.0.0.2, and the actual hostname too, but not localhost. I'm not sure how or why it's become like this. Using xhost or xauth as a remedy does work.

It's no fault of ex11, although the demo does fail silently, there's no supervisor to catch the exit value of sw_driver:wConnect/2.

Pete.

On Mon, 12 Jan 2004 14:45:19 +0100 (CET)
Post by unknown
This should not be necessary - I'd really like to know those cases
where the start procedure fails.
If authentication fails it is because
ex11_lib_driver:get_cookie
Has not been able to figure out what cookie to use
If authentication fails then give the commands
xauth
list
To see what cookies you have, then stare at the code in ex11_lib_driver
and ex11_lib_xauth to figure out what when wrong.
/Joe
xhost +localhost
erl -pa ./lib -pa ./widget.
Pete.
P.s. thanks Joe :-)
On Mon, 12 Jan 2004 13:39:38 +0100
Post by unknown
Excellent!!
I've tested it and it works now, even for me :-)
I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.
best regards,
Vlad
--
Peter-Henry Mander
BSc hons. Comp Sci & Cyb
Software Engineer
Newport Networks Limited

Tel: + 44 (0) 1494 470 681
unknown
2004-01-12 14:21:36 UTC
Permalink
Post by unknown
I will support the widget infrastructure and the low level X library.
It's quite soon to ask this, but I wonder: do your plans include adding
functionality for X extensions? From what I saw in the code, it's not so easy to
extend in a modular way, but I may be jumping to conclusions.

What I had in mind was the Render extension, and also support for Xft. This goes
a bit beyond "Erlang only talks to X server", but I guess you would be also
interested in high quality output, TrueType fonts, antialiasing, transparency
and so on ;-)

regards,
Vlad
unknown
2004-01-12 14:26:55 UTC
Permalink
Post by unknown
Post by unknown
I will support the widget infrastructure and the low level X library.
It's quite soon to ask this, but I wonder: do your plans include adding
functionality for X extensions? From what I saw in the code, it's not so easy to
extend in a modular way, but I may be jumping to conclusions.
What I had in mind was the Render extension, and also support for Xft. This goes
a bit beyond "Erlang only talks to X server", but I guess you would be also
interested in high quality output, TrueType fonts, antialiasing, transparency
and so on ;-)
Yes indeed - but this is running before we can walk - text widgets
for variable width fonts etc is not entirely trivial.

I'm beginnging to wonder about extension this - now do I do alpha
blending for example??

/Joe
Post by unknown
regards,
Vlad
unknown
2004-01-12 14:36:24 UTC
Permalink
Post by unknown
I'm beginnging to wonder about extension this - now do I do alpha
blending for example??
I used to have a link to documentation for most X protocols (core and
extensions) but I lost it. Maybe I will find it at home.

Otherwise, I think the best way to learn about Render is from the sources that
come with XFree86.

/Vlad
unknown
2004-01-12 16:40:56 UTC
Permalink
Oh yes!
could I add some support for PDF like primitives to the wishlist, so
one could have an ErlGuten like interface.
See: http://www.cairographics.org/

There are actually two X11 libraries under jungerl:
ex11 and x11, is "ex11" the one to choose?

Regards Mikael.
Post by unknown
Post by unknown
Post by unknown
I will support the widget infrastructure and the low level X library.
It's quite soon to ask this, but I wonder: do your plans include adding
functionality for X extensions? From what I saw in the code, it's not so
easy to extend in a modular way, but I may be jumping to conclusions.
What I had in mind was the Render extension, and also support for Xft.
This goes a bit beyond "Erlang only talks to X server", but I guess you
would be also interested in high quality output, TrueType fonts,
antialiasing, transparency and so on ;-)
Yes indeed - but this is running before we can walk - text widgets
for variable width fonts etc is not entirely trivial.
I'm beginnging to wonder about extension this - now do I do alpha
blending for example??
/Joe
Post by unknown
regards,
Vlad
unknown
2004-01-12 18:43:00 UTC
Permalink
From: "Mikael Karlsson" <mikael.karlsson>
Post by unknown
could I add some support for PDF like primitives to the wishlist, so
one could have an ErlGuten like interface.
See: http://www.cairographics.org/
And slightly related, on the To Do list ahould probably be a gs emulation
layer, so that existing graphics applications can be ported smoothly.

/Vlad
unknown
2004-01-12 14:40:40 UTC
Permalink
Post by unknown
Post by unknown
I will support the widget infrastructure and the low level X library.
It's quite soon to ask this, but I wonder: do your plans include adding
functionality for X extensions? From what I saw in the code, it's not so easy to
extend in a modular way, but I may be jumping to conclusions.
On the contrary it is *very* easy - If I have not misunderstood.

In my code most commands boil down to things like (for example)


xDo(Display, ePolyFillRectangle(DrawCursor, GC0,
[mkRectangle(0,0,?CursorWidth, ?CursorHt)])),


All names like

ex11_lib:eXXXXX

Are primitive protocol messages.

To add support for (say) a rendering extension one could make a new
protocol conversion module and write:

xDo(Display, render:eSomeProtocolMessage(.....))

etc.

/Joe
Post by unknown
What I had in mind was the Render extension, and also support for Xft. This goes
a bit beyond "Erlang only talks to X server", but I guess you would be also
interested in high quality output, TrueType fonts, antialiasing, transparency
and so on ;-)
regards,
Vlad
unknown
2004-01-12 14:53:28 UTC
Permalink
Post by unknown
To add support for (say) a rendering extension one could make a new
xDo(Display, render:eSomeProtocolMessage(.....))
etc.
Oh, yes! :-)

The replies are a little more tricky (i.e. one has to know which module to ask
to decode the data) but not much, and what I was thinking was to have the
extensions in mind so that it will be easy to add them after the core
functionality runs smoothly.

Just to check if I didn't miss this one: the image functionality isn't complete,
is it?

/Vlad
unknown
2004-01-12 15:35:42 UTC
Permalink
Post by unknown
Post by unknown
To add support for (say) a rendering extension one could make a new
xDo(Display, render:eSomeProtocolMessage(.....))
etc.
Oh, yes! :-)
The replies are a little more tricky (i.e. one has to know which module to ask
to decode the data) but not much, and what I was thinking was to have the
extensions in mind so that it will be easy to add them after the core
functionality runs smoothly.
This is also easy :-)

Primitives end up by calling either req or call like this:


ePutImage(Draw, GC, Width, Ht, X, Y, Pad, Depth, Data) ->
req(72, 2, <<Draw:32,GC:32,Width:16,Ht:16,X:16,Y:16,Pad:8,Depth:8,
0:16,Data/binary>>).

PutImage has no reply


eQueryFont(Id) ->
call(47, <<Id:32>>, eQueryFont).
**********

Query font has a reply. Here eQueryFont is the name of the parser to
be called when the command returns

Then when later the command returns this code gets called: ...

pReply1(eQueryFont, <<_:64,
MinBounds:12/binary, % note the units of binary
% are inbytes
_:32,
MaxBounds:12/binary,
_:32,
MinByte2:16,
MaxByte2:16,
DefaultChar:16,
NFontProps:16,
DrawDirection:8,
MinByte1:8,
MaxByte1:8,
AllCharsExist:8,
FontAscent:?INT16,
FontDescent:?INT16,
NCharInfos:32,
...
Post by unknown
Just to check if I didn't miss this one: the image functionality isn't complete,
is it?
No. I have included the code to read and display a Jpeg - but I removed it
from the examples when I found that it didn't work on all machines.
You can try it if you like

The example only works if you have "true color" (I think its called this)

The code works if you have a modern graphics card but fails if you have to
map the colors. I have written the code for this but
still get weird colors on my machine at work.

/Joe
Post by unknown
/Vlad
unknown
2004-01-12 18:45:15 UTC
Permalink
Post by unknown
Post by unknown
The replies are a little more tricky
This is also easy :-)
eQueryFont(Id) ->
call(47, <<Id:32>>, eQueryFont).
**********
Then when later the command returns this code gets called: ...
pReply1(eQueryFont, <<_:64,
MinBounds:12/binary, % note the units of binary
Great! I couldn't figure that out in the short time I had.

/Vlad
unknown
2004-01-13 12:58:54 UTC
Permalink
From: "Joe Armstrong" <joe>
Post by unknown
Post by unknown
The replies are a little more tricky
This is also easy :-)
Ok, you got me into a corner here ;-)

The only remaining thing to pick on are events. It doesn't seem probable that
extensions would define own events, but it seems worth checking.

/Vlad
unknown
2004-01-14 08:44:16 UTC
Permalink
Hi,

I thought I'd share some random and unsorted thoughts I had about a widget
framework. Nothing revolutionary, but why let them go to waste? :-)

* widget users should see only generic events, not X ones. By that I mean there
should be a generic protocol (as is sketched in ex11_widget_button) for example
onClick, onDoubleClick, onEnter, onKeyPressed, onMouseMove, onMouseButtonDown,
etc. Maybe even onCreate, onDestroy?

* the event handlers should get the widget pid as an argument, so that they can
react according to the current state. For example draw_button() paints slightly
different if the button is pressed.

* the !! operator is cool, but it should be used with care. Maybe the
implementation of sysd:rpc should be refined to include timeouts and the
possibility to get the reply later (? la gen_server). The reason is that if
there are several widgets interacting (i.e. their states are interdependent)
it's very easy to get a deadlock.
For example radio buttons work as a unit.

* there is some GUI functionality that isn't local to a widget (even if it may
seem to be). For example tab order is known at parent window level, so the
parent window should get the opportunity to see keypresses before the child,
filtering tabs out (unless the child specifically wants to get them).

* there will be quite a bit of functionality common for many widgets. I think
there should be a way to reuse it without resorting to cut-and-paste techniques
;-) I won't mention inheritance (oops, I just did!) because there are other
ways - like for example providing plenty of hook points and functionality for
adding/removing custom hooks (? la Emacs).
For example implementing a tri-state button would require very little
changes to a regular button.

* It would be good if we could find an existing framework from which to map the
functionality. There's no need to make all mistakes from scratch. Most
frameworks are OO and make heavy use of inheritance, which is not a good
starting point, but see above.

That's it for now. Cheers!
/Vlad
unknown
2004-01-13 09:57:31 UTC
Permalink
thought i try ex11, but then i saw this;
"!! is an infix RPC operator. This needs a ONE LINE change to
erl_parse.yrl which makes a new version of erl_parse.erl"
so only people that willing/able to rebuild erl_parse can try ex11. i
for one am not (willing, that is).
but maybe a sed script or something can convert the code to erlang?

mats
unknown
2004-01-13 10:25:39 UTC
Permalink
Oh dear, sorry it's not *pure* erlang :-)

If the great maintainers add the following line to erl_parse.yrl

-----
expr_100 -> expr_150 '!' '!' expr_100: {call, line('$1'),
{remote, line('$1'),
{atom, line('$1'),sysd},
{atom, line('$1'),rpc}},
['$1', '$4']}.
-----

then it would be standard Erlang :-)

Users would be free to define their own sysd:rpc

((possibly even better is to exapand this into ?MODULE:rpc/2))

The change is purely *local* - if you "make" everything a new versions of
erl_parse.erl{.beam} are put into the /widgets subdirectory.

Pid !! X is just expanded into

sysd:rpc(Pid, X).

This make the code (IMHO) very pretty

The code to swap the values in two entries, is thus ...

Entry1 = Win !! mkEntry(....)
Entry2 = Win !! mkEntry(...)
Button = Win !! mkButton(....)
...

Swap = fun(_) ->
Str1 = Entry1 !! read,
Str2 = Entry2 !! read,
Entry1 ! {set, Str1},
Entry2 ! {set, Str2}
end,

Button ! {onClick, Swap}

...

To my mind this code is very clear and beautiful.

We could even see at a glance that

Entry !! read

is a possible error (ie it should be)

Var = Entry !! read

ie why do an rpc and NOT store the value - if you *wanted* to
read the value but not get a return value you could write

Entry ! read

Instead ....

Converting this to rpc(Entry, read) etc is a lot uglier.

<<aside>>

It's a pity I had to change the parser to do this.

I can't do this with -parse_transform(...) because parse transform
only works with correctly parsed forms and !! is not a correct form.

What one needs is

-token_transform(Mod).

Which transforms the input token stream prior to parsing.

/Joe
Post by unknown
thought i try ex11, but then i saw this;
"!! is an infix RPC operator. This needs a ONE LINE change to
erl_parse.yrl which makes a new version of erl_parse.erl"
so only people that willing/able to rebuild erl_parse can try ex11. i
for one am not (willing, that is).
but maybe a sed script or something can convert the code to erlang?
mats
unknown
2004-01-13 10:39:12 UTC
Permalink
As I understand things authentication works like this.

When you run an X app it reads the (local) .Xauthority file
and chooses the cookie of one of the entries in this file to
start a session with the server.

This is reasonably secure since a remote program cannot read the (local)
Xauthority file.

To allow remote hosts to run server sessions you can do one of two things:

1) do xhosts+ on the servfer machine (dangerous)
2) get the entry in the server Xauthority file into
the Xauthority file on the client. You do an "xauth extract"
command on the server to get the cookie - send it to the client and do
an "xauth add" command on the client.

2) Is the preferred method - 1) is unsafe since ANYBODY can connect
to your X server and do *anything* (like log all keystrokes)

So how does a local client figure out which Xauthority entry to use?

My code tries the following

1) try "localhost"
2) if that fails find the local host name
and look that up
3) give up

ie

host2cookie("localhost", Adata) ->
case host2cookie1("localhost", Adata) of
T = {true, Cookie} ->
T;
false ->
case inet:gethostname() of
{ok, Host} ->
case host2cookie1(Host, Adata) of
T = {true, Cookie} ->
T;
false ->
get_screen_zero(Adata)
end;
_ ->
get_screen_zero(Adata)
end
end;

What next do I try 127.0.0.0 then 127.0.0.2 etc .....

Any ideas

/Joe
Post by unknown
Hi Joe,
In my case with SuSE 8.2 the .Xauthority list simply doesn't contain localhost. There's 127.0.0.2, and the actual hostname too, but not localhost. I'm not sure how or why it's become like this. Using xhost or xauth as a remedy does work.
It's no fault of ex11, although the demo does fail silently, there's no supervisor to catch the exit value of sw_driver:wConnect/2.
Pete.
On Mon, 12 Jan 2004 14:45:19 +0100 (CET)
Post by unknown
This should not be necessary - I'd really like to know those cases
where the start procedure fails.
If authentication fails it is because
ex11_lib_driver:get_cookie
Has not been able to figure out what cookie to use
If authentication fails then give the commands
xauth
list
To see what cookies you have, then stare at the code in ex11_lib_driver
and ex11_lib_xauth to figure out what when wrong.
/Joe
xhost +localhost
erl -pa ./lib -pa ./widget.
Pete.
P.s. thanks Joe :-)
On Mon, 12 Jan 2004 13:39:38 +0100
Post by unknown
Excellent!!
I've tested it and it works now, even for me :-)
I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.
best regards,
Vlad
unknown
2004-01-13 13:15:07 UTC
Permalink
Post by unknown
As I understand things authentication works like this.
When you run an X app it reads the (local) .Xauthority file
and chooses the cookie of one of the entries in this file to
start a session with the server.
This is reasonably secure since a remote program cannot read the (local)
Xauthority file.
Security entirely depends on the authorization protocol in use. Some
send the cookies as plaintext.
Post by unknown
So how does a local client figure out which Xauthority entry to use?
My code tries the following
1) try "localhost"
2) if that fails find the local host name
and look that up
3) give up
Wouldn't it be better to look up the X server name? I think that's how
authorization is supposed to work: the client specifies on what machine
the display should go, the server checks whether the client has proper
credentials.
(Part of the confusion may stem from the fact that the same records are
used by client and server.)

Typical usage:

User logs on to an X machine.
User starts a background task on a remote machine.
Background task is supposed to display a progress bar on user's terminal.

-> Background task is told the host name of user's machine, to use as an
X server for the display.

In an installation running a fixed set of software, the assignment of X
Servers to background processes may be part of a configuration. IOW the
background processes would get their machine names from a file or database.

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-13 20:55:26 UTC
Permalink
AFAIK, X examines the DISPLAY environment variable, and uses
that to lookup the cookie. It seems that the routine is something
like:

1) Try getenv("DISPLAY") in cookies. (Handle "serv:0".)
2) Try "localhost:0" + getenv("DISPLAY") in cookies.
3) Try gethostname() + getenv("DISPLAY") in cookies.
4) Try "localhost:0" in cookies.
5) Try gethostname() + ":0" in cookies.
6) Maybe try "127.0.0.1:0" in cookies (though this is not normal).

The DISPLAY environment variable should be set for any X application
to work properly, and from what I have seen X servers typically set it
so the above cases would yeild a proper cookie from the .Xauthority
file.

Today's shells make it easy enough to change the DISPLAY environment
variable before running an application, so I don't see any reason why
this would need to be available as an Erlang command line option. But
login systems like gdm, xdm, etc. would set DISPLAY anyway.

But I think you know all of this already. :-)

X also loves to use unix sockets, especially for local connections when
the administrator or user does not want to expose the X server to
the network. In this case, its possible to configure the X server so
TCP is not available for remote communication, and ex11 won't work.
Erlang needs gen_unix. :)

If unix sockets are being used, the address is "hostname/unix:n" in
the .Xauthority file, and the local server is very commonly named by
its actual hostname, and not the string "localhost".
Post by unknown
As I understand things authentication works like this.
When you run an X app it reads the (local) .Xauthority file
and chooses the cookie of one of the entries in this file to
start a session with the server.
This is reasonably secure since a remote program cannot read the (local)
Xauthority file.
1) do xhosts+ on the servfer machine (dangerous)
2) get the entry in the server Xauthority file into
the Xauthority file on the client. You do an "xauth extract"
command on the server to get the cookie - send it to the client and do
an "xauth add" command on the client.
2) Is the preferred method - 1) is unsafe since ANYBODY can connect
to your X server and do *anything* (like log all keystrokes)
So how does a local client figure out which Xauthority entry to use?
My code tries the following
1) try "localhost"
2) if that fails find the local host name
and look that up
3) give up
ie
host2cookie("localhost", Adata) ->
case host2cookie1("localhost", Adata) of
T = {true, Cookie} ->
T;
false ->
case inet:gethostname() of
{ok, Host} ->
case host2cookie1(Host, Adata) of
T = {true, Cookie} ->
T;
false ->
get_screen_zero(Adata)
end;
_ ->
get_screen_zero(Adata)
end
end;
What next do I try 127.0.0.0 then 127.0.0.2 etc .....
Any ideas
/Joe
Post by unknown
Hi Joe,
In my case with SuSE 8.2 the .Xauthority list simply doesn't contain localhost. There's 127.0.0.2, and the actual hostname too, but not localhost. I'm not sure how or why it's become like this. Using xhost or xauth as a remedy does work.
It's no fault of ex11, although the demo does fail silently, there's no supervisor to catch the exit value of sw_driver:wConnect/2.
Pete.
On Mon, 12 Jan 2004 14:45:19 +0100 (CET)
Post by unknown
This should not be necessary - I'd really like to know those cases
where the start procedure fails.
If authentication fails it is because
ex11_lib_driver:get_cookie
Has not been able to figure out what cookie to use
If authentication fails then give the commands
xauth
list
To see what cookies you have, then stare at the code in ex11_lib_driver
and ex11_lib_xauth to figure out what when wrong.
/Joe
xhost +localhost
erl -pa ./lib -pa ./widget.
Pete.
P.s. thanks Joe :-)
On Mon, 12 Jan 2004 13:39:38 +0100
Post by unknown
Excellent!!
I've tested it and it works now, even for me :-)
I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.
best regards,
Vlad
--
Shawn.

Youth is a disease from which we all recover.
-- Dorothy Fuldheim
unknown
2004-01-13 10:45:46 UTC
Permalink
Post by unknown
Oh yes!
could I add some support for PDF like primitives to the wishlist, so
one could have an ErlGuten like interface.
See: http://www.cairographics.org/
This is the plan ...

The next goal is to get support for anti-alised fonts and alpha blending
+ to get the kind of TCL/TK usability.

IMHO the ex11 graphics stuff is *much* easier to program than TCL since
you can *directly* hit the X protocol level.

In TCL/TK you have to *change languages* to do real tricky stuff
(ie you can no longer program in TCL to do tricky things but have to change to
C)


If you want to do tricky things in ex11 you can *stay* in Erlang - since
All levels can direcly communicate with the X server socket.
Post by unknown
ex11 and x11, is "ex11" the one to choose?
Neither - the ex11 on http://www.sics.se/~joe/ex11 is derived from
the Jungerl but has now been significantly changed.

/Joe
Post by unknown
Regards Mikael.
Post by unknown
Post by unknown
Post by unknown
I will support the widget infrastructure and the low level X library.
It's quite soon to ask this, but I wonder: do your plans include adding
functionality for X extensions? From what I saw in the code, it's not so
easy to extend in a modular way, but I may be jumping to conclusions.
What I had in mind was the Render extension, and also support for Xft.
This goes a bit beyond "Erlang only talks to X server", but I guess you
would be also interested in high quality output, TrueType fonts,
antialiasing, transparency and so on ;-)
Yes indeed - but this is running before we can walk - text widgets
for variable width fonts etc is not entirely trivial.
I'm beginnging to wonder about extension this - now do I do alpha
blending for example??
/Joe
Post by unknown
regards,
Vlad
unknown
2004-01-16 20:11:34 UTC
Permalink
Post by unknown
IMHO the ex11 graphics stuff is *much* easier to program than TCL since
you can *directly* hit the X protocol level.
In TCL/TK you have to *change languages* to do real tricky stuff (ie you
can no longer program in TCL to do tricky things but have to change to C)
Agreed! So ex11 is sort of like Swing for Erlang, albeit running only on Unix(-ish)
platforms. Did I get that right?

-- O.L.
unknown
2004-01-14 09:50:56 UTC
Permalink
Thank you very much, I shall try this.

I'm really after a "bombproof" methods that works with badly
configured machines

/Joe
Post by unknown
AFAIK, X examines the DISPLAY environment variable, and uses
that to lookup the cookie. It seems that the routine is something
1) Try getenv("DISPLAY") in cookies. (Handle "serv:0".)
2) Try "localhost:0" + getenv("DISPLAY") in cookies.
3) Try gethostname() + getenv("DISPLAY") in cookies.
4) Try "localhost:0" in cookies.
5) Try gethostname() + ":0" in cookies.
6) Maybe try "127.0.0.1:0" in cookies (though this is not normal).
The DISPLAY environment variable should be set for any X application
to work properly, and from what I have seen X servers typically set it
so the above cases would yeild a proper cookie from the .Xauthority
file.
Today's shells make it easy enough to change the DISPLAY environment
variable before running an application, so I don't see any reason why
this would need to be available as an Erlang command line option. But
login systems like gdm, xdm, etc. would set DISPLAY anyway.
But I think you know all of this already. :-)
X also loves to use unix sockets, especially for local connections when
the administrator or user does not want to expose the X server to
the network. In this case, its possible to configure the X server so
TCP is not available for remote communication, and ex11 won't work.
Erlang needs gen_unix. :)
If unix sockets are being used, the address is "hostname/unix:n" in
the .Xauthority file, and the local server is very commonly named by
its actual hostname, and not the string "localhost".
Post by unknown
As I understand things authentication works like this.
When you run an X app it reads the (local) .Xauthority file
and chooses the cookie of one of the entries in this file to
start a session with the server.
This is reasonably secure since a remote program cannot read the (local)
Xauthority file.
1) do xhosts+ on the servfer machine (dangerous)
2) get the entry in the server Xauthority file into
the Xauthority file on the client. You do an "xauth extract"
command on the server to get the cookie - send it to the client and do
an "xauth add" command on the client.
2) Is the preferred method - 1) is unsafe since ANYBODY can connect
to your X server and do *anything* (like log all keystrokes)
So how does a local client figure out which Xauthority entry to use?
My code tries the following
1) try "localhost"
2) if that fails find the local host name
and look that up
3) give up
ie
host2cookie("localhost", Adata) ->
case host2cookie1("localhost", Adata) of
T = {true, Cookie} ->
T;
false ->
case inet:gethostname() of
{ok, Host} ->
case host2cookie1(Host, Adata) of
T = {true, Cookie} ->
T;
false ->
get_screen_zero(Adata)
end;
_ ->
get_screen_zero(Adata)
end
end;
What next do I try 127.0.0.0 then 127.0.0.2 etc .....
Any ideas
/Joe
Post by unknown
Hi Joe,
In my case with SuSE 8.2 the .Xauthority list simply doesn't contain localhost. There's 127.0.0.2, and the actual hostname too, but not localhost. I'm not sure how or why it's become like this. Using xhost or xauth as a remedy does work.
It's no fault of ex11, although the demo does fail silently, there's no supervisor to catch the exit value of sw_driver:wConnect/2.
Pete.
On Mon, 12 Jan 2004 14:45:19 +0100 (CET)
Post by unknown
This should not be necessary - I'd really like to know those cases
where the start procedure fails.
If authentication fails it is because
ex11_lib_driver:get_cookie
Has not been able to figure out what cookie to use
If authentication fails then give the commands
xauth
list
To see what cookies you have, then stare at the code in ex11_lib_driver
and ex11_lib_xauth to figure out what when wrong.
/Joe
xhost +localhost
erl -pa ./lib -pa ./widget.
Pete.
P.s. thanks Joe :-)
On Mon, 12 Jan 2004 13:39:38 +0100
Post by unknown
Excellent!!
I've tested it and it works now, even for me :-)
I'm glad you managed to implement the "widget = process" in what seems to be a
very nice way. I've been struggling with this issue for long, and couldn't find
enough inspiration and spare time at the same time.
best regards,
Vlad
unknown
2004-01-14 10:06:15 UTC
Permalink
Some more random thoughts:

I am now into "yet another" rewrite.

Here are some random design thoughts.

When an X event occurs you have to do something.
How should event processing be written:


-----------------
method 1)

The internal code in the display server did the following
To get an event to be processed I did the following:

Display ! {onEvent, Win, Type, Fun/1}

The server remembers the fun. then when event Type with argument Args
occurs in Win the server did

Fun(Args)

This is the good 'old "callback" style of programming

But what happens if Fun does not terminate or crashes - bad news

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

method 2)

Same as above but I do

spawn(fun() -> Fun() end)

when an event occurs

This *almost* worked but there are two problems

a) What happens if the Fun is something like

Fun(Event) ->
Pid !! op
end.

(answer possible deadlock - so funs must be carefully written)

b) How can I synchronise execution of several callbacks

annswer - you can't you must do it yourself

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

method 3)

Junk the callbacks.

I now send a

{onevent, Win, Type, Pid, Tag}

message to the server

This means:

If event Type occurs in Win then execute

Pid ! {Tag, Event}

This *cannot* fail for any reason

With this method a button widget looks like this

-module(swButton).

-export([make/8]).

-include("sw.hrl").

-import(ex11_lib, [ePolyText8/5, rpc/2, sleep/1,
xClearArea/1,
xDo/2, xFlush/1,
xVar/2]).

make(Parent, X, Y, Width, Ht, Border, Color, Str) ->
Wargs = #win{x=X, y=Y, border=Border,width=Width,ht=Ht,color=Color,
type=button, mask = ?EVENT_EXPOSURE bor
?EVENT_BUTTON_PRESS},
sw:startWidget(Parent, Wargs, fun(D,W) -> init1(D,W,Str) end).

init1(Display, Wargs, Str) ->
Win = Wargs#win.win,
Bin = ePolyText8(Win, xVar(Display, sysFontId), 10, 18, Str),


+------------------------------------------------------------+
| Display ! {onEvent, Win, expose, self(), expose1}, |
| Display ! {onEvent, Win, buttonPress, self(), click}, |
| |
+------------------------------------------------------------+

loop(Bin, Display, Wargs, fun(_) -> void end).

loop(B, Display, Wargs, Fun) ->
receive
{click, X} ->
flash(Display, Wargs),
Fun(X),
loop(B, Display, Wargs, Fun);
{expose1, _} ->
xDo(Display, B),
xFlush(Display),
loop(B, Display, Wargs, Fun);
{onClick, Fun1} ->
loop(B, Display, Wargs, Fun1);
{set, Str} ->
Win = Wargs#win.win,
xDo(Display, xClearArea(Win)),
Bin = ePolyText8(Win, xVar(Display, sysFontId), 10, 18, Str),
loop(Bin, Display, Wargs, Fun);
Any ->
io:format("Top loop got:~p~n", [Any]),
%% Now we call the generic operators
loop(B, Display, Wargs, Fun)
end.

flash(Display, Wargs) ->
S = self(),
Win=Wargs#win.win,
spawn(fun() ->
xDo(Display, xClearArea(Win)),
xFlush(Display),
sleep(200),
S ! {expose1, void}
end).


So far I can see no disadvanges with this.

I am re-writing all the widgets in this style.
Post by unknown
Hi,
I thought I'd share some random and unsorted thoughts I had about a widget
framework. Nothing revolutionary, but why let them go to waste? :-)
* widget users should see only generic events, not X ones. By that I mean there
should be a generic protocol (as is sketched in ex11_widget_button) for example
onClick, onDoubleClick, onEnter, onKeyPressed, onMouseMove, onMouseButtonDown,
etc. Maybe even onCreate, onDestroy?
* the event handlers should get the widget pid as an argument, so that they can
react according to the current state. For example draw_button() paints slightly
different if the button is pressed.
* the !! operator is cool, but it should be used with care. Maybe the
implementation of sysd:rpc should be refined to include timeouts and the
possibility to get the reply later (? la gen_server). The reason is that if
there are several widgets interacting (i.e. their states are interdependent)
it's very easy to get a deadlock.
For example radio buttons work as a unit.
* there is some GUI functionality that isn't local to a widget (even if it may
seem to be). For example tab order is known at parent window level, so the
parent window should get the opportunity to see keypresses before the child,
filtering tabs out (unless the child specifically wants to get them).
* there will be quite a bit of functionality common for many widgets. I think
there should be a way to reuse it without resorting to cut-and-paste techniques
;-) I won't mention inheritance (oops, I just did!) because there are other
ways - like for example providing plenty of hook points and functionality for
adding/removing custom hooks (? la Emacs).
For example implementing a tri-state button would require very little
changes to a regular button.
* It would be good if we could find an existing framework from which to map the
functionality. There's no need to make all mistakes from scratch. Most
frameworks are OO and make heavy use of inheritance, which is not a good
starting point, but see above.
That's it for now. Cheers!
/Vlad
unknown
2004-01-19 10:40:39 UTC
Permalink
Post by unknown
Post by unknown
IMHO the ex11 graphics stuff is *much* easier to program than TCL since
you can *directly* hit the X protocol level.
In TCL/TK you have to *change languages* to do real tricky stuff (ie you
can no longer program in TCL to do tricky things but have to change to C)
Agreed! So ex11 is sort of like Swing for Erlang, albeit running only on Unix(-ish)
platforms. Did I get that right?
Possibly, I've never used swing.

Since the first release of ex11 I have realized that ex11 is much
more powerful that TCL/TK or any other graphics package that I've seen.

The reason has to do with the concurrency modeling. In my ex11 GUI
widgets *every* object you can see on the screen is a process.

Buttons are processes, labels are processes, sliders are processes
etc. They all obey a generic protocol and all operate concurrently.
Thus adding (say) a clock (which needs some concurrency) to a button
is easy.

In the widget framework all S/W layers have accesses to the display
socket (via a library) so *any* process (including application layer
processes) can bypass all library code and talk *directly* with the
X-server itself - ie any S/W at any point can do any operation
directly against the X-sever and does not need to go through a library
layer.

The bottom (driver) layer is merely a thin interface to the
X-protocol. By directly sending X-protocol messages and by directly
delivering X-protocol messages to the widget controlling process we
eliminate all call back routines and can do anything that X can do.

It turns out that with 20 odd protocol messages one can do *most* of
the fun things that are possible with X. The entire design of
virtually all widget sets (motif, GTK etc) seems to be predicated by
the desire to simulate concurrency with callbacks. In ex11 I do
*exactly the opposite* and expose the concurrency to the applications.

All the top-level widgets speak directly to the X-server, and
callbacks are not necessary - this *greatly* simplifies the
programming model.

This style of programming is impossible without very light-weight
processes since it would be a nightmare to (say) fork of a new OS
process for every button or label or slider in a GUI ... so this style
of GUI programming is very rare - this is a shame - since it seems to
me that the "natural" way to model a GUI is with a large number of
parallel processes.

I'm often suprised when things stop working in traditional
GUI's. For example, when you drop down a menu what's going on
elsewhere in the GUI often stops - presumably because concurrently
handling the menus and all other activities is just too difficult to
program. In ex11 it's easy :-)


/Joe
Post by unknown
-- O.L.
unknown
2004-01-19 11:32:41 UTC
Permalink
From: "Joe Armstrong" <joe>
Post by unknown
In the widget framework all S/W layers have accesses to the display
socket (via a library) so *any* process (including application layer
processes) can bypass all library code and talk *directly* with the
X-server itself - ie any S/W at any point can do any operation
directly against the X-sever and does not need to go through a library
layer.
This is powerful, but it basically means that every user of ex11 would need to
have a good or very good understanding of the X11 workings and protocols. Which
may be quite a lot, if all one wants is to have a couple of buttons to press and
some text input.
Post by unknown
It turns out that with 20 odd protocol messages one can do *most* of
the fun things that are possible with X. The entire design of
virtually all widget sets (motif, GTK etc) seems to be predicated by
the desire to simulate concurrency with callbacks.
I think there is a nother reason too: hiding some of the complexity, and letting
programmers concentrate on the job at hand, not X11.
Post by unknown
In ex11 I do *exactly the opposite* and expose the concurrency to the
applications.

And it fits Erlang very well!
Post by unknown
All the top-level widgets speak directly to the X-server, and
callbacks are not necessary - this *greatly* simplifies the
programming model.
I'm not sure I understand you fully. We still have to tell the widget what to do
when it receives an "onClick" event, don't we? This can be done with a
traditional callback, or by letting it send a (possibly refined) message to an
application process - but I don't see any fundamental difference. It's still a
link to application-provided code.

Or maybe we are talking about different things?

regards,
Vlad
unknown
2004-01-19 18:06:53 UTC
Permalink
Post by unknown
From: "Joe Armstrong" <joe>
Post by unknown
All the top-level widgets speak directly to the X-server,
and callbacks are not necessary - this *greatly*
simplifies the programming model.
I'm not sure I understand you fully. We still have to tell the widget
what to do when it receives an "onClick" event, don't we? This can be
done with a traditional callback, or by letting it send a (possibly
refined) message to an application process - but I don't see any
fundamental difference. It's still a link to application-provided
code.
In principle, you're right. The problems lie in the details.

A user-defined message is easy to program, but you'll have to make sure
that its code doesn't collide with the message code of another
user-defined message. Which means you have a global dependency between
modules, and most GUI frameworks handle this aspect poorly, and for
those that do, the application program has to register any new message
handler so that it gets the message code it can use, which then must be
held in a (global, of course...) variable.
In short, it's a hassle. The main reason is that the user code that's
supposed to get/handle a message must be selected according to the
message id, and this dispatch is globally defined (by necessity: typical
GUI applications listen on exactly one message queue). If you're not
ultra-careful, you'll end up with all sorts of globals in your library
design.

Callbacks are difficult as well. You have to provide the environment for
the called-back function, so that it can access other elements of the
GUI elements (e.g. a button may react differently depending on the
validity of input fields' contents).
Easy for Erlang processes.
Difficult for a C function. Usually, you have to pass a pointer to the
GUI framework, to be passed back to the C function when it's called
back. With all the typecast hassles that this involves.
Easier for closures, particularly if the language gives them access to
mutable state. Well, such closures can do the Erlang process model in a
one-on-one fashion, so that's not a real surprise :-)

Been there, done that, got the T-short.
(I used to work on a GUI library in my last job. That was for MS
Windows, so details may vary a little, but the basic issues should be
the same for X. The main difference is that you have far less messages
to care about in X, but essentially you still have to carry the same
information between server and client.)

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-19 13:24:39 UTC
Permalink
Post by unknown
It turns out that with 20 odd protocol messages one can do *most* of
the fun things that are possible with X. The entire design of
virtually all widget sets (motif, GTK etc) seems to be predicated by
the desire to simulate concurrency with callbacks. In ex11 I do
*exactly the opposite* and expose the concurrency to the applications.
Is it really concurrency they are simulating?

I think what they're simulating is object-oriented programming. The
callbacks are there to poke in behaviour so that e.g. "Ok" and
"Cancel" buttons do different things.

I'm very curious to see how this experiment goes though :-). I tried
something similar by making Ermacs a "concurrent Emacs", where a
command could return control to the user but continue working in the
background on some "borrowed" (locked) buffer(s).

The Ermacs `erlang-interaction-mode' is an Erlang shell written as an
Ermacs mode. When you press return it spins off a new process that
borrows the shell buffer until the computation is finished and the
result is inserted. Meanwhile you can keep editing other buffers, but
will be blocked from mucking with that particular one.

However, in practice I think Emacs's event-loop is much better than
Ermacs's concurrency. I don't think Emacs editors have a great deal of
intrinsic concurrency, and introducing it just makes things more
complicated. I wonder if other UIs are similar.

(Also, having multiple activities in a UI makes the "abort what you're
doing now" (C-g) command more confusing. But I'm told some people use
low-level UIs without such basic features ;-)

BTW, Java initially had a multithreaded event-loop (i.e. events
dispatched by N threads at once), but this was a disaster. They
replaced this with an Emacs-like single-threaded event loop. If
another thread wants to do some GUI work then it passes a fun to the
GUI event-thread to run when it's ready (quite Erlangish).

I'm not sure what the lesson of the Java GUI toolkits is, but they
clearly crashed and retreated when they tried concurrency. Maybe ex11
could have more success.
Post by unknown
This style of programming is impossible without very light-weight
processes since it would be a nightmare to (say) fork of a new OS
process for every button or label or slider in a GUI ...
I have been pondering lately the weight of OS processes. In Linux 2.6
the scheduler context-switches 1000 times per second (up from 100 in
2.4) without appreciable overhead. Processes seem to be losing weight.

How about an Erlang clone that uses OS processes/IPC directly? I
wonder how far it could get. It certainly wouldn't scale as far, but
maybe it would scale enough for some applications -- my Erlang nodes
rarely have more than a few hundred processes I think. It could be
interesting to be able to use Unix debugging tools like
top/strace/lsof/... directly on a per-process basis.

I'm wondering this after hearing about the Qmail author's programming
style, which seems to strike a balance between Erlang and Unix style
(from what I'm told and have just read in the very good _Art of Unix
Programming_ book).

Cheers,
Luke
unknown
2004-01-19 14:07:01 UTC
Permalink
From: "Luke Gorrie" <luke>
Post by unknown
Post by unknown
It turns out that with 20 odd protocol messages one can do *most* of
the fun things that are possible with X. The entire design of
virtually all widget sets (motif, GTK etc) seems to be predicated by
the desire to simulate concurrency with callbacks. In ex11 I do
*exactly the opposite* and expose the concurrency to the applications.
Is it really concurrency they are simulating?
I think what they're simulating is object-oriented programming. The
callbacks are there to poke in behaviour so that e.g. "Ok" and
"Cancel" buttons do different things.
It is also a means to handle the complexity associated with GUIs. In a non-COPL,
this is a major issue. Once one is already in a concurrent environment, one's
mindstate is already handling several processes.

One possible show-stopper that I see is handling circular message paths, which
may lead to deadlocks.

I'd like to recommend some interesting reading
http://citeseer.nj.nec.com/fuchs95escaping.html, pleading for replacing the
event loop with continuation passing.
Post by unknown
I'm very curious to see how this experiment goes though :-).
Who isn't? :-)

/Vlad
unknown
2004-01-19 18:20:41 UTC
Permalink
Post by unknown
From: "Luke Gorrie" <luke>
One possible show-stopper that I see is handling circular message paths, which
may lead to deadlocks.
This is unavoidable, and independent of the library design.

Here's the canonical example:

You have two input fields A and B, and they are supposed to always sum
up to 100.
Nothing easier than that: handle any event that may change A's field
value, have that event processed, then send an event to B so set its
contents to (100 - A's value).
The problem is that an event that causes B to change its contents will,
in turn, send a message to A to update that value.

There are various ways to break such a loop.

One way would be to provide a high-level "field contents has changed"
message, and have the framework check whether the contents really
changed before sending the message. (Since this example is a relatively
common situation in real GUI dialogs, this would even make sense, though
that's not a general solution.)

Another possibility is to detect the loop. If the GUI library finds that
the same set of messages is being sent between a given set of controls,
it can let them crash.
MS Windows actually does that. I once had such a message recursion, and
found that the recursion would break at level 20 or so. (That was a
mighty surprise because this behaviour was undocumented... and it
doesn't work for all messages :-((( )

In all cases, it's absolutely essential that, for every piece of code,
there's a full documentation on what messages it may send, and under
what circumstances this is done. Otherwise, programmers have a hard time
determining whether their message code is inadvertently creating a loop.

In practice, this kind of documentation is the first thing that's
incorrect. So some general guidelines are in order:
1) Divide the messages into abstraction levels. A message of a higher
abstraction level may trigger only messages at lower abstraction levels.
2) If a message must trigger another message at the same or a higher
abstraction level, this fact and the precise set of trigger conditions
must be documented. Alternatively, one could make sure that the source
code for all such triggers is easily found, either by requiring
registration in a central place (downside: all the hassles of central
registration that one would avoid), or by requiring a special (easily
greppable) form of message send (downside: works only if source code is
available - true for ex11, but not true once companies start making
custom controls).

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-20 00:18:25 UTC
Permalink
Post by unknown
I'd like to recommend some interesting reading
http://citeseer.nj.nec.com/fuchs95escaping.html, pleading for replacing the
event loop with continuation passing.
another interesting read, from 1989 (cited in Fuch's paper too):

http://citeseer.nj.nec.com/pike89concurrent.html

which advocates a concurrency oriented model for window systems.

here's an excerpt from its Conclusions section:

Window systems are not inherently complex. They seem complex because we
traditionally write them, and their client applications, as single processes
controlled by an asynchronous, event-driven interface. We force them into the
mold of real-time software. They can be simplified greatly by writing them as
multiple processes, each with individual, synchronous communication channels on
which to receive data and control information.

-taj
unknown
2004-01-19 14:13:31 UTC
Permalink
Post by unknown
Post by unknown
It turns out that with 20 odd protocol messages one can do *most* of
the fun things that are possible with X. The entire design of
virtually all widget sets (motif, GTK etc) seems to be predicated by
the desire to simulate concurrency with callbacks. In ex11 I do
*exactly the opposite* and expose the concurrency to the applications.
Is it really concurrency they are simulating?
I think what they're simulating is object-oriented programming. The
callbacks are there to poke in behaviour so that e.g. "Ok" and
"Cancel" buttons do different things.
This may not be completely to the point, but however: In OO languages,
UIs are often modelled as one object per widget. This is imo a
natural thing to do. But although OO literature (at least that
introducing OO) often speaks of method invocation as message passing,
all of these `messages' are synchronous. One process per widget may
be similar to one object per widget, but advantageous if processes are
cheap enough.

A functional language with lightweight processes (like Haskell, oh
wrong list ;-) may more OO than OO languages, but that is a discussion
we do not want to start ;-) And actually, I am not at all
knowledgeable enough to make such a claim.

Greetings,

Carsten
--
Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin
http://carsten.codimi.de/
PGP/GPG key on the pgp.net key servers,
fingerprint on my home page.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20040119/60e277f8/attachment.bin>
unknown
2004-01-19 17:05:15 UTC
Permalink
While citations are flying around, does anyone have good references
about very-high-level user interface toolkits?

I have no crisp definition of this. I mean toolkits that have simple
and general programming and user interfaces. Emacs is an excellent
example, despite its obvious graphical limitations, because of these
wonderful properties:

Small number of objects to deal with:
Buffer (displays text)
Window (displays a buffer)
Frame (what appears on the screen. displays a window, or can be
split between several).

Extensible:
Extend by writing a "command". This is a named function that can
be called to manipulate the current buffers/windows/frames in some
arbitrary way. Examples: make the current window display the
buffer for a particular file; make all windows in the current
frame equally sized; check the spelling of the word at the cursor;
send the contents of the current buffer as an email.

Commands are invoked by name or assigned keys and menus. Modes are
collections of key assignments for related commands that can be
assigned to buffers.

Commands are universal:
Every user interface is composed to buffers, so any command that
works on buffers works on any interface. Search, copy,
check-spelling, save-contents-to-file,
pipe-contents-to-shell-command, etc work on absolutely anything,
whether the buffer contains a text-file, unix shell, erlang
debugger, whatever.

This is a great interface. It lets you do things your own way and it
pays back the effort you put into customising it many times over.

Using programs like Mozilla I am *constantly* bumping against little
niggles that I would immediately hack in any high-level interface. But
with "modern" GUIs I have to go into hackstincts-suppression-mode and
just take what I'm given. *Harrumph!* Is there some law of the
universe that I shouldn't be able to select an item from a list by
typing a unique substring of it, rather than pulling scrollbars around
while trying to mentally perform alphabetical-sort ? *Harrumph* I say!

So what better systems are out there? Links, citations, stories?
Anybody actually using one?

It seems the Oberon system has basically the same UI as Emacs.
Presentation-based [1] interfaces like CLIM [2] look really groovy.
I've played around a little with McCLIM [3] and I'm hoping that one
day I can jump ship onto it from Emacs. (Meanwhile I need to learn not
to wretch at the sight of CLOS code.)

There's also Squeak [4], which seems to be about the fanciest UI
currently available. I don't have a feel for how "high level" it is in
the sense sketched above though. The risk with OO seems to be having a
huge number of datatypes and a small number of ways to manipulate
them. The ultimate test of programmability might be to see if one can
hack it into working solely via the keyboard, killing two birds with
one stone :-)

Cheers,
Luke (looking for an Emacs replacement year after year after year..)

Refs:
1: Presentation Based User Interfaces
http://citeseer.nj.nec.com/iv84presentation.html
2: User Interface Management Systems: The CLIM Perspective
http://www.sts.tu-harburg.de/~r.f.moeller/uims-clim/clim-intro.html
3: McCLIM: A Free Implementation of CLIM
http://clim.mikemac.com/images/index.html
4: Squeak Smalltalk
http://www.squeak.org/
unknown
2004-01-19 18:30:45 UTC
Permalink
Post by unknown
I have no crisp definition of this. I mean toolkits that have simple
and general programming and user interfaces. Emacs is an excellent
example, despite its obvious graphical limitations, because of these
Buffer (displays text)
Window (displays a buffer)
Frame (what appears on the screen. displays a window, or can be
split between several).
I don't think that's true. What's a control in other languages just gets
mapped to the existing objects, which means that every object gets a
*huge* API.
Not that this in itself is a bad thing, it's just that you can't avoid
complexity just by hiding it under the hood of a few very general controls.
It's also an indicator that there's a wide spectrum, from frameworks
with many specialized minimal-API controls (MS Windows) over those with
few, fairly general ones (Tk, GTK+) to those with very few, extremely
powerful ones (Emacs). Personally, I'd stick with a middle ground: every
widget should have a clear purpose (buttons *are* different from text
input fields after all), but they should be as general as possible (a
button should be able to take up any kind of child control, not just a
bitmap or a text - if a designer places a text input field on a control,
he just gets what he deserves).

[I don't know enough about the Commands stuff that you describe to
comment on it.]
Post by unknown
Using programs like Mozilla I am *constantly* bumping against little
niggles that I would immediately hack in any high-level interface. But
with "modern" GUIs I have to go into hackstincts-suppression-mode and
just take what I'm given. *Harrumph!* Is there some law of the
universe that I shouldn't be able to select an item from a list by
typing a unique substring of it, rather than pulling scrollbars around
while trying to mentally perform alphabetical-sort ? *Harrumph* I say!
Mozilla is an excellent example of mediocre interface design :-)

However, I think here you're making a point for user-scriptable GUIs,
not a point for actual design decisions in ex11. (Not that user
scripting is a bad idea in itself.)
Post by unknown
There's also Squeak [4], which seems to be about the fanciest UI
currently available. I don't have a feel for how "high level" it is in
the sense sketched above though.
It offers many levels of abstraction, from the very down-to-earth stuff
to quite high-level widgets.
Post by unknown
The risk with OO seems to be having a
huge number of datatypes and a small number of ways to manipulate
them. The ultimate test of programmability might be to see if one can
hack it into working solely via the keyboard, killing two birds with
one stone :-)
In Squeak, the main problem would be to find the classes that are
responsible for a given abstraction level.
Also, you'd wrestle with software that uses the toolkit at the wrong
abstraction level (doing things at a lower-than-necessary level, so the
first thing to do would be to rewrite the software at the "right" level...)
The main reason for software working at a "too low" level would be that
this software was written before the higher abstraction levels were
conceived...

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-19 18:34:08 UTC
Permalink
Post by unknown
I don't think that's true. What's a control in other languages just
gets mapped to the existing objects, which means that every object
gets a *huge* API.
Terrible. Everything on my whole computer that deals with text has
this _awfully_ big API that includes everything I could possibly want
to do with text...

;-)
unknown
2004-01-19 19:25:17 UTC
Permalink
Post by unknown
Post by unknown
I don't think that's true. What's a control in other languages just
gets mapped to the existing objects, which means that every object
gets a *huge* API.
Terrible. Everything on my whole computer that deals with text has
this _awfully_ big API that includes everything I could possibly want
to do with text...
;-)
LOL!

However, you don't need this API for tasks like, selecting text from a
list or displaying a button. But you need other things.
And that's the point at which I usually make a break for a new widget.

Actually I think Emacs is just overdoing a step that's generally in the
right direction; my personal widget list goes like the following:
* Area (with border effects) (does layout of child widgets)
(is the only control that has layout-wise children)
(with some useful routines for adding scrollbars)
* Text input field (with a read-only mode)
* Pushbutton (includes checkboxes)
* Slider/scrollbar
* Noninteractive graphics elements (lines, rectangles, bitmaps)
* A toolkit for building new types of widgets,
which mainly consists of a framework for "draw" routines,
a framework for routine screen positions to widget components,
and a way to identify the borders of a control
(it's pretty sure that somebody wants to custom-make a big
red round "Emergency Stop" button - with this he can).

The list is already longer than that of Emacs, and I'm still not sure
that I have covered everything, but I don't see that anything can be
dropped; these widgets all behave in fundamentally different ways:

Area does child layouting; no other widget does this.
Text input fields do text layout and keyboard input.
Pushbuttons have a fixed size, a handful of states that are directly
tied to the state of mouse buttons or keyboard keys, and slightly
different appearance in each state.
Sliders and scrollbars have dragging capabilities.
Noninteractive graphic elements don't interact at all. Strictly
speaking, read-only text widgets fall into that category as well (but
there's much to be said for making every label amenable to selection
with the mouse and copying - I'm sick and tired of having to retype the
contents of error message boxes...)
... and the toolkit isn't really a widget :-)

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-20 07:59:58 UTC
Permalink
Hi Gurus,

GUI is one subject that seems to generate a lot of discussion here! :-)

I'd like to apply Occam's razor, and try to define the absolute minimum basic characteristics that widgets must have to enable more sophisiticated and specialised widgets to be created as an additional layer of s/w over the basic widget set.

The parent-child-sibling organisation of Xwindow maps neatly into processes. If ex11 can become a concurrent set of loosly coupled Xwindows mapped as processes, I reckon that designing new widgets will become easy enough not to require a huge library if canned widgets that we generally see in most windowing environments.

True, some commonly expected widgets need to be supplied, but I'd be disappointed if ex11 becomes tightly coupled to a set of widgets.

Pete
--
"The Tao of Programming
flows far away
and returns
on the wind of morning."
unknown
2004-01-20 09:54:30 UTC
Permalink
Post by unknown
I'd like to apply Occam's razor, and try to define the absolute
minimum basic characteristics that widgets must have to enable more
sophisiticated and specialised widgets to be created as an
additional layer of s/w over the basic widget set.
It is in vain to do with widgets that which can be done without ;-)

More seriously, the job of a user-interface is to interface with a
user. This doesn't have to involve widgets. Today most widget-based
GUIs are much less programmable and hacker-friendly than Emacs,
Acme/Wily, /bin/sh, etc. It isn't obvious that widgets or
widget-drawing primitives are the best axiom for a user interface.

How about hacking an Erlang UI that lets us do things in a new way?
Certainly sounds like a job for Joe to me :-)

-Luke
unknown
2004-01-20 10:19:51 UTC
Permalink
----- Original Message -----
From: "Luke Gorrie" <luke>
Post by unknown
How about hacking an Erlang UI that lets us do things in a new way?
Certainly sounds like a job for Joe to me :-)
I think it's a great idea. But for us mere mortals, that are somewhat stuck with
the currently available paradigms, it would be nice with a regular UI too, may
that be graphical, or text-based. At least for starters :-) Something all new
would have a very steep learning curve, and I become easily short-breathed...

I was thinking about directly interfacing Erlang to Emcas (as some previous
postings hinted at) and Luke's implementation of an Emacs rpc server got
slightly improved. It works, I can call ELisp functions from Erlang, and get the
answers back. But there should be a higher-level interface, to reduce the
traffic which slows down things a lot.

/Vlad
unknown
2004-01-19 21:38:54 UTC
Permalink
On Mon, 19 Jan 2004 18:05:15 +0100
Post by unknown
While citations are flying around, does anyone have good references
about very-high-level user interface toolkits?
I have no crisp definition of this. I mean toolkits that have simple
and general programming and user interfaces.
If I'm free to interpret this to mean "abstract enough for my liking,"
then no, I haven't, which is why I've been working on such a thing, off
and on, for the past 'N' years.

By "abstract enough for my liking", I mean, having a single description
of a user interface able to generate concrete interfaces that can be
used in a GUI, or in a CUI like slang or curses, or on a teletype, or in
a telephone call, and so forth. I also mean, having the description
general enough so that the programmer doesn't have to deal with
individual widgets, and their position, and such. (Obviously these two
things are related.)

Ideally, the programmer just deals with the data structure. The UI
engine figures out how to present that data structure to the user in
such a way so that the user can view and/or modify it. Ideally ideally,
the programming language itself should deal with the data structure so
that the programmer can just say something like 'input(MyCar)' and that
would take care of synchronously presenting a form with widgets apropos
to the user entering make, model, colour, and having radio buttons for
automatic vs manual transmission and so forth, whatever is defined in
the Car data type. Realistically, programming languages tend to have
either ridiculously impoverished (numbers, arrays and aggregates) or
horrifically stereotyped (objects) notions of data types, so I've
taken to describing the data type with it's own structure (which is
actually very nice in Erlang, as there are several abstractions, like
behaviours, which make this pleasant.)

Of course, anything this abstract doesn't provide a fine enough level
of detail for you to be able to build a decent word processor or web
browser or paint program with it. But most data entry tasks - which
includes many day-to-day things like program configuration dialog boxes
- all follow the same basic formulas, which I'm trying to distill and
make reusable.

I'll let you know when I'm happy with it. (Ha!)

Meanwhile, I have to say that Jef Raskin's book "The Humane Interface:
New Directions for Designing Interactive Systems" (Addison-Wesley, 2000)
was quite gripping (if occasionally a bit snotty) - it would be
interesting to know how an Emacs fan would take to some of his ideas.

-Chris
unknown
2004-01-19 14:17:48 UTC
Permalink
Joe Armstrong wrote:
...deleted
Post by unknown
The reason has to do with the concurrency modeling. In my ex11 GUI
widgets *every* object you can see on the screen is a process.
i remember reading about a process oriented gui. take a look at
http://www.cs.nyu.edu/phd_students/fuchs/gui.ps for ''Escaping the event
loop: an alternative control structure for GUIs''.


bengt
unknown
2004-01-19 14:45:18 UTC
Permalink
Another interesting research is Chiron or C2,
http://www.isr.uci.edu/architecture/c2.html

Quoted from the homepage:

"C2 is UCI's component- and message-based architectural style for constructing
flexible and extensible software systems. A C2 architecture is a hierarchical
network of concurrent components linked together by connectors (or message
routing devices) in accordance with a set of style rules. C2 communication rules
require that all communication between C2 components be achieved via message
passing.

Central to the architectural style is a principle of limited visibility, or
substrate independence: a component within a given architecture is only aware of
services provided by components "above" it in the hierarchy, and is completely
unaware of services provided by components "beneath" it. This makes component
substitutability tenable, thus promoting component reuse and system
extensibility. Click here for a more detailed discussion of C2 style rules.

To learn more about C2, we have a number of technical papers on C2."



/Vlad
unknown
2004-01-19 14:20:59 UTC
Permalink
Hi Joe,

I'm exploring the ex11 code, and I think I've strayed into peaty marsh along the way. Probably the Will 'o the Wisp of lib/hello_world.erl that get me a bit confused. :-)

I've only identified the following events: onClick, onMove and onReturn. Are there other events that may be used, or need to be implemented? (I've counted 33 in X11/X.h)

And I've successfully prodded the WinGravity property to enable rudimentary placement management on resizing the parent, but I'm not too sure how to fit this into your design. How would I specify window properties such as WinGravity?

Do you have a napkin-sketch design you can impart? I'd like to replace gs/tk in my application with something that doesn't eat quite so much resources!

Pete.
--
"The Tao of Programming
flows far away
and returns
on the wind of morning."
unknown
2004-01-19 18:43:49 UTC
Permalink
Post by unknown
And I've successfully prodded the WinGravity property to enable rudimentary placement management on resizing the parent,
A note to library designers: X gravity sucks.
It is far too limited to be useful in good designs.
The minimum resize model would be something along the lines of Tk: it
strikes a pretty useful balance between generality and ease of
specification.
For something entirely different, one could do it in a constraint-based
fashion: allow programmers to specify constraints, and plop in a
constraint solver (there are several open-source ones available, I can
dig one up if there's interest).

The downside with the Tk approach is that it uses the control hierarchy
to express visual constraints. These often go with the logical
hierarchy, but not always - and things become pretty ugly if you have to
work against it.

In other words: if you have a control hierarchy, you can use it only for
*one* aspect: EITHER layout, OR to determine control order (there's
often a natural order in which the end user will visit fields, and it's
often nice to support this by automatically placing the keyboard focus
to the next field at appropriate triggers), OR to inherit default
property settings (such as background color or visibility).
All GUI toolkits that I have seen which tried to hook more than one
aspect into control hierarchy made life quite miserable for the
application programmer.

That's why I vastly prefer the constraint-based approach - but I'm well
aware that this is a lot of code to write. At this stage of development,
I'd use a simple hand-crafted constraint engine.

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-19 14:09:11 UTC
Permalink
Post by unknown
Possibly, I've never used swing.
The reason I said it's like Swing is that in Swing, too, everything is done in Java (save for
the lowest-level operations, such as creating the window and allocating space for it on the
screen), so you don't have this chasm to cross whenever you want to modify a widget: you
just extend and override. This is in contrast to the Tk (or, in Java, the SWT) approach in
which every widget maps to a native one and you must drop down to C if you want to
change anything.

Re. concurrency, I am also very curious to see if it will work. As Luke pointed out, Swing
was indeed made single-threaded after disastrous experiences with concurrent updates.
I think the problem was that with programs whose execution is under your control you can
reason about race conditions, deadlocks etc but GUIs, which are driven by unpredictable
user input, are harder to reason about and to secure. Furthermore in practice I have found
the trick of "injecting" a task into the AWT event queue (using SwingUtilities.invokeLater)
is perfectly sufficient in practice. Full concurrency is certainly an interesting experiment
but is it _needed_?

-- O.L.
unknown
2004-01-19 19:42:09 UTC
Permalink
Post by unknown
Full concurrency is certainly an interesting experiment
but is it _needed_?
I don't have a definitive answer to this one, but imagine a real-time
data acquisition application: it will generate a separate stream of
events that must be integrated into the GUI display.
I'm not entirely sure, but I think keeping things fully concurrent is a
bonus for that kind of application.

I suspect that this independent event source thing is the key point.
If you have such event sources, it's likely that only a very limited set
of widgets is interested in them (in the case of data acquisition, the
events may go to a scrolling event log and/or a status display, there's
usually no reason why window frames or text input fields should be
bothered with them).
If you have full concurrency, you can feed these messages directly to
the interested controls. It's actually easy to set up a process that can
accept both GUI messages and data acquisition messages, and Do the Right
Thing with each kind of message.
If you don't have full concurrency, you must feed the independent
messages into the message dispatcher. This means defining a special kind
of message, *and* making sure that the message ultimately is dispatched
to exactly those controls that can make sense of it. That's a horrible
hassle. (Been there, done that. It's really not a pretty sight, and -
worst of all - it's something from the application domain, but to
program it, you need intricate knowledge of the GUI library because you
have to tamper with one of its central mechanisms, namely message dispatch.)

Here's the grain of salt: I don't know the ins and outs of the decision
to drop concurrency in Swing.
One of the things that I suspect is that the Java model of concurrency
is quite heavyweight, which means developers are constantly trying to
invent mechanisms to circumvent it. Which, of course, means that they
are going to introduce bugs in that mechanism, which can easily lead to
the described behaviour.
My other guess is that redrawing wasn't very well-designed in AWT
(witness the constant "things don't redraw properly" posts by newbies on
the awt newsgroups), and it may be that Swing inherited these problems.
(I find it quite strange that redrawing is a difficult task in AWT.
Actually that's one of the few things that are easy in in Windows...
it's been ages since I have been bitten by a bug in this area, and only
if I was handcrafting my own custom controls.)

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-19 14:34:27 UTC
Permalink
Post by unknown
Hi Joe,
I'm exploring the ex11 code, and I think I've strayed into peaty marsh along the way. Probably the Will 'o the Wisp of lib/hello_world.erl that get me a bit confused. :-)
I've only identified the following events: onClick, onMove and onReturn. Are there other events that may be used, or need to be implemented? (I've counted 33 in X11/X.h)
These are not the X-events but pseudo events that I generate
internally.

I wouldn't stare too hard at this code yet - my next release will be
rather different internally.

I have completed revised how widgets are written - the code to implement
a widget is somewhat longer but (I hope) much clearer.

I'm adding a proper failure model - and I will document how to write a
widget.

You'll have to wait a bit for this (a few days I hope) ...



/Joe
Post by unknown
And I've successfully prodded the WinGravity property to enable rudimentary placement management on resizing the parent, but I'm not too sure how to fit this into your design. How would I specify window properties such as WinGravity?
Do you have a napkin-sketch design you can impart? I'd like to replace gs/tk in my application with something that doesn't eat quite so much resources!
Pete.
unknown
2004-01-20 08:58:02 UTC
Permalink
Before we plunge ahead defining minimum specs etc, I'd like to suggest that
there need to be two "categories" of GUI tool considered here:

1) the production of application suites, where we are looking for consistent
behaviour across several applications where the emphasis is the application
functionality
(like appmon, pman, tv etc, which currentlyuse gs for this)

2) the production of special purpose, or speculative, UI's where the emphasis is
probably on the UI itself

I purport that for category #1 we need a standardised widget scheme that is
accessible with a "high level" of abstraction and for category #2 we need "bare
metal" micro access to the internals of whatever display technology we are using
(which may not necessarily be X.11, in some future world?).

Can we split the discussion into these two directions perhaps?

I'm not sure, at the moment, whether ex11 would like to address both categories,
or just #2 .... Erlang obviously gets used for both.

N.
unknown
2004-01-20 09:50:09 UTC
Permalink
From: <Nigel.Head>
Post by unknown
Before we plunge ahead defining minimum specs etc, I'd like to suggest that
1) the production of application suites, where we are looking for consistent
behaviour across several applications where the emphasis is the application
functionality
(like appmon, pman, tv etc, which currentlyuse gs for this)
2) the production of special purpose, or speculative, UI's where the emphasis is
probably on the UI itself
Defining the standard widget set for #1 is (should be) the same thing as
building a non-standard one. The point is to design the core framework so that
this is easily done.

/Vlad
unknown
0000-01-25 15:50:33 UTC
Permalink
Post by unknown
Post by unknown
I'd like to recommend some interesting reading
http://citeseer.nj.nec.com/fuchs95escaping.html, pleading for replacing the
event loop with continuation passing.
http://citeseer.nj.nec.com/pike89concurrent.html
which advocates a concurrency oriented model for window systems.
Rob Pike also wrote acme, which in my eyes qualifies as a
"very-high-level user interface toolkit" (Luke Gorrie). Its
programmable interface consists of a set of files and directories that
a "programmer" can query and/or write to. You can find a paper on an
earlier version of acme (the current one uses a bit of colour and has
a few new features) at
http://inferno.bell-labs.com/sys/doc/acme/acme.html
(for some reason I can't get the pictures to show in that, so here's
the pdf link,
http://inferno.bell-labs.com/sys/doc/acme/acme.pdf).

There is also a clone for Unix called wily
(http://www.cs.yorku.ca/~oz/wily/), but its programmatic model is
completely different and uses sockets.

Robby
unknown
2004-01-20 10:47:46 UTC
Permalink
Post by unknown
http://inferno.bell-labs.com/sys/doc/acme/acme.pdf
That paper says it all. Brilliant!
Post by unknown
There is also a clone for Unix called wily
(http://www.cs.yorku.ca/~oz/wily/), but its programmatic model is
completely different and uses sockets.
Make sure you have this up and running when you read it.
unknown
2004-01-27 00:59:06 UTC
Permalink
Post by unknown
Post by unknown
http://inferno.bell-labs.com/sys/doc/acme/acme.pdf
That paper says it all. Brilliant!
Post by unknown
There is also a clone for Unix called wily
(http://www.cs.yorku.ca/~oz/wily/), but its programmatic model is
completely different and uses sockets.
Make sure you have this up and running when you read it.
btw, for anyone that's interested, the "real deal" acme is becoming
available (courtesy of Russ Cox) on some flavors of Unix and Mac OS X

http://pdos.lcs.mit.edu/~rsc/software/plan9/

-taj
unknown
2004-01-27 11:07:42 UTC
Permalink
Post by unknown
Post by unknown
Make sure you have this up and running when you read it.
btw, for anyone that's interested, the "real deal" acme is becoming
available (courtesy of Russ Cox) on some flavors of Unix and Mac OS X
http://pdos.lcs.mit.edu/~rsc/software/plan9/
It turns out the whole Plan9 operating system can be downloaded as a
preinstalled VMware disk image. Takes no time to get it up and running
and it's only 80MB.

That's on the main Plan9 site.

-Luke
unknown
2004-01-28 01:00:23 UTC
Permalink
i forgot to mention that www.vitanuova.com/inferno also includes
an acme port, so that makes it 3 ways to run acme - plan9 (native
or vmware), inferno and rsc's unix port.

anyways, to bring this back on topic for the erlang list :)

Joe's recent advocacy of bang bang 'everything is a process' is
sort of reminiscent of plan9 and inferno's advocacy of 'present
all resources as files in a hierarchical name space' [*]

one fundamental difference seems to be that in bang bang, message
passing and distribution is explicit, whereas in the plan9 approach
the interface is fixed (standard open/close/read/write etc. file
ops) and the 9P message glue lives transparently underneath.

vitanuova has recently begun to exploit the 9P approach in the grid
arena (check their website). it would be interesting to see what
an erlang based grid architecture would look like.

-taj


[*] Rob Pike and Dennis Ritchie wrote a nice paper on this in the
bell labs technical journal a few years ago - see
www.vitanuova.com/inferno/papers/styx.html (a pdf of the bltj
original is at pobox.com/~taj.khattra/paper09.pdf )
unknown
2004-01-28 06:32:23 UTC
Permalink
Post by unknown
i forgot to mention that www.vitanuova.com/inferno also includes
an acme port, so that makes it 3 ways to run acme - plan9 (native
or vmware), inferno and rsc's unix port.
i would like to take the opportunity to remind the list readers that it
was inferno i used when finding the (only?) other system that does as
well as erlang on the experiment presented in ''Concurrency Oriented
programming in Erlang'' (http://www.sics.se/~joe).


bengt

unknown
2004-01-20 12:19:45 UTC
Permalink
erlang wrote:
...deleted
Post by unknown
Rob Pike also wrote acme, which in my eyes qualifies as a
"very-high-level user interface toolkit" (Luke Gorrie). Its
...deleted
Post by unknown
There is also a clone for Unix called wily
(http://www.cs.yorku.ca/~oz/wily/), but its programmatic model is
completely different and uses sockets.
the user interface part of wily is very close to acme. most differences
i can remember are a few niceties in wily, like the possibility to
execute a command directly by doing <RET> after having typed it.

due to the extream simplicity of the underlying concepts most of the
daily use of acme/wily is automatic, without thinking.
so there is a really confusing difference: b1b2 on text executes this
text as a command in both acme and wily. the command gets as its
arguments the text that was selected. but the current directory is the
directory of the ''command'' in acme, whereas wily uses the directory of
the arguments as current directory.


bengt
unknown
2004-01-20 12:24:55 UTC
Permalink
Post by unknown
There is also a clone for Unix called wily
(http://www.cs.yorku.ca/~oz/wily/), but its programmatic model is
completely different and uses sockets.
Here are some tips for Wily+Erlang that Bengt Kleberg (real live Wily
user) told me about off-list:

the standard table of cool things would be:
http://www.cs.yorku.ca/~oz/wily/idioms.html

it is really easy to select things (directories, files, text, output,
etc) and then run any program with the selection as input or
arguments.this is so easy to use that it is really hard to motivate
the effort needed to use the real wily interface
(http://www.cs.yorku.ca/~oz/wily/ look for ''Programmers Manuals
(writing programs which use Wily's message interface)'').

i have written some clear case scripts
(checkout/checkin/make/ln/extract label/warn if somebody else has this
file checkedout/etc) that makes it possible to not use x-clear-case.

i have a few erlang programs that pretty-prints, refactor (that is
your find-unbound-variables program) and checks for missing functions
in a beam directory (xref).

there are a some shell scripts i have written to find where functions
are defined or used. others locate hrl files based on name or contents
(useful when i have a record but can not remember the fields).


the down side to wily:
http://www.cs.yorku.ca/~oz/wily/intro.html
look for ''Drawbacks and problems''
unknown
2004-01-20 10:46:30 UTC
Permalink
Post by unknown
Defining the standard widget set for #1 is (should be) the same thing as
building a non-standard one. The point is to design the core framework so that
this is easily done.
I beg to differ! I believe the standard widget set for type #1 should offload
as much as possible of the intellectual and practical effort needed for
application implementation (and therefore probably flexibility) from the
application implementer whereas the #2 approach should expose all kinds of
customisation possibilities and hooks etc., at the cost of having a bigger
intellectual footprint.

I guess maybe the first case could be seen as a supplementary wrapper around the
second (in one possible implementation approach, at any rate) but I believe
there are fundamental architectural issues at stake here, for example:

+ the application design approach the widget set is designed for -- event driven
with hooks, concurrent etc

+ the nature of the interface made available -- grpahical, canvas related or
functionally oriented

+ the location (in process terms) of possible customisation logic (assuming for
the moment that we're headed for some form of client/server setup, if only to
avoid access conflicts to the lowest level hardware used for the GUI. This is
kind of like the difference between postscript printers and the windows GDI
thingy's maybe?

Perhaps I've misunderstood the topic of the your original mail though? To avoid
getting wires crossed and wasting bandwidth, I'll rest my case here unless
anyone really wants to continue in private mails.

N.
unknown
2004-01-20 13:14:28 UTC
Permalink
From: <Nigel.Head>
Post by unknown
Post by unknown
Defining the standard widget set for #1 is (should be) the same thing as
building a non-standard one.
I beg to differ!
You are right too, but I think we are talking about slightly different
matters.

I see #1 as "application development" and #2 as "widget development". After
a widget set has been developed, it can be used instead of the standard one
without any changes in the application (except maybe specifying the widget
set's name at initialization).
Post by unknown
I believe the standard widget set for type #1 should offload
as much as possible of the intellectual and practical effort needed for
application implementation (and therefore probably flexibility) from the
application implementer whereas the #2 approach should expose all kinds of
customisation possibilities and hooks etc., at the cost of having a bigger
intellectual footprint.
All widget sets can (but are not required to) have both a simple API
(allowing to do normal things without hassle, as you say) and a more
advanced one, even the standard one.

regards,
Vlad
unknown
2004-01-20 10:59:31 UTC
Permalink
Post by unknown
Hi Gurus,
GUI is one subject that seems to generate a lot of discussion here! :-)
I'd like to apply Occam's razor, and try to define the absolute minimum basic characteristics that widgets must have to enable more sophisiticated and specialised widgets to be created as an additional layer of s/w over the basic widget set.
The parent-child-sibling organisation of Xwindow maps neatly into processes. If ex11 can become a concurrent set of loosly coupled Xwindows mapped as processes, I reckon that designing new widgets will become easy enough not to require a huge library if canned widgets that we generally see in most windowing environments.
Yes - this is *exactly* how I'm building things. The only problem is
garbage collecting the windows and graphics context etc when you
kill the windows.

----

Yesterday I made a wonderful simplification. I make a simple draggable
blob widget.

Draggable = makeDraggable(Parent, X, Y, Width, Ht, Border, Color)

Creates a draggable blob.

Then you send it a fun

Draggable ! {onMove, fun(X,Y) -> ....}

So when the draggable is moved to X,Y it executes fun(X,Y)

Now a window is just a draggable border + a frame

+------------------------+
| border |
+------------------------+
| |
| Frame |
| |
+------------------------+

So Wrote

mkWindow(Parent, X, Y, Width, Ht) ->
Border = makeDraggable(Win, X, Y, Width, 10, ?blue),
Frame = makeRectangle(Win, X, Y+10, Width, Ht-10),
Border ! {onMove, fun(X,Y) ->
Frame ! {setXY,X,Y+10}
end},
Frame.

Which worked like a charm.

I wondered if the border might temporarily detach itself from the frame
but no - the border and the frame moved instantaneously.

My "draggable" can even be used as the basis of a scrollbar etc...

All this is nicely held together by the concurrency.

Now suppose you want to add a resizing "handle"

Like this:


+------------------------+
| border |
+------------------------+
| |
| Frame |
| +--|--+
+---------------------|--+ |
+-----+


mkWindow(Parent, X, Y, Width, Ht) ->
Border = makeDraggable(Win, X, Y, Width, 10, ?blue),
Frame = makeRectangle(Win, X, Y+10, Width, Ht-10),
Resizer = makeDraggable(Win, X+Width-5, Y+Ht-5, 10, 10, ?black),
Border ! {onMove, fun(X,Y) ->
Frame ! {setXY,X,Y+10},
Resizer ! {setXY, X+Width-5,Y+Ht+5}
end},
Resizer ! {onMove, fun(X, Y) ->
Border ! {setWidth, ...}
Frame ! {setWidth, ...}
...
end
Frame.


Which again is pretty simple :-)

But note how everything is built from a few powerful primitive widgets -
these widgets are just X-windows primitive windows + some control glue.
Post by unknown
True, some commonly expected widgets need to be supplied, but I'd be disappointed if ex11 becomes tightly coupled to a set of widgets.
No - a small set of primitive widgets (draggables, drawables, ...)
with powerful glue.
Post by unknown
Pete
/Joe
unknown
2004-01-20 11:08:25 UTC
Permalink
Post by unknown
Post by unknown
http://inferno.bell-labs.com/sys/doc/acme/acme.pdf
That paper says it all. Brilliant!
Yes I agree -- IMHO it would be relatively easy to build
a smalltalk/acme ... style front end to Erlang.

Once ex11 is complete stable (a few weeks away) then these things become
rather easy to build.

I'm not really sure how to proceed here.

Sources of inspiration are:

- smalltalk
- acme
- oberon
- humane interface (with a zoomable interface)

I'm intersted in Raskin's ideas on zoomable interfaces -
in his system files are never closed, they are always open, but a long way away
so they appear very small.

Another idea would be to build an "active power point" on the surface it
might look like powerpoint but it would really be a complete Erlang front
end.

I think we'll need quite a few volunteers :-)

(oh and then we could build our own window manager .....)

/Joe
Post by unknown
Post by unknown
There is also a clone for Unix called wily
(http://www.cs.yorku.ca/~oz/wily/), but its programmatic model is
completely different and uses sockets.
Make sure you have this up and running when you read it.
unknown
2004-01-20 11:23:32 UTC
Permalink
Post by unknown
Post by unknown
The parent-child-sibling organisation of Xwindow maps neatly into
processes. If ex11 can become a concurrent set of loosly coupled
Xwindows mapped as processes, I reckon that designing new widgets will
become easy enough not to require a huge library if canned widgets
that we generally see in most windowing environments.
Yes - this is *exactly* how I'm building things. The only problem is
garbage collecting the windows and graphics context etc when you
kill the windows.
I had similiar problem - garbage collecting destroyed gtk+ widgets,
when implementing yet another erlang-gtk+ binding with pipe driver
(http://home.uninet.ee/~taavi/files/erlang/xgs/).

Erlang Driver Toolkit raised same issue:
http://www.snookles.com/erlang/edtk/edtk-1.0/doc/FAQ.html#foreignptr

best regards,
taavi
unknown
2004-01-20 12:08:25 UTC
Permalink
Sounds like two distinct problems, please explain why they're the same (if they are).

I think Joe's problem is to maintain consistency between what is visible on screen, and what the Erlang data structures contain, i.e. the user kills a window (maybe forcefully) but ex11 isn't aware the window has gone. The windows don't unexpectedly vanish (I hope!)

Am I correct Joe? I would expect some form of event or notification in this context. My knowledge of X11 is not all that good, so I'm probably babbling.

The erlang-gtk thing sounds like a garbage collection issue, i.e. how to keep window handles within the reachable memory set. If the window reference is no longer reachable, it get garbage collected and probably destroyed.

Pete.


On Tue, 20 Jan 2004 13:23:32 +0200 (EET)
Post by unknown
Post by unknown
Post by unknown
The parent-child-sibling organisation of Xwindow maps neatly into
processes. If ex11 can become a concurrent set of loosly coupled
Xwindows mapped as processes, I reckon that designing new widgets will
become easy enough not to require a huge library if canned widgets
that we generally see in most windowing environments.
Yes - this is *exactly* how I'm building things. The only problem is
garbage collecting the windows and graphics context etc when you
kill the windows.
I had similiar problem - garbage collecting destroyed gtk+ widgets,
when implementing yet another erlang-gtk+ binding with pipe driver
(http://home.uninet.ee/~taavi/files/erlang/xgs/).
--
"The Tao of Programming
flows far away
and returns
on the wind of morning."
unknown
2004-01-20 12:58:39 UTC
Permalink
Post by unknown
Sounds like two distinct problems, please explain why they're the same (if they are).
I think Joe's problem is to maintain consistency between what is visible on screen, and what the Erlang data structures contain, i.e. the user kills a window (maybe forcefully) but ex11 isn't aware the window has gone. The windows don't unexpectedly vanish (I hope!)
Not quite.

Lets suppose an application program creates several top level windows
to do this it opens (say) port 6000 and zaps off commands to the X server.
If the user kills an individual window then X closes the socket
and all windows vanish.

To avoid this I make a new connection for each top level window.

The problem is more in the other direction. The user can only kill
top level windows - not interior windows.

I associate a controlling process with each widget - if there is an error
in that process then I need to remove the window in a clean way
so that it does not effect the other windows. I also need to tidy up after
a window has been deleted and remove any event handlers which were installed
to take care of internal events.

/Joe
Post by unknown
Am I correct Joe? I would expect some form of event or notification in this context. My knowledge of X11 is not all that good, so I'm probably babbling.
The erlang-gtk thing sounds like a garbage collection issue, i.e. how to keep window handles within the reachable memory set. If the window reference is no longer reachable, it get garbage collected and probably destroyed.
Pete.
On Tue, 20 Jan 2004 13:23:32 +0200 (EET)
Post by unknown
Post by unknown
Post by unknown
The parent-child-sibling organisation of Xwindow maps neatly into
processes. If ex11 can become a concurrent set of loosly coupled
Xwindows mapped as processes, I reckon that designing new widgets will
become easy enough not to require a huge library if canned widgets
that we generally see in most windowing environments.
Yes - this is *exactly* how I'm building things. The only problem is
garbage collecting the windows and graphics context etc when you
kill the windows.
I had similiar problem - garbage collecting destroyed gtk+ widgets,
when implementing yet another erlang-gtk+ binding with pipe driver
(http://home.uninet.ee/~taavi/files/erlang/xgs/).
unknown
2004-01-21 09:33:19 UTC
Permalink
Post by unknown
Sounds like two distinct problems, please explain why they're the same
(if they are).
I think Joe's problem is to maintain consistency between what is visible
on screen, and what the Erlang data structures contain, i.e. the user
kills a window (maybe forcefully) but ex11 isn't aware the window has
gone. The windows don't unexpectedly vanish (I hope!)
Am I correct Joe? I would expect some form of event or notification in
this context. My knowledge of X11 is not all that good, so I'm probably
babbling.
The erlang-gtk thing sounds like a garbage collection issue, i.e. how to
keep window handles within the reachable memory set. If the window
reference is no longer reachable, it get garbage collected and probably
destroyed.
I beleive, that this is similiar problem.

Joe greates some widget - erlang process. This erlang process fires
some commands to X serverver via sockets. X server allocates some
resources on behalf of Joe's widget.

When Joe's widget is not needed anymore, it can be explicitly
deleted. And widget process fires again some commands to X server
to deallocate resources on X server side.

It would be nice if this deallocation of external resources is transparent
- i.e. if widget process just terminates (by crashing, or just finishing
it's work without cleaning up resources), some time garbage collection
kicks in and garbage collector informs somehow, that external resources
can also be freed.

Not knowing anything about erlang VM internals, following may be useful
for tracking external resources tied to erlang variables.

Create new type with

make_external_ref(Pid, Message)

whict behaves like current make_ref/0. However, when this
reference is to be garbage collected following message is
sent

Pid ! Message

Then process can take whatever actions necessary to free
external resources associated with this reference.

best regards,
taavi
unknown
2004-01-21 10:21:33 UTC
Permalink
----- Original Message -----
From: "Taavi Talvik" <taavi>
Post by unknown
It would be nice if this deallocation of external resources is transparent
- i.e. if widget process just terminates (by crashing, or just finishing
it's work without cleaning up resources), some time garbage collection
kicks in and garbage collector informs somehow, that external resources
can also be freed.
Not knowing anything about erlang VM internals, following may be useful
for tracking external resources tied to erlang variables.
Create new type with
make_external_ref(Pid, Message)
whict behaves like current make_ref/0. However, when this
reference is to be garbage collected following message is
sent
Pid ! Message
Then process can take whatever actions necessary to free
external resources associated with this reference.
A problem with such a scheme is that one has no control over _when_ the
collection will take place. This may be important.

Another problem is that today in the normal heap management (one hep per
process) when the process dies, the heap is just discarded as a whole. If it
were to be scanned for dangling references, the lightness of the processes would
be affected negatively (I think).

I am not sure about this, but external references might also affect the
generational property of the memory manager.

Also, what if the associated Pid is dead?

In short, it would need quite a lot of changes to implement it at the language
level. I think a good analysis is needed, to show if it would be worth it or
not.

There are other solutions: using supervision trees can get you a long way, and
if it's not enough maybe a registry of external resources can be used (workers
register callbacks to be used when they die).

regards,
/Vlad
unknown
2004-01-21 10:30:15 UTC
Permalink
Hmm, I don't like the idea of using garbage collection to clean up X-Window resources; The widgets would stay on the screen, leaving unresponsive zombie windows on the screen, until a (non-deterministic?) GC occurs. That leaves a bad impression on the user (i.e. me!)

Lets leave GC alone, it was designed for a single purpose, and I hate piggy-back features stapled on because the problem wasn't analysed thouroughly enough to come up with the right answer!

To summerise, I can imagine two scenarii:-

A) Process controlling widget terminates --> delete corresponding X-Window widget.

B) User kills X-Window widget --> controlling process gets a `close' message (or dies).

Maybe there ought to be _two_ linked processes for each widget, or at least a supervising process that monitors the X connection and the corresponding Erlang process(es). If either disconnects/dies the other is likewise terminated.

Would this be a reasonable mechanism?

Pete.

On Wed, 21 Jan 2004 11:33:19 +0200 (EET)
Post by unknown
Post by unknown
Sounds like two distinct problems, please explain why they're the same (if they are).
I think Joe's problem is to maintain consistency between what is visible
on screen, and what the Erlang data structures contain, i.e. the user
kills a window (maybe forcefully) but ex11 isn't aware the window has
gone. The windows don't unexpectedly vanish (I hope!)
Am I correct Joe? I would expect some form of event or notification in
this context. My knowledge of X11 is not all that good, so I'm probably
babbling.
The erlang-gtk thing sounds like a garbage collection issue, i.e. how to
keep window handles within the reachable memory set. If the window
reference is no longer reachable, it get garbage collected and probably
destroyed.
I beleive, that this is similiar problem.
Joe greates some widget - erlang process. This erlang process fires
some commands to X serverver via sockets. X server allocates some
resources on behalf of Joe's widget.
When Joe's widget is not needed anymore, it can be explicitly
deleted. And widget process fires again some commands to X server
to deallocate resources on X server side.
It would be nice if this deallocation of external resources is transparent
- i.e. if widget process just terminates (by crashing, or just finishing
it's work without cleaning up resources), some time garbage collection
kicks in and garbage collector informs somehow, that external resources
can also be freed.
Not knowing anything about erlang VM internals, following may be useful
for tracking external resources tied to erlang variables.
Create new type with
make_external_ref(Pid, Message)
whict behaves like current make_ref/0. However, when this
reference is to be garbage collected following message is
sent
Pid ! Message
Then process can take whatever actions necessary to free
external resources associated with this reference.
best regards,
taavi
--
"The Tao of Programming
flows far away
and returns
on the wind of morning."
unknown
2004-01-21 11:43:54 UTC
Permalink
Post by unknown
It would be nice if this deallocation of external resources is transparent
- i.e. if widget process just terminates (by crashing, or just finishing
it's work without cleaning up resources), some time garbage collection
kicks in and garbage collector informs somehow, that external resources
can also be freed.
It's generally accepted that resource deallocation shouldn't be tied to
automatic garbage collection. Peter-Henry Mander already nicely summed
that up for X windows, but it's a more general principle: if any
resource has constraints on when it should be released, releasing it
during garbage collection is usually a bad idea (except as a stopgab
measure). This applies not just to windows but also to file handles (on
systems where they are a limited resource or where opening a file will
always lock it, such as Windows), hardware locks, Internet connections,
and what-have-you.

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-21 12:19:53 UTC
Permalink
Joachim Durchholz wrote:
...deleted
Post by unknown
It's generally accepted that resource deallocation shouldn't be tied to
automatic garbage collection. Peter-Henry Mander already nicely summed
that up for X windows, but it's a more general principle: if any
resource has constraints on when it should be released, releasing it
during garbage collection is usually a bad idea (except as a stopgab
measure). This applies not just to windows but also to file handles (on
interestingly enough there is no sys->close() function for file handles
in inferno programming with limbo. the manual says ''There is no
explicit ``close'' routine: when the last reference to the file
descriptor is released, the system closes the associated file.''


bengt
unknown
2004-01-21 12:51:12 UTC
Permalink
From: "Bengt Kleberg" <Bengt.Kleberg>
Post by unknown
interestingly enough there is no sys->close() function for file handles
in inferno programming with limbo. the manual says ''There is no
explicit ``close'' routine: when the last reference to the file
descriptor is released, the system closes the associated file.''
Limbo uses reference counting, so this is feasible.

/Vlad
unknown
2004-01-21 16:45:01 UTC
Permalink
Post by unknown
interestingly enough there is no sys->close() function for file
handles in inferno programming with limbo. the manual says ''There is
no explicit ``close'' routine: when the last reference to the file
descriptor is released, the system closes the associated file.''
I conclude that there's no reason to ever close a file on Limbo.
Probably because opening a file doesn't place a lock on it, and because
keeping a file open doesn't take up any resources.

Unfortunately, the first isn't true on Windows (which automatically
places a lock on a file as long as it's open), and the second isn't true
on neither Windows nor Unix. Since Erlang lives on top of the native
file systems, this makes the Limbo strategy nontransferrable.
(Unfortuantely, I should add.)

Regards,
Jo
--
Currently looking for a new job.
unknown
2004-01-21 18:43:00 UTC
Permalink
Since the discussion on this list some time ago I have not been
closing things. I did however find it necessary to close disk_log
files. Otherwise they ended up being repaired the next time I
opened them. My fix for this was to do the close in the
application's stop function.

-Vance

} interestingly enough there is no sys->close() function for file handles
} in inferno programming with limbo. the manual says ''There is no
} explicit ``close'' routine: when the last reference to the file
} descriptor is released, the system closes the associated file.''
}
}
} bengt
Continue reading on narkive:
Loading...