1 /*--------------------------------*-C-*---------------------------------*
2  * File:	scrollbar-rxvt.c
3  *----------------------------------------------------------------------*
4  *
5  * All portions of code are copyright by their respective author/s.
6  * Copyright (c) 1997,1998   mj olesen <olesen@me.QueensU.CA>
7  * Copyright (c) 1999-2001   Geoff Wing <gcw@pobox.com>
8  * Copyright (c) 2004        Jingmin Zhou <jimmyzhou@users.sourceforge.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *----------------------------------------------------------------------*/
24 /*
25 ** $Id: scrollbar-rxvt.c,v 1.18 2004/11/11 00:20:28 cvs Exp $
26 */
27 
28 #include "../config.h"
29 #include "rxvt.h"
30 
31 
32 #ifdef DEBUG_VERBOSE
33 # define DEBUG_LEVEL 1
34 #else
35 # define DEBUG_LEVEL 0
36 #endif
37 
38 #if DEBUG_LEVEL
39 # define DBG_MSG(d,x) if(d <= DEBUG_LEVEL) fprintf x
40 #else
41 # define DBG_MSG(d,x)
42 #endif
43 
44 
45 /*----------------------------------------------------------------------*/
46 #ifdef HAVE_SCROLLBARS
47 #ifdef RXVT_SCROLLBAR
48 
49 
50 #define CHOOSE_GC_FG(R, PIXCOL)	\
51 	XSetForeground ((R)->Xdisplay, (R)->scrollBar.gc, (PIXCOL))
52 
53 
54 /* draw triangular button with a shadow of SHADOW (1 or 2) pixels */
55 /* INTPROTO */
56 void
rxvt_draw_button(rxvt_t * r,int x,int y,int state,int dirn)57 rxvt_draw_button(rxvt_t *r, int x, int y, int state, int dirn)
58 {
59 	unsigned int	sz, sz2;
60 	XPoint			pt[3];
61 	unsigned long	top, bot;
62 
63 	sz = r->scrollBar.width;
64 	sz2 = sz / 2;
65 	switch (state) {
66 	case +1:
67 		top = r->scrollBar.rxvt_topshadow;
68 		bot = r->scrollBar.rxvt_botshadow;
69 		break;
70 	case -1:
71 		top = r->scrollBar.rxvt_botshadow;
72 		bot = r->scrollBar.rxvt_topshadow;
73 		break;
74 	default:
75 		top = bot = r->scrollBar.rxvt_fg;
76 		break;
77 	}
78 
79 	/* fill triangle */
80 	pt[0].x = x;
81 	pt[1].x = x + sz - 1;
82 	pt[2].x = x + sz2;
83 	if (dirn == UP) {
84 		pt[0].y = pt[1].y = y + sz - 1;
85 		pt[2].y = y;
86 	} else {
87 		pt[0].y = pt[1].y = y;
88 		pt[2].y = y + sz - 1;
89 	}
90 
91 	CHOOSE_GC_FG (r, r->scrollBar.rxvt_fg);
92 	XFillPolygon(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
93 		 pt, 3, Convex, CoordModeOrigin);
94 
95 	/* draw base */
96 	CHOOSE_GC_FG (r, (dirn == UP) ? bot : top);
97 	XDrawLine(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
98 		  pt[0].x, pt[0].y, pt[1].x, pt[1].y);
99 
100 	/* draw shadow on left */
101 	pt[1].x = x + sz2 - 1;
102 	pt[1].y = y + (dirn == UP ? 0 : sz - 1);
103 	CHOOSE_GC_FG (r, top);
104 	XDrawLine(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
105 		  pt[0].x, pt[0].y, pt[1].x, pt[1].y);
106 
107 #if (SHADOW > 1)
108 	/* doubled */
109 	pt[0].x++;
110 	if (dirn == UP) {
111 		pt[0].y--;
112 		pt[1].y++;
113 	} else {
114 		pt[0].y++;
115 		pt[1].y--;
116 	}
117 	CHOOSE_GC_FG (r, top);
118 	XDrawLine(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
119 		  pt[0].x, pt[0].y, pt[1].x, pt[1].y);
120 #endif
121 	/* draw shadow on right */
122 	pt[1].x = x + sz - 1;
123 	/*  pt[2].x = x + sz2; */
124 	pt[1].y = y + (dirn == UP ? sz - 1 : 0);
125 	pt[2].y = y + (dirn == UP ? 0 : sz - 1);
126 	CHOOSE_GC_FG (r, bot);
127 	XDrawLine(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
128 		  pt[2].x, pt[2].y, pt[1].x, pt[1].y);
129 #if (SHADOW > 1)
130 	/* doubled */
131 	pt[1].x--;
132 	if (dirn == UP) {
133 		pt[2].y++;
134 		pt[1].y--;
135 	} else {
136 		pt[2].y--;
137 		pt[1].y++;
138 	}
139 	CHOOSE_GC_FG (r, bot);
140 	XDrawLine(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
141 		  pt[2].x, pt[2].y, pt[1].x, pt[1].y);
142 #endif
143 }
144 
145 
146 
147 /* EXTPROTO */
148 void
rxvt_scrollbar_init_rxvt(rxvt_t * r)149 rxvt_scrollbar_init_rxvt (rxvt_t* r)
150 {
151 	XGCValues		gcvalue;
152 	unsigned long	gcmask;
153 
154 
155 	/* Initialize the colors */
156 	r->scrollBar.rxvt_fg = r->PixColors[Color_trough];
157 	r->scrollBar.rxvt_bg = r->PixColors[Color_bottomShadow];
158 	r->scrollBar.rxvt_topshadow = r->PixColors[Color_topShadow];
159 	r->scrollBar.rxvt_botshadow = r->PixColors[Color_bottomShadow];
160 
161 
162 	gcvalue.foreground = r->scrollBar.rxvt_fg;
163 # ifdef TRANSPARENT
164 	/* set background color when there's no transparent */
165 	if (!((r->Options & Opt_transparent) &&
166 		(r->Options & Opt_transparent_scrollbar)))
167 # endif
168 # ifdef BACKGROUND_IMAGE
169 	/* set background color when there's no bg image */
170 	if (None == r->scrollBar.pixmap)
171 # endif
172 	gcvalue.background = r->scrollBar.rxvt_bg;
173 	gcmask = GCForeground;
174 # ifdef TRANSPARENT
175 	/* set background color when there's no transparent */
176 	if (!((r->Options & Opt_transparent) &&
177 		(r->Options & Opt_transparent_scrollbar)))
178 # endif
179 # ifdef BACKGROUND_IMAGE
180 	/* set background color when there's no bg image */
181 	if (None == r->scrollBar.pixmap)
182 # endif
183 	gcmask |= GCBackground;
184 	r->scrollBar.gc = XCreateGC (r->Xdisplay, r->scrollBar.win,
185 						gcmask, &gcvalue);
186 	assert (None != r->scrollBar.gc);
187 
188 # ifdef TRANSPARENT
189 	/* set background color when there's no transparent */
190 	if (!((r->Options & Opt_transparent) &&
191 		(r->Options & Opt_transparent_scrollbar)))
192 # endif
193 # ifdef BACKGROUND_IMAGE
194 	/* set background color when there's no bg image */
195 	if (None == r->scrollBar.pixmap)
196 # endif
197 		XSetWindowBackground (r->Xdisplay, r->scrollBar.win,
198 			r->scrollBar.rxvt_bg);
199 }
200 
201 
202 /* EXTPROTO */
203 void
rxvt_scrollbar_exit_rxvt(rxvt_t * r)204 rxvt_scrollbar_exit_rxvt (rxvt_t* r)
205 {
206 	/* No resources to free */
207 }
208 
209 
210 /* EXTPROTO */
211 int
rxvt_scrollbar_show_rxvt(rxvt_t * r,int update,int last_top,int last_bot,int scroller_len)212 rxvt_scrollbar_show_rxvt(rxvt_t *r, int update __attribute__((unused)), int last_top, int last_bot, int scroller_len)
213 {
214 	int			 sbshadow = r->sb_shadow;
215 	int			 sbwidth = (int)r->scrollBar.width;
216 
217 
218 	if (last_top < r->scrollBar.top)
219 		XClearArea(r->Xdisplay, r->scrollBar.win,
220 			sbshadow, last_top,
221 			sbwidth, (r->scrollBar.top - last_top),
222 			False);
223 
224 	if (r->scrollBar.bot < last_bot)
225 		XClearArea(r->Xdisplay, r->scrollBar.win,
226 			sbshadow, r->scrollBar.bot,
227 			sbwidth, (last_bot - r->scrollBar.bot),
228 			False);
229 
230 	/* scrollbar slider */
231 #ifdef TRANSPARENT
232 	/* clear background when there's transparent */
233 	if ((r->Options & Opt_transparent) &&
234 		(r->Options & Opt_transparent_scrollbar))	{
235 		XClearArea (r->Xdisplay, r->scrollBar.win,
236 			sbshadow, r->scrollBar.top, sbwidth, scroller_len,
237 			False);
238 	}
239 	else
240 #endif
241 # ifdef BACKGROUND_IMAGE
242 	/* clear background when there's bg image */
243 	if (None != r->scrollBar.pixmap)	{
244 		XClearArea (r->Xdisplay, r->scrollBar.win,
245 			sbshadow, r->scrollBar.top, sbwidth, scroller_len,
246 			False);
247 	}
248 	else
249 # endif
250 	{
251 		CHOOSE_GC_FG (r, r->scrollBar.rxvt_fg);
252 		XFillRectangle (r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
253 			sbshadow, r->scrollBar.top, sbwidth, scroller_len);
254 	}
255 
256 	if (sbshadow)
257 		/* trough shadow */
258 		rxvt_draw_shadow(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
259 			r->scrollBar.rxvt_botshadow, r->scrollBar.rxvt_topshadow,
260 			0, 0,
261 			sbwidth + 2 * sbshadow, /* scrollbar_TotalWidth() */
262 			r->scrollBar.end + (sbwidth + 1) + sbshadow);
263 	/* shadow for scrollbar slider */
264 	rxvt_draw_shadow(r->Xdisplay, r->scrollBar.win, r->scrollBar.gc,
265 		r->scrollBar.rxvt_topshadow, r->scrollBar.rxvt_botshadow,
266 		sbshadow, r->scrollBar.top, sbwidth,
267 		scroller_len);
268 
269 	/* Redraw scrollbar arrows */
270 	rxvt_draw_button(r, sbshadow, sbshadow,
271 			 (scrollbar_isUp() ? -1 : +1), UP);
272 	rxvt_draw_button(r, sbshadow, (r->scrollBar.end + 1),
273 			 (scrollbar_isDn() ? -1 : +1), DN);
274 	return 1;
275 }
276 
277 #endif	/* RXVT_SCROLLBAR */
278 #endif	/* HAVE_SCROLLBARS */
279 /*----------------------- end-of-file (C source) -----------------------*/
280