Commit ab4c571e authored by Youness Alaoui's avatar Youness Alaoui
Browse files

Make it parse whiptail args

parent b8614bd0
all : test-menu-gtk test-menu-fb fbwhiptail test-dri
test-menu-gtk: test-menu-gtk.c cairo_menu.c cairo_utils.c
gcc -g -O0 -o $@ $^ \
test-menu-gtk: test-menu-gtk.c cairo_menu.c cairo_utils.c fbwhiptail_menu.c
$(CC) -g -O0 -o $@ $^ \
`pkg-config --cflags --libs cairo` \
`pkg-config --cflags --libs gtk+-2.0` -lm
test-menu-fb: test-menu-fb.c cairo_menu.c cairo_utils.c cairo_linuxfb.c \
libcairo.a libpixman-1.a libpng16.a libz.a
gcc -g -O0 -o $@ $^ -lm
strip $@
$(CC) -g -O0 -o $@ $^ -lm
fbwhiptail: fbwhiptail.c fbwhiptail_menu.c cairo_menu.c cairo_utils.c cairo_dri.c cairo_linuxfb.c \
libcairo.a libpixman-1.a libpng16.a libz.a
gcc -g -O0 -o $@ $^ -lm
fbwhiptail: fbwhiptail.c fbwhiptail_menu.c cairo_menu.c cairo_utils.c cairo_dri.c
$(CC) -g -O0 -o $@ $^ -lm
test-dri: test-dri.c
gcc -g -O0 -o $@ $^
$(CC) -g -O0 -o $@ $^
......@@ -23,7 +23,7 @@
#include <sys/mman.h>
#include <time.h>
#ifdef DEBUG
#ifdef DRI_DEBUG
#define PERROR perror
#define PRINTF printf
#else
......@@ -234,11 +234,11 @@ static void cairo_dri_surface_destroy(void *data)
return;
/* If current fb is mapped, restored saved fb */
printf ("Destroying surface with fb : %d\n", fb->fb_id);
PRINTF ("Destroying surface with fb : %d\n", fb->fb_id);
crtc.crtc_id = fb->screen->crtc;
if (ioctl(fb->dri->dri_fd, DRM_IOCTL_MODE_GETCRTC, &crtc) == 0) {
if (crtc.fb_id == fb->fb_id) {
printf ("Currently displayed FB, restoring saved one\n");
PRINTF ("Currently displayed FB, restoring saved one\n");
crtc = fb->screen->saved_crtc;
crtc.set_connectors_ptr = (uint64_t)&fb->screen->conn;
crtc.count_connectors = 1;
......@@ -305,7 +305,7 @@ cairo_dri_create_surface(cairo_dri_t *dri, dri_screen_t *screen)
fb->fb_id = cmd_dumb.fb_id;
fb->screen = screen;
printf ("Created framebuffer %p of size %d (%dx%d) with id %d\n", fb->fb_data,
PRINTF ("Created framebuffer %p of size %d (%dx%d) with id %d\n", fb->fb_data,
fb->size, fb->screen->mode.hdisplay, fb->screen->mode.vdisplay, fb->fb_id);
/* Create the cairo surface which will be used to draw to */
surface = cairo_image_surface_create_for_data(fb_data,
......
......@@ -407,6 +407,15 @@ cairo_menu_new (cairo_surface_t *surface, int rows, int columns,
NULL, NULL, NULL);
}
cairo_surface_t *
cairo_menu_scale_or_reference_surface (cairo_surface_t *surface, int width, int height)
{
/* int ref_width, ref_height;
cairo_utils_get_surface_size (surface, &ref_width, &ref_height);
if (ref_width == width && ref_height == height)*/
return cairo_surface_reference (surface);
}
int
cairo_menu_add_item_full (CairoMenu *menu, cairo_surface_t *image,
CairoMenuImagePosition image_position, const char *text, int text_size,
......@@ -455,8 +464,8 @@ cairo_menu_add_item_full (CairoMenu *menu, cairo_surface_t *image,
if (bg_sel_image == NULL)
bg_sel_image = menu->bg_sel_image;
item->bg_image = cairo_surface_reference (bg_image);
item->bg_sel_image = cairo_surface_reference (bg_sel_image);
item->bg_image = cairo_menu_scale_or_reference_surface (bg_image, width, height);
item->bg_sel_image = cairo_menu_scale_or_reference_surface (bg_sel_image, width, height);
if (image != NULL)
cairo_menu_set_item_image (menu, item->index, image, image_position);
......@@ -667,6 +676,9 @@ cairo_menu_handle_input (CairoMenu *menu, CairoMenuInput input,
int new_selection;
int previous_selection;
if (menu->items == NULL)
return -1;
old_start_item = menu->start_item;
old_selection = new_selection = previous_selection = menu->selection;
......@@ -697,8 +709,17 @@ cairo_menu_handle_input (CairoMenu *menu, CairoMenuInput input,
void
cairo_menu_set_selection (CairoMenu *menu, int id, CairoMenuRectangle *bbox)
{
/* TODO: Implement this some day... */
assert ("Not implemented" == NULL);
if (menu->items[id].enabled == FALSE)
return;
menu->selection = id;
//TODO : menu->start_item = old_start_item;
cairo_menu_redraw (menu);
bbox->x = 0;
bbox->y = 0;
cairo_utils_get_surface_size (menu->surface, &bbox->width, &bbox->height);
}
void
......
......@@ -44,6 +44,27 @@
static volatile sig_atomic_t cancel = 0;
typedef struct {
char *tag;
char *item;
} whiptail_menu_item;
typedef struct {
char *title;
char *backtitle;
char *text;
char *default_item;
int noitem;
int notags;
int topleft;
int output_fd;
int width;
int height;
int menu_height;
whiptail_menu_item *items;
int num_items;
} whiptail_args;
void signal_handler(int signum)
{
cancel = 1;
......@@ -69,6 +90,117 @@ static int handle_input(Menu *menu, short code)
return (bbox.width * bbox.height) != 0;
}
int parse_whiptail_args (int argc, char **argv, whiptail_args *args)
{
int i;
int end_of_args = 0, menu = 0;
/*
static whiptail_menu_item items[] = {
{"first", "menu entry 1"},
{"second", "blablabla"},
{"foo", "bar"},
{"default", "item"},
{"usb1", "usb boot"},
{"linux2", "Linux boot"},
{"etc..", "you get the idea"},
};
args->title = "Whiptail test menu";
args->backtitle = "background title";
args->text = "some text to show in frame?";
args->default_item = "default";
args->noitem = 0;
args->notags = 0;
args->topleft = 0;
args->output_fd = 2;
args->width = 600;
args->height = 400;
args->menu_height = 10;
args->items = items;
args->num_items = 7;
*/
memset (args, 0, sizeof(whiptail_args));
args->output_fd = 2;
for (i = 1; i < argc; i++) {
if (end_of_args == 0 && strncmp (argv[i], "--", 2) == 0) {
if (strcmp (argv[i], "--title") == 0) {
i++;
if (i >= argc)
goto error;
args->title = argv[i];
} else if (strcmp (argv[i], "--backtitle") == 0) {
i++;
if (i >= argc)
goto error;
args->backtitle = argv[i];
} else if (strcmp (argv[i], "--default-item") == 0) {
i++;
if (i >= argc)
goto error;
args->default_item = argv[i];
} else if (strcmp (argv[i], "--output-fd") == 0) {
i++;
if (i >= argc)
goto error;
args->output_fd = atoi (argv[i]);
}else if (strcmp (argv[i], "--noitem") == 0) {
args->noitem = 1;
} else if (strcmp (argv[i], "--notags") == 0) {
args->notags = 1;
} else if (strcmp (argv[i], "--topleft") == 0) {
args->topleft = 1;
} else if (menu == 0 && strcmp (argv[i], "--menu") == 0) {
if (i + 4 >= argc)
goto error;
args->text = argv[i+1];
args->height = atoi (argv[i+2]);
args->width = atoi (argv[i+3]);
args->menu_height = atoi (argv[i+4]);
i += 4;
menu = 1;
args->items = malloc (sizeof(whiptail_menu_item) * (argc - i) / 2);
} else if (strcmp (argv[i], "--") == 0) {
end_of_args = 1;
} else if (strcmp (argv[i], "--yes-button") == 0 ||
strcmp (argv[i], "--no-button") == 0 ||
strcmp (argv[i], "--ok-button") == 0 ||
strcmp (argv[i], "--cancel-button") == 0) {
i++;
if (i >= argc)
goto error;
// Ignore arguments
} else if (strcmp (argv[i], "--clear") == 0 ||
strcmp (argv[i], "--fb") == 0 ||
strcmp (argv[i], "--fullbuttons") == 0 ||
strcmp (argv[i], "--defaultno") == 0 ||
strcmp (argv[i], "--nocancel") == 0 ||
strcmp (argv[i], "--scrolltext") == 0 ||
strcmp (argv[i], "--separate-output") == 0 ||
strcmp (argv[i], "--help") == 0 ||
strcmp (argv[i], "--version") == 0) {
// Ignore arguments
}
} else if (menu) {
if (i + 1 >= argc)
goto error;
args->items[args->num_items].tag = argv[i++];
args->items[args->num_items].item = argv[i];
args->num_items++;
} else {
goto error;
}
}
if (menu == 0 || args->num_items == 0)
goto error;
return 0;
error:
if (args->items)
free (args->items);
return -1;
}
int main(int argc, char **argv)
{
struct sigaction action;
......@@ -79,6 +211,8 @@ int main(int argc, char **argv)
int xres, yres;
Menu *menu = NULL;
int redraw = 1;
whiptail_args args;
int default_selection;
cairo_t *cr;
#ifdef USE_LINUXFB
cairo_surface_t *fbsurface = NULL;
......@@ -89,6 +223,11 @@ int main(int argc, char **argv)
int current_fb = 0;
#endif
if (parse_whiptail_args (argc, argv, &args) != 0) {
printf ("Invalid arguments received\n");
return -1;
}
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = signal_handler;
sigaction(SIGTERM, &action, NULL);
......@@ -108,13 +247,7 @@ int main(int argc, char **argv)
cr = cairo_create(fbsurface);
#else
dri = cairo_dri_open("/dev/dri/card0");
printf ("Got DRI %p with %d screens : \n", dri, dri? dri->num_screens : 0);
if (dri && dri->num_screens > 0) {
for (i = 0; i < dri->num_screens; i++) {
printf (" %d: %dx%d on connector %d using crtc %d\n", i,
dri->screens[i].mode.hdisplay, dri->screens[i].mode.vdisplay,
dri->screens[i].conn, dri->screens[i].crtc);
}
xres = dri->screens[0].mode.hdisplay;
yres = dri->screens[0].mode.vdisplay;
surfaces[0] = cairo_dri_create_surface(dri, &dri->screens[0]);
......@@ -124,65 +257,51 @@ int main(int argc, char **argv)
}
#endif
menu = standard_menu_create ("Frambuffer Cairo menu", xres, yres);
idx = standard_menu_add_item (menu, "TOP LEFT", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_TOP_LEFT;
idx = standard_menu_add_item (menu, "TOP CENTER", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_TOP_CENTER;
idx = standard_menu_add_item (menu, "TOP RIGHT", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_TOP_RIGHT;
idx = standard_menu_add_item (menu, "MIDDLE LEFT", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_MIDDLE_LEFT;
idx = standard_menu_add_item (menu, "MIDDLE CENTER", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_MIDDLE_CENTER;
idx = standard_menu_add_item (menu, "MIDDLE RIGHT", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_MIDDLE_RIGHT;
idx = standard_menu_add_item (menu, "BOTTOM LEFT", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_BOTTOM_LEFT;
idx = standard_menu_add_item (menu, "BOTTOM CENTER", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_BOTTOM_CENTER;
idx = standard_menu_add_item (menu, "BOTTOM RIGHT", 10);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_BOTTOM_RIGHT;
idx = standard_menu_add_item (menu, "Pattern", 15);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_MIDDLE_LEFT;
image = cairo_image_surface_create_from_png ("pattern.png");
cairo_menu_set_item_image (menu->menu, idx, image, CAIRO_MENU_IMAGE_POSITION_RIGHT);
cairo_surface_destroy (image);
idx = standard_menu_add_item (menu, "Rectangles", 15);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_MIDDLE_RIGHT;
image = cairo_image_surface_create_from_png ("rect.png");
cairo_menu_set_item_image (menu->menu, idx, image, CAIRO_MENU_IMAGE_POSITION_LEFT);
cairo_surface_destroy (image);
standard_menu_add_item (menu, "Hello world 3", 20);
standard_menu_add_item (menu, "Hello world 4", 20);
standard_menu_add_item (menu, "Hello world 5", 20);
standard_menu_add_item (menu, "Hello world 6", 20);
standard_menu_add_item (menu, "Hello world 7", 20);
standard_menu_add_item (menu, "Hello world 8", 20);
standard_menu_add_item (menu, "Hello world 9", 20);
standard_menu_add_item (menu, "Hello world 10", 15);
standard_menu_add_item (menu, "Hello world 11", 5);
standard_menu_add_item (menu, "Hello world 12", 5);
standard_menu_add_item (menu, "Hello world 13", 5);
standard_menu_add_item (menu, "Hello world 14", 5);
standard_menu_add_item (menu, "Hello world 5", 15);
standard_menu_add_item (menu, "Hello world 1", 10);
standard_menu_add_item (menu, "Hello world 2", 10);
standard_menu_add_item (menu, "Hello world 3", 10);
standard_menu_add_item (menu, "Hello world 4", 10);
standard_menu_add_item (menu, "Hello world 5", 10);
standard_menu_add_item (menu, "Hello world 6", 10);
standard_menu_add_item (menu, "Hello world 7", 10);
standard_menu_add_item (menu, "Hello world 8", 10);
standard_menu_add_item (menu, "Hello world 9", 10);
standard_menu_add_item (menu, "Hello world 10", 10);
standard_menu_add_item (menu, "Hello world 11", 10);
standard_menu_add_item (menu, "Hello world 12", 10);
standard_menu_add_item (menu, "Hello world 13", 10);
standard_menu_add_item (menu, "Hello world 14", 10);
standard_menu_add_item (menu, "Hello world 15", 10);
/*
menu = standard_menu_create (args.title, xres, yres,
-1, (args.noitem || args.notags) ? 1 : 2);
for (i = 0; i < args.num_items; i++) {
if (args.notags == 0) {
idx = standard_menu_add_tag (menu, args.items[i].tag, 10);
if (1 || args.noitem)
menu->menu->items[idx].enabled = 1;
}
if (args.noitem == 0) {
idx = standard_menu_add_item (menu, args.items[i].item, 20);
}
if (args.default_item && strcmp (args.default_item, args.items[i].item) == 0) {
CairoMenuRectangle bbox;
cairo_menu_set_selection (menu->menu, idx, &bbox);
}
}
*/
menu = standard_menu_create (args.title, xres, yres,-1, 1);
idx = standard_menu_add_item (menu, args.text, 15);
menu->menu->items[idx].enabled = 0;
for (i = 0; i < args.num_items; i++) {
char *text;
whiptail_menu_item *item = &args.items[i];
if (args.notags || args.noitem) {
text = malloc ((args.notags ? strlen (item->item) : strlen (item->tag)) + 1);
strcpy (text, args.notags ? item->item : item->tag);
} else {
text = malloc (strlen (item->item) + strlen (item->tag) + 1 + 3);
strcpy (text, args.notags ? item->item : item->tag);
strcat (text, " - ");
strcat (text, item->item);
}
idx = standard_menu_add_item (menu, text, 20);
menu->menu->items[idx].alignment = CAIRO_MENU_ALIGN_MIDDLE_LEFT;
free (text);
if (i == 0 ||
(args.default_item && strcmp (args.default_item, item->tag) == 0)) {
CairoMenuRectangle bbox;
cairo_menu_set_selection (menu->menu, idx, &bbox);
}
}
while (!cancel) {
char c;
......@@ -204,14 +323,17 @@ int main(int argc, char **argv)
switch (c = getchar ()) {
case 0x1B: // Escape character
escape = 1;
if (escape == 0)
escape = 1;
else
cancel = 1;
break;
case 0xA:
if (escape == 0) {
printf ("Selection is %d: %s\n", menu->menu->selection,
menu->menu->items[menu->menu->selection].text);
cancel = 1;
fprintf (stderr, "%s", args.items[menu->menu->selection].tag);
}
escape = 0;
break;
case 0x41:
case 0x42:
......@@ -221,6 +343,8 @@ int main(int argc, char **argv)
redraw = handle_input (menu, c);
}
default:
if (escape == 0) {
}
if (escape == 1) {
escape = 2;
} else {
......
......@@ -74,8 +74,6 @@ create_standard_menu_frame (Menu *menu)
cairo_t *cr;
int x, y;
printf ("Creating %s frame\n", menu->title);
/* Adapt frame height depending on items in the menu */
width = STANDARD_MENU_FRAME_WIDTH;
height = menu->menu->nitems * STANDARD_MENU_ITEM_TOTAL_HEIGHT;
......@@ -171,7 +169,6 @@ draw_standard_menu (Menu *menu, cairo_t *cr)
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_paint_with_alpha (cr, 0.5);
printf ("Drawing menu\n");
cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr);
cairo_restore (cr);
......@@ -229,13 +226,14 @@ create_standard_background (float r, float g, float b) {
}
Menu *
standard_menu_create (const char *title, int width, int height)
standard_menu_create (const char *title, int width, int height, int rows, int columns)
{
cairo_surface_t *surface;
cairo_surface_t *background, *selected_background, *disabled;
cairo_t *cr;
Menu * menu = malloc (sizeof(Menu));
memset (menu, 0, sizeof(Menu));
menu->draw = draw_standard_menu;
menu->title = title;
menu->width = width;
......@@ -261,7 +259,7 @@ standard_menu_create (const char *title, int width, int height)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
STANDARD_MENU_WIDTH, STANDARD_MENU_HEIGHT);
/* Infinite vertical scrollable menu */
menu->menu = cairo_menu_new_full (surface, -1, 1,
menu->menu = cairo_menu_new_full (surface, rows, columns,
STANDARD_MENU_ITEM_BOX_WIDTH, STANDARD_MENU_ITEM_BOX_HEIGHT,
STANDARD_MENU_PAD_X, STANDARD_MENU_PAD_Y, 0,
background, selected_background, disabled);
......@@ -273,6 +271,16 @@ standard_menu_create (const char *title, int width, int height)
return menu;
}
int
standard_menu_add_tag (Menu *menu, const char *title, int fontsize)
{
return cairo_menu_add_item_full (menu->menu, NULL, CAIRO_MENU_IMAGE_POSITION_LEFT, title,
fontsize, CAIRO_MENU_DEFAULT_TEXT_COLOR, CAIRO_MENU_ALIGN_MIDDLE_CENTER,
menu->menu->default_item_width / 2, menu->menu->default_item_height,
STANDARD_MENU_ITEM_IPAD_X, STANDARD_MENU_ITEM_IPAD_Y, FALSE,
NULL, NULL, NULL, NULL);
}
int
standard_menu_add_item (Menu *menu, const char *title, int fontsize)
{
......
......@@ -73,7 +73,8 @@ struct Menu_s {
#define MAIN_MENU_FONT_SIZE 15
void draw_background (Menu *menu, cairo_t *cr);
Menu *standard_menu_create (const char *title, int width, int height);
Menu *standard_menu_create (const char *title, int width, int height, int rows, int columns);
int standard_menu_add_item (Menu *menu, const char *title, int fontsize);
int standard_menu_add_tag (Menu *menu, const char *title, int fontsize);
#endif
......@@ -37,341 +37,39 @@
#include <X11/Xatom.h>
#include <cairo/cairo.h>
#include "cairo_menu.h"
#include "fbwhiptail_menu.h"
#include "cairo_utils.h"
typedef struct Menu_s Menu;
struct Menu_s {
cairo_surface_t *background;
CairoMenu *menu;
int width;
int height;
const char *title;
cairo_surface_t *frame;
void (*callback) (Menu *menu, int accepted);
void (*draw) (Menu *menu, cairo_t *cr);
};
static Menu *menu = NULL;
#define STANDARD_MENU_ITEM_WIDTH (300)
#define STANDARD_MENU_ITEM_HEIGHT 35
#define STANDARD_MENU_PAD_X 10
#define STANDARD_MENU_PAD_Y 3
#define STANDARD_MENU_BOX_X 7
#define STANDARD_MENU_BOX_Y 7
#define STANDARD_MENU_ITEM_BOX_WIDTH (STANDARD_MENU_ITEM_WIDTH + \
(2 * STANDARD_MENU_BOX_X))
#define STANDARD_MENU_ITEM_BOX_HEIGHT (STANDARD_MENU_ITEM_HEIGHT + \
(2 * STANDARD_MENU_BOX_Y))
#define STANDARD_MENU_ITEM_TOTAL_WIDTH (STANDARD_MENU_ITEM_BOX_WIDTH + \
(2 * STANDARD_MENU_PAD_X))
#define STANDARD_MENU_ITEM_TOTAL_HEIGHT (STANDARD_MENU_ITEM_BOX_HEIGHT + \
(2 * STANDARD_MENU_PAD_Y))
#define STANDARD_MENU_ITEM_IPAD_X (STANDARD_MENU_BOX_X + CAIRO_MENU_DEFAULT_IPAD_X)
#define STANDARD_MENU_ITEM_IPAD_Y (STANDARD_MENU_BOX_Y + CAIRO_MENU_DEFAULT_IPAD_Y)
#define STANDARD_MENU_FRAME_SIDE 25
#define STANDARD_MENU_FRAME_TOP 60
#define STANDARD_MENU_FRAME_BOTTOM 40
#define STANDARD_MENU_FRAME_HEIGHT (STANDARD_MENU_FRAME_TOP + \
STANDARD_MENU_FRAME_BOTTOM) // + nitems * STANDARD_MENU_ITEM_TOTAL_HEIGHT
#define STANDARD_MENU_FRAME_WIDTH (STANDARD_MENU_ITEM_TOTAL_WIDTH + \
(2 * STANDARD_MENU_FRAME_SIDE))
#define STANDARD_MENU_WIDTH (STANDARD_MENU_ITEM_TOTAL_WIDTH)
#define STANDARD_MENU_HEIGHT (menu->height * 0.7)
#define STANDARD_MENU_BOX_CORNER_RADIUS 11
#define STANDARD_MENU_BOX_BORDER_WIDTH 1
#define STANDARD_MENU_FRAME_CORNER_RADIUS 32
#define STANDARD_MENU_FRAME_BORDER_WIDTH 2
#define STANDARD_MENU_TITLE_FONT_SIZE 25
#define MAIN_MENU_FONT_SIZE 15
static void
draw_background (Menu *menu, cairo_t *cr)
{
/* Pre-cache the gradient background pattern into a cairo image surface.
* The cairo_pattern is a vector basically, so when painting the gradient
* into our surface, it needs to rasterize it, which makes the FPS drop
* to 6 or 7 FPS and makes the game unusable (misses controller input, and
* animations don't work anymore). So by pre-rasterizing it into an
* image surface, we can do the background paint very quickly and FPS should
* stay at 60fps or if we miss the VSYNC, drop to 30fps.
*/
if (menu->background == NULL) {
cairo_pattern_t *linpat = NULL;
cairo_t *grad_cr = NULL;
menu->background = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
menu->width, menu->height);
linpat = cairo_pattern_create_linear (0, 0,
menu->width, menu->height);
cairo_pattern_add_color_stop_rgb (linpat, 0, 0, 0.3, 0.8);
cairo_pattern_add_color_stop_rgb (linpat, 1, 0, 0.8, 0.3);
grad_cr = cairo_create (menu->background);
cairo_set_source (grad_cr, linpat);
cairo_paint (grad_cr);
cairo_destroy (grad_cr);
cairo_pattern_destroy (linpat);
cairo_surface_flush (menu->background);
}
cairo_set_source_surface (cr, menu->background, 0, 0);
cairo_paint (cr);
}
static void
create_standard_menu_frame (Menu *menu)
{
cairo_font_extents_t fex;
cairo_text_extents_t tex;
cairo_pattern_t *linpat = NULL;
cairo_surface_t *frame = NULL;
int width, height;
cairo_t *cr;
int x, y;
printf ("Creating %s frame\n", menu->title);
/* Adapt frame height depending on items in the menu */
width = STANDARD_MENU_FRAME_WIDTH;
height = menu->menu->nitems * STANDARD_MENU_ITEM_TOTAL_HEIGHT;
if (height > STANDARD_MENU_HEIGHT)
height = STANDARD_MENU_HEIGHT;
height += STANDARD_MENU_FRAME_HEIGHT;
frame = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
width, height);
cr = cairo_create (frame);
cairo_utils_clip_round_edge (cr, width, height,
STANDARD_MENU_FRAME_CORNER_RADIUS, STANDARD_MENU_FRAME_CORNER_RADIUS,
STANDARD_MENU_FRAME_CORNER_RADIUS);