1 /* cairo-tutorial-xlib.h - a tutorial framework for cairo with xlib
3 * Copyright © 2005, Keith Packard
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.
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.
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.
25 #include <X11/Xutil.h>
26 #include <X11/Xatom.h>
28 #include <cairo-xlib.h>
38 #ifndef DEFAULT_VISUAL
39 #define DEFAULT_VISUAL 0
45 fprintf (stderr, "Usage: %s\n", program);
46 fprintf (stderr, "\t-display <display-name>\n");
47 fprintf (stderr, "\t-geometry <geometry>\n");
52 VisualID vid = DEFAULT_VISUAL;
56 unsigned int width = WIDTH, height = HEIGHT;
62 draw (cairo_t *cr, int width, int height);
65 draw_to_pixmap (Display *dpy, Pixmap pix)
67 cairo_surface_t *surface;
70 surface = cairo_xlib_surface_create (dpy, pix, visual,
72 cr = cairo_create (surface);
74 draw (cr, width, height);
77 cairo_surface_destroy (surface);
81 handle_configure (Display *dpy, XConfigureEvent *cev)
86 XFreePixmap(dpy, pix);
87 pix = XCreatePixmap(dpy, win, width, height, depth);
88 XFillRectangle(dpy, pix, gc, 0, 0, width, height);
89 draw_to_pixmap (dpy, pix);
93 handle_expose (Display *dpy, XExposeEvent *eev)
95 XCopyArea (dpy, pix, win, gc,
97 eev->width, eev->height,
108 char **init_argv = argv;
109 XSetWindowAttributes attr;
113 int border_width = 1;
114 XSizeHints sizeHints;
116 XClassHint classHints;
121 XTextProperty wm_name, icon_name;
122 Atom wm_delete_window;
123 unsigned long gc_mask;
125 char quit_string[10];
126 unsigned long window_mask;
127 int has_colormap = 0;
129 wm_name.value = (unsigned char *) argv[0];
130 wm_name.encoding = XA_STRING;
132 wm_name.nitems = strlen (argv[0]) + 1;
136 if (!strcmp (*argv, "-display"))
138 else if (!strcmp (*argv, "-visual"))
139 vid = strtol(*++argv, NULL, 0);
140 else if (!strcmp (*argv, "-geometry"))
141 geometryMask = XParseGeometry (*++argv, &x, &y, &width, &height);
142 else if (!strcmp (*argv, "-sync"))
144 else if (!strcmp (*argv, "-bw"))
145 border_width = strtol(*++argv, NULL, 0);
146 else if (!strcmp (*argv, "-root"))
147 root = strtol (*++argv, NULL, 0);
152 wmHints.flags = InputHint;
153 wmHints.input = True;
154 classHints.res_name = init_argv[0];
155 classHints.res_class = init_argv[0];
156 dpy = XOpenDisplay (dpy_name);
158 fprintf (stderr, "Error: failed to open display: %s\n",
159 XDisplayName (dpy_name));
163 XSynchronize (dpy, sync);
164 scr = DefaultScreen (dpy);
166 root = RootWindow (dpy, scr);
167 window_mask = CWBackPixel|CWBorderPixel|CWEventMask;
169 colormap = DefaultColormap (dpy, scr);
172 window_mask |= CWColormap;
173 attr.colormap = colormap;
175 visual = DefaultVisual (dpy, scr);
176 depth = DefaultDepth (dpy, scr);
179 XVisualInfo vi, *vi_ret;
184 vi_ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask,
188 visual = vi_ret->visual;
191 colormap = XCreateColormap (dpy, root, visual, AllocNone);
192 window_mask |= CWColormap;
193 attr.colormap = colormap;
195 depth = vi_ret->depth;
198 attr.background_pixel = WhitePixel (dpy, scr);
199 attr.border_pixel = 0;
200 attr.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask;
201 wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
202 win = XCreateWindow (dpy, root, x, y, width, height, border_width,
207 pix = XCreatePixmap (dpy, win, width, height, depth);
208 gcv.foreground = WhitePixel (dpy, scr);
209 gc = XCreateGC (dpy, pix, GCForeground, &gcv);
210 XFillRectangle(dpy, pix, gc, 0, 0, width, height);
211 draw_to_pixmap (dpy, pix);
212 XSetWMProperties (dpy, win,
213 &wm_name, &icon_name,
215 &sizeHints, &wmHints, 0);
216 XSetWMProtocols (dpy, win, &wm_delete_window, 1);
217 XMapWindow (dpy, win);
219 XNextEvent (dpy, &ev);
220 if (HasExpose && ev.type != Expose) {
222 handle_expose (dpy, &eev.xexpose);
225 case ConfigureNotify:
226 handle_configure (dpy, &ev.xconfigure);
232 } else if (ev.xexpose.count == 0) {
233 handle_expose (dpy, &ev.xexpose);
237 if (XLookupString ((XKeyEvent *) &ev, quit_string, sizeof (quit_string), 0, 0) == 1) {
238 switch (quit_string[0]) {
242 XClearArea (dpy, ev.xkey.window, 0, 0, 0, 0, True);