X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b447c159a98ef4b4a928373123b7f73a4ad7a22f..cb993c584c8ef91f5352ec9aa97d26fd76cfd643:/src/xterm.c diff --git a/src/xterm.c b/src/xterm.c index d6d6457f52..4d3b572ade 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -100,7 +100,7 @@ along with GNU Emacs. If not, see . */ #endif #ifdef USE_X_TOOLKIT -#if !defined(NO_EDITRES) +#if !defined (NO_EDITRES) #define HACK_EDITRES extern void _XEditResCheckMessages (Widget, XtPointer, XEvent *, Boolean *); #endif /* not NO_EDITRES */ @@ -356,7 +356,7 @@ static int x_dispatch_event (XEvent *, Display *); interference with debugging failing X calls. */ static void x_connection_closed (Display *, const char *); static void x_wm_set_window_state (struct frame *, int); -static void x_wm_set_icon_pixmap (struct frame *, int); +static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t); static void x_initialize (void); @@ -442,6 +442,27 @@ x_display_info_for_display (Display *dpy) return 0; } +static Window +x_find_topmost_parent (struct frame *f) +{ + struct x_output *x = f->output_data.x; + Window win = None, wi = x->parent_desc; + Display *dpy = FRAME_X_DISPLAY (f); + + while (wi != FRAME_X_DISPLAY_INFO (f)->root_window) + { + Window root; + Window *children; + unsigned int nchildren; + + win = wi; + XQueryTree (dpy, win, &root, &wi, &children, &nchildren); + XFree (children); + } + + return win; +} + #define OPAQUE 0xffffffff void @@ -453,6 +474,7 @@ x_set_frame_alpha (struct frame *f) double alpha = 1.0; double alpha_min = 1.0; unsigned long opac; + Window parent; if (dpyinfo->x_highlight_frame == f) alpha = f->alpha[0]; @@ -473,6 +495,19 @@ x_set_frame_alpha (struct frame *f) opac = alpha * OPAQUE; + x_catch_errors (dpy); + + /* If there is a parent from the window manager, put the property there + also, to work around broken window managers that fail to do that. + Do this unconditionally as this function is called on reparent when + alpha has not changed on the frame. */ + + parent = x_find_topmost_parent (f); + if (parent != None) + XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) &opac, 1L); + /* return unless necessary */ { unsigned char *data; @@ -480,7 +515,6 @@ x_set_frame_alpha (struct frame *f) int rc, format; unsigned long n, left; - x_catch_errors (dpy); rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left, @@ -1272,6 +1306,8 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s) int y = s->ybase; for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) + /* TAB in a composition means display glyphs with padding + space on the left or right. */ if (COMPOSITION_GLYPH (s->cmp, j) != '\t') { int xx = x + s->cmp->offsets[j * 2]; @@ -1446,6 +1482,8 @@ x_frame_of_widget (Widget widget) } +#ifdef USE_LUCID + /* Allocate a color which is lighter or darker than *PIXEL by FACTOR or DELTA. Try a color with RGB values multiplied by FACTOR first. If this produces the same color as PIXEL, try a color where all RGB @@ -1461,6 +1499,8 @@ x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta); } +#endif + /* Structure specifying which arguments should be passed by Xt to cvt_string_to_pixel. We want the widget's screen and colormap. */ @@ -1621,19 +1661,18 @@ x_color_cells (Display *dpy, int *ncells) if (dpyinfo->color_cells == NULL) { Screen *screen = dpyinfo->screen; + int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); int i; - dpyinfo->ncolor_cells - = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); - dpyinfo->color_cells - = (XColor *) xmalloc (dpyinfo->ncolor_cells - * sizeof *dpyinfo->color_cells); + dpyinfo->color_cells = xnmalloc (ncolor_cells, + sizeof *dpyinfo->color_cells); + dpyinfo->ncolor_cells = ncolor_cells; - for (i = 0; i < dpyinfo->ncolor_cells; ++i) + for (i = 0; i < ncolor_cells; ++i) dpyinfo->color_cells[i].pixel = i; XQueryColors (dpy, dpyinfo->cmap, - dpyinfo->color_cells, dpyinfo->ncolor_cells); + dpyinfo->color_cells, ncolor_cells); } *ncells = dpyinfo->ncolor_cells; @@ -1693,16 +1732,18 @@ x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color) a least-squares matching, which is what X uses for closest color matching with StaticColor visuals. */ int nearest, i; - unsigned long nearest_delta = ~ (unsigned long) 0; + int max_color_delta = 255; + int max_delta = 3 * max_color_delta; + int nearest_delta = max_delta + 1; int ncells; const XColor *cells = x_color_cells (dpy, &ncells); for (nearest = i = 0; i < ncells; ++i) { - long dred = (color->red >> 8) - (cells[i].red >> 8); - long dgreen = (color->green >> 8) - (cells[i].green >> 8); - long dblue = (color->blue >> 8) - (cells[i].blue >> 8); - unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue; + int dred = (color->red >> 8) - (cells[i].red >> 8); + int dgreen = (color->green >> 8) - (cells[i].green >> 8); + int dblue = (color->blue >> 8) - (cells[i].blue >> 8); + int delta = dred * dred + dgreen * dgreen + dblue * dblue; if (delta < nearest_delta) { @@ -4184,7 +4225,7 @@ xt_action_hook (Widget widget, XtPointer client_data, String action_name, x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ static struct window **scroll_bar_windows; -static size_t scroll_bar_windows_size; +static ptrdiff_t scroll_bar_windows_size; /* Send a client message with message type Xatom_Scrollbar for a @@ -4199,7 +4240,7 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) XClientMessageEvent *ev = (XClientMessageEvent *) &event; struct window *w = XWINDOW (window); struct frame *f = XFRAME (w->frame); - size_t i; + ptrdiff_t i; BLOCK_INPUT; @@ -4220,16 +4261,15 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole) if (i == scroll_bar_windows_size) { - size_t new_size = max (10, 2 * scroll_bar_windows_size); - size_t nbytes = new_size * sizeof *scroll_bar_windows; - size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; - - if ((size_t) -1 / sizeof *scroll_bar_windows < new_size) - memory_full (SIZE_MAX); - scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, - nbytes); + ptrdiff_t old_nbytes = + scroll_bar_windows_size * sizeof *scroll_bar_windows; + ptrdiff_t nbytes; + enum { XClientMessageEvent_MAX = 0x7fffffff }; + scroll_bar_windows = + xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1, + XClientMessageEvent_MAX, sizeof *scroll_bar_windows); + nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes); - scroll_bar_windows_size = new_size; } scroll_bar_windows[i] = w; @@ -5807,11 +5847,12 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, } inev; int count = 0; int do_help = 0; - int nbytes = 0; + ptrdiff_t nbytes = 0; struct frame *f = NULL; struct coding_system coding; XEvent event = *eventptr; Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; + USE_SAFE_ALLOCA; *finish = X_EVENT_NORMAL; @@ -6082,6 +6123,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, /* Perhaps reparented due to a WM restart. Reset this. */ FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0; + + x_set_frame_alpha (f); } goto OTHER; @@ -6438,8 +6481,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, keys". It seems there's no cleaner way. Test IsModifierKey to avoid handling mode_switch incorrectly. */ - || ((unsigned) (keysym) >= XK_Select - && (unsigned)(keysym) < XK_KP_Space) + || (XK_Select <= keysym && keysym < XK_KP_Space) #endif #ifdef XK_dead_circumflex || orig_keysym == XK_dead_circumflex @@ -6492,10 +6534,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, should be treated similarly to Mode_switch by Emacs. */ #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock - || ((unsigned)(orig_keysym) - >= XK_ISO_Lock - && (unsigned)(orig_keysym) - <= XK_ISO_Last_Group_Lock) + || (XK_ISO_Lock <= orig_keysym + && orig_keysym <= XK_ISO_Last_Group_Lock) #endif )) { @@ -6508,7 +6548,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, } { /* Raw bytes, not keysym. */ - register int i; + ptrdiff_t i; int nchars, len; for (i = 0, nchars = 0; i < nbytes; i++) @@ -6521,7 +6561,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, if (nchars < nbytes) { /* Decode the input data. */ - int require; /* The input should be decoded with `coding_system' which depends on which X*LookupString function @@ -6534,9 +6573,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, gives us composition information. */ coding.common_flags &= ~CODING_ANNOTATION_MASK; - require = MAX_MULTIBYTE_LENGTH * nbytes; - coding.destination = alloca (require); - coding.dst_bytes = require; + SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, + nbytes); + coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes; coding.mode |= CODING_MODE_LAST_BLOCK; decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil); nbytes = coding.produced; @@ -6995,6 +7034,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, count++; } + SAFE_FREE (); *eventptr = event; return count; } @@ -7424,7 +7464,7 @@ x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, int int x_bitmap_icon (struct frame *f, Lisp_Object file) { - int bitmap_id; + ptrdiff_t bitmap_id; if (FRAME_X_WINDOW (f) == 0) return 1; @@ -7450,7 +7490,7 @@ x_bitmap_icon (struct frame *f, Lisp_Object file) /* Create the GNU bitmap and mask if necessary. */ if (FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id < 0) { - int rc = -1; + ptrdiff_t rc = -1; #ifdef USE_GTK @@ -7648,14 +7688,6 @@ x_fully_uncatch_errors (void) } #endif -/* Nonzero if x_catch_errors has been done and not yet canceled. */ - -int -x_catching_errors (void) -{ - return x_error_message != 0; -} - #if 0 static unsigned int x_wire_count; x_trace_wire (void) @@ -7862,7 +7894,8 @@ x_io_error_quitter (Display *display) { char buf[256]; - sprintf (buf, "Connection lost to X server `%s'", DisplayString (display)); + snprintf (buf, sizeof buf, "Connection lost to X server `%s'", + DisplayString (display)); x_connection_closed (display, buf); return 0; } @@ -8081,7 +8114,7 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name) { #ifdef HAVE_X11R6_XIM struct xim_inst_t *xim_inst; - int len; + ptrdiff_t len; xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t)); dpyinfo->xim_callback_data = xim_inst; @@ -9598,7 +9631,7 @@ x_wm_set_window_state (struct frame *f, int state) } static void -x_wm_set_icon_pixmap (struct frame *f, int pixmap_id) +x_wm_set_icon_pixmap (struct frame *f, ptrdiff_t pixmap_id) { Pixmap icon_pixmap, icon_mask; @@ -9670,8 +9703,6 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) static void x_check_font (struct frame *f, struct font *font) { - Lisp_Object frame; - xassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX])); if (font->driver->check) xassert (font->driver->check (f, font) == 0); @@ -9717,8 +9748,8 @@ same_x_server (const char *name1, const char *name2) { int seen_colon = 0; const char *system_name = SSDATA (Vsystem_name); - int system_name_length = strlen (system_name); - int length_until_period = 0; + ptrdiff_t system_name_length = SBYTES (Vsystem_name); + ptrdiff_t length_until_period = 0; while (system_name[length_until_period] != 0 && system_name[length_until_period] != '.') @@ -9821,6 +9852,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) struct x_display_info *dpyinfo; XrmDatabase xrdb; Mouse_HLInfo *hlinfo; + ptrdiff_t lim; BLOCK_INPUT; @@ -10039,12 +10071,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) XSetAfterFunction (x_current_display, x_trace_wire); #endif /* ! 0 */ + lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@"; + if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name)) + memory_full (SIZE_MAX); dpyinfo->x_id_name = (char *) xmalloc (SBYTES (Vinvocation_name) + SBYTES (Vsystem_name) + 2); - sprintf (dpyinfo->x_id_name, "%s@%s", - SSDATA (Vinvocation_name), SSDATA (Vsystem_name)); + strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), + SSDATA (Vsystem_name)); /* Figure out which modifier bits mean what. */ x_find_modifier_meanings (dpyinfo); @@ -10271,7 +10306,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window, gray_bitmap_bits, gray_bitmap_width, gray_bitmap_height, - (unsigned long) 1, (unsigned long) 0, 1); + 1, 0, 1); } #ifdef HAVE_X_I18N @@ -10697,11 +10732,8 @@ syms_of_xterm (void) staticpro (&last_mouse_scroll_bar); last_mouse_scroll_bar = Qnil; - staticpro (&Qvendor_specific_keysyms); - Qvendor_specific_keysyms = intern_c_string ("vendor-specific-keysyms"); - - staticpro (&Qlatin_1); - Qlatin_1 = intern_c_string ("latin-1"); + DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); + DEFSYM (Qlatin_1, "latin-1"); staticpro (&last_mouse_press_frame); last_mouse_press_frame = Qnil; @@ -10710,8 +10742,7 @@ syms_of_xterm (void) xg_default_icon_file = make_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); staticpro (&xg_default_icon_file); - Qx_gtk_map_stock = intern_c_string ("x-gtk-map-stock"); - staticpro (&Qx_gtk_map_stock); + DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock"); #endif DEFVAR_BOOL ("x-use-underline-position-properties",