Mercurial > hg > xemacs-beta
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 |