hexagram/examples/cluster.c

205 lines
4.8 KiB
C
Raw Normal View History

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
2019-05-25 22:08:26 -05:00
static void draw_needle(cairo_t *cr,
double x,
double y,
double r,
double min_angle,
double max_angle,
double value) {
double angle = min_angle + ((max_angle - min_angle) * value) - 90.0;
cairo_move_to(cr, x, y);
2019-05-25 22:11:26 -05:00
cairo_set_source_rgb(cr, 0, 0.25, 1.0);
2019-05-25 22:08:26 -05:00
cairo_line_to(cr,
x + r * cos((M_PI/180.0) * angle),
y + r * sin((M_PI/180.0) * angle));
cairo_stroke(cr);
}
static void draw_face_number(cairo_t *cr,
double x,
double y,
double r,
double min_angle,
double max_angle,
double value,
const char *text) {
double angle = min_angle + ((max_angle - min_angle) * value) - 95;
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_move_to(cr,
x + r * cos((M_PI/180.0) * angle),
y + r * sin((M_PI/180.0) * angle));
cairo_save(cr);
cairo_rotate(cr, (M_PI/180.0) * (angle + 95));
cairo_show_text(cr, text);
cairo_restore(cr);
}
static void draw_tachometer(cairo_t *cr) {
int i;
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_arc(cr, 208, 240, 192, 0, 360);
cairo_stroke(cr);
/*
* Draw face numbers
*/
for (i=0; i<=80; i+=10) {
char text[4];
snprintf(text, 3, "%02d", i);
draw_face_number(cr, 208, 240, 162, 232, 488, i / 80.0, text);
}
2019-05-25 22:08:26 -05:00
/*
* Draw a gauge needle
*/
draw_needle(cr, 208, 240, 148, 232, 488, 0.0);
2019-05-25 22:08:26 -05:00
/*
* Draw a tiny boi circle
2019-05-25 22:08:26 -05:00
*/
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_arc(cr, 208, 240, 16, 0, 360);
cairo_fill(cr);
}
static void draw_speedometer(cairo_t *cr) {
cairo_arc(cr, 816, 240, 192, 0, 360);
cairo_stroke(cr);
}
static void redraw(cairo_t *cr) {
/*
* Set up text
*/
cairo_select_font_face(cr, "Helvetica",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cr, 24);
/*
* Paint canvas black
*/
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_paint(cr);
draw_tachometer(cr);
draw_speedometer(cr);
/*
* Draw two smaller circles
*/
cairo_arc(cr, 442, 368, 64, 0, 360 * (M_PI/180));
cairo_stroke(cr);
cairo_arc(cr, 582, 368, 64, 0, 360 * (M_PI/180));
cairo_stroke(cr);
/*
* Draw a rectangle
*/
cairo_move_to(cr, 432, 48);
cairo_line_to(cr, 592, 48);
cairo_line_to(cr, 592, 288);
cairo_line_to(cr, 432, 288);
cairo_line_to(cr, 432, 48);
cairo_set_source_rgb(cr, 0.75, 0, 0);
cairo_fill(cr);
cairo_move_to(cr, 432, 48);
cairo_line_to(cr, 592, 48);
cairo_line_to(cr, 592, 288);
cairo_line_to(cr, 432, 288);
cairo_line_to(cr, 432, 48);
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_stroke(cr);
}
int main(int argc, char **argv) {
Display *display;
Window win;
Pixmap buf;
GC gc;
int screen, x = 1024, y = 480;
XGCValues values = {
.foreground = 0x000000,
.background = 0xffffff,
.graphics_exposures = 0
};
cairo_surface_t *sfc;
cairo_t *ctx;
XEvent e;
if ((display = XOpenDisplay(NULL)) == NULL)
exit(1);
screen = DefaultScreen(display);
win = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, x, y, 0, 0, 0);
gc = XCreateGC(display, win, GCForeground | GCBackground | GCGraphicsExposures, &values);
buf = XCreatePixmap(display, win, x, y, 24);
XSelectInput(display, win, ExposureMask | ButtonPressMask | KeyPressMask);
XMapWindow(display, win);
sfc = cairo_xlib_surface_create(display, buf, DefaultVisual(display, screen), x, y);
cairo_xlib_surface_set_size(sfc, x, y);
ctx = cairo_create(sfc);
redraw(ctx);
while (1) {
XExposeEvent *expose;
XNextEvent(cairo_xlib_surface_get_display(sfc), &e);
switch (e.type) {
case Expose:
expose = (XExposeEvent *)&e;
XCopyArea(display, buf, win, gc, expose->x, expose->y,
expose->width, expose->height,
expose->x, expose->y);
break;
case ButtonPress:
case KeyPress:
goto done;
default:
fprintf(stderr, "Dropping unhandled XEvent.type = %d.\n", e.type);
}
}
done:
cairo_destroy(ctx);
cairo_surface_destroy(sfc);
XCloseDisplay(display);
return 0;
}