diff --git a/c/gtk3/texture/texture.c b/c/gtk3/texture/texture.c
new file mode 100644
index 0000000..2e4a901
--- /dev/null
+++ b/c/gtk3/texture/texture.c
@@ -0,0 +1,79 @@
+#include <math.h>
+#include <gtk/gtk.h>
+
+
+GtkWidget *window;
+cairo_surface_t *surface;
+cairo_t *context;
+
+double mouse_x = 0.0;
+double mouse_y = 0.0;
+
+
+void line(double x1, double y1, double x2, double y2) {
+  cairo_set_source_rgba(context, 0, 0, 0, 1);
+  cairo_set_line_width(context, 1.0);
+  cairo_set_line_cap(context, CAIRO_LINE_CAP_ROUND);
+  for(int col = -10; col <= 10; ++col) {
+    for(int row = -10; row <= 10; ++row) {
+      cairo_move_to(context, x1 + col*200.0, y1 + row*200.0);
+      cairo_line_to(context, x2 + col*200.0, y2 + row*200.0);
+    }
+  }
+  cairo_stroke(context);
+}
+
+gboolean motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) {
+  if (event->state & GDK_BUTTON1_MASK) {
+    line(mouse_x, mouse_y, event->x, event->y);
+    cairo_surface_flush(surface);
+    gtk_widget_queue_draw(window);
+  }
+
+  if (event->state & GDK_BUTTON3_MASK) {
+    cairo_save(context);
+    cairo_set_operator(context, CAIRO_OPERATOR_CLEAR);
+    cairo_paint(context);
+    cairo_restore(context);
+    cairo_surface_flush(surface);
+    gtk_widget_queue_draw(window);
+  }
+
+  mouse_x = event->x;
+  mouse_y = event->y;
+  return TRUE;
+}
+
+gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
+  cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1);
+  cairo_paint(cr);
+  cairo_set_source_surface(cr, surface, 0, 0);
+  cairo_paint(cr);
+  return TRUE;
+}
+
+void activate(GtkApplication* app, gpointer data) {
+  window = gtk_application_window_new(app);
+  g_signal_connect(window, "draw", G_CALLBACK(draw), NULL);
+  g_signal_connect(window, "motion-notify-event", G_CALLBACK(motion), NULL);
+  gtk_widget_add_events(window, GDK_POINTER_MOTION_MASK);
+  gtk_window_set_default_size(
+    GTK_WINDOW(window),
+    cairo_image_surface_get_width(surface),
+    cairo_image_surface_get_height(surface) );
+  gtk_widget_show_all(window);
+}
+
+int main(int argc, char **argv) {
+  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 700, 500);
+  context = cairo_create(surface);
+
+  GtkApplication *application = gtk_application_new(NULL, 0);
+  g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
+  int status = g_application_run(G_APPLICATION(application), argc, argv);
+  g_object_unref(application);
+
+  cairo_destroy(context);
+  cairo_surface_destroy(surface);
+  return status;
+}