#ifdef USE_GTK
#include "gtkutil.h"
+#ifdef HAVE_GTK3
+#include <X11/Xproto.h>
+#endif
#endif
#ifdef USE_LUCID
#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 */
enum scroll_bar_part *,
Lisp_Object *, Lisp_Object *,
Time *);
-static void x_handle_net_wm_state (struct frame *, XPropertyEvent *);
+static int x_handle_net_wm_state (struct frame *, XPropertyEvent *);
static void x_check_fullscreen (struct frame *);
static void x_check_expected_move (struct frame *, int, int);
static void x_sync_with_move (struct frame *, int, int, int);
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);
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
double alpha = 1.0;
double alpha_min = 1.0;
unsigned long opac;
+ Window parent;
if (dpyinfo->x_highlight_frame == f)
alpha = f->alpha[0];
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;
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,
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];
}
+#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
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. */
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;
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)
{
and border pixel are window attributes which are "private to the
client", so we can always change it to whatever we want. */
BLOCK_INPUT;
+ /* I recently started to get errors in this XSetWindowBorder, depending on
+ the window-manager in use, tho something more is at play since I've been
+ using that same window-manager binary for ever. Let's not crash just
+ because of this (bug#9310). */
+ x_catch_errors (FRAME_X_DISPLAY (f));
XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
f->output_data.x->border_pixel);
+ x_uncatch_errors ();
UNBLOCK_INPUT;
x_update_cursor (f, 1);
x_set_frame_alpha (f);
and border pixel are window attributes which are "private to the
client", so we can always change it to whatever we want. */
BLOCK_INPUT;
+ /* Same as above for XSetWindowBorder (bug#9310). */
+ x_catch_errors (FRAME_X_DISPLAY (f));
XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
f->output_data.x->border_tile);
+ x_uncatch_errors ();
UNBLOCK_INPUT;
x_update_cursor (f, 1);
x_set_frame_alpha (f);
/* Whether the drag scrolling maintains the mouse at the top of the
thumb. If not, resizing the thumb needs to be done more carefully
- to avoid jerkyness. */
+ to avoid jerkiness. */
static Boolean xaw3d_pick_top;
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
XClientMessageEvent *ev = (XClientMessageEvent *) &event;
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- size_t i;
+ ptrdiff_t i;
BLOCK_INPUT;
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 ();
- 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;
} 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;
last_user_time = event.xproperty.time;
f = x_top_window_to_frame (dpyinfo, event.xproperty.window);
if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state)
- x_handle_net_wm_state (f, &event.xproperty);
+ if (x_handle_net_wm_state (f, &event.xproperty) && f->iconified)
+ {
+ /* Gnome shell does not iconify us when C-z is pressed. It hides
+ the frame. So if our state says we aren't hidden anymore,
+ treat it as deiconified. */
+ if (! f->async_iconified)
+ SET_FRAME_GARBAGED (f);
+ f->async_visible = 1;
+ f->async_iconified = 0;
+ f->output_data.x->has_been_visible = 1;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
x_handle_property_notify (&event.xproperty);
xft_settings_event (dpyinfo, &event);
/* 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;
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
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
))
{
}
{ /* Raw bytes, not keysym. */
- register int i;
+ ptrdiff_t i;
int nchars, len;
for (i = 0, nchars = 0; i < nbytes; i++)
if (nchars < nbytes)
{
/* Decode the input data. */
- int require;
/* The input should be decoded with `coding_system'
which depends on which X*LookupString function
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;
count++;
}
+ SAFE_FREE ();
*eventptr = event;
return count;
}
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;
/* 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
}
#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)
static int
x_error_handler (Display *display, XErrorEvent *event)
{
+#ifdef HAVE_GTK3
+ if (event->error_code == BadMatch
+ && event->request_code == X_SetInputFocus
+ && event->minor_code == 0)
+ {
+ return 0;
+ }
+#endif
+
if (x_error_message)
x_error_catcher (display, event);
else
{
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;
}
{
#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;
/* Return the current _NET_WM_STATE.
SIZE_STATE is set to one of the FULLSCREEN_* values.
- STICKY is set to 1 if the sticky state is set, 0 if not. */
+ STICKY is set to 1 if the sticky state is set, 0 if not.
-static void
+ Return non-zero if we are not hidden, zero if we are. */
+
+static int
get_current_wm_state (struct frame *f,
Window window,
int *size_state,
{
Atom actual_type;
unsigned long actual_size, bytes_remaining;
- int i, rc, actual_format;
+ int i, rc, actual_format, is_hidden = 0;
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
long max_len = 65536;
Display *dpy = FRAME_X_DISPLAY (f);
if (tmp_data) XFree (tmp_data);
x_uncatch_errors ();
UNBLOCK_INPUT;
- return;
+ return ! f->iconified;
}
x_uncatch_errors ();
for (i = 0; i < actual_size; ++i)
{
Atom a = ((Atom*)tmp_data)[i];
- if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
+ if (a == dpyinfo->Xatom_net_wm_state_hidden)
+ is_hidden = 1;
+ else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
{
if (*size_state == FULLSCREEN_HEIGHT)
*size_state = FULLSCREEN_MAXIMIZED;
if (tmp_data) XFree (tmp_data);
UNBLOCK_INPUT;
+ return ! is_hidden;
}
/* Do fullscreen as specified in extended window manager hints */
int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state);
int cur, dummy;
- get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
+ (void)get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
/* Some window managers don't say they support _NET_WM_STATE, but they do say
they support _NET_WM_STATE_FULLSCREEN. Try that also. */
}
-static void
+static int
x_handle_net_wm_state (struct frame *f, XPropertyEvent *event)
{
int value = FULLSCREEN_NONE;
Lisp_Object lval;
int sticky = 0;
+ int not_hidden = get_current_wm_state (f, event->window, &value, &sticky);
- get_current_wm_state (f, event->window, &value, &sticky);
lval = Qnil;
switch (value)
{
store_frame_param (f, Qfullscreen, lval);
store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
+
+ return not_hidden;
}
/* Check if we need to resize the frame due to a fullscreen request.
if (!NILP (type))
x_bitmap_icon (f, type);
-#ifdef USE_GTK
+#if defined (USE_GTK)
if (FRAME_GTK_OUTER_WIDGET (f))
{
if (! FRAME_VISIBLE_P (f))
}
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;
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);
{
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] != '.')
struct x_display_info *dpyinfo;
XrmDatabase xrdb;
Mouse_HLInfo *hlinfo;
+ ptrdiff_t lim;
BLOCK_INPUT;
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);
{ "_NET_WM_STATE_MAXIMIZED_VERT",
&dpyinfo->Xatom_net_wm_state_maximized_vert },
{ "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky },
+ { "_NET_WM_STATE_HIDDEN", &dpyinfo->Xatom_net_wm_state_hidden },
{ "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type },
{ "_NET_WM_WINDOW_TYPE_TOOLTIP",
&dpyinfo->Xatom_net_window_type_tooltip },
= 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
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;
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",