mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-12-25 04:06:03 +00:00
4d1d328de9
git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky@5 7f574dfc-610e-0410-a909-a81674777703
231 lines
5.3 KiB
C
231 lines
5.3 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/* Small example demonstrating emulating knockout-groups as in PDF-1.4
|
|
* using cairo_set_operator().
|
|
*
|
|
* Owen Taylor,
|
|
|
|
* v0.1 30 November 2002
|
|
* v0.2 1 December 2002 - typo fixes from Keith Packard
|
|
* v0.3 17 April 2003 - Tracking changes in Xr, (Removal of Xr{Push,Pop}Group)
|
|
* v0.4 29 September 2003 - Use cairo_rectangle rather than private rect_path
|
|
* Use cairo_arc for oval_path
|
|
* Keeping log of changes in ChangeLog/CVS now. (2003-11-19) Carl Worth
|
|
*/
|
|
#include "conky.h"
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <cairo.h>
|
|
#include <cairo-xlib.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
|
|
/* Fill the given area with checks in the standard style
|
|
* for showing compositing effects.
|
|
*/
|
|
static void
|
|
fill_checks (cairo_t *cr,
|
|
int x, int y,
|
|
int width, int height)
|
|
{
|
|
cairo_surface_t *check;
|
|
cairo_pattern_t *check_pattern;
|
|
|
|
cairo_save (cr);
|
|
|
|
#define CHECK_SIZE 32
|
|
|
|
check = cairo_surface_create_similar (cairo_current_target_surface (cr),
|
|
CAIRO_FORMAT_RGB24,
|
|
2 * CHECK_SIZE, 2 * CHECK_SIZE);
|
|
cairo_surface_set_repeat (check, 1);
|
|
|
|
/* Draw the check */
|
|
{
|
|
cairo_save (cr);
|
|
|
|
cairo_set_target_surface (cr, check);
|
|
|
|
cairo_set_operator (cr, CAIRO_OPERATOR_SRC);
|
|
|
|
cairo_set_rgb_color (cr, 0.4, 0.4, 0.4);
|
|
|
|
cairo_rectangle (cr, 0, 0, 2 * CHECK_SIZE, 2 * CHECK_SIZE);
|
|
cairo_fill (cr);
|
|
|
|
cairo_set_rgb_color (cr, 0.7, 0.7, 0.7);
|
|
|
|
cairo_rectangle (cr, x, y, CHECK_SIZE, CHECK_SIZE);
|
|
cairo_fill (cr);
|
|
cairo_rectangle (cr, x + CHECK_SIZE, y + CHECK_SIZE, CHECK_SIZE, CHECK_SIZE);
|
|
cairo_fill (cr);
|
|
|
|
cairo_restore (cr);
|
|
}
|
|
|
|
/* Fill the whole surface with the check */
|
|
|
|
check_pattern = cairo_pattern_create_for_surface (check);
|
|
cairo_set_pattern (cr, check_pattern);
|
|
cairo_rectangle (cr, 0, 0, width, height);
|
|
cairo_fill (cr);
|
|
|
|
cairo_pattern_destroy (check_pattern);
|
|
cairo_surface_destroy (check);
|
|
|
|
cairo_restore (cr);
|
|
}
|
|
|
|
static void draw_pee (cairo_t *cr, double xc, double yc)
|
|
{
|
|
cairo_set_rgb_color (cr, 0, 0, 0);
|
|
cairo_show_text (cr, "Conky");
|
|
}
|
|
|
|
static void
|
|
draw (cairo_t *cr,
|
|
int width,
|
|
int height)
|
|
{
|
|
cairo_surface_t *overlay;
|
|
|
|
/* Fill the background */
|
|
double xc = width / 2.;
|
|
double yc = height / 2.;
|
|
|
|
overlay = cairo_surface_create_similar (cairo_current_target_surface (cr),
|
|
CAIRO_FORMAT_ARGB32,
|
|
width, height);
|
|
if (overlay == NULL)
|
|
return;
|
|
|
|
fill_checks (cr, 0, 0, width, height);
|
|
|
|
cairo_save (cr);
|
|
cairo_set_target_surface (cr, overlay);
|
|
|
|
cairo_set_alpha (cr, 0.5);
|
|
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
|
draw_pee (cr, xc, yc);
|
|
|
|
cairo_restore (cr);
|
|
|
|
cairo_show_surface (cr, overlay, width, height);
|
|
|
|
cairo_surface_destroy (overlay);
|
|
}
|
|
|
|
int
|
|
do_it (void)
|
|
{
|
|
Display *dpy;
|
|
int screen;
|
|
Window w;
|
|
Pixmap pixmap;
|
|
char *title = "cairo: Knockout Groups";
|
|
unsigned int quit_keycode;
|
|
int needs_redraw;
|
|
GC gc;
|
|
XWMHints *wmhints;
|
|
XSizeHints *normalhints;
|
|
XClassHint *classhint;
|
|
|
|
int width = 400;
|
|
int height = 400;
|
|
|
|
dpy = XOpenDisplay (NULL);
|
|
screen = DefaultScreen (dpy);
|
|
|
|
w = XCreateSimpleWindow (dpy, RootWindow (dpy, screen),
|
|
0, 0, width, height, 0,
|
|
BlackPixel (dpy, screen), WhitePixel (dpy, screen));
|
|
|
|
normalhints = XAllocSizeHints ();
|
|
normalhints->flags = 0;
|
|
normalhints->x = 0;
|
|
normalhints->y = 0;
|
|
normalhints->width = width;
|
|
normalhints->height = height;
|
|
|
|
classhint = XAllocClassHint ();
|
|
classhint->res_name = "cairo-knockout";
|
|
classhint->res_class = "Cairo-knockout";
|
|
|
|
wmhints = XAllocWMHints ();
|
|
wmhints->flags = InputHint;
|
|
wmhints->input = True;
|
|
|
|
XmbSetWMProperties (dpy, w, title, "cairo-knockout", 0, 0,
|
|
normalhints, wmhints, classhint);
|
|
XFree (wmhints);
|
|
XFree (classhint);
|
|
XFree (normalhints);
|
|
|
|
pixmap = XCreatePixmap (dpy, w, width, height, DefaultDepth (dpy, screen));
|
|
gc = XCreateGC (dpy, pixmap, 0, NULL);
|
|
|
|
quit_keycode = XKeysymToKeycode(dpy, XStringToKeysym("Q"));
|
|
|
|
XSelectInput (dpy, w, ExposureMask | StructureNotifyMask | ButtonPressMask | KeyPressMask);
|
|
XMapWindow (dpy, w);
|
|
|
|
needs_redraw = 1;
|
|
|
|
while (1) {
|
|
XEvent xev;
|
|
|
|
/* Only do the redraw if there are no events pending. This
|
|
* avoids us getting behind doing several redraws for several
|
|
* consecutive resize events for example.
|
|
*/
|
|
if (!XPending (dpy) && needs_redraw) {
|
|
cairo_t *cr = cairo_create ();
|
|
|
|
cairo_set_target_drawable (cr, dpy, pixmap);
|
|
|
|
draw (cr, width, height);
|
|
|
|
cairo_destroy (cr);
|
|
|
|
XCopyArea (dpy, pixmap, w, gc,
|
|
0, 0,
|
|
width, height,
|
|
0, 0);
|
|
|
|
needs_redraw = 0;
|
|
}
|
|
|
|
XNextEvent (dpy, &xev);
|
|
|
|
switch (xev.xany.type) {
|
|
case ButtonPress:
|
|
/* A click on the canvas ends the program */
|
|
goto DONE;
|
|
case KeyPress:
|
|
if (xev.xkey.keycode == quit_keycode)
|
|
goto DONE;
|
|
break;
|
|
case ConfigureNotify:
|
|
/* Note new size and create new pixmap. */
|
|
width = xev.xconfigure.width;
|
|
height = xev.xconfigure.height;
|
|
XFreePixmap (dpy, pixmap);
|
|
pixmap = XCreatePixmap (dpy, w, width, height, DefaultDepth (dpy, screen));
|
|
needs_redraw = 1;
|
|
break;
|
|
case Expose:
|
|
XCopyArea (dpy, pixmap, w, gc,
|
|
xev.xexpose.x, xev.xexpose.y,
|
|
xev.xexpose.width, xev.xexpose.height,
|
|
xev.xexpose.x, xev.xexpose.y);
|
|
break;
|
|
}
|
|
}
|
|
DONE:
|
|
|
|
XFreeGC (dpy, gc);
|
|
XCloseDisplay (dpy);
|
|
|
|
return 0;
|
|
}
|