804 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			804 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GTK - The GIMP Toolkit
 | |
|  * Copyright (C) 2016 Benjamin Otte <otte@gnome.org>
 | |
|  *
 | |
|  * 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 <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include <config.h>
 | |
| 
 | |
| #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;
 | |
| }
 | |
| 
 | 
