diff options
Diffstat (limited to 'doc/tutorial/src/cairo-tutorial-xlib.h')
-rw-r--r-- | doc/tutorial/src/cairo-tutorial-xlib.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/doc/tutorial/src/cairo-tutorial-xlib.h b/doc/tutorial/src/cairo-tutorial-xlib.h new file mode 100644 index 00000000..301b9524 --- /dev/null +++ b/doc/tutorial/src/cairo-tutorial-xlib.h @@ -0,0 +1,219 @@ +/* cairo-tutorial-xlib.h - a tutorial framework for cairo with xlib + * + * Copyright © 2005, Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <strings.h> +#include <X11/Xos.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <cairo.h> +#include <cairo-xlib.h> + +#ifndef WIDTH +#define WIDTH 400 +#endif + +#ifndef HEIGHT +#define HEIGHT 400 +#endif + +#ifndef DEFAULT_VISUAL +#define DEFAULT_VISUAL 0 +#endif + +static void +Usage (char *program) +{ + fprintf (stderr, "Usage: %s\n", program); + fprintf (stderr, "\t-display <display-name>\n"); + fprintf (stderr, "\t-geometry <geometry>\n"); + exit (1); +} + +char *dpy_name; +VisualID vid = DEFAULT_VISUAL; +Colormap colormap; +Visual *visual; +int depth; +unsigned int width = WIDTH, height = HEIGHT; + +static void +draw (cairo_t *cr); + +static void +handle_expose (Display *dpy, Drawable d) +{ + cairo_surface_t *surface; + cairo_t *cr; + + surface = cairo_xlib_surface_create (dpy, d, visual, + width, height); + cr = cairo_create (surface); + + draw (cr); + + cairo_destroy (cr); + cairo_surface_destroy (surface); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + Display *dpy; + Window win; + Window root = 0; + char **init_argv = argv; + XSetWindowAttributes attr; + int scr; + int x = 0, y = 0; + int geometryMask; + int border_width = 1; + XSizeHints sizeHints; + XWMHints wmHints; + XClassHint classHints; + XEvent ev; + XEvent eev; + int HasExpose = 0; + int sync = 0; + XTextProperty wm_name, icon_name; + Atom wm_delete_window; + unsigned long gc_mask; + char quit_string[10]; + unsigned long window_mask; + int has_colormap = 0; + + wm_name.value = (unsigned char *) argv[0]; + wm_name.encoding = XA_STRING; + wm_name.format = 8; + wm_name.nitems = strlen (argv[0]) + 1; + icon_name = wm_name; + gc_mask = 0; + while (*++argv) { + if (!strcmp (*argv, "-display")) + dpy_name = *++argv; + else if (!strcmp (*argv, "-visual")) + vid = strtol(*++argv, NULL, 0); + else if (!strcmp (*argv, "-geometry")) + geometryMask = XParseGeometry (*++argv, &x, &y, &width, &height); + else if (!strcmp (*argv, "-sync")) + sync = 1; + else if (!strcmp (*argv, "-bw")) + border_width = strtol(*++argv, NULL, 0); + else if (!strcmp (*argv, "-root")) + root = strtol (*++argv, NULL, 0); + else + Usage (*init_argv); + } + sizeHints.flags = 0; + wmHints.flags = InputHint; + wmHints.input = True; + classHints.res_name = init_argv[0]; + classHints.res_class = init_argv[0]; + dpy = XOpenDisplay (dpy_name); + if (!dpy) { + fprintf (stderr, "Error: failed to open display: %s\n", + XDisplayName (dpy_name)); + exit (1); + } + if (sync) + XSynchronize (dpy, sync); + scr = DefaultScreen (dpy); + if (!root) + root = RootWindow (dpy, scr); + window_mask = CWBackPixel|CWBorderPixel|CWEventMask; + if (!has_colormap) + colormap = DefaultColormap (dpy, scr); + else + { + window_mask |= CWColormap; + attr.colormap = colormap; + } + visual = DefaultVisual (dpy, scr); + depth = DefaultDepth (dpy, scr); + if (vid) + { + XVisualInfo vi, *vi_ret; + int n; + + vi.visualid = vid; + vi.screen = scr; + vi_ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask, + &vi, &n); + if (vi_ret) + { + visual = vi_ret->visual; + if (!has_colormap) + { + colormap = XCreateColormap (dpy, root, visual, AllocNone); + window_mask |= CWColormap; + attr.colormap = colormap; + } + depth = vi_ret->depth; + } + } + attr.background_pixel = WhitePixel (dpy, scr); + attr.border_pixel = 0; + attr.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask; + wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + win = XCreateWindow (dpy, root, x, y, width, height, border_width, + depth, InputOutput, + visual, + window_mask, + &attr); + XSetWMProperties (dpy, win, + &wm_name, &icon_name, + init_argv, argc, + &sizeHints, &wmHints, 0); + XSetWMProtocols (dpy, win, &wm_delete_window, 1); + XMapWindow (dpy, win); + for (;;) { + XNextEvent (dpy, &ev); + if (HasExpose && ev.type != Expose) { + HasExpose = 0; + handle_expose (dpy, eev.xexpose.window); + } + switch (ev.type) { + case Expose: + if (QLength(dpy)) { + eev = ev; + HasExpose = 1; + } else if (ev.xexpose.count == 0) { + handle_expose (dpy, ev.xexpose.window); + } + break; + case KeyPress: + if (XLookupString ((XKeyEvent *) &ev, quit_string, sizeof (quit_string), 0, 0) == 1) { + switch (quit_string[0]) { + case 'q': + exit (0); + case 'c': + XClearArea (dpy, ev.xkey.window, 0, 0, 0, 0, True); + break; + } + } + break; + case ClientMessage: + exit (0); + } + } +} |