1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/* Copyright (C) 2006 Evan Martin <martine@danga.com> */
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <aosd.h>
#define MARGIN 10
#define RADIUS 20
#define WIDTH 185
#define HEIGHT 220
struct
{
gboolean transparent;
int pos;
int x, y;
int alpha;
char* filename;
} opts =
{
TRUE,
4,
0, 0,
50,
NULL
};
static void
round_rect(cairo_t* cr, int x, int y, int w, int h, int r)
{
cairo_move_to(cr, x+r, y);
cairo_line_to(cr, x+w-r, y); /* top edge */
cairo_curve_to(cr, x+w, y, x+w, y, x+w, y+r);
cairo_line_to(cr, x+w, y+h-r); /* right edge */
cairo_curve_to(cr, x+w, y+h, x+w, y+h, x+w-r, y+h);
cairo_line_to(cr, x+r, y+h); /* bottom edge */
cairo_curve_to(cr, x, y+h, x, y+h, x, y+h-r);
cairo_line_to(cr, x, y+r); /* left edge */
cairo_curve_to(cr, x, y, x, y, x+r, y);
}
static void
render(cairo_t* cr, void* data)
{
cairo_surface_t* image = data;
const int width = cairo_image_surface_get_width(image);
const int height = cairo_image_surface_get_height(image);
cairo_set_source_rgba(cr, 0, 0, 0, 0);
cairo_new_path(cr);
round_rect(cr, 0, 0, width + (2 * MARGIN), height + (2 * MARGIN), RADIUS);
cairo_close_path(cr);
cairo_fill(cr);
cairo_save(cr);
cairo_set_source_surface(cr, image, MARGIN, MARGIN);
cairo_paint_with_alpha(cr, opts.alpha / (float)100);
cairo_restore(cr);
}
static gboolean
parse_options(int* argc, char** argv[])
{
GOptionContext* ctx;
GOptionGroup* group;
gboolean ret;
GOptionEntry display[] =
{
{ "opaque", 'o', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE,
(gpointer)&opts.transparent, "turn off transparent background" },
{ "alpha", 'a', 0, G_OPTION_ARG_INT,
(gpointer)&opts.alpha, "alpha level of a displayed image (0:100)" },
{ NULL }
};
GOptionEntry coords[] =
{
{ "position", 'p', 0, G_OPTION_ARG_INT,
(gpointer)&opts.pos, "window position (0:8)"},
{ "x", 'x', G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_INT,
(gpointer)&opts.x, "x offset coordinate for window" },
{ "y", 'y', G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_INT,
(gpointer)&opts.y, "y offset coordinate for window" },
{ NULL }
};
GOptionEntry image[] =
{
{ "image", 'i', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME,
(gpointer)&opts.filename, "image to display", "PATH" },
{ NULL }
};
ctx = g_option_context_new("");
g_option_context_set_ignore_unknown_options(ctx, FALSE);
#define ADD_GROUP(name, desc, help, entries, main) \
group = g_option_group_new((name), (desc), (help), NULL, NULL); \
g_option_group_add_entries(group, (entries)); \
if ((main)) \
g_option_context_set_main_group(ctx, group); \
else \
g_option_context_add_group(ctx, group);
ADD_GROUP("display", "Display Options:", "Show display help options", display, FALSE);
ADD_GROUP("coords", "Position Options:", "Show position help options", coords, FALSE);
ADD_GROUP("image", "Image Options:", "Show image help options", image, TRUE);
#undef ADD_GROUP
ret = g_option_context_parse(ctx, argc, argv, NULL);
g_option_context_free(ctx);
if (ret == FALSE ||
opts.filename == NULL)
return FALSE;
if (opts.pos < 0 ||
opts.pos > 8)
opts.pos = 4;
if (opts.alpha < 0)
opts.alpha = 0;
if (opts.alpha > 100)
opts.alpha = 100;
return TRUE;
}
int
main(int argc, char* argv[])
{
if (parse_options(&argc, &argv) == FALSE)
{
fprintf(stderr, "Error parsing options, try --help.\n");
return 1;
}
Aosd* aosd;
cairo_surface_t* image = cairo_image_surface_create_from_png(opts.filename);
const int width = cairo_image_surface_get_width(image);
const int height = cairo_image_surface_get_height(image);
aosd = aosd_new();
aosd_set_transparency(aosd,
opts.transparent ? TRANSPARENCY_COMPOSITE : TRANSPARENCY_NONE);
aosd_set_position(aosd, opts.pos, width + 2 * MARGIN, height + 2 * MARGIN);
aosd_set_position_offset(aosd, opts.x, opts.y);
aosd_set_renderer(aosd, render, image);
aosd_flash(aosd, 300, 3000, 300);
cairo_surface_destroy(image);
aosd_destroy(aosd);
return 0;
}
/* vim: set ts=2 sw=2 et : */
|