The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Поиск:  Каталог документации | Приложения, ПО

hush (hyper utility shell) FAQ

hush -- a hyper utility shell and C++ API for Tcl/Tk
Archive-name: unix-faq/shell/hush-faq
Submitted-by: Jacco van Ossenbruggen <jrvosse@cs.vu.nl>
Version: 1.0a6
Last-modified: Fri May 30 10:04:16 MET DST 1997
URL: http://www.cs.vu.nl/~hush/FAQ/

This article contains answers to Frequently Asked Questions about hush
(an object-oriented hyper utility shell -- see the answer to question
1.1 for a short overview).  Please send any comments or suggestions to
<hush@cs.vu.nl>.

Address information:

hush is developed by:
	Anton Eliens
	Email: <eliens@cs.vu.nl>

FAQ maintained by:
	Jacco van Ossenbruggen 
	Email: <jrvosse@cs.vu.nl>

Postal Address:
	Vrije Universiteit 
	Fac. of Mathematics and Computer Sciences 
	De Boelelaan 1081a 
	1081 HV Amsterdam
	The Netherlands 

This article is provided as is without any express or implied
warranties.  While every effort has been taken to ensure the accuracy
of the information contained in this article, the contributors assume
no responsibility for errors or omissions, or for damages resulting
from the use of the information contained herein.

The latest version of this FAQ is available from
<URL:http://www.cs.vu.nl/~hush/FAQ/>.  

This FAQ is divided in the following chapters:

 1. General information and availability
 2. Building hush
 3. hush extensions  
 4. Script programming in hush
 5. C++ Programming in hush
 6. Compiling and Running hush applications

To find the start of a particular chapter, search for the chapter
number followed by a dot and a space at the beginning of a line
(e.g. to find chapter 4 in vi, type /^4\. /).

Here's an overview of the questions per chapter:

 1. General information and availability
  1.1. Q. What is hush?
  1.2. Q. Why is it called hush?
  1.3. Q. How do I obtain a copy of the hush source?
  1.4. Q. How do I get documentation on hush?
  1.5. Q. Are there other ftp sites that mirror the hush distribution?
  1.6. Q. Is there a newsgroup or mailing list devoted to hush?
  1.7. Q. Is there a WWW page devoted to hush?
  1.8. Q. Is the hush documentation available on the WWW?
  1.9. Q. Is there a book on hush, or will there be one out soon?
  1.10. Q. Are there any published articles about hush that I can quote?
  1.11. Q. Has hush been used outside your own institute?

 2. Building hush
  2.1. Q. On what platforms has hush successfully been installed?
  2.2. Q. What compiler do I need to compile hush?
  2.3. Q. Which version of Tcl/Tk do I need?
  2.4. Q. What are resource.mk, install.mk, lib.mk etc?
  2.5. Q. Why do I get those Xpm related errors during linking?
  2.6. Q. Can I link BSD-ish software (like ucblib) with hush on my
       non-BSD platform?

 3. hush extensions  
  3.1. Q. Can I use hush in combination with any extensions to Tcl/Tk?
  3.2. Q. Are there any other extensions to hush?
  3.3. Q. What is the video-widget?
  3.4. Q. What is the web-widget?
  3.5. Q. What is hymne?
  3.6. Q. What is sim?

 4. Script programming in hush
  4.1. Q. What is Tcl/Tk?
  4.2. Q. Can I use interpreted programs (scripts) with hush?
  4.3. Q. How do make my scripts independent of the location of the
       interpreter?
  4.4. Q. How do I open a new window?
  4.5. Q. How do I convert screen coordinates to canvas coordinates?
  4.6. Q. Why do my "ButtonRelease" bindings not work?
  4.7. Q. Why does the Tcl "glob" function returns corrupted filenames?
  4.8. Q. How do I apply (GIF) images in my hush scripts?
  4.9. Q. How can I load images once and use them many times?
  4.10. Q. How do I apply transparent GIF images in my hush scripts?

 5. C++ Programming in hush
  5.1. Q. What does a typical hush main program look like?
  5.2. Q. Why do I need handlers?
  5.3. Q. What about garbage collection?
  5.4. Q. I created a new toplevel window. How do I confine all keyboard
       and mouse events to this new window?
  5.5. Q. How do I apply (GIF) images in C++ code?
  5.6. Q. How can I load images once and use them many times?
  5.7. Q. I have bound a handler to a button widget. Why is the
       handler::operator()() still called if the button is pressed,
       __even__ after disabling the button?
  5.8. Q. I have just inserted some text in my text widget. How do I
       make it scroll to the place the text is inserted so the new text
       becomes visable?
  5.9. Q. What is that dashed line at the top of my menus, and
       how do I make it disappear?
  5.10. Q. How do I convert X-keycodes to ASCII without using Xlib directly. 
  5.11. Q. How do I wait for (socket) IO without blocking the X main loop?

 6. Compiling and Running hush applications
  6.1. Q. Why does the compiler complain about declaring/creating a 
       button object?
  6.2. Q. Why does g++ complain about the use of widget::handler(...) ?

