60516a3562114d5af1f46376b21e603c2f94f1a1
[framework/graphics/cairo.git] / doc / tutorial / src / include / cairo-tutorial-gtk.h
1 /* cairo-tutorial-gtk.h - a tutorial framework for cairo with gtk+
2  *
3  * Copyright © 2005, Carl Worth
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
17  */
18
19 #include <gtk/gtk.h>
20 #include <gdk/gdkkeysyms.h>
21
22 #include <cairo.h>
23
24 #ifndef WIDTH
25 #define WIDTH 400
26 #endif
27
28 #ifndef HEIGHT
29 #define HEIGHT 400
30 #endif
31
32 static void
33 draw (cairo_t *cr, int width, int height);
34
35 #if ! GTK_CHECK_VERSION(2,7,0)
36 /* copied from gtk+/gdk/gdkcairo.c and gtk+/gdk/x11/gdkdrawable-x11.c
37  * gdk_cairo_create() which is available in 2.7.0 and later.
38  */
39 static cairo_t *
40 gdk_cairo_create (GdkDrawable *drawable)
41 {
42     int width, height;
43     cairo_t *cr = NULL;
44     cairo_surface_t *surface = NULL;
45     GdkVisual *visual = gdk_drawable_get_visual (drawable);
46
47     gdk_drawable_get_size (drawable, &width, &height);
48     if (visual)
49         surface = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable),
50                                              GDK_DRAWABLE_XID (drawable),
51                                              GDK_VISUAL_XVISUAL (visual),
52                                              width, height);
53     else if (gdk_drawable_get_depth (drawable) == 1)
54         surface = cairo_xlib_surface_create_for_bitmap
55             (GDK_PIXMAP_XDISPLAY (drawable),
56              GDK_PIXMAP_XID (drawable),
57              GDK_SCREEN_XSCREEN (gdk_drawable_get_screen (drawable)),
58              width, height);
59     else {
60         g_warning ("Using Cairo rendering requires the drawable argument to\n"
61                    "have a specified colormap. All windows have a colormap,\n"
62                    "however, pixmaps only have colormap by default if they\n"
63                    "were created with a non-NULL window argument. Otherwise\n"
64                    "a colormap must be set on them with "
65                    "gdk_drawable_set_colormap");
66         return NULL;
67     }
68     if (surface) {
69         cr = cairo_create (surface);
70         cairo_surface_destroy (surface);
71     }
72     return cr;
73 }
74 #endif
75
76 static gboolean
77 handle_expose (GtkWidget      *widget,
78                GdkEventExpose *event,
79                gpointer        data)
80 {
81     cairo_t *cr;
82
83     cr = gdk_cairo_create (widget->window);
84
85     draw (cr, widget->allocation.width, widget->allocation.height);
86
87     cairo_destroy (cr);
88
89     return FALSE;
90 }
91
92 static gboolean
93 handle_key_press (GtkWidget *widget,
94                   GdkEventKey *event,
95                   gpointer data)
96 {
97     if ((event->keyval == GDK_Q ||
98          event->keyval == GDK_q) && (event->state & GDK_CONTROL_MASK))
99         gtk_main_quit ();
100
101     return FALSE;
102 }
103
104 int
105 main (int argc, char **argv)
106 {
107     GtkWidget *window, *drawing_area;
108
109     gtk_init (&argc, &argv);
110
111     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
112
113     gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
114     gtk_window_set_title (GTK_WINDOW (window), "cairo demo");
115
116     g_signal_connect (window, "destroy",
117                       G_CALLBACK (gtk_main_quit), NULL);
118
119     drawing_area = gtk_drawing_area_new ();
120     gtk_container_add (GTK_CONTAINER (window), drawing_area);
121
122     g_signal_connect (drawing_area, "expose-event",
123                       G_CALLBACK (handle_expose), NULL);
124
125     g_signal_connect (window, "key-press-event",
126                       G_CALLBACK (handle_key_press), NULL);
127
128     gtk_widget_show_all (window);
129
130     gtk_main ();
131
132     return 0;
133 }