/* Functions for the X window system.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
+ 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
-#include <signal.h>
#include <stdio.h>
#include <math.h>
#include "keyboard.h"
#include "blockinput.h"
#include <epaths.h>
+#include "character.h"
#include "charset.h"
#include "coding.h"
#include "fontset.h"
int x_use_old_gtk_file_dialog;
+/* If non-zero, by default show hidden files in the GTK file chooser. */
+
+int x_gtk_show_hidden_files;
+
+/* If non-zero, don't collapse to tool bar when it is detached. */
+
+int x_gtk_whole_detached_tool_bar;
+
/* The background and shape of the mouse pointer, and shape when not
over text or in the modeline. */
int had_errors = 0;
Window win = f->output_data.x->parent_desc;
- int count;
-
BLOCK_INPUT;
- count = x_catch_errors (FRAME_X_DISPLAY (f));
+ x_catch_errors (FRAME_X_DISPLAY (f));
if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
win = FRAME_OUTER_WINDOW (f);
if (! had_errors)
{
- int ign;
+ unsigned int ign;
Window child, rootw;
/* Get the real coordinates for the WM window upper left corner */
had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
}
- x_uncatch_errors (FRAME_X_DISPLAY (f), count);
+ x_uncatch_errors ();
UNBLOCK_INPUT;
FRAME_PTR f;
Lisp_Object file;
{
- struct gcpro gcpro1;
int result = 0;
Lisp_Object found;
- GCPRO1 (found);
-
found = x_find_image_file (file);
if (! NILP (found))
{
GdkPixbuf *pixbuf;
GError *err = NULL;
- char *filename;
-
- filename = SDATA (found);
+ char *filename = (char *) SDATA (found);
BLOCK_INPUT;
pixbuf = gdk_pixbuf_new_from_file (filename, &err);
UNBLOCK_INPUT;
}
- UNGCPRO;
return result;
}
+
+int
+xg_set_icon_from_xpm_data (f, data)
+ FRAME_PTR f;
+ char **data;
+{
+ int result = 0;
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) data);
+
+ if (!pixbuf)
+ return 0;
+
+ gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
+ g_object_unref (pixbuf);
+ return 1;
+}
#endif /* USE_GTK */
Display *dpy = FRAME_X_DISPLAY (f);
Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
Cursor hourglass_cursor, horizontal_drag_cursor;
- int count;
unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
unsigned long mask_color = x->background_pixel;
BLOCK_INPUT;
/* It's not okay to crash if the user selects a screwy cursor. */
- count = x_catch_errors (dpy);
+ x_catch_errors (dpy);
if (!NILP (Vx_pointer_shape))
{
/* Check and report errors with the above calls. */
x_check_errors (dpy, "can't set cursor shape: %s");
- x_uncatch_errors (dpy, count);
+ x_uncatch_errors ();
{
XColor fore_color, back_color;
Otherwise store 0 in *STRINGP, which means that the `encoding' of
the result should be `COMPOUND_TEXT'. */
-unsigned char *
-x_encode_text (string, coding_system, selectionp, text_bytes, stringp)
+static unsigned char *
+x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep)
Lisp_Object string, coding_system;
int *text_bytes, *stringp;
int selectionp;
+ int *freep;
{
- unsigned char *str = SDATA (string);
- int chars = SCHARS (string);
- int bytes = SBYTES (string);
- int charset_info;
- int bufsize;
- unsigned char *buf;
+ int result = string_xstring_p (string);
struct coding_system coding;
- extern Lisp_Object Qcompound_text_with_extensions;
- 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 = SBYTES (string);
*stringp = 1;
- return str;
+ *freep = 0;
+ return SDATA (string);
}
setup_coding_system (coding_system, &coding);
- if (selectionp
- && SYMBOLP (coding.pre_write_conversion)
- && !NILP (Ffboundp (coding.pre_write_conversion)))
- {
- string = run_pre_post_conversion_on_str (string, &coding, 1);
- str = SDATA (string);
- chars = SCHARS (string);
- bytes = SBYTES (string);
- }
- 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 = SCHARS (string) * 2;
+ coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
+ encode_coding_object (&coding, string, 0, 0,
+ SCHARS (string), SBYTES (string), Qnil);
*text_bytes = coding.produced;
- *stringp = (charset_info == 1
- || (!EQ (coding_system, Qcompound_text)
- && !EQ (coding_system, Qcompound_text_with_extensions)));
- return buf;
+ *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
+ *freep = 1;
+ return coding.destination;
}
\f
in the future which can encode all Unicode characters.
But, for the moment, there's no way to know that the
current window manager supports it or not. */
- text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp);
+ text.value = x_encode_text (name, coding_system, 0, &bytes, &stringp,
+ &do_free_text_value);
text.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
text.format = 8;
text.nitems = bytes;
- /* Check early, because ENCODE_UTF_8 below may GC and name may be
- relocated. */
- do_free_text_value = text.value != SDATA (name);
-
if (NILP (f->icon_name))
{
icon = text;
{
/* See the above comment "Note: Encoding strategy". */
icon.value = x_encode_text (f->icon_name, coding_system, 0,
- &bytes, &stringp);
+ &bytes, &stringp, &do_free_icon_value);
icon.encoding = (stringp ? XA_STRING
: FRAME_X_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
icon.format = 8;
icon.nitems = bytes;
- do_free_icon_value = icon.value != SDATA (f->icon_name);
}
#ifdef USE_GTK
gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
- SDATA (ENCODE_UTF_8 (name)));
+ (char *) SDATA (ENCODE_UTF_8 (name)));
#else /* not USE_GTK */
XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
#endif /* not USE_GTK */
char xic_defaut_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
+/* Create an Xt fontset spec from the name of a base font.
+ If `motif' is True use the Motif syntax. */
char *
-xic_create_fontsetname (base_fontname)
+xic_create_fontsetname (base_fontname, motif)
char *base_fontname;
+ Bool motif;
{
+ const char *sep = motif ? ";" : ",";
+ char *fontsetname;
+
/* Make a fontset name from the base font name. */
if (xic_defaut_fontset == base_fontname)
- /* There is no base font name, use the default. */
- return base_fontname;
+ { /* There is no base font name, use the default. */
+ int len = strlen (base_fontname) + 2;
+ fontsetname = xmalloc (len);
+ bzero (fontsetname, len);
+ strcpy (fontsetname, base_fontname);
+ }
else
{
/* Make a fontset name from the base font name.
- the base font where the charset spec is replaced by -*-*.
- the same but with the family also replaced with -*-*-. */
char *p = base_fontname;
- char *fontsetname;
int i;
-
+
for (i = 0; *p; p++)
if (*p == '-') i++;
if (i != 14)
{ /* As the font name doesn't conform to XLFD, we can't
modify it to generalize it to allcs and allfamilies.
Use the specified font plus the default. */
- int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 2;
+ int len = strlen (base_fontname) + strlen (xic_defaut_fontset) + 3;
fontsetname = xmalloc (len);
bzero (fontsetname, len);
strcpy (fontsetname, base_fontname);
- strcat (fontsetname, ",");
+ strcat (fontsetname, sep);
strcat (fontsetname, xic_defaut_fontset);
}
else
{
int len;
- char *p1 = NULL;
+ char *p1 = NULL, *p2 = NULL;
char *font_allcs = NULL;
char *font_allfamilies = NULL;
+ char *font_all = NULL;
char *allcs = "*-*-*-*-*-*-*";
char *allfamilies = "-*-*-";
-
+ char *all = "*-*-*-*-";
+
for (i = 0, p = base_fontname; i < 8; p++)
{
if (*p == '-')
i++;
if (i == 3)
p1 = p + 1;
+ else if (i == 7)
+ p2 = p + 1;
}
}
/* Build the font spec that matches all charsets. */
font_allfamilies = (char *) alloca (len);
bzero (font_allfamilies, len);
strcpy (font_allfamilies, allfamilies);
- bcopy (p1, font_allfamilies + (strlen (allfamilies)), p - p1);
+ bcopy (p1, font_allfamilies + strlen (allfamilies), p - p1);
strcat (font_allfamilies, allcs);
+ /* Build the font spec that matches all. */
+ len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
+ font_all = (char *) alloca (len);
+ bzero (font_all, len);
+ strcpy (font_all, allfamilies);
+ strcat (font_all, all);
+ bcopy (p2, font_all + strlen (all) + strlen (allfamilies), p - p2);
+ strcat (font_all, allcs);
+
/* Build the actual font set name. */
len = strlen (base_fontname) + strlen (font_allcs)
- + strlen (font_allfamilies) + 3;
+ + strlen (font_allfamilies) + strlen (font_all) + 5;
fontsetname = xmalloc (len);
bzero (fontsetname, len);
strcpy (fontsetname, base_fontname);
- strcat (fontsetname, ",");
+ strcat (fontsetname, sep);
strcat (fontsetname, font_allcs);
- strcat (fontsetname, ",");
+ strcat (fontsetname, sep);
strcat (fontsetname, font_allfamilies);
+ strcat (fontsetname, sep);
+ strcat (fontsetname, font_all);
}
- return fontsetname;
}
+ if (motif)
+ strcat (fontsetname, ":");
+ return fontsetname;
}
static XFontSet
if (!xfs)
{
- char *fontsetname = xic_create_fontsetname (base_fontname);
+ char *fontsetname = xic_create_fontsetname (base_fontname, False);
/* New fontset. */
xfs = XCreateFontSet (FRAME_X_DISPLAY (f),
&missing_count, &def_string);
if (missing_list)
XFreeStringList (missing_list);
- if (fontsetname != base_fontname)
- xfree (fontsetname);
+ xfree (fontsetname);
}
if (FRAME_XIC_BASE_FONTNAME (f))
if (! EQ (icon_x, Qunbound))
x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
+#if 0 /* x_get_arg removes the visibility parameter as a side effect,
+ but x_create_frame still needs it. */
/* Start up iconic or window? */
x_wm_set_window_state
(f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
Qicon)
? IconicState
: NormalState));
+#endif
x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
? f->icon_name
check_x ();
+ parms = Fcopy_alist (parms);
+
/* Use this general default value to start with
until we know if this frame has a specified name. */
Vx_resource_name = Vinvocation_name;
font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
- BLOCK_INPUT;
- /* First, try whatever font the caller has specified. */
- if (STRINGP (font))
+ /* If the caller has specified no font, try out fonts which we
+ hope have bold and italic variations. */
+ if (!STRINGP (font))
{
- tem = Fquery_fontset (font, Qnil);
- if (STRINGP (tem))
- font = x_new_fontset (f, SDATA (tem));
- else
- font = x_new_font (f, SDATA (font));
+ char *names[]
+ = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
+ "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
+ "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
+ /* This was formerly the first thing tried, but it finds
+ too many fonts and takes too long. */
+ "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
+ /* If those didn't work, look for something which will
+ at least work. */
+ "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
+ NULL };
+ int i;
+
+ BLOCK_INPUT;
+ for (i = 0; names[i]; i++)
+ {
+ Lisp_Object list;
+
+ list = x_list_fonts (f, build_string (names[i]), 0, 1);
+ if (CONSP (list))
+ {
+ font = XCAR (list);
+ break;
+ }
+ }
+ UNBLOCK_INPUT;
+ if (! STRINGP (font))
+ font = build_string ("fixed");
}
-
- /* 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");
- if (!STRINGP (font))
- font = x_new_font (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");
- 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");
- /* 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");
- UNBLOCK_INPUT;
- if (! STRINGP (font))
- font = build_string ("fixed");
-
x_default_parameter (f, parms, Qfont, font,
"font", "Font", RES_TYPE_STRING);
}
/* We need to do this after creating the X window, so that the
icon-creation functions can say whose icon they're describing. */
- x_default_parameter (f, parms, Qicon_type, Qnil,
+ x_default_parameter (f, parms, Qicon_type, Qt,
"bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
x_default_parameter (f, parms, Qauto_raise, Qnil,
FRAME_OUTER_WINDOW (f),
dpyinfo->Xatom_wm_client_leader,
XA_WINDOW, 32, PropModeReplace,
- (char *) &dpyinfo->client_leader_window, 1);
+ (unsigned char *) &dpyinfo->client_leader_window, 1);
UNBLOCK_INPUT;
}
+ /* Initialize `default-minibuffer-frame' in case this is the first
+ frame on this display device. */
+ if (FRAME_HAS_MINIBUF_P (f)
+ && (!FRAMEP (kb->Vdefault_minibuffer_frame)
+ || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
+ kb->Vdefault_minibuffer_frame = frame;
+
+ /* All remaining specified parameters, which have not been "used"
+ by x_get_arg and friends, now go in the misc. alist of the frame. */
+ for (tem = parms; !NILP (tem); tem = XCDR (tem))
+ if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+ f->param_alist = Fcons (XCAR (tem), f->param_alist);
+
UNGCPRO;
/* Make sure windows on this frame appear in calls to next-window
{
struct frame *f = check_x_frame (frame);
Display *dpy = FRAME_X_DISPLAY (f);
- int count;
BLOCK_INPUT;
- count = x_catch_errors (dpy);
+ x_catch_errors (dpy);
XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
RevertToParent, CurrentTime);
- x_uncatch_errors (dpy, count);
+ x_uncatch_errors ();
UNBLOCK_INPUT;
return Qnil;
EMACS_TIME delay;
int secs, usecs = 0;
+ /* Don't bother for ttys. */
+ if (NILP (Vwindow_system))
+ return;
+
cancel_hourglass ();
if (INTEGERP (Vhourglass_delay)
check_x ();
- /* Use this general default value to start with until we know if
- this frame has a specified name. */
- Vx_resource_name = Vinvocation_name;
+ parms = Fcopy_alist (parms);
#ifdef MULTI_KBOARD
kb = dpyinfo->kboard;
&& !EQ (name, Qunbound)
&& !NILP (name))
error ("Invalid frame name--not a string or nil");
- Vx_resource_name = name;
frame = Qnil;
GCPRO3 (parms, name, frame);
{
tem = Fquery_fontset (font, Qnil);
if (STRINGP (tem))
- font = x_new_fontset (f, SDATA (tem));
+ font = x_new_fontset (f, tem);
else
font = x_new_font (f, SDATA (font));
}
if (INTEGERP (top))
*root_y = XINT (top);
- else if (*root_y + XINT (dy) - height < 0)
- *root_y -= XINT (dy);
- else
- {
- *root_y -= height;
+ else if (*root_y + XINT (dy) <= 0)
+ *root_y = 0; /* Can happen for negative dy */
+ else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height)
+ /* It fits below the pointer */
*root_y += XINT (dy);
- }
+ else if (height + XINT (dy) <= *root_y)
+ /* It fits above the pointer. */
+ *root_y -= height + XINT (dy);
+ else
+ /* Put it on the top. */
+ *root_y = 0;
if (INTEGERP (left))
*root_x = XINT (left);
+ else if (*root_x + XINT (dx) <= 0)
+ *root_x = 0; /* Can happen for negative dx */
else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width)
/* It fits to the right of the pointer. */
*root_x += XINT (dx);
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
- try_window (FRAME_ROOT_WINDOW (f), pos);
+ try_window (FRAME_ROOT_WINDOW (f), pos, 0);
/* Compute width and height of the tooltip. */
width = height = 0;
File selection dialog
***********************************************************************/
-#ifdef USE_MOTIF
+DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
+ Sx_uses_old_gtk_dialog,
+ 0, 0, 0,
+ doc: /* Return t if the old Gtk+ file selection dialog is used. */)
+ ()
+{
+#ifdef USE_GTK
+ extern int use_dialog_box;
+ extern int use_file_dialog;
+
+ if (use_dialog_box
+ && use_file_dialog
+ && have_menus_p ()
+ && xg_uses_old_file_dialog ())
+ return Qt;
+#endif
+ return Qnil;
+}
+
+#ifdef USE_MOTIF
/* Callback for "OK" and "Cancel" on file selection dialog. */
static void
int result;
struct frame *f = SELECTED_FRAME ();
Lisp_Object file = Qnil;
+ Lisp_Object decoded_file;
Widget dialog, text, help;
Arg al[10];
int ac = 0;
if (NILP (file))
Fsignal (Qquit, Qnil);
- return unbind_to (count, file);
+ decoded_file = DECODE_FILE (file);
+
+ return unbind_to (count, decoded_file);
}
#endif /* USE_MOTIF */
FRAME_PTR f = SELECTED_FRAME ();
char *fn;
Lisp_Object file = Qnil;
+ Lisp_Object decoded_file;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
char *cdef_file;
if (NILP (file))
Fsignal (Qquit, Qnil);
- return unbind_to (count, file);
+ decoded_file = DECODE_FILE (file);
+
+ return unbind_to (count, decoded_file);
}
#endif /* USE_GTK */
doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
FRAME nil means use the selected frame.
Value is t if we know that both keys are present, and are mapped to the
-usual X keysyms. */)
+usual X keysyms. Value is `lambda' if we cannot determine if both keys are
+present and mapped to the usual X keysyms. */)
(frame)
Lisp_Object frame;
{
if (!XkbLibraryVersion (&major, &minor))
{
UNBLOCK_INPUT;
- return Qnil;
+ return Qlambda;
}
/* Check that the server supports XKB. */
if (!XkbQueryExtension (dpy, &op, &event, &error, &major, &minor))
{
UNBLOCK_INPUT;
- return Qnil;
+ return Qlambda;
}
/* In this code we check that the keyboard has physical keys with names
UNBLOCK_INPUT;
return have_keys;
#else /* not HAVE_XKBGETKEYBOARD */
- return Qnil;
+ return Qlambda;
#endif /* not HAVE_XKBGETKEYBOARD */
}
variable `use-file-dialog'. */);
x_use_old_gtk_file_dialog = 0;
+ DEFVAR_BOOL ("x-gtk-show-hidden-files", &x_gtk_show_hidden_files,
+ doc: /* *If non-nil, the GTK file chooser will by default show hidden files.
+Note that this is just the default, there is a toggle button on the file
+chooser to show or not show hidden files on a case by case basis. */);
+ x_gtk_show_hidden_files = 0;
+
+ DEFVAR_BOOL ("x-gtk-whole-detached-tool-bar", &x_gtk_whole_detached_tool_bar,
+ doc: /* *If non-nil, a detached tool bar is shown in full.
+The default is to just show an arrow and pressing on that arrow shows
+the tool bar buttons. */);
+ x_gtk_whole_detached_tool_bar = 0;
+
+ Fprovide (intern ("x"), Qnil);
+
#ifdef USE_X_TOOLKIT
Fprovide (intern ("x-toolkit"), Qnil);
#ifdef USE_MOTIF
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;
hourglass_atimer = NULL;
last_show_tip_args = Qnil;
staticpro (&last_show_tip_args);
+ defsubr (&Sx_uses_old_gtk_dialog);
#if defined (USE_MOTIF) || defined (USE_GTK)
defsubr (&Sx_file_dialog);
#endif