To find a particular question, search for the question number followed
by a dot, a space, and a Q at the beginning of a line (e.g. to find
question 4.2 in vi, type /^4\.2\. Q/).


1. General information and availability
=======================================

1.1. Q. What is hush?

A.  The standard interpreter associated with the hush library is a
shell, called hush, including a number of the available extensions of
Tcl/Tk and widgets developed by ourselves (such as a www and a video
widget). The hush library offers a C++ interface to the Tcl/Tk toolkit
and its extensions.  It allows the programmer to employ the
functionality of Tcl/Tk in a C++ program.  Moreover, a program created
with hush is itself an interpreter extending the hush interpreter (and
wish).

The hush library is explicitly intended to support the needs of both
novice and experienced window programmers. Its C++ class interface
should suffice for most applications, yet it allows for employing Tcl
script code when more is demanded. The contribution of hush with
respect to the Tcl/Tk toolkit is essentially that it provides a
type-secure solution for connecting Tcl and C++ code. As an additional
advantage, the hush library allows the programmer to employ
inheritance for the development of possibly compound widgets. In
particular, it provides the means to define composite widgets that
behave as the standard Tk widgets.

hush has been developed by Anton Eliens, with contributions from Dirk
Bolier, Matthijs van Doorn, Jacco van Ossenbruggen, 
Bastiaan Schonhage, Cees Visser and Martijn van Welie.

1.2. Q. Why is it called hush?

A. Hush stands for Hyper Utility SHell.  In the future, hush should
offer a full-fledged component-based, multi-paradigm object-oriented
hypermedia programming environment. hush!

1.3. Q. How do I obtain a copy of the hush source?

A. The latest complete hush source distribution is always available by
anonymous ftp, e.g.
<URL:ftp://ftp.cs.vu.nl/pub/hush/hush-2.0.tar.Z>. It is a
compressed tar file containing the complete C++/Tcl source,
documentation, example programs, and several useful pieces of freely
distributable software.  The distribution in this directory is still
experimental.  It may be freely used for education and research only.
A newer beta relaease is at 
<URL:ftp://ftp.cs.vu.nl/pub/hush/hush-3.0b1.4.tar.gz> which needs
Tcl/Tk 8.0a2.

Binaries for Solaris 2.5 are at 
<URL:ftp://ftp.cs.vu.nl/pub/eliens/hush/hush-solaris-3.0b1.3.tar.gz>.

1.4. Q. How do I get documentation on hush?

A. The documentation is part of the source distribution.  The latest
version of the manuals are available on the WWW at
<URL:http://www.cs.vu.nl/~hush/manuals>.

1.5. Q. Are there other ftp sites that mirror the hush distribution?

A. Not yet.

1.6. Q. Is there a newsgroup or mailing list devoted to hush?

A. Not yet.

1.7. Q. Is there a WWW page devoted to hush?

A. Yes, <URL:http://www.cs.vu.nl/~hush/> is the official hush home
page.

1.8. Q. Is the hush documentation available on the WWW?

A. Yes, see <URL:http://www.cs.vu.nl/~hush/> (hush' home page).  It
contains pointers to hypertext versions of the whole documentation set
(as hypertext, not just PostScript).  The latest version of the
manuals are available on the WWW at
<URL:http://www.cs.vu.nl/~hush/manuals/>.

1.9. Q. Is there a book on hush, or will there be one out soon?

A. Not really. However, chapter 12 of the following book
is largely devoted to hush:

	 Principles of Object-Oriented Software Development 
	 A. Eliens
	 Addison-Wesley (ISBN 0-201-62444-3) 
	 1995

