1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2016 Benjamin Otte <otte@gnome.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <config.h>
19
20 #include "gtkwin32drawprivate.h"
21
22 typedef enum {
23 ICON_CLOSE,
24 ICON_MINIMIZE,
25 ICON_MAXIMIZE,
26 ICON_RESTORE
27 } Icon;
28
29 const guchar icon_close_pixels[] = {
30 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00,
32 0x0c, 0x06, 0x00, 0x00,
33 0x1c, 0x07, 0x00, 0x00,
34 0xb8, 0x03, 0x00, 0x00,
35 0xf0, 0x01, 0x00, 0x00,
36 0xe0, 0x00, 0x00, 0x00,
37 0xf0, 0x01, 0x00, 0x00,
38 0xb8, 0x03, 0x00, 0x00,
39 0x1c, 0x07, 0x00, 0x00,
40 0x0c, 0x06, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00
43 };
44
45 const guchar icon_minimize_pixels[] = {
46 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00,
56 0xfc, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00
59 };
60
61 const guchar icon_maximize_pixels[] = {
62 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00,
64 0xfe, 0x07, 0x00, 0x00,
65 0xfe, 0x07, 0x00, 0x00,
66 0x02, 0x04, 0x00, 0x00,
67 0x02, 0x04, 0x00, 0x00,
68 0x02, 0x04, 0x00, 0x00,
69 0x02, 0x04, 0x00, 0x00,
70 0x02, 0x04, 0x00, 0x00,
71 0x02, 0x04, 0x00, 0x00,
72 0xfe, 0x07, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00
75 };
76
77 const guchar icon_restore_pixels[] = {
78 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00,
80 0xf8, 0x07, 0x00, 0x00,
81 0xf8, 0x07, 0x00, 0x00,
82 0x08, 0x04, 0x00, 0x00,
83 0x08, 0x04, 0x00, 0x00,
84 0xfe, 0x04, 0x00, 0x00,
85 0x82, 0x07, 0x00, 0x00,
86 0x82, 0x00, 0x00, 0x00,
87 0x82, 0x00, 0x00, 0x00,
88 0xfe, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00
91 };
92
93 static struct {
94 int width;
95 int height;
96 gsize pixels_size;
97 const guchar *pixels;
98 } icon_masks[] = {
99 { 13, 13, sizeof (icon_close_pixels), icon_close_pixels },
100 { 13, 13, sizeof (icon_minimize_pixels), icon_minimize_pixels },
101 { 13, 13, sizeof (icon_maximize_pixels), icon_maximize_pixels },
102 { 13, 13, sizeof (icon_restore_pixels), icon_restore_pixels }
103 };
104
105 static void
mask_icon(cairo_t * cr,Icon icon,double x,double y,double width,double height)106 mask_icon (cairo_t *cr,
107 Icon icon,
108 double x,
109 double y,
110 double width,
111 double height)
112 {
113 cairo_surface_t *surface;
114
115 surface = cairo_image_surface_create_for_data ((guchar *) icon_masks[icon].pixels,
116 CAIRO_FORMAT_A1,
117 icon_masks[icon].width,
118 icon_masks[icon].height,
119 icon_masks[icon].pixels_size / icon_masks[icon].height);
120 cairo_mask_surface (cr,
121 surface,
122 x + (width - icon_masks[icon].width) / 2,
123 y + (height - icon_masks[icon].height) / 2);
124 cairo_surface_destroy (surface);
125 }
126
127 static void
gtk_cairo_set_source_sys_color(cairo_t * cr,gint id)128 gtk_cairo_set_source_sys_color (cairo_t *cr,
129 gint id)
130 {
131 GdkRGBA rgba;
132
133 gtk_win32_get_sys_color (id, &rgba);
134 gdk_cairo_set_source_rgba (cr, &rgba);
135 }
136
137 static void
draw_outline(cairo_t * cr,int top_color_id,int bottom_color_id,int x,int y,int width,int height)138 draw_outline (cairo_t *cr,
139 int top_color_id,
140 int bottom_color_id,
141 int x,
142 int y,
143 int width,
144 int height)
145 {
146 gtk_cairo_set_source_sys_color (cr, top_color_id);
147 cairo_rectangle (cr, x, y, width, 1);
148 cairo_rectangle (cr, x, y, 1, height);
149 cairo_fill (cr);
150
151 gtk_cairo_set_source_sys_color (cr, bottom_color_id);
152 cairo_rectangle (cr, x + width, y + height, -1, -height);
153 cairo_rectangle (cr, x + width, y + height, -width, -1);
154 cairo_fill (cr);
155 }
156
157 typedef enum {
158 EDGE_RAISED_OUTER = 1 << 0,
159 EDGE_SUNKEN_OUTER = 1 << 1,
160 EDGE_RAISED_INNER = 1 << 2,
161 EDGE_SUNKEN_INNER = 1 << 3,
162 EDGE_RAISED = (EDGE_RAISED_OUTER | EDGE_RAISED_INNER),
163 EDGE_SUNKEN = (EDGE_SUNKEN_OUTER | EDGE_SUNKEN_INNER),
164 EDGE_ETCHED = (EDGE_SUNKEN_OUTER | EDGE_RAISED_INNER),
165 EDGE_BUMP = (EDGE_RAISED_OUTER | EDGE_SUNKEN_INNER)
166 } GtkWin32Edge;
167
168 static void
draw_edge(cairo_t * cr,GtkWin32Edge edge,gboolean soft,int x,int y,int width,int height)169 draw_edge (cairo_t *cr,
170 GtkWin32Edge edge,
171 gboolean soft,
172 int x,
173 int y,
174 int width,
175 int height)
176 {
177 switch (edge & (EDGE_RAISED_OUTER | EDGE_SUNKEN_OUTER))
178 {
179 case EDGE_RAISED_OUTER:
180 draw_outline (cr,
181 soft ? GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT : GTK_WIN32_SYS_COLOR_3DLIGHT,
182 GTK_WIN32_SYS_COLOR_3DDKSHADOW,
183 x, y, width, height);
184 break;
185 case EDGE_SUNKEN_OUTER:
186 draw_outline (cr,
187 soft ? GTK_WIN32_SYS_COLOR_3DDKSHADOW : GTK_WIN32_SYS_COLOR_BTNSHADOW,
188 GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT,
189 x, y, width, height);
190 break;
191 case (EDGE_RAISED_OUTER | EDGE_SUNKEN_OUTER):
192 return;
193 default:
194 break;
195 }
196
197 x += 1;
198 y += 1;
199 width -= 2;
200 height -= 2;
201
202 switch (edge & (EDGE_RAISED_INNER | EDGE_SUNKEN_INNER))
203 {
204 case EDGE_RAISED_INNER:
205 draw_outline (cr,
206 soft ? GTK_WIN32_SYS_COLOR_3DLIGHT : GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT,
207 GTK_WIN32_SYS_COLOR_BTNSHADOW,
208 x, y, width, height);
209 break;
210 case EDGE_SUNKEN_INNER:
211 draw_outline (cr,
212 soft ? GTK_WIN32_SYS_COLOR_BTNSHADOW : GTK_WIN32_SYS_COLOR_3DDKSHADOW,
213 GTK_WIN32_SYS_COLOR_3DLIGHT,
214 x, y, width, height);
215 break;
216 case (EDGE_RAISED_INNER | EDGE_SUNKEN_INNER):
217 return;
218 default:
219 break;
220 }
221 }
222
223 static void
draw_button(cairo_t * cr,int part,int state,int width,int height)224 draw_button (cairo_t *cr,
225 int part,
226 int state,
227 int width,
228 int height)
229 {
230 draw_edge (cr, state == 3 ? EDGE_SUNKEN : EDGE_RAISED, TRUE, 0, 0, width, height);
231
232 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
233 cairo_rectangle (cr, 2, 2, width - 4, height - 4);
234 cairo_fill (cr);
235 }
236
237 static void
draw_frame(cairo_t * cr,int part,int state,int width,int height)238 draw_frame (cairo_t *cr,
239 int part,
240 int state,
241 int width,
242 int height)
243 {
244 draw_edge (cr, EDGE_ETCHED, FALSE, 0, 0, width, height);
245
246 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
247 cairo_rectangle (cr, 2, 2, width - 4, height - 4);
248 cairo_fill (cr);
249 }
250
251 static void
draw_check(cairo_t * cr,int part,int state,int width,int height)252 draw_check (cairo_t *cr,
253 int part,
254 int state,
255 int width,
256 int height)
257 {
258 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT);
259 cairo_set_line_width (cr, 1.0);
260 cairo_rectangle (cr, 0.5, 0.5, width - 1.0, height - 1.0);
261 cairo_stroke (cr);
262 }
263
264 static void
draw_radio(cairo_t * cr,int part,int state,int width,int height)265 draw_radio (cairo_t *cr,
266 int part,
267 int state,
268 int width,
269 int height)
270 {
271 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNHIGHLIGHT);
272 cairo_set_line_width (cr, 1.0);
273 cairo_arc (cr, width / 2.0, height / 2.0, MIN (width, height) / 2.0 - 0.5, 0, G_PI * 2);
274 cairo_stroke (cr);
275 }
276
277 static void
draw_edit(cairo_t * cr,int part,int state,int width,int height)278 draw_edit (cairo_t *cr,
279 int part,
280 int state,
281 int width,
282 int height)
283 {
284 int xborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CXBORDER);
285 int yborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CYBORDER);
286
287 cairo_rectangle (cr, 0, 0, width, height);
288 gtk_cairo_set_source_sys_color (cr, (state == 6 || state == 4) ? GTK_WIN32_SYS_COLOR_BTNFACE
289 : GTK_WIN32_SYS_COLOR_WINDOW);
290 cairo_fill_preserve (cr);
291
292 cairo_rectangle (cr, width - xborder, yborder,
293 - (width - 2 * xborder), height - 2 * yborder);
294 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_WINDOWFRAME);
295 cairo_fill (cr);
296 }
297
298 static void
draw_edit_noborder(cairo_t * cr,int part,int state,int width,int height)299 draw_edit_noborder (cairo_t *cr,
300 int part,
301 int state,
302 int width,
303 int height)
304 {
305
306 cairo_rectangle (cr, 0, 0, width, height);
307 gtk_cairo_set_source_sys_color (cr, (state == 6 || state == 4) ? GTK_WIN32_SYS_COLOR_BTNFACE
308 : GTK_WIN32_SYS_COLOR_WINDOW);
309 cairo_fill (cr);
310 }
311
312 static void
draw_window(cairo_t * cr,int part,int state,int width,int height)313 draw_window (cairo_t *cr,
314 int part,
315 int state,
316 int width,
317 int height)
318 {
319 draw_edge (cr, EDGE_RAISED, TRUE, 0, 0, width, height + 2);
320
321 gtk_cairo_set_source_sys_color (cr, state == 2 ? GTK_WIN32_SYS_COLOR_INACTIVECAPTION
322 : GTK_WIN32_SYS_COLOR_ACTIVECAPTION);
323 cairo_rectangle (cr, 2, 2, width - 4, height - 2);
324 cairo_fill (cr);
325 }
326
327 static void
draw_window_left(cairo_t * cr,int part,int state,int width,int height)328 draw_window_left (cairo_t *cr,
329 int part,
330 int state,
331 int width,
332 int height)
333 {
334 draw_edge (cr, EDGE_RAISED, TRUE, 0, -2, width + 2, height + 4);
335
336 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
337 cairo_rectangle (cr, 2, 0, width - 2, height);
338 cairo_fill (cr);
339 }
340
341 static void
draw_window_right(cairo_t * cr,int part,int state,int width,int height)342 draw_window_right (cairo_t *cr,
343 int part,
344 int state,
345 int width,
346 int height)
347 {
348 draw_edge (cr, EDGE_RAISED, TRUE, -2, -2, width + 2, height + 4);
349
350 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
351 cairo_rectangle (cr, 0, 0, width - 2, height);
352 cairo_fill (cr);
353 }
354
355 static void
draw_window_bottom(cairo_t * cr,int part,int state,int width,int height)356 draw_window_bottom (cairo_t *cr,
357 int part,
358 int state,
359 int width,
360 int height)
361 {
362 draw_edge (cr, EDGE_RAISED, TRUE, 0, -2, width, height + 2);
363
364 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
365 cairo_rectangle (cr, 2, 0, width - 4, height - 2);
366 cairo_fill (cr);
367 }
368
369 static void
draw_window_button(cairo_t * cr,int part,int state,int width,int height)370 draw_window_button (cairo_t *cr,
371 int part,
372 int state,
373 int width,
374 int height)
375 {
376 Icon icon;
377
378
379 switch (part)
380 {
381 case 15: /* minimize */
382 icon = ICON_MINIMIZE;
383 break;
384 case 17: /* maximize */
385 icon = ICON_MAXIMIZE;
386 break;
387 default:
388 g_assert_not_reached ();
389 case 18: /* close */
390 icon = ICON_CLOSE;
391 break;
392 case 21: /* restore */
393 icon = ICON_RESTORE;
394 break;
395 }
396
397 draw_button (cr, 0, state, width, height);
398
399 gtk_cairo_set_source_sys_color (cr, state == 4 ? GTK_WIN32_SYS_COLOR_BTNSHADOW
400 : GTK_WIN32_SYS_COLOR_BTNTEXT);
401 mask_icon (cr, icon, 1, 1, width - 2, height - 2);
402 }
403
404 static void
draw_tab_item(cairo_t * cr,int part,int state,int width,int height)405 draw_tab_item (cairo_t *cr,
406 int part,
407 int state,
408 int width,
409 int height)
410 {
411 draw_edge (cr, EDGE_RAISED, TRUE, 0, 0, width, height + 2);
412
413 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
414 cairo_rectangle (cr, 2, 2, width - 4, height - 2);
415 cairo_fill (cr);
416 }
417
418 static void
draw_tab_pane(cairo_t * cr,int part,int state,int width,int height)419 draw_tab_pane (cairo_t *cr,
420 int part,
421 int state,
422 int width,
423 int height)
424 {
425 draw_edge (cr, EDGE_RAISED, TRUE, 0, 0, width, height);
426
427 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_BTNFACE);
428 cairo_rectangle (cr, 2, 2, width - 4, height - 4);
429 cairo_fill (cr);
430 }
431
432 static void
draw_tooltip(cairo_t * cr,int part,int state,int width,int height)433 draw_tooltip (cairo_t *cr,
434 int part,
435 int state,
436 int width,
437 int height)
438 {
439 int xborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CXDLGFRAME) -
440 gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CXEDGE);
441 int yborder = gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CYDLGFRAME) -
442 gtk_win32_get_sys_metric (GTK_WIN32_SYS_METRIC_CYEDGE);
443
444 cairo_rectangle (cr, 0, 0, width, height);
445 cairo_rectangle (cr, width - xborder, yborder,
446 - (width - 2 * xborder), height - 2 * yborder);
447 gtk_cairo_set_source_sys_color (cr, GTK_WIN32_SYS_COLOR_WINDOWFRAME);
448 cairo_fill (cr);
449 }
450
451 typedef struct _GtkWin32ThemePart GtkWin32ThemePart;
452 struct _GtkWin32ThemePart {
453 const char *class_name;
454 gint part;
455 gint size;
456 GtkBorder margins;
457 void (* draw_func) (cairo_t *cr,
458 int part,
459 int state,
460 int width,
461 int height);
462 };
463
464 static GtkWin32ThemePart theme_parts[] = {
465 { "button", 1, 0, { 3, 3, 3, 3 }, draw_button },
466 { "button", 2, 13, { 0, 0, 0, 0 }, draw_radio },
467 { "button", 3, 13, { 0, 0, 0, 0 }, draw_check },
468 { "button", 4, 0, { 3, 3, 3, 3 }, draw_frame },
469 { "edit", 1, 0, { 0, 0, 0, 0 }, draw_edit },
470 { "edit", 3, 0, { 0, 0, 0, 0 }, draw_edit_noborder },
471 { "edit", 6, 0, { 0, 0, 0, 0 }, draw_edit },
472 { "edit", 7, 0, { 0, 0, 0, 0 }, draw_edit },
473 { "edit", 8, 0, { 0, 0, 0, 0 }, draw_edit },
474 { "edit", 9, 0, { 0, 0, 0, 0 }, draw_edit },
475 { "tab", 1, 0, { 0, 0, 0, 0 }, draw_tab_item },
476 { "tab", 2, 0, { 0, 0, 0, 0 }, draw_tab_item },
477 { "tab", 3, 0, { 0, 0, 0, 0 }, draw_tab_item },
478 { "tab", 4, 0, { 0, 0, 0, 0 }, draw_tab_item },
479 { "tab", 5, 0, { 0, 0, 0, 0 }, draw_tab_item },
480 { "tab", 6, 0, { 0, 0, 0, 0 }, draw_tab_item },
481 { "tab", 7, 0, { 0, 0, 0, 0 }, draw_tab_item },
482 { "tab", 8, 0, { 0, 0, 0, 0 }, draw_tab_item },
483 { "tab", 9, 0, { 0, 0, 0, 0 }, draw_tab_pane },
484 { "tooltip", 1, 0, { 0, 0, 0, 0 }, draw_tooltip },
485 { "window", 1, 0, { 0, 0, 0, 0 }, draw_window },
486 { "window", 7, 0, { 0, 0, 0, 0 }, draw_window_left },
487 { "window", 8, 0, { 0, 0, 0, 0 }, draw_window_right },
488 { "window", 9, 0, { 0, 0, 0, 0 }, draw_window_bottom },
489 { "window", 15, 0, { 0, 0, 0, 0 }, draw_window_button },
490 { "window", 17, 0, { 0, 0, 0, 0 }, draw_window_button },
491 { "window", 18, 0, { 0, 0, 0, 0 }, draw_window_button },
492 { "window", 21, 0, { 0, 0, 0, 0 }, draw_window_button }
493 };
494
495 static const GtkWin32ThemePart *
get_theme_part(const char * class_name,gint part)496 get_theme_part (const char *class_name,
497 gint part)
498 {
499 gsize i;
500
501 for (i = 0; i < G_N_ELEMENTS (theme_parts); i++)
502 {
503 if (g_str_equal (theme_parts[i].class_name, class_name) &&
504 theme_parts[i].part == part)
505 return &theme_parts[i];
506 }
507
508 return NULL;
509 }
510
511 void
gtk_win32_draw_theme_background(cairo_t * cr,const char * class_name,int part,int state,int width,int height)512 gtk_win32_draw_theme_background (cairo_t *cr,
513 const char *class_name,
514 int part,
515 int state,
516 int width,
517 int height)
518 {
519 const GtkWin32ThemePart *theme_part;
520
521 theme_part = get_theme_part (class_name, part);
522
523 if (theme_part)
524 {
525 theme_part->draw_func (cr, part, state, width, height);
526 }
527 else
528 {
529 g_warning ("No fallback code to draw background for class \"%s\", part %d", class_name, part);
530 }
531 }
532
533 void
gtk_win32_get_theme_part_size(const char * class_name,int part,int state,int * width,int * height)534 gtk_win32_get_theme_part_size (const char *class_name,
535 int part,
536 int state,
537 int *width,
538 int *height)
539 {
540 const GtkWin32ThemePart *theme_part;
541
542 theme_part = get_theme_part (class_name, part);
543
544 if (theme_part)
545 {
546 if (width)
547 *width = theme_part->size;
548 if (height)
549 *height = theme_part->size;
550 }
551 else
552 {
553 if (width)
554 *width = 1;
555 if (height)
556 *height = 1;
557 }
558 }
559
560 void
gtk_win32_get_theme_margins(const char * class_name,int part,int state,GtkBorder * out_margins)561 gtk_win32_get_theme_margins (const char *class_name,
562 int part,
563 int state,
564 GtkBorder *out_margins)
565 {
566 const GtkWin32ThemePart *theme_part;
567
568 theme_part = get_theme_part (class_name, part);
569
570 if (theme_part)
571 {
572 *out_margins = theme_part->margins;
573 }
574 else
575 {
576 out_margins->top = out_margins->bottom = out_margins->left = out_margins->right = 0;
577 }
578 }
579
580 static int
FIXME_IMPLEMENT(int id)581 FIXME_IMPLEMENT (int id)
582 {
583 g_warning ("win32 sys metric %d not implemented", id);
584 return 0;
585 }
586
587 static struct {
588 const char *name;
589 int value;
590 int (* get_value) (int id);
591 } win32_default_metrics[] = {
592 { "cxscreen", 0, FIXME_IMPLEMENT },
593 { "cyscreen", 0, FIXME_IMPLEMENT },
594 { "cxvscroll", 16, NULL },
595 { "cyhscroll", 16, NULL },
596 { "cycaption", 16, NULL },
597 { "cxborder", 1, NULL },
598 { "cyborder", 1, NULL },
599 { "cxdlgframe", 3, NULL },
600 { "cydlgframe", 3, NULL },
601 { "cyvthumb", 16, NULL },
602 { "cxhthumb", 16, NULL },
603 { "cxicon", 32, NULL },
604 { "cyicon", 32, NULL },
605 { "cxcursor", 32, NULL },
606 { "cycursor", 32, NULL },
607 { "cymenu", 19, NULL },
608 { "cxfullscreen", 0, FIXME_IMPLEMENT },
609 { "cyfullscreen", 0, FIXME_IMPLEMENT },
610 { "cykanjiwindow", 0, NULL },
611 { "mousepresent", 1, NULL },
612 { "cyvscroll", 16, NULL },
613 { "cxhscroll", 16, NULL },
614 { "debug", 0, NULL },
615 { "swapbutton", 0, NULL },
616 { "reserved1", 0, NULL },
617 { "reserved2", 0, NULL },
618 { "reserved3", 0, NULL },
619 { "reserved4", 0, NULL },
620 { "cxmin", 112, NULL },
621 { "cymin", 24, NULL },
622 { "cxsize", 18, NULL },
623 { "cysize", 15, NULL },
624 { "cxframe", 4, NULL },
625 { "cyframe", 4, NULL },
626 { "cxmintrack", 112, NULL },
627 { "cymintrack", 24, NULL },
628 { "cxdoubleclk", 0, FIXME_IMPLEMENT },
629 { "cydoubleclk", 0, FIXME_IMPLEMENT },
630 { "cxiconspacing", 75, NULL },
631 { "cyiconspacing", 75, NULL },
632 { "menudropalignment", 0, NULL },
633 { "penwindows", 0, NULL },
634 { "dbcsenabled", 1, NULL },
635 { "cmousebuttons", 3, NULL },
636 { "secure", 0, NULL },
637 { "cxedge", 2, NULL },
638 { "cyedge", 2, NULL },
639 { "cxminspacing", 160, NULL },
640 { "cyminspacing", 21, NULL },
641 { "cxsmicon", 16, NULL },
642 { "cysmicon", 16, NULL },
643 { "cysmcaption", 16, NULL },
644 { "cxsmsize", 15, NULL },
645 { "cysmsize", 15, NULL },
646 { "cxmenusize", 18, NULL },
647 { "cymenusize", 18, NULL },
648 { "arrange", 8, NULL },
649 { "cxminimized", 160, NULL },
650 { "cyminimized", 21, NULL },
651 { "cxmaxtrack", 0, FIXME_IMPLEMENT },
652 { "cymaxtrack", 0, FIXME_IMPLEMENT },
653 { "cxmaximized", 0, FIXME_IMPLEMENT },
654 { "cymaximized", 0, FIXME_IMPLEMENT },
655 { "network", 3, NULL },
656 { NULL, 0, NULL },
657 { NULL, 0, NULL },
658 { NULL, 0, NULL },
659 { "cleanboot", 0, NULL },
660 { "cxdrag", 4, NULL },
661 { "cydrag", 4, NULL },
662 { "showsounds", 0, NULL },
663 { "cxmenucheck", 13, NULL },
664 { "cymenucheck", 13, NULL },
665 { "slowmachine", 0, NULL },
666 { "mideastenabled", 0, NULL },
667 { "mousewheelpresent", 1, NULL },
668 { "xvirtualscreen", 0, FIXME_IMPLEMENT },
669 { "yvirtualscreen", 0, FIXME_IMPLEMENT },
670 { "cxvirtualscreen", 0, FIXME_IMPLEMENT },
671 { "cyvirtualscreen", 0, FIXME_IMPLEMENT },
672 { "cmonitors", 0, FIXME_IMPLEMENT },
673 { "samedisplayformat", 1, NULL },
674 { "immenabled", 1, NULL },
675 { "cxfocusborder", 1, NULL },
676 { "cyfocusborder", 1, NULL },
677 { NULL, 0, NULL },
678 { "tabletpc", 0, NULL },
679 { "mediacenter", 0, NULL },
680 { "starter", 0, NULL },
681 { "serverr2", 0, NULL },
682 { "cmetrics", 90, NULL },
683 { "mousehorizontalwheelpresent", 0, NULL },
684 { "cxpaddedborder", 0, NULL }
685 };
686
687 const char *
gtk_win32_get_sys_metric_name_for_id(gint id)688 gtk_win32_get_sys_metric_name_for_id (gint id)
689 {
690 if (id >= 0 && id < G_N_ELEMENTS (win32_default_metrics))
691 return win32_default_metrics[id].name;
692 else
693 return NULL;
694 }
695
696 int
gtk_win32_get_sys_metric_id_for_name(const char * name)697 gtk_win32_get_sys_metric_id_for_name (const char *name)
698 {
699 int i;
700
701 g_return_val_if_fail (name != NULL, -1);
702
703 for (i = 0; i < G_N_ELEMENTS (win32_default_metrics); i++)
704 {
705 if (win32_default_metrics[i].name == NULL)
706 continue;
707
708 if (g_str_equal (name, win32_default_metrics[i].name))
709 return i;
710 }
711
712 return -1;
713 }
714
715 int
gtk_win32_get_sys_metric(gint id)716 gtk_win32_get_sys_metric (gint id)
717 {
718 if (id < 0 || id >= G_N_ELEMENTS (win32_default_metrics))
719 return 0;
720
721 if (win32_default_metrics[id].get_value)
722 return win32_default_metrics[id].get_value (id);
723
724 return win32_default_metrics[id].value;
725 }
726
727 static struct {
728 const char *name;
729 GdkRGBA rgba;
730 } win32_default_colors[] = {
731 #define RGB(r, g, b) { (r)/255.0, (g)/255.0, (b)/255., 1.0 }
732 { "scrollbar", RGB(212, 208, 200) },
733 { "background", RGB(58, 110, 165) },
734 { "activecaption", RGB(10, 36, 106) },
735 { "inactivecaption", RGB(128, 128, 128) },
736 { "menu", RGB(212, 208, 200) },
737 { "window", RGB(255, 255, 255) },
738 { "windowframe", RGB(0, 0, 0) },
739 { "menutext", RGB(0, 0, 0) },
740 { "windowtext", RGB(0, 0, 0) },
741 { "captiontext", RGB(255, 255, 255) },
742 { "activeborder", RGB(212, 208, 200) },
743 { "inactiveborder", RGB(212, 208, 200) },
744 { "appworkspace", RGB(128, 128, 128) },
745 { "highlight", RGB(10, 36, 106) },
746 { "highlighttext", RGB(255, 255, 255) },
747 { "btnface", RGB(212, 208, 200) },
748 { "btnshadow", RGB(128, 128, 128) },
749 { "graytext", RGB(128, 128, 128) },
750 { "btntext", RGB(0, 0, 0) },
751 { "inactivecaptiontext", RGB(212, 208, 200) },
752 { "btnhighlight", RGB(255, 255, 255) },
753 { "3ddkshadow", RGB(64, 64, 64) },
754 { "3dlight", RGB(212, 208, 200) },
755 { "infotext", RGB(0, 0, 0) },
756 { "infobk", RGB(255, 255, 225) },
757 { "alternatebtnface", RGB(181, 181, 181) },
758 { "hotlight", RGB(0, 0, 200) },
759 { "gradientactivecaption", RGB(166, 202, 240) },
760 { "gradientinactivecaption", RGB(192, 192, 192) },
761 { "menuhilight", RGB(10, 36, 106) },
762 { "menubar", RGB(212, 208, 200) }
763 #undef RGB
764 };
765
766 const char *
gtk_win32_get_sys_color_name_for_id(gint id)767 gtk_win32_get_sys_color_name_for_id (gint id)
768 {
769 if (id >= 0 && id < G_N_ELEMENTS (win32_default_colors))
770 return win32_default_colors[id].name;
771 else
772 return NULL;
773 }
774
775 int
gtk_win32_get_sys_color_id_for_name(const char * name)776 gtk_win32_get_sys_color_id_for_name (const char *name)
777 {
778 int i;
779
780 g_return_val_if_fail (name != NULL, -1);
781
782 for (i = 0; i < G_N_ELEMENTS (win32_default_colors); i++)
783 {
784 if (g_str_equal (name, win32_default_colors[i].name))
785 return i;
786 }
787
788 return -1;
789 }
790
791 void
gtk_win32_get_sys_color(gint id,GdkRGBA * color)792 gtk_win32_get_sys_color (gint id,
793 GdkRGBA *color)
794 {
795 if (id < 0 || id >= G_N_ELEMENTS (win32_default_colors))
796 {
797 gdk_rgba_parse (color, "black");
798 return;
799 }
800
801 *color = win32_default_colors[id].rgba;
802 }
803
804