/* Functions for the X window system.
- Copyright (C) 1989, 92, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 01, 02
Free Software Foundation.
This file is part of GNU Emacs.
#include "keyboard.h"
#include "blockinput.h"
#include <epaths.h>
+#include "character.h"
#include "charset.h"
#include "coding.h"
#include "fontset.h"
Lisp_Object Qscreen_gamma, Qline_spacing, Qcenter;
Lisp_Object Qcompound_text, Qcancel_timer;
Lisp_Object Qwait_for_wm;
+Lisp_Object Qfullscreen;
+Lisp_Object Qfullwidth;
+Lisp_Object Qfullheight;
+Lisp_Object Qfullboth;
/* The below are defined in frame.c. */
void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object));
static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object));
+static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
{"line-spacing", x_set_line_spacing},
{"left-fringe", x_set_fringe_width},
{"right-fringe", x_set_fringe_width},
- {"wait-for-wm", x_set_wait_for_wm}
+ {"wait-for-wm", x_set_wait_for_wm},
+ {"fullscreen", x_set_fullscreen},
+
};
/* Attach the `x-frame-parameter' properties to
make_number (i));
}
\f
+
+/* Really try to move where we want to be in case of fullscreen. Some WMs
+ moves the window where we tell them. Some (mwm, twm) moves the outer
+ window manager window there instead.
+ Try to compensate for those WM here. */
+static void
+x_fullscreen_move (f, new_top, new_left)
+ struct frame *f;
+ int new_top;
+ int new_left;
+{
+ if (new_top != f->output_data.x->top_pos
+ || new_left != f->output_data.x->left_pos)
+ {
+ int move_x = new_left + f->output_data.x->x_pixels_outer_diff;
+ int move_y = new_top + f->output_data.x->y_pixels_outer_diff;
+
+ f->output_data.x->want_fullscreen |= FULLSCREEN_MOVE_WAIT;
+ x_set_offset (f, move_x, move_y, 1);
+ }
+}
+
/* Change the parameters of frame F as specified by ALIST.
If a parameter is not specially recognized, do nothing special;
otherwise call the `x_set_...' function for that parameter.
int i, p;
int left_no_change = 0, top_no_change = 0;
int icon_left_no_change = 0, icon_top_no_change = 0;
+ int fullscreen_is_being_set = 0;
struct gcpro gcpro1, gcpro2;
They are independent of other properties, but other properties (e.g.,
cursor_color) are dependent upon them. */
/* Process default font as well, since fringe widths depends on it. */
+ /* Also, process fullscreen, width and height depend upon that */
for (p = 0; p < i; p++)
{
Lisp_Object prop, val;
val = values[p];
if (EQ (prop, Qforeground_color)
|| EQ (prop, Qbackground_color)
- || EQ (prop, Qfont))
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
{
register Lisp_Object param_index, old_value;
old_value = get_frame_param (f, prop);
+ fullscreen_is_being_set |= EQ (prop, Qfullscreen);
if (NILP (Fequal (val, old_value)))
{
icon_left = val;
else if (EQ (prop, Qforeground_color)
|| EQ (prop, Qbackground_color)
- || EQ (prop, Qfont))
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
/* Processed above. */
continue;
else
XSETINT (icon_top, 0);
}
+ if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
+ {
+ /* If the frame is visible already and the fullscreen parameter is
+ being set, it is too late to set WM manager hints to specify
+ size and position.
+ Here we first get the width, height and position that applies to
+ fullscreen. We then move the frame to the appropriate
+ position. Resize of the frame is taken care of in the code after
+ this if-statement. */
+ int new_left, new_top;
+
+ x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
+ x_fullscreen_move (f, new_top, new_left);
+ }
+
/* Don't set these parameters unless they've been explicitly
specified. The window might be mapped or resized while we're in
this function, and we don't want to override that unless the lisp
FRAME_PTR f;
int *xptr, *yptr;
{
- int win_x, win_y;
- Window child;
+ int win_x, win_y, outer_x, outer_y;
+ int real_x = 0, real_y = 0;
+ int had_errors = 0;
+ Window win = f->output_data.x->parent_desc;
- /* This is pretty gross, but seems to be the easiest way out of
- the problem that arises when restarting window-managers. */
+ int count;
-#ifdef USE_X_TOOLKIT
- Window outer = (f->output_data.x->widget
- ? XtWindow (f->output_data.x->widget)
- : FRAME_X_WINDOW (f));
-#else
- Window outer = f->output_data.x->window_desc;
-#endif
- Window tmp_root_window;
- Window *tmp_children;
- unsigned int tmp_nchildren;
+ BLOCK_INPUT;
+
+ count = x_catch_errors (FRAME_X_DISPLAY (f));
- while (1)
+ if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
+ win = FRAME_OUTER_WINDOW (f);
+
+ /* This loop traverses up the containment tree until we hit the root
+ window. Window managers may intersect many windows between our window
+ and the root window. The window we find just before the root window
+ should be the outer WM window. */
+ for (;;)
{
- int count = x_catch_errors (FRAME_X_DISPLAY (f));
- Window outer_window;
+ Window wm_window, rootw;
+ Window *tmp_children;
+ unsigned int tmp_nchildren;
- XQueryTree (FRAME_X_DISPLAY (f), outer, &tmp_root_window,
- &f->output_data.x->parent_desc,
- &tmp_children, &tmp_nchildren);
+ XQueryTree (FRAME_X_DISPLAY (f), win, &rootw,
+ &wm_window, &tmp_children, &tmp_nchildren);
XFree ((char *) tmp_children);
- win_x = win_y = 0;
+ had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
- /* Find the position of the outside upper-left corner of
- the inner window, with respect to the outer window. */
- if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
- outer_window = f->output_data.x->parent_desc;
- else
- outer_window = outer;
+ if (wm_window == rootw || had_errors)
+ break;
+ win = wm_window;
+ }
+
+ if (! had_errors)
+ {
+ int ign;
+ Window child, rootw;
+
+ /* Get the real coordinates for the WM window upper left corner */
+ XGetGeometry (FRAME_X_DISPLAY (f), win,
+ &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
+
+ /* Translate real coordinates to coordinates relative to our
+ window. For our window, the upper left corner is 0, 0.
+ Since the upper left corner of the WM window is outside
+ our window, win_x and win_y will be negative:
+
+ ------------------ ---> x
+ | title |
+ | ----------------- v y
+ | | our window
+ */
XTranslateCoordinates (FRAME_X_DISPLAY (f),
/* From-window, to-window. */
- outer_window,
FRAME_X_DISPLAY_INFO (f)->root_window,
+ FRAME_X_WINDOW (f),
/* From-position, to-position. */
- 0, 0, &win_x, &win_y,
+ real_x, real_y, &win_x, &win_y,
/* Child of win. */
&child);
- /* It is possible for the window returned by the XQueryNotify
- to become invalid by the time we call XTranslateCoordinates.
- That can happen when you restart some window managers.
- If so, we get an error in XTranslateCoordinates.
- Detect that and try the whole thing over. */
- if (! x_had_errors_p (FRAME_X_DISPLAY (f)))
+ if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
{
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
- break;
+ outer_x = win_x;
+ outer_y = win_y;
}
+ else
+ {
+ XTranslateCoordinates (FRAME_X_DISPLAY (f),
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+ /* From-window, to-window. */
+ FRAME_X_DISPLAY_INFO (f)->root_window,
+ FRAME_OUTER_WINDOW (f),
+
+ /* From-position, to-position. */
+ real_x, real_y, &outer_x, &outer_y,
+
+ /* Child of win. */
+ &child);
}
- *xptr = win_x;
- *yptr = win_y;
+ had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
+ }
+
+ x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+
+ UNBLOCK_INPUT;
+
+ if (had_errors) return;
+
+ f->output_data.x->x_pixels_diff = -win_x;
+ f->output_data.x->y_pixels_diff = -win_y;
+ f->output_data.x->x_pixels_outer_diff = -outer_x;
+ f->output_data.x->y_pixels_outer_diff = -outer_y;
+
+ *xptr = real_x;
+ *yptr = real_y;
}
/* Insert a description of internally-recorded parameters of frame X
}
+/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
+ the previous value of that parameter, NEW_VALUE is the new value. */
+
+static void
+x_set_fullscreen (f, new_value, old_value)
+ struct frame *f;
+ Lisp_Object new_value, old_value;
+{
+ if (NILP (new_value))
+ f->output_data.x->want_fullscreen = FULLSCREEN_NONE;
+ else if (EQ (new_value, Qfullboth))
+ f->output_data.x->want_fullscreen = FULLSCREEN_BOTH;
+ else if (EQ (new_value, Qfullwidth))
+ f->output_data.x->want_fullscreen = FULLSCREEN_WIDTH;
+ else if (EQ (new_value, Qfullheight))
+ f->output_data.x->want_fullscreen = FULLSCREEN_HEIGHT;
+}
+
+
/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
the previous value of that parameter, NEW_VALUE is the new
value. */
BLOCK_INPUT;
result = (STRINGP (fontset_name)
? x_new_fontset (f, XSTRING (fontset_name)->data)
- : x_new_font (f, XSTRING (arg)->data));
+ : x_new_fontset (f, XSTRING (arg)->data));
UNBLOCK_INPUT;
if (EQ (result, Qnil))
if (old_fontset == f->output_data.x->fontset)
return;
}
- else if (!NILP (Fequal (result, oldval)))
+ store_frame_param (f, Qfont, result);
+ if (!NILP (Fequal (result, oldval)))
return;
- store_frame_param (f, Qfont, result);
recompute_basic_faces (f);
}
else
CODING_SYSTEM, and return a newly allocated memory area which
should be freed by `xfree' by a caller.
+ SELECTIONP non-zero means the string is being encoded for an X
+ selection, so it is safe to run pre-write conversions (which
+ may run Lisp code).
+
Store the byte length of resulting text in *TEXT_BYTES.
If the text contains only ASCII and Latin-1, store 1 in *STRING_P,
the result should be `COMPOUND_TEXT'. */
unsigned char *
-x_encode_text (string, coding_system, text_bytes, stringp)
+x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
Lisp_Object string, coding_system;
int *text_bytes, *stringp;
+ int selectionp;
{
- unsigned char *str = XSTRING (string)->data;
- int chars = XSTRING (string)->size;
- int bytes = STRING_BYTES (XSTRING (string));
- int charset_info;
- int bufsize;
- unsigned char *buf;
+ int result = string_xstring_p (string);
struct coding_system coding;
- charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil);
- if (charset_info == 0)
+ if (result == 0)
{
/* No multibyte character in OBJ. We need not encode it. */
- *text_bytes = bytes;
+ *text_bytes = STRING_BYTES (XSTRING (string));
*stringp = 1;
- return str;
+ return XSTRING (string)->data;
}
setup_coding_system (coding_system, &coding);
- coding.src_multibyte = 1;
- coding.dst_multibyte = 0;
- coding.mode |= CODING_MODE_LAST_BLOCK;
- if (coding.type == coding_type_iso2022)
- coding.flags |= CODING_FLAG_ISO_SAFE;
+ coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
/* We suppress producing escape sequences for composition. */
- coding.composing = COMPOSITION_DISABLED;
- bufsize = encoding_buffer_size (&coding, bytes);
- buf = (unsigned char *) xmalloc (bufsize);
- encode_coding (&coding, str, buf, bytes, bufsize);
+ coding.common_flags &= ~CODING_ANNOTATION_MASK;
+ coding.dst_bytes = XSTRING (string)->size * 2;
+ coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+ encode_coding_object (&coding, string, 0, 0,
+ XSTRING (string)->size,
+ STRING_BYTES (XSTRING (string)), Qnil);
*text_bytes = coding.produced;
- *stringp = (charset_info == 1 || !EQ (coding_system, Qcompound_text));
- return buf;
+ *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
+ return coding.destination;
}
\f
coding_system = Vlocale_coding_system;
if (NILP (coding_system))
coding_system = Qcompound_text;
- text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+ text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
text.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
text.format = 8;
}
else
{
- icon.value = x_encode_text (f->icon_name, coding_system,
+ icon.value = x_encode_text (f->icon_name, coding_system, 0,
&bytes, &stringp);
icon.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
coding_system = Vlocale_coding_system;
if (NILP (coding_system))
coding_system = Qcompound_text;
- text.value = x_encode_text (name, coding_system, &bytes, &stringp);
+ text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
text.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
text.format = 8;
}
else
{
- icon.value = x_encode_text (f->icon_name, coding_system,
+ icon.value = x_encode_text (f->icon_name, coding_system, 0,
&bytes, &stringp);
icon.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
window_prompting |= PPosition;
}
+ if (f->output_data.x->want_fullscreen != FULLSCREEN_NONE)
+ {
+ int left, top;
+ int width, height;
+
+ /* It takes both for some WM:s to place it where we want */
+ window_prompting = USPosition | PPosition;
+ x_fullscreen_adjust (f, &width, &height, &top, &left);
+ f->width = width;
+ f->height = height;
+ f->output_data.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
+ f->output_data.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
+ f->output_data.x->left_pos = left;
+ f->output_data.x->top_pos = top;
+ }
+
return window_prompting;
}
BLOCK_INPUT;
/* First, try whatever font the caller has specified. */
if (STRINGP (font))
- {
- tem = Fquery_fontset (font, Qnil);
- if (STRINGP (tem))
- font = x_new_fontset (f, XSTRING (tem)->data);
- else
- font = x_new_font (f, XSTRING (font)->data);
- }
+ font = x_new_fontset (f, XSTRING (font)->data);
/* Try out a font which we hope has bold and italic variations. */
if (!STRINGP (font))
- font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
+ font = x_new_fontset (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
if (!STRINGP (font))
- font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
if (! STRINGP (font))
- font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
if (! STRINGP (font))
/* This was formerly the first thing tried, but it finds too many fonts
and takes too long. */
- font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
/* If those didn't work, look for something which will at least work. */
if (! STRINGP (font))
- font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_fontset (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
UNBLOCK_INPUT;
if (! STRINGP (font))
font = build_string ("fixed");
"title", "Title", RES_TYPE_STRING);
x_default_parameter (f, parms, Qwait_for_wm, Qt,
"waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
+ x_default_parameter (f, parms, Qfullscreen, Qnil,
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window;
struct frame *f;
XImage *ximg;
Pixmap pixmap;
+ int width, height;
{
GC gc;
/* Work around a warning about HAVE_STDLIB_H being redefined in
jconfig.h. */
#ifdef HAVE_STDLIB_H
-#define HAVE_STDLIB_H_1
-#undef HAVE_STDLIB_H
-#endif /* HAVE_STLIB_H */
-
-#include <jpeglib.h>
+# undef HAVE_STDLIB_H
+# include <jpeglib.h>
+# undef HAVE_STDLIB_H
+# define HAVE_STDLIB_H 1
+#else
+# include <jpeglib.h>
+#endif /* HAVE_STDLIB_H */
#include <jerror.h>
-#include <setjmp.h>
-#ifdef HAVE_STLIB_H_1
-#define HAVE_STDLIB_H 1
-#endif
+#include <setjmp.h>
static int jpeg_image_p P_ ((Lisp_Object object));
static int jpeg_load P_ ((struct frame *f, struct image *img));
return 0;
}
- width = img->width = gif->SWidth;
- height = img->height = gif->SHeight;
+ width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
+ height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
staticpro (&Qcancel_timer);
Qwait_for_wm = intern ("wait-for-wm");
staticpro (&Qwait_for_wm);
+ Qfullscreen = intern ("fullscreen");
+ staticpro (&Qfullscreen);
+ Qfullwidth = intern ("fullwidth");
+ staticpro (&Qfullwidth);
+ Qfullheight = intern ("fullheight");
+ staticpro (&Qfullheight);
+ Qfullboth = intern ("fullboth");
+ staticpro (&Qfullboth);
/* This is the end of symbol initialization. */
/* Text property `display' should be nonsticky by default. */
find_ccl_program_func = x_find_ccl_program;
query_font_func = x_query_font;
set_frame_fontset_func = x_set_font;
+ get_font_repertory_func = x_get_font_repertory;
check_window_system_func = check_x;
/* Images. */