diff -uNr gimp-2.2.17/app/paint/Makefile.am gimp-2.2.17-gpen-work/app/paint/Makefile.am
--- gimp-2.2.17/app/paint/Makefile.am	2007-04-18 06:10:04.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/Makefile.am	2007-08-16 15:20:58.000000000 +0900
@@ -68,7 +68,11 @@
 	gimpsmudge.c		\
 	gimpsmudge.h		\
 	gimpsmudgeoptions.c	\
-	gimpsmudgeoptions.h
+	gimpsmudgeoptions.h	\
+	gimpink2.c		\
+	gimpink2.h		\
+	gimpink2options.c	\
+	gimpink2options.h
 
 libapppaint_a_built_sources = paint-enums.c
 
diff -uNr gimp-2.2.17/app/paint/Makefile.in gimp-2.2.17-gpen-work/app/paint/Makefile.in
--- gimp-2.2.17/app/paint/Makefile.in	2007-07-13 00:35:21.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/Makefile.in	2007-08-16 16:42:10.000000000 +0900
@@ -63,7 +63,8 @@
 	gimppaintcore-undo.$(OBJEXT) gimppaintoptions.$(OBJEXT) \
 	gimppencil.$(OBJEXT) gimppenciloptions.$(OBJEXT) \
 	gimppaintbrush.$(OBJEXT) gimpsmudge.$(OBJEXT) \
-	gimpsmudgeoptions.$(OBJEXT)
+	gimpsmudgeoptions.$(OBJEXT) \
+	gimpink2.$(OBJEXT) gimpink2options.$(OBJEXT) gimpink2-undo.$(OBJEXT)
 am_libapppaint_a_OBJECTS = $(am__objects_1) $(am__objects_2)
 libapppaint_a_OBJECTS = $(am_libapppaint_a_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -488,7 +489,13 @@
 	gimpsmudge.c		\
 	gimpsmudge.h		\
 	gimpsmudgeoptions.c	\
-	gimpsmudgeoptions.h
+	gimpsmudgeoptions.h	\
+	gimpink2.c		\
+	gimpink2.h		\
+	gimpink2options.c	\
+	gimpink2options.h	\
+	gimpink2-undo.c		\
+	gimpink2-undo.h
 
 libapppaint_a_built_sources = paint-enums.c
 libapppaint_a_SOURCES = $(libapppaint_a_built_sources) $(libapppaint_a_sources)
diff -uNr gimp-2.2.17/app/paint/gimp-paint.c gimp-2.2.17-gpen-work/app/paint/gimp-paint.c
--- gimp-2.2.17/app/paint/gimp-paint.c	2007-04-18 06:10:04.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimp-paint.c	2007-08-16 15:26:55.000000000 +0900
@@ -37,6 +37,7 @@
 #include "gimppaintbrush.h"
 #include "gimppencil.h"
 #include "gimpsmudge.h"
+#include "gimpink2.h"
 
 
 /*  local function prototypes  */
@@ -62,7 +63,8 @@
     gimp_airbrush_register,
     gimp_eraser_register,
     gimp_paintbrush_register,
-    gimp_pencil_register
+    gimp_pencil_register,
+    gimp_ink2_register
   };
 
   gint i;
