X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fscrollbar-msw.c;h=2d7e9a921ebb24ed6f7ea6b1e3130a63c062c158;hb=21db8709c0c2dcedbd278c7fe571290d5ce80a71;hp=dd1caa3bfd964711b72c6d4cd1754cd195b8fef8;hpb=762383636a99307282c2d93d26c35c046ec24da1;p=chise%2Fxemacs-chise.git.1 diff --git a/src/scrollbar-msw.c b/src/scrollbar-msw.c index dd1caa3..2d7e9a9 100644 --- a/src/scrollbar-msw.c +++ b/src/scrollbar-msw.c @@ -47,14 +47,14 @@ mswindows_create_scrollbar_instance (struct frame *f, int vertical, struct scrollbar_instance *sb) { int orientation; - + sb->scrollbar_data = xnew_and_zero (struct mswindows_scrollbar_data); - + if (vertical) orientation = SBS_VERT; else orientation = SBS_HORZ; - + SCROLLBAR_MSW_HANDLE (sb) = CreateWindowEx(0, "SCROLLBAR", 0, orientation|WS_CHILD, CW_USEDEFAULT, CW_USEDEFAULT, @@ -83,14 +83,26 @@ static void mswindows_free_scrollbar_instance (struct scrollbar_instance *sb) { DestroyWindow (SCROLLBAR_MSW_HANDLE (sb)); - if (sb->scrollbar_data) + if (sb->scrollbar_data) xfree (sb->scrollbar_data); } static void +unshow_that_mofo (void *handle) +{ + ShowScrollBar ((HWND) handle, SB_CTL, 0); +} + +static void mswindows_release_scrollbar_instance (struct scrollbar_instance *sb) { - ShowScrollBar (SCROLLBAR_MSW_HANDLE (sb), SB_CTL, 0); + if (gc_in_progress) + /* #### way bogus! need to remove the offending call. + see mark_redisplay(). */ + register_post_gc_action (unshow_that_mofo, + (void *) SCROLLBAR_MSW_HANDLE (sb)); + else + ShowScrollBar (SCROLLBAR_MSW_HANDLE (sb), SB_CTL, 0); SCROLLBAR_MSW_SIZE (sb) = 0; } @@ -114,7 +126,13 @@ mswindows_update_scrollbar_instance_values (struct window *w, int new_scrollbar_y) { int pos_changed = 0; - int vert = GetWindowLong (SCROLLBAR_MSW_HANDLE (sb), GWL_STYLE) & SBS_VERT; + long styles = GetWindowLong (SCROLLBAR_MSW_HANDLE (sb), GWL_STYLE); + int vert = styles & SBS_VERT; + + if (styles == 0) { + mswindows_output_last_error("GetWindowLong"); + return; + } #if 0 stderr_out ("[%d, %d], page = %d, pos = %d, inhibit = %d\n", new_minimum, new_maximum, @@ -146,7 +164,7 @@ mswindows_update_scrollbar_instance_values (struct window *w, UPDATE_POS_FIELD (scrollbar_width); UPDATE_POS_FIELD (scrollbar_height); - if (pos_changed) + if (pos_changed) { MoveWindow(SCROLLBAR_MSW_HANDLE (sb), new_scrollbar_x, new_scrollbar_y, @@ -176,17 +194,35 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) struct frame *f; Lisp_Object win, frame; struct scrollbar_instance *sb; - SCROLLINFO scrollinfo; - int vert = GetWindowLong (hwnd, GWL_STYLE) & SBS_VERT; - int value; + long styles = GetWindowLong (hwnd, GWL_STYLE); + int vert = styles & SBS_VERT; + + if (styles == 0) { + mswindows_output_last_error("GetWindowLong"); + return; + } sb = (struct scrollbar_instance *)GetWindowLong (hwnd, GWL_USERDATA); - win = real_window (sb->mirror, 1); + win = real_window ((sb==NULL) ? GetFocus() : sb->mirror, 1); + /* "0 as the second parameter" refers to the call to real_window above. + This comment was taken from Ben's 21.5 code that differs somewhat + from this, I don't think the 21.4 code ever had a 0 there. + #### we're still hitting an abort here with 0 as the second + parameter, although only occasionally. It seems that sometimes we + receive events for scrollbars that don't exist anymore. I assume + it must happen like this: The user does something that causes a + scrollbar to disappear (e.g. Alt-TAB, causing recomputation of + everything in the new frame) and then immediately uses the mouse + wheel, generating scrollbar events. Both events get posted before + we have a chance to process them, and in processing the first, the + scrollbar mentioned in the second disappears. */ + if (NILP (win)) + return; frame = XWINDOW (win)->frame; f = XFRAME (frame); /* SB_LINEDOWN == SB_CHARLEFT etc. This is the way they will - always be - any Windows is binary compatible backward with + always be - any Windows is binary compatible backward with old programs */ switch (code) @@ -195,12 +231,12 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) mswindows_enqueue_misc_user_event (frame, vert ? Qscrollbar_line_down : Qscrollbar_char_right, win); break; - + case SB_LINEUP: mswindows_enqueue_misc_user_event (frame, vert ? Qscrollbar_line_up : Qscrollbar_char_left, win); break; - + case SB_PAGEDOWN: mswindows_enqueue_misc_user_event (win, vert ? Qscrollbar_page_down : Qscrollbar_page_right, @@ -213,7 +249,7 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) vert ? Qscrollbar_page_up : Qscrollbar_page_left, vert ? Fcons (win, Qnil) : win); break; - + case SB_BOTTOM: mswindows_enqueue_misc_user_event (frame, vert ? Qscrollbar_to_bottom : Qscrollbar_to_right, win); @@ -226,10 +262,13 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) case SB_THUMBTRACK: case SB_THUMBPOSITION: - scrollinfo.cbSize = sizeof(SCROLLINFO); - scrollinfo.fMask = SIF_ALL; - GetScrollInfo (hwnd, SB_CTL, &scrollinfo); - vertical_drag_in_progress = vert; + { + int pos; + SCROLLINFO scrollinfo; + scrollinfo.cbSize = sizeof(SCROLLINFO); + scrollinfo.fMask = SIF_ALL; + GetScrollInfo (hwnd, SB_CTL, &scrollinfo); + vertical_drag_in_progress = vert; #ifdef VERTICAL_SCROLLBAR_DRAG_HACK if (vert && (scrollinfo.nTrackPos > scrollinfo.nPos)) /* new buffer position = @@ -237,7 +276,7 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) * ((text remaining in buffer at start of drag) * * (amount that the thumb has been moved) / * (space that remained past end of the thumb at start of drag)) */ - value = (int) + pos = (int) (scrollinfo.nPos + (((double) (scrollinfo.nMax - scrollinfo.nPos) @@ -246,16 +285,17 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) - 2; /* ensure that the last line doesn't disappear off screen */ else #endif - value = scrollinfo.nTrackPos; + pos = scrollinfo.nTrackPos; mswindows_enqueue_misc_user_event (frame, vert ? Qscrollbar_vertical_drag : Qscrollbar_horizontal_drag, - Fcons (win, make_int (value))); + Fcons (win, make_int (pos))); + } break; case SB_ENDSCROLL: #ifdef VERTICAL_SCROLLBAR_DRAG_HACK - if (vertical_drag_in_progress) + if (vertical_drag_in_progress && sb) /* User has just dropped the thumb - finally update it */ SetScrollInfo (SCROLLBAR_MSW_HANDLE (sb), SB_CTL, &SCROLLBAR_MSW_INFO (sb), TRUE); @@ -266,7 +306,7 @@ mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos) } static int -can_scroll(struct scrollbar_instance* scrollbar) +can_scroll (struct scrollbar_instance* scrollbar) { return scrollbar != NULL && IsWindowVisible (SCROLLBAR_MSW_HANDLE (scrollbar)) @@ -274,15 +314,48 @@ can_scroll(struct scrollbar_instance* scrollbar) } int -mswindows_handle_mousewheel_event (Lisp_Object frame, int keys, int delta) +mswindows_handle_mousewheel_event (Lisp_Object frame, int keys, int delta, + POINTS where) { - int hasVertBar, hasHorzBar; /* Indicates prescence of scroll bars */ + int hasVertBar, hasHorzBar; /* Indicates presence of scroll bars */ unsigned wheelScrollLines = 0; /* Number of lines per wheel notch */ + Lisp_Object win; + struct window_mirror *mirror; + POINT donde_esta; - /* Find the currently selected window */ - Lisp_Object win = FRAME_SELECTED_WINDOW (XFRAME (frame)); - struct window* w = XWINDOW (win); - struct window_mirror* mirror = find_window_mirror (w); + donde_esta.x = where.x; + donde_esta.y = where.y; + + ScreenToClient (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), &donde_esta); + + /* Find the window to scroll */ + { + int mene, _mene, tekel, upharsin; + Bufpos mens, sana; + Charcount in; + Lisp_Object corpore, sano; + struct window *needle_in_haystack; + + // stderr_out ("donde_esta: %d %d\n", donde_esta.x, donde_esta.y); + pixel_to_glyph_translation (XFRAME (frame), donde_esta.x, donde_esta.y, + &mene, &_mene, &tekel, &upharsin, + &needle_in_haystack, + &mens, &sana, &in, &corpore, &sano); + + if (needle_in_haystack) + { + XSETWINDOW (win, needle_in_haystack); + // stderr_out ("found needle\n"); + // debug_print (win); + } + else + { + win = FRAME_SELECTED_WINDOW (XFRAME (frame)); + needle_in_haystack = XWINDOW (win); + } + + mirror = find_window_mirror (needle_in_haystack); + } /* Check that there is something to scroll */ hasVertBar = can_scroll (mirror->scrollbar_vertical_instance);