X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/c8bcd18afb92587391000ccd826b3bcbe8b2d7a9..7d6b4d3cadac4b8343309388dd5e9e225d6f9f4c:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index 4be3d1df66..27d0b025a2 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -21,6 +21,8 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include +#include #ifdef HAVE_UNISTD_H #include @@ -62,6 +64,8 @@ along with GNU Emacs. If not, see . */ #include #endif +#include "xsettings.h" + #ifdef USE_GTK #include "gtkutil.h" #endif @@ -97,13 +101,10 @@ along with GNU Emacs. If not, see . */ #include #endif -/* Do the EDITRES protocol if running X11R5 - Exception: HP-UX (at least version A.09.05) has X11R5 without EditRes */ - -#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES) +#if !defined(NO_EDITRES) #define HACK_EDITRES extern void _XEditResCheckMessages (); -#endif /* R5 + Athena */ +#endif /* not defined NO_EDITRES */ /* Unique id counter for widgets created by the Lucid Widget Library. */ @@ -196,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 */ @@ -208,6 +209,9 @@ extern Lisp_Object Vwindow_system_version; int image_cache_refcount, dpyinfo_refcount; #endif +#if defined (USE_GTK) && defined (HAVE_FREETYPE) +char *x_last_font_name; +#endif /* Error if we are not connected to X. */ @@ -247,7 +251,7 @@ check_x_frame (frame) } /* Let the user specify an X display with a Lisp object. - OBJECT may be nil, a frame or a terminal id. + OBJECT may be nil, a frame or a terminal object. nil stands for the selected frame--or, if that is not an X frame, the first X display on the list. */ @@ -268,7 +272,7 @@ check_x_display_info (object) else error ("X windows are not in use or not initialized"); } - else if (INTEGERP (object)) + else if (TERMINALP (object)) { struct terminal *t = get_terminal (object, 1); @@ -374,10 +378,7 @@ x_any_window_to_frame (dpyinfo, wdesc) #ifdef USE_GTK GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); if (gwdesc != 0 - && (gwdesc == x->widget - || gwdesc == x->edit_widget - || gwdesc == x->vbox_widget - || gwdesc == x->menubar_widget)) + && gtk_widget_get_toplevel (gwdesc) == x->widget) found = f; #else if (wdesc == XtWindow (x->widget) @@ -398,54 +399,6 @@ x_any_window_to_frame (dpyinfo, wdesc) return found; } -/* Likewise, but exclude the menu bar widget. */ - -struct frame * -x_non_menubar_window_to_frame (dpyinfo, wdesc) - struct x_display_info *dpyinfo; - int wdesc; -{ - Lisp_Object tail, frame; - struct frame *f; - struct x_output *x; - - if (wdesc == None) return 0; - - for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) - { - frame = XCAR (tail); - if (!FRAMEP (frame)) - continue; - f = XFRAME (frame); - if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) - continue; - x = f->output_data.x; - /* This frame matches if the window is any of its widgets. */ - if (x->hourglass_window == wdesc) - return f; - else if (x->widget) - { -#ifdef USE_GTK - GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); - if (gwdesc != 0 - && (gwdesc == x->widget - || gwdesc == x->edit_widget - || gwdesc == x->vbox_widget)) - return f; -#else - if (wdesc == XtWindow (x->widget) - || wdesc == XtWindow (x->column_widget) - || wdesc == XtWindow (x->edit_widget)) - return f; -#endif - } - else if (FRAME_X_WINDOW (f) == wdesc) - /* A tooltip frame. */ - return f; - } - return 0; -} - /* Likewise, but consider only the menu bar widget. */ struct frame * @@ -473,15 +426,14 @@ x_menubar_window_to_frame (dpyinfo, wdesc) if (x->menubar_widget) { GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc); - int found = 0; - BLOCK_INPUT; + /* 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_get_parent (gwdesc) == x->menubar_widget)) - found = 1; - UNBLOCK_INPUT; - if (found) return f; + || gtk_widget_is_ancestor (x->menubar_widget, gwdesc) + || gtk_widget_is_ancestor (gwdesc, x->menubar_widget))) + return f; } #else if (x->menubar_widget @@ -941,6 +893,35 @@ x_set_background_color (f, arg, oldval) } } +static Cursor +make_invisible_cursor (f) + struct frame *f; +{ + Display *dpy = FRAME_X_DISPLAY (f); + static char const no_data[] = { 0 }; + Pixmap pix; + XColor col; + Cursor c; + + x_catch_errors (dpy); + pix = XCreateBitmapFromData (dpy, FRAME_X_DISPLAY_INFO (f)->root_window, + no_data, 1, 1); + if (! x_had_errors_p (dpy) && pix != None) + { + col.pixel = 0; + col.red = col.green = col.blue = 0; + col.flags = DoRed | DoGreen | DoBlue; + c = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0); + if (x_had_errors_p (dpy) || c == None) + c = 0; + XFreePixmap (dpy, pix); + } + + x_uncatch_errors (); + + return c; +} + void x_set_mouse_color (f, arg, oldval) struct frame *f; @@ -1046,8 +1027,12 @@ x_set_mouse_color (f, arg, oldval) } if (FRAME_X_WINDOW (f) != 0) - XDefineCursor (dpy, FRAME_X_WINDOW (f), cursor); + XDefineCursor (dpy, FRAME_X_WINDOW (f), + f->output_data.x->current_cursor = cursor); + 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); @@ -2671,7 +2656,8 @@ x_window (f, window_prompting, minibuffer_only) } XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->output_data.x->text_cursor); + f->output_data.x->current_cursor + = f->output_data.x->text_cursor); UNBLOCK_INPUT; @@ -2816,7 +2802,8 @@ x_window (f) } XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - f->output_data.x->text_cursor); + f->output_data.x->current_cursor + = f->output_data.x->text_cursor); UNBLOCK_INPUT; @@ -2901,14 +2888,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; @@ -2967,7 +2946,7 @@ x_make_gc (f) } -/* Free what was was allocated in x_make_gc. */ +/* Free what was allocated in x_make_gc. */ void x_free_gcs (f) @@ -3049,10 +3028,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); @@ -3092,7 +3083,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); } @@ -3292,7 +3287,6 @@ This function is an internal primitive--use `make-frame' instead. */) f->resx = dpyinfo->resx; f->resy = dpyinfo->resy; - register_font_driver (&xfont_driver, f); #ifdef HAVE_FREETYPE #ifdef HAVE_XFT register_font_driver (&xftfont_driver, f); @@ -3300,6 +3294,7 @@ This function is an internal primitive--use `make-frame' instead. */) register_font_driver (&ftxfont_driver, f); #endif /* not HAVE_XFT */ #endif /* HAVE_FREETYPE */ + register_font_driver (&xfont_driver, f); x_default_parameter (f, parms, Qfont_backend, Qnil, "fontBackend", "FontBackend", RES_TYPE_STRING); @@ -3307,6 +3302,11 @@ This function is an internal primitive--use `make-frame' instead. */) /* Extract the window parameters from the supplied values that are needed to determine window geometry. */ x_default_font_parameter (f, parms); + if (!FRAME_FONT (f)) + { + delete_frame (frame, Qnoelisp); + error ("Invalid frame font"); + } #ifdef USE_LUCID /* Prevent lwlib/xlwmenu.c from crashing because of a bug @@ -3634,7 +3634,7 @@ DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, doc: /* Return t if the X display supports shades of gray. Note that color displays do support shades of gray. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3663,7 +3663,7 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0, doc: /* Return the width in pixels of the X display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3677,7 +3677,7 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0, doc: /* Return the height in pixels of the X display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3691,7 +3691,7 @@ DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 0, 1, 0, doc: /* Return the number of bitplanes of the X display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3705,7 +3705,7 @@ DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 0, 1, 0, doc: /* Return the number of color cells of the X display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3730,7 +3730,7 @@ DEFUN ("x-server-max-request-size", Fx_server_max_request_size, 0, 1, 0, doc: /* Return the maximum request size of the X server of display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3745,7 +3745,7 @@ DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0, \(Labelling 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. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3764,7 +3764,7 @@ version numbers of the X Protocol in use, and the distributor-specific release number. See also the function `x-server-vendor'. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3780,7 +3780,7 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0, doc: /* Return the number of screens on the X server of display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3793,7 +3793,7 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0, doc: /* Return the height in millimeters of the X display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3806,7 +3806,7 @@ If omitted or nil, that stands for the selected frame's display. */) DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, doc: /* Return the width in millimeters of the X display TERMINAL. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3821,7 +3821,7 @@ DEFUN ("x-display-backing-store", Fx_display_backing_store, doc: /* Return an indication of whether X display TERMINAL does backing store. The value may be `always', `when-mapped', or `not-useful'. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3858,7 +3858,7 @@ The value is one of the symbols `static-gray', `gray-scale', `static-color', `pseudo-color', `true-color', or `direct-color'. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should a terminal id, a frame or a display name (a string). +TERMINAL should a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -3898,7 +3898,7 @@ DEFUN ("x-display-save-under", Fx_display_save_under, Sx_display_save_under, 0, 1, 0, doc: /* Return t if the X display TERMINAL supports the save-under feature. The optional argument TERMINAL specifies which display to ask about. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If omitted or nil, that stands for the selected frame's display. */) (terminal) Lisp_Object terminal; @@ -4169,7 +4169,7 @@ An insecure way to solve the problem may be to use `xhost'.\n", DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1, 1, 0, doc: /* Close the connection to TERMINAL's X server. -For TERMINAL, specify a terminal id, a frame or a display name (a +For TERMINAL, specify a terminal object, a frame or a display name (a string). If TERMINAL is nil, that stands for the selected frame's terminal. */) (terminal) @@ -4205,7 +4205,7 @@ Turning on synchronization prohibits the Xlib routines from buffering requests and seriously degrades performance, but makes debugging much easier. The optional second argument TERMINAL specifies which display to act on. -TERMINAL should be a terminal id, a frame or a display name (a string). +TERMINAL should be a terminal object, a frame or a display name (a string). If TERMINAL is omitted or nil, that stands for the selected frame's display. */) (on, terminal) Lisp_Object terminal, on; @@ -5588,7 +5588,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, gcpro2; int count = SPECPDL_INDEX (); check_x (); @@ -5602,21 +5605,43 @@ If FRAME is omitted or nil, it defaults to the selected frame. */) BLOCK_INPUT; - XSETFONT (default_font, FRAME_FONT (f)); - if (FONTP (default_font)) + 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 { - char *default_name = alloca (256); - if (font_unparse_gtkname (default_font, f, default_name, 256) < 0) - default_name = NULL; - name = xg_get_font_name (f, default_name); + font_param = Fframe_parameter (frame, Qfont_param); + if (STRINGP (font_param)) + default_name = xstrdup (SDATA (font_param)); } - else - name = xg_get_font_name (f, NULL); + + if (default_name == NULL && x_last_font_name != NULL) + default_name = xstrdup (x_last_font_name); + + /* Convert fontconfig names to Gtk names, i.e. remove - before number */ + if (default_name) + { + 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) { font = build_string (name); - xfree (name); + g_free (x_last_font_name); + x_last_font_name = name; } UNBLOCK_INPUT; @@ -5774,7 +5799,8 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_wait_for_wm, x_set_fullscreen, x_set_font_backend, - x_set_alpha + x_set_alpha, + x_set_sticky, }; void @@ -5786,17 +5812,17 @@ syms_of_xfns () /* The section below is built by the lisp expression at the top of the file, just above where these variables are declared. */ /*&&& init symbols here &&&*/ - Qnone = intern ("none"); + Qnone = intern_c_string ("none"); staticpro (&Qnone); - Qsuppress_icon = intern ("suppress-icon"); + Qsuppress_icon = intern_c_string ("suppress-icon"); staticpro (&Qsuppress_icon); - Qundefined_color = intern ("undefined-color"); + Qundefined_color = intern_c_string ("undefined-color"); staticpro (&Qundefined_color); - Qcompound_text = intern ("compound-text"); + Qcompound_text = intern_c_string ("compound-text"); staticpro (&Qcompound_text); - Qcancel_timer = intern ("cancel-timer"); + Qcancel_timer = intern_c_string ("cancel-timer"); staticpro (&Qcancel_timer); - Qfont_param = intern ("font-parameter"); + Qfont_param = intern_c_string ("font-parameter"); staticpro (&Qfont_param); /* This is the end of symbol initialization. */ @@ -5806,9 +5832,9 @@ syms_of_xfns () Fput (Qundefined_color, Qerror_conditions, - Fcons (Qundefined_color, Fcons (Qerror, Qnil))); + pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); Fput (Qundefined_color, Qerror_message, - build_string ("Undefined color")); + make_pure_c_string ("Undefined color")); DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, doc: /* The shape of the pointer when over text. @@ -5905,12 +5931,12 @@ 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); + Fprovide (intern_c_string ("x"), Qnil); #ifdef USE_X_TOOLKIT - Fprovide (intern ("x-toolkit"), Qnil); + Fprovide (intern_c_string ("x-toolkit"), Qnil); #ifdef USE_MOTIF - Fprovide (intern ("motif"), Qnil); + Fprovide (intern_c_string ("motif"), Qnil); DEFVAR_LISP ("motif-version-string", &Vmotif_version_string, doc: /* Version info for LessTif/Motif. */); @@ -5923,8 +5949,8 @@ the tool bar buttons. */); is not an X toolkit in that sense (USE_X_TOOLKIT is not defined). But for a user it is a toolkit for X, and indeed, configure accepts --with-x-toolkit=gtk. */ - Fprovide (intern ("x-toolkit"), Qnil); - Fprovide (intern ("gtk"), Qnil); + Fprovide (intern_c_string ("x-toolkit"), Qnil); + Fprovide (intern_c_string ("gtk"), Qnil); DEFVAR_LISP ("gtk-version-string", &Vgtk_version_string, doc: /* Version info for GTK+. */); @@ -5932,7 +5958,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 */ @@ -5987,6 +6013,7 @@ the tool bar buttons. */); #if defined (USE_GTK) && defined (HAVE_FREETYPE) defsubr (&Sx_select_font); + x_last_font_name = NULL; #endif }