diff --git a/tutorial/gtk_part1.wmml b/tutorial/gtk_part1.wmml
new file mode 100644
index 0000000000000000000000000000000000000000..4c0c8620035a6a4430f672d401357907d8e876da
--- /dev/null
+++ b/tutorial/gtk_part1.wmml
@@ -0,0 +1,316 @@
+<section title="The Pike GTK wrapper library" name=gtk>
+
+<section title="Introduction">
+
+The GTK module provides an object oriented wrapper library for the <a
+href="http://www.gtk.org/">GTK+ Widget library</a>
+
+<p>
+From the GTK web-site:
+
+<p>
+<i>
+GTK (GIMP Toolkit) is a library for creating graphical user
+interfaces. It is licensed using the LGPL license, so you can develop
+open software, free software, or even commercial non-free software
+using GTK without having to spend anything for licenses or royalties.
+
+<p>
+It's called the GIMP toolkit because it was originally written for
+developing the General Image Manipulation Program (GIMP), but GTK has
+now been used in a large number of software projects, including the
+GNU Network Object Model Environment (GNOME) project. GTK is built on
+top of GDK (GIMP Drawing Kit) which is basically a wrapper around the
+low-level functions for accessing the underlying windowing functions
+(Xlib in the case of the X windows system). The primary authors of GTK
+are:
+
+<ul>
+<li>Peter Mattis <a href=mailto:petm@xcf.berkeley.edu>petm@xcf.berkeley.edu</a>
+<li>Spencer Kimball <a href=mailto:spencer@xcf.berkeley.edu>spencer@xcf.berkeley.edu</a>
+<li>Josh MacDonald <a href="mailto:jmacd@xcf.berkeley.edu">jmacd@xcf.berkeley.edu</a>
+</ul>
+<p>
+</i>
+
+The Pike GTK module is written mainly by <a
+href=http://per.hedbor.org>Per Hedbor</a> <a
+href="mailto:per@idonex.se">per@idonex.se</a>
+
+
+<p>
+
+Pike GTK contains more than simple wrappers for all GTK functions,
+especially image handling capabilities has been added.
+
+<p>
+</section>
+
+<section title="Tutorial">
+<section title="Getting started with Pike GTK">
+
+First, you must have GTK 1.2 or newer installed when you compile pike,
+otherwise the GTK module will not be enabled.
+
+<p>
+If you are unsure whether or not the pike you are using has GTK, try
+running 'pike -e GTK.setup_gtk()' from a shell, if you do not get an
+error message, GTK is available.
+
+<p>
+
+The first program is a (very) short example program that creates a
+window, and then does nothing else.
+
+<example language=pike>
+#!/usr/local/bin/pike
+void main(int argc, array argv)
+{
+  argv = GTK.setup_gtk( argv );
+  GTK.Window( GTK.WindowToplevel )->show();
+  GTK.main();
+}
+</example>
+
+<p>
+
+All GTK programs must call GTK.setup_gtk() before any widgets are
+created (you will get an error if you don't do this).
+
+<p> 
+
+The array returned by GTK.setup_gtk() is the new argv array, all
+arguments handled by GTK has been removed from the list of arguments.
+
+<p>
+
+<tt>GTK.Window( GTK.WindowToplevel )</tt> creates a new instance of a
+window widget, and <tt>show()</tt> causes the window to be shown on the screen.
+
+<p>
+
+GTK.main() starts the GTK mainloop, and waits for events to
+occur. Since our window does not have any signals connected to it, the
+program will actually never exit, unless you press break in the shell.
+
+<p> 
+
+Another way to start the GTK mainloop is to return -1 from main, this
+latter approach has one rather big advantage and one small
+disadvantage.
+
+
+<p> The advantage is that you can use the normal pike backend
+functions (such as nonblocking callback based I/O and timouts using
+call_out)
+
+<p> The disadvantage is that it will use some CPU, since a polling
+mechanism is used. The amount of CPU used is not even noticeable on
+most machines (less than 0.001% CPU usage on my PII350 PC machine)
+</section>
+
+<section title="Hello world"> 
+
+Let's create a somewhat more advanced example, this time using custom
+widgets and a few signals.
+
+<example language=pike>
+class HelloWorldButton
+{
+  inherit GTK.Button;
+  void show_hi()
+  {
+    GTK.Alert( "Hi there" )->show();
+  }
+
+  void create()
+  {
+    ::create( "Hello World" );
+    signal_connect( "clicked", show_hi );
+  }
+}
+
+ 
+class MainWindow
+{
+  inherit GTK.Window;
+
+  void create()
+  {
+    ::create( GTK.WindowToplevel );
+    add( HelloWorldButton()->show() );
+    signal_connect( "destroy", exit, 0 ); // Call exit(0) directly
+  }
+}
+
+int main( int argc, array argv )
+{
+  argv = GTK.setup_gtk( argv );
+  MainWindow( )->show();
+  return -1;
+}
+</example>
+
+This example would undoubtedly been shorter without the custom widgets
+(the MainWindow and the HelloWorldButton one), but it is usually a
+good idea to write pike GTK applications by overloading existing
+widgets and add code in their constructor to add their contents.
+
+<p>
+
+The reason is that the MainWindows does not need to know how a
+HelloWorldButton is constructed, and the main function does not need
+to know how to build a MainWindow widget, it is thus very easy to
+change the subwidgets later on.
+
+<p>
+A more 'standard' approach would be:
+
+<example language=pike>
+void show_hi()
+{
+  GTK.Alert( "Hi there" )->show();  
+}
+
+int main( int argc, array argv )
+{
+  GTK.Window window;
+  GTK.Button button;
+  
+  argv = GTK.setup_gtk( argv );
+  window  = GTK.Window( GTK.Windowtoplevel );
+  button = GTK.Button( "Hello World" );
+  
+  window->add( button->show() );
+
+  window->signal_connect( "destroy", exit, 0 );
+  button->signal_connect( "clicked", show_hi );
+  
+  window->show();
+  return -1;
+}
+</example>
+AS programs grow more complex, the object oriented approach is much
+easier to maintain than the "standard" approach.
+</section>
+
+<section name="Theory of Signals and Callbacks">
+
+GTK is an event driven toolkit, which means it will sleep until an
+event occurs and control is passed to the appropriate function.
+
+<p>
+This passing of control is done using the idea of "signals". (Note
+that these signals are not the same as the Unix system signals, and
+are not implemented using them, although the terminology is almost
+identical.) 
+
+<p>
+
+When an event occurs, such as the press of a mouse button, the
+appropriate signal will be "emitted" by the widget that was
+pressed. This is how GTK does most of its useful work. There are
+signals that all widgets inherit, such as "destroy", and there are
+signals that are widget specific, such as "toggled" on a toggle
+button.
+
+<p>
+To make a button perform an action, we set up a signal handler to
+catch these signals and call the appropriate function. This is done by
+using the signal_connect method in the widget.
+
+
+<tt>
+     int <b>signal_connect</b>( string <b>signal_name</b>,
+                                function <b>callback_function</b>
+                                mixed|void <b>callback_argument</b> );
+</tt>
+The signal name is either a string such as "destroy", or one of the
+predefined GTK.s_* constants (which are actually strings,
+GTK.s_destroy is the string "destroy".
+
+<p>
+
+The specified function will be called when the signal is emitted, the
+first argument will always be the one you specified as the (optional)
+last argument to signal_connect, the second argument is always the
+widget to which the signal was connected, all other arguments are
+signal specific.
+</section>
+
+<section title="Packing widgets">
+
+When creating an application, you'll want to put more than one widget
+inside a window. Our first helloworld example only used one widget so
+we could simply use a <tt>add</tt> call to "pack" the widget into
+the window. But when you want to put more than one widget into a
+window, how do you control where that widget is positioned? This is
+where packing comes in.
+
+<p>
+Most packing is done by creating boxes. These are invisible widget
+containers that we can pack our widgets into which come in two forms,
+a horizontal box, and a vertical box. When packing widgets into a
+horizontal box, the objects are inserted horizontally from left to
+right or right to left depending on the call used. In a vertical box,
+widgets are packed from top to bottom or vice versa. You may use any
+combination of boxes inside or beside other boxes to create the
+desired effect.
+
+<p>
+To create a new horizontal box, we use a call to GTK.Hbox(), or create
+a widget that inherits the GTK.Hbox widget, and for vertical boxes
+Vbox is used instead. pack_start and pack_end member functions are
+used to place objects inside of the boxes.
+
+<p>
+ The pack_start() function will start at the top
+and work its way down in a vbox, and pack left to right in an
+hbox. 
+
+pack_end() will do the opposite, packing from bottom to
+top in a vbox, and right to left in an hbox. 
+
+<p>
+
+Using these functions allows us to right justify or left justify our
+widgets and may be mixed in any way to achieve the desired effect. We
+will use pack_start() in most of our examples. An object may be
+another container or a widget. In fact, many widgets are actually
+containers themselves, including the button, but we usually only use a
+label inside a button.
+
+<p>
+By using these calls, GTK knows where you want to place your widgets
+so it can do automatic resizing and other nifty things. There are also
+a number of options as to how your widgets should be packed. As you
+can imagine, this method gives us a quite a bit of flexibility when
+placing and creating widgets.
+<p>
+
+
+
+Because of this flexibility, packing boxes in GTK can be confusing at
+first. There are a lot of options, and it's not immediately obvious
+how they all fit together.
+</section>
+
+<section title="Notable differences between GTK and Pike GTK">
+
+<section title="Image handling">
+</section>
+
+<section title="The .pgtkrc file">
+  Pike GTK reads $HOME/.pgtkrc if it exists, and passes it through the
+  pike Pre-processor. This is mostly for compatibility with older Pike
+  GTK releases, it is reccommended that the normal .gtkrc file is used
+  instead, since this gives the same style to all GTK applications.
+</section>
+
+</section>
+
+</section>
+
+<section title="Reference">
+ <include file="gtk_reference.wmml">
+</section>
\ No newline at end of file