1 /* look-gtk.c - look 'n feel type: GTK
2    Copyright (C) 1996-2017 Paul Sheer
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
9    This program 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
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307, USA.
18  */
19 
20 #include <config.h>
21 #include <stdio.h>
22 #include <my_string.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 
26 #include <X11/Intrinsic.h>
27 #include "lkeysym.h"
28 
29 #include "stringtools.h"
30 #include "app_glob.c"
31 #include "coolwidget.h"
32 #include "coollocal.h"
33 
34 #include "mad.h"
35 
36 extern struct look *look;
37 
38 extern void look_cool_search_replace_dialog (Window parent, int x, int y, char **search_text, char **replace_text, char **arg_order, const char *heading, int option);
39 
40 extern CWidget *look_cool_draw_file_list (const char *identifier, Window parent, int x, int y,
41 					 int width, int height, int line, int column,
42 					 struct file_entry *directentry, long options);
43 
44 extern CWidget *look_cool_redraw_file_list (const char *identifier,
45 						  struct file_entry *directentry, int preserve);
46 
47 extern struct file_entry *look_cool_get_file_list_line (CWidget * w, int line);
48 
49 Window find_mapped_window (Window w);
50 
51 extern char *look_cool_get_file_or_dir (Window parent, int x, int y, const char *dir,
52 					const char *file, const char *label, int options);
53 
54 extern void look_cool_draw_browser (const char *ident, Window parent, int x, int y, const char *dir,
55 				    const char *file, const char *label);
56 
57 
58 /* }}} file browser stuff */
59 
60 int find_menu_hotkey (struct menu_item m[], int this, int num);
61 
62 /* outermost bevel */
63 #define BEVEL_MAIN	2
64 /* next-outermost bevel */
65 #define BEVEL_IN 	2
66 #define BEVEL_OUT	2
67 /* between items, and between items and next-outermost bevel */
68 #define SPACING		2
69 /* between items rectangle and text */
70 #define RELIEF		3
71 
72 #define S		SPACING
73 /* between window border and items */
74 #define O		(BEVEL_OUT + SPACING)
75 /* total height of an item */
76 
77 /* size of bar item */
78 #define BAR_HEIGHT	4
79 
80 #define H		(FONT_PIX_PER_LINE + RELIEF * 2)
81 
82 #define B		BAR_HEIGHT
83 
look_gtk_get_default_widget_font(void)84 static char *look_gtk_get_default_widget_font (void)
85 {
86     return "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*";
87 }
88 
look_gtk_get_menu_item_extents(int n,int j,struct menu_item m[],int * border,int * relief,int * y1,int * y2)89 static void look_gtk_get_menu_item_extents (int n, int j, struct menu_item m[], int *border, int *relief, int *y1, int *y2)
90 {
91     int i, n_items = 0, n_bars = 0;
92 
93     *border = O;
94     *relief = RELIEF;
95 
96     if (!n || j < 0) {
97 	*y1 = O;
98 	*y2 = *y1 + H;
99     } else {
100 	int not_bar;
101 	not_bar = (m[j].text[2] != '\0');
102 	for (i = 0; i < j; i++)
103 	    if (m[i].text[2])
104 		n_items++;
105 	    else
106 		n_bars++;
107 	*y1 = O + n_items * (H + S) + n_bars * (B + S) + (not_bar ? 0 : 2);
108 	*y2 = *y1 + (not_bar ? H : (B - 4));
109     }
110 }
111 
112 unsigned long bevel_background_color = 1;
113 
look_gtk_menu_draw(Window win,int w,int h,struct menu_item m[],int n,int light)114 static void look_gtk_menu_draw (Window win, int w, int h, struct menu_item m[], int n, int light)
115 {
116     int i, y1, y2, offset = 0;
117     static int last_light = 0, last_n = 0;
118     static Window last_win = 0;
119 
120     render_bevel (win, 0, 0, w - 1, h - 1, BEVEL_MAIN, 0);
121 #if 0
122     render_bevel (win, BEVEL_IN, BEVEL_IN, w - 1 - BEVEL_IN, h - 1 - BEVEL_IN, BEVEL_OUT - BEVEL_IN, 1);
123 #endif
124 
125     if (last_win == win && last_n != n) {
126 	XClearWindow (CDisplay, win);
127     } else if (last_light >= 0 && last_light < n) {
128 	int border, relief;
129 	look_gtk_get_menu_item_extents (n, last_light, m, &border, &relief, &y1, &y2);
130 	CSetColor (COLOR_FLAT);
131 	CRectangle (win, O - 1, y1 - 1, w - O * 2 + 2, y2 - y1 + 2);
132     }
133     last_win = win;
134     last_n = n;
135     CPushFont ("widget", 0);
136     for (i = 0; i < n; i++) {
137 	int border, relief;
138 	look_gtk_get_menu_item_extents (n, i, m, &border, &relief, &y1, &y2);
139 	if (i == light && m[i].text[2]) {
140 	    offset = 1;
141 	    bevel_background_color = color_widget (14);
142 	    render_bevel (win, O - 1, y1 - 1, w - O, y2, 2, 2);
143 	    bevel_background_color = COLOR_FLAT;
144 	} else {
145 	    if (!(m[i].text[2])) {
146 		CSetColor (color_widget (9));
147 		CLine (win, O, y1 - 1, w - O, y1 - 1);
148 		CSetColor (color_widget (14));
149 		CLine (win, O, y1, w - O, y1);
150 	    }
151 	    offset = 0;
152 	}
153 	if (m[i].text[2]) {
154 
155 	    char *u;
156 	    u = strrchr (m[i].text, '\t');
157 	    if (u)
158 		*u = 0;
159 	    CSetColor (COLOR_BLACK);
160 	    if (m[i].hot_key == '~')
161 		m[i].hot_key = find_menu_hotkey (m, i, n);
162 	    if (i == light)
163 		CSetBackgroundColor (color_widget (14));
164 	    else
165 		CSetBackgroundColor (COLOR_FLAT);
166 	    drawstring_xy_hotkey (win, RELIEF + O - offset,
167 			  RELIEF + y1 - offset, m[i].text, m[i].hot_key);
168 	    if (u) {
169 		drawstring_xy (win, RELIEF + O + (w - (O + RELIEF) * 2 - CImageStringWidth (u + 1)) - offset,
170 			       RELIEF + y1 - offset, u + 1);
171 		*u = '\t';
172 	    }
173 	}
174     }
175     last_light = light;
176     CPopFont ();
177 }
178 
look_gtk_render_menu_button(CWidget * wdt)179 static void look_gtk_render_menu_button (CWidget * wdt)
180 {
181     int w = wdt->width, h = wdt->height;
182     int x = 0, y = 0;
183 
184     Window win = wdt->winid;
185 
186     if (wdt->disabled)
187 	goto disabled;
188     if (wdt->options & BUTTON_PRESSED || wdt->droppedmenu) {
189 	render_bevel (win, x, y, x + w - 1, y + h - 1, 2, 0);
190     } else {
191   disabled:
192 	CSetColor (COLOR_FLAT);
193 	XDrawRectangle (CDisplay, win, CGC, x, y, w - 1, h - 1);
194 	XDrawRectangle (CDisplay, win, CGC, x + 1, y + 1, w - 3, h - 3);
195     }
196 
197     if (!wdt->label)
198 	return;
199     if (!(*(wdt->label)))
200 	return;
201     CSetColor (COLOR_BLACK);
202     CPushFont ("widget", 0);
203     CSetBackgroundColor (COLOR_FLAT);
204     drawstring_xy_hotkey (win, x + 2 + BUTTON_RELIEF, y + 2 + BUTTON_RELIEF, wdt->label, wdt->hotkey);
205     CPopFont ();
206 }
207 
look_gtk_render_button(CWidget * wdt)208 static void look_gtk_render_button (CWidget * wdt)
209 {
210     int w = wdt->width, h = wdt->height;
211     int x = 0, y = 0;
212     XGCValues gcv;
213 
214     Window win = wdt->winid;
215 #define BUTTON_BEVEL 2
216 
217     if (wdt->pixmap_mask) {
218 	gcv.clip_mask = wdt->pixmap_mask;
219 	XChangeGC (CDisplay, CGC, GCClipMask, &gcv);
220     }
221 
222     if (wdt->disabled)
223 	goto disabled;
224     if (wdt->options & BUTTON_PRESSED) {
225 	bevel_background_color = color_widget (10);
226 	render_bevel (win, x, y, x + w - 1, y + h - 1, BUTTON_BEVEL, 3);
227 	bevel_background_color = COLOR_FLAT;
228 	CSetBackgroundColor (color_widget (10));
229     } else if (wdt->options & BUTTON_HIGHLIGHT) {
230 	bevel_background_color = color_widget (14);
231 	render_bevel (win, x, y, x + w - 1, y + h - 1, 2, 2);
232 	bevel_background_color = COLOR_FLAT;
233 	CSetBackgroundColor (color_widget (14));
234     } else {
235       disabled:
236 	render_bevel (win, x, y, x + w - 1, y + h - 1, BUTTON_BEVEL, 2);
237 	CSetBackgroundColor (COLOR_FLAT);
238     }
239 
240     if (wdt->label) {
241 	if ((*(wdt->label))) {
242 	    CSetColor (COLOR_BLACK);
243 	    CPushFont ("widget", 0);
244 	    drawstring_xy_hotkey (win, x + 2 + BUTTON_RELIEF, y + 2 + BUTTON_RELIEF, wdt->label,
245 				  wdt->hotkey);
246 	    CPopFont ();
247 	}
248     }
249     if (wdt->pixmap_mask) {
250 	gcv.clip_mask = 0;
251 	XChangeGC (CDisplay, CGC, GCClipMask, &gcv);
252     }
253 }
254 
look_gtk_render_bar(CWidget * wdt)255 static void look_gtk_render_bar (CWidget * wdt)
256 {
257     int w = wdt->width, h = wdt->height;
258     Window win = wdt->winid;
259     CSetColor (color_widget (9));
260     CLine (win, 0, 0, w - 1, 0);
261     CSetColor (color_widget (15));
262     CLine (win, 0, h - 1, w - 1, h - 1);
263 }
264 
look_gtk_render_sunken_bevel(Window win,int x1,int y1,int x2,int y2,int thick,int sunken)265 void look_gtk_render_sunken_bevel (Window win, int x1, int y1, int x2, int y2, int thick,
266 				   int sunken)
267 {
268     int i;
269 
270     CSetColor (color_widget (9));
271     CLine (win, x1, y1, x2, y1);
272     CLine (win, x1, y1 + 1, x1, y2);
273 
274     if (thick > 1) {
275 	CSetColor (color_widget (0));
276 	CLine (win, x1 + 1, y1 + 1, x2 - 1, y1 + 1);
277 	CLine (win, x1 + 1, y1 + 2, x1 + 1, y2 - 1);
278     }
279 
280     CSetColor (color_widget (15));
281     CLine (win, x2, y1 + 1, x2, y2);
282     CLine (win, x1 + 1, y2, x2 - 1, y2);
283 
284     if (thick > 1) {
285 	CSetColor (bevel_background_color == COLOR_WHITE ? COLOR_FLAT : bevel_background_color);
286 	CLine (win, x2 - 1, y1 + 2, x2 - 1, y2 - 1);
287 	CLine (win, x1 + 2, y2 - 1, x2 - 2, y2 - 1);
288     }
289 
290     if (thick > 2) {
291 	CSetColor (bevel_background_color);
292 	for (i = 2; i < thick; i++) {
293 	    CLine (win, x1 + i, y1 + i, x2 - 1 - i, y1 + i);
294 	    CLine (win, x1 + i, y1 + i + 1, x1 + i, y2 - 1 - i);
295 	    CLine (win, x2 - i, y1 + i, x2 - i, y2 - i);
296 	    CLine (win, x1 + i, y2 - i, x2 - i - 1, y2 - i);
297 	}
298     }
299 
300     if ((sunken & 2)) {
301 	CSetColor (bevel_background_color);
302 	CRectangle (win, x1 + thick, y1 + thick, x2 - x1 - 2 * thick + 1, y2 - y1 - 2 * thick + 1);
303     }
304 }
305 
look_gtk_render_raised_bevel(Window win,int x1,int y1,int x2,int y2,int thick,int sunken)306 static void look_gtk_render_raised_bevel (Window win, int x1, int y1, int x2, int y2, int thick,
307 					  int sunken)
308 {
309     int i;
310 
311     if (bevel_background_color == 1)
312 	bevel_background_color = COLOR_FLAT;
313 
314     x2--;
315     y2--;
316 
317     CSetColor (color_widget (15));
318     CLine (win, x1, y1, x1, y2);
319     CLine (win, x1 + 1, y1, x2, y1);
320     if (thick > 1) {
321 	CLine (win, x1 + 1, y2, x1 + 1, y2);
322 	CLine (win, x2, y1 + 1, x2, y1 + 1);
323 
324 	CSetColor (color_widget (9));
325 	CLine (win, x1 + 2, y2, x2 - 1, y2);
326 	CLine (win, x2, y1 + 2, x2, y2);
327     }
328 
329     CSetColor (color_widget (0));
330     CLine (win, x1, y2 + 1, x2, y2 + 1);
331     CLine (win, x2 + 1, y1, x2 + 1, y2 + 1);
332 
333     if (thick > 1) {
334 	CSetColor (bevel_background_color);
335 	CLine (win, x1 + 1, y1 + 1, x1 + 1, y2 - 1);
336 	CLine (win, x1 + 1, y1 + 1, x2 - 1, y1 + 1);
337     }
338 
339     x2++;
340     y2++;
341 
342     if (thick > 2) {
343 	for (i = 2; i < thick; i++) {
344 	    CLine (win, x1 + i, y1 + i, x2 - 1 - i, y1 + i);
345 	    CLine (win, x1 + i, y1 + i + 1, x1 + i, y2 - 1 - i);
346 	    CLine (win, x2 - i, y1 + i, x2 - i, y2 - i);
347 	    CLine (win, x1 + i, y2 - i, x2 - i - 1, y2 - i);
348 	}
349     }
350     if ((sunken & 2)) {
351 	CSetColor (bevel_background_color);
352 	CRectangle (win, x1 + thick, y1 + thick, x2 - x1 - 2 * thick + 1, y2 - y1 - 2 * thick + 1);
353     }
354 }
355 
look_gtk_draw_hotkey_understroke(Window win,int x,int y,int hotkey)356 static void look_gtk_draw_hotkey_understroke (Window win, int x, int y, int hotkey)
357 {
358     CLine (win, x, y + 1, x + FONT_PER_CHAR (hotkey) - 1, y + 1);
359 }
360 
look_gtk_render_text(CWidget * wdt)361 static void look_gtk_render_text (CWidget * wdt)
362 {
363     Window win = wdt->winid;
364     char text[1024], *p, *q;
365     int hot, y, w = wdt->width, center = 0;
366 
367     CPushFont ("widget", 0);
368 
369     CSetColor (COLOR_FLAT);
370     CRectangle (win, 0, 0, w - 1, wdt->height - 1);
371     CSetColor (COLOR_BLACK);
372 
373     hot = wdt->hotkey;		/* a letter that needs underlining */
374     y = 1;			/* bevel */
375     q = wdt->text;
376 
377     CSetBackgroundColor (COLOR_FLAT);
378     for (;;) {
379 	p = strchr (q, '\n');
380 	if (!p) {	/* last line */
381 	    if (wdt->options & TEXT_CENTRED)
382 		center = (wdt->width - (TEXT_RELIEF + 1) * 2 - CImageTextWidth (q, strlen (q))) / 2;
383 	    drawstring_xy_hotkey (win, TEXT_RELIEF + 1 + center,
384 		 TEXT_RELIEF + y, q, hot);
385 	    break;
386 	} else {
387 	    int l;
388 	    l = min (1023, (unsigned long) p - (unsigned long) q);
389 	    memcpy (text, q, l);
390 	    text[l] = 0;
391 	    if (wdt->options & TEXT_CENTRED)
392 		center = (wdt->width - (TEXT_RELIEF + 1) * 2 - CImageTextWidth (q, l)) / 2;
393 	    drawstring_xy_hotkey (win, TEXT_RELIEF + 1 + center,
394 		 TEXT_RELIEF + y, text, hot);
395 	}
396 	y += FONT_PIX_PER_LINE;
397 	hot = 0;	/* only for first line */
398 	q = p + 1;	/* next line */
399     }
400 
401     CPopFont ();
402 
403     return;
404 }
405 
look_gtk_render_window(CWidget * wdt)406 static void look_gtk_render_window (CWidget * wdt)
407 {
408     int w = wdt->width, h = wdt->height;
409 
410     Window win = wdt->winid;
411 
412     if (wdt->options & WINDOW_NO_BORDER)
413 	return;
414 
415     if (wdt->position & WINDOW_RESIZABLE) {
416 	CSetColor (color_widget (13));
417 	CLine (win, w - 4, h - 31, w - 31, h - 4);
418 	CLine (win, w - 4, h - 21, w - 21, h - 4);
419 	CLine (win, w - 4, h - 11, w - 11, h - 4);
420 
421 	CLine (win, w - 4, h - 32, w - 32, h - 4);
422 	CLine (win, w - 4, h - 22, w - 22, h - 4);
423 	CLine (win, w - 4, h - 12, w - 12, h - 4);
424 
425 	CSetColor (color_widget (3));
426 	CLine (win, w - 4, h - 27, w - 27, h - 4);
427 	CLine (win, w - 4, h - 17, w - 17, h - 4);
428 	CLine (win, w - 4, h -  7, w -  7, h - 4);
429 
430 	CLine (win, w - 4, h - 28, w - 28, h - 4);
431 	CLine (win, w - 4, h - 18, w - 18, h - 4);
432 	CLine (win, w - 4, h -  8, w -  8, h - 4);
433     }
434     render_bevel (win, 0, 0, w - 1, h - 1, 2, 0);
435     if (CRoot != wdt->parentid)
436 	if (win == CGetFocus ())
437 	    render_bevel (win, 4, 4, w - 5, h - 5, 3, 1);
438 }
439 
look_gtk_render_vert_scrollbar(Window win,int x,int y,int w,int h,int pos,int prop,int pos2,int prop2,int flags)440 static void look_gtk_render_vert_scrollbar (Window win, int x, int y, int w, int h, int pos, int prop, int pos2, int prop2, int flags)
441 {
442     int l = h - 10 * w / 3 - 5;
443 
444     render_bevel (win, 0, 0, w - 1, h - 1, 2, 1);
445     CSetColor (COLOR_FLAT);
446     CRectangle (win, 2, w + 2 * w / 3 + 2, w - 4, (l - 5) * pos / 65535);
447     CRectangle (win, 2, w + 2 * w / 3 + 3 + l * (prop + pos) / 65535, w - 4, h - 1 - w - 2 * w / 3 - (w + 2 * w / 3 + 4 + l * (prop + pos) / 65535));
448 
449     if (flags & 32) {
450 	bevel_background_color = ((flags & 15) == 1) ? color_widget (14) : COLOR_FLAT;
451 	render_bevel (win, 2, 2, w - 3, w + 1, 2, 2);
452 	bevel_background_color = ((flags & 15) == 2) ? color_widget (14) : COLOR_FLAT;
453 	render_bevel (win, 2, w + 2, w - 3, w + 2 * w / 3 + 1, 2, 2);
454 	bevel_background_color = ((flags & 15) == 4) ? color_widget (14) : COLOR_FLAT;
455 	render_bevel (win, 2, h - 2 - w, w - 3, h - 3, 2, 2);
456 	bevel_background_color = ((flags & 15) == 5) ? color_widget (14) : COLOR_FLAT;
457 	render_bevel (win, 2, h - 2 - w - 2 * w / 3, w - 3, h - 3 - w, 2, 2);
458 	bevel_background_color = ((flags & 15) == 3) ? color_widget (14) : COLOR_FLAT;
459 	render_bevel (win, 2, w + 2 * w / 3 + 2 + (l - 5) * pos / 65535, w - 3, w + 2 * w / 3 + 7 + (l - 5) * (prop + pos) / 65535, 2, 2);
460 	bevel_background_color = COLOR_FLAT;
461     } else {
462 	render_bevel (win, 2, 2, w - 3, w + 1, 2, 2 | ((flags & 15) == 1));
463 	render_bevel (win, 2, w + 2, w - 3, w + 2 * w / 3 + 1, 2, 2 | ((flags & 15) == 2));
464 	render_bevel (win, 2, h - 2 - w, w - 3, h - 3, 2, 2 | ((flags & 15) == 4));
465 	render_bevel (win, 2, h - 2 - w - 2 * w / 3, w - 3, h - 3 - w, 2, 2 | ((flags & 15) == 5));
466 	if ((flags & 15) == 3) {
467 	    CSetColor (color_widget (5));
468 	    XDrawRectangle (CDisplay, win, CGC, 4, w + 2 * w / 3 + 4 + (l - 5) * pos2 / 65535, w - 10, 2 + (l - 5) * prop2 / 65535);
469 	}
470 	render_bevel (win, 2, w + 2 * w / 3 + 2 + (l - 5) * pos / 65535, w - 3, w + 2 * w / 3 + 7 + (l - 5) * (prop + pos) / 65535, 2, 2 | ((flags & 15) == 3));
471     }
472 }
473 
look_gtk_render_hori_scrollbar(Window win,int x,int y,int h,int w,int pos,int prop,int flags)474 static void look_gtk_render_hori_scrollbar (Window win, int x, int y, int h, int w, int pos, int prop, int flags)
475 {
476     int l = h - 10 * w / 3 - 5, k;
477     k = (l - 5) * pos / 65535;
478 
479     render_bevel (win, 0, 0, h - 1, w - 1, 2, 1);
480     CSetColor (COLOR_FLAT);
481 
482     CRectangle (win, w + 2 * w / 3 + 2, 2, (l - 5) * pos / 65535, w - 4);
483     CRectangle (win, w + 2 * w / 3 + 3 + l * (prop + pos) / 65535, 2, h - 1 - w - 2 * w / 3 - (w + 2 * w / 3 + 4 + l * (prop + pos) / 65535), w - 4);
484 
485     if (flags & 32) {
486 	bevel_background_color = ((flags & 15) == 1) ? color_widget (14) : COLOR_FLAT;
487 	render_bevel (win, 2, 2, w + 1, w - 3, 2, 2);
488 	bevel_background_color = ((flags & 15) == 2) ? color_widget (14) : COLOR_FLAT;
489 	render_bevel (win, w + 2, 2, w + 2 * w / 3 + 1, w - 3, 2, 2);
490 	bevel_background_color = ((flags & 15) == 4) ? color_widget (14) : COLOR_FLAT;
491 	render_bevel (win, h - 2 - w, 2, h - 3, w - 3, 2, 2);
492 	bevel_background_color = ((flags & 15) == 5) ? color_widget (14) : COLOR_FLAT;
493 	render_bevel (win, h - 2 - w - 2 * w / 3, 2, h - 3 - w, w - 3, 2, 2);
494 	bevel_background_color = ((flags & 15) == 3) ? color_widget (14) : COLOR_FLAT;
495 	render_bevel (win, w + 2 * w / 3 + 2 + k, 2, w + 2 * w / 3 + 7 + (l - 5) * (prop + pos) / 65535, w - 3, 2, 2);
496 	bevel_background_color = COLOR_FLAT;
497     } else {
498 	render_bevel (win, 2, 2, w + 1, w - 3, 2, 2 | ((flags & 15) == 1));
499 	render_bevel (win, w + 2, 2, w + 2 * w / 3 + 1, w - 3, 2, 2 | ((flags & 15) == 2));
500 	render_bevel (win, h - 2 - w, 2, h - 3, w - 3, 2, 2 | ((flags & 15) == 4));
501 	render_bevel (win, h - 2 - w - 2 * w / 3, 2, h - 3 - w, w - 3, 2, 2 | ((flags & 15) == 5));
502 	render_bevel (win, w + 2 * w / 3 + 2 + k, 2, w + 2 * w / 3 + 7 + (l - 5) * (prop + pos) / 65535, w - 3, 2, 2 | ((flags & 15) == 3));
503     }
504 }
505 
look_gtk_render_scrollbar(CWidget * wdt)506 static void look_gtk_render_scrollbar (CWidget * wdt)
507 {
508     int flags = wdt->options;
509     if (!wdt)
510 	return;
511     if (wdt->numlines < 0)
512 	wdt->numlines = 0;
513     if (wdt->firstline < 0)
514 	wdt->firstline = 0;
515     if (wdt->firstline > 65535)
516 	wdt->firstline = 65535;
517     if (wdt->firstline + wdt->numlines >= 65535)
518 	wdt->numlines = 65535 - wdt->firstline;
519     if (wdt->kind == C_VERTSCROLL_WIDGET) {
520 	look_gtk_render_vert_scrollbar (wdt->winid,
521 			      wdt->x, wdt->y,
522 			      wdt->width, wdt->height,
523 			      wdt->firstline, wdt->numlines, wdt->search_start, wdt->search_len, flags);
524     } else
525 	look_gtk_render_hori_scrollbar (wdt->winid,
526 			      wdt->x, wdt->y,
527 			      wdt->width, wdt->height,
528 			      wdt->firstline, wdt->numlines, flags);
529     if (wdt->scroll_bar_extra_render)
530 	(*wdt->scroll_bar_extra_render) (wdt);
531 }
532 
533 /*
534    Which scrollbar button was pressed: 3 is the middle button ?
535  */
look_gtk_which_scrollbar_button(int bx,int by,CWidget * wdt)536 static int look_gtk_which_scrollbar_button (int bx, int by, CWidget * wdt)
537 {
538     int w, h;
539     int pos = wdt->firstline;
540     int prop = wdt->numlines;
541     int l;
542 
543     if (wdt->kind == C_VERTSCROLL_WIDGET) {
544 	w = wdt->width;
545 	h = wdt->height;
546     } else {
547 	int t = bx;
548 	bx = by;
549 	by = t;
550 	w = wdt->height;
551 	h = wdt->width;
552     }
553     l = h - 10 * w / 3 - 5;
554 
555     if (inbounds (bx, by, 2, 2, w - 3, w + 1))
556 	return 1;
557     if (inbounds (bx, by, 2, w + 2, w - 3, w + 2 * w / 3 + 1))
558 	return 2;
559     if (inbounds (bx, by, 2, h - 2 - w, w - 3, h - 3))
560 	return 4;
561     if (inbounds (bx, by, 2, h - 2 - w - 2 * w / 3, w - 3, h - 3 - w))
562 	return 5;
563     if (inbounds (bx, by, 2, w + 2 * w / 3 + 2 + (l - 5) * pos / 65535, w - 3, w + 2 * w / 3 + 7 + (l - 5) * (prop + pos) / 65535))
564 	return 3;
565     return 0;
566 }
567 
568 extern int look_cool_scrollbar_handler (CWidget * w, XEvent * xevent, CEvent * cwevent);
569 
look_gtk_init_scrollbar_icons(CWidget * w)570 static void look_gtk_init_scrollbar_icons (CWidget * w)
571 {
572     return;
573 }
574 
look_gtk_get_scrollbar_size(int type)575 static int look_gtk_get_scrollbar_size (int type)
576 {
577     if (type == C_HORISCROLL_WIDGET)
578 	return 13;
579     return 20;
580 }
581 
look_gtk_get_button_color(XColor * color,int i)582 static void look_gtk_get_button_color (XColor * color, int i)
583 {
584     color->red = i * 65535 / 15;
585     color->green = i * 65535 / 15;
586     color->blue = i * 65535 / 15;
587     color->flags = DoRed | DoBlue | DoGreen;
588 
589 #if 0
590     double r, g, b, min_wc;
591 
592     r = 0.6;
593     g = 0.6;
594     b = 0.6;
595 
596     min_wc = min (r, min (g, b));
597 
598     color->red = (float) 65535 *my_pow ((float) i / 20, r) * my_pow (0.75, -min_wc);
599     color->green = (float) 65535 *my_pow ((float) i / 20, g) * my_pow (0.75, -min_wc);
600     color->blue = (float) 65535 *my_pow ((float) i / 20, b) * my_pow (0.75, -min_wc);
601     color->flags = DoRed | DoBlue | DoGreen;
602 #endif
603 }
604 
look_gtk_get_default_interwidget_spacing(void)605 static int look_gtk_get_default_interwidget_spacing (void)
606 {
607     return 2;
608 }
609 
610 extern int look_cool_window_handler (CWidget * w, XEvent * xevent, CEvent * cwevent);
611 
612 extern Pixmap Cswitchon;
613 extern Pixmap Cswitchoff;
614 
look_gtk_render_switch(CWidget * wdt)615 static void look_gtk_render_switch (CWidget * wdt)
616 {
617     int w = wdt->width, h = wdt->height;
618     Window win = wdt->winid;
619     if (wdt->options & BUTTON_HIGHLIGHT)
620 	bevel_background_color = color_widget (14);
621     CSetColor (bevel_background_color);
622     CRectangle (win, 0, 0, w, h);
623     render_bevel (win, w / 2 - 5, h / 2 - 5, w / 2 + 4, h / 2 + 4, 2, wdt->keypressed ? 1 : 0);
624     bevel_background_color = COLOR_FLAT;
625 }
626 
627 extern int edit_normal_background_color;
628 
look_gtk_edit_render_tidbits(CWidget * wdt)629 static void look_gtk_edit_render_tidbits (CWidget * wdt)
630 {
631     int isfocussed;
632     int w = wdt->width, h = wdt->height;
633     Window win;
634 
635     win = wdt->winid;
636     isfocussed = (win == CGetFocus ());
637     bevel_background_color = edit_normal_background_color;
638     if (isfocussed) {
639 	render_bevel (win, 1, 1, w - 2, h - 2, 2, 1);	/*most outer border bevel */
640 	CSetColor (color_widget (0));
641 	XDrawRectangle(CDisplay, win, CGC, 0, 0, w - 1, h - 1);
642     } else {
643 	render_bevel (win, 0, 0, w - 1, h - 1, 3, 1);	/*most outer border bevel */
644     }
645     bevel_background_color = COLOR_FLAT;
646     CSetColor (edit_normal_background_color);
647     CLine (CWindowOf (wdt), 3, 3, 3, CHeightOf (wdt) - 4);
648 }
649 
650 extern CWidget *look_cool_draw_exclam_cancel_button (char *ident, Window win, int x, int y);
651 
652 extern CWidget *look_cool_draw_tick_cancel_button (char *ident, Window win, int x, int y);
653 
654 extern CWidget *look_cool_draw_cross_cancel_button (char *ident, Window win, int x, int y);
655 
656 extern int option_text_bg_normal;
657 
look_gtk_render_fielded_textbox_tidbits(CWidget * w,int isfocussed)658 static void look_gtk_render_fielded_textbox_tidbits (CWidget * w, int isfocussed)
659 {
660     bevel_background_color = COLOR_WHITE;
661     if (isfocussed) {
662 	render_bevel (w->winid, 1, 1, w->width - 2, w->height - 2, 2, 1);	/*most outer border bevel */
663 	CSetColor (color_widget (0));
664 	XDrawRectangle (CDisplay, w->winid, CGC, 0, 0, w->width - 1, w->height - 1);
665     } else {
666 	render_bevel (w->winid, 0, 0, w->width - 1, w->height - 1, 3, 1);	/*most outer border bevel */
667     }
668     bevel_background_color = COLOR_FLAT;
669     CSetColor (color_palette (option_text_bg_normal));
670     CLine (w->winid, 3, 3, 3, w->height - 4);
671 }
672 
look_gtk_render_textbox_tidbits(CWidget * w,int isfocussed)673 static void look_gtk_render_textbox_tidbits (CWidget * w, int isfocussed)
674 {
675     bevel_background_color = COLOR_WHITE;
676     if (isfocussed) {
677 	render_bevel (w->winid, 1, 1, w->width - 2, w->height - 2, 2, 1);	/*most outer border bevel */
678 	CSetColor (color_widget (0));
679 	XDrawRectangle (CDisplay, w->winid, CGC, 0, 0, w->width - 1, w->height - 1);
680     } else {
681 	render_bevel (w->winid, 0, 0, w->width - 1, w->height - 1, 3, 1);	/*most outer border bevel */
682     }
683     bevel_background_color = COLOR_FLAT;
684 }
685 
look_gtk_render_passwordinput_tidbits(CWidget * wdt,int isfocussed)686 static void look_gtk_render_passwordinput_tidbits (CWidget * wdt, int isfocussed)
687 {
688     int w = wdt->width, h = wdt->height;
689     Window win = wdt->winid;
690     bevel_background_color = COLOR_WHITE;
691     if ((win == CGetFocus ())) {
692 	render_bevel (win, 1, 1, w - 2, h - 2, 2, 1);	/*most outer border bevel */
693 	CSetColor (color_widget (0));
694 	XDrawRectangle (CDisplay, win, CGC, 0, 0, w - 1, h - 1);
695     } else {
696 	render_bevel (win, 0, 0, w - 1, h - 1, 3, 1);	/*most outer border bevel */
697     }
698     bevel_background_color = COLOR_FLAT;
699 }
700 
look_gtk_render_textinput_tidbits(CWidget * wdt,int isfocussed)701 static void look_gtk_render_textinput_tidbits (CWidget * wdt, int isfocussed)
702 {
703     int w = wdt->width, h = wdt->height;
704     Window win = wdt->winid;
705     bevel_background_color = COLOR_WHITE;
706     if (isfocussed) {
707 	render_bevel (win, 1, 1, w - h - 2, h - 2, 2, 1);	/*most outer border bevel */
708 	CSetColor (color_widget (0));
709 	XDrawRectangle (CDisplay, win, CGC, 0, 0, w - h - 1, h - 1);
710     } else {
711 	render_bevel (win, 0, 0, w - h - 1, h - 1, 3, 1);	/*most outer border bevel */
712     }
713     bevel_background_color = COLOR_FLAT;
714     /* history button to the right */
715     if (wdt->options & BUTTON_PRESSED) {
716 	CSetColor (COLOR_FLAT);
717 	CRectangle (win, w - h + 2, 2, h - 4, h - 4);
718 	render_bevel (win, w - h, 0, w - 1, h - 1, 2, 1);
719     } else if (wdt->options & BUTTON_HIGHLIGHT) {
720 	bevel_background_color = color_widget (14);
721 	render_bevel (win, w - h, 0, w - 1, h - 1, 2, 2);
722 	bevel_background_color = COLOR_FLAT;
723     } else {
724 	CSetColor (COLOR_FLAT);
725 	CRectangle (win, w - h + 2, 2, h - 4, h - 4);
726 	render_bevel (win, w - h, 0, w - 1, h - 1, 2, 0);
727     }
728 }
729 
730 extern struct focus_win focus_border;
731 
look_gtk_render_focus_border(Window win)732 static void look_gtk_render_focus_border (Window win)
733 {
734     if (win == focus_border.top || win == focus_border.bottom || win == focus_border.left
735 	|| win == focus_border.right) {
736 	CSetColor (color_widget (0));
737 	CRectangle (win, 0, 0, focus_border.width + 2, focus_border.height + 2);
738     }
739 }
740 
look_gtk_get_extra_window_spacing(void)741 static int look_gtk_get_extra_window_spacing (void)
742 {
743     return 2;
744 }
745 
look_gtk_get_focus_ring_size(void)746 static int look_gtk_get_focus_ring_size (void)
747 {
748     return 1;
749 }
750 
look_gtk_get_button_flat_color(void)751 static unsigned long look_gtk_get_button_flat_color (void)
752 {
753     return color_widget(12);
754 }
755 
look_gtk_get_window_resize_bar_thickness(void)756 static int look_gtk_get_window_resize_bar_thickness (void)
757 {
758     return 0;
759 }
760 
look_gtk_get_switch_size(void)761 static int look_gtk_get_switch_size (void)
762 {
763     return FONT_PIX_PER_LINE + TEXT_RELIEF * 2 + 2 + 4;
764 }
765 
look_gtk_get_fielded_textbox_hscrollbar_width(void)766 static int look_gtk_get_fielded_textbox_hscrollbar_width (void)
767 {
768     return 12;
769 }
770 
771 struct look look_gtk = {
772     look_gtk_get_default_interwidget_spacing,
773     look_gtk_menu_draw,
774     look_gtk_get_menu_item_extents,
775     look_gtk_render_menu_button,
776     look_gtk_render_button,
777     look_gtk_render_bar,
778     look_gtk_render_raised_bevel,
779     look_gtk_render_sunken_bevel,
780     look_gtk_draw_hotkey_understroke,
781     look_gtk_get_default_widget_font,
782     look_gtk_render_text,
783     look_gtk_render_window,
784     look_gtk_render_scrollbar,
785     look_gtk_get_scrollbar_size,
786     look_gtk_init_scrollbar_icons,
787     look_gtk_which_scrollbar_button,
788     look_cool_scrollbar_handler,
789     look_gtk_get_button_color,
790     look_gtk_get_extra_window_spacing,
791     look_cool_window_handler,
792     look_gtk_get_focus_ring_size,
793     look_gtk_get_button_flat_color,
794     look_gtk_get_window_resize_bar_thickness,
795     look_gtk_render_switch,
796     look_gtk_get_switch_size,
797     look_cool_draw_browser,
798     look_cool_get_file_or_dir,
799     look_cool_draw_file_list,
800     look_cool_redraw_file_list,
801     look_cool_get_file_list_line,
802     look_cool_search_replace_dialog,
803     look_gtk_edit_render_tidbits,
804     look_cool_draw_exclam_cancel_button,
805     look_cool_draw_tick_cancel_button,
806     look_cool_draw_cross_cancel_button,
807     look_cool_draw_tick_cancel_button,
808     look_gtk_render_fielded_textbox_tidbits,
809     look_gtk_render_textbox_tidbits,
810     look_gtk_get_fielded_textbox_hscrollbar_width,
811     look_gtk_render_textinput_tidbits,
812     look_gtk_render_passwordinput_tidbits,
813     look_gtk_render_focus_border,
814 };
815 
816