diff -uNr gimp-2.2.17/app/paint/gimpink2-undo.c gimp-2.2.17-gpen-work/app/paint/gimpink2-undo.c
--- gimp-2.2.17/app/paint/gimpink2-undo.c	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimpink2-undo.c	2007-08-16 16:58:11.000000000 +0900
@@ -0,0 +1,188 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib-object.h>
+
+#include "paint-types.h"
+
+#include "core/gimpimage-undo.h"
+#include "core/gimpimage.h"
+#include "core/gimpundo.h"
+
+#include "gimpink2.h"
+#include "gimpink-blob.h"
+#include "gimpink2-undo.h"
+
+
+/**************/
+/*  Ink Undo  */
+/**************/
+
+typedef struct _Ink2Undo Ink2Undo;
+
+struct _Ink2Undo
+{
+  GimpInk2 *ink;
+
+  Blob    *last_blob;
+
+  gdouble  dt_buffer[INK2_DIST_SMOOTHER_BUFFER];
+  gint     dt_index;
+
+  guint32  ts_buffer[INK2_TIME_SMOOTHER_BUFFER];
+  gint     ts_index;
+
+  gdouble  last_time;
+
+  gboolean init_velocity;
+};
+
+
+static gboolean  undo_pop_ink2  (GimpUndo            *undo,
+                                GimpUndoMode         undo_mode,
+                                GimpUndoAccumulator *accum);
+static void      undo_free_ink2 (GimpUndo            *undo,
+                                GimpUndoMode         undo_mode);
+
+
+gboolean
+gimp_ink2_push_undo (GimpPaintCore *core,
+                    GimpImage     *gimage,
+                    const gchar   *undo_desc)
+{
+  GimpUndo *new;
+
+  g_return_val_if_fail (GIMP_IS_INK2 (core), FALSE);
+  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
+
+  if (! GIMP_PAINT_CORE_CLASS (g_type_class_peek_parent (GIMP_INK2_GET_CLASS (core)))->push_undo (core, gimage, undo_desc))
+    return FALSE;
+
+  if ((new = gimp_image_undo_push (gimage, GIMP_TYPE_UNDO,
+                                   sizeof (Ink2Undo),
+                                   sizeof (Ink2Undo),
+                                   GIMP_UNDO_INK, undo_desc,
+                                   FALSE,
+                                   undo_pop_ink2,
+                                   undo_free_ink2,
+                                   NULL)))
+    {
+      GimpInk2 *ink	= GIMP_INK2 (core);
+      Ink2Undo *ink_undo = new->data;
+
+      ink_undo->ink = ink;
+
+      if (ink->start_blob)
+        ink_undo->last_blob = blob_duplicate (ink->start_blob);
+
+      memcpy (ink_undo->dt_buffer, ink->dt_buffer,
+              sizeof (ink_undo->dt_buffer));
+
+      ink_undo->dt_index = ink->dt_index;
+
+      memcpy (ink_undo->ts_buffer, ink->ts_buffer,
+              sizeof (ink_undo->ts_buffer));
+
+      ink_undo->ts_index = ink->ts_index;
+
+      ink_undo->last_time = ink->last_time;
+
+      ink_undo->init_velocity = ink->init_velocity;
+
+      g_object_add_weak_pointer (G_OBJECT (ink), (gpointer) &ink_undo->ink);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+undo_pop_ink2 (GimpUndo            *undo,
+              GimpUndoMode         undo_mode,
+              GimpUndoAccumulator *accum)
+{
+  Ink2Undo *ink_undo = undo->data;
+
+  /*  only pop if the core still exists  */
+  if (ink_undo->ink)
+    {
+      GimpInk2 *ink = GIMP_INK2 (ink_undo->ink);
+      Blob    *tmp_blob;
+      gint     tmp_int;
+      gdouble  tmp_double;
+      guint32  tmp_int_buf[INK2_DIST_SMOOTHER_BUFFER];
+      gdouble  tmp_double_buf[INK2_DIST_SMOOTHER_BUFFER];
+
+      tmp_blob = ink->last_blob;
+      ink->last_blob = ink_undo->last_blob;
+      ink_undo->last_blob = tmp_blob;
+
+      memcpy (tmp_double_buf, ink->dt_buffer,
+              sizeof (tmp_double_buf));
+      memcpy (ink->dt_buffer, ink_undo->dt_buffer,
+              sizeof (tmp_double_buf));
+      memcpy (ink_undo->dt_buffer, tmp_double_buf,
+              sizeof (tmp_double_buf));
+
+      tmp_int = ink->dt_index;
+      ink->dt_index = ink_undo->dt_index;
+      ink_undo->dt_index = tmp_int;
+
+      memcpy (tmp_int_buf, ink->ts_buffer,
+              sizeof (tmp_int_buf));
+      memcpy (ink->ts_buffer, ink_undo->ts_buffer,
+              sizeof (tmp_int_buf));
+      memcpy (ink_undo->ts_buffer, tmp_int_buf,
+              sizeof (tmp_int_buf));
+
+      tmp_int = ink->ts_index;
+      ink->ts_index = ink_undo->ts_index;
+      ink_undo->ts_index = tmp_int;
+
+      tmp_double = ink->last_time;
+      ink->last_time = ink_undo->last_time;
+      ink_undo->last_time = tmp_double;
+
+      tmp_int = ink->init_velocity;
+      ink->init_velocity = ink_undo->init_velocity;
+      ink_undo->init_velocity = tmp_int;
+    }
+
+  return TRUE;
+}
+
+static void
+undo_free_ink2 (GimpUndo     *undo,
+               GimpUndoMode  undo_mode)
+{
+  Ink2Undo *ink_undo = undo->data;
+
+  if (ink_undo->ink)
+    g_object_remove_weak_pointer (G_OBJECT (ink_undo->ink),
+                                  (gpointer) &ink_undo->ink);
+
+  if (ink_undo->last_blob)
+    g_free (ink_undo->last_blob);
+
+  g_free (ink_undo);
+}
diff -uNr gimp-2.2.17/app/paint/gimpink2-undo.h gimp-2.2.17-gpen-work/app/paint/gimpink2-undo.h
--- gimp-2.2.17/app/paint/gimpink2-undo.h	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimpink2-undo.h	2007-08-16 16:36:08.000000000 +0900
@@ -0,0 +1,28 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GIMP_INK2_UNDO_H__
+#define __GIMP_INK2_UNDO_H__
+
+
+gboolean   gimp_ink2_push_undo (GimpPaintCore *core,
+                               GimpImage     *gimage,
+                               const gchar   *undo_desc);
+
+
+#endif  /* __GIMP_INK2_UNDO_H__ */
diff -uNr gimp-2.2.17/app/paint/gimpink2.c gimp-2.2.17-gpen-work/app/paint/gimpink2.c
--- gimp-2.2.17/app/paint/gimpink2.c	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimpink2.c	2007-08-17 00:50:54.000000000 +0900
@@ -0,0 +1,916 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib-object.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include "paint-types.h"
+
+#include "base/pixel-region.h"
+#include "base/temp-buf.h"
+#include "base/tile.h"
+#include "base/tile-manager.h"
+
+#include "paint-funcs/paint-funcs.h"
+
+#include "core/gimpdrawable.h"
+#include "core/gimpimage.h"
+
+#include "gimpink2options.h"
+#include "gimpink2.h"
+#include "gimpink-blob.h"
+#include "gimpink2-undo.h"
+
+#include "gimp-intl.h"
+
+
+#define SUBSAMPLE 8
+
+
+/*  local function prototypes  */
+
+static void      gimp_ink2_class_init     (GimpInk2Class     *klass);
+static void      gimp_ink2_init           (GimpInk2          *ink);
+
+static void      gimp_ink2_finalize       (GObject          *object);
+
+static void      gimp_ink2_paint          (GimpPaintCore    *paint_core,
+                                          GimpDrawable     *drawable,
+                                          GimpPaintOptions *paint_options,
+                                          GimpPaintState    paint_state,
+                                          guint32           time);
+static TempBuf * gimp_ink2_get_paint_area (GimpPaintCore    *paint_core,
+                                          GimpDrawable     *drawable,
+                                          GimpPaintOptions *paint_options);
+
+static void      gimp_ink2_motion         (GimpPaintCore    *paint_core,
+                                          GimpDrawable     *drawable,
+                                          GimpPaintOptions *paint_options,
+                                          guint32           time,
+					  gboolean	    at_last);
+
+static Blob    * ink2_pen_ellipse         (GimpInk2Options   *options,
+                                          gdouble           x_center,
+                                          gdouble           y_center,
+                                          gdouble           pressure,
+                                          gdouble           xtilt,
+                                          gdouble           ytilt,
+                                          gdouble           velocity);
+
+static void      time_smoother_add       (GimpInk2          *ink,
+                                          guint32           value);
+static guint32   time_smoother_result    (GimpInk2          *ink);
+static void      time_smoother_init      (GimpInk2          *ink,
+                                          guint32           initval);
+
+static void      dist_smoother_add       (GimpInk2          *ink,
+                                          gdouble           value);
+static gdouble   dist_smoother_result    (GimpInk2          *ink);
+static void      dist_smoother_init      (GimpInk2          *ink,
+                                          gdouble           initval);
+
+static void      render_blob             (Blob             *blob,
+                                          PixelRegion      *dest);
+
+static void	hist_init (GimpInk2 *ink, GimpCoords* coords);
+static void     hist_add  (GimpInk2 *ink, GimpCoords* coords);
+static GimpCoords     hist_result  (GimpInk2 *ink, GimpInk2Options *options);
+static GimpCoords     hist_result_velocity  (GimpInk2 *ink, GimpInk2Options *options);
+
+
+static GimpPaintCoreClass *parent_class = NULL;
+
+
+void
+gimp_ink2_register (Gimp                      *gimp,
+                   GimpPaintRegisterCallback  callback)
+{
+  (* callback) (gimp,
+                GIMP_TYPE_INK2,
+                GIMP_TYPE_INK2_OPTIONS,
+                _("Ink"));
+}
+
+GType
+gimp_ink2_get_type (void)
+{
+  static GType type = 0;
+
+  if (! type)
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (GimpInk2Class),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gimp_ink2_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data     */
+        sizeof (GimpInk2),
+        0,              /* n_preallocs    */
+        (GInstanceInitFunc) gimp_ink2_init,
+      };
+
+      type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
+                                     "GimpInk2",
+                                     &info, 0);
+    }
+
+  return type;
+}
+
+static void
+gimp_ink2_class_init (GimpInk2Class *klass)
+{
+  GObjectClass       *object_class     = G_OBJECT_CLASS (klass);
+  GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize  = gimp_ink2_finalize;
+
+  paint_core_class->paint          = gimp_ink2_paint;
+  paint_core_class->get_paint_area = gimp_ink2_get_paint_area;
+  paint_core_class->push_undo      = gimp_ink2_push_undo;
+}
+
+static void
+gimp_ink2_init (GimpInk2 *ink)
+{
+}
+
+static void
+gimp_ink2_finalize (GObject *object)
+{
+  GimpInk2 *ink = GIMP_INK2 (object);
+
+  if (ink->start_blob)
+    {
+      g_free (ink->start_blob);
+      ink->start_blob = NULL;
+    }
+
+  if (ink->last_blob)
+    {
+      g_free (ink->last_blob);
+      ink->last_blob = NULL;
+    }
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_ink2_paint (GimpPaintCore    *paint_core,
+                GimpDrawable     *drawable,
+                GimpPaintOptions *paint_options,
+                GimpPaintState    paint_state,
+                guint32           time)
+{
+  GimpInk2 *ink = GIMP_INK2 (paint_core);
+
+  switch (paint_state)
+    {
+    case GIMP_PAINT_STATE_INIT:
+      if (paint_core->cur_coords.x == paint_core->last_coords.x &&
+          paint_core->cur_coords.y == paint_core->last_coords.y)
+        {
+          /*  start with new blobs if we're not interpolating  */
+
+          if (ink->start_blob)
+            {
+              g_free (ink->start_blob);
+              ink->start_blob = NULL;
+            }
+
+          if (ink->last_blob)
+            {
+              g_free (ink->last_blob);
+              ink->last_blob = NULL;
+            }
+        }
+      else if (ink->last_blob)
+        {
+          /*  save the start blob of the line for undo otherwise  */
+
+          if (ink->start_blob)
+            g_free (ink->start_blob);
+
+          ink->start_blob = blob_duplicate (ink->last_blob);
+        }
+      break;
+
+    case GIMP_PAINT_STATE_MOTION:
+      gimp_ink2_motion (paint_core, drawable, paint_options, time, FALSE);
+      break;
+
+    case GIMP_PAINT_STATE_FINISH:
+      gimp_ink2_motion (paint_core, drawable, paint_options, time, TRUE);
+      break;
+    }
+}
+
+static TempBuf *
+gimp_ink2_get_paint_area (GimpPaintCore    *paint_core,
+                         GimpDrawable     *drawable,
+                         GimpPaintOptions *paint_options)
+{
+  GimpInk2 *ink  = GIMP_INK2 (paint_core);
+  gint     x, y;
+  gint     width, height;
+  gint     dwidth, dheight;
+  gint     x1, y1, x2, y2;
+  gint     bytes;
+
+  bytes = gimp_drawable_bytes_with_alpha (drawable);
+
+  blob_bounds (ink->cur_blob, &x, &y, &width, &height);
+
+  dwidth  = gimp_item_width  (GIMP_ITEM (drawable));
+  dheight = gimp_item_height (GIMP_ITEM (drawable));
+
+  x1 = CLAMP (x / SUBSAMPLE - 1,            0, dwidth);
+  y1 = CLAMP (y / SUBSAMPLE - 1,            0, dheight);
+  x2 = CLAMP ((x + width)  / SUBSAMPLE + 2, 0, dwidth);
+  y2 = CLAMP ((y + height) / SUBSAMPLE + 2, 0, dheight);
+
+  /*  configure the canvas buffer  */
+  if ((x2 - x1) && (y2 - y1))
+    paint_core->canvas_buf = temp_buf_resize (paint_core->canvas_buf, bytes,
+                                              x1, y1,
+                                              (x2 - x1), (y2 - y1));
+  else
+    return NULL;
+
+  return paint_core->canvas_buf;
+}
+
+static void
+gimp_ink2_motion (GimpPaintCore    *paint_core,
+                 GimpDrawable     *drawable,
+                 GimpPaintOptions *paint_options,
+                 guint32           time,
+                 gboolean          at_last)
+{
+  GimpInk2        *ink     = GIMP_INK2 (paint_core);
+  GimpInk2Options *options = GIMP_INK2_OPTIONS (paint_options);
+  GimpContext    *context = GIMP_CONTEXT (paint_options);
+  GimpImage      *gimage;
+  Blob           *blob_union = NULL;
+  Blob           *blob_to_render;
+  TempBuf        *area;
+  guchar          col[MAX_CHANNELS];
+  PixelRegion     blob_maskPR;
+
+  if (at_last && !options->compensate_at_last)
+    return;
+
+  gimage = gimp_item_get_image (GIMP_ITEM (drawable));
+
+  if (! ink->last_blob)
+    {
+      ink->last_blob = ink2_pen_ellipse (options,
+                                        paint_core->cur_coords.x,
+                                        paint_core->cur_coords.y,
+                                        paint_core->cur_coords.pressure,
+                                        paint_core->cur_coords.xtilt,
+                                        paint_core->cur_coords.ytilt,
+                                        10.0);
+
+      if (ink->start_blob)
+        g_free (ink->start_blob);
+
+      ink->start_blob = blob_duplicate (ink->last_blob);
+
+      time_smoother_init (ink, time);
+      ink->last_time = time;
+
+      dist_smoother_init (ink, 0.0);
+      ink->init_velocity = TRUE;
+
+      hist_init (ink, &paint_core->cur_coords);
+
+      blob_to_render = ink->last_blob;
+    }
+  else
+    {
+      Blob    *blob;
+      gdouble  dist;
+      gdouble  velocity;
+      guint32  lasttime = ink->last_time;
+      guint32  thistime;
+      GimpCoords average_hist;
+      GimpCoords average_velocity;
+
+      time_smoother_add (ink, time);
+      thistime = ink->last_time = time_smoother_result (ink);
+
+      /* The time resolution on X-based GDK motion events is bloody
+       * awful, hence the use of the smoothing function.  Sadly this
+       * also means that there is always the chance of having an
+       * indeterminite velocity since this event and the previous
+       * several may still appear to issue at the same
+       * instant. -ADM
+       */
+      if (thistime == lasttime)
+        thistime = lasttime + 1;
+
+      dist = sqrt ((paint_core->last_coords.x - paint_core->cur_coords.x) *
+                   (paint_core->last_coords.x - paint_core->cur_coords.x) +
+                   (paint_core->last_coords.y - paint_core->cur_coords.y) *
+                   (paint_core->last_coords.y - paint_core->cur_coords.y));
+      if (ink->init_velocity)
+        {
+          dist_smoother_init (ink, dist);
+          ink->init_velocity = FALSE;
+        }
+      else
+        {
+          dist_smoother_add (ink, dist);
+          dist = dist_smoother_result (ink);
+        }
+
+      velocity = 10.0 * sqrt ((dist) / (gdouble) (thistime - lasttime));
+
+      if (!at_last && options->compensation_hist_size > 1) 
+        {
+          hist_add(ink, &paint_core->cur_coords);
+          average_hist = hist_result(ink, options);
+//        average_velocity = hist_result_velocity(ink, options);
+//        g_printf("dist_x=%f(avg=%f), dist_y=%f(avg=%f)\n", paint_core->cur_coords.x - paint_core->last_coords.x, average_hist.x, paint_core->cur_coords.y - paint_core->last_coords.y, average_hist.y);
+
+          blob = ink2_pen_ellipse (options,
+                                  average_hist.x,
+                                  average_hist.y,
+                                  paint_core->cur_coords.pressure,
+                                  paint_core->cur_coords.xtilt,
+                                  paint_core->cur_coords.ytilt,
+                                  velocity);
+        }
+      else
+        {
+          blob = ink2_pen_ellipse (options,
+                                  paint_core->cur_coords.x,
+                                  paint_core->cur_coords.y,
+                                  paint_core->cur_coords.pressure,
+                                  paint_core->cur_coords.xtilt,
+                                  paint_core->cur_coords.ytilt,
+                                  velocity);
+         }
+
+      blob_union = blob_convex_union (ink->last_blob, blob);
+      g_free (ink->last_blob);
+      ink->last_blob = blob;
+
+      blob_to_render = blob_union;
+    }
+
+  /* Get the the buffer */
+  ink->cur_blob = blob_to_render;
+  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
+  ink->cur_blob = NULL;
+
+  if (! area)
+    return;
+
+  gimp_image_get_foreground (gimage, drawable, context, col);
+
+  /*  set the alpha channel  */
+  col[paint_core->canvas_buf->bytes - 1] = OPAQUE_OPACITY;
+
+  /*  color the pixels  */
+  color_pixels (temp_buf_data (paint_core->canvas_buf), col,
+                area->width * area->height, area->bytes);
+
+  gimp_paint_core_validate_canvas_tiles (paint_core,
+                                         paint_core->canvas_buf->x,
+                                         paint_core->canvas_buf->y,
+                                         paint_core->canvas_buf->width,
+                                         paint_core->canvas_buf->height);
+
+  /*  draw the blob directly to the canvas_tiles  */
+  pixel_region_init (&blob_maskPR, paint_core->canvas_tiles,
+                     paint_core->canvas_buf->x,
+                     paint_core->canvas_buf->y,
+                     paint_core->canvas_buf->width,
+                     paint_core->canvas_buf->height,
+                     TRUE);
+
+  render_blob (blob_to_render, &blob_maskPR);
+
+  /*  draw the canvas_buf using the just rendered canvas_tiles as mask */
+  pixel_region_init (&blob_maskPR, paint_core->canvas_tiles,
+                     paint_core->canvas_buf->x,
+                     paint_core->canvas_buf->y,
+                     paint_core->canvas_buf->width,
+                     paint_core->canvas_buf->height,
+                     FALSE);
+
+  gimp_paint_core_paste (paint_core, &blob_maskPR, drawable,
+                         GIMP_OPACITY_OPAQUE,
+                         gimp_context_get_opacity (context),
+                         gimp_context_get_paint_mode (context),
+                         GIMP_PAINT_CONSTANT);
+
+  if (blob_union)
+    g_free (blob_union);
+}
+
+static Blob *
+ink2_pen_ellipse (GimpInk2Options *options,
+                 gdouble         x_center,
+		 gdouble         y_center,
+		 gdouble         pressure,
+		 gdouble         xtilt,
+		 gdouble         ytilt,
+		 gdouble         velocity)
+{
+  BlobFunc blob_function;
+  gdouble  size;
+  gdouble  tsin, tcos;
+  gdouble  aspect, radmin;
+  gdouble  x,y;
+  gdouble  tscale;
+  gdouble  tscale_c;
+  gdouble  tscale_s;
+
+  /* Adjust the size depending on pressure. */
+
+  size = options->size * (1.0 + options->size_sensitivity *
+                          (2.0 * pressure - 1.0));
+
+  /* Adjust the size further depending on pointer velocity and
+   * velocity-sensitivity.  These 'magic constants' are 'feels
+   * natural' tigert-approved. --ADM
+   */
+
+  if (velocity < 3.0)
+    velocity = 3.0;
+
+#ifdef VERBOSE
+  g_printerr ("%g (%g) -> ", size, velocity);
+#endif
+
+  size = (options->vel_sensitivity *
+          ((4.5 * size) / (1.0 + options->vel_sensitivity * (2.0 * velocity)))
+          + (1.0 - options->vel_sensitivity) * size);
+
+#ifdef VERBOSE
+  g_printerr ("%g\n", (gfloat) size);
+#endif
+
+  /* Clamp resulting size to sane limits */
+
+  if (size > options->size * (1.0 + options->size_sensitivity))
+    size = options->size * (1.0 + options->size_sensitivity);
+
+  if (size * SUBSAMPLE < 1.0)
+    size = 1.0 / SUBSAMPLE;
+
+  /* Add brush angle/aspect to tilt vectorially */
+
+  /* I'm not happy with the way the brush widget info is combined with
+   * tilt info from the brush. My personal feeling is that
+   * representing both as affine transforms would make the most
+   * sense. -RLL
+   */
+
+  tscale   = options->tilt_sensitivity * 10.0;
+  tscale_c = tscale * cos (gimp_deg_to_rad (options->tilt_angle));
+  tscale_s = tscale * sin (gimp_deg_to_rad (options->tilt_angle));
+
+  x = (options->blob_aspect * cos (options->blob_angle) +
+       xtilt * tscale_c - ytilt * tscale_s);
+  y = (options->blob_aspect * sin (options->blob_angle) +
+       ytilt * tscale_c + xtilt * tscale_s);
+
+#ifdef VERBOSE
+  g_printerr ("angle %g aspect %g; %g %g; %g %g\n",
+              options->blob_angle, options->blob_aspect,
+              tscale_c, tscale_s, x, y);
+#endif
+
+  aspect = sqrt (x * x + y * y);
+
+  if (aspect != 0)
+    {
+      tcos = x / aspect;
+      tsin = y / aspect;
+    }
+  else
+    {
+      tsin = sin (options->blob_angle);
+      tcos = cos (options->blob_angle);
+    }
+
+  aspect = CLAMP (aspect, 1.0, 10.0);
+
+  radmin = MAX (1.0, SUBSAMPLE * size / aspect);
+
+  switch (options->blob_type)
+    {
+    case GIMP_INK_BLOB_TYPE_ELLIPSE:
+      blob_function = blob_ellipse;
+      break;
+
+    case GIMP_INK_BLOB_TYPE_SQUARE:
+      blob_function = blob_square;
+      break;
+
+    case GIMP_INK_BLOB_TYPE_DIAMOND:
+      blob_function = blob_diamond;
+      break;
+
+    default:
+      g_return_val_if_reached (NULL);
+      break;
+    }
+
+  return (* blob_function) (x_center * SUBSAMPLE,
+                            y_center * SUBSAMPLE,
+                            radmin * aspect * tcos,
+                            radmin * aspect * tsin,
+                            -radmin * tsin,
+                            radmin * tcos);
+}
+
+
+static void
+time_smoother_init (GimpInk2 *ink,
+                    guint32  initval)
+{
+  gint i;
+
+  ink->ts_index = 0;
+
+  for (i = 0; i < INK2_TIME_SMOOTHER_BUFFER; i++)
+    ink->ts_buffer[i] = initval;
+}
+
+static guint32
+time_smoother_result (GimpInk2 *ink)
+{
+  gint    i;
+  guint64 result = 0;
+
+  for (i = 0; i < INK2_TIME_SMOOTHER_BUFFER; i++)
+    result += ink->ts_buffer[i];
+
+  return (result / (guint64) INK2_TIME_SMOOTHER_BUFFER);
+}
+
+static void
+time_smoother_add (GimpInk2 *ink,
+                   guint32  value)
+{
+  guint64 long_value = (guint64) value;
+
+  /*  handle wrap-around of time values  */
+  if (long_value < ink->ts_buffer[ink->ts_index])
+    long_value += (guint64) + G_MAXUINT32;
+
+  ink->ts_buffer[ink->ts_index++] = long_value;
+
+  ink->ts_buffer[ink->ts_index++] = value;
+
+  if (ink->ts_index == INK2_TIME_SMOOTHER_BUFFER)
+    ink->ts_index = 0;
+}
+
+
+static void
+dist_smoother_init (GimpInk2 *ink,
+                    gdouble  initval)
+{
+  gint i;
+
+  ink->dt_index = 0;
+
+  for (i = 0; i < INK2_DIST_SMOOTHER_BUFFER; i++)
+    ink->dt_buffer[i] = initval;
+}
+
+static gdouble
+dist_smoother_result (GimpInk2 *ink)
+{
+  gint    i;
+  gdouble result = 0.0;
+
+  for (i = 0; i < INK2_DIST_SMOOTHER_BUFFER; i++)
+    result += ink->dt_buffer[i];
+
+  return (result / (gdouble) INK2_DIST_SMOOTHER_BUFFER);
+}
+
+static void
+dist_smoother_add (GimpInk2 *ink,
+                   gdouble  value)
+{
+  ink->dt_buffer[ink->dt_index++] = value;
+
+  if (ink->dt_index == INK2_DIST_SMOOTHER_BUFFER)
+    ink->dt_index = 0;
+}
+
+
+static void
+hist_init(GimpInk2 * ink, GimpCoords* coords)
+{
+  ink->hist_index = 0;
+  ink->hist_count = 0;
+  if (coords)
+    hist_add(ink, coords);
+}
+
+
+#define HIST_IGNORE_THRESHOULD 0.0001
+static void
+hist_add(GimpInk2 *ink, GimpCoords* coords)
+{
+  if (coords) {
+    if (ink->hist_count > 0) {
+      gint prev_index = (ink->hist_index + INK2_HISTORY_BUFFER - 1) % INK2_HISTORY_BUFFER;
+      gdouble dist_x = coords->x - ink->hist_buffer[prev_index].x;
+      gdouble dist_y = coords->y - ink->hist_buffer[prev_index].y;
+      if (sqrt(dist_x * dist_x + dist_y * dist_y) < HIST_IGNORE_THRESHOULD)
+        return;
+    }
+    ink->hist_buffer[ink->hist_index++] = *coords;
+
+    if (ink->hist_count < INK2_HISTORY_BUFFER)
+      ink->hist_count ++;
+  
+    if (ink->hist_index == INK2_HISTORY_BUFFER)
+      ink->hist_index = 0;
+  }
+}
+
+
+#define min(x, y) ((x) < (y))? (x) : (y)
+static GimpCoords
+hist_result(GimpInk2 *ink, GimpInk2Options* options)
+{
+  gint i;
+  GimpCoords result;
+  result.x = result.y = 0.0;
+  if (ink->hist_count > 0) {
+    gint max_hist_count = min(ink->hist_count , options->compensation_hist_size);
+    gint cur_index = (ink->hist_index + INK2_HISTORY_BUFFER - max_hist_count) % INK2_HISTORY_BUFFER; 
+    for (i = 0; i < max_hist_count; i ++, cur_index ++) {
+      if (cur_index == INK2_HISTORY_BUFFER)
+        cur_index = 0;
+      result.x += ink->hist_buffer[cur_index].x;
+      result.y += ink->hist_buffer[cur_index].y;
+    }
+    result.x /= max_hist_count;
+    result.y /= max_hist_count;
+  }
+  return result;
+}
+
+static GimpCoords
+hist_result_velocity(GimpInk2 *ink, GimpInk2Options* options)
+{
+  gint i;
+  GimpCoords result;
+  result.x = result.y = 0.0;
+  if (ink->hist_count > 1) {
+    gint max_hist_count = min(ink->hist_count ,options->compensation_hist_size);
+    gint cur_index = (ink->hist_index + INK2_HISTORY_BUFFER - max_hist_count + 1) % INK2_HISTORY_BUFFER;
+    gint prev_index = (cur_index + INK2_HISTORY_BUFFER - 1)% INK2_HISTORY_BUFFER;
+    for (i = 0; i < max_hist_count - 1; i ++) {
+      if (cur_index != 0 || ink->hist_count >= INK2_HISTORY_BUFFER) {
+        GimpCoords* prev = &ink->hist_buffer[prev_index];
+//        g_printf("%d-%d: (%f,%f) - (%f,%f) = (%f, %f) --> (%f, %f)\n", cur_index, prev_index, ink->hist_buffer[cur_index].x, ink->hist_buffer[cur_index].y, prev->x, prev->y, ink->hist_buffer[cur_index].x - prev->x, ink->hist_buffer[cur_index].y - prev->y, result.x, result.y);
+        result.x += ink->hist_buffer[cur_index].x - prev->x;
+        result.y += ink->hist_buffer[cur_index].y - prev->y;
+      }
+      cur_index ++, prev_index ++;
+      if (prev_index == INK2_HISTORY_BUFFER)
+        prev_index = 0;
+      if (cur_index == INK2_HISTORY_BUFFER)
+        cur_index = 0;
+//    g_printf("Inc: %f, %f\n", result.x, result.y);
+    }
+//    g_printf("Total: %f, %f\n", result.x, result.y);
+    result.x /= max_hist_count;
+    result.y /= max_hist_count;
+  }
+  return result;
+}
+#undef min
+
+
+/*********************************/
+/*  Rendering functions          */
+/*********************************/
+
+/* Some of this stuff should probably be combined with the
+ * code it was copied from in paint_core.c; but I wanted
+ * to learn this stuff, so I've kept it simple.
+ *
+ * The following only supports CONSTANT mode. Incremental
+ * would, I think, interact strangely with the way we
+ * do things. But it wouldn't be hard to implement at all.
+ */
+
+enum { ROW_START, ROW_STOP };
+
+/* The insertion sort here, for SUBSAMPLE = 8, tends to beat out
+ * qsort() by 4x with CFLAGS=-O2, 2x with CFLAGS=-g
+ */
+static void
+insert_sort (gint *data,
+	     gint  n)
+{
+  gint i, j, k;
+  gint tmp1, tmp2;
+
+  for (i = 2; i < 2 * n; i += 2)
+    {
+      tmp1 = data[i];
+      tmp2 = data[i + 1];
+      j = 0;
+      while (data[j] < tmp1)
+	j += 2;
+
+      for (k = i; k > j; k -= 2)
+	{
+	  data[k]     = data[k - 2];
+	  data[k + 1] = data[k - 1];
+	}
+
+      data[j]     = tmp1;
+      data[j + 1] = tmp2;
+    }
+}
+
+static void
+fill_run (guchar *dest,
+	  guchar  alpha,
+	  gint    w)
+{
+  if (alpha == 255)
+    {
+      memset (dest, 255, w);
+    }
+  else
+    {
+      while (w--)
+        {
+          *dest = MAX (*dest, alpha);
+          dest++;
+        }
+    }
+}
+
+static void
+render_blob_line (Blob   *blob,
+		  guchar *dest,
+		  gint    x,
+		  gint    y,
+		  gint    width)
+{
+  gint  buf[4 * SUBSAMPLE];
+  gint *data    = buf;
+  gint  n       = 0;
+  gint  i, j;
+  gint  current = 0;  /* number of filled rows at this point
+		       * in the scan line
+		       */
+  gint last_x;
+
+  /* Sort start and ends for all lines */
+
+  j = y * SUBSAMPLE - blob->y;
+  for (i = 0; i < SUBSAMPLE; i++)
+    {
+      if (j >= blob->height)
+	break;
+
+      if ((j > 0) && (blob->data[j].left <= blob->data[j].right))
+	{
+	  data[2 * n]                     = blob->data[j].left;
+	  data[2 * n + 1]                 = ROW_START;
+	  data[2 * SUBSAMPLE + 2 * n]     = blob->data[j].right;
+	  data[2 * SUBSAMPLE + 2 * n + 1] = ROW_STOP;
+	  n++;
+	}
+      j++;
+    }
+
+  /*   If we have less than SUBSAMPLE rows, compress */
+  if (n < SUBSAMPLE)
+    {
+      for (i = 0; i < 2 * n; i++)
+	data[2 * n + i] = data[2 * SUBSAMPLE + i];
+    }
+
+  /*   Now count start and end separately */
+  n *= 2;
+
+  insert_sort (data, n);
+
+  /* Discard portions outside of tile */
+
+  while ((n > 0) && (data[0] < SUBSAMPLE*x))
+    {
+      if (data[1] == ROW_START)
+	current++;
+      else
+	current--;
+      data += 2;
+      n--;
+    }
+
+  while ((n > 0) && (data[2*(n-1)] >= SUBSAMPLE*(x+width)))
+    n--;
+
+  /* Render the row */
+
+  last_x = 0;
+  for (i = 0; i < n;)
+    {
+      gint cur_x = data[2 * i] / SUBSAMPLE - x;
+      gint pixel;
+
+      /* Fill in portion leading up to this pixel */
+      if (current && cur_x != last_x)
+	fill_run (dest + last_x, (255 * current) / SUBSAMPLE, cur_x - last_x);
+
+      /* Compute the value for this pixel */
+      pixel = current * SUBSAMPLE;
+
+      while (i<n)
+	{
+	  gint tmp_x = data[2 * i] / SUBSAMPLE;
+
+	  if (tmp_x - x != cur_x)
+	    break;
+
+	  if (data[2 * i + 1] == ROW_START)
+	    {
+	      current++;
+	      pixel += ((tmp_x + 1) * SUBSAMPLE) - data[2 * i];
+	    }
+	  else
+	    {
+	      current--;
+	      pixel -= ((tmp_x + 1) * SUBSAMPLE) - data[2 * i];
+	    }
+
+	  i++;
+	}
+
+      dest[cur_x] = MAX (dest[cur_x], (pixel * 255) / (SUBSAMPLE * SUBSAMPLE));
+
+      last_x = cur_x + 1;
+    }
+
+  if (current != 0)
+    fill_run (dest + last_x, (255 * current)/ SUBSAMPLE, width - last_x);
+}
+
+static void
+render_blob (Blob        *blob,
+             PixelRegion *dest)
+{
+  gint      i;
+  gint      h;
+  guchar   *s;
+  gpointer  pr;
+
+  for (pr = pixel_regions_register (1, dest);
+       pr != NULL;
+       pr = pixel_regions_process (pr))
+    {
+      h = dest->h;
+      s = dest->data;
+
+      for (i=0; i<h; i++)
+	{
+	  render_blob_line (blob, s,
+			    dest->x, dest->y + i, dest->w);
+	  s += dest->rowstride;
+	}
+    }
+}
diff -uNr gimp-2.2.17/app/paint/gimpink2.h gimp-2.2.17-gpen-work/app/paint/gimpink2.h
--- gimp-2.2.17/app/paint/gimpink2.h	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimpink2.h	2007-08-16 17:26:12.000000000 +0900
@@ -0,0 +1,81 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef  __GIMP_INK2_H__
+#define  __GIMP_INK2_H__
+
+
+#include "gimppaintcore.h"
+#include "gimpink-blob.h"
+
+
+#define INK2_DIST_SMOOTHER_BUFFER 10
+#define INK2_TIME_SMOOTHER_BUFFER 10
+#define INK2_HISTORY_BUFFER 20
+
+
+#define GIMP_TYPE_INK2            (gimp_ink2_get_type ())
+#define GIMP_INK2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_INK2, GimpInk2))
+#define GIMP_INK2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_INK2, GimpInk2Class))
+#define GIMP_IS_INK2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_INK2))
+#define GIMP_IS_INK2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_INK2))
+#define GIMP_INK2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_INK2, GimpInk2Class))
+
+
+typedef struct _GimpInk2      GimpInk2;
+typedef struct _GimpInk2Class GimpInk2Class;
+
+struct _GimpInk2
+{
+  GimpPaintCore  parent_instance;
+
+  Blob          *start_blob;   /*  starting blob (for undo)       */
+
+  Blob          *cur_blob;     /*  current blob                   */
+  Blob          *last_blob;    /*  blob for last cursor position  */
+
+  /* circular distance history buffer */
+  gdouble        dt_buffer[INK2_DIST_SMOOTHER_BUFFER];
+  gint           dt_index;
+
+  /* circular timing history buffer */
+  guint32        ts_buffer[INK2_TIME_SMOOTHER_BUFFER];
+  gint           ts_index;
+
+  GimpCoords	hist_buffer[INK2_HISTORY_BUFFER];
+  gint		hist_index;
+  gint		hist_count;
+  
+  gdouble        last_time;     /*  previous time of a motion event      */
+  
+  gboolean       init_velocity;
+};
+
+struct _GimpInk2Class
+{
+  GimpPaintCoreClass  parent_class;
+};
+
+
+void    gimp_ink2_register (Gimp                      *gimp,
+                           GimpPaintRegisterCallback  callback);
+
+GType   gimp_ink2_get_type (void) G_GNUC_CONST;
+
+
+#endif  /*  __GIMP_INK2_H__  */
diff -uNr gimp-2.2.17/app/paint/gimpink2options.c gimp-2.2.17-gpen-work/app/paint/gimpink2options.c
--- gimp-2.2.17/app/paint/gimpink2options.c	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimpink2options.c	2007-08-17 00:15:32.000000000 +0900
@@ -0,0 +1,240 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#include "paint-types.h"
+
+#include "config/gimpconfig-params.h"
+
+#include "core/gimp.h"
+#include "core/gimpdrawable.h"
+#include "core/gimppaintinfo.h"
+
+#include "gimpink2options.h"
+#include "gimpink2.h"
+#include "gimpink-blob.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_SIZE,
+  PROP_TILT_ANGLE,
+  PROP_SIZE_SENSITIVITY,
+  PROP_VEL_SENSITIVITY,
+  PROP_TILT_SENSITIVITY,
+  PROP_BLOB_TYPE,
+  PROP_BLOB_ASPECT,
+  PROP_BLOB_ANGLE,
+  PROP_COMPENSATION_HIST_SIZE,
+  PROP_COMPENSATE_AT_LAST
+};
+
+
+static void   gimp_ink2_options_class_init   (GimpInk2OptionsClass *klass);
+
+static void   gimp_ink2_options_set_property (GObject         *object,
+                                             guint            property_id,
+                                             const GValue    *value,
+                                             GParamSpec      *pspec);
+static void   gimp_ink2_options_get_property (GObject         *object,
+                                             guint            property_id,
+                                             GValue          *value,
+                                             GParamSpec      *pspec);
+
+
+static GimpPaintOptionsClass *parent_class = NULL;
+
+
+GType
+gimp_ink2_options_get_type (void)
+{
+  static GType type = 0;
+
+  if (! type)
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (GimpInk2OptionsClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gimp_ink2_options_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data     */
+        sizeof (GimpInk2Options),
+        0,              /* n_preallocs    */
+        (GInstanceInitFunc) NULL
+      };
+
+      type = g_type_register_static (GIMP_TYPE_PAINT_OPTIONS,
+                                     "GimpInk2Options",
+                                     &info, 0);
+    }
+
+  return type;
+}
+
+static void
+gimp_ink2_options_class_init (GimpInk2OptionsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->set_property = gimp_ink2_options_set_property;
+  object_class->get_property = gimp_ink2_options_get_property;
+
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SIZE,
+                                   "size", NULL,
+                                   0.0, 200.0, 16.0,
+                                   0);
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_TILT_ANGLE,
+                                   "tilt-angle", NULL,
+                                   -90.0, 90.0, 0.0,
+                                   0);
+
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SIZE_SENSITIVITY,
+                                   "size-sensitivity", NULL,
+                                   0.0, 1.0, 1.0,
+                                   0);
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_VEL_SENSITIVITY,
+                                   "vel-sensitivity", NULL,
+                                   0.0, 1.0, 0.8,
+                                   0);
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_TILT_SENSITIVITY,
+                                   "tilt-sensitivity", NULL,
+                                   0.0, 1.0, 0.4,
+                                   0);
+
+  GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_BLOB_TYPE,
+                                 "blob-type", NULL,
+                                 GIMP_TYPE_INK_BLOB_TYPE,
+                                 GIMP_INK_BLOB_TYPE_ELLIPSE,
+                                 0);
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_BLOB_ASPECT,
+                                   "blob-aspect", NULL,
+                                   1.0, 10.0, 1.0,
+                                   0);
+  GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_BLOB_ANGLE,
+                                   "blob-angle", NULL,
+                                   -90.0, 90.0, 0.0,
+                                   0);
+  GIMP_CONFIG_INSTALL_PROP_INT    (object_class, PROP_COMPENSATION_HIST_SIZE,
+				   "compensation-history-size", NULL,
+				   1, INK2_HISTORY_BUFFER, INK2_HISTORY_BUFFER, 0);
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN(object_class, PROP_COMPENSATE_AT_LAST,
+				   "compensate-at-last", NULL,
+				   TRUE, 0);
+}
+
+static void
+gimp_ink2_options_set_property (GObject      *object,
+                               guint         property_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GimpInk2Options *options = GIMP_INK2_OPTIONS (object);
+
+  switch (property_id)
+    {
+    case PROP_SIZE:
+      options->size = g_value_get_double (value);
+      break;
+    case PROP_TILT_ANGLE:
+      options->tilt_angle = g_value_get_double (value);
+      break;
+    case PROP_SIZE_SENSITIVITY:
+      options->size_sensitivity = g_value_get_double (value);
+      break;
+    case PROP_VEL_SENSITIVITY:
+      options->vel_sensitivity = g_value_get_double (value);
+      break;
+    case PROP_TILT_SENSITIVITY:
+      options->tilt_sensitivity = g_value_get_double (value);
+      break;
+    case PROP_BLOB_TYPE:
+      options->blob_type = g_value_get_enum (value);
+      break;
+    case PROP_BLOB_ASPECT:
+      options->blob_aspect = g_value_get_double (value);
+      break;
+    case PROP_BLOB_ANGLE:
+      options->blob_angle = g_value_get_double (value);
+      break;
+    case PROP_COMPENSATION_HIST_SIZE:
+      options->compensation_hist_size = g_value_get_int (value);
+      break;
+    case PROP_COMPENSATE_AT_LAST:
+      options->compensate_at_last = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_ink2_options_get_property (GObject    *object,
+                               guint       property_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GimpInk2Options *options = GIMP_INK2_OPTIONS (object);
+
+  switch (property_id)
+    {
+    case PROP_SIZE:
+      g_value_set_double (value, options->size);
+      break;
+    case PROP_TILT_ANGLE:
+      g_value_set_double (value, options->tilt_angle);
+      break;
+    case PROP_SIZE_SENSITIVITY:
+      g_value_set_double (value, options->size_sensitivity);
+      break;
+    case PROP_VEL_SENSITIVITY:
+      g_value_set_double (value, options->vel_sensitivity);
+      break;
+    case PROP_TILT_SENSITIVITY:
+      g_value_set_double (value, options->tilt_sensitivity);
+      break;
+    case PROP_BLOB_TYPE:
+      g_value_set_enum (value, options->blob_type);
+      break;
+    case PROP_BLOB_ASPECT:
+      g_value_set_double (value, options->blob_aspect);
+      break;
+    case PROP_BLOB_ANGLE:
+      g_value_set_double (value, options->blob_angle);
+      break;
+    case PROP_COMPENSATION_HIST_SIZE:
+      g_value_set_int (value, options->compensation_hist_size);
+      break;
+    case PROP_COMPENSATE_AT_LAST:
+      g_value_set_boolean (value, options->compensate_at_last);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
diff -uNr gimp-2.2.17/app/paint/gimpink2options.h gimp-2.2.17-gpen-work/app/paint/gimpink2options.h
--- gimp-2.2.17/app/paint/gimpink2options.h	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/paint/gimpink2options.h	2007-08-17 00:12:39.000000000 +0900
@@ -0,0 +1,60 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef  __GIMP_INK2_OPTIONS_H__
+#define  __GIMP_INK2_OPTIONS_H__
+
+
+#include "gimppaintoptions.h"
+
+
+#define GIMP_TYPE_INK2_OPTIONS            (gimp_ink2_options_get_type ())
+#define GIMP_INK2_OPTIONS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_INK2_OPTIONS, GimpInk2Options))
+#define GIMP_INK2_OPTIONS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_INK2_OPTIONS, GimpInk2OptionsClass))
+#define GIMP_IS_INK2_OPTIONS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_INK2_OPTIONS))
+#define GIMP_IS_INK2_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_INK2_OPTIONS))
+#define GIMP_INK2_OPTIONS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_INK2_OPTIONS, GimpInk2OptionsClass))
+
+
+typedef struct _GimpInk2Options        GimpInk2Options;
+typedef struct _GimpPaintOptionsClass GimpInk2OptionsClass;
+
+struct _GimpInk2Options
+{
+  GimpPaintOptions  paint_options;
+
+  gdouble           size;
+  gdouble           tilt_angle;
+
+  gdouble           size_sensitivity;
+  gdouble           vel_sensitivity;
+  gdouble           tilt_sensitivity;
+
+  GimpInkBlobType   blob_type;
+  gdouble           blob_aspect;
+  gdouble           blob_angle;
+
+  gint              compensation_hist_size;
+  gboolean          compensate_at_last;
+};
+
+
+GType   gimp_ink2_options_get_type (void) G_GNUC_CONST;
+
+
+#endif  /*  __GIMP_INK2_OPTIONS_H__  */
バイナリー・ファイルgimp-2.2.17/app/tools/.gimpinktool2.c.swpとgimp-2.2.17-gpen-work/app/tools/.gimpinktool2.c.swpは違います
diff -uNr gimp-2.2.17/app/tools/Makefile.in gimp-2.2.17-gpen-work/app/tools/Makefile.in
--- gimp-2.2.17/app/tools/Makefile.in	2007-07-13 00:35:22.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/tools/Makefile.in	2007-08-16 15:38:03.000000000 +0900
@@ -85,7 +85,8 @@
 	gimptool.$(OBJEXT) gimptoolcontrol.$(OBJEXT) \
 	gimptooloptions-gui.$(OBJEXT) gimptransformoptions.$(OBJEXT) \
 	gimptransformtool.$(OBJEXT) gimptransformtool-undo.$(OBJEXT) \
-	gimpvectoroptions.$(OBJEXT) gimpvectortool.$(OBJEXT)
+	gimpvectoroptions.$(OBJEXT) gimpvectortool.$(OBJEXT) \
+	gimpinktool2.$(OBJEXT) gimpink2options-gui.$(OBJEXT)
 am_libapptools_a_OBJECTS = $(am__objects_1) $(am__objects_2)
 libapptools_a_OBJECTS = $(am_libapptools_a_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -583,7 +584,11 @@
 	gimpvectoroptions.c		\
 	gimpvectoroptions.h		\
 	gimpvectortool.c		\
-	gimpvectortool.h
+	gimpvectortool.h		\
+	gimpinktool2.c			\
+	gimpinktool2.h			\
+	gimpink2options-gui.c		\
+	gimpink2options-gui.h
 
 libapptools_a_built_sources = tools-enums.c
 libapptools_a_SOURCES = $(libapptools_a_built_sources) $(libapptools_a_sources)
diff -uNr gimp-2.2.17/app/tools/gimp-tools.c gimp-2.2.17-gpen-work/app/tools/gimp-tools.c
--- gimp-2.2.17/app/tools/gimp-tools.c	2007-04-18 06:09:50.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/tools/gimp-tools.c	2007-08-16 15:36:46.000000000 +0900
@@ -73,6 +73,7 @@
 #include "gimpsmudgetool.h"
 #include "gimptexttool.h"
 #include "gimpvectortool.h"
+#include "gimpinktool2.h"
 
 #include "gimp-intl.h"
 
@@ -127,6 +128,7 @@
     gimp_blend_tool_register,
     gimp_bucket_fill_tool_register,
     gimp_text_tool_register,
+    gimp_ink2_tool_register,
 
     /*  transform tools  */
 
@@ -437,6 +439,10 @@
     {
       paint_core_name = "GimpInk";
     }
+  else if (tool_type == GIMP_TYPE_INK2_TOOL)
+    {
+      paint_core_name = "GimpInk2";
+    }
   else
     {
       paint_core_name = "GimpPaintbrush";
diff -uNr gimp-2.2.17/app/tools/gimpink2options-gui.c gimp-2.2.17-gpen-work/app/tools/gimpink2options-gui.c
--- gimp-2.2.17/app/tools/gimpink2options-gui.c	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/tools/gimpink2options-gui.c	2007-08-17 01:24:07.000000000 +0900
@@ -0,0 +1,226 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#include "config/gimpconfig-utils.h"
+
+#include "paint/gimpink2options.h"
+#include "paint/gimpink2.h"
+
+#include "widgets/gimpblobeditor.h"
+#include "widgets/gimppropwidgets.h"
+
+#include "gimpink2options-gui.h"
+#include "gimppaintoptions-gui.h"
+
+#include "gimp-intl.h"
+
+
+static GtkWidget * blob_image_new  (GimpInkBlobType  blob_type);
+
+
+GtkWidget *
+gimp_ink2_options_gui (GimpToolOptions *tool_options)
+{
+  GObject        *config      = G_OBJECT (tool_options);
+  GimpInk2Options *ink_options = GIMP_INK2_OPTIONS (tool_options);
+  GtkWidget      *table;
+  GtkWidget      *vbox;
+  GtkWidget      *blob_vbox;
+  GtkWidget      *hbox;
+  GtkWidget      *frame;
+  GtkWidget      *editor;
+  GtkObject      *adj;
+  GtkWidget      *compensate_box;
+  GtkWidget      *compensate_vbox;
+  GtkWidget      *checkbox;
+
+  vbox = gimp_paint_options_gui (tool_options);
+
+  /* adjust sliders */
+  frame = gimp_frame_new (_("Adjustment"));
+  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  table = gtk_table_new (2, 3, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+  gtk_container_add (GTK_CONTAINER (frame), table);
+  gtk_widget_show (table);
+
+  /*  size slider  */
+  adj = gimp_prop_scale_entry_new (config, "size",
+                                   GTK_TABLE (table), 0, 0,
+                                   _("Size:"),
+                                   1.0, 2.0, 1,
+                                   FALSE, 0.0, 0.0);
+  gimp_scale_entry_set_logarithmic (adj, TRUE);
+
+  /* angle adjust slider */
+  gimp_prop_scale_entry_new (config, "tilt-angle",
+                             GTK_TABLE (table), 0, 1,
+                             _("Angle:"),
+                             1.0, 10.0, 1,
+                             FALSE, 0.0, 0.0);
+
+  /* sens sliders */
+  frame = gimp_frame_new (_("Sensitivity"));
+  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  table = gtk_table_new (3, 3, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+  gtk_container_add (GTK_CONTAINER (frame), table);
+  gtk_widget_show (table);
+
+  /* size sens slider */
+  gimp_prop_scale_entry_new (config, "size-sensitivity",
+                             GTK_TABLE (table), 0, 0,
+                             _("Size:"),
+                             0.01, 0.1, 1,
+                             FALSE, 0.0, 0.0);
+
+  /* tilt sens slider */
+  gimp_prop_scale_entry_new (config, "tilt-sensitivity",
+                             GTK_TABLE (table), 0, 1,
+                             _("Tilt:"),
+                             0.01, 0.1, 1,
+                             FALSE, 0.0, 0.0);
+
+  /* velocity sens slider */
+  gimp_prop_scale_entry_new (config, "vel-sensitivity",
+                             GTK_TABLE (table), 0, 2,
+                             _("Speed:"),
+                             0.01, 0.1, 1,
+                             FALSE, 0.0, 0.0);
+
+  /* compensate at last checkbox */
+  compensate_box = gtk_frame_new (_("Pointer Adjustment"));
+  gtk_box_pack_start (GTK_BOX (vbox), compensate_box, FALSE, TRUE, 0);
+  gtk_widget_show(compensate_box);
+  compensate_vbox = gtk_vbox_new (FALSE, 2);
+  gtk_container_add (GTK_CONTAINER (compensate_box), compensate_vbox);
+  gtk_widget_show (compensate_vbox);
+
+  table = gtk_table_new (2, 3, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+  gtk_box_pack_start (GTK_VBOX (compensate_vbox), table, TRUE, TRUE, 0);
+  gtk_widget_show (table);
+  /* compensation history size slider */
+  gimp_prop_scale_entry_new (config, "compensation-history-size",
+                             GTK_TABLE (table), 0, 0,
+                             _("History:"),
+                             1, 1, 0,
+                             FALSE, 1.0, INK2_HISTORY_BUFFER);
+
+ checkbox = 
+    gimp_prop_check_button_new (config, "compensate-at-last",
+                               _("Draw pen line to finished point:"));
+  gtk_box_pack_start (GTK_VBOX (compensate_vbox), checkbox, FALSE, FALSE, 0);
+  gtk_widget_show(checkbox);
+
+  /*  bottom hbox */
+  hbox = gtk_hbox_new (FALSE, 2);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  gtk_widget_show (hbox);
+
+  /* Blob type radiobuttons */
+  frame = gimp_prop_enum_radio_frame_new (config, "blob-type",
+                                          _("Type"), 0, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  {
+    GList           *children;
+    GList           *list;
+    GimpInkBlobType  blob_type;
+
+    children =
+      gtk_container_get_children (GTK_CONTAINER (GTK_BIN (frame)->child));
+
+    for (list = children, blob_type = GIMP_INK_BLOB_TYPE_ELLIPSE;
+         list;
+         list = g_list_next (list), blob_type++)
+      {
+        GtkWidget *radio = GTK_WIDGET (list->data);
+        GtkWidget *blob;
+
+        gtk_container_remove (GTK_CONTAINER (radio), GTK_BIN (radio)->child);
+
+        blob = blob_image_new (blob_type);
+        gtk_container_add (GTK_CONTAINER (radio), blob);
+        gtk_widget_show (blob);
+      }
+
+    g_list_free (children);
+  }
+
+  /* Blob shape widget */
+  frame = gimp_frame_new (_("Shape"));
+  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  blob_vbox = gtk_vbox_new (FALSE, 2);
+  gtk_container_add (GTK_CONTAINER (frame), blob_vbox);
+  gtk_widget_show (blob_vbox);
+
+  frame = gtk_aspect_frame_new (NULL, 0.0, 0.5, 1.0, FALSE);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+  gtk_box_pack_start (GTK_BOX (blob_vbox), frame, TRUE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  editor = gimp_blob_editor_new (ink_options->blob_type,
+                                 ink_options->blob_aspect,
+                                 ink_options->blob_angle);
+  gtk_widget_set_size_request (editor, 60, 60);
+  gtk_container_add (GTK_CONTAINER (frame), editor);
+  gtk_widget_show (editor);
+
+  gimp_config_connect (config, G_OBJECT (editor), NULL);
+
+  return vbox;
+}
+
+static GtkWidget *
+blob_image_new (GimpInkBlobType blob_type)
+{
+  const guchar *stock_id = NULL;
+
+  switch (blob_type)
+    {
+    case GIMP_INK_BLOB_TYPE_ELLIPSE:
+      stock_id = GIMP_STOCK_SHAPE_CIRCLE;
+      break;
+
+    case GIMP_INK_BLOB_TYPE_SQUARE:
+      stock_id = GIMP_STOCK_SHAPE_SQUARE;
+      break;
+
+    case GIMP_INK_BLOB_TYPE_DIAMOND:
+      stock_id = GIMP_STOCK_SHAPE_DIAMOND;
+      break;
+    }
+
+  return gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+}
diff -uNr gimp-2.2.17/app/tools/gimpink2options-gui.h gimp-2.2.17-gpen-work/app/tools/gimpink2options-gui.h
--- gimp-2.2.17/app/tools/gimpink2options-gui.h	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/tools/gimpink2options-gui.h	2007-08-16 15:34:15.000000000 +0900
@@ -0,0 +1,26 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef  __GIMP_INK2_OPTIONS_GUI_H__
+#define  __GIMP_INK2_OPTIONS_GUI_H__
+
+
+GtkWidget * gimp_ink2_options_gui      (GimpToolOptions *tool_options);
+
+
+#endif  /*  __GIMP_INK2_OPTIONS_GUI_H__  */
diff -uNr gimp-2.2.17/app/tools/gimpinktool2.c gimp-2.2.17-gpen-work/app/tools/gimpinktool2.c
--- gimp-2.2.17/app/tools/gimpinktool2.c	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/tools/gimpinktool2.c	2007-08-17 01:26:02.000000000 +0900
@@ -0,0 +1,130 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#include "paint/gimpink2options.h"
+
+#include "widgets/gimphelp-ids.h"
+
+#include "gimpink2options-gui.h"
+#include "gimpinktool2.h"
+#include "gimptoolcontrol.h"
+
+#include "gimp-intl.h"
+
+
+static void   gimp_ink2_tool_init          (GimpInk2Tool      *tool);
+static void   gimp_ink2_tool_class_init    (GimpInk2ToolClass *klass);
+
+static void   gimp_ink2_tool_cursor_update (GimpTool         *tool,
+                                           GimpCoords       *coords,
+                                           GdkModifierType   state,
+                                           GimpDisplay      *gdisp);
+
+
+static GimpPaintToolClass *parent_class = NULL;
+
+
+void
+gimp_ink2_tool_register (GimpToolRegisterCallback  callback,
+                        gpointer                  data)
+{
+  (* callback) (GIMP_TYPE_INK2_TOOL,
+                GIMP_TYPE_INK2_OPTIONS,
+                gimp_ink2_options_gui,
+                GIMP_CONTEXT_FOREGROUND_MASK |
+                GIMP_CONTEXT_BACKGROUND_MASK |
+                GIMP_CONTEXT_OPACITY_MASK    |
+                GIMP_CONTEXT_PAINT_MODE_MASK,
+                "gimp-ink2-tool",
+                _("G-pen"),
+                _("Draw in G-pen -2-"),
+                N_("G-pen"), "G",
+                NULL, GIMP_HELP_TOOL_INK,
+                GIMP_STOCK_TOOL_INK,
+                data);
+}
+
+GType
+gimp_ink2_tool_get_type (void)
+{
+  static GType tool_type = 0;
+
+  if (! tool_type)
+    {
+      static const GTypeInfo tool_info =
+      {
+        sizeof (GimpInk2ToolClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gimp_ink2_tool_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data     */
+        sizeof (GimpInk2Tool),
+        0,              /* n_preallocs    */
+        (GInstanceInitFunc) gimp_ink2_tool_init,
+      };
+
+      tool_type = g_type_register_static (GIMP_TYPE_PAINT_TOOL,
+                                          "GimpInk2Tool",
+                                          &tool_info, 0);
+    }
+
+  return tool_type;
+}
+
+static void
+gimp_ink2_tool_class_init (GimpInk2ToolClass *klass)
+{
+  GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  tool_class->cursor_update = gimp_ink2_tool_cursor_update;
+}
+
+static void
+gimp_ink2_tool_init (GimpInk2Tool *ink_tool)
+{
+  GimpTool *tool = GIMP_TOOL (ink_tool);
+
+  gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_INK);
+
+  gimp_paint_tool_enable_color_picker (GIMP_PAINT_TOOL (ink_tool),
+                                       GIMP_COLOR_PICK_MODE_FOREGROUND);
+}
+
+static void
+gimp_ink2_tool_cursor_update (GimpTool         *tool,
+                             GimpCoords       *coords,
+                             GdkModifierType   state,
+                             GimpDisplay      *gdisp)
+{
+  GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool);
+
+  paint_tool->show_cursor = TRUE;
+
+  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
+}
diff -uNr gimp-2.2.17/app/tools/gimpinktool2.h gimp-2.2.17-gpen-work/app/tools/gimpinktool2.h
--- gimp-2.2.17/app/tools/gimpinktool2.h	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.2.17-gpen-work/app/tools/gimpinktool2.h	2007-08-16 15:33:55.000000000 +0900
@@ -0,0 +1,54 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef  __GIMP_INK2_TOOL_H__
+#define  __GIMP_INK2_TOOL_H__
+
+
+#include "gimppainttool.h"
+
+
+#define GIMP_TYPE_INK2_TOOL            (gimp_ink2_tool_get_type ())
+#define GIMP_INK2_TOOL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_INK2_TOOL, GimpInk2Tool))
+#define GIMP_INK2_TOOL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_INK2_TOOL, GimpInk2ToolClass))
+#define GIMP_IS_INK2_TOOL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_INK2_TOOL))
+#define GIMP_IS_INK2_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_INK2_TOOL))
+#define GIMP_INK2_TOOL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_INK2_TOOL, GimpInk2ToolClass))
+
+
+typedef struct _GimpInk2Tool      GimpInk2Tool;
+typedef struct _GimpInk2ToolClass GimpInk2ToolClass;
+
+struct _GimpInk2Tool
+{
+  GimpPaintTool parent_instance;
+};
+
+struct _GimpInk2ToolClass
+{
+  GimpPaintToolClass parent_class;
+};
+
+
+void    gimp_ink2_tool_register (GimpToolRegisterCallback  callback,
+                                gpointer                  data);
+
+GType   gimp_ink2_tool_get_type (void) G_GNUC_CONST;
+
+
+#endif  /*  __GIMP_INK2_TOOL_H__  */
