/* GTK - The GIMP Toolkit * Copyright (C) 2016 Benjamin Otte * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include #include "gtkwin32drawprivate.h" typedef enum { ICON_CLOSE, ICON_MINIMIZE, ICON_MAXIMIZE, ICON_RESTORE } Icon; const guchar icon_close_pixels[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x1c, 0x07, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x1c, 0x07, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const guchar icon_minimize_pixels[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const guchar icon_maximize_pixels[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const guchar icon_restore_pixels[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x00, 0x82, 0x07, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static struct { int width; int height; gsize pixels_size; const guchar *pixels; } icon_masks[] = { { 13, 13, sizeof (icon_close_pixels), icon_close_pixels }, { 13, 13, sizeof (icon_minimize_pixels), icon_minimize_pixels }, { 13, 13, sizeof (icon_maximize_pixels), icon_maximize_pixels }, { 13, 13, sizeof (icon_restore_pixels), icon_restore_pixels } }; static void mask_icon (cairo_t *cr, Icon icon, double x, double y, double width, double height) { cairo_surface_t *surface; surface = cairo_image_surface_create_for_data ((guchar *) icon_masks[icon].pixels, CAIRO_FORMAT_A1, icon_masks[icon].width, icon_masks[icon].height, icon_masks[icon].pixels_size / icon_masks[icon].height); cairo_mask_surface (cr, surface, x + (width - icon_masks[icon].width) / 2, y + (height - icon_masks[icon].height) / 2); cairo_surface_destroy (surface); } static void gtk_cairo_set_source_sys_color (cairo_t *cr, gint id) { GdkRGBA rgba; gtk_win32_get_sys_color (id, &rgba); gdk_cairo_set_source_rgba (cr, &rgba); } static void draw_outline (cairo_t *cr, int top_color_id, int bottom_color_id, int x, int y, int width, int height) { gtk_cairo_set_source_sys_color (cr, top_color_id); cairo_rectangle (cr, x, y, width, 1); cairo_rectangle (cr, x, y, 1, height); cairo_fill (cr); gtk_cairo_set_source_sys_color (cr, bottom_color_id); cairo_rectangle (cr, x + width, y + height, -1, -height); cairo_rectangle (cr, x + width, y + height, -width, -1); cairo_fill (cr); } typedef enum { EDGE_RAISED_OUTER = 1 << 0, EDGE_SUNKEN_OUTER = 1 << 1, EDGE_RAISED_INNER = 1 << 2, EDGE_SUNKEN_INNER = 1 << 3, EDGE_RAISED = (EDGE_RAISED_OUTER | EDGE_RAISED_INNER), EDGE_SUNKEN = (EDGE_SUNKEN_OUTER | EDGE_SUNKEN_INNER), EDGE_ETCHED = (EDGE_SUNKEN_OUTER | EDGE_RAISED_INNER), EDGE_BUMP = (EDGE_RAISED_OUTER | EDGE_SUNKEN_INNER) } GtkWin32Edge; static void draw_edge (cairo_t *cr, GtkWin32Edge edge, gboolean soft, int x, int y, int width, int height) { switch (edge & (EDGE_RAISED_OUTER | EDGE_SUNKEN_OUTER)) { case EDGE_RAISED_OUTER: draw_outline (cr, soft ? GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT : GTK_WIN32_SYS_COLOR_3DLIGHT, GTK_WIN32_SYS_COLOR_3DDKSHADOW, x, y, width, height); break; case EDGE_SUNKEN_OUTER: draw_outline (cr, soft ? GTK_WIN32_SYS_COLOR_3DDKSHADOW : GTK_WIN32_SYS_COLOR_BTNSHADOW, GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT, x, y, width, height); break; case (EDGE_RAISED_OUTER | EDGE_SUNKEN_OUTER): return; default: break; } x += 1; y += 1; width -= 2; height -= 2; switch (edge & (EDGE_RAISED_INNER | EDGE_SUNKEN_INNER)) { case EDGE_RAISED_INNER: draw_outline (cr, soft ? GTK_WIN32_SYS_COLOR_3DLIGHT : GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT, GTK_WIN32_SYS_COLOR_BTNSHADOW, x, y, width, height); break; case EDGE_SUNKEN_INNER: draw_outline (cr, soft ? GTK_WIN32_SYS_COLOR_BTNSHADOW : GTK_WIN32_SYS_COLOR_3DDKSHADOW, GTK_WIN32_SYS_COLOR_3DLIGHT, x, y, width, height); break; case (EDGE_RAISED_INNER | EDGE_SUNKEN_INNER): return; default: break; } } static void draw_button (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, state == 3 ? EDGE_SUNKEN : EDGE_RAISED, TRUE, 0, 0, width, height); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 2, 2, width - 4, height - 4); cairo_fill (cr); } static void draw_frame (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_ETCHED, FALSE, 0, 0, width, height); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 2, 2, width - 4, height - 4); cairo_fill (cr); } static void draw_check (cairo_t *cr, int part, int state, int width, int height) { gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT); cairo_set_line_width (cr, 1.0); cairo_rectangle (cr, 0.5, 0.5, width - 1.0, height - 1.0); cairo_stroke (cr); } static void draw_radio (cairo_t *cr, int part, int state, int width, int height) { gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT); cairo_set_line_width (cr, 1.0); cairo_arc (cr, width / 2.0, height / 2.0, MIN (width, height) / 2.0 - 0.5, 0, G_PI * 2); cairo_stroke (cr); } static void draw_edit (cairo_t *cr, int part, int state, int width, int height) { int xborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CXBORDER); int yborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CYBORDER); cairo_rectangle (cr, 0, 0, width, height); gtk_cairo_set_source_sys_color (cr, (state == 6 || state == 4) ? GTK_WIN32_SYS_COLOR_BTNFACE : GTK_WIN32_SYS_COLOR_WINDOW); cairo_fill_preserve (cr); cairo_rectangle (cr, width - xborder, yborder, - (width - 2 * xborder), height - 2 * yborder); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_WINDOWFRAME); cairo_fill (cr); } static void draw_edit_noborder (cairo_t *cr, int part, int state, int width, int height) { cairo_rectangle (cr, 0, 0, width, height); gtk_cairo_set_source_sys_color (cr, (state == 6 || state == 4) ? GTK_WIN32_SYS_COLOR_BTNFACE : GTK_WIN32_SYS_COLOR_WINDOW); cairo_fill (cr); } static void draw_window (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_RAISED, TRUE, 0, 0, width, height + 2); gtk_cairo_set_source_sys_color (cr, state == 2 ? GTK_WIN32_SYS_COLOR_INACTIVECAPTION : GTK_WIN32_SYS_COLOR_ACTIVECAPTION); cairo_rectangle (cr, 2, 2, width - 4, height - 2); cairo_fill (cr); } static void draw_window_left (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_RAISED, TRUE, 0, -2, width + 2, height + 4); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 2, 0, width - 2, height); cairo_fill (cr); } static void draw_window_right (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_RAISED, TRUE, -2, -2, width + 2, height + 4); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 0, 0, width - 2, height); cairo_fill (cr); } static void draw_window_bottom (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_RAISED, TRUE, 0, -2, width, height + 2); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 2, 0, width - 4, height - 2); cairo_fill (cr); } static void draw_window_button (cairo_t *cr, int part, int state, int width, int height) { Icon icon; switch (part) { case 15: /* minimize */ icon = ICON_MINIMIZE; break; case 17: /* maximize */ icon = ICON_MAXIMIZE; break; default: g_assert_not_reached (); case 18: /* close */ icon = ICON_CLOSE; break; case 21: /* restore */ icon = ICON_RESTORE; break; } draw_button (cr, 0, state, width, height); gtk_cairo_set_source_sys_color (cr, state == 4 ? GTK_WIN32_SYS_COLOR_BTNSHADOW : GTK_WIN32_SYS_COLOR_BTNTEXT); mask_icon (cr, icon, 1, 1, width - 2, height - 2); } static void draw_tab_item (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_RAISED, TRUE, 0, 0, width, height + 2); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 2, 2, width - 4, height - 2); cairo_fill (cr); } static void draw_tab_pane (cairo_t *cr, int part, int state, int width, int height) { draw_edge (cr, EDGE_RAISED, TRUE, 0, 0, width, height); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE); cairo_rectangle (cr, 2, 2, width - 4, height - 4); cairo_fill (cr); } static void draw_tooltip (cairo_t *cr, int part, int state, int width, int height) { int xborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CXDLGFRAME) - gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CXEDGE); int yborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CYDLGFRAME) - gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CYEDGE); cairo_rectangle (cr, 0, 0, width, height); cairo_rectangle (cr, width - xborder, yborder, - (width - 2 * xborder), height - 2 * yborder); gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_WINDOWFRAME); cairo_fill (cr); } typedef struct _GtkWin32ThemePart GtkWin32ThemePart; struct _GtkWin32ThemePart { const char *class_name; gint part; gint size; GtkBorder margins; void (* draw_func) (cairo_t *cr, int part, int state, int width, int height); }; static GtkWin32ThemePart theme_parts[] = { { "button", 1, 0, { 3, 3, 3, 3 }, draw_button }, { "button", 2, 13, { 0, 0, 0, 0 }, draw_radio }, { "button", 3, 13, { 0, 0, 0, 0 }, draw_check }, { "button", 4, 0, { 3, 3, 3, 3 }, draw_frame }, { "edit", 1, 0, { 0, 0, 0, 0 }, draw_edit }, { "edit", 3, 0, { 0, 0, 0, 0 }, draw_edit_noborder }, { "edit", 6, 0, { 0, 0, 0, 0 }, draw_edit }, { "edit", 7, 0, { 0, 0, 0, 0 }, draw_edit }, { "edit", 8, 0, { 0, 0, 0, 0 }, draw_edit }, { "edit", 9, 0, { 0, 0, 0, 0 }, draw_edit }, { "tab", 1, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 2, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 3, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 4, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 5, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 6, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 7, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 8, 0, { 0, 0, 0, 0 }, draw_tab_item }, { "tab", 9, 0, { 0, 0, 0, 0 }, draw_tab_pane }, { "tooltip", 1, 0, { 0, 0, 0, 0 }, draw_tooltip }, { "window", 1, 0, { 0, 0, 0, 0 }, draw_window }, { "window", 7, 0, { 0, 0, 0, 0 }, draw_window_left }, { "window", 8, 0, { 0, 0, 0, 0 }, draw_window_right }, { "window", 9, 0, { 0, 0, 0, 0 }, draw_window_bottom }, { "window", 15, 0, { 0, 0, 0, 0 }, draw_window_button }, { "window", 17, 0, { 0, 0, 0, 0 }, draw_window_button }, { "window", 18, 0, { 0, 0, 0, 0 }, draw_window_button }, { "window", 21, 0, { 0, 0, 0, 0 }, draw_window_button } }; static const GtkWin32ThemePart * get_theme_part (const char *class_name, gint part) { gsize i; for (i = 0; i < G_N_ELEMENTS (theme_parts); i++) { if (g_str_equal (theme_parts[i].class_name, class_name) && theme_parts[i].part == part) return &theme_parts[i]; } return NULL; } void gtk_win32_draw_theme_background (cairo_t *cr, const char *class_name, int part, int state, int width, int height) { const GtkWin32ThemePart *theme_part; theme_part = get_theme_part (class_name, part); if (theme_part) { theme_part->draw_func (cr, part, state, width, height); } else { g_warning ("No fallback code to draw background for class \"%s\", part %d", class_name, part); } } void gtk_win32_get_theme_part_size (const char *class_name, int part, int state, int *width, int *height) { const GtkWin32ThemePart *theme_part; theme_part = get_theme_part (class_name, part); if (theme_part) { if (width) *width = theme_part->size; if (height) *height = theme_part->size; } else { if (width) *width = 1; if (height) *height = 1; } } void gtk_win32_get_theme_margins (const char *class_name, int part, int state, GtkBorder *out_margins) { const GtkWin32ThemePart *theme_part; theme_part = get_theme_part (class_name, part); if (theme_part) { *out_margins = theme_part->margins; } else { out_margins->top = out_margins->bottom = out_margins->left = out_margins->right = 0; } } static int FIXME_IMPLEMENT (int id) { g_warning ("win32 sys metric %d not implemented", id); return 0; } static struct { const char *name; int value; int (* get_value) (int id); } win32_default_metrics[] = { { "cxscreen", 0, FIXME_IMPLEMENT }, { "cyscreen", 0, FIXME_IMPLEMENT }, { "cxvscroll", 16, NULL }, { "cyhscroll", 16, NULL }, { "cycaption", 16, NULL }, { "cxborder", 1, NULL }, { "cyborder", 1, NULL }, { "cxdlgframe", 3, NULL }, { "cydlgframe", 3, NULL }, { "cyvthumb", 16, NULL }, { "cxhthumb", 16, NULL }, { "cxicon", 32, NULL }, { "cyicon", 32, NULL }, { "cxcursor", 32, NULL }, { "cycursor", 32, NULL }, { "cymenu", 19, NULL }, { "cxfullscreen", 0, FIXME_IMPLEMENT }, { "cyfullscreen", 0, FIXME_IMPLEMENT }, { "cykanjiwindow", 0, NULL }, { "mousepresent", 1, NULL }, { "cyvscroll", 16, NULL }, { "cxhscroll", 16, NULL }, { "debug", 0, NULL }, { "swapbutton", 0, NULL }, { "reserved1", 0, NULL }, { "reserved2", 0, NULL }, { "reserved3", 0, NULL }, { "reserved4", 0, NULL }, { "cxmin", 112, NULL }, { "cymin", 24, NULL }, { "cxsize", 18, NULL }, { "cysize", 15, NULL }, { "cxframe", 4, NULL }, { "cyframe", 4, NULL }, { "cxmintrack", 112, NULL }, { "cymintrack", 24, NULL }, { "cxdoubleclk", 0, FIXME_IMPLEMENT }, { "cydoubleclk", 0, FIXME_IMPLEMENT }, { "cxiconspacing", 75, NULL }, { "cyiconspacing", 75, NULL }, { "menudropalignment", 0, NULL }, { "penwindows", 0, NULL }, { "dbcsenabled", 1, NULL }, { "cmousebuttons", 3, NULL }, { "secure", 0, NULL }, { "cxedge", 2, NULL }, { "cyedge", 2, NULL }, { "cxminspacing", 160, NULL }, { "cyminspacing", 21, NULL }, { "cxsmicon", 16, NULL }, { "cysmicon", 16, NULL }, { "cysmcaption", 16, NULL }, { "cxsmsize", 15, NULL }, { "cysmsize", 15, NULL }, { "cxmenusize", 18, NULL }, { "cymenusize", 18, NULL }, { "arrange", 8, NULL }, { "cxminimized", 160, NULL }, { "cyminimized", 21, NULL }, { "cxmaxtrack", 0, FIXME_IMPLEMENT }, { "cymaxtrack", 0, FIXME_IMPLEMENT }, { "cxmaximized", 0, FIXME_IMPLEMENT }, { "cymaximized", 0, FIXME_IMPLEMENT }, { "network", 3, NULL }, { NULL, 0, NULL }, { NULL, 0, NULL }, { NULL, 0, NULL }, { "cleanboot", 0, NULL }, { "cxdrag", 4, NULL }, { "cydrag", 4, NULL }, { "showsounds", 0, NULL }, { "cxmenucheck", 13, NULL }, { "cymenucheck", 13, NULL }, { "slowmachine", 0, NULL }, { "mideastenabled", 0, NULL }, { "mousewheelpresent", 1, NULL }, { "xvirtualscreen", 0, FIXME_IMPLEMENT }, { "yvirtualscreen", 0, FIXME_IMPLEMENT }, { "cxvirtualscreen", 0, FIXME_IMPLEMENT }, { "cyvirtualscreen", 0, FIXME_IMPLEMENT }, { "cmonitors", 0, FIXME_IMPLEMENT }, { "samedisplayformat", 1, NULL }, { "immenabled", 1, NULL }, { "cxfocusborder", 1, NULL }, { "cyfocusborder", 1, NULL }, { NULL, 0, NULL }, { "tabletpc", 0, NULL }, { "mediacenter", 0, NULL }, { "starter", 0, NULL }, { "serverr2", 0, NULL }, { "cmetrics", 90, NULL }, { "mousehorizontalwheelpresent", 0, NULL }, { "cxpaddedborder", 0, NULL } }; const char * gtk_win32_get_sys_metric_name_for_id (gint id) { if (id >= 0 && id < G_N_ELEMENTS (win32_default_metrics)) return win32_default_metrics[id].name; else return NULL; } int gtk_win32_get_sys_metric_id_for_name (const char *name) { int i; g_return_val_if_fail (name != NULL, -1); for (i = 0; i < G_N_ELEMENTS (win32_default_metrics); i++) { if (win32_default_metrics[i].name == NULL) continue; if (g_str_equal (name, win32_default_metrics[i].name)) return i; } return -1; } int gtk_win32_get_sys_metric (gint id) { if (id < 0 || id >= G_N_ELEMENTS (win32_default_metrics)) return 0; if (win32_default_metrics[id].get_value) return win32_default_metrics[id].get_value (id); return win32_default_metrics[id].value; } static struct { const char *name; GdkRGBA rgba; } win32_default_colors[] = { #define RGB(r, g, b) { (r)/255.0, (g)/255.0, (b)/255., 1.0 } { "scrollbar", RGB(212, 208, 200) }, { "background", RGB(58, 110, 165) }, { "activecaption", RGB(10, 36, 106) }, { "inactivecaption", RGB(128, 128, 128) }, { "menu", RGB(212, 208, 200) }, { "window", RGB(255, 255, 255) }, { "windowframe", RGB(0, 0, 0) }, { "menutext", RGB(0, 0, 0) }, { "windowtext", RGB(0, 0, 0) }, { "captiontext", RGB(255, 255, 255) }, { "activeborder", RGB(212, 208, 200) }, { "inactiveborder", RGB(212, 208, 200) }, { "appworkspace", RGB(128, 128, 128) }, { "highlight", RGB(10, 36, 106) }, { "highlighttext", RGB(255, 255, 255) }, { "btnface", RGB(212, 208, 200) }, { "btnshadow", RGB(128, 128, 128) }, { "graytext", RGB(128, 128, 128) }, { "btntext", RGB(0, 0, 0) }, { "inactivecaptiontext", RGB(212, 208, 200) }, { "btnhighlight", RGB(255, 255, 255) }, { "3ddkshadow", RGB(64, 64, 64) }, { "3dlight", RGB(212, 208, 200) }, { "infotext", RGB(0, 0, 0) }, { "infobk", RGB(255, 255, 225) }, { "alternatebtnface", RGB(181, 181, 181) }, { "hotlight", RGB(0, 0, 200) }, { "gradientactivecaption", RGB(166, 202, 240) }, { "gradientinactivecaption", RGB(192, 192, 192) }, { "menuhilight", RGB(10, 36, 106) }, { "menubar", RGB(212, 208, 200) } #undef RGB }; const char * gtk_win32_get_sys_color_name_for_id (gint id) { if (id >= 0 && id < G_N_ELEMENTS (win32_default_colors)) return win32_default_colors[id].name; else return NULL; } int gtk_win32_get_sys_color_id_for_name (const char *name) { int i; g_return_val_if_fail (name != NULL, -1); for (i = 0; i < G_N_ELEMENTS (win32_default_colors); i++) { if (g_str_equal (name, win32_default_colors[i].name)) return i; } return -1; } void gtk_win32_get_sys_color (gint id, GdkRGBA *color) { if (id < 0 || id >= G_N_ELEMENTS (win32_default_colors)) { gdk_rgba_parse (color, "black"); return; } *color = win32_default_colors[id].rgba; }