comparison src/scrollbar-msw.c @ 371:cc15677e0335 r21-2b1

Import from CVS: tag r21-2b1
author cvs
date Mon, 13 Aug 2007 11:03:08 +0200
parents 182f72e8cd0d
children a300bb07d72d
comparison
equal deleted inserted replaced
370:bd866891f083 371:cc15677e0335
22 Boston, MA 02111-1307, USA. */ 22 Boston, MA 02111-1307, USA. */
23 23
24 /* Synched up with: Not in FSF. */ 24 /* Synched up with: Not in FSF. */
25 25
26 #include <config.h> 26 #include <config.h>
27 #include <limits.h>
28 #include "lisp.h" 27 #include "lisp.h"
29 28
30 #include "console-msw.h" 29 #include "console-msw.h"
31 #include "events.h" 30 #include "events.h"
32 #include "frame.h" 31 #include "frame.h"
33 #include "scrollbar-msw.h" 32 #include "scrollbar-msw.h"
34 #include "scrollbar.h" 33 #include "scrollbar.h"
35 #include "specifier.h" 34 #include "specifier.h"
36 #include "window.h" 35 #include "window.h"
37 36
38 /* We use a similar sort of vertical scrollbar drag hack for mswindows 37 /* This has really different semantics in Windows than in Motif.
39 * scrollbars as is used for Motif or Lucid scrollbars under X. 38 There's no corresponding method; we just do not change slider
40 * We do character-based instead of line-based scrolling, which can mean that 39 size while dragging. It makes the scrollbar look smother and
41 * without the hack it is impossible to drag to the end of a buffer. */ 40 prevents some weird behavior when scrolled near the bottom */
42 #define VERTICAL_SCROLLBAR_DRAG_HACK 41 static int inhibit_slider_size_change = 0;
43
44 static int vertical_drag_in_progress = 0;
45 42
46 static void 43 static void
47 mswindows_create_scrollbar_instance (struct frame *f, int vertical, 44 mswindows_create_scrollbar_instance (struct frame *f, int vertical,
48 struct scrollbar_instance *sb) 45 struct scrollbar_instance *sb)
49 { 46 {
60 CreateWindowEx(0, "SCROLLBAR", 0, orientation|WS_CHILD, 57 CreateWindowEx(0, "SCROLLBAR", 0, orientation|WS_CHILD,
61 CW_USEDEFAULT, CW_USEDEFAULT, 58 CW_USEDEFAULT, CW_USEDEFAULT,
62 CW_USEDEFAULT, CW_USEDEFAULT, 59 CW_USEDEFAULT, CW_USEDEFAULT,
63 FRAME_MSWINDOWS_HANDLE (f), 60 FRAME_MSWINDOWS_HANDLE (f),
64 NULL, NULL, NULL); 61 NULL, NULL, NULL);
65 SCROLLBAR_MSW_INFO (sb).cbSize = sizeof(SCROLLINFO);
66 SCROLLBAR_MSW_INFO (sb).fMask = SIF_ALL; 62 SCROLLBAR_MSW_INFO (sb).fMask = SIF_ALL;
67 GetScrollInfo(SCROLLBAR_MSW_HANDLE (sb), SB_CTL, 63 GetScrollInfo(SCROLLBAR_MSW_HANDLE (sb), SB_CTL,
68 &SCROLLBAR_MSW_INFO (sb)); 64 &SCROLLBAR_MSW_INFO (sb));
69 SetWindowLong (SCROLLBAR_MSW_HANDLE(sb), GWL_USERDATA, (LONG)sb); 65 SetWindowLong (SCROLLBAR_MSW_HANDLE(sb), GWL_USERDATA, (LONG)sb);
70 66
112 int new_scrollbar_width, 108 int new_scrollbar_width,
113 int new_scrollbar_height, 109 int new_scrollbar_height,
114 int new_scrollbar_x, 110 int new_scrollbar_x,
115 int new_scrollbar_y) 111 int new_scrollbar_y)
116 { 112 {
113 struct frame *f;
117 int pos_changed = 0; 114 int pos_changed = 0;
118 int vert = GetWindowLong (SCROLLBAR_MSW_HANDLE (sb), GWL_STYLE) & SBS_VERT; 115
116 f = XFRAME (w->frame);
119 117
120 #if 0 118 #if 0
121 stderr_out ("[%d, %d], page = %d, pos = %d, inhibit = %d\n", new_minimum, new_maximum, 119 stderr_out ("[%d, %d], page = %d, pos = %d, inhibit = %d\n", new_minimum, new_maximum,
122 new_slider_size, new_slider_position,inhibit_slider_size_change); 120 new_slider_size, new_slider_position,inhibit_slider_size_change);
123 #endif 121 #endif
124 122
125 /* These might be optimized, but since at least one will change at each 123 /* These might be optimized, but since at least one will change at each
126 call, it's probably not worth it. */ 124 call, it's probably not worth it. */
125 SCROLLBAR_MSW_INFO (sb).cbSize = sizeof(SCROLLINFO);
127 SCROLLBAR_MSW_INFO (sb).nMin = new_minimum; 126 SCROLLBAR_MSW_INFO (sb).nMin = new_minimum;
128 SCROLLBAR_MSW_INFO (sb).nMax = new_maximum; 127 SCROLLBAR_MSW_INFO (sb).nMax = new_maximum;
129 SCROLLBAR_MSW_INFO (sb).nPage = new_slider_size + 1; /* +1 for DISABLENOSCROLL */ 128 SCROLLBAR_MSW_INFO (sb).nPage = new_slider_size + 1; /* for DISABLENOSCROLL */
130 SCROLLBAR_MSW_INFO (sb).nPos = new_slider_position; 129 SCROLLBAR_MSW_INFO (sb).nPos = new_slider_position;
131 #ifndef VERTICAL_SCROLLBAR_DRAG_HACK 130 SCROLLBAR_MSW_INFO (sb).fMask = (inhibit_slider_size_change
132 SCROLLBAR_MSW_INFO (sb).fMask = ((vert && vertical_drag_in_progress)
133 ? SIF_RANGE | SIF_POS 131 ? SIF_RANGE | SIF_POS
134 : SIF_ALL | SIF_DISABLENOSCROLL); 132 : SIF_ALL | SIF_DISABLENOSCROLL);
135 #else 133
136 SCROLLBAR_MSW_INFO (sb).fMask = SIF_ALL | SIF_DISABLENOSCROLL; 134 SetScrollInfo(SCROLLBAR_MSW_HANDLE (sb), SB_CTL, &SCROLLBAR_MSW_INFO (sb),
137 135 !pos_changed);
138 /* Ignore XEmacs' requests to update the thumb position and size; they don't
139 * bear any relation to reality because we're reporting made-up positions */
140 if (!(vert && vertical_drag_in_progress))
141 #endif
142 SetScrollInfo (SCROLLBAR_MSW_HANDLE (sb), SB_CTL, &SCROLLBAR_MSW_INFO (sb),
143 TRUE);
144 136
145 UPDATE_POS_FIELD (scrollbar_x); 137 UPDATE_POS_FIELD (scrollbar_x);
146 UPDATE_POS_FIELD (scrollbar_y); 138 UPDATE_POS_FIELD (scrollbar_y);
147 UPDATE_POS_FIELD (scrollbar_width); 139 UPDATE_POS_FIELD (scrollbar_width);
148 UPDATE_POS_FIELD (scrollbar_height); 140 UPDATE_POS_FIELD (scrollbar_height);
177 struct frame *f; 169 struct frame *f;
178 Lisp_Object win, frame; 170 Lisp_Object win, frame;
179 struct scrollbar_instance *sb; 171 struct scrollbar_instance *sb;
180 SCROLLINFO scrollinfo; 172 SCROLLINFO scrollinfo;
181 int vert = GetWindowLong (hwnd, GWL_STYLE) & SBS_VERT; 173 int vert = GetWindowLong (hwnd, GWL_STYLE) & SBS_VERT;
182 int value;
183 174
184 sb = (struct scrollbar_instance *)GetWindowLong (hwnd, GWL_USERDATA); 175 sb = (struct scrollbar_instance *)GetWindowLong (hwnd, GWL_USERDATA);
185 win = real_window (sb->mirror, 1); 176 win = real_window (sb->mirror, 1);
186 frame = XWINDOW (win)->frame; 177 frame = XWINDOW (win)->frame;
187 f = XFRAME (frame); 178 f = XFRAME (frame);
188 179
180 inhibit_slider_size_change = code == SB_THUMBTRACK;
181
189 /* SB_LINEDOWN == SB_CHARLEFT etc. This is the way they will 182 /* SB_LINEDOWN == SB_CHARLEFT etc. This is the way they will
190 always be - any Windows is binary compatible backward with 183 always be - any Windows is binary compatible backward with
191 old programs */ 184 old programs */
192 185
193 switch (code) 186 switch (code)
226 break; 219 break;
227 220
228 case SB_THUMBTRACK: 221 case SB_THUMBTRACK:
229 case SB_THUMBPOSITION: 222 case SB_THUMBPOSITION:
230 scrollinfo.cbSize = sizeof(SCROLLINFO); 223 scrollinfo.cbSize = sizeof(SCROLLINFO);
231 scrollinfo.fMask = SIF_ALL; 224 scrollinfo.fMask = SIF_TRACKPOS;
232 GetScrollInfo (hwnd, SB_CTL, &scrollinfo); 225 GetScrollInfo (hwnd, SB_CTL, &scrollinfo);
233 vertical_drag_in_progress = vert;
234 #ifdef VERTICAL_SCROLLBAR_DRAG_HACK
235 if (vert && (scrollinfo.nTrackPos > scrollinfo.nPos))
236 /* new buffer position =
237 * buffer position at start of drag +
238 * ((text remaining in buffer at start of drag) *
239 * (amount that the thumb has been moved) /
240 * (space that remained past end of the thumb at start of drag)) */
241 value = (int)
242 (scrollinfo.nPos
243 + (((double)
244 (scrollinfo.nMax - scrollinfo.nPos)
245 * (scrollinfo.nTrackPos - scrollinfo.nPos))
246 / (scrollinfo.nMax - scrollinfo.nPage - scrollinfo.nPos)))
247 - 2; /* ensure that the last line doesn't disappear off screen */
248 else
249 #endif
250 value = scrollinfo.nTrackPos;
251 mswindows_enqueue_misc_user_event 226 mswindows_enqueue_misc_user_event
252 (frame, 227 (frame,
253 vert ? Qscrollbar_vertical_drag : Qscrollbar_horizontal_drag, 228 vert ? Qscrollbar_vertical_drag : Qscrollbar_horizontal_drag,
254 Fcons (win, make_int (value))); 229 Fcons (win, make_int (scrollinfo.nTrackPos)));
255 break; 230 break;
256 231 }
257 case SB_ENDSCROLL:
258 #ifdef VERTICAL_SCROLLBAR_DRAG_HACK
259 if (vertical_drag_in_progress)
260 /* User has just dropped the thumb - finally update it */
261 SetScrollInfo (SCROLLBAR_MSW_HANDLE (sb), SB_CTL,
262 &SCROLLBAR_MSW_INFO (sb), TRUE);
263 #endif
264 vertical_drag_in_progress = 0;
265 break;
266 }
267 }
268
269 static int
270 can_scroll(struct scrollbar_instance* scrollbar)
271 {
272 return scrollbar != NULL
273 && IsWindowVisible (SCROLLBAR_MSW_HANDLE (scrollbar))
274 && IsWindowEnabled (SCROLLBAR_MSW_HANDLE (scrollbar));
275 }
276
277 int
278 mswindows_handle_mousewheel_event (Lisp_Object frame, int keys, int delta)
279 {
280 int hasVertBar, hasHorzBar; /* Indicates prescence of scroll bars */
281 unsigned wheelScrollLines = 0; /* Number of lines per wheel notch */
282
283 /* Find the currently selected window */
284 Lisp_Object win = FRAME_SELECTED_WINDOW (XFRAME (frame));
285 struct window* w = XWINDOW (win);
286 struct window_mirror* mirror = find_window_mirror (w);
287
288 /* Check that there is something to scroll */
289 hasVertBar = can_scroll (mirror->scrollbar_vertical_instance);
290 hasHorzBar = can_scroll (mirror->scrollbar_horizontal_instance);
291 if (!hasVertBar && !hasHorzBar)
292 return FALSE;
293
294 /* No support for panning and zooming, so ignore */
295 if (keys & (MK_SHIFT | MK_CONTROL))
296 return FALSE;
297
298 /* Get the number of lines per wheel delta */
299 SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0);
300
301 /* Calculate the amount to scroll */
302 if (wheelScrollLines == WHEEL_PAGESCROLL)
303 {
304 /* Scroll by a page */
305 Lisp_Object function;
306 if (hasVertBar)
307 function = delta > 0 ? Qscrollbar_page_up : Qscrollbar_page_down;
308 else
309 function = delta > 0 ? Qscrollbar_page_left : Qscrollbar_page_right;
310 mswindows_enqueue_misc_user_event (frame, function, Fcons (win, Qnil));
311 }
312 else /* Scroll by a number of lines */
313 {
314 /* Calc the number of lines to scroll */
315 int toScroll = MulDiv (delta, wheelScrollLines, WHEEL_DELTA);
316
317 /* Do the scroll */
318 Lisp_Object function;
319 if (hasVertBar)
320 function = delta > 0 ? Qscrollbar_line_up : Qscrollbar_line_down;
321 else
322 function = delta > 0 ? Qscrollbar_char_left : Qscrollbar_char_right;
323 if (toScroll < 0)
324 toScroll = -toScroll;
325 while (toScroll--)
326 mswindows_enqueue_misc_user_event (frame, function, win);
327 }
328
329 return TRUE;
330 } 232 }
331 233
332 #ifdef MEMORY_USAGE_STATS 234 #ifdef MEMORY_USAGE_STATS
333 235
334 static int 236 static int