diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/xterm.c b/src/xterm.c index dadc6405d2c..bae2c229aa9 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -7717,6 +7717,12 @@ xt_action_hook (widget, client_data, action_name, event, params, | |||
| 7717 | } | 7717 | } |
| 7718 | } | 7718 | } |
| 7719 | 7719 | ||
| 7720 | /* A vector of windows used for communication between | ||
| 7721 | x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ | ||
| 7722 | |||
| 7723 | static struct window **scroll_bar_windows; | ||
| 7724 | static int scroll_bar_windows_size; | ||
| 7725 | |||
| 7720 | 7726 | ||
| 7721 | /* Send a client message with message type Xatom_Scrollbar for a | 7727 | /* Send a client message with message type Xatom_Scrollbar for a |
| 7722 | scroll action to the frame of WINDOW. PART is a value identifying | 7728 | scroll action to the frame of WINDOW. PART is a value identifying |
| @@ -7730,15 +7736,41 @@ x_send_scroll_bar_event (window, part, portion, whole) | |||
| 7730 | { | 7736 | { |
| 7731 | XEvent event; | 7737 | XEvent event; |
| 7732 | XClientMessageEvent *ev = (XClientMessageEvent *) &event; | 7738 | XClientMessageEvent *ev = (XClientMessageEvent *) &event; |
| 7733 | struct frame *f = XFRAME (XWINDOW (window)->frame); | 7739 | struct window *w = XWINDOW (window); |
| 7740 | struct frame *f = XFRAME (w->frame); | ||
| 7741 | int i; | ||
| 7734 | 7742 | ||
| 7743 | BLOCK_INPUT; | ||
| 7744 | |||
| 7735 | /* Construct a ClientMessage event to send to the frame. */ | 7745 | /* Construct a ClientMessage event to send to the frame. */ |
| 7736 | ev->type = ClientMessage; | 7746 | ev->type = ClientMessage; |
| 7737 | ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar; | 7747 | ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar; |
| 7738 | ev->display = FRAME_X_DISPLAY (f); | 7748 | ev->display = FRAME_X_DISPLAY (f); |
| 7739 | ev->window = FRAME_X_WINDOW (f); | 7749 | ev->window = FRAME_X_WINDOW (f); |
| 7740 | ev->format = 32; | 7750 | ev->format = 32; |
| 7741 | ev->data.l[0] = (long) XFASTINT (window); | 7751 | |
| 7752 | /* We can only transfer 32 bits in the XClientMessageEvent, which is | ||
| 7753 | not enough to store a pointer or Lisp_Object on a 64 bit system. | ||
| 7754 | So, store the window in scroll_bar_windows and pass the index | ||
| 7755 | into that array in the event. */ | ||
| 7756 | for (i = 0; i < scroll_bar_windows_size; ++i) | ||
| 7757 | if (scroll_bar_windows[i] == NULL) | ||
| 7758 | break; | ||
| 7759 | |||
| 7760 | if (i == scroll_bar_windows_size) | ||
| 7761 | { | ||
| 7762 | int new_size = max (10, 2 * scroll_bar_windows_size); | ||
| 7763 | size_t nbytes = new_size * sizeof *scroll_bar_windows; | ||
| 7764 | size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; | ||
| 7765 | |||
| 7766 | scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, | ||
| 7767 | nbytes); | ||
| 7768 | bzero (&scroll_bar_windows[i], nbytes - old_nbytes); | ||
| 7769 | scroll_bar_windows_size = new_size; | ||
| 7770 | } | ||
| 7771 | |||
| 7772 | scroll_bar_windows[i] = w; | ||
| 7773 | ev->data.l[0] = (long) i; | ||
| 7742 | ev->data.l[1] = (long) part; | 7774 | ev->data.l[1] = (long) part; |
| 7743 | ev->data.l[2] = (long) 0; | 7775 | ev->data.l[2] = (long) 0; |
| 7744 | ev->data.l[3] = (long) portion; | 7776 | ev->data.l[3] = (long) portion; |
| @@ -7750,7 +7782,6 @@ x_send_scroll_bar_event (window, part, portion, whole) | |||
| 7750 | /* Setting the event mask to zero means that the message will | 7782 | /* Setting the event mask to zero means that the message will |
| 7751 | be sent to the client that created the window, and if that | 7783 | be sent to the client that created the window, and if that |
| 7752 | window no longer exists, no event will be sent. */ | 7784 | window no longer exists, no event will be sent. */ |
| 7753 | BLOCK_INPUT; | ||
| 7754 | XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False, 0, &event); | 7785 | XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False, 0, &event); |
| 7755 | UNBLOCK_INPUT; | 7786 | UNBLOCK_INPUT; |
| 7756 | } | 7787 | } |
| @@ -7767,9 +7798,13 @@ x_scroll_bar_to_input_event (event, ievent) | |||
| 7767 | XClientMessageEvent *ev = (XClientMessageEvent *) event; | 7798 | XClientMessageEvent *ev = (XClientMessageEvent *) event; |
| 7768 | Lisp_Object window; | 7799 | Lisp_Object window; |
| 7769 | struct frame *f; | 7800 | struct frame *f; |
| 7801 | struct window *w; | ||
| 7802 | |||
| 7803 | w = scroll_bar_windows[ev->data.l[0]]; | ||
| 7804 | scroll_bar_windows[ev->data.l[0]] = NULL; | ||
| 7770 | 7805 | ||
| 7771 | XSETFASTINT (window, ev->data.l[0]); | 7806 | XSETWINDOW (window, w); |
| 7772 | f = XFRAME (XWINDOW (window)->frame); | 7807 | f = XFRAME (w->frame); |
| 7773 | 7808 | ||
| 7774 | ievent->kind = scroll_bar_click; | 7809 | ievent->kind = scroll_bar_click; |
| 7775 | ievent->frame_or_window = window; | 7810 | ievent->frame_or_window = window; |