extern int extra_keyboard_modifiers;
+/* The keysyms to use for the various modifiers. */
+
+Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
+static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
+
static Lisp_Object Qvendor_specific_keysyms;
extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
enum scroll_bar_part *,
Lisp_Object *, Lisp_Object *,
unsigned long *));
+static void x_check_fullscreen P_ ((struct frame *));
+static void x_check_fullscreen_move P_ ((struct frame *));
/* Flush display of frame F, or of all frames if F is null. */
4. `:height HEIGHT' specifies that the height of the stretch produced
should be HEIGHT, measured in canonical character units.
- 5. `:relative-height FACTOR' specifies that the height of the the
+ 5. `:relative-height FACTOR' specifies that the height of the
stretch should be FACTOR times the height of the characters having
the glyph property.
if (s->face->use_box_color_for_shadows_p)
color = s->face->box_color;
else if (s->first_glyph->type == IMAGE_GLYPH
+ && s->img->pixmap
&& !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
color = IMAGE_BACKGROUND (s->img, s->f, 0);
else
struct x_display_info *dpyinfo;
unsigned int state;
{
+ EMACS_UINT mod_meta = meta_modifier;
+ EMACS_UINT mod_alt = alt_modifier;
+ EMACS_UINT mod_hyper = hyper_modifier;
+ EMACS_UINT mod_super = super_modifier;
+ Lisp_Object tem;
+
+ tem = Fget (Vx_alt_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
+ tem = Fget (Vx_meta_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_meta = XUINT (tem);
+ tem = Fget (Vx_hyper_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem);
+ tem = Fget (Vx_super_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_super = XUINT (tem);
+
+
return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
- | ((state & ControlMask) ? ctrl_modifier : 0)
- | ((state & dpyinfo->meta_mod_mask) ? meta_modifier : 0)
- | ((state & dpyinfo->alt_mod_mask) ? alt_modifier : 0)
- | ((state & dpyinfo->super_mod_mask) ? super_modifier : 0)
- | ((state & dpyinfo->hyper_mod_mask) ? hyper_modifier : 0));
+ | ((state & ControlMask) ? ctrl_modifier : 0)
+ | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0)
+ | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0)
+ | ((state & dpyinfo->super_mod_mask) ? mod_super : 0)
+ | ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
}
static unsigned int
struct x_display_info *dpyinfo;
unsigned int state;
{
- return ( ((state & alt_modifier) ? dpyinfo->alt_mod_mask : 0)
- | ((state & super_modifier) ? dpyinfo->super_mod_mask : 0)
- | ((state & hyper_modifier) ? dpyinfo->hyper_mod_mask : 0)
- | ((state & shift_modifier) ? ShiftMask : 0)
- | ((state & ctrl_modifier) ? ControlMask : 0)
- | ((state & meta_modifier) ? dpyinfo->meta_mod_mask : 0));
+ EMACS_UINT mod_meta = meta_modifier;
+ EMACS_UINT mod_alt = alt_modifier;
+ EMACS_UINT mod_hyper = hyper_modifier;
+ EMACS_UINT mod_super = super_modifier;
+
+ Lisp_Object tem;
+
+ tem = Fget (Vx_alt_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
+ tem = Fget (Vx_meta_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_meta = XUINT (tem);
+ tem = Fget (Vx_hyper_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem);
+ tem = Fget (Vx_super_keysym, Qmodifier_value);
+ if (! EQ (tem, Qnil)) mod_super = XUINT (tem);
+
+
+ return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0)
+ | ((state & mod_super) ? dpyinfo->super_mod_mask : 0)
+ | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0)
+ | ((state & shift_modifier) ? ShiftMask : 0)
+ | ((state & ctrl_modifier) ? ControlMask : 0)
+ | ((state & mod_meta) ? dpyinfo->meta_mod_mask : 0));
}
/* Convert a keysym to its name. */
set_help_echo:
- /* Set help_echo to a help string.to display for this tool-bar item.
+ /* Set help_echo to a help string to display for this tool-bar item.
XTread_socket does the rest. */
help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
#endif /* not 0 */
-/* Find the position of the the glyph for position POS in OBJECT in
- window W's current matrix, and return in *X/*Y the pixel
- coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
+/* Find the position of the glyph for position POS in OBJECT in
+ window W's current matrix, and return in *X, *Y the pixel
+ coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
RIGHT_P non-zero means return the position of the right edge of the
glyph, RIGHT_P zero means return the left edge position.
f = x_window_to_frame (dpyinfo, event.xexpose.window);
if (f)
{
+ x_check_fullscreen (f);
+
if (f->async_visible == 0)
{
f->async_visible = 1;
if (f)
{
#ifndef USE_X_TOOLKIT
+ /* If there is a pending resize for fullscreen, don't
+ do this one, the right one will come later.
+ The toolkit version doesn't seem to need this, but we
+ need to reset it below. */
+ int dont_resize =
+ ((f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
+ && FRAME_NEW_WIDTH (f) != 0);
int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
+ if (dont_resize)
+ goto OTHER;
/* In the toolkit version, change_frame_size
is called by the code that handles resizing
x_real_positions (f, &f->output_data.x->left_pos,
&f->output_data.x->top_pos);
+ x_check_fullscreen_move(f);
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
+ f->output_data.x->want_fullscreen &=
+ ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
#ifdef HAVE_X_I18N
if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
xic_set_statusarea (f);
if (!cursor_row->enabled_p)
goto mark_cursor_off;
+ /* If row is completely invisible, don't attempt to delete a cursor which
+ isn't there. This can happen if cursor is at top of a window, and
+ we switch to a buffer with a header line in that window. */
+ if (cursor_row->visible_height <= 0)
+ goto mark_cursor_off;
+
/* This can happen when the new row is shorter than the old one.
In this case, either x_draw_glyphs or clear_end_of_line
should have cleared the cursor. Note that we wouldn't be
UNBLOCK_INPUT;
}
+/* Check if we need to resize the frame due to a fullscreen request.
+ If so needed, resize the frame. */
+static void
+x_check_fullscreen (f)
+ struct frame *f;
+{
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_BOTH)
+ {
+ int width, height, ign;
+
+ x_real_positions (f, &f->output_data.x->left_pos,
+ &f->output_data.x->top_pos);
+
+ x_fullscreen_adjust (f, &width, &height, &ign, &ign);
+
+ /* We do not need to move the window, it shall be taken care of
+ when setting WM manager hints.
+ If the frame is visible already, the position is checked by
+ x_check_fullscreen_move. */
+ if (f->width != width || f->height != height)
+ {
+ change_frame_size (f, height, width, 0, 1, 0);
+ SET_FRAME_GARBAGED (f);
+ cancel_mouse_face (f);
+
+ /* Wait for the change of frame size to occur */
+ f->output_data.x->want_fullscreen |= FULLSCREEN_WAIT;
+
+ }
+ }
+}
+
+/* If frame parameters are set after the frame is mapped, we need to move
+ the window. This is done in xfns.c.
+ Some window managers moves the window to the right position, some
+ moves the outer window manager window to the specified position.
+ Here we check that we are in the right spot. If not, make a second
+ move, assuming we are dealing with the second kind of window manager. */
+static void
+x_check_fullscreen_move (f)
+ struct frame *f;
+{
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_MOVE_WAIT)
+ {
+ int expect_top = f->output_data.x->top_pos;
+ int expect_left = f->output_data.x->left_pos;
+
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT)
+ expect_top = 0;
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH)
+ expect_left = 0;
+
+ if (expect_top != f->output_data.x->top_pos
+ || expect_left != f->output_data.x->left_pos)
+ x_set_offset (f, expect_left, expect_top, 1);
+
+ /* Just do this once */
+ f->output_data.x->want_fullscreen &= ~FULLSCREEN_MOVE_WAIT;
+ }
+}
+
+
+/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
+ wanted positions of the WM window (not emacs window).
+ Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
+ window (FRAME_X_WINDOW).
+ */
+void
+x_fullscreen_adjust (f, width, height, top_pos, left_pos)
+ struct frame *f;
+ int *width;
+ int *height;
+ int *top_pos;
+ int *left_pos;
+{
+ int newwidth = f->width, newheight = f->height;
+
+ *top_pos = f->output_data.x->top_pos;
+ *left_pos = f->output_data.x->left_pos;
+
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT)
+ {
+ int ph;
+
+ ph = FRAME_X_DISPLAY_INFO (f)->height;
+ newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+ ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
+ - f->output_data.x->y_pixels_diff;
+ newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
+ *top_pos = 0;
+ }
+
+ if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH)
+ {
+ int pw;
+
+ pw = FRAME_X_DISPLAY_INFO (f)->width;
+ newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+ pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
+ - f->output_data.x->x_pixels_diff;
+ newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
+ *left_pos = 0;
+ }
+
+ *width = newwidth;
+ *height = newheight;
+}
+
/* Change the size of frame F's X window to COLS/ROWS in the case F
doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
/* Set global flag fonts_changed_p to non-zero if the font loaded
has a character with a smaller width than any other character
- before, or if the font loaded has a smalle>r height than any
+ before, or if the font loaded has a smaller height than any
other font loaded before. If this happens, it will make a
glyph matrix reallocation necessary. */
- fonts_changed_p = x_compute_min_glyph_bounds (f);
+ fonts_changed_p |= x_compute_min_glyph_bounds (f);
UNBLOCK_INPUT;
return fontp;
}
staticpro (&last_mouse_motion_frame);
last_mouse_motion_frame = Qnil;
+
+ Qmodifier_value = intern ("modifier-value");
+ Qalt = intern ("alt");
+ Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
+ Qhyper = intern ("hyper");
+ Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
+ Qmeta = intern ("meta");
+ Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
+ Qsuper = intern ("super");
+ Fput (Qsuper, Qmodifier_value, make_number (super_modifier));
+
+ DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym,
+ doc: /* Which keys Emacs uses for the alt modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `alt' means use the Alt_L and Alt_R keysyms. The default
+is nil, which is the same as `alt'. */);
+ Vx_alt_keysym = Qnil;
+
+ DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym,
+ doc: /* Which keys Emacs uses for the hyper modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `hyper' means use the Hyper_L and Hyper_R keysyms. The
+default is nil, which is the same as `hyper'. */);
+ Vx_hyper_keysym = Qnil;
+
+ DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym,
+ doc: /* Which keys Emacs uses for the meta modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `meta' means use the Meta_L and Meta_R keysyms. The
+default is nil, which is the same as `meta'. */);
+ Vx_meta_keysym = Qnil;
+
+ DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym,
+ doc: /* Which keys Emacs uses for the super modifier.
+This should be one of the symbols `alt', `hyper', `meta', `super'.
+For example, `super' means use the Super_L and Super_R keysyms. The
+default is nil, which is the same as `super'. */);
+ Vx_super_keysym = Qnil;
+
}
#endif /* HAVE_X_WINDOWS */