1.10. Q. Are there any published articles about hush that I can quote?

A. So far the only refereed and published article that describes hush
in detail is:

	 Hush: A C++ API for Tcl/Tk
	 A. Eliens 
	 The X Resource, Nr 14 (pages 111-155) 
	 April 1995

The discrete event simulation library is described in:

	 Sim --- a C++ library for discrete event simulation
      	 D. Bolier and A. Eliens
      	 Vrije Universiteit, Amsterdam , Techreport IR-367,
	 November 1994
	 <URL:http://www.cs.vu.nl/~eliens/sim/>

The web-widget is described in:

	 Integrating Applications and the World Wide Web
	 M.A.B. van Doorn and A. Eliens
	 In: Computer Networks and ISDN Systems 
	 Proceedings of the Third International World-Wide Web Conference 
	 April 10-14 1995, Darmstadt, Germany (pages 1105-1110)
	 <URL:http://www.cs.vu.nl/~dejavu/papers/Darmstadt95/>

The hymne library is described in:
	 Music in Time-based Hypermedia
	 J.R. van Ossenbruggen and A. Eliens
	 In: ECHT'94 
	 The European Conference on Hypermedia Technology (pages 224-270) 
	 September 1994
	 <URL:http://www.cs.vu.nl/~jrvosse/Papers/echt94/html/>


1.11. Q. Has hush been used outside your own institute?

A. Yes. Several people outside our university use hush.  You can read
some comments of hush users at
<URL:http://www.cs.vu.nl/~eliens/hush/comments-hush.html>


2. Building hush
================

2.1. Q. On what platforms has hush successfully been installed?

A. hush runs on Solaris 2.X, SunOS 4.X and Linux.  On other platforms,
hush has not been tested yet.  We are interested if you run hush on
another platform.

It should be possible to port hush to any platform running Tcl/Tk.  At
the moment, an experimental port to Windows 3.11 / Windows 95 /
Windows-NT of hush is available.  See 
the latest beta release of hush 3.0 for more information.

2.2. Q. What compiler do I need to compile hush?

A. At the moment, hush compiles with GNU g++ (version > 2.5.8) and
Sun's C++ compiler CC (version > SC3.0.1 02 Mar 1995).  We are
interested if you have successfully built hush with other C++
compilers.

2.3. Q. Which version of Tcl/Tk do I need?

A. The standard distribution contains a copy of Tcl7.4 and Tk4.0.
Hush 3.0 will be based on Tcl/Tk 8.0.

2.4. Q. What are resource.mk, install.mk, lib.mk etc?

A. These files are included by the Makefiles.  We are trying to find a
way to be able to change the resources without updating all the
Makefiles in the source directory tree.  This may improve in the
future. Suggestions welcome.

The main problem is the huge amount of third party software used by
the hush package. While compiling hush (or a hush application), one
need the specify the directories where the various include files are
located, the directories of all the libraries, which libraries should
be linked etc, etc.  This is not trivial at all...

2.5. Q. Why do I get those Xpm related errors during linking?

A. This will not happen with the new versions of hush (>= 1.7) hush
1.5 used the pixmap extension to Tk.  So you have to link the Xpm
library to, otherwise you will get not defined messages of:

		_XpmCreateDataFromPixmap 
		_XpmWriteFileFromPixmap 
		_XpmCreatePixmapFromData 
		_XpmReadFileToPixmap 
		_XpmFreeAttributes 

Newer versions of hush use the build-in image support of Tk and the
Xpm library is no longer supported.  See question 4.7 and question 5.4

2.6. Q. Can I link BSD-ish software (like ucblib) with hush on my
non-BSD platform?

A. Yes. However, we have experienced some troubles. In particular, the
Tcl "glob" command returns corrupted filenames. Seems that the
implementation uses a function (fstat?) defined by both the C library
and the BSD library, and picks the wrong one (BSD). We solved the
problem by explicit linking of the C lib __before__ the BSD libs.

E.g. on Solaris we define:
		SYSTEMLIBS = -R/usr/openwin/lib -L/usr/openwin/lib \
				-lX11 -lm -lc -lucb

3. hush extensions  
===================

3.1. Q. Can I use hush in combination with any extensions to Tcl/Tk?

