*** empty log message ***
[dana/urxvt.git] / src / scrollbar.C
1 /*--------------------------------*-C-*---------------------------------*
2  * File:        scrollbar.c
3  *----------------------------------------------------------------------*
4  *
5  * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA>
6  * Copyright (c) 1998      Alfredo K. Kojima <kojima@windowmaker.org>
7  *                              - N*XTstep like scrollbars
8  * Copyright (c) 1999-2001 Geoff Wing <gcw@pobox.com>
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 #include "../config.h"          /* NECESSARY */
26 #include "rxvt.h"               /* NECESSARY */
27 #include "scrollbar.intpro"     /* PROTOS for internal routines */
28
29 /*----------------------------------------------------------------------*/
30
31 /*
32  * Map or unmap a scrollbar.  Returns non-zero upon change of state
33  */
34 int
35 rxvt_term::scrollbar_mapping (int map)
36 {
37   int             change = 0;
38
39 #ifdef HAVE_SCROLLBARS
40   if (map && !scrollbar_visible())
41     {
42       scrollBar.setIdle ();
43       if (!scrollBar.win)
44         resize_scrollbar ();
45       if (scrollBar.win)
46         {
47           XMapWindow(display->display, scrollBar.win);
48           change = 1;
49         }
50     }
51   else if (!map && scrollbar_visible())
52     {
53       scrollBar.state = 0;
54       XUnmapWindow(display->display, scrollBar.win);
55       change = 1;
56     }
57 #endif
58   return change;
59 }
60
61 void
62 rxvt_term::resize_scrollbar ()
63 {
64 #ifdef HAVE_SCROLLBARS
65   int delayed_init = 0;
66
67 #define R_SCROLLBEG_XTERM       0
68 #define R_SCROLLEND_XTERM       szHint.height
69 #define R_SCROLLBEG_NEXT        0
70 #define R_SCROLLEND_NEXT        szHint.height - (SB_BUTTON_TOTAL_HEIGHT + \
71                                                     SB_PADDING)
72 #define R_SCROLLBEG_RXVT        (scrollBar.width + 1) + sb_shadow
73 #define R_SCROLLEND_RXVT        szHint.height - R_SCROLLBEG_RXVT - \
74                                     (2 * sb_shadow)
75
76 #if defined(PLAIN_SCROLLBAR)
77   if (scrollBar.style == R_SB_PLAIN)
78     {
79       scrollBar.beg = R_SCROLLBEG_XTERM;
80       scrollBar.end = R_SCROLLEND_XTERM;
81       scrollBar.update = &rxvt_term::scrollbar_show_plain;
82     }
83 #endif
84 #if defined(XTERM_SCROLLBAR)
85   if (scrollBar.style == R_SB_XTERM)
86     {
87       scrollBar.beg = R_SCROLLBEG_XTERM;
88       scrollBar.end = R_SCROLLEND_XTERM;
89       scrollBar.update = &rxvt_term::scrollbar_show_xterm;
90     }
91 #endif
92 #if defined(NEXT_SCROLLBAR)
93   if (scrollBar.style == R_SB_NEXT)
94     {
95       scrollBar.beg = R_SCROLLBEG_NEXT;
96       scrollBar.end = R_SCROLLEND_NEXT;
97       scrollBar.update = &rxvt_term::scrollbar_show_next;
98     }
99 #endif
100 #if defined(RXVT_SCROLLBAR)
101   if (scrollBar.style == R_SB_RXVT)
102     {
103       scrollBar.beg = R_SCROLLBEG_RXVT;
104       scrollBar.end = R_SCROLLEND_RXVT;
105       scrollBar.update = &rxvt_term::scrollbar_show_rxvt;
106     }
107 #endif
108
109   if (!scrollBar.win)
110     {
111       /* create the scrollbar window */
112       scrollBar.win = XCreateSimpleWindow(display->display,
113                                           TermWin.parent[0],
114                                           window_sb_x, 0,
115                                           scrollbar_TotalWidth(),
116                                           szHint.height,
117                                           0,
118                                           PixColors[Color_fg],
119                                           PixColors[Color_bg]);
120 #ifdef DEBUG_X
121       XStoreName(display->display, scrollBar.win, "scrollbar");
122 #endif
123       XDefineCursor(display->display, scrollBar.win, leftptr_cursor);
124
125       XSelectInput(display->display, scrollBar.win,
126                    ExposureMask | ButtonPressMask | ButtonReleaseMask
127                    | Button1MotionMask | Button2MotionMask
128                    | Button3MotionMask);
129       scrollbar_ev.start (display, scrollBar.win);
130
131       delayed_init = 1;
132     }
133
134   scrollbar_show (1);
135
136   if (delayed_init)
137     XMapWindow (display->display, scrollBar.win);
138 #endif
139 }
140
141 /*
142  * Update current scrollbar view w.r.t. slider heights, etc.
143  */
144 int
145 rxvt_term::scrollbar_show (int update)
146 {
147   int             ret = 0;
148 #ifdef HAVE_SCROLLBARS
149   int             top, bot, len, adj;
150
151   if (!scrollbar_visible())
152     return 0;
153
154   if (update)
155     {
156       top = (TermWin.nscrolled - TermWin.view_start);
157       bot = top + (TermWin.nrow - 1);
158       len = max((TermWin.nscrolled + (TermWin.nrow - 1)), 1);
159       adj = (((bot - top) * scrollbar_size()) % len) > 0 ? 1 : 0;
160
161       scrollBar.top = (scrollBar.beg + (top * scrollbar_size()) / len);
162       scrollbar_len = ((bot - top) * scrollbar_size()) / len +
163                       scrollbar_minheight() + adj;
164       scrollBar.bot = (scrollBar.top + scrollbar_len);
165       /* no change */
166       if (scrollBar.top == last_top
167           && scrollBar.bot == last_bot
168           && (scrollBar.state == last_state || !scrollbar_isUpDn()))
169         return 0;
170     }
171
172   ret = (this->*scrollBar.update) (update, last_top, last_bot, scrollbar_len);
173
174   last_top = scrollBar.top;
175   last_bot = scrollBar.bot;
176   last_state = scrollBar.state;
177 #endif
178
179   return ret;
180 }
181
182 void
183 rxvt_term::setup_scrollbar (const char *scrollalign, const char *scrollstyle, const char *thickness)
184 {
185 #ifdef HAVE_SCROLLBARS
186   int             i;
187   short           style, width;
188
189 # if defined(RXVT_SCROLLBAR)
190   style = R_SB_RXVT;
191 # elif defined(XTERM_SCROLLBAR)
192   style = R_SB_XTERM;
193 # elif defined(NEXT_SCROLLBAR)
194   style = R_SB_NEXT;
195 # elif defined(PLAIN_SCROLLBAR)
196   style = R_SB_PLAIN;
197 #else
198   style = R_SB_RXVT;
199 # endif
200
201 # if (defined(NEXT_SCROLLBAR) || defined(XTERM_SCROLLBAR) || defined(PLAIN_SCROLLBAR))
202   if (scrollstyle)
203     {
204 #  ifdef NEXT_SCROLLBAR
205       if (STRNCASECMP(scrollstyle, "next", 4) == 0)
206         style = R_SB_NEXT;
207 #  endif
208 #  ifdef XTERM_SCROLLBAR
209       if (STRNCASECMP(scrollstyle, "xterm", 5) == 0)
210         style = R_SB_XTERM;
211 #  endif
212 #  ifdef PLAIN_SCROLLBAR
213       if (STRNCASECMP(scrollstyle, "plain", 5) == 0)
214         style = R_SB_PLAIN;
215 #  endif
216
217     }
218 # endif
219   if (style == R_SB_NEXT)
220     width = SB_WIDTH_NEXT;
221   else if (style == R_SB_XTERM)
222     width = SB_WIDTH_XTERM;
223   else if (style == R_SB_PLAIN)
224     width = SB_WIDTH_PLAIN;
225   else /* if (style == R_SB_RXVT) */
226     width = SB_WIDTH_RXVT;
227
228   if (style != R_SB_NEXT)       /* dishonour request - for now */
229     if (thickness && (i = atoi(thickness)) >= SB_WIDTH_MINIMUM)
230       width = min(i, SB_WIDTH_MAXIMUM);
231
232 # if defined(RXVT_SCROLLBAR)
233   if (!(Options & Opt_scrollBar_floating) && style == R_SB_RXVT)
234     sb_shadow = SHADOW;
235 # endif
236
237   scrollBar.style = style;
238   scrollBar.width = width;
239
240   /* scrollbar_align = R_SB_ALIGN_CENTRE; */
241   if (scrollalign)
242     {
243       if (STRNCASECMP(scrollalign, "top", 3) == 0)
244         scrollbar_align = R_SB_ALIGN_TOP;
245       else if (STRNCASECMP(scrollalign, "bottom", 6) == 0)
246         scrollbar_align = R_SB_ALIGN_BOTTOM;
247     }
248 #endif
249 }
250
251 /*----------------------- end-of-file (C source) -----------------------*/
252