aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-07-31 10:41:58 +0800
committerPo Lu2022-07-31 10:41:58 +0800
commita66e6542769eae039aba57644eca2d6afcbe3360 (patch)
tree584c63cc79c28d5fd6fd3c93127d029cffd13f13 /src
parent88d719e95b76ccb38e4a39b24729d5b3d9514118 (diff)
downloademacs-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.c18
-rw-r--r--src/xterm.c441
-rw-r--r--src/xterm.h5
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);
1129static bool x_get_current_wm_state (struct frame *, Window, int *, bool *, bool *); 1129static bool x_get_current_wm_state (struct frame *, Window, int *, bool *, bool *);
1130static void x_update_opaque_region (struct frame *, XEvent *); 1130static void x_update_opaque_region (struct frame *, XEvent *);
1131 1131
1132#if !defined USE_TOOLKIT_SCROLL_BARS && defined HAVE_XDBE
1133static 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
1137static int x_filter_event (struct x_display_info *, XEvent *); 1133static 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 *);
1143static Window x_get_window_below (Display *, Window, int, int, int *, int *); 1139static Window x_get_window_below (Display *, Window, int, int, int *, int *);
1144 1140
1141#ifndef USE_TOOLKIT_SCROLL_BARS
1142static 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
14775x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end, 14754x_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
15337static void 15312static void
15338x_scroll_bar_expose (struct scroll_bar *bar, const XEvent *event) 15313x_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
15369static void
15370x_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
15556static void
15557x_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
15718static void 15687static void
15719x_scroll_bar_clear (struct frame *f) 15688x_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;