diff options
| author | Po Lu | 2022-07-31 10:41:58 +0800 |
|---|---|---|
| committer | Po Lu | 2022-07-31 10:41:58 +0800 |
| commit | a66e6542769eae039aba57644eca2d6afcbe3360 (patch) | |
| tree | 584c63cc79c28d5fd6fd3c93127d029cffd13f13 /src | |
| parent | 88d719e95b76ccb38e4a39b24729d5b3d9514118 (diff) | |
| download | emacs-a66e6542769eae039aba57644eca2d6afcbe3360.tar.gz emacs-a66e6542769eae039aba57644eca2d6afcbe3360.zip | |
Fix frame synchronization with scroll bar movement
* src/xfns.c (x_set_inhibit_double_buffering): Stop condeming
scroll bars.
* src/xterm.c (x_scroll_bar_create): Create an InputOnly window.
Update event masks accordingly and stop allocating back buffer.
(x_scroll_bar_remove): Stop deallocating back buffer.
(XTset_vertical_scroll_bar, x_scroll_bar_set_handle): Draw onto
the edit window so they can be synchronized with buffer flips.
(x_scroll_bar_clear): Redraw scroll bars instead of just
clearing them.
(x_scroll_bar_handle_expose, x_scroll_bar_redraw): New
functions.
(x_scroll_bar_expose, x_scroll_bar_end_update): Delete
functions.
(handle_one_xevent): Update exposure logic accordingly.
* src/xterm.h (struct scroll_bar): Remove `x_drawable' field.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 18 | ||||
| -rw-r--r-- | src/xterm.c | 441 | ||||
| -rw-r--r-- | src/xterm.h | 5 |
3 files changed, 195 insertions, 269 deletions
diff --git a/src/xfns.c b/src/xfns.c index 579237068a2..1ae615fad44 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -838,21 +838,9 @@ x_set_inhibit_double_buffering (struct frame *f, | |||
| 838 | 838 | ||
| 839 | block_input (); | 839 | block_input (); |
| 840 | if (want_double_buffering != was_double_buffered) | 840 | if (want_double_buffering != was_double_buffered) |
| 841 | { | 841 | /* Force XftDraw etc to be recreated with the new double |
| 842 | /* Force XftDraw etc to be recreated with the new double | 842 | buffered drawable. */ |
| 843 | buffered drawable. */ | 843 | font_drop_xrender_surfaces (f); |
| 844 | font_drop_xrender_surfaces (f); | ||
| 845 | |||
| 846 | /* Scroll bars decide whether or not to use a back buffer | ||
| 847 | based on the value of this frame parameter, so destroy | ||
| 848 | all scroll bars. */ | ||
| 849 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 850 | if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook) | ||
| 851 | FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); | ||
| 852 | if (FRAME_TERMINAL (f)->judge_scroll_bars_hook) | ||
| 853 | FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); | ||
| 854 | #endif | ||
| 855 | } | ||
| 856 | if (FRAME_X_DOUBLE_BUFFERED_P (f) && !want_double_buffering) | 844 | if (FRAME_X_DOUBLE_BUFFERED_P (f) && !want_double_buffering) |
| 857 | tear_down_x_back_buffer (f); | 845 | tear_down_x_back_buffer (f); |
| 858 | else if (!FRAME_X_DOUBLE_BUFFERED_P (f) && want_double_buffering) | 846 | else if (!FRAME_X_DOUBLE_BUFFERED_P (f) && want_double_buffering) |
diff --git a/src/xterm.c b/src/xterm.c index dc9637d35c7..6dd3aad0e01 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1129,10 +1129,6 @@ static void x_initialize (void); | |||
| 1129 | static bool x_get_current_wm_state (struct frame *, Window, int *, bool *, bool *); | 1129 | static bool x_get_current_wm_state (struct frame *, Window, int *, bool *, bool *); |
| 1130 | static void x_update_opaque_region (struct frame *, XEvent *); | 1130 | static void x_update_opaque_region (struct frame *, XEvent *); |
| 1131 | 1131 | ||
| 1132 | #if !defined USE_TOOLKIT_SCROLL_BARS && defined HAVE_XDBE | ||
| 1133 | static void x_scroll_bar_end_update (struct x_display_info *, struct scroll_bar *); | ||
| 1134 | #endif | ||
| 1135 | |||
| 1136 | #ifdef HAVE_X_I18N | 1132 | #ifdef HAVE_X_I18N |
| 1137 | static int x_filter_event (struct x_display_info *, XEvent *); | 1133 | static int x_filter_event (struct x_display_info *, XEvent *); |
| 1138 | #endif | 1134 | #endif |
| @@ -1142,6 +1138,10 @@ static struct frame *x_tooltip_window_to_frame (struct x_display_info *, | |||
| 1142 | Window, bool *); | 1138 | Window, bool *); |
| 1143 | static Window x_get_window_below (Display *, Window, int, int, int *, int *); | 1139 | static Window x_get_window_below (Display *, Window, int, int, int *, int *); |
| 1144 | 1140 | ||
| 1141 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 1142 | static void x_scroll_bar_redraw (struct scroll_bar *); | ||
| 1143 | #endif | ||
| 1144 | |||
| 1145 | /* Global state maintained during a drag-and-drop operation. */ | 1145 | /* Global state maintained during a drag-and-drop operation. */ |
| 1146 | 1146 | ||
| 1147 | /* Flag that indicates if a drag-and-drop operation is in progress. */ | 1147 | /* Flag that indicates if a drag-and-drop operation is in progress. */ |
| @@ -14627,20 +14627,12 @@ x_scroll_bar_create (struct window *w, int top, int left, | |||
| 14627 | XSetWindowAttributes a; | 14627 | XSetWindowAttributes a; |
| 14628 | unsigned long mask; | 14628 | unsigned long mask; |
| 14629 | Window window; | 14629 | Window window; |
| 14630 | #ifdef HAVE_XDBE | ||
| 14631 | Drawable drawable; | ||
| 14632 | #endif | ||
| 14633 | |||
| 14634 | a.background_pixel = f->output_data.x->scroll_bar_background_pixel; | ||
| 14635 | if (a.background_pixel == -1) | ||
| 14636 | a.background_pixel = FRAME_BACKGROUND_PIXEL (f); | ||
| 14637 | 14630 | ||
| 14638 | a.event_mask = (ButtonPressMask | ButtonReleaseMask | 14631 | a.event_mask = (ButtonPressMask | ButtonReleaseMask |
| 14639 | | ButtonMotionMask | PointerMotionHintMask | 14632 | | ButtonMotionMask | PointerMotionHintMask); |
| 14640 | | ExposureMask); | ||
| 14641 | a.cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; | 14633 | a.cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; |
| 14642 | 14634 | ||
| 14643 | mask = (CWBackPixel | CWEventMask | CWCursor); | 14635 | mask = (CWEventMask | CWCursor); |
| 14644 | 14636 | ||
| 14645 | /* Clear the area of W that will serve as a scroll bar. This is | 14637 | /* Clear the area of W that will serve as a scroll bar. This is |
| 14646 | for the case that a window has been split horizontally. In | 14638 | for the case that a window has been split horizontally. In |
| @@ -14648,32 +14640,22 @@ x_scroll_bar_create (struct window *w, int top, int left, | |||
| 14648 | if (width > 0 && window_box_height (w) > 0) | 14640 | if (width > 0 && window_box_height (w) > 0) |
| 14649 | x_clear_area (f, left, top, width, window_box_height (w)); | 14641 | x_clear_area (f, left, top, width, window_box_height (w)); |
| 14650 | 14642 | ||
| 14643 | /* Create an input only window. Scroll bar contents are drawn to | ||
| 14644 | the frame window itself, so they can be double buffered and | ||
| 14645 | synchronized using the same mechanism as the frame. */ | ||
| 14651 | window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 14646 | window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 14652 | /* Position and size of scroll bar. */ | 14647 | /* Position and size of scroll bar. */ |
| 14653 | left, top, width, height, | 14648 | left, top, width, height, |
| 14654 | /* Border width, depth, class, and visual. */ | 14649 | /* Border width. */ |
| 14655 | 0, | 14650 | 0, |
| 14651 | /* Depth. */ | ||
| 14656 | CopyFromParent, | 14652 | CopyFromParent, |
| 14657 | CopyFromParent, | 14653 | /* Class. */ |
| 14654 | InputOnly, | ||
| 14655 | /* Visual class. */ | ||
| 14658 | CopyFromParent, | 14656 | CopyFromParent, |
| 14659 | /* Attributes. */ | 14657 | /* Attributes. */ |
| 14660 | mask, &a); | 14658 | mask, &a); |
| 14661 | #ifdef HAVE_XDBE | ||
| 14662 | if (FRAME_DISPLAY_INFO (f)->supports_xdbe | ||
| 14663 | && FRAME_X_DOUBLE_BUFFERED_P (f)) | ||
| 14664 | { | ||
| 14665 | x_catch_errors (FRAME_X_DISPLAY (f)); | ||
| 14666 | drawable = XdbeAllocateBackBufferName (FRAME_X_DISPLAY (f), | ||
| 14667 | window, XdbeCopied); | ||
| 14668 | if (x_had_errors_p (FRAME_X_DISPLAY (f))) | ||
| 14669 | drawable = window; | ||
| 14670 | else | ||
| 14671 | XSetWindowBackgroundPixmap (FRAME_X_DISPLAY (f), window, None); | ||
| 14672 | x_uncatch_errors_after_check (); | ||
| 14673 | } | ||
| 14674 | else | ||
| 14675 | drawable = window; | ||
| 14676 | #endif | ||
| 14677 | 14659 | ||
| 14678 | #ifdef HAVE_XINPUT2 | 14660 | #ifdef HAVE_XINPUT2 |
| 14679 | /* Ask for input extension button and motion events. This lets us | 14661 | /* Ask for input extension button and motion events. This lets us |
| @@ -14700,9 +14682,6 @@ x_scroll_bar_create (struct window *w, int top, int left, | |||
| 14700 | #endif | 14682 | #endif |
| 14701 | 14683 | ||
| 14702 | bar->x_window = window; | 14684 | bar->x_window = window; |
| 14703 | #ifdef HAVE_XDBE | ||
| 14704 | bar->x_drawable = drawable; | ||
| 14705 | #endif | ||
| 14706 | } | 14685 | } |
| 14707 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 14686 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 14708 | 14687 | ||
| @@ -14775,14 +14754,11 @@ static void | |||
| 14775 | x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, | 14754 | x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, |
| 14776 | bool rebuild) | 14755 | bool rebuild) |
| 14777 | { | 14756 | { |
| 14778 | bool dragging = bar->dragging != -1; | 14757 | bool dragging; |
| 14779 | #ifndef HAVE_XDBE | 14758 | struct frame *f; |
| 14780 | Window w = bar->x_window; | 14759 | Drawable w; |
| 14781 | #else | 14760 | GC gc; |
| 14782 | Drawable w = bar->x_drawable; | 14761 | int inside_width, inside_height, top_range, length; |
| 14783 | #endif | ||
| 14784 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | ||
| 14785 | GC gc = f->output_data.x->normal_gc; | ||
| 14786 | 14762 | ||
| 14787 | /* If the display is already accurate, do nothing. */ | 14763 | /* If the display is already accurate, do nothing. */ |
| 14788 | if (! rebuild | 14764 | if (! rebuild |
| @@ -14790,106 +14766,102 @@ x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, | |||
| 14790 | && end == bar->end) | 14766 | && end == bar->end) |
| 14791 | return; | 14767 | return; |
| 14792 | 14768 | ||
| 14793 | block_input (); | 14769 | f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); |
| 14794 | 14770 | dragging = bar->dragging != -1; | |
| 14795 | { | 14771 | gc = f->output_data.x->normal_gc; |
| 14796 | int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width); | 14772 | w = FRAME_X_DRAWABLE (f); |
| 14797 | int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height); | ||
| 14798 | int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height); | ||
| 14799 | 14773 | ||
| 14800 | /* Make sure the values are reasonable, and try to preserve | 14774 | block_input (); |
| 14801 | the distance between start and end. */ | ||
| 14802 | { | ||
| 14803 | int length = end - start; | ||
| 14804 | 14775 | ||
| 14805 | if (start < 0) | 14776 | inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width); |
| 14806 | start = 0; | 14777 | inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height); |
| 14807 | else if (start > top_range) | 14778 | top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height); |
| 14808 | start = top_range; | ||
| 14809 | end = start + length; | ||
| 14810 | 14779 | ||
| 14811 | if (end < start) | 14780 | /* Make sure the values are reasonable, and try to preserve |
| 14812 | end = start; | 14781 | the distance between start and end. */ |
| 14813 | else if (end > top_range && ! dragging) | 14782 | length = end - start; |
| 14814 | end = top_range; | ||
| 14815 | } | ||
| 14816 | 14783 | ||
| 14817 | /* Store the adjusted setting in the scroll bar. */ | 14784 | if (start < 0) |
| 14818 | bar->start = start; | 14785 | start = 0; |
| 14819 | bar->end = end; | 14786 | else if (start > top_range) |
| 14787 | start = top_range; | ||
| 14788 | end = start + length; | ||
| 14820 | 14789 | ||
| 14821 | /* Clip the end position, just for display. */ | 14790 | if (end < start) |
| 14822 | if (end > top_range) | 14791 | end = start; |
| 14823 | end = top_range; | 14792 | else if (end > top_range && ! dragging) |
| 14793 | end = top_range; | ||
| 14824 | 14794 | ||
| 14825 | /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels | 14795 | /* Store the adjusted setting in the scroll bar. */ |
| 14826 | below top positions, to make sure the handle is always at least | 14796 | bar->start = start; |
| 14827 | that many pixels tall. */ | 14797 | bar->end = end; |
| 14828 | end += VERTICAL_SCROLL_BAR_MIN_HANDLE; | ||
| 14829 | 14798 | ||
| 14830 | /* Draw the empty space above the handle. Note that we can't clear | 14799 | /* Clip the end position, just for display. */ |
| 14831 | zero-height areas; that means "clear to end of window." */ | 14800 | if (end > top_range) |
| 14832 | if ((inside_width > 0) && (start > 0)) | 14801 | end = top_range; |
| 14833 | { | ||
| 14834 | if (f->output_data.x->scroll_bar_background_pixel != -1) | ||
| 14835 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 14836 | f->output_data.x->scroll_bar_background_pixel); | ||
| 14837 | else | ||
| 14838 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 14839 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 14840 | 14802 | ||
| 14841 | XFillRectangle (FRAME_X_DISPLAY (f), w, gc, | 14803 | /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels |
| 14842 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | 14804 | below top positions, to make sure the handle is always at least |
| 14843 | VERTICAL_SCROLL_BAR_TOP_BORDER, | 14805 | that many pixels tall. */ |
| 14844 | inside_width, start); | 14806 | end += VERTICAL_SCROLL_BAR_MIN_HANDLE; |
| 14845 | 14807 | ||
| 14808 | /* Draw the empty space above the handle. Note that we can't clear | ||
| 14809 | zero-height areas; that means "clear to end of window." */ | ||
| 14810 | if ((inside_width > 0) && (start > 0)) | ||
| 14811 | { | ||
| 14812 | if (f->output_data.x->scroll_bar_background_pixel != -1) | ||
| 14846 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 14813 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 14847 | FRAME_FOREGROUND_PIXEL (f)); | 14814 | f->output_data.x->scroll_bar_background_pixel); |
| 14848 | } | 14815 | else |
| 14816 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 14817 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 14849 | 14818 | ||
| 14850 | /* Change to proper foreground color if one is specified. */ | 14819 | XFillRectangle (FRAME_X_DISPLAY (f), w, gc, |
| 14851 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 14820 | bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER, |
| 14852 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 14821 | bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER, |
| 14853 | f->output_data.x->scroll_bar_foreground_pixel); | 14822 | inside_width, start); |
| 14854 | 14823 | ||
| 14855 | /* Draw the handle itself. */ | 14824 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 14856 | XFillRectangle (FRAME_X_DISPLAY (f), w, gc, | 14825 | FRAME_FOREGROUND_PIXEL (f)); |
| 14857 | /* x, y, width, height */ | 14826 | } |
| 14858 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | ||
| 14859 | VERTICAL_SCROLL_BAR_TOP_BORDER + start, | ||
| 14860 | inside_width, end - start); | ||
| 14861 | 14827 | ||
| 14828 | /* Change to proper foreground color if one is specified. */ | ||
| 14829 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | ||
| 14830 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 14831 | f->output_data.x->scroll_bar_foreground_pixel); | ||
| 14862 | 14832 | ||
| 14863 | /* Draw the empty space below the handle. Note that we can't | 14833 | /* Draw the handle itself. */ |
| 14864 | clear zero-height areas; that means "clear to end of window." */ | 14834 | XFillRectangle (FRAME_X_DISPLAY (f), w, gc, |
| 14865 | if ((inside_width > 0) && (end < inside_height)) | 14835 | /* x, y, width, height */ |
| 14866 | { | 14836 | bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER, |
| 14867 | if (f->output_data.x->scroll_bar_background_pixel != -1) | 14837 | bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + start, |
| 14868 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 14838 | inside_width, end - start); |
| 14869 | f->output_data.x->scroll_bar_background_pixel); | ||
| 14870 | else | ||
| 14871 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 14872 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 14873 | 14839 | ||
| 14874 | XFillRectangle (FRAME_X_DISPLAY (f), w, gc, | ||
| 14875 | VERTICAL_SCROLL_BAR_LEFT_BORDER, | ||
| 14876 | VERTICAL_SCROLL_BAR_TOP_BORDER + end, | ||
| 14877 | inside_width, inside_height - end); | ||
| 14878 | 14840 | ||
| 14841 | /* Draw the empty space below the handle. Note that we can't | ||
| 14842 | clear zero-height areas; that means "clear to end of window." */ | ||
| 14843 | if ((inside_width > 0) && (end < inside_height)) | ||
| 14844 | { | ||
| 14845 | if (f->output_data.x->scroll_bar_background_pixel != -1) | ||
| 14879 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 14846 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 14880 | FRAME_FOREGROUND_PIXEL (f)); | 14847 | f->output_data.x->scroll_bar_background_pixel); |
| 14881 | } | 14848 | else |
| 14849 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 14850 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 14851 | |||
| 14852 | XFillRectangle (FRAME_X_DISPLAY (f), w, gc, | ||
| 14853 | bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER, | ||
| 14854 | bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + end, | ||
| 14855 | inside_width, inside_height - end); | ||
| 14882 | 14856 | ||
| 14883 | /* Restore the foreground color of the GC if we changed it above. */ | ||
| 14884 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | ||
| 14885 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 14857 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 14886 | FRAME_FOREGROUND_PIXEL (f)); | 14858 | FRAME_FOREGROUND_PIXEL (f)); |
| 14887 | } | 14859 | } |
| 14888 | 14860 | ||
| 14889 | #ifdef HAVE_XDBE | 14861 | /* Restore the foreground color of the GC if we changed it above. */ |
| 14890 | if (!rebuild) | 14862 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| 14891 | x_scroll_bar_end_update (FRAME_DISPLAY_INFO (f), bar); | 14863 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 14892 | #endif | 14864 | FRAME_FOREGROUND_PIXEL (f)); |
| 14893 | 14865 | ||
| 14894 | unblock_input (); | 14866 | unblock_input (); |
| 14895 | } | 14867 | } |
| @@ -14912,11 +14884,6 @@ x_scroll_bar_remove (struct scroll_bar *bar) | |||
| 14912 | XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar)); | 14884 | XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar)); |
| 14913 | #endif /* not USE_GTK */ | 14885 | #endif /* not USE_GTK */ |
| 14914 | #else | 14886 | #else |
| 14915 | #ifdef HAVE_XDBE | ||
| 14916 | if (bar->x_window != bar->x_drawable) | ||
| 14917 | XdbeDeallocateBackBufferName (FRAME_X_DISPLAY (f), | ||
| 14918 | bar->x_drawable); | ||
| 14919 | #endif | ||
| 14920 | XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window); | 14887 | XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window); |
| 14921 | #endif | 14888 | #endif |
| 14922 | 14889 | ||
| @@ -14962,6 +14929,12 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 14962 | } | 14929 | } |
| 14963 | 14930 | ||
| 14964 | bar = x_scroll_bar_create (w, top, left, width, max (height, 1), false); | 14931 | bar = x_scroll_bar_create (w, top, left, width, max (height, 1), false); |
| 14932 | #ifdef USE_TOOKIT_SCROLL_BARS | ||
| 14933 | /* Since non-toolkit scroll bars don't display their contents to | ||
| 14934 | a dedicated window, no expose event will be generated. | ||
| 14935 | Redraw the scroll bar manually. */ | ||
| 14936 | x_scroll_bar_redraw (bar); | ||
| 14937 | #endif | ||
| 14965 | } | 14938 | } |
| 14966 | else | 14939 | else |
| 14967 | { | 14940 | { |
| @@ -15021,6 +14994,11 @@ XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int positio | |||
| 15021 | bar->width = width; | 14994 | bar->width = width; |
| 15022 | bar->height = height; | 14995 | bar->height = height; |
| 15023 | 14996 | ||
| 14997 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 14998 | /* Redraw the scroll bar. */ | ||
| 14999 | x_scroll_bar_redraw (bar); | ||
| 15000 | #endif | ||
| 15001 | |||
| 15024 | unblock_input (); | 15002 | unblock_input (); |
| 15025 | } | 15003 | } |
| 15026 | 15004 | ||
| @@ -15328,60 +15306,84 @@ XTjudge_scroll_bars (struct frame *f) | |||
| 15328 | 15306 | ||
| 15329 | 15307 | ||
| 15330 | #ifndef USE_TOOLKIT_SCROLL_BARS | 15308 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| 15331 | /* Handle an Expose or GraphicsExpose event on a scroll bar. This | 15309 | /* Handle exposure event EVENT generated for F, by redrawing all |
| 15332 | is a no-op when using toolkit scroll bars. | 15310 | intersecting scroll bars. */ |
| 15333 | |||
| 15334 | This may be called from a signal handler, so we have to ignore GC | ||
| 15335 | mark bits. */ | ||
| 15336 | 15311 | ||
| 15337 | static void | 15312 | static void |
| 15338 | x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event) | 15313 | x_scroll_bar_handle_exposure (struct frame *f, XEvent *event) |
| 15339 | { | 15314 | { |
| 15340 | #ifndef HAVE_XDBE | ||
| 15341 | Window w = bar->x_window; | ||
| 15342 | #else | ||
| 15343 | Drawable w = bar->x_drawable; | ||
| 15344 | int x, y, width, height; | 15315 | int x, y, width, height; |
| 15316 | XRectangle rect, scroll_bar_rect, intersection; | ||
| 15317 | Lisp_Object bar, condemned; | ||
| 15318 | struct scroll_bar *b; | ||
| 15345 | 15319 | ||
| 15346 | if (event->type == Expose) | 15320 | if (event->type == GraphicsExpose) |
| 15321 | { | ||
| 15322 | x = event->xgraphicsexpose.x; | ||
| 15323 | y = event->xgraphicsexpose.y; | ||
| 15324 | width = event->xgraphicsexpose.width; | ||
| 15325 | height = event->xgraphicsexpose.height; | ||
| 15326 | } | ||
| 15327 | else | ||
| 15347 | { | 15328 | { |
| 15348 | x = event->xexpose.x; | 15329 | x = event->xexpose.x; |
| 15349 | y = event->xexpose.y; | 15330 | y = event->xexpose.y; |
| 15350 | width = event->xexpose.width; | 15331 | width = event->xexpose.width; |
| 15351 | height = event->xexpose.height; | 15332 | height = event->xexpose.height; |
| 15352 | } | 15333 | } |
| 15353 | else | 15334 | |
| 15335 | rect.x = x; | ||
| 15336 | rect.y = y; | ||
| 15337 | rect.width = width; | ||
| 15338 | rect.height = height; | ||
| 15339 | |||
| 15340 | /* Scan this frame's scroll bar list for intersecting scroll | ||
| 15341 | bars. */ | ||
| 15342 | condemned = FRAME_CONDEMNED_SCROLL_BARS (f); | ||
| 15343 | for (bar = FRAME_SCROLL_BARS (f); | ||
| 15344 | /* This trick allows us to search both the ordinary and | ||
| 15345 | condemned scroll bar lists with one loop. */ | ||
| 15346 | !NILP (bar) || (bar = condemned, | ||
| 15347 | condemned = Qnil, | ||
| 15348 | !NILP (bar)); | ||
| 15349 | bar = XSCROLL_BAR (bar)->next) | ||
| 15354 | { | 15350 | { |
| 15355 | x = event->xgraphicsexpose.x; | 15351 | b = XSCROLL_BAR (bar); |
| 15356 | y = event->xgraphicsexpose.y; | 15352 | |
| 15357 | width = event->xgraphicsexpose.width; | 15353 | scroll_bar_rect.x = b->left; |
| 15358 | height = event->xgraphicsexpose.height; | 15354 | scroll_bar_rect.y = b->top; |
| 15355 | scroll_bar_rect.width = b->width; | ||
| 15356 | scroll_bar_rect.height = b->height; | ||
| 15357 | |||
| 15358 | if (gui_intersect_rectangles (&rect, | ||
| 15359 | &scroll_bar_rect, | ||
| 15360 | &intersection)) | ||
| 15361 | x_scroll_bar_redraw (b); | ||
| 15359 | } | 15362 | } |
| 15360 | #endif | 15363 | } |
| 15364 | |||
| 15365 | /* Redraw the scroll bar BAR. Draw its border and set its thumb. | ||
| 15366 | This is usually called from x_clear_frame, but is also used to | ||
| 15367 | handle exposure events that overlap scroll bars. */ | ||
| 15361 | 15368 | ||
| 15369 | static void | ||
| 15370 | x_scroll_bar_redraw (struct scroll_bar *bar) | ||
| 15371 | { | ||
| 15362 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); | 15372 | struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); |
| 15363 | GC gc = f->output_data.x->normal_gc; | 15373 | GC gc = f->output_data.x->normal_gc; |
| 15364 | 15374 | ||
| 15365 | block_input (); | 15375 | if (f->output_data.x->scroll_bar_background_pixel != -1) |
| 15366 | 15376 | XSetForeground (FRAME_X_DISPLAY (f), gc, | |
| 15367 | #ifdef HAVE_XDBE | 15377 | f->output_data.x->scroll_bar_background_pixel); |
| 15368 | if (w != bar->x_window) | 15378 | else |
| 15369 | { | 15379 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 15370 | if (f->output_data.x->scroll_bar_background_pixel != -1) | 15380 | FRAME_BACKGROUND_PIXEL (f)); |
| 15371 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 15372 | f->output_data.x->scroll_bar_background_pixel); | ||
| 15373 | else | ||
| 15374 | XSetForeground (FRAME_X_DISPLAY (f), gc, | ||
| 15375 | FRAME_BACKGROUND_PIXEL (f)); | ||
| 15376 | 15381 | ||
| 15377 | XFillRectangle (FRAME_X_DISPLAY (f), | 15382 | XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc, |
| 15378 | bar->x_drawable, | 15383 | bar->left, bar->top, bar->width, bar->height); |
| 15379 | gc, x, y, width, height); | ||
| 15380 | 15384 | ||
| 15381 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 15385 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 15382 | FRAME_FOREGROUND_PIXEL (f)); | 15386 | FRAME_FOREGROUND_PIXEL (f)); |
| 15383 | } | ||
| 15384 | #endif | ||
| 15385 | 15387 | ||
| 15386 | x_scroll_bar_set_handle (bar, bar->start, bar->end, true); | 15388 | x_scroll_bar_set_handle (bar, bar->start, bar->end, true); |
| 15387 | 15389 | ||
| @@ -15391,27 +15393,13 @@ x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event) | |||
| 15391 | f->output_data.x->scroll_bar_foreground_pixel); | 15393 | f->output_data.x->scroll_bar_foreground_pixel); |
| 15392 | 15394 | ||
| 15393 | /* Draw a one-pixel border just inside the edges of the scroll bar. */ | 15395 | /* Draw a one-pixel border just inside the edges of the scroll bar. */ |
| 15394 | XDrawRectangle (FRAME_X_DISPLAY (f), w, gc, | 15396 | XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc, |
| 15395 | /* x, y, width, height */ | 15397 | bar->left, bar->top, bar->width - 1, bar->height - 1); |
| 15396 | 0, 0, bar->width - 1, bar->height - 1); | ||
| 15397 | |||
| 15398 | /* XDrawPoint (FRAME_X_DISPLAY (f), w, gc, | ||
| 15399 | bar->width - 1, bar->height - 1); | ||
| 15400 | |||
| 15401 | This code is no longer required since the normal GC now uses the | ||
| 15402 | regular line width. */ | ||
| 15403 | 15398 | ||
| 15404 | /* Restore the foreground color of the GC if we changed it above. */ | 15399 | /* Restore the foreground color of the GC if we changed it above. */ |
| 15405 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) | 15400 | if (f->output_data.x->scroll_bar_foreground_pixel != -1) |
| 15406 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 15401 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 15407 | FRAME_FOREGROUND_PIXEL (f)); | 15402 | FRAME_FOREGROUND_PIXEL (f)); |
| 15408 | |||
| 15409 | #ifdef HAVE_XDBE | ||
| 15410 | x_scroll_bar_end_update (FRAME_DISPLAY_INFO (f), bar); | ||
| 15411 | #endif | ||
| 15412 | |||
| 15413 | unblock_input (); | ||
| 15414 | |||
| 15415 | } | 15403 | } |
| 15416 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 15404 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 15417 | 15405 | ||
| @@ -15552,24 +15540,6 @@ x_scroll_bar_note_movement (struct scroll_bar *bar, | |||
| 15552 | } | 15540 | } |
| 15553 | } | 15541 | } |
| 15554 | 15542 | ||
| 15555 | #ifdef HAVE_XDBE | ||
| 15556 | static void | ||
| 15557 | x_scroll_bar_end_update (struct x_display_info *dpyinfo, | ||
| 15558 | struct scroll_bar *bar) | ||
| 15559 | { | ||
| 15560 | XdbeSwapInfo swap_info; | ||
| 15561 | |||
| 15562 | /* This means the scroll bar is double-buffered. */ | ||
| 15563 | if (bar->x_drawable != bar->x_window) | ||
| 15564 | { | ||
| 15565 | memset (&swap_info, 0, sizeof swap_info); | ||
| 15566 | swap_info.swap_window = bar->x_window; | ||
| 15567 | swap_info.swap_action = XdbeCopied; | ||
| 15568 | XdbeSwapBuffers (dpyinfo->display, &swap_info, 1); | ||
| 15569 | } | ||
| 15570 | } | ||
| 15571 | #endif | ||
| 15572 | |||
| 15573 | #endif /* !USE_TOOLKIT_SCROLL_BARS */ | 15543 | #endif /* !USE_TOOLKIT_SCROLL_BARS */ |
| 15574 | 15544 | ||
| 15575 | /* Return information to the user about the current position of the mouse | 15545 | /* Return information to the user about the current position of the mouse |
| @@ -15710,17 +15680,15 @@ x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_windo | |||
| 15710 | } | 15680 | } |
| 15711 | 15681 | ||
| 15712 | 15682 | ||
| 15713 | /* The screen has been cleared so we may have changed foreground or | 15683 | /* The screen has been cleared and foreground or background colors may |
| 15714 | background colors, and the scroll bars may need to be redrawn. | 15684 | have changed, so the scroll bars need to be redrawn. Clear the |
| 15715 | Clear out the scroll bars, and ask for expose events, so we can | 15685 | scroll bars and redraw them. */ |
| 15716 | redraw them. */ | ||
| 15717 | 15686 | ||
| 15718 | static void | 15687 | static void |
| 15719 | x_scroll_bar_clear (struct frame *f) | 15688 | x_scroll_bar_clear (struct frame *f) |
| 15720 | { | 15689 | { |
| 15721 | #ifndef USE_TOOLKIT_SCROLL_BARS | 15690 | #ifndef USE_TOOLKIT_SCROLL_BARS |
| 15722 | Lisp_Object bar; | 15691 | Lisp_Object bar, condemned; |
| 15723 | #ifdef HAVE_XDBE | ||
| 15724 | GC gc = f->output_data.x->normal_gc; | 15692 | GC gc = f->output_data.x->normal_gc; |
| 15725 | 15693 | ||
| 15726 | if (f->output_data.x->scroll_bar_background_pixel != -1) | 15694 | if (f->output_data.x->scroll_bar_background_pixel != -1) |
| @@ -15729,35 +15697,25 @@ x_scroll_bar_clear (struct frame *f) | |||
| 15729 | else | 15697 | else |
| 15730 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 15698 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 15731 | FRAME_BACKGROUND_PIXEL (f)); | 15699 | FRAME_BACKGROUND_PIXEL (f)); |
| 15732 | #endif | ||
| 15733 | 15700 | ||
| 15734 | /* We can have scroll bars even if this is 0, | 15701 | /* We can have scroll bars even if this is 0, |
| 15735 | if we just turned off scroll bar mode. | 15702 | if we just turned off scroll bar mode. |
| 15736 | But in that case we should not clear them. */ | 15703 | But in that case we should not clear them. */ |
| 15737 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) | 15704 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) |
| 15738 | for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar); | 15705 | { |
| 15739 | bar = XSCROLL_BAR (bar)->next) | 15706 | condemned = FRAME_CONDEMNED_SCROLL_BARS (f); |
| 15740 | { | 15707 | for (bar = FRAME_SCROLL_BARS (f); |
| 15741 | #ifdef HAVE_XDBE | 15708 | /* This trick allows us to search both the ordinary and |
| 15742 | if (XSCROLL_BAR (bar)->x_window | 15709 | condemned scroll bar lists with one loop. */ |
| 15743 | == XSCROLL_BAR (bar)->x_drawable) | 15710 | !NILP (bar) || (bar = condemned, |
| 15744 | #endif | 15711 | condemned = Qnil, |
| 15745 | XClearArea (FRAME_X_DISPLAY (f), | 15712 | !NILP (bar)); |
| 15746 | XSCROLL_BAR (bar)->x_window, | 15713 | bar = XSCROLL_BAR (bar)->next) |
| 15747 | 0, 0, 0, 0, True); | 15714 | x_scroll_bar_redraw (XSCROLL_BAR (bar)); |
| 15748 | #ifdef HAVE_XDBE | 15715 | } |
| 15749 | else | ||
| 15750 | XFillRectangle (FRAME_X_DISPLAY (f), | ||
| 15751 | XSCROLL_BAR (bar)->x_drawable, | ||
| 15752 | gc, 0, 0, XSCROLL_BAR (bar)->width, | ||
| 15753 | XSCROLL_BAR (bar)->height); | ||
| 15754 | #endif | ||
| 15755 | } | ||
| 15756 | 15716 | ||
| 15757 | #ifdef HAVE_XDBE | ||
| 15758 | XSetForeground (FRAME_X_DISPLAY (f), gc, | 15717 | XSetForeground (FRAME_X_DISPLAY (f), gc, |
| 15759 | FRAME_FOREGROUND_PIXEL (f)); | 15718 | FRAME_FOREGROUND_PIXEL (f)); |
| 15760 | #endif | ||
| 15761 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 15719 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
| 15762 | } | 15720 | } |
| 15763 | 15721 | ||
| @@ -17643,7 +17601,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17643 | 17601 | ||
| 17644 | if (!FRAME_GARBAGED_P (f)) | 17602 | if (!FRAME_GARBAGED_P (f)) |
| 17645 | { | 17603 | { |
| 17646 | #ifdef USE_X_TOOLKIT | 17604 | #if defined USE_X_TOOLKIT && defined USE_TOOLKIT_SCROLL_BARS |
| 17647 | if (f->output_data.x->edit_widget) | 17605 | if (f->output_data.x->edit_widget) |
| 17648 | /* The widget's expose proc will be run in this | 17606 | /* The widget's expose proc will be run in this |
| 17649 | case. */ | 17607 | case. */ |
| @@ -17658,10 +17616,17 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17658 | #endif | 17616 | #endif |
| 17659 | expose_frame (f, event->xexpose.x, event->xexpose.y, | 17617 | expose_frame (f, event->xexpose.x, event->xexpose.y, |
| 17660 | event->xexpose.width, event->xexpose.height); | 17618 | event->xexpose.width, event->xexpose.height); |
| 17619 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 17620 | x_scroll_bar_handle_exposure (f, (XEvent *) event); | ||
| 17621 | #endif | ||
| 17661 | #ifdef USE_GTK | 17622 | #ifdef USE_GTK |
| 17662 | x_clear_under_internal_border (f); | 17623 | x_clear_under_internal_border (f); |
| 17663 | #endif | 17624 | #endif |
| 17664 | } | 17625 | } |
| 17626 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 17627 | else | ||
| 17628 | x_scroll_bar_handle_exposure (f, (XEvent *) event); | ||
| 17629 | #endif | ||
| 17665 | 17630 | ||
| 17666 | #ifdef HAVE_XDBE | 17631 | #ifdef HAVE_XDBE |
| 17667 | if (!FRAME_GARBAGED_P (f)) | 17632 | if (!FRAME_GARBAGED_P (f)) |
| @@ -17670,9 +17635,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17670 | } | 17635 | } |
| 17671 | else | 17636 | else |
| 17672 | { | 17637 | { |
| 17673 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 17674 | struct scroll_bar *bar; | ||
| 17675 | #endif | ||
| 17676 | #if defined USE_LUCID | 17638 | #if defined USE_LUCID |
| 17677 | /* Submenus of the Lucid menu bar aren't widgets | 17639 | /* Submenus of the Lucid menu bar aren't widgets |
| 17678 | themselves, so there's no way to dispatch events | 17640 | themselves, so there's no way to dispatch events |
| @@ -17684,20 +17646,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17684 | } | 17646 | } |
| 17685 | #endif /* USE_LUCID */ | 17647 | #endif /* USE_LUCID */ |
| 17686 | 17648 | ||
| 17687 | #ifdef USE_TOOLKIT_SCROLL_BARS | ||
| 17688 | /* Dispatch event to the widget. */ | 17649 | /* Dispatch event to the widget. */ |
| 17689 | goto OTHER; | 17650 | goto OTHER; |
| 17690 | #else /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 17691 | bar = x_window_to_scroll_bar (event->xexpose.display, | ||
| 17692 | event->xexpose.window, 2); | ||
| 17693 | |||
| 17694 | if (bar) | ||
| 17695 | x_scroll_bar_expose (bar, event); | ||
| 17696 | #ifdef USE_X_TOOLKIT | ||
| 17697 | else | ||
| 17698 | goto OTHER; | ||
| 17699 | #endif /* USE_X_TOOLKIT */ | ||
| 17700 | #endif /* not USE_TOOLKIT_SCROLL_BARS */ | ||
| 17701 | } | 17651 | } |
| 17702 | break; | 17652 | break; |
| 17703 | 17653 | ||
| @@ -17711,6 +17661,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17711 | event->xgraphicsexpose.y, | 17661 | event->xgraphicsexpose.y, |
| 17712 | event->xgraphicsexpose.width, | 17662 | event->xgraphicsexpose.width, |
| 17713 | event->xgraphicsexpose.height); | 17663 | event->xgraphicsexpose.height); |
| 17664 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 17665 | x_scroll_bar_handle_exposure (f, (XEvent *) event); | ||
| 17666 | #endif | ||
| 17714 | #ifdef USE_GTK | 17667 | #ifdef USE_GTK |
| 17715 | x_clear_under_internal_border (f); | 17668 | x_clear_under_internal_border (f); |
| 17716 | #endif | 17669 | #endif |
| @@ -17718,16 +17671,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17718 | show_back_buffer (f); | 17671 | show_back_buffer (f); |
| 17719 | #endif | 17672 | #endif |
| 17720 | } | 17673 | } |
| 17721 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 17722 | struct scroll_bar *bar | ||
| 17723 | = x_window_to_scroll_bar (dpyinfo->display, | ||
| 17724 | /* Hopefully this is just a window, | ||
| 17725 | not the back buffer. */ | ||
| 17726 | event->xgraphicsexpose.drawable, 2); | ||
| 17727 | |||
| 17728 | if (bar) | ||
| 17729 | x_scroll_bar_expose (bar, event); | ||
| 17730 | #endif | ||
| 17731 | #ifdef USE_X_TOOLKIT | 17674 | #ifdef USE_X_TOOLKIT |
| 17732 | else | 17675 | else |
| 17733 | goto OTHER; | 17676 | goto OTHER; |
diff --git a/src/xterm.h b/src/xterm.h index 2e3d0950d91..2b8a2e5da49 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -1282,11 +1282,6 @@ struct scroll_bar | |||
| 1282 | /* The X window representing this scroll bar. */ | 1282 | /* The X window representing this scroll bar. */ |
| 1283 | Window x_window; | 1283 | Window x_window; |
| 1284 | 1284 | ||
| 1285 | #if defined HAVE_XDBE && !defined USE_TOOLKIT_SCROLL_BARS | ||
| 1286 | /* The X drawable representing this scroll bar. */ | ||
| 1287 | Drawable x_drawable; | ||
| 1288 | #endif | ||
| 1289 | |||
| 1290 | /* The position and size of the scroll bar in pixels, relative to the | 1285 | /* The position and size of the scroll bar in pixels, relative to the |
| 1291 | frame. */ | 1286 | frame. */ |
| 1292 | int top, left, width, height; | 1287 | int top, left, width, height; |