A. Yes. We use hush in combination with the following packages:
3ditems, TkSteal-3.3, blt-1.7, expect-4.5, graph-1.0, itcl-1.3,
minterp, photo-2.3, tcl-dp2.0 and tree-3.3.

3.2. Q. Are there any other extensions to hush?

A. Yes. You may use the video-widget, the web widget, the hymne
library and the sim library.

3.3. Q. What is the video-widget?

A. With the video widget, you can display video files in your hush
application's interface. At the moment, only (black and white) MPEG is
supported, but a new video widget will be out this summer.  The new
widget will support full color MPEG, QuickTime and many more other
formats as well.

3.4. Q. What is the web-widget?

A. The hush web-widget provides for a two-way integration of the World
Wide Web with your application. First, the widget behaves as a
graphical WWW browser. Secondly, it allows HTML-pages to contain
embedded Tcl-commands, enabling highly interactive and dynamic
WWW-pages. For instance, you may use an embedded video widget to have
in-line video player in your HTML pages.  See also
<URL:http://www.cs.vu.nl/~dejavu/papers/Darmstadt95/>.

Currently, a new SGML version of the web widget is being developed.
It is based on James Clark's SGML parser SP.

3.5. Q. What is hymne?

A. Hymne provides a flexible C++ class interface to Csound.  The hymne
class library offers a C++ API to Csound.  Csound is a Software Sound
Synthesis (SWSS) package.

SWSS involves the generation of digital audio samples.  Csound runs
real-time on a SPARC, so applications can use music without having to
use (large) pre-recorded samples.

One can synthesize music from Tcl scripts by using a hush interpreter
with the hymne extension.  See also
<URL:http://www.cs.vu.nl/~jrvosse/papers/echt94/html/>.

Currently, we are developing a MIDI-based sound C/S package for hush.

3.6. Q. What is sim?

A. Sim is a C++ library for discrete event simulation. The sim library
supports both an event and process-oriented approach to developing
simulations. Events as well as entities (which may be considered as
objects in the simulation combining several related events and having
an additional phase signifying episodes in its life-time) are provided
as abstract classes that must be refined by the application programmer
to define the actual events and entities participating in the
simulation. The sim library is integrated with the hush library, thus
offering powerful graphic and animation facilities. However, the sim
library may also be used independently, on both Unix and MS-DOS
platforms.

The notion of 'event' in the discrete event simulation library and the
window environment event are fully integrated in hush.

See also <URL:http://www.cs.vu.nl/~eliens/sim/sim.html>


4. Script programming in hush
===============================

4.1. Q. What is Tcl/Tk?

A. The hush kernel provides a flexible C++ interface to Tcl/Tk.  Tcl
is a cshell-like (interpreted) script language that may be embedded in
C or C++. Tk is a window and graphics toolkit based on X11, partly
implemented in Tcl and partly in C. Tk offers numerous widgets,
including a powerful canvas and text widget.  Moreover, the Tcl
scripting language allows the user to rapidly prototype rather complex
graphical user interfaces by writing Tcl scripts. These scripts may be
executed by using wish, the windowing shell interpreter that comes
with Tk. Despite being based on Tcl, the performance of Tk (and wish)
is comparable with (and in some respects even better than) C or C++
based toolkits. The Tcl/Tk toolkit has become very popular in a rather
short period of time.

For more information, see
<URL:http://www.x.co.uk/of_interest/tcl/Tcl.html> or check out the Tcl
FAQ at <URL:http://route.psg.com/tcl.html> or <URL:news:news.answers>.
See
<URL:ftp://ftp.slac.stanford.edu/software/TkMail/tkref-4.0.1.tar.gz>
for a Quick Reference Card package, or a PostScript version at
<URL:http://www.cs.vu.nl/~hush/documents/refguide.ps>.  Manpages are
also available from
<URL:http://www.elf.org/tcltk-man-html/contents.html>.

4.2. Q. Can I use interpreted programs (scripts) with hush?

A. Yes. Every hush application is a (extended) version of the Tcl/Tk
windowing shell (wish) by default. As a result, you can use such
applications as a interpreter for your Tcl/Tk scripts.  Additionally,
you can use the kit::source(filename) member to evaluate Tcl/Tk
scripts in your C++ program.  In these scripts, you can use plain
Tcl/Tk and all extra commands you defined in your hush application.

