aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c246
1 files changed, 179 insertions, 67 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 20516ee9d6f..ddc5db23414 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1,6 +1,6 @@
1/* X Communication module for terminals which understand the X protocol. 1/* X Communication module for terminals which understand the X protocol.
2 2
3Copyright (C) 1989, 1993-2011 Free Software Foundation, Inc. 3Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -93,6 +93,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
93 93
94#ifdef USE_GTK 94#ifdef USE_GTK
95#include "gtkutil.h" 95#include "gtkutil.h"
96#ifdef HAVE_GTK3
97#include <X11/Xproto.h>
98#endif
96#endif 99#endif
97 100
98#ifdef USE_LUCID 101#ifdef USE_LUCID
@@ -100,7 +103,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
100#endif 103#endif
101 104
102#ifdef USE_X_TOOLKIT 105#ifdef USE_X_TOOLKIT
103#if !defined(NO_EDITRES) 106#if !defined (NO_EDITRES)
104#define HACK_EDITRES 107#define HACK_EDITRES
105extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *); 108extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *);
106#endif /* not NO_EDITRES */ 109#endif /* not NO_EDITRES */
@@ -343,7 +346,7 @@ static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
343 enum scroll_bar_part *, 346 enum scroll_bar_part *,
344 Lisp_Object *, Lisp_Object *, 347 Lisp_Object *, Lisp_Object *,
345 Time *); 348 Time *);
346static void x_handle_net_wm_state (struct frame *, XPropertyEvent *); 349static int x_handle_net_wm_state (struct frame *, XPropertyEvent *);
347static void x_check_fullscreen (struct frame *); 350static void x_check_fullscreen (struct frame *);
348static void x_check_expected_move (struct frame *, int, int); 351static void x_check_expected_move (struct frame *, int, int);
349static void x_sync_with_move (struct frame *, int, int, int); 352static void x_sync_with_move (struct frame *, int, int, int);
@@ -442,6 +445,27 @@ x_display_info_for_display (Display *dpy)
442 return 0; 445 return 0;
443} 446}
444 447
448static Window
449x_find_topmost_parent (struct frame *f)
450{
451 struct x_output *x = f->output_data.x;
452 Window win = None, wi = x->parent_desc;
453 Display *dpy = FRAME_X_DISPLAY (f);
454
455 while (wi != FRAME_X_DISPLAY_INFO (f)->root_window)
456 {
457 Window root;
458 Window *children;
459 unsigned int nchildren;
460
461 win = wi;
462 XQueryTree (dpy, win, &root, &wi, &children, &nchildren);
463 XFree (children);
464 }
465
466 return win;
467}
468
445#define OPAQUE 0xffffffff 469#define OPAQUE 0xffffffff
446 470
447void 471void
@@ -453,6 +477,7 @@ x_set_frame_alpha (struct frame *f)
453 double alpha = 1.0; 477 double alpha = 1.0;
454 double alpha_min = 1.0; 478 double alpha_min = 1.0;
455 unsigned long opac; 479 unsigned long opac;
480 Window parent;
456 481
457 if (dpyinfo->x_highlight_frame == f) 482 if (dpyinfo->x_highlight_frame == f)
458 alpha = f->alpha[0]; 483 alpha = f->alpha[0];
@@ -473,6 +498,19 @@ x_set_frame_alpha (struct frame *f)
473 498
474 opac = alpha * OPAQUE; 499 opac = alpha * OPAQUE;
475 500
501 x_catch_errors (dpy);
502
503 /* If there is a parent from the window manager, put the property there
504 also, to work around broken window managers that fail to do that.
505 Do this unconditionally as this function is called on reparent when
506 alpha has not changed on the frame. */
507
508 parent = x_find_topmost_parent (f);
509 if (parent != None)
510 XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
511 XA_CARDINAL, 32, PropModeReplace,
512 (unsigned char *) &opac, 1L);
513
476 /* return unless necessary */ 514 /* return unless necessary */
477 { 515 {
478 unsigned char *data; 516 unsigned char *data;
@@ -480,7 +518,6 @@ x_set_frame_alpha (struct frame *f)
480 int rc, format; 518 int rc, format;
481 unsigned long n, left; 519 unsigned long n, left;
482 520
483 x_catch_errors (dpy);
484 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, 521 rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
485 0L, 1L, False, XA_CARDINAL, 522 0L, 1L, False, XA_CARDINAL,
486 &actual, &format, &n, &left, 523 &actual, &format, &n, &left,
@@ -1272,6 +1309,8 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1272 int y = s->ybase; 1309 int y = s->ybase;
1273 1310
1274 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) 1311 for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1312 /* TAB in a composition means display glyphs with padding
1313 space on the left or right. */
1275 if (COMPOSITION_GLYPH (s->cmp, j) != '\t') 1314 if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1276 { 1315 {
1277 int xx = x + s->cmp->offsets[j * 2]; 1316 int xx = x + s->cmp->offsets[j * 2];
@@ -1625,19 +1664,18 @@ x_color_cells (Display *dpy, int *ncells)
1625 if (dpyinfo->color_cells == NULL) 1664 if (dpyinfo->color_cells == NULL)
1626 { 1665 {
1627 Screen *screen = dpyinfo->screen; 1666 Screen *screen = dpyinfo->screen;
1667 int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
1628 int i; 1668 int i;
1629 1669
1630 dpyinfo->ncolor_cells 1670 dpyinfo->color_cells = xnmalloc (ncolor_cells,
1631 = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); 1671 sizeof *dpyinfo->color_cells);
1632 dpyinfo->color_cells 1672 dpyinfo->ncolor_cells = ncolor_cells;
1633 = (XColor *) xmalloc (dpyinfo->ncolor_cells
1634 * sizeof *dpyinfo->color_cells);
1635 1673
1636 for (i = 0; i < dpyinfo->ncolor_cells; ++i) 1674 for (i = 0; i < ncolor_cells; ++i)
1637 dpyinfo->color_cells[i].pixel = i; 1675 dpyinfo->color_cells[i].pixel = i;
1638 1676
1639 XQueryColors (dpy, dpyinfo->cmap, 1677 XQueryColors (dpy, dpyinfo->cmap,
1640 dpyinfo->color_cells, dpyinfo->ncolor_cells); 1678 dpyinfo->color_cells, ncolor_cells);
1641 } 1679 }
1642 1680
1643 *ncells = dpyinfo->ncolor_cells; 1681 *ncells = dpyinfo->ncolor_cells;
@@ -2254,7 +2292,8 @@ x_draw_image_foreground (struct glyph_string *s)
2254static void 2292static void
2255x_draw_image_relief (struct glyph_string *s) 2293x_draw_image_relief (struct glyph_string *s)
2256{ 2294{
2257 int x0, y0, x1, y1, thick, raised_p, extra; 2295 int x0, y0, x1, y1, thick, raised_p;
2296 int extra_x, extra_y;
2258 XRectangle r; 2297 XRectangle r;
2259 int x = s->x; 2298 int x = s->x;
2260 int y = s->ybase - image_ascent (s->img, s->face, &s->slice); 2299 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
@@ -2285,13 +2324,24 @@ x_draw_image_relief (struct glyph_string *s)
2285 raised_p = s->img->relief > 0; 2324 raised_p = s->img->relief > 0;
2286 } 2325 }
2287 2326
2288 extra = s->face->id == TOOL_BAR_FACE_ID 2327 extra_x = extra_y = 0;
2289 ? XINT (Vtool_bar_button_margin) : 0; 2328 if (s->face->id == TOOL_BAR_FACE_ID)
2329 {
2330 if (CONSP (Vtool_bar_button_margin)
2331 && INTEGERP (XCAR (Vtool_bar_button_margin))
2332 && INTEGERP (XCDR (Vtool_bar_button_margin)))
2333 {
2334 extra_x = XINT (XCAR (Vtool_bar_button_margin));
2335 extra_y = XINT (XCDR (Vtool_bar_button_margin));
2336 }
2337 else if (INTEGERP (Vtool_bar_button_margin))
2338 extra_x = extra_y = XINT (Vtool_bar_button_margin);
2339 }
2290 2340
2291 x0 = x - thick - extra; 2341 x0 = x - thick - extra_x;
2292 y0 = y - thick - extra; 2342 y0 = y - thick - extra_y;
2293 x1 = x + s->slice.width + thick - 1 + extra; 2343 x1 = x + s->slice.width + thick - 1 + extra_x;
2294 y1 = y + s->slice.height + thick - 1 + extra; 2344 y1 = y + s->slice.height + thick - 1 + extra_y;
2295 2345
2296 x_setup_relief_colors (s); 2346 x_setup_relief_colors (s);
2297 get_glyph_string_clip_rect (s, &r); 2347 get_glyph_string_clip_rect (s, &r);
@@ -2925,9 +2975,7 @@ x_clear_frame (struct frame *f)
2925 follow an explicit cursor_to. */ 2975 follow an explicit cursor_to. */
2926 BLOCK_INPUT; 2976 BLOCK_INPUT;
2927 2977
2928 /* The following call is commented out because it does not seem to accomplish 2978 XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
2929 anything, apart from causing flickering during window resize. */
2930 /* XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); */
2931 2979
2932 /* We have to clear the scroll bars. If we have changed colors or 2980 /* We have to clear the scroll bars. If we have changed colors or
2933 something like that, then they should be notified. */ 2981 something like that, then they should be notified. */
@@ -3281,7 +3329,7 @@ x_scroll_run (struct window *w, struct run *run)
3281 } 3329 }
3282 else 3330 else
3283 { 3331 {
3284 /* Scolling down. Make sure we don't copy over the mode line. 3332 /* Scrolling down. Make sure we don't copy over the mode line.
3285 at the bottom. */ 3333 at the bottom. */
3286 if (to_y + run->height > bottom_y) 3334 if (to_y + run->height > bottom_y)
3287 height = bottom_y - to_y; 3335 height = bottom_y - to_y;
@@ -3320,8 +3368,14 @@ frame_highlight (struct frame *f)
3320 and border pixel are window attributes which are "private to the 3368 and border pixel are window attributes which are "private to the
3321 client", so we can always change it to whatever we want. */ 3369 client", so we can always change it to whatever we want. */
3322 BLOCK_INPUT; 3370 BLOCK_INPUT;
3371 /* I recently started to get errors in this XSetWindowBorder, depending on
3372 the window-manager in use, tho something more is at play since I've been
3373 using that same window-manager binary for ever. Let's not crash just
3374 because of this (bug#9310). */
3375 x_catch_errors (FRAME_X_DISPLAY (f));
3323 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 3376 XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3324 f->output_data.x->border_pixel); 3377 f->output_data.x->border_pixel);
3378 x_uncatch_errors ();
3325 UNBLOCK_INPUT; 3379 UNBLOCK_INPUT;
3326 x_update_cursor (f, 1); 3380 x_update_cursor (f, 1);
3327 x_set_frame_alpha (f); 3381 x_set_frame_alpha (f);
@@ -3335,8 +3389,11 @@ frame_unhighlight (struct frame *f)
3335 and border pixel are window attributes which are "private to the 3389 and border pixel are window attributes which are "private to the
3336 client", so we can always change it to whatever we want. */ 3390 client", so we can always change it to whatever we want. */
3337 BLOCK_INPUT; 3391 BLOCK_INPUT;
3392 /* Same as above for XSetWindowBorder (bug#9310). */
3393 x_catch_errors (FRAME_X_DISPLAY (f));
3338 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 3394 XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
3339 f->output_data.x->border_tile); 3395 f->output_data.x->border_tile);
3396 x_uncatch_errors ();
3340 UNBLOCK_INPUT; 3397 UNBLOCK_INPUT;
3341 x_update_cursor (f, 1); 3398 x_update_cursor (f, 1);
3342 x_set_frame_alpha (f); 3399 x_set_frame_alpha (f);
@@ -4137,7 +4194,7 @@ static Boolean xaw3d_arrow_scroll;
4137 4194
4138/* Whether the drag scrolling maintains the mouse at the top of the 4195/* Whether the drag scrolling maintains the mouse at the top of the
4139 thumb. If not, resizing the thumb needs to be done more carefully 4196 thumb. If not, resizing the thumb needs to be done more carefully
4140 to avoid jerkyness. */ 4197 to avoid jerkiness. */
4141 4198
4142static Boolean xaw3d_pick_top; 4199static Boolean xaw3d_pick_top;
4143 4200
@@ -4190,7 +4247,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name,
4190 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ 4247 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
4191 4248
4192static struct window **scroll_bar_windows; 4249static struct window **scroll_bar_windows;
4193static size_t scroll_bar_windows_size; 4250static ptrdiff_t scroll_bar_windows_size;
4194 4251
4195 4252
4196/* Send a client message with message type Xatom_Scrollbar for a 4253/* Send a client message with message type Xatom_Scrollbar for a
@@ -4205,7 +4262,7 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
4205 XClientMessageEvent *ev = (XClientMessageEvent *) &event; 4262 XClientMessageEvent *ev = (XClientMessageEvent *) &event;
4206 struct window *w = XWINDOW (window); 4263 struct window *w = XWINDOW (window);
4207 struct frame *f = XFRAME (w->frame); 4264 struct frame *f = XFRAME (w->frame);
4208 size_t i; 4265 ptrdiff_t i;
4209 4266
4210 BLOCK_INPUT; 4267 BLOCK_INPUT;
4211 4268
@@ -4226,16 +4283,15 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
4226 4283
4227 if (i == scroll_bar_windows_size) 4284 if (i == scroll_bar_windows_size)
4228 { 4285 {
4229 size_t new_size = max (10, 2 * scroll_bar_windows_size); 4286 ptrdiff_t old_nbytes =
4230 size_t nbytes = new_size * sizeof *scroll_bar_windows; 4287 scroll_bar_windows_size * sizeof *scroll_bar_windows;
4231 size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; 4288 ptrdiff_t nbytes;
4232 4289 enum { XClientMessageEvent_MAX = 0x7fffffff };
4233 if ((size_t) -1 / sizeof *scroll_bar_windows < new_size) 4290 scroll_bar_windows =
4234 memory_full (SIZE_MAX); 4291 xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1,
4235 scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, 4292 XClientMessageEvent_MAX, sizeof *scroll_bar_windows);
4236 nbytes); 4293 nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
4237 memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); 4294 memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes);
4238 scroll_bar_windows_size = new_size;
4239 } 4295 }
4240 4296
4241 scroll_bar_windows[i] = w; 4297 scroll_bar_windows[i] = w;
@@ -5107,7 +5163,7 @@ x_scroll_bar_remove (struct scroll_bar *bar)
5107 XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window); 5163 XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window);
5108#endif 5164#endif
5109 5165
5110 /* Disassociate this scroll bar from its window. */ 5166 /* Dissociate this scroll bar from its window. */
5111 XWINDOW (bar->window)->vertical_scroll_bar = Qnil; 5167 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
5112 5168
5113 UNBLOCK_INPUT; 5169 UNBLOCK_INPUT;
@@ -5813,11 +5869,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
5813 } inev; 5869 } inev;
5814 int count = 0; 5870 int count = 0;
5815 int do_help = 0; 5871 int do_help = 0;
5816 int nbytes = 0; 5872 ptrdiff_t nbytes = 0;
5817 struct frame *f = NULL; 5873 struct frame *f = NULL;
5818 struct coding_system coding; 5874 struct coding_system coding;
5819 XEvent event = *eventptr; 5875 XEvent event = *eventptr;
5820 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; 5876 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
5877 USE_SAFE_ALLOCA;
5821 5878
5822 *finish = X_EVENT_NORMAL; 5879 *finish = X_EVENT_NORMAL;
5823 5880
@@ -6069,7 +6126,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6069 last_user_time = event.xproperty.time; 6126 last_user_time = event.xproperty.time;
6070 f = x_top_window_to_frame (dpyinfo, event.xproperty.window); 6127 f = x_top_window_to_frame (dpyinfo, event.xproperty.window);
6071 if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state) 6128 if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state)
6072 x_handle_net_wm_state (f, &event.xproperty); 6129 if (x_handle_net_wm_state (f, &event.xproperty) && f->iconified
6130 && f->output_data.x->net_wm_state_hidden_seen)
6131 {
6132 /* Gnome shell does not iconify us when C-z is pressed. It hides
6133 the frame. So if our state says we aren't hidden anymore,
6134 treat it as deiconified. */
6135 if (! f->async_iconified)
6136 SET_FRAME_GARBAGED (f);
6137 f->async_visible = 1;
6138 f->async_iconified = 0;
6139 f->output_data.x->has_been_visible = 1;
6140 f->output_data.x->net_wm_state_hidden_seen = 0;
6141 inev.ie.kind = DEICONIFY_EVENT;
6142 XSETFRAME (inev.ie.frame_or_window, f);
6143 }
6073 6144
6074 x_handle_property_notify (&event.xproperty); 6145 x_handle_property_notify (&event.xproperty);
6075 xft_settings_event (dpyinfo, &event); 6146 xft_settings_event (dpyinfo, &event);
@@ -6088,6 +6159,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6088 /* Perhaps reparented due to a WM restart. Reset this. */ 6159 /* Perhaps reparented due to a WM restart. Reset this. */
6089 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; 6160 FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
6090 FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0; 6161 FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0;
6162
6163 x_set_frame_alpha (f);
6091 } 6164 }
6092 goto OTHER; 6165 goto OTHER;
6093 6166
@@ -6511,7 +6584,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6511 } 6584 }
6512 6585
6513 { /* Raw bytes, not keysym. */ 6586 { /* Raw bytes, not keysym. */
6514 register int i; 6587 ptrdiff_t i;
6515 int nchars, len; 6588 int nchars, len;
6516 6589
6517 for (i = 0, nchars = 0; i < nbytes; i++) 6590 for (i = 0, nchars = 0; i < nbytes; i++)
@@ -6524,7 +6597,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6524 if (nchars < nbytes) 6597 if (nchars < nbytes)
6525 { 6598 {
6526 /* Decode the input data. */ 6599 /* Decode the input data. */
6527 int require;
6528 6600
6529 /* The input should be decoded with `coding_system' 6601 /* The input should be decoded with `coding_system'
6530 which depends on which X*LookupString function 6602 which depends on which X*LookupString function
@@ -6537,9 +6609,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6537 gives us composition information. */ 6609 gives us composition information. */
6538 coding.common_flags &= ~CODING_ANNOTATION_MASK; 6610 coding.common_flags &= ~CODING_ANNOTATION_MASK;
6539 6611
6540 require = MAX_MULTIBYTE_LENGTH * nbytes; 6612 SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH,
6541 coding.destination = alloca (require); 6613 nbytes);
6542 coding.dst_bytes = require; 6614 coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes;
6543 coding.mode |= CODING_MODE_LAST_BLOCK; 6615 coding.mode |= CODING_MODE_LAST_BLOCK;
6544 decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil); 6616 decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil);
6545 nbytes = coding.produced; 6617 nbytes = coding.produced;
@@ -6998,6 +7070,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
6998 count++; 7070 count++;
6999 } 7071 }
7000 7072
7073 SAFE_FREE ();
7001 *eventptr = event; 7074 *eventptr = event;
7002 return count; 7075 return count;
7003} 7076}
@@ -7651,14 +7724,6 @@ x_fully_uncatch_errors (void)
7651} 7724}
7652#endif 7725#endif
7653 7726
7654/* Nonzero if x_catch_errors has been done and not yet canceled. */
7655
7656int
7657x_catching_errors (void)
7658{
7659 return x_error_message != 0;
7660}
7661
7662#if 0 7727#if 0
7663static unsigned int x_wire_count; 7728static unsigned int x_wire_count;
7664x_trace_wire (void) 7729x_trace_wire (void)
@@ -7819,6 +7884,15 @@ static void x_error_quitter (Display *, XErrorEvent *);
7819static int 7884static int
7820x_error_handler (Display *display, XErrorEvent *event) 7885x_error_handler (Display *display, XErrorEvent *event)
7821{ 7886{
7887#ifdef HAVE_GTK3
7888 if (event->error_code == BadMatch
7889 && event->request_code == X_SetInputFocus
7890 && event->minor_code == 0)
7891 {
7892 return 0;
7893 }
7894#endif
7895
7822 if (x_error_message) 7896 if (x_error_message)
7823 x_error_catcher (display, event); 7897 x_error_catcher (display, event);
7824 else 7898 else
@@ -7865,7 +7939,8 @@ x_io_error_quitter (Display *display)
7865{ 7939{
7866 char buf[256]; 7940 char buf[256];
7867 7941
7868 sprintf (buf, "Connection lost to X server `%s'", DisplayString (display)); 7942 snprintf (buf, sizeof buf, "Connection lost to X server `%s'",
7943 DisplayString (display));
7869 x_connection_closed (display, buf); 7944 x_connection_closed (display, buf);
7870 return 0; 7945 return 0;
7871} 7946}
@@ -8376,9 +8451,11 @@ x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
8376 8451
8377/* Return the current _NET_WM_STATE. 8452/* Return the current _NET_WM_STATE.
8378 SIZE_STATE is set to one of the FULLSCREEN_* values. 8453 SIZE_STATE is set to one of the FULLSCREEN_* values.
8379 STICKY is set to 1 if the sticky state is set, 0 if not. */ 8454 STICKY is set to 1 if the sticky state is set, 0 if not.
8380 8455
8381static void 8456 Return non-zero if we are not hidden, zero if we are. */
8457
8458static int
8382get_current_wm_state (struct frame *f, 8459get_current_wm_state (struct frame *f,
8383 Window window, 8460 Window window,
8384 int *size_state, 8461 int *size_state,
@@ -8386,7 +8463,7 @@ get_current_wm_state (struct frame *f,
8386{ 8463{
8387 Atom actual_type; 8464 Atom actual_type;
8388 unsigned long actual_size, bytes_remaining; 8465 unsigned long actual_size, bytes_remaining;
8389 int i, rc, actual_format; 8466 int i, rc, actual_format, is_hidden = 0;
8390 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 8467 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8391 long max_len = 65536; 8468 long max_len = 65536;
8392 Display *dpy = FRAME_X_DISPLAY (f); 8469 Display *dpy = FRAME_X_DISPLAY (f);
@@ -8408,7 +8485,7 @@ get_current_wm_state (struct frame *f,
8408 if (tmp_data) XFree (tmp_data); 8485 if (tmp_data) XFree (tmp_data);
8409 x_uncatch_errors (); 8486 x_uncatch_errors ();
8410 UNBLOCK_INPUT; 8487 UNBLOCK_INPUT;
8411 return; 8488 return ! f->iconified;
8412 } 8489 }
8413 8490
8414 x_uncatch_errors (); 8491 x_uncatch_errors ();
@@ -8416,7 +8493,12 @@ get_current_wm_state (struct frame *f,
8416 for (i = 0; i < actual_size; ++i) 8493 for (i = 0; i < actual_size; ++i)
8417 { 8494 {
8418 Atom a = ((Atom*)tmp_data)[i]; 8495 Atom a = ((Atom*)tmp_data)[i];
8419 if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) 8496 if (a == dpyinfo->Xatom_net_wm_state_hidden)
8497 {
8498 is_hidden = 1;
8499 f->output_data.x->net_wm_state_hidden_seen = 1;
8500 }
8501 else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
8420 { 8502 {
8421 if (*size_state == FULLSCREEN_HEIGHT) 8503 if (*size_state == FULLSCREEN_HEIGHT)
8422 *size_state = FULLSCREEN_MAXIMIZED; 8504 *size_state = FULLSCREEN_MAXIMIZED;
@@ -8438,6 +8520,7 @@ get_current_wm_state (struct frame *f,
8438 8520
8439 if (tmp_data) XFree (tmp_data); 8521 if (tmp_data) XFree (tmp_data);
8440 UNBLOCK_INPUT; 8522 UNBLOCK_INPUT;
8523 return ! is_hidden;
8441} 8524}
8442 8525
8443/* Do fullscreen as specified in extended window manager hints */ 8526/* Do fullscreen as specified in extended window manager hints */
@@ -8449,7 +8532,7 @@ do_ewmh_fullscreen (struct frame *f)
8449 int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state); 8532 int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state);
8450 int cur, dummy; 8533 int cur, dummy;
8451 8534
8452 get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy); 8535 (void)get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
8453 8536
8454 /* Some window managers don't say they support _NET_WM_STATE, but they do say 8537 /* Some window managers don't say they support _NET_WM_STATE, but they do say
8455 they support _NET_WM_STATE_FULLSCREEN. Try that also. */ 8538 they support _NET_WM_STATE_FULLSCREEN. Try that also. */
@@ -8524,14 +8607,14 @@ XTfullscreen_hook (FRAME_PTR f)
8524} 8607}
8525 8608
8526 8609
8527static void 8610static int
8528x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) 8611x_handle_net_wm_state (struct frame *f, XPropertyEvent *event)
8529{ 8612{
8530 int value = FULLSCREEN_NONE; 8613 int value = FULLSCREEN_NONE;
8531 Lisp_Object lval; 8614 Lisp_Object lval;
8532 int sticky = 0; 8615 int sticky = 0;
8616 int not_hidden = get_current_wm_state (f, event->window, &value, &sticky);
8533 8617
8534 get_current_wm_state (f, event->window, &value, &sticky);
8535 lval = Qnil; 8618 lval = Qnil;
8536 switch (value) 8619 switch (value)
8537 { 8620 {
@@ -8551,6 +8634,8 @@ x_handle_net_wm_state (struct frame *f, XPropertyEvent *event)
8551 8634
8552 store_frame_param (f, Qfullscreen, lval); 8635 store_frame_param (f, Qfullscreen, lval);
8553 store_frame_param (f, Qsticky, sticky ? Qt : Qnil); 8636 store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
8637
8638 return not_hidden;
8554} 8639}
8555 8640
8556/* Check if we need to resize the frame due to a fullscreen request. 8641/* Check if we need to resize the frame due to a fullscreen request.
@@ -8695,7 +8780,7 @@ x_wait_for_event (struct frame *f, int eventtype)
8695 pending_event_wait.f = f; 8780 pending_event_wait.f = f;
8696 pending_event_wait.eventtype = eventtype; 8781 pending_event_wait.eventtype = eventtype;
8697 8782
8698 /* Set timeout to 0.1 second. Hopefully not noticable. 8783 /* Set timeout to 0.1 second. Hopefully not noticeable.
8699 Maybe it should be configurable. */ 8784 Maybe it should be configurable. */
8700 EMACS_SET_SECS_USECS (tmo, 0, 100000); 8785 EMACS_SET_SECS_USECS (tmo, 0, 100000);
8701 EMACS_GET_TIME (tmo_at); 8786 EMACS_GET_TIME (tmo_at);
@@ -8908,6 +8993,18 @@ x_lower_frame (struct frame *f)
8908 } 8993 }
8909} 8994}
8910 8995
8996/* Request focus with XEmbed */
8997
8998void
8999xembed_request_focus (FRAME_PTR f)
9000{
9001 /* See XEmbed Protocol Specification at
9002 http://freedesktop.org/wiki/Specifications/xembed-spec */
9003 if (f->async_visible)
9004 xembed_send_message (f, CurrentTime,
9005 XEMBED_REQUEST_FOCUS, 0, 0, 0);
9006}
9007
8911/* Activate frame with Extended Window Manager Hints */ 9008/* Activate frame with Extended Window Manager Hints */
8912 9009
8913void 9010void
@@ -9234,7 +9331,7 @@ x_iconify_frame (struct frame *f)
9234 if (!NILP (type)) 9331 if (!NILP (type))
9235 x_bitmap_icon (f, type); 9332 x_bitmap_icon (f, type);
9236 9333
9237#ifdef USE_GTK 9334#if defined (USE_GTK)
9238 if (FRAME_GTK_OUTER_WIDGET (f)) 9335 if (FRAME_GTK_OUTER_WIDGET (f))
9239 { 9336 {
9240 if (! FRAME_VISIBLE_P (f)) 9337 if (! FRAME_VISIBLE_P (f))
@@ -9488,6 +9585,14 @@ x_wm_set_size_hint (struct frame *f, long flags, int user_position)
9488 XSizeHints size_hints; 9585 XSizeHints size_hints;
9489 Window window = FRAME_OUTER_WINDOW (f); 9586 Window window = FRAME_OUTER_WINDOW (f);
9490 9587
9588#ifdef USE_X_TOOLKIT
9589 if (f->output_data.x->widget)
9590 {
9591 widget_update_wm_size_hints (f->output_data.x->widget);
9592 return;
9593 }
9594#endif
9595
9491 /* Setting PMaxSize caused various problems. */ 9596 /* Setting PMaxSize caused various problems. */
9492 size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; 9597 size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
9493 9598
@@ -9822,6 +9927,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9822 struct x_display_info *dpyinfo; 9927 struct x_display_info *dpyinfo;
9823 XrmDatabase xrdb; 9928 XrmDatabase xrdb;
9824 Mouse_HLInfo *hlinfo; 9929 Mouse_HLInfo *hlinfo;
9930 ptrdiff_t lim;
9825 9931
9826 BLOCK_INPUT; 9932 BLOCK_INPUT;
9827 9933
@@ -9879,6 +9985,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9879 https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ 9985 https://bugzilla.gnome.org/show_bug.cgi?id=563627. */
9880 id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL 9986 id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
9881 | G_LOG_FLAG_RECURSION, my_log_handler, NULL); 9987 | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
9988
9989 /* NULL window -> events for all windows go to our function.
9990 Call before gtk_init so Gtk+ event filters comes after our. */
9991 gdk_window_add_filter (NULL, event_handler_gdk, NULL);
9992
9882 gtk_init (&argc, &argv2); 9993 gtk_init (&argc, &argv2);
9883 g_log_remove_handler ("GLib", id); 9994 g_log_remove_handler ("GLib", id);
9884 9995
@@ -9888,9 +9999,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9888 9999
9889 dpy = DEFAULT_GDK_DISPLAY (); 10000 dpy = DEFAULT_GDK_DISPLAY ();
9890 10001
9891 /* NULL window -> events for all windows go to our function */
9892 gdk_window_add_filter (NULL, event_handler_gdk, NULL);
9893
9894#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90 10002#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION <= 90
9895 /* Load our own gtkrc if it exists. */ 10003 /* Load our own gtkrc if it exists. */
9896 { 10004 {
@@ -10040,12 +10148,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10040 XSetAfterFunction (x_current_display, x_trace_wire); 10148 XSetAfterFunction (x_current_display, x_trace_wire);
10041#endif /* ! 0 */ 10149#endif /* ! 0 */
10042 10150
10151 lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@";
10152 if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name))
10153 memory_full (SIZE_MAX);
10043 dpyinfo->x_id_name 10154 dpyinfo->x_id_name
10044 = (char *) xmalloc (SBYTES (Vinvocation_name) 10155 = (char *) xmalloc (SBYTES (Vinvocation_name)
10045 + SBYTES (Vsystem_name) 10156 + SBYTES (Vsystem_name)
10046 + 2); 10157 + 2);
10047 sprintf (dpyinfo->x_id_name, "%s@%s", 10158 strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"),
10048 SSDATA (Vinvocation_name), SSDATA (Vsystem_name)); 10159 SSDATA (Vsystem_name));
10049 10160
10050 /* Figure out which modifier bits mean what. */ 10161 /* Figure out which modifier bits mean what. */
10051 x_find_modifier_meanings (dpyinfo); 10162 x_find_modifier_meanings (dpyinfo);
@@ -10210,6 +10321,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10210 { "_NET_WM_STATE_MAXIMIZED_VERT", 10321 { "_NET_WM_STATE_MAXIMIZED_VERT",
10211 &dpyinfo->Xatom_net_wm_state_maximized_vert }, 10322 &dpyinfo->Xatom_net_wm_state_maximized_vert },
10212 { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky }, 10323 { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky },
10324 { "_NET_WM_STATE_HIDDEN", &dpyinfo->Xatom_net_wm_state_hidden },
10213 { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type }, 10325 { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type },
10214 { "_NET_WM_WINDOW_TYPE_TOOLTIP", 10326 { "_NET_WM_WINDOW_TYPE_TOOLTIP",
10215 &dpyinfo->Xatom_net_window_type_tooltip }, 10327 &dpyinfo->Xatom_net_window_type_tooltip },
@@ -10744,7 +10856,7 @@ selected window or cursor position is preserved. */);
10744A value of nil means Emacs doesn't use toolkit scroll bars. 10856A value of nil means Emacs doesn't use toolkit scroll bars.
10745With the X Window system, the value is a symbol describing the 10857With the X Window system, the value is a symbol describing the
10746X toolkit. Possible values are: gtk, motif, xaw, or xaw3d. 10858X toolkit. Possible values are: gtk, motif, xaw, or xaw3d.
10747With MS Windows, the value is t. */); 10859With MS Windows or Nextstep, the value is t. */);
10748#ifdef USE_TOOLKIT_SCROLL_BARS 10860#ifdef USE_TOOLKIT_SCROLL_BARS
10749#ifdef USE_MOTIF 10861#ifdef USE_MOTIF
10750 Vx_toolkit_scroll_bars = intern_c_string ("motif"); 10862 Vx_toolkit_scroll_bars = intern_c_string ("motif");