/* Functions for the X window system.
-Copyright (C) 1989, 1992-2015 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2016 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
XFree (tmp_children);
#endif
- if (wm_window == rootw || had_errors)
+ if (had_errors || wm_window == rootw)
break;
win = wm_window;
\f
DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
doc: /* Internal function called by `color-defined-p', which see.
-(Note that the Nextstep version of this function ignores FRAME.) */)
+\(Note that the Nextstep version of this function ignores FRAME.) */)
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
doc: /* Return the "vendor ID" string of the GUI software on TERMINAL.
-(Labeling every distributor as a "vendor" embodies the false assumption
+\(Labeling every distributor as a "vendor" embodies the false assumption
that operating systems cannot be developed and distributed noncommercially.)
The optional argument TERMINAL specifies which display to ask about.
RROutput pxid = None;
struct MonitorInfo *monitors;
-#ifdef HAVE_XRRGETSCREENRESOURCESCURRENT
- resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
+#define RANDR13_LIBRARY \
+ (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3))
+
+#if RANDR13_LIBRARY
+ /* Check if the display supports 1.3 too. */
+ bool randr13_avail = (dpyinfo->xrandr_major_version > 1
+ || (dpyinfo->xrandr_major_version == 1
+ && dpyinfo->xrandr_minor_version >= 3));
+
+ if (randr13_avail)
+ resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
+ else
+ resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
#else
resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
#endif
n_monitors = resources->noutput;
monitors = xzalloc (n_monitors * sizeof *monitors);
-#ifdef HAVE_XRRGETOUTPUTPRIMARY
- pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
+#if RANDR13_LIBRARY
+ if (randr13_avail)
+ pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
#endif
for (i = 0; i < n_monitors; ++i)
xrr_ok = XRRQueryExtension (dpy, &xrr_event_base, &xrr_error_base);
if (xrr_ok)
{
- int xrr_major, xrr_minor;
- XRRQueryVersion (dpy, &xrr_major, &xrr_minor);
- xrr_ok = (xrr_major == 1 && xrr_minor >= 2) || xrr_major > 1;
+ XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version,
+ &dpyinfo->xrandr_minor_version);
+ xrr_ok = ((dpyinfo->xrandr_major_version == 1
+ && dpyinfo->xrandr_minor_version >= 2)
+ || dpyinfo->xrandr_major_version > 1);
}
if (xrr_ok)
Sx_set_mouse_absolute_pixel_position, 2, 2, 0,
doc: /* Move mouse pointer to absolute pixel position (X, Y).
The coordinates X and Y are interpreted in pixels relative to a position
-(0, 0) of the selected frame's display. */)
+\(0, 0) of the selected frame's display. */)
(Lisp_Object x, Lisp_Object y)
{
struct frame *f = SELECTED_FRAME ();
Optional second arg XRM-STRING is a string of resources in xrdb format.
If the optional third arg MUST-SUCCEED is non-nil,
terminate Emacs if we can't open the connection.
-(In the Nextstep version, the last two arguments are currently ignored.) */)
+\(In the Nextstep version, the last two arguments are currently ignored.) */)
(Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
{
char *xrm_option;
"autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
x_default_parameter (f, parms, Qcursor_type, Qbox,
"cursorType", "CursorType", RES_TYPE_SYMBOL);
+ x_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
/* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
Change will not be effected unless different from the current
int win_x, win_y;
Window root, child;
unsigned pmask;
+ int min_x, min_y, max_x, max_y = -1;
/* User-specified position? */
left = Fcdr (Fassq (Qleft, parms));
if ((!INTEGERP (left) && !INTEGERP (right))
|| (!INTEGERP (top) && !INTEGERP (bottom)))
{
+ Lisp_Object frame, attributes, monitor, geometry;
+
block_input ();
XQueryPointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
&root, &child, root_x, root_y, &win_x, &win_y, &pmask);
unblock_input ();
+
+ XSETFRAME(frame, f);
+ attributes = Fx_display_monitor_attributes_list (frame);
+
+ /* Try to determine the monitor where the mouse pointer is and
+ its geometry. See bug#22549. */
+ while (CONSP (attributes))
+ {
+ monitor = XCAR (attributes);
+ geometry = Fassq (Qgeometry, monitor);
+ if (CONSP (geometry))
+ {
+ min_x = XINT (Fnth (make_number (1), geometry));
+ min_y = XINT (Fnth (make_number (2), geometry));
+ max_x = min_x + XINT (Fnth (make_number (3), geometry));
+ max_y = min_y + XINT (Fnth (make_number (4), geometry));
+ if (min_x <= *root_x && *root_x < max_x
+ && min_y <= *root_y && *root_y < max_y)
+ {
+ break;
+ }
+ max_y = -1;
+ }
+
+ attributes = XCDR (attributes);
+ }
+ }
+
+ /* It was not possible to determine the monitor's geometry, so we
+ assign some sane defaults here: */
+ if ( max_y < 0 )
+ {
+ min_x = 0;
+ min_y = 0;
+ max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (f));
+ max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f));
}
if (INTEGERP (top))
*root_y = XINT (top);
else if (INTEGERP (bottom))
*root_y = XINT (bottom) - height;
- else if (*root_y + XINT (dy) <= 0)
- *root_y = 0; /* Can happen for negative dy */
- else if (*root_y + XINT (dy) + height
- <= x_display_pixel_height (FRAME_DISPLAY_INFO (f)))
+ else if (*root_y + XINT (dy) <= min_y)
+ *root_y = min_y; /* Can happen for negative dy */
+ else if (*root_y + XINT (dy) + height <= max_y)
/* It fits below the pointer */
*root_y += XINT (dy);
- else if (height + XINT (dy) <= *root_y)
+ else if (height + XINT (dy) + min_y <= *root_y)
/* It fits above the pointer. */
*root_y -= height + XINT (dy);
else
/* Put it on the top. */
- *root_y = 0;
+ *root_y = min_y;
if (INTEGERP (left))
*root_x = XINT (left);
else if (INTEGERP (right))
- *root_y = XINT (right) - width;
- else if (*root_x + XINT (dx) <= 0)
+ *root_x = XINT (right) - width;
+ else if (*root_x + XINT (dx) <= min_x)
*root_x = 0; /* Can happen for negative dx */
- else if (*root_x + XINT (dx) + width
- <= x_display_pixel_width (FRAME_DISPLAY_INFO (f)))
+ else if (*root_x + XINT (dx) + width <= max_x)
/* It fits to the right of the pointer. */
*root_x += XINT (dx);
- else if (width + XINT (dx) <= *root_x)
+ else if (width + XINT (dx) + min_x <= *root_x)
/* It fits to the left of the pointer. */
*root_x -= width + XINT (dx);
else
- /* Put it left-justified on the screen--it ought to fit that way. */
- *root_x = 0;
+ /* Put it left justified on the screen -- it ought to fit that way. */
+ *root_x = min_x;
}
items is unmapped. Redisplay the menu manually... */
{
Widget w;
- struct frame *f = SELECTED_FRAME ();
- w = f->output_data.x->menubar_widget;
+ struct frame *f = SELECTED_FRAME ();
+ if (FRAME_X_P (f) && FRAME_LIVE_P (f))
+ {
+ w = f->output_data.x->menubar_widget;
- if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
- && w != NULL)
- {
- block_input ();
- xlwmenu_redisplay (w);
- unblock_input ();
- }
+ if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
+ && w != NULL)
+ {
+ block_input ();
+ xlwmenu_redisplay (w);
+ unblock_input ();
+ }
+ }
}
#endif /* USE_LUCID */
}
DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
doc: /* Return image data of FRAMES in TYPE format.
FRAMES should be nil (the selected frame), a frame, or a list of
-frames (each of which corresponds to one page). Optional arg TYPE
-should be either `pdf' (default), `png', `postscript', or `svg'.
-Supported types are determined by the compile-time configuration of
-cairo. */)
+frames (each of which corresponds to one page). Each frame should be
+visible. Optional arg TYPE should be either `pdf' (default), `png',
+`postscript', or `svg'. Supported types are determined by the
+compile-time configuration of cairo. */)
(Lisp_Object frames, Lisp_Object type)
{
- Lisp_Object result, rest, tmp;
+ Lisp_Object rest, tmp;
cairo_surface_type_t surface_type;
- if (NILP (frames))
- frames = selected_frame;
if (!CONSP (frames))
frames = list1 (frames);
tmp = Qnil;
for (rest = frames; CONSP (rest); rest = XCDR (rest))
{
- struct frame *f = XFRAME (XCAR (rest));
-
- if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f))
- error ("Invalid frame");
-
+ struct frame *f = decode_window_system_frame (XCAR (rest));
Lisp_Object frame;
XSETFRAME (frame, f);
+ if (!FRAME_VISIBLE_P (f))
+ error ("Frames to be exported must be visible.");
tmp = Fcons (frame, tmp);
}
frames = Fnreverse (tmp);
#endif
error ("Unsupported export type");
- result = x_cr_export_frames (frames, surface_type);
-
- return result;
+ return x_cr_export_frames (frames, surface_type);
}
#ifdef USE_GTK
on, in points.
The paper width can be obtained as the sum of width, left-margin, and
-right-margin values. Likewise, the paper height is the sum of height,
-top-margin, and bottom-margin values. */)
+right-margin values if the page orientation is `portrait' or
+`reverse-portrait'. Otherwise, it is the sum of width, top-margin,
+and bottom-margin values. Likewise, the paper height is the sum of
+height, top-margin, and bottom-margin values if the page orientation
+is `portrait' or `reverse-portrait'. Otherwise, it is the sum of
+height, left-margin, and right-margin values. */)
(void)
{
Lisp_Object result;
(Lisp_Object frames)
{
Lisp_Object rest, tmp;
+ int count;
- if (NILP (frames))
- frames = selected_frame;
if (!CONSP (frames))
frames = list1 (frames);
tmp = Qnil;
for (rest = frames; CONSP (rest); rest = XCDR (rest))
{
- struct frame *f = XFRAME (XCAR (rest));
- if (! FRAME_LIVE_P (f) || ! FRAME_X_P (f) || ! FRAME_LIVE_P (f))
- error ("Invalid frame");
+ struct frame *f = decode_window_system_frame (XCAR (rest));
Lisp_Object frame;
XSETFRAME (frame, f);
- if (!EQ (Fframe_visible_p (frame), Qt))
+ if (!FRAME_VISIBLE_P (f))
error ("Frames to be printed must be visible.");
tmp = Fcons (frame, tmp);
}
frames = Fnreverse (tmp);
/* Make sure the current matrices are up-to-date. */
- Fredisplay (Qt);
+ count = SPECPDL_INDEX ();
+ specbind (Qredisplay_dont_pause, Qt);
+ redisplay_preserve_echo_area (32);
+ unbind_to (count, Qnil);
block_input ();
xg_print_frames_dialog (frames);