diff options
| author | Dmitry Antipov | 2013-09-19 09:21:32 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-09-19 09:21:32 +0400 |
| commit | 091f1e1f29214ab169d60f1f82f1346c1742743b (patch) | |
| tree | adeed7ea3f799ff4185f8ecbe73e1485fa375ea5 /src | |
| parent | 336b5a56bc0e840cd2a59f976b2f801d5a4a260c (diff) | |
| download | emacs-091f1e1f29214ab169d60f1f82f1346c1742743b.tar.gz emacs-091f1e1f29214ab169d60f1f82f1346c1742743b.zip | |
Do not use external array to process X scroll bar messages.
* xterm.c (scroll_bar_windows, scroll_bar_windows_size): Remove.
(x_send_scroll_bar_event): Pack window pointer into two slots
of XClientMessageEvent if we're 64-bit. Adjust comment.
(x_scroll_bar_to_input_event): Unpack accordingly.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/xterm.c | 81 |
2 files changed, 49 insertions, 40 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 9337e83a2a7..2a931693f62 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-09-19 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Do not use external array to process X scroll bar messages. | ||
| 4 | * xterm.c (scroll_bar_windows, scroll_bar_windows_size): Remove. | ||
| 5 | (x_send_scroll_bar_event): Pack window pointer into two slots | ||
| 6 | of XClientMessageEvent if we're 64-bit. Adjust comment. | ||
| 7 | (x_scroll_bar_to_input_event): Unpack accordingly. | ||
| 8 | |||
| 1 | 2013-09-18 Dmitry Antipov <dmantipov@yandex.ru> | 9 | 2013-09-18 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 10 | ||
| 3 | Ifdef away recent changes which aren't relevant to NS port. | 11 | Ifdef away recent changes which aren't relevant to NS port. |
diff --git a/src/xterm.c b/src/xterm.c index 9e10037685b..f52466f52d1 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -4266,13 +4266,6 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, | |||
| 4266 | } | 4266 | } |
| 4267 | #endif /* not USE_GTK */ | 4267 | #endif /* not USE_GTK */ |
| 4268 | 4268 | ||
| 4269 | /* A vector of windows used for communication between | ||
| 4270 | x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ | ||
| 4271 | |||
| 4272 | static struct window **scroll_bar_windows; | ||
| 4273 | static ptrdiff_t scroll_bar_windows_size; | ||
| 4274 | |||
| 4275 | |||
| 4276 | /* Send a client message with message type Xatom_Scrollbar for a | 4269 | /* Send a client message with message type Xatom_Scrollbar for a |
| 4277 | scroll action to the frame of WINDOW. PART is a value identifying | 4270 | scroll action to the frame of WINDOW. PART is a value identifying |
| 4278 | the part of the scroll bar that was clicked on. PORTION is the | 4271 | the part of the scroll bar that was clicked on. PORTION is the |
| @@ -4282,10 +4275,9 @@ static void | |||
| 4282 | x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) | 4275 | x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) |
| 4283 | { | 4276 | { |
| 4284 | XEvent event; | 4277 | XEvent event; |
| 4285 | XClientMessageEvent *ev = (XClientMessageEvent *) &event; | 4278 | XClientMessageEvent *ev = &event.xclient; |
| 4286 | struct window *w = XWINDOW (window); | 4279 | struct window *w = XWINDOW (window); |
| 4287 | struct frame *f = XFRAME (w->frame); | 4280 | struct frame *f = XFRAME (w->frame); |
| 4288 | ptrdiff_t i; | ||
| 4289 | 4281 | ||
| 4290 | block_input (); | 4282 | block_input (); |
| 4291 | 4283 | ||
| @@ -4296,33 +4288,30 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) | |||
| 4296 | ev->window = FRAME_X_WINDOW (f); | 4288 | ev->window = FRAME_X_WINDOW (f); |
| 4297 | ev->format = 32; | 4289 | ev->format = 32; |
| 4298 | 4290 | ||
| 4299 | /* We can only transfer 32 bits in the XClientMessageEvent, which is | 4291 | /* 32-bit X client on a 64-bit X server can pass window pointer |
| 4300 | not enough to store a pointer or Lisp_Object on a 64 bit system. | 4292 | as is. 64-bit client on a 32-bit X server is in trouble |
| 4301 | So, store the window in scroll_bar_windows and pass the index | 4293 | because pointer does not fit and will be truncated while |
| 4302 | into that array in the event. */ | 4294 | passing through the server. So we should use two slots |
| 4303 | for (i = 0; i < scroll_bar_windows_size; ++i) | 4295 | and hope that X12 will resolve such an issues someday. */ |
| 4304 | if (scroll_bar_windows[i] == NULL) | ||
| 4305 | break; | ||
| 4306 | 4296 | ||
| 4307 | if (i == scroll_bar_windows_size) | 4297 | if (BITS_PER_LONG > 32) |
| 4308 | { | 4298 | { |
| 4309 | ptrdiff_t old_nbytes = | 4299 | union { |
| 4310 | scroll_bar_windows_size * sizeof *scroll_bar_windows; | 4300 | int i[2]; |
| 4311 | ptrdiff_t nbytes; | 4301 | void *v; |
| 4312 | enum { XClientMessageEvent_MAX = 0x7fffffff }; | 4302 | } val; |
| 4313 | scroll_bar_windows = | 4303 | val.v = w; |
| 4314 | xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1, | 4304 | ev->data.l[0] = val.i[0]; |
| 4315 | XClientMessageEvent_MAX, sizeof *scroll_bar_windows); | 4305 | ev->data.l[1] = val.i[1]; |
| 4316 | nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; | ||
| 4317 | memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); | ||
| 4318 | } | 4306 | } |
| 4319 | 4307 | else | |
| 4320 | scroll_bar_windows[i] = w; | 4308 | { |
| 4321 | ev->data.l[0] = (long) i; | 4309 | ev->data.l[0] = 0; |
| 4322 | ev->data.l[1] = (long) part; | 4310 | ev->data.l[1] = (long) w; |
| 4323 | ev->data.l[2] = (long) 0; | 4311 | } |
| 4324 | ev->data.l[3] = (long) portion; | 4312 | ev->data.l[2] = part; |
| 4325 | ev->data.l[4] = (long) whole; | 4313 | ev->data.l[3] = portion; |
| 4314 | ev->data.l[4] = whole; | ||
| 4326 | 4315 | ||
| 4327 | /* Make Xt timeouts work while the scroll bar is active. */ | 4316 | /* Make Xt timeouts work while the scroll bar is active. */ |
| 4328 | #ifdef USE_X_TOOLKIT | 4317 | #ifdef USE_X_TOOLKIT |
| @@ -4345,12 +4334,24 @@ static void | |||
| 4345 | x_scroll_bar_to_input_event (const XEvent *event, | 4334 | x_scroll_bar_to_input_event (const XEvent *event, |
| 4346 | struct input_event *ievent) | 4335 | struct input_event *ievent) |
| 4347 | { | 4336 | { |
| 4348 | XClientMessageEvent *ev = (XClientMessageEvent *) event; | 4337 | const XClientMessageEvent *ev = &event->xclient; |
| 4349 | Lisp_Object window; | 4338 | Lisp_Object window; |
| 4350 | struct window *w; | 4339 | struct window *w; |
| 4351 | 4340 | ||
| 4352 | w = scroll_bar_windows[ev->data.l[0]]; | 4341 | /* See the comment in the function above. */ |
| 4353 | scroll_bar_windows[ev->data.l[0]] = NULL; | 4342 | |
| 4343 | if (BITS_PER_LONG > 32) | ||
| 4344 | { | ||
| 4345 | union { | ||
| 4346 | int i[2]; | ||
| 4347 | void *v; | ||
| 4348 | } val; | ||
| 4349 | val.i[0] = ev->data.l[0]; | ||
| 4350 | val.i[1] = ev->data.l[1]; | ||
| 4351 | w = val.v; | ||
| 4352 | } | ||
| 4353 | else | ||
| 4354 | w = (void *) ev->data.l[1]; | ||
| 4354 | 4355 | ||
| 4355 | XSETWINDOW (window, w); | 4356 | XSETWINDOW (window, w); |
| 4356 | 4357 | ||
| @@ -4363,10 +4364,10 @@ x_scroll_bar_to_input_event (const XEvent *event, | |||
| 4363 | ievent->timestamp = | 4364 | ievent->timestamp = |
| 4364 | XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame))); | 4365 | XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame))); |
| 4365 | #endif | 4366 | #endif |
| 4366 | ievent->part = ev->data.l[1]; | 4367 | ievent->code = 0; |
| 4367 | ievent->code = ev->data.l[2]; | 4368 | ievent->part = ev->data.l[2]; |
| 4368 | ievent->x = make_number ((int) ev->data.l[3]); | 4369 | ievent->x = make_number (ev->data.l[3]); |
| 4369 | ievent->y = make_number ((int) ev->data.l[4]); | 4370 | ievent->y = make_number (ev->data.l[4]); |
| 4370 | ievent->modifiers = 0; | 4371 | ievent->modifiers = 0; |
| 4371 | } | 4372 | } |
| 4372 | 4373 | ||