X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d67b4f80dbe514d6e351e7d89c78921c85e7dbe7..31887d45e8c5cf28b1e85f76a0aba40186f7f1a5:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index 8fd46fa1a0..635264ea86 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1,6 +1,6 @@ /* Functions for the X window system. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include #ifdef HAVE_UNISTD_H #include @@ -63,6 +64,8 @@ along with GNU Emacs. If not, see . */ #include #endif +#include "xsettings.h" + #ifdef USE_GTK #include "gtkutil.h" #endif @@ -194,7 +197,7 @@ Lisp_Object Qnone; Lisp_Object Qsuppress_icon; Lisp_Object Qundefined_color; Lisp_Object Qcompound_text, Qcancel_timer; -static Lisp_Object Qfont_param; +Lisp_Object Qfont_param; /* In dispnew.c */ @@ -202,6 +205,8 @@ extern Lisp_Object Vwindow_system_version; /* The below are defined in frame.c. */ +extern Lisp_Object Qtooltip; + #if GLYPH_DEBUG int image_cache_refcount, dpyinfo_refcount; #endif @@ -399,10 +404,11 @@ x_any_window_to_frame (dpyinfo, wdesc) /* Likewise, but consider only the menu bar widget. */ struct frame * -x_menubar_window_to_frame (dpyinfo, wdesc) +x_menubar_window_to_frame (dpyinfo, event) struct x_display_info *dpyinfo; - int wdesc; + XEvent *event; { + Window wdesc = event->xany.window; Lisp_Object tail, frame; struct frame *f; struct x_output *x; @@ -418,21 +424,11 @@ x_menubar_window_to_frame (dpyinfo, wdesc) if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) continue; x = f->output_data.x; - /* Match if the window is this frame's menubar. */ #ifdef USE_GTK - if (x->menubar_widget) - { - GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); - - /* This gives false positives, but the rectangle check in xterm.c - where this is called takes care of that. */ - if (gwdesc != 0 - && (gwdesc == x->menubar_widget - || gtk_widget_is_ancestor (x->menubar_widget, gwdesc) - || gtk_widget_is_ancestor (gwdesc, x->menubar_widget))) - return f; - } + if (x->menubar_widget && xg_event_is_for_menubar (f, event)) + return f; #else + /* Match if the window is this frame's menubar. */ if (x->menubar_widget && lw_window_is_in_menubar (wdesc, x->menubar_widget)) return f; @@ -537,12 +533,20 @@ x_real_positions (f, xptr, yptr) int real_x = 0, real_y = 0; int had_errors = 0; Window win = f->output_data.x->parent_desc; + Atom actual_type; + unsigned long actual_size, bytes_remaining; + int i, rc, actual_format; + struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + long max_len = 400; + Display *dpy = FRAME_X_DISPLAY (f); + unsigned char *tmp_data = NULL; + Atom target_type = XA_CARDINAL; BLOCK_INPUT; - x_catch_errors (FRAME_X_DISPLAY (f)); + x_catch_errors (dpy); - if (win == FRAME_X_DISPLAY_INFO (f)->root_window) + if (win == dpyinfo->root_window) win = FRAME_OUTER_WINDOW (f); /* This loop traverses up the containment tree until we hit the root @@ -627,6 +631,34 @@ x_real_positions (f, xptr, yptr) had_errors = x_had_errors_p (FRAME_X_DISPLAY (f)); } + + if (dpyinfo->root_window == f->output_data.x->parent_desc) + { + /* Try _NET_FRAME_EXTENTS if our parent is the root window. */ + rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_frame_extents, + 0, max_len, False, target_type, + &actual_type, &actual_format, &actual_size, + &bytes_remaining, &tmp_data); + + if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy) + && actual_size == 4 && actual_format == 32) + { + int ign; + Window rootw; + + XGetGeometry (FRAME_X_DISPLAY (f), win, + &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign); + long *fe = (long *)tmp_data; + + outer_x = -fe[0]; + outer_y = -fe[2]; + real_x -= fe[0]; + real_y -= fe[2]; + } + } + + if (tmp_data) XFree (tmp_data); + x_uncatch_errors (); UNBLOCK_INPUT; @@ -1029,7 +1061,7 @@ x_set_mouse_color (f, arg, oldval) if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0) FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f); - + if (cursor != x->text_cursor && x->text_cursor != 0) XFreeCursor (dpy, x->text_cursor); @@ -1314,7 +1346,43 @@ x_set_menu_bar_lines (f, value, oldval) #else /* not USE_X_TOOLKIT && not USE_GTK */ FRAME_MENU_BAR_LINES (f) = nlines; change_window_heights (f->root_window, nlines - olines); -#endif /* not USE_X_TOOLKIT */ + + /* If the menu bar height gets changed, the internal border below + the top margin has to be cleared. Also, if the menu bar gets + larger, the area for the added lines has to be cleared except for + the first menu bar line that is to be drawn later. */ + if (nlines != olines) + { + int height = FRAME_INTERNAL_BORDER_WIDTH (f); + int width = FRAME_PIXEL_WIDTH (f); + int y; + + /* height can be zero here. */ + if (height > 0 && width > 0) + { + y = FRAME_TOP_MARGIN_HEIGHT (f); + + BLOCK_INPUT; + x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + 0, y, width, height, False); + UNBLOCK_INPUT; + } + + if (nlines > 1 && nlines > olines) + { + y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f); + height = nlines * FRAME_LINE_HEIGHT (f) - y; + + BLOCK_INPUT; + x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), + 0, y, width, height, False); + UNBLOCK_INPUT; + } + + if (nlines == 0 && WINDOWP (f->menu_bar_window)) + clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix); + } +#endif /* not USE_X_TOOLKIT && not USE_GTK */ adjust_glyphs (f); } @@ -1400,7 +1468,7 @@ x_set_tool_bar_lines (f, value, oldval) { int height = FRAME_INTERNAL_BORDER_WIDTH (f); int width = FRAME_PIXEL_WIDTH (f); - int y = nlines * FRAME_LINE_HEIGHT (f); + int y = (FRAME_MENU_BAR_LINES (f) + nlines) * FRAME_LINE_HEIGHT (f); /* height can be zero here. */ if (height > 0 && width > 0) @@ -2885,14 +2953,6 @@ x_icon (f, parms) background, border and mouse colors; also create the mouse cursor and the gray border tile. */ -static char cursor_bits[] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - static void x_make_gc (f) struct frame *f; @@ -3033,10 +3093,22 @@ x_default_font_parameter (f, parms) { struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL, - RES_TYPE_STRING); + RES_TYPE_STRING); Lisp_Object font; + int got_from_gconf = 0; if (EQ (font_param, Qunbound)) font_param = Qnil; + + if (NILP (font_param)) + { + /* System font takes precedendce over X resources. We must suggest this + regardless of font-use-system-font because .emacs may not have been + read yet. */ + const char *system_font = xsettings_get_system_font (); + if (system_font) font_param = make_string (system_font, + strlen (system_font)); + } + font = !NILP (font_param) ? font_param : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING); @@ -3046,7 +3118,7 @@ x_default_font_parameter (f, parms) = { #ifdef HAVE_XFT /* This will find the normal Xft font. */ - "monospace-12", + "monospace-10", #endif "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1", "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1", @@ -3076,7 +3148,11 @@ x_default_font_parameter (f, parms) we've applied the `default' face settings. */ x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil)); } - x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); + + x_default_parameter (f, parms, Qfont, font, + got_from_gconf ? NULL : "font", + got_from_gconf ? NULL : "Font", + RES_TYPE_STRING); } @@ -3300,7 +3376,9 @@ This function is an internal primitive--use `make-frame' instead. */) #ifdef USE_LUCID /* Prevent lwlib/xlwmenu.c from crashing because of a bug whereby it fails to get any font. */ + BLOCK_INPUT; xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed"); + UNBLOCK_INPUT; #endif /* Frame contents get displaced if an embedded X window has a border. */ @@ -3369,7 +3447,7 @@ This function is an internal primitive--use `make-frame' instead. */) init_frame_faces (f); x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1), - "menuBar", "MenuBar", RES_TYPE_NUMBER); + "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER); x_default_parameter (f, parms, Qtool_bar_lines, make_number (1), "toolBar", "ToolBar", RES_TYPE_NUMBER); x_default_parameter (f, parms, Qbuffer_predicate, Qnil, @@ -4814,6 +4892,7 @@ x_create_tip_frame (dpyinfo, parms, text) { XSetWindowAttributes attrs; unsigned long mask; + Atom type = FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip; BLOCK_INPUT; mask = CWBackPixel | CWOverrideRedirect | CWEventMask; @@ -4838,6 +4917,10 @@ x_create_tip_frame (dpyinfo, parms, text) f->border_width, CopyFromParent, InputOutput, CopyFromParent, mask, &attrs); + XChangeProperty (FRAME_X_DISPLAY (f), tip_window, + FRAME_X_DISPLAY_INFO (f)->Xatom_net_window_type, + XA_ATOM, 32, PropModeReplace, + (unsigned char *)&type, 1); UNBLOCK_INPUT; } @@ -4860,9 +4943,8 @@ x_create_tip_frame (dpyinfo, parms, text) change_frame_size (f, height, width, 1, 0, 0); /* Add `tooltip' frame parameter's default value. */ - if (NILP (Fframe_parameter (frame, intern ("tooltip")))) - Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt), - Qnil)); + if (NILP (Fframe_parameter (frame, Qtooltip))) + Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil)); /* FIXME - can this be done in a similar way to normal frames? http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */ @@ -5577,10 +5659,10 @@ If FRAME is omitted or nil, it defaults to the selected frame. */) { FRAME_PTR f = check_x_frame (frame); char *name; - Lisp_Object default_font, font = Qnil; + Lisp_Object font; Lisp_Object font_param; char *default_name = NULL; - struct gcpro gcpro1; + struct gcpro gcpro1, gcpro2; int count = SPECPDL_INDEX (); check_x (); @@ -5594,22 +5676,37 @@ If FRAME is omitted or nil, it defaults to the selected frame. */) BLOCK_INPUT; - GCPRO1(font_param); - font_param = Fframe_parameter (frame, Qfont_param); + GCPRO2(font_param, font); + + XSETFONT (font, FRAME_FONT (f)); + font_param = Ffont_get (font, intern (":name")); + if (STRINGP (font_param)) + default_name = xstrdup (SDATA (font_param)); + else + { + font_param = Fframe_parameter (frame, Qfont_param); + if (STRINGP (font_param)) + default_name = xstrdup (SDATA (font_param)); + } + + if (default_name == NULL && x_last_font_name != NULL) + default_name = xstrdup (x_last_font_name); - if (x_last_font_name != NULL) - default_name = x_last_font_name; - else if (STRINGP (font_param)) - default_name = SDATA (font_param); - else if (FONTP (default_font)) + /* Convert fontconfig names to Gtk names, i.e. remove - before number */ + if (default_name) { - XSETFONT (default_font, FRAME_FONT (f)); - default_name = alloca (256); - if (font_unparse_gtkname (default_font, f, default_name, 256) < 0) - default_name = NULL; + char *p = strrchr (default_name, '-'); + if (p) + { + char *ep = p+1; + while (isdigit (*ep)) + ++ep; + if (*ep == '\0') *p = ' '; + } } name = xg_get_font_name (f, default_name); + xfree (default_name); if (name) { @@ -5857,8 +5954,8 @@ or when you set the mouse color. */); Vx_cursor_fore_pixel = Qnil; DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size, - doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS). -Text larger than this is clipped. */); + doc: /* Maximum size for tooltips. +Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); Vx_max_tooltip_size = Fcons (make_number (80), make_number (40)); DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, @@ -5932,7 +6029,7 @@ the tool bar buttons. */); char gtk_version[40]; g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); - Vgtk_version_string = build_string (gtk_version); + Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0); } #endif /* USE_GTK */