In the future, hush might support Python
(<URL:http://www.python.org/>) and Scheme scripts as well.

4.3. Q. How do make my scripts independent of the location of the
interpreter?

A. Use Unix' env(1) to call the first matching interpreter in your
PATH.  E.g:
		#!/bin/env hush
		puts "Hello world"

instead of:
		#!/some/local/and/often/changing/path/hush
		puts "Hello world"


4.4. Q. How do I open a new window?

A. Use the toplevel widget.

4.5. Q. How do I convert screen coordinates to canvas coordinates?

A. As long as your canvas does not have scrollbars, you will probably
have no problem. As soon as you have adjusted the view of the canvas
using x- or yview (usually via scrollbars), you will notice that the
canvas coordinates differ from screen coordinates as returned by
window events.

Use the canvasx and canvasy commands to solve the problem.  They map
from screen coordinates to canvas coordinates.  In a Tcl procedure
bound to a mouse event, you can use something like:

		 set posX [.c canvasx %x]
		 set posY [.c canvasy %y]
 
(thanks to Christopher Herringshaw <xxviper@umich.edu>)

The hush canvas widget class features automatic conversion from window
coordinates to canvas coordinates. As a consequence, drawing a point
on (10,20) on a canvas which has been scrolled over a vector
(100,200), results in drawing a point on (10+100, 20+200).
 
However, since some users prefer to do this calculation themselves
(using canvasx() and canvasy()), the latest hush version will have a
canvas widget which provides an extra member function to switch this
feature on and off.
 
  enum { window_coords, canvas_coords }; // window_coords is default
  void coordsystem(int);
  int coordsystem() const;
 
If you set coordsystem(canvas::window_coords), which is the default,
the canvas expects window coordinates, which will be transformed to
canvas coordinates automatically.
 
However, if you set coordsystem(canvas::canvas_coords), the canvas
widget expects canvas coordinates and will do no further calculations.
 
4.6. Q. Why do my "ButtonRelease" bindings not work?

A. This may be a bug in old Tcl/Tk versions.  Workaround: use explicit
button numbers.

See <URL:http://www.cs.vu.nl/~hush/FAQ/examples/buttonrelease> for a
Tcl example.

4.7. Q. Why does the Tcl "glob" function returns corrupted filenames?

A. You are probably using BSD libraries (like ucb) as well.  See
question 2.6.  Thanks to Sebastiaan A. Megens for reporting this bug.

4.8. Q. How do I apply (GIF) images in my hush scripts?

A. Use the standard Tk image script command. See man image(n).  See
<URL:http://www.cs.vu.nl/~hush/FAQ/examples/image-tcl> for a Tcl
example.

4.9. Q. How can I load images once and use them many times?

A. Use the standard Tk image script command. See man image(n).  See
<URL:http://www.cs.vu.nl/~hush/FAQ/examples/image2-tcl> for a Tcl
example.

4.10. Q. How do I apply transparent GIF images in my hush scripts?

A. You don't :-( 
hush does not support transparency because Tk doesn't
(yet).

But ... you can change the transparent color of a GIF by setting the
magic Tcl variable TRANSPARENT_GIF_COLOR.

E.g:
		set TRANSPARENT_GIF_COLOR [.w cget -background]

5. C++ Programming in hush
==========================

5.1. Q. What does a typical hush main program look like?

A. Typically, one defines a class, usually called "application",
derived from the session class.  One may override its "prelude" member
function to provide for user-defined initializations. For instance,
this is the place to initialize all extensions packages. The "main"
member function can be used to set up the interface.

Like most window toolkits, the main loop of the application is hidden
in the library code, which is doing all the window-event dispatching.
User-defined code is usually activated by the use of
call-back-functions, or in the case of hush: by installing handlers.

See <URL:http://www.cs.vu.nl/~hush/FAQ/examples/template.cc> 
for a template C++ main program.

5.2. Q. Why do I need handlers?

A. In general, a user defined function activated by the call-back
mechanism needs user-defined parameters. The type of those parameters
is not known by the dispatching code doing the call-back.  In other
toolkits, this data usually is a parameter of type void* and needs to
be casted by the application programmer to a pointer of the right
type.

The hush handler class solves this problem, and provides a type secure
way to bind C++ code to events.  By deriving a subclass from handler,
a application programmer may activate it's own code by overiding the
operator()() function.  Any data can be stored (locally) within the
data members of the object.  No type casts are needed.

5.3. Q. What about garbage collection?

A. See <URL:http://www.cs.vu.nl/~hush/tutorials/garbage/>.

5.4. Q. I created a new toplevel window. How do I confine all keyboard
and mouse events to this new window?

A.  You can confine window events to any (mapped) widget subtree by
using the widget::grab() member function. E.g:

		toplevel *t = new toplevel(".top");
		tk->update();		// make sure window is mapped
		t->grab();		// Local grab
		t->grab("-global");	// Global grab - dangerous!
		t->grab("release");	// Release grab

See the man-page of the Tcl/Tk grab command for more details
(<URL:http://www.cs.vu.nl/~hush/manuals/mann/grab.html>).

5.5. Q. How do I apply (GIF) images in C++ code?

A. Most widgets have an image() member. See
<URL:http://www.cs.vu.nl/~hush/FAQ/examples/image.cc>
for a C++ main program.

5.6. Q. How can I load images once and use them many times?
 
A. Most widgets have an image() member. See
<URL:http://www.cs.vu.nl/~hush/FAQ/examples/image2.cc>
for a C++ example.

5.7. Q. I have bound a handler to a button widget. Why is the
handler::operator()() still called if the button is pressed,
__even__ after disabling the button?

A. You probably bound the handler by using something like:

		abutton->bind("<ButtonPress>", ahandler, "some-argument");

which activates a general binding for widgets, and circumvents the
special binding for buttons. Leave out the "ButtonPress" argument to fix
this problem:

		abutton->bind(ahandler, "some-argument");

5.8. Q. I have just inserted some text in my text widget. How do I
make it scroll to the place the text is inserted so the new text
becomes visable?

A. Use the "see" command of the text widget in combination with the
index of the first character of the newly inserted text.  The
insertion cursor is called "insert", so you have to use the index
"insert linestart". See text(n) for details.  Since the hush class
interface to text does not provide a see() member (yet), use:

		text *t
		...
		t->eval("see {insert linestart}");
		tk->update();	// to be sure ...

5.9. Q. What is that dashed line at the top of my menus, and
how do I make it disappear?

A. The dashed line is a so-called "tear-off" entry, which
makes a tear-off copy of the menu if it is invoked.
You can prevent this by creating/configuring your menus with a
"-tearoff false" option.
    

5.10. Q. How do I convert X-keycodes to ASCII without using Xlib directly. 

A. See the Tk bind(n) manual and example at
<URL:http://www.cs.vu.nl/~hush/FAQ/examples/key.cc>


5.11. Q. How do I wait for (socket) IO without blocking the X main loop?

A. You can use the kit->bind(int fd, handler*, int mask=readable) to
bind a handler to a file descriptor. Its operator()() will be called by
the system if there arrives readable data on fd. You can use alternative
masks for other IO events.

6. Compiling and Running hush applications
=========================================== 

In general: The color management of earlier Tcl/Tk versions are be the
cause of many errors and core dumps.  Killing color-intensive
applications (such as Netscape!) may be worth the trouble ...

6.1. Q. Why does the compiler complain about declaring/creating a 
button object?

A. This only happens if the declaration/creation occurs within the
scope of a class derived from event.  The button(...) member of event
hides the button class.  Note that the session class used to be
derived from event, and the problem above often occured in a member of
a class derived from session in older versions of hush (< 2.0).

Solution: use global scoping (::), e.g. something like
	 ::button* b = new ::button(".b");

6.2. Q. Why does g++ complain about the use of widget::handler(...) ?

A. We think (?) this is a bug in the GNU compiler (at least version
2.7.0 and earlier).  Widget's member function "handler" hides the
constructor of its base class, called "handler" as well...

Solution: Use handler::bind(...) instead to work around this bug.
Note: In the newer versions of hush, widget::handler(...) is no longer
available.
-- 
Jacco van Ossenbruggen             Faculty of Mathematics and Computer Science
mailto:jrvosse@cs.vu.nl            Vrije Universiteit, de Boelelaan 1081a
http://www.cs.vu.nl/~jrvosse/      1081 HV Amsterdam (fax: +31 20 44 47653)



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру