home *** CD-ROM | disk | FTP | other *** search
- /* Functions for the X window system.
- Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
-
- This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Synched up with: Not synched with FSF. */
-
- /* Substantially rewritten for XEmacs. */
-
- #include <config.h>
- #include "lisp.h"
-
- #include "device-x.h"
- #include "frame-x.h"
- #include "xintrinsicp.h" /* CoreP.h needs this */
- #include <X11/CoreP.h> /* Numerous places access the fields of
- a core widget directly. We could
- use XtVaGetValues(), but ... */
- #include <X11/Shell.h>
- #include <X11/ShellP.h>
- #include "xmu.h"
- #include "EmacsManager.h"
- #include "EmacsFrameP.h"
- #include "EmacsShell.h"
- #ifdef EXTERNAL_WIDGET
- #include "ExternalShell.h"
- #endif
- #include "glyphs-x.h"
- #include "objects-x.h"
-
- #include "buffer.h"
- #include "events.h"
- #include "extents.h"
- #include "faces.h"
- #include "scrollbar-x.h"
- #include "window.h"
-
- Lisp_Object Vx_gc_pointer_shape;
- Lisp_Object Vx_scrollbar_pointer_shape;
-
- /* Default parameters to use when creating frames. */
- Lisp_Object Vdefault_x_frame_alist;
-
- static Lisp_Object Vpre_gc_cursor;
-
- Lisp_Object Qwindow_id;
- Lisp_Object Qpopup;
- Lisp_Object Qx_resource_name;
- Lisp_Object Qpointer;
- Lisp_Object Qscrollbar_pointer;
-
-
- /************************************************************************/
- /* helper functions */
- /************************************************************************/
-
- /* Return the Emacs frame-object corresponding to an X window */
- struct frame *
- x_window_to_frame (struct device *d, Window wdesc)
- {
- Lisp_Object tail, frame;
- struct frame *f;
-
- /* This function was previously written to accept only a window argument
- (and to loop over all devices looking for a matching window), but
- that is incorrect because window ID's are not unique across displays. */
-
- for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail))
- {
- frame = XCAR (tail);
- if (!FRAMEP (frame))
- continue;
- f = XFRAME (frame);
- if (FRAME_IS_X (f) && XtWindow (FRAME_X_TEXT_WIDGET (f)) == wdesc)
- return f;
- }
- return 0;
- }
-
- /* Like x_window_to_frame but also compares the window with the widget's
- windows */
- struct frame *
- x_any_window_to_frame (struct device *d, Window wdesc)
- {
- Lisp_Object tail, frame;
- struct frame *f;
-
- /* This function was previously written to accept only a window argument
- (and to loop over all devices looking for a matching window), but
- that is incorrect because window ID's are not unique across displays. */
-
- for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail))
- {
- int i;
-
- frame = XCAR (tail);
- if (!FRAMEP (frame))
- continue;
- f = XFRAME (frame);
- if (!FRAME_IS_X (f))
- continue;
- /* This frame matches if the window is any of its widgets. */
- if (wdesc == XtWindow (FRAME_X_SHELL_WIDGET (f)) ||
- wdesc == XtWindow (FRAME_X_CONTAINER_WIDGET (f)) ||
- wdesc == XtWindow (FRAME_X_TEXT_WIDGET (f)))
- return f;
-
- /* Match if the window is one of the widgets at the top of the frame
- (menubar, Energize psheets). */
-
- /* Note: Jamie once said
-
- "Do *not* match if the window is this frame's psheet."
-
- But this is wrong and will screw up some functions that expect
- x_any_window_to_frame() to work as advertised. I think the reason
- for this statement is that, in the old (broken) event loop, where
- not all events went through XtDispatchEvent(), psheet events
- would incorrectly get sucked away by Emacs if this function matched
- on psheet widgets. */
-
- for (i = 0; i < FRAME_X_NUM_TOP_WIDGETS (f); i++)
- {
- Widget wid = FRAME_X_TOP_WIDGETS (f)[i];
- if (wid && XtIsManaged (wid) && wdesc == XtWindow (wid))
- return f;
- }
-
- /* Match if the window is one of this frame's scrollbars. */
- if (x_window_is_scrollbar (f, wdesc))
- return f;
- }
-
- return 0;
- }
-
- struct frame *
- get_x_frame (Lisp_Object frame)
- {
- if (NILP (frame))
- XSETFRAME (frame, selected_frame ());
- CHECK_LIVE_FRAME (frame, 0);
- /* this will also catch dead frames, but putting in the above check
- results in a more useful error */
- CHECK_X_FRAME (frame, 0);
- return XFRAME (frame);
- }
-
-
- /************************************************************************/
- /* window-manager interactions */
- /************************************************************************/
-
- #if 0
- /* Not currently used. */
-
- void
- x_wm_mark_shell_size_user_specified (Widget wmshell)
- {
- if (! XtIsWMShell (wmshell)) abort ();
- EmacsShellSetSizeUserSpecified (wmshell);
- }
-
- void
- x_wm_mark_shell_position_user_specified (Widget wmshell)
- {
- if (! XtIsWMShell (wmshell)) abort ();
- EmacsShellSetPositionUserSpecified (wmshell);
- }
-
- #endif
-
- void
- x_wm_set_shell_iconic_p (Widget shell, int iconic_p)
- {
- if (! XtIsWMShell (shell)) abort ();
-
- /* Because of questionable logic in Shell.c, this sequence can't work:
-
- w = XtCreatePopupShell (...);
- XtVaSetValues (w, XtNiconic, True, 0);
- XtRealizeWidget (w);
-
- The iconic resource is only consulted at initialization time (when
- XtCreatePopupShell is called) instead of at realization time (just
- before the window gets created, which would be more sensible) or
- at management-time (just before the window gets mapped, which would
- be most sensible of all).
-
- The bug is that Shell's SetValues method doesn't do anything to
- w->wm.wm_hints.initial_state until after the widget has been realized.
- Calls to XtSetValues are ignored in the window between creation and
- realization. This is true of MIT X11R5 patch level 25, at least.
- (Apparently some other versions of Xt don't have this bug?)
- */
- XtVaSetValues (shell, XtNiconic, iconic_p, 0);
- EmacsShellSmashIconicHint (shell, iconic_p);
- }
-
- void
- x_wm_set_cell_size (Widget wmshell, int cw, int ch)
- {
- if (!XtIsWMShell (wmshell))
- abort ();
- if (cw <= 0 || ch <= 0)
- abort ();
-
- XtVaSetValues (wmshell,
- XtNwidthInc, cw,
- XtNheightInc, ch,
- 0);
- }
-
- void
- x_wm_set_variable_size (Widget wmshell, int width, int height)
- {
- if (!XtIsWMShell (wmshell))
- abort ();
- #ifdef DEBUG_GEOMETRY_MANAGEMENT
- /* See comment in EmacsShell.c */
- printf ("x_wm_set_variable_size: %d %d\n", width, height);
- fflush (stdout);
- #endif
- XtVaSetValues (wmshell,
- XtNwidthCells, width,
- XtNheightCells, height,
- 0);
- }
-
- /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS
- and WM_DELETE_WINDOW, then add them. (They may already be present
- because of the toolkit (Motif adds them, for example, but Xt doesn't).
- */
- static void
- x_wm_hack_wm_protocols (Widget widget)
- {
- Display *dpy = XtDisplay (widget);
- struct device *d = get_device_from_display (dpy);
- Window w = XtWindow (widget);
- int need_delete = 1;
- int need_focus = 1;
-
- if (!XtIsWMShell (widget))
- abort ();
-
- {
- Atom type, *atoms = 0;
- int format = 0;
- unsigned long nitems = 0;
- unsigned long bytes_after;
-
- if (Success == XGetWindowProperty (dpy, w, DEVICE_XATOM_WM_PROTOCOLS (d),
- 0, 100, False, XA_ATOM,
- &type, &format, &nitems, &bytes_after,
- (unsigned char **) &atoms)
- && format == 32 && type == XA_ATOM)
- while (nitems > 0)
- {
- nitems--;
- if (atoms [nitems] == DEVICE_XATOM_WM_DELETE_WINDOW (d))
- need_delete = 0;
- else if (atoms [nitems] == DEVICE_XATOM_WM_TAKE_FOCUS (d))
- need_focus = 0;
- }
- if (atoms) XFree ((char *) atoms);
- }
- {
- Atom props [10];
- int count = 0;
- if (need_delete) props[count++] = DEVICE_XATOM_WM_DELETE_WINDOW (d);
- if (need_focus) props[count++] = DEVICE_XATOM_WM_TAKE_FOCUS (d);
- if (count)
- XChangeProperty (dpy, w, DEVICE_XATOM_WM_PROTOCOLS (d), XA_ATOM, 32,
- PropModeAppend, (unsigned char *) props, count);
- }
- }
-
- static void
- x_wm_store_class_hints (Widget shell, char *frame_name)
- {
- Display *dpy = XtDisplay (shell);
- char *app_name, *app_class;
- XClassHint classhint;
-
- if (!XtIsWMShell (shell))
- abort ();
-
- XtGetApplicationNameAndClass (dpy, &app_name, &app_class);
- classhint.res_name = frame_name;
- classhint.res_class = app_class;
- XSetClassHint (dpy, XtWindow (shell), &classhint);
- }
-
- static void
- x_wm_maybe_store_wm_command (struct frame *f)
- {
- Widget w = FRAME_X_SHELL_WIDGET (f);
- struct device *d = XDEVICE (FRAME_DEVICE (f));
-
- if (!XtIsWMShell (w))
- abort ();
-
- if (NILP (DEVICE_X_WM_COMMAND_FRAME (d)))
- {
- int argc;
- char **argv;
- make_argc_argv (Vcommand_line_args, &argc, &argv);
- XSetCommand (XtDisplay (w), XtWindow (w), argv, argc);
- free_argc_argv (argv);
- XSETFRAME (DEVICE_X_WM_COMMAND_FRAME (d), f);
- }
- }
-
- /* If we're deleting the frame on which the WM_COMMAND property has been
- set, then move that property to another frame so that there is exactly
- one frame that has that property set.
- */
- static void
- x_wm_maybe_move_wm_command (struct frame *f)
- {
- struct device *d = XDEVICE (FRAME_DEVICE (f));
-
- /* At this point there should always be a frame in
- DEVICE_X_WM_COMMAND_FRAME() */
- if (f == XFRAME (DEVICE_X_WM_COMMAND_FRAME (d)))
- {
- Lisp_Object rest = DEVICE_FRAME_LIST (d);
- DEVICE_X_WM_COMMAND_FRAME (d) = Qnil;
- /* find some random other X frame that is not this one, or give up */
- /* skip non-top-level (ExternalClient) frames */
- while (!NILP (rest) &&
- (f == XFRAME (XCAR (rest)) ||
- !FRAME_X_TOP_LEVEL_FRAME_P (XFRAME (XCAR (rest)))))
- rest = XCDR (rest);
- if (NILP (rest))
- return;
- f = XFRAME (XCAR (rest));
- x_wm_maybe_store_wm_command (f);
- }
- }
-
- static int
- x_frame_iconified_p (struct frame *f)
- {
- Atom actual_type;
- int actual_format;
- unsigned long nitems, bytesafter;
- unsigned long *datap = 0;
- Widget widget;
- int result = 0;
- struct device *d = XDEVICE (FRAME_DEVICE (f));
-
- widget = FRAME_X_SHELL_WIDGET (f);
- if (Success == XGetWindowProperty (XtDisplay (widget), XtWindow (widget),
- DEVICE_XATOM_WM_STATE (d), 0, 2, False,
- DEVICE_XATOM_WM_STATE (d), &actual_type,
- &actual_format, &nitems, &bytesafter,
- (unsigned char **) &datap)
- && datap)
- {
- if (nitems <= 2 /* "suggested" by ICCCM version 1 */
- && datap[0] == IconicState)
- result = 1;
- XFree ((char *) datap);
- }
- return result;
- }
-
-
- /************************************************************************/
- /* frame parameters */
- /************************************************************************/
-
- /* Connect the frame-parameter names (symbols) to the corresponding
- X Resource Manager names. The name of a parameter, as a Lisp symbol,
- has an `x-resource-name' property which is a Lisp_String. */
-
- static void
- init_x_parm_symbols (void)
- {
- #define def(sym, rsrc) \
- pure_put (intern (sym), Qx_resource_name, build_string (rsrc))
- #define defi(sym,rsrc) \
- def (sym, rsrc); pure_put (intern (sym), Qintegerp, Qt)
-
- def ("minibuffer", XtNminibuffer);
- def ("unsplittable", XtNunsplittable);
- defi("internal-border-width", XtNinternalBorderWidth);
- defi("scrollbar-width", XtNscrollBarWidth);
- def ("top-toolbar-shadow-color", XtNtopToolBarShadowColor);
- def ("bottom-toolbar-shadow-color", XtNbottomToolBarShadowColor);
- def ("background-toolbar-color", XtNbackgroundToolBarColor);
- def ("top-toolbar-shadow-pixmap", XtNtopToolBarShadowPixmap);
- def ("bottom-toolbar-shadow-pixmap", XtNbottomToolBarShadowPixmap);
- defi("toolbar-shadow-thickness", XtNtoolBarShadowThickness);
- def ("scrollbar-placement", XtNscrollBarPlacement);
- defi("inter-line-space", XtNinterline);
- /* font, foreground */
- def ("iconic", XtNiconic);
- def ("cursor-color", XtNcursorColor);
- def ("bar-cursor", XtNbarCursor);
- def ("visual-bell", XtNvisualBell);
- defi("bell-volume", XtNbellVolume);
- def ("pointer-background", XtNpointerBackground);
- def ("pointer-color", XtNpointerColor);
- def ("text-pointer", XtNtextPointer);
- def ("space-pointer", XtNspacePointer);
- def ("modeline-pointer", XtNmodeLinePointer);
- def ("gc-pointer", XtNgcPointer);
- /* geometry, initial-geometry */
- def ("menubar", XtNmenubar);
- def ("initially-unmapped", XtNinitiallyUnmapped);
- /* preferred-width, preferred-height */
- def ("use-backing-store", XtNuseBackingStore);
-
- /* inherited: */
-
- def ("border-color", XtNborderColor);
- defi("border-width", XtNborderWidth);
- defi("width", XtNwidth);
- defi("height", XtNheight);
- defi("left", XtNx);
- defi("top", XtNy);
-
- #undef def
- }
-
- /* Insert a description of internally-recorded parameters of frame X
- into the parameter alist *ALISTPTR that is to be given to the user.
- Only parameters that are specific to the X window system
- and whose values are not correctly recorded in the frame's
- param_alist need to be considered here. */
-
- static void
- color_to_string (Widget w, unsigned long pixel, char *buf)
- {
- XColor color;
- color.pixel = pixel;
- XQueryColor (XtDisplay (w), w->core.colormap, &color);
- sprintf (buf, "#%04x%04x%04x", color.red, color.green, color.blue);
- }
-
- static void
- x_get_top_level_position (Display *d, Window w, Position *x, Position *y)
- {
- Window root, parent = w, *children;
- unsigned int nchildren;
- XWindowAttributes xwa;
-
- do
- {
- w = parent;
- if (!XQueryTree (d, w, &root, &parent, &children, &nchildren))
- {
- *x = 0;
- *y = 0;
- return;
- }
- XFree (children);
- } while (root != parent);
- XGetWindowAttributes (d, w, &xwa);
- *x = xwa.x;
- *y = xwa.y;
- }
-
- static void
- x_get_frame_params (struct frame *f, Lisp_Object *alistptr)
- {
- Widget shell = FRAME_X_SHELL_WIDGET (f);
- EmacsFrame w = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
- char buf [255];
-
- #define store_int(sym, slot) \
- store_in_alist (alistptr, sym, make_number (slot))
- #define store_str(sym, slot) \
- store_in_alist (alistptr, sym, build_string (slot))
- #define store_bool(sym, slot) \
- store_in_alist (alistptr, sym, (slot) ? Qt : Qnil)
- #define store_color(sym, slot) \
- color_to_string ((Widget) w, slot, buf); \
- store_in_alist (alistptr, sym, build_string (buf))
-
- store_color ("cursor-color", w->emacs_frame.cursor_color);
- store_color ("border-color", w->core.border_pixel);
- /* Naturally those bastards who wrote Xt couldn't be bothered
- to learn about race conditions and such. We can't trust
- the X and Y values to have any resemblance of correctness,
- so we smash the right values in place. */
- x_get_top_level_position (XtDisplay (shell), XtWindow (shell),
- &shell->core.x, &shell->core.y);
- store_int ("left", shell->core.x);
- store_int ("top", shell->core.y);
- store_int ("border-width", w->core.border_width);
- store_int ("internal-border-width", w->emacs_frame.internal_border_width);
- store_int ("scrollbar-width", w->emacs_frame.scrollbar_width);
- store_color ("top-toolbar-shadow-color",
- w->emacs_frame.top_toolbar_shadow_pixel);
- store_color ("bottom-toolbar-shadow-color",
- w->emacs_frame.bottom_toolbar_shadow_pixel);
- store_color ("background-toolbar-color",
- w->emacs_frame.background_toolbar_pixel);
- store_int ("toolbar-shadow-thickness",
- w->emacs_frame.toolbar_shadow_thickness);
- store_int ("inter-line-space", w->emacs_frame.interline);
- store_bool ("minibuffer", w->emacs_frame.minibuffer);
- store_bool ("unsplittable", w->emacs_frame.unsplittable);
- sprintf (buf, "0x%x", (int) XtWindow (w));
- store_str ("window-id", buf);
- }
-
-
- /* Functions called only from `x_set_frame_params' to set
- ** individual parameters. */
-
- static void
- x_set_title_from_char (struct frame *f, char* name)
- {
- char *old_name = 0;
- Arg av [1];
- XtSetArg (av[0], XtNtitle, &old_name);
- XtGetValues (FRAME_X_SHELL_WIDGET (f), av, 1);
- if (!old_name || strcmp (name, old_name))
- {
- XtSetArg (av[0], XtNtitle, name);
- XtSetValues (FRAME_X_SHELL_WIDGET (f), av, 1);
- }
- }
-
- static void
- x_set_icon_name_from_char (struct frame *f, char* name)
- {
- char *old_name = 0;
- Arg av [1];
- XtSetArg (av[0], XtNiconName, &old_name);
- XtGetValues (FRAME_X_SHELL_WIDGET (f), av, 1);
- if (!old_name || strcmp (name, old_name))
- {
- XtSetArg (av[0], XtNiconName, name);
- XtSetValues (FRAME_X_SHELL_WIDGET (f), av, 1);
- }
- }
-
- /* Set the initial frame size as specified. This function is used
- when the frame's widgets have not yet been realized. In this
- case, it is not sufficient just to set the width and height of
- the EmacsFrame widget, because they will be ignored when the
- widget is realized (instead, the shell's geometry resource is
- used). */
-
- static void
- x_set_initial_frame_size (struct frame *f, int flags, int x, int y,
- unsigned int w, unsigned int h)
- {
- char shell_geom [255];
- int xval, yval;
- char xsign, ysign;
- char uspos = !!(flags & (XValue | YValue));
- char ussize = !!(flags & (WidthValue | HeightValue));
- char *temp;
-
- /* assign the correct size to the EmacsFrame widget ... */
- EmacsFrameSetCharSize (FRAME_X_TEXT_WIDGET (f), w, h);
-
- /* and also set the WMShell's geometry */
- (flags & XNegative) ? (xval = -x, xsign = '-') : (xval = x, xsign = '+');
- (flags & YNegative) ? (yval = -y, ysign = '-') : (yval = y, ysign = '+');
-
- if (uspos && ussize)
- sprintf (shell_geom, "=%dx%d%c%d%c%d", w, h, xsign, xval, ysign, yval);
- else if (uspos)
- sprintf (shell_geom, "=%c%d%c%d", xsign, xval, ysign, yval);
- else if (ussize)
- sprintf (shell_geom, "=%dx%d", w, h);
-
- if (uspos || ussize)
- {
- temp = xmalloc (1 + strlen (shell_geom));
- strcpy (temp, shell_geom);
- FRAME_X_GEOM_FREE_ME_PLEASE (f) = temp;
- }
- else
- temp = NULL;
- XtVaSetValues (FRAME_X_SHELL_WIDGET (f), XtNgeometry, temp, 0);
- }
-
- /* Report to X that a frame parameter of frame S is being set or changed.
- If the parameter is not specially recognized, do nothing.
- */
-
- static void
- x_set_frame_params_1 (struct frame *f, Lisp_Object alist, int initialized_p)
- {
- int x = 0, y = 0;
- Dimension width = 0, height = 0;
- Bool width_specified_p = False;
- Bool height_specified_p = False;
- Bool x_position_specified_p = False;
- Bool y_position_specified_p = False;
- Bool internal_border_width_specified = False;
- Lisp_Object tail;
- Widget w = FRAME_X_TEXT_WIDGET (f);
-
- for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
- {
- Lisp_Object elt = Fcar (tail);
- Lisp_Object prop = Fcar (elt);
- Lisp_Object val = Fcdr (elt);
-
- if (STRINGP (prop))
- {
- if (string_length (XSTRING (prop)) == 0)
- continue;
-
- if (STRINGP (val))
- XtVaSetValues (w, XtVaTypedArg, string_data (XSTRING (prop)),
- XtRString, string_data (XSTRING (val)),
- string_length (XSTRING (val)) + 1, 0);
- else
- XtVaSetValues (w, XtVaTypedArg,
- string_data (XSTRING (prop)), XtRInt, XINT (val),
- sizeof (int),
- 0);
- }
- #if 0
- /* mly wants this, but it's not reasonable to change the name of a
- frame after it has been created, because the old name was used
- for resource lookup. */
- else if (EQ (elt, Qname))
- {
- CHECK_STRING (val, 0);
- f->name = val;
- }
- #endif /* 0 */
- else
- {
- Lisp_Object str = Fget (prop, Qx_resource_name, Qnil);
- int int_p = !NILP (Fget (prop, Qintegerp, Qnil));
-
- if (NILP (prop) || NILP (str))
- {
- /* #### No error-checking on property names! FMH!!! */
- /* RMS apparently thinks this is a feature.
- This whole frame-parameters things has got to go. */
-
- /* Kludge to handle the font property. */
- if (EQ (prop, Qfont))
- {
- /* If the value is not a string we silently ignore it. */
- if (STRINGP (val))
- {
- Lisp_Object frm, font_spec;
-
- XSETFRAME (frm, f);
- font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);
-
- Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
- update_frame_face_values (f);
- }
-
- continue;
- }
- else
- continue;
- }
- CHECK_STRING (str, 0);
-
- /* Kludge the width/height so that we interpret them in characters
- instead of pixels. Yuck yuck yuck. */
- if (!strcmp ((char *) string_data (XSTRING (str)), "width"))
- {
- CHECK_INT (val, 0);
- width = XINT (val);
- width_specified_p = True;
- continue;
- }
- if (!strcmp ((char *) string_data (XSTRING (str)), "height"))
- {
- CHECK_INT (val, 0);
- height = XINT (val);
- height_specified_p = True;
- continue;
- }
- /* Further kludge the x/y. */
- if (!strcmp ((char *) string_data (XSTRING (str)), "x"))
- {
- CHECK_INT (val, 0);
- x = XINT (val);
- x_position_specified_p = True;
- continue;
- }
- if (!strcmp ((char *) string_data (XSTRING (str)), "y"))
- {
- CHECK_INT (val, 0);
- y = XINT (val);
- y_position_specified_p = True;
- continue;
- }
- /* Have you figured out by now that this entire function is
- one gigantic kludge? */
- if (!strcmp ((char *) string_data (XSTRING (str)),
- "internalBorderWidth"))
- {
- internal_border_width_specified = True;
- }
-
- if (int_p)
- {
- CHECK_INT (val, 0);
- XtVaSetValues (w, (char *) string_data (XSTRING (str)),
- XINT (val), 0);
- }
- else if (EQ (val, Qt))
- XtVaSetValues (w, (char *) string_data (XSTRING (str)), /* XtN... */
- True,
- 0);
- else if (EQ (val, Qnil))
- XtVaSetValues (w, (char *) string_data (XSTRING (str)), /* XtN... */
- False,
- 0);
- else
- {
- CHECK_STRING (val, 0);
- XtVaSetValues (w, XtVaTypedArg,
- (char *) string_data (XSTRING (str)), /* XtN... */
- XtRString,
- string_data (XSTRING (val)), string_length (XSTRING (val)) + 1,
- 0);
- }
-
- if (!strcmp ((char *) string_data (XSTRING (str)), "scrollBarWidth")
- || !strcmp ((char *) string_data (XSTRING (str)),
- "scrollBarHeight"))
- {
- x_update_frame_scrollbars (f);
- }
- }
- }
-
- /* Kludge kludge kludge. We need to deal with the size and position
- specially. */
- {
- int size_specified_p = width_specified_p || height_specified_p;
- int position_specified_p = x_position_specified_p ||
- y_position_specified_p;
-
- if (!width_specified_p)
- width = FRAME_WIDTH (f);
- if (!height_specified_p)
- height = FRAME_HEIGHT (f);
-
- /* Kludge kludge kludge kludge. */
- if (!x_position_specified_p)
- x = (int) (FRAME_X_SHELL_WIDGET (f)->core.x);
- if (!y_position_specified_p)
- y = (int) (FRAME_X_SHELL_WIDGET (f)->core.y);
-
- if (!initialized_p)
- {
- int flags = (size_specified_p ? WidthValue | HeightValue : 0) |
- (position_specified_p ? XValue | YValue : 0) |
- (x < 0 ? XNegative : 0) | (y < 0 ? YNegative : 0);
- if (size_specified_p
- || position_specified_p
- || internal_border_width_specified)
- x_set_initial_frame_size (f, flags, x, y, width, height);
- }
- else
- {
- if (size_specified_p || internal_border_width_specified)
- {
- Lisp_Object frame;
- XSETFRAME (frame, f);
- Fset_frame_size (frame, make_number (width),
- make_number (height), Qnil);
- }
- if (position_specified_p)
- {
- Lisp_Object frame;
- XSETFRAME (frame, f);
- Fset_frame_position (frame, make_number (x), make_number (y));
- }
- }
- }
- }
-
- static void
- x_set_frame_params (struct frame *f, Lisp_Object alist)
- {
- x_set_frame_params_1 (f, alist, 1);
- }
-
- static int frame_title_format_already_set;
-
- static void
- maybe_set_frame_title_format (Widget shell)
- {
-
- /* Only do this if this is the first X frame we're creating.
-
- If the *title resource (or -title option) was specified, then
- set frame-title-format to its value.
- */
-
- if (!frame_title_format_already_set)
- {
- /* No doubt there's a less stupid way to do this. */
- char *results [2];
- XtResource resources [2];
- results [0] = results [1] = 0;
- resources [0].resource_name = XtNtitle;
- resources [0].resource_class = XtCTitle;
- resources [0].resource_type = XtRString;
- resources [0].resource_size = sizeof (String);
- resources [0].resource_offset = 0;
- resources [0].default_type = XtRString;
- resources [0].default_addr = 0;
- resources [1].resource_name = XtNiconName;
- resources [1].resource_class = XtCIconName;
- resources [1].resource_type = XtRString;
- resources [1].resource_size = sizeof (String);
- resources [1].resource_offset = sizeof (char *);
- resources [1].default_type = XtRString;
- resources [1].default_addr = 0;
- XtGetSubresources (XtParent(shell), (XtPointer)results, shell->core.name,
- shell->core.widget_class->core_class.class_name,
- resources, XtNumber (resources), 0, 0);
- if (results[0])
- Vframe_title_format = build_string (results[0]);
- if (results[1])
- Vframe_icon_title_format = build_string (results[1]);
- }
-
- frame_title_format_already_set = 1;
- }
-
-
- /************************************************************************/
- /* widget creation */
- /************************************************************************/
-
- /* The widget hierarchy is
-
- argv[0] shell container FRAME-NAME
- ApplicationShell EmacsShell EmacsManager EmacsFrame
-
- We accept geometry specs in this order:
-
- *FRAME-NAME.geometry
- *EmacsFrame.geometry
- Emacs.geometry
-
- Other possibilities for widget hierarchies might be
-
- argv[0] frame container FRAME-NAME
- ApplicationShell EmacsShell EmacsManager EmacsFrame
- or
- argv[0] FRAME-NAME container FRAME-NAME
- ApplicationShell EmacsShell EmacsManager EmacsFrame
- or
- argv[0] FRAME-NAME container emacsTextPane
- ApplicationShell EmacsShell EmacsManager EmacsFrame
-
- #ifdef EXTERNAL_WIDGET
- The ExternalShell widget is simply a replacement for the Shell widget
- which is able to deal with using an externally-supplied window instead
- of always creating its own.
- #endif
-
- */
-
- #ifdef EXTERNAL_WIDGET
-
- static int
- is_valid_window (Window w, struct device *d)
- {
- XWindowAttributes xwa;
- Display *dpy = DEVICE_X_DISPLAY (d);
-
- expect_x_error (dpy);
- XGetWindowAttributes (dpy, w, &xwa);
- return !x_error_occurred_p (dpy);
- }
-
- #endif /* EXTERNAL_WIDGET */
-
- /* This sends a synthetic mouse-motion event to the frame, if the mouse
- is over the frame. This ensures that the cursor gets set properly
- before the user moves the mouse for the first time. */
-
- static void
- x_send_synthetic_mouse_event (struct frame *f)
- {
- /* #### write this function. */
- }
-
- static int
- first_x_frame_p (struct frame *f)
- {
- Lisp_Object rest = DEVICE_FRAME_LIST (XDEVICE (f->device));
- while (!NILP (rest) &&
- (f == XFRAME (XCAR (rest)) ||
- !FRAME_IS_X (XFRAME (XCAR (rest)))))
- rest = XCDR (rest);
- return (NILP (rest));
- }
-
- /* Figure out what size the EmacsFrame widget should initially be,
- and set it. Should be called after the default font has been
- determined but before the widget has been realized. */
-
- static void
- x_initialize_frame_size (struct frame *f)
- {
- /* Geometry of the AppShell */
- int app_flags = 0;
- int app_x = 0;
- int app_y = 0;
- unsigned int app_w = 0;
- unsigned int app_h = 0;
-
- /* Geometry of the EmacsFrame */
- int frame_flags = 0;
- int frame_x = 0;
- int frame_y = 0;
- unsigned int frame_w = 0;
- unsigned int frame_h = 0;
-
- /* Hairily merged geometry */
- int x = 0;
- int y = 0;
- unsigned int w = 80;
- unsigned int h = 40;
- int flags = 0;
-
- char *geom = 0, *ew_geom = 0;
- Boolean iconic_p = False, ew_iconic_p = False;
-
- Widget wmshell = FRAME_X_SHELL_WIDGET (f);
- /* #### This may not be an ApplicationShell any more, with the 'popup
- frame parameter. */
- Widget app_shell = XtParent (wmshell);
- Widget ew = FRAME_X_TEXT_WIDGET (f);
-
- /* set the position of the frame's root window now. When the
- frame was created, the position was initialized to (0,0). */
- {
- struct window *win = XWINDOW (f->root_window);
-
- WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f);
- WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f);
-
- if (!NILP (f->minibuffer_window))
- {
- win = XWINDOW (f->minibuffer_window);
- WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f);
- }
- }
-
- #ifdef EXTERNAL_WIDGET
- /* If we're an external widget, then the size of the frame is predetermined
- (by the client) and is not our decision to make. */
- if (FRAME_X_EXTERNAL_WINDOW_P (f))
- return;
- #endif
-
- #if 0
- /* #### this junk has not been tested; therefore it's
- probably wrong. Doesn't really matter at this point because
- currently all frames are either top-level or external widgets. */
-
- /* If we're not our own top-level window, then we shouldn't go messing around
- with top-level shells or "Emacs.geometry" or any such stuff. Therefore,
- we do as follows to determine the size of the frame:
-
- 1) If a value for the frame's "geometry" resource was specified, then
- use it. (This specifies a size in characters.)
- 2) Else, if the "width" and "height" resources were specified, then
- leave them alone. (This is a value in pixels. Sorry, we can't break
- Xt conventions here.)
- 3) Else, assume a size of 64x12. (This is somewhat arbitrary, but
- it's unlikely that a size of 80x40 is desirable because we're probably
- inside of a dialog box.)
-
- Set the widget's x, y, height, and width as determined. Don't set the
- top-level container widget, because we don't necessarily know what it
- is. (Assume it is smart and pays attention to our values.)
- */
-
- if (!FRAME_X_TOP_LEVEL_FRAME_P (f))
- {
- XtVaGetValues (ew, XtNgeometry, &ew_geom, 0);
- if (ew_geom)
- frame_flags = XParseGeometry (ew_geom, &frame_x, &frame_y,
- &frame_w, &frame_h);
- if (! (frame_flags & (WidthValue | HeightValue)))
- {
- XtVaGetValues (ew, XtNwidth, &frame_w,
- XtNheight, &frame_h, 0);
- if (!frame_w && !frame_h)
- {
- frame_w = 64;
- frame_h = 12;
- frame_flags |= WidthValue | HeightValue;
- }
- }
- if (frame_flags & (WidthValue | HeightValue))
- EmacsFrameSetCharSize (ew, frame_w, frame_h);
- if (frame_flags & (XValue | YValue))
- {
- XtVaGetValues (ew, XtNwidth, &frame_w,
- XtNheight, &frame_h, 0);
- if (frame_flags & XNegative)
- frame_x += frame_w;
- if (frame_flags & YNegative)
- frame_y += frame_h;
- XtVaSetValues (ew, XtNx, frame_x, XtNy, frame_y, 0);
- }
- return;
- }
- #endif
-
- /* OK, we're a top-level shell. */
-
- if (!XtIsWMShell (wmshell))
- abort ();
-
- /* If the EmacsFrame doesn't have a geometry but the shell does,
- treat that as the geometry of the frame. (Is this bogus?
- I'm not sure.) */
-
- XtVaGetValues (ew, XtNgeometry, &ew_geom, 0);
- if (!ew_geom)
- {
- XtVaGetValues (wmshell, XtNgeometry, &geom, 0);
- if (geom)
- {
- ew_geom = geom;
- XtVaSetValues (ew, XtNgeometry, ew_geom, 0);
- }
- }
-
- /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
- this bogus? I'm not sure.) */
- XtVaGetValues (ew, XtNiconic, &ew_iconic_p, 0);
- if (!ew_iconic_p)
- {
- XtVaGetValues (wmshell, XtNiconic, &iconic_p, 0);
- if (iconic_p)
- {
- ew_iconic_p = iconic_p;
- XtVaSetValues (ew, XtNiconic, iconic_p, 0);
- }
- }
-
- XtVaGetValues (app_shell, XtNgeometry, &geom, 0);
- if (geom)
- app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h);
-
- if (ew_geom)
- frame_flags = XParseGeometry (ew_geom, &frame_x, &frame_y,
- &frame_w, &frame_h);
-
- if (first_x_frame_p (f))
- {
- /* If this is the first frame created:
- ====================================
-
- - Use the ApplicationShell's size/position, if specified.
- (This is "Emacs.geometry", or the "-geometry" command line arg.)
- - Else use the EmacsFrame's size/position.
- (This is "*FRAME-NAME.geometry")
-
- - If the AppShell is iconic, the frame should be iconic.
-
- AppShell comes first so that -geometry always applies to the first
- frame created, even if there is an "every frame" entry in the
- resource database.
- */
- if (app_flags & (XValue | YValue))
- {
- x = app_x; y = app_y;
- flags |= (app_flags & (XValue | YValue | XNegative | YNegative));
- }
- else if (frame_flags & (XValue | YValue))
- {
- x = frame_x; y = frame_y;
- flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
- }
-
- if (app_flags & (WidthValue | HeightValue))
- {
- w = app_w; h = app_h;
- flags |= (app_flags & (WidthValue | HeightValue));
- }
- else if (frame_flags & (WidthValue | HeightValue))
- {
- w = frame_w; h = frame_h;
- flags |= (frame_flags & (WidthValue | HeightValue));
- }
-
- /* If the AppShell is iconic, then the EmacsFrame is iconic. */
- if (!ew_iconic_p)
- {
- XtVaGetValues (app_shell, XtNiconic, &iconic_p, 0);
- if (iconic_p)
- {
- ew_iconic_p = iconic_p;
- XtVaSetValues (ew, XtNiconic, iconic_p, 0);
- }
- }
- }
- else
- {
- /* If this is not the first frame created:
- ========================================
-
- - use the EmacsFrame's size/position if specified
- - Otherwise, use the ApplicationShell's size, but not position.
-
- So that means that one can specify the position of the first frame
- with "Emacs.geometry" or `-geometry'; but can only specify the
- position of subsequent frames with "*FRAME-NAME.geometry".
-
- AppShell comes second so that -geometry does not apply to subsequent
- frames when there is an "every frame" entry in the resource db,
- but does apply to the first frame.
- */
- if (frame_flags & (XValue | YValue))
- {
- x = frame_x; y = frame_y;
- flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
- }
-
- if (frame_flags & (WidthValue | HeightValue))
- {
- w = frame_w; h = frame_h;
- flags |= (frame_flags & (WidthValue | HeightValue));
- }
- else if (app_flags & (WidthValue | HeightValue))
- {
- w = app_w;
- h = app_h;
- flags |= (app_flags & (WidthValue | HeightValue));
- }
- }
-
- x_set_initial_frame_size (f, flags, x, y, w, h);
- }
-
- static void
- x_get_layout_sizes (struct frame *f, Dimension *topbreadth)
- {
- int i;
-
- /* compute height of all top-area widgets */
- for (i=0, *topbreadth = 0; i<FRAME_X_NUM_TOP_WIDGETS (f); i++)
- {
- Widget wid = FRAME_X_TOP_WIDGETS (f)[i];
- if (wid && XtIsManaged (wid))
- *topbreadth += wid->core.height + 2*wid->core.border_width;
- }
- }
-
- static void
- x_layout_widgets (Widget w, XtPointer client_data, XtPointer call_data)
- {
- struct frame *f = (struct frame *) client_data;
- EmacsManagerResizeStruct *emst = (EmacsManagerResizeStruct *) call_data;
- Dimension width = emst->width;
- Dimension height = emst->height;
- Widget text = FRAME_X_TEXT_WIDGET (f);
- Dimension textbord = text->core.border_width;
- Dimension topbreadth;
- Position text_x = 0, text_y = 0;
- int i;
- unsigned char scrollbar_placement;
-
- x_get_layout_sizes (f, &topbreadth);
-
- /* first the menubar and psheets ... */
- for (i=0; i<FRAME_X_NUM_TOP_WIDGETS (f); i++)
- {
- Widget wid = FRAME_X_TOP_WIDGETS (f)[i];
- if (wid && XtIsManaged (wid))
- {
- Dimension bord = wid->core.border_width;
- XtConfigureWidget (wid, 0, text_y,
- width - 2*bord, wid->core.height,
- bord);
- text_y += wid->core.height + 2*bord;
- }
- }
-
- /* The scrollbar positioning is completely handled by redisplay. We
- just need to know which sides they are supposed to go on. */
- XtVaGetValues (text, XtNscrollBarPlacement, &scrollbar_placement, 0);
- if (scrollbar_placement == XtTOP_LEFT ||
- scrollbar_placement == XtBOTTOM_LEFT)
- {
- f->scrollbar_on_left = 1;
- }
- else
- f->scrollbar_on_left = 0;
-
- if (scrollbar_placement == XtTOP_LEFT ||
- scrollbar_placement == XtTOP_RIGHT)
- {
- f->scrollbar_on_top = 1;
- }
- else
- f->scrollbar_on_top = 0;
-
- f->scrollbar_y_offset = topbreadth + textbord;
-
- /* finally the text area */
- XtConfigureWidget (text, text_x, text_y,
- width - 2*textbord,
- height - text_y - 2*textbord,
- textbord);
- }
-
- static void
- x_do_query_geometry (Widget w, XtPointer client_data, XtPointer call_data)
- {
- struct frame *f = (struct frame *) client_data;
- EmacsManagerQueryGeometryStruct *emst =
- (EmacsManagerQueryGeometryStruct *) call_data;
- Widget text = FRAME_X_TEXT_WIDGET (f);
- Dimension textbord = text->core.border_width;
- Dimension topbreadth;
- XtWidgetGeometry req, repl;
- int mask = emst->request_mode & (CWWidth | CWHeight);
-
- x_get_layout_sizes (f, &topbreadth);
-
- /* strip away menubar from suggested size, and ask the text widget
- what size it wants to be */
- req.request_mode = mask;
- if (mask & CWWidth)
- req.width = emst->proposed_width - 2*textbord;
- if (mask & CWHeight)
- req.height = emst->proposed_height - topbreadth - 2*textbord;
- XtQueryGeometry (text, &req, &repl);
-
- /* Now add the menubar back again */
- emst->proposed_width = repl.width + 2*textbord;
- emst->proposed_height = repl.height + topbreadth + 2*textbord;
- }
-
- /* Creates the widgets for a frame.
- lisp_window_id is a Lisp description of an X window or Xt
- widget to parse.
-
- This function does not create or map the windows. (That is
- done by x_popup_frame().)
- */
- static void
- x_create_widgets (struct frame *f, Lisp_Object lisp_window_id,
- Lisp_Object parent)
- {
- int menubar_visible;
- struct device *d = XDEVICE (f->device);
- #ifdef EXTERNAL_WIDGET
- Window window_id = 0;
- #endif
- char *name;
- Arg av [25];
- int ac = 0;
- Widget text, container, menubar, shell;
- Widget parentwid = 0;
-
-
- if (STRINGP (f->name))
- name = string_ext_data (XSTRING (f->name));
- else
- name = "emacs";
-
- /* The widget hierarchy is
-
- argv[0] shell pane FRAME-NAME
- ApplicationShell EmacsShell EmacsManager EmacsFrame
-
- (the type of the shell is ExternalShell if this frame is running
- in another client's window)
-
- However the EmacsShell widget has WM_CLASS of FRAME-NAME/Emacs.
- Normally such shells have name/class shellname/appclass, which in this
- case would be "shell/Emacs" instead of "frame-name/Emacs". We could
- also get around this by naming the shell "frame-name", but that would
- be confusing because the text area (the EmacsFrame widget inferior of
- the shell) is also called that. So we just set the WM_CLASS property.
- */
-
- #ifndef EXTERNAL_WIDGET
- if (!NILP (lisp_window_id))
- error ("support for external widgets was not enabled at compile-time");
- #else
- if (!NILP (lisp_window_id))
- {
- char *string;
-
- CHECK_STRING (lisp_window_id, 0);
- string = (char *) (string_data (XSTRING (lisp_window_id)));
- if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X'))
- sscanf (string+2, "%lxu", &window_id);
- #if 0
- else if (string[0] == 'w')
- {
- sscanf (string+1, "%x", &parent_widget);
- if (parent_widget)
- window_id = XtWindow (parent_widget);
- }
- #endif
- else
- sscanf (string, "%lu", &window_id);
- if (!is_valid_window (window_id, d))
- error ("Invalid window %d", window_id);
- FRAME_X_EXTERNAL_WINDOW_P (f) = 1;
- } else
- #endif /* EXTERNAL_WIDGET */
- FRAME_X_TOP_LEVEL_FRAME_P (f) = 1;
-
- ac = 0;
- XtSetArg (av[ac], XtNallowShellResize, True); ac++;
- #ifdef LWLIB_USES_MOTIF
- /* Motif sucks beans. Without this in here, it will delete the window
- out from under us when it receives a WM_DESTROY_WINDOW message
- from the WM. */
- XtSetArg (av[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
- #endif
-
- #ifdef EXTERNAL_WIDGET
- if (window_id)
- {
- XtSetArg (av[ac], XtNwindow, window_id); ac++;
- }
- else
- #endif
- {
- XtSetArg (av[ac], XtNinput, True); ac++;
- XtSetArg (av[ac], XtNminWidthCells, 10); ac++;
- XtSetArg (av[ac], XtNminHeightCells, 4); ac++;
- }
-
- if (!NILP (parent))
- {
- parentwid = FRAME_X_SHELL_WIDGET (XFRAME (parent));
- XtSetArg (av[ac], XtNtransientFor, parentwid); ac++;
- }
-
- shell = XtCreatePopupShell ("shell",
- (
- #ifdef EXTERNAL_WIDGET
- window_id ? externalShellWidgetClass :
- #endif
- parentwid ? transientEmacsShellWidgetClass :
- topLevelEmacsShellWidgetClass
- ),
- parentwid ? parentwid :
- DEVICE_XT_APP_SHELL (d),
- av, ac);
- FRAME_X_SHELL_WIDGET (f) = shell;
- maybe_set_frame_title_format (shell);
-
- /* Create the manager widget */
- container = XtVaCreateWidget ("container",
- emacsManagerWidgetClass,
- shell, 0);
- FRAME_X_CONTAINER_WIDGET (f) = container;
- XtAddCallback (container, XtNresizeCallback, x_layout_widgets,
- (XtPointer) f);
- XtAddCallback (container, XtNqueryGeometryCallback, x_do_query_geometry,
- (XtPointer) f);
-
- /* Create the text area */
- ac = 0;
- XtSetArg (av[ac], XtNborderWidth, 0); ac++; /* should this be settable? */
- XtSetArg (av[ac], XtNemacsFrame, f); ac++;
- text = XtCreateWidget (name,
- emacsFrameClass,
- container, av, ac);
- FRAME_X_TEXT_WIDGET (f) = text;
-
- /* Create the initial menubar widget. */
- menubar_visible = initialize_frame_menubar (f);
- FRAME_X_TOP_WIDGETS (f)[0] = menubar = FRAME_X_MENUBAR_WIDGET (f);
- FRAME_X_NUM_TOP_WIDGETS (f) = 1;
-
- if (menubar_visible)
- XtManageChild (menubar);
- XtManageChild (text);
- XtManageChild (container);
- }
-
- /* We used to call XtPopup() in x_popup_frame, but that doesn't give
- you control over whether the widget is initially mapped or not
- because XtPopup() makes an unconditional call to XMapRaised().
- Boy, those Xt designers were clever.
-
- When we first removed it we only kept the XtRealizeWidget call in
- XtPopup. For everything except HP's that was enough. For HP's,
- though, the failure to call the popup callbacks resulted in XEmacs
- not accepting any input. Bizarre but true. Stupid but true.
-
- So, in case there are any other gotches floating out there along
- the same lines I've duplicated the majority of XtPopup here. It
- assumes no grabs and that the widget is not already popped up, both
- valid assumptions for the one place this is called from. */
- static void
- xemacs_XtPopup (Widget widget)
- {
- ShellWidget shell_widget = (ShellWidget) widget;
- XtGrabKind call_data = XtGrabNone;
-
- XtCallCallbacks(widget, XtNpopupCallback, (XtPointer)&call_data);
-
- shell_widget->shell.popped_up = TRUE;
- shell_widget->shell.grab_kind = XtGrabNone;
- shell_widget->shell.spring_loaded = False;
-
- if (shell_widget->shell.create_popup_child_proc != NULL)
- (*(shell_widget->shell.create_popup_child_proc))(widget);
-
- /* The XtVaSetValues below are not in XtPopup menu. We just want to
- make absolutely sure... */
- XtVaSetValues (widget, XtNmappedWhenManaged, False, NULL);
- XtRealizeWidget (widget);
- XtVaSetValues (widget, XtNmappedWhenManaged, True, NULL);
- }
-
- /* create the windows for the specified frame and display them.
- Note that the widgets have already been created, and any
- necessary geometry calculations have already been done. */
- static void
- x_popup_frame (struct frame *f)
- {
- Widget shell_widget = FRAME_X_SHELL_WIDGET (f);
- Widget frame_widget = FRAME_X_TEXT_WIDGET (f);
- struct device *d = XDEVICE (FRAME_DEVICE (f));
-
- /* Before mapping the window, make sure that the WMShell's notion of
- whether it should be iconified is synchronized with the EmacsFrame's
- notion.
- */
- if (FRAME_X_TOP_LEVEL_FRAME_P (f))
- x_wm_set_shell_iconic_p (shell_widget,
- ((EmacsFrame) frame_widget)
- ->emacs_frame.iconic);
-
- xemacs_XtPopup (shell_widget);
-
- if (!((EmacsFrame) frame_widget)->emacs_frame.initially_unmapped)
- XtMapWidget (shell_widget);
- else
- {
- /* We may have set f->visible to 1 in x_init_frame(), so undo
- that now. */
- FRAME_X_TOTALLY_VISIBLE_P (f) = 0;
- f->visible = 0;
- }
-
- #ifdef EXTERNAL_WIDGET
- if (FRAME_X_EXTERNAL_WINDOW_P (f))
- ExternalShellReady (shell_widget, XtWindow (frame_widget), KeyPressMask);
- else
- #endif
- if (FRAME_X_TOP_LEVEL_FRAME_P (f))
- {
- /* tell the window manager about us. */
- x_wm_store_class_hints (shell_widget, XtName (frame_widget));
- x_wm_maybe_store_wm_command (f);
- x_wm_hack_wm_protocols (shell_widget);
- }
-
- #ifdef I18N4
- /* #### not device-independent. */
- if (initial_input_context)
- {
- Window main_window = XtWindow (frame_widget);
- static int initial_ic_used_already = 0;
- /* kludge alert...I want to make sure that init_input() actually
- completed its dirty work (event_mask setup) */
-
- if (!initial_ic_used_already)
- {
- /* I probably ought to just waste this initial_input_context crap and
- do all XIC setup here... But then I'd have to mess around with
- event_masks. see init_input() */
- FRAME_X_INPUT_CONTEXT (f) = initial_input_context;
- initial_ic_used_already = 1;
- }
- else
- {
- FRAME_X_INPUT_CONTEXT (f) =
- XCreateIC (input_method,
- XNInputStyle, input_method_style,
- NULL);
- }
-
- XSetICValues (FRAME_X_INPUT_CONTEXT (x),
- XNClientWindow, main_window,
- XNFocusWindow, main_window,
- NULL);
- }
- #endif /* I18N4 */
-
- #ifdef HACK_EDITRES
- /* Allow XEmacs to respond to EditRes requests. See the O'Reilly Xt */
- /* Instrinsics Programming Manual, Motif Edition, Aug 1993, Sect 14.14, */
- /* pp. 483-493. */
- XtAddEventHandler (shell_widget, /* the widget in question */
- (EventMask) 0, /* OR this mask with existing mask */
- True, /* called on non-maskable events? */
- _XEditResCheckMessages, /* the handler */
- NULL );
- #endif
-
- /* Do a stupid property change to force the server to generate a
- propertyNotify event so that the event_stream server timestamp will
- be initialized to something relevant to the time we created the window.
- */
- XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
- DEVICE_XATOM_WM_PROTOCOLS (d), XA_ATOM, 32, PropModeAppend,
- (unsigned char*) NULL, 0);
-
- x_send_synthetic_mouse_event (f);
- }
-
- static void
- allocate_x_frame_struct (struct frame *f)
- {
- /* zero out all slots. */
- f->frame_data = malloc_type_and_zero (struct x_frame);
-
- /* yeah, except the lisp ones */
- FRAME_X_ICON_PIXMAP (f) = Qnil;
- FRAME_X_ICON_PIXMAP_MASK (f) = Qnil;
- #ifdef ENERGIZE
- FRAME_X_CURRENT_PSHEET_BUFFER (f) = Qnil;
- FRAME_X_DESIRED_PSHEET_BUFFER (f) = Qnil;
- #endif
- }
-
-
- /************************************************************************/
- /* Lisp functions */
- /************************************************************************/
-
- static void
- x_init_frame (struct frame *f, Lisp_Object parms)
- {
- /* This function can GC */
- Lisp_Object device = FRAME_DEVICE (f);
- struct device *d = XDEVICE (device);
- Lisp_Object lisp_window_id;
- Lisp_Object popup;
-
- lisp_window_id = Fassq (Qwindow_id, parms);
- if (!NILP (lisp_window_id))
- lisp_window_id = Fcdr (lisp_window_id);
- popup = Fassq (Qpopup, parms);
- if (!NILP (popup))
- {
- popup = XCDR (popup);
- if (EQ (popup, Qt))
- popup = Fselected_frame (device);
- CHECK_LIVE_FRAME (popup, 0);
- if (!EQ (device, FRAME_DEVICE (XFRAME (popup))))
- signal_simple_error_2 ("Parent must be on same device as frame",
- device, popup);
- }
-
- if (NILP (DEVICE_SELECTED_FRAME (d)))
- {
- /* This means that this is the first frame on the device.
- So short-ciruit the delay in processing the initial MapNotify
- event so that output on the first frame shows up right
- away... */
- f->visible = 1;
- }
-
- allocate_x_frame_struct (f);
- x_create_widgets (f, lisp_window_id, popup);
- }
-
- static void
- x_finish_init_frame (struct frame *f, Lisp_Object parms)
- {
- /* Set up the values of the widget/frame. A case could be made for putting
- this inside of the widget's initialize method. */
-
- update_frame_face_values (f);
- x_initialize_frame_size (f);
- update_frame_title (f);
- x_set_frame_params_1 (f, parms, 0);
-
- /* Pop up the frame. */
-
- x_popup_frame (f);
- }
-
- static void
- x_mark_frame (struct frame *f, void (*markobj) (Lisp_Object))
- {
- ((markobj) (FRAME_X_ICON_PIXMAP (f)));
- ((markobj) (FRAME_X_ICON_PIXMAP_MASK (f)));
- #ifdef ENERGIZE
- ((markobj) (FRAME_X_CURRENT_PSHEET_BUFFER (f)));
- ((markobj) (FRAME_X_DESIRED_PSHEET_BUFFER (f)));
- #endif
- }
-
- /* #### We need to update documentation once fully converted to glyph
- system. */
- DEFUN ("x-set-frame-icon-pixmap", Fx_set_frame_icon_pixmap,
- Sx_set_frame_icon_pixmap, 2, 3, 0,
- "Set the icon of the given frame to the given image instance,\n\
- which should be an image instance object (as returned by\n\
- `make-image-instance'), a glyph object (as returned by `make-glyph'),\n\
- or nil. If a glyph object is given, the glyph will be instantiated on\n\
- the frame to produce an image instance object.\n\
- \n\
- If the given image instance has a mask, that will be used as the icon mask;\n\
- however, not all window managers support this.\n\
- \n\
- The window manager is also not required to support color pixmaps,\n\
- only bitmaps (one plane deep).\n\
- \n\
- If the image instance does not have a mask, then the optional\n\
- third argument may be the image instance to use as the mask (it must be\n\
- one plane deep).")
- (frame, image_instance, mask)
- Lisp_Object frame, image_instance, mask;
- {
- struct frame *f = get_x_frame (frame);
- Pixmap x_pixmap, x_mask;
-
- XSETFRAME (frame, f);
-
- if (!NILP (image_instance))
- {
- if (GLYPHP (image_instance))
- image_instance =
- glyph_image_instance (image_instance, frame, 0);
- CHECK_IMAGE_INSTANCE (image_instance, 0);
- }
- if (!NILP (mask))
- {
- if (GLYPHP (mask))
- mask = glyph_image_instance (mask, frame, 0);
- CHECK_IMAGE_INSTANCE (mask, 0);
- }
-
- if (IMAGE_INSTANCEP (image_instance)
- && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (image_instance)))
- {
- x_pixmap = XIMAGE_INSTANCE_X_PIXMAP (image_instance);
- x_mask = XIMAGE_INSTANCE_PIXMAP_DEPTH (image_instance);
- if (x_mask) mask = Qnil;
- }
- else
- {
- x_pixmap = 0;
- x_mask = 0;
- mask = Qnil;
- }
-
- if (IMAGE_INSTANCEP (mask)
- && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (mask)))
- {
- if (XIMAGE_INSTANCE_PIXMAP_DEPTH (mask) > 1)
- signal_simple_error ("mask must be one plane", mask);
- x_mask = XIMAGE_INSTANCE_X_PIXMAP (mask);
- }
-
- /* GC-protect the lisp objects (and underlying X data) */
- FRAME_X_ICON_PIXMAP (f) = image_instance;
- FRAME_X_ICON_PIXMAP_MASK (f) = mask;
-
- /* Store the X data into the widget. */
- {
- Arg av [10];
- int ac = 0;
- XtSetArg (av [ac], XtNiconPixmap, x_pixmap); ac++;
- XtSetArg (av [ac], XtNiconMask, x_mask); ac++;
- XtSetValues (FRAME_X_SHELL_WIDGET (f), av, ac);
- }
-
- return image_instance;
- }
-
- DEFUN ("x-set-frame-pointer", Fx_set_frame_pointer, Sx_set_frame_pointer,
- 2, 2, 0,
- "Set the mouse cursor of FRAME to the given cursor,\n\
- which should be an object returned by `make-cursor'.")
- (frame, cursor)
- Lisp_Object frame, cursor;
- {
- /* #### seriously broken. */
- struct frame *f = get_x_frame (frame);
- CHECK_CURSOR (cursor, 0);
- if (! EQ (f->pointer, cursor))
- {
- XDefineCursor (XtDisplay (FRAME_X_TEXT_WIDGET (f)),
- XtWindow (FRAME_X_TEXT_WIDGET (f)),
- XCURSOR (cursor)->cursor);
- XSync (XtDisplay (FRAME_X_TEXT_WIDGET (f)), 0);
- /* #### If the user cuts this pointer, we'll get X errors.
- This needs to be rethunk. */
- /* change_cursor_for_gc() accesses this */
- f->pointer = cursor;
- }
- return Qnil;
- }
-
- DEFUN ("x-set-scrollbar-pointer", Fx_set_scrollbar_pointer,
- Sx_set_scrollbar_pointer, 2, 2, 0,
- "Set the mouse cursor of the scrollbars on FRAME to the given\n\
- cursor, which should be an object returned by `make-cursor'.")
- (frame, cursor)
- Lisp_Object frame, cursor;
- {
- /* #### seriously broken. */
- struct frame *f = get_x_frame (frame);
- CHECK_CURSOR (cursor, 0);
- x_set_scrollbar_pointer (f, cursor);
- return Qnil;
- }
-
- /* GC calls x_show_gc_cursor() with a cursor object to turn on the GC cursor,
- and with nil to turn it off.
- */
-
- int
- x_show_gc_cursor (struct frame *f, Lisp_Object cursor)
- {
- int speccount = specpdl_depth ();
- Lisp_Object frame;
- int changed = 0;
-
- specbind (Qinhibit_quit, Qt); /* some losers in here call Fassq() */
-
- XSETFRAME (frame, f);
- if (NILP (cursor))
- {
- if (!NILP (Vpre_gc_cursor))
- {
- if (!CURSORP (Vpre_gc_cursor)) abort ();
- /* We know it's a frame, we know it's a pointer, so
- x-set-frame-pointer won't error. */
- Fx_set_frame_pointer (frame, Vpre_gc_cursor);
- changed = 1;
- }
- }
- else if (CURSORP (cursor))
- {
- Vpre_gc_cursor = f->pointer;
-
- if (CURSORP (Vpre_gc_cursor))
- /* if we don't know what cursor is there, don't change to the GC
- cursor, because we'd have no way of changing back... */
- {
- /* We know it's a frame, we know it's a pointer, so
- x-set-frame-pointer won't error. */
- Fx_set_frame_pointer (frame, cursor);
- changed = 1;
- }
- }
-
- unbind_to (speccount, Qnil);
- return changed;
- }
-
- DEFUN ("x-window-id", Fx_window_id, Sx_window_id, 0, 1, 0,
- "Get the ID of the X11 window.\n\
- This gives us a chance to manipulate the Emacs window from within a\n\
- different program. Since the ID is an unsigned long, we return it as\n\
- a string.")
- (frame)
- Lisp_Object frame;
- {
- char str[255];
- struct frame *f = get_x_frame (frame);
-
- sprintf (str, "%lu", XtWindow (FRAME_X_TEXT_WIDGET (f)));
- return build_string (str);
- }
-
-
- /************************************************************************/
- /* manipulating the X window */
- /************************************************************************/
-
- static void
- x_set_frame_position (struct frame *f, int xoff, int yoff)
- {
- Widget w = FRAME_X_SHELL_WIDGET (f);
- Display *dpy = XtDisplay (w);
- Dimension frame_w = DisplayWidth (dpy, DefaultScreen (dpy));
- Dimension frame_h = DisplayHeight (dpy, DefaultScreen (dpy));
- Dimension shell_w, shell_h, shell_bord;
- int win_gravity;
-
- XtVaGetValues (w,
- XtNwidth, &shell_w,
- XtNheight, &shell_h,
- XtNborderWidth, &shell_bord,
- 0);
-
- win_gravity =
- xoff >= 0 && yoff >= 0 ? NorthWestGravity :
- xoff >= 0 ? SouthWestGravity :
- yoff >= 0 ? NorthEastGravity :
- SouthEastGravity;
- if (xoff < 0)
- xoff += frame_w - shell_w - 2*shell_bord;
- if (yoff < 0)
- yoff += frame_h - shell_h - 2*shell_bord;
-
- /* Update the hints so that, if this window is currently iconified, it will
- come back at the right place. We can't look at s->visible to determine
- whether it is iconified because it might not be up-to-date yet (the queue
- might not be processed). */
- XtVaSetValues (w,
- XtNwinGravity, win_gravity,
- XtNx, xoff,
- XtNy, yoff,
- 0);
- /* Sometimes you will find that
-
- (set-frame-position (selected-frame) -50 -50)
-
- doesn't put the frame where you expect it to:
- i.e. it's closer to the lower-right corner than
- ) it should be, and it appears that the size of
- the WM decorations was not taken into account.
- This is *not* a problem with this function.
- Both mwm and twm have bugs in handling this
- situation. (mwm ignores the window gravity
- and always assumes NorthWest, except the first
- time you map the window; twm gets things almost
- right, but forgets to account for the border
- width of the top-level window.) This function
- does what it's supposed to according to the ICCCM,
- and I'm not about to hack around window-manager
- bugs. */
-
- #if 0
- /* This is not necessary under either mwm or twm */
- x_wm_mark_shell_position_user_specified (w);
- #endif
- }
-
- /* Call this to change the size of frame S's x-window. */
-
- static void
- x_set_frame_size (struct frame *f, int cols, int rows)
- {
- EmacsFrameSetCharSize (FRAME_X_TEXT_WIDGET (f), cols, rows);
- #if 0
- /* this is not correct. x_set_frame_size() is called from
- Fset_frame_size(), which may or may not have been called
- by the user (e.g. update_EmacsFrame() calls it when the font
- changes). For now, don't bother with getting this right. */
- x_wm_mark_shell_size_user_specified (FRAME_X_SHELL_WIDGET (f));
- #endif
- }
-
- static void
- x_set_mouse_position (struct window *w, int x, int y)
- {
- struct frame *f = XFRAME (w->frame);
-
- Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device));
- XWarpPointer (display, None, XtWindow (FRAME_X_TEXT_WIDGET (f)),
- 0, 0, 0, 0, w->pixel_left + x, w->pixel_top + y);
- }
-
- static int
- x_get_mouse_position (struct device *d, struct window **w, int *x, int *y)
- {
- Display *display = DEVICE_X_DISPLAY (d);
- Window child_window;
- Window root_window;
- Window win;
- int root_x, root_y;
- int win_x, win_y;
- unsigned int keys_and_buttons;
- struct frame *f;
-
- if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)),
- &root_window, &child_window, &root_x, &root_y,
- &win_x, &win_y, &keys_and_buttons) == False)
- return 0;
-
- if (child_window == None)
- return 0; /* not over any window. */
-
- while (1)
- {
- win = child_window;
- if (XTranslateCoordinates (display, root_window, win, root_x, root_y,
- &win_x, &win_y, &child_window) == False)
- /* Huh? */
- return 0;
-
- if (child_window == None)
- break;
- }
-
- /* At this point, win is the innermost window containing the pointer
- and win_x and win_y are the coordinates of that window. */
- f = x_any_window_to_frame (d, win);
- if (!f)
- return 0;
-
- if (XTranslateCoordinates (display, win,
- XtWindow (FRAME_X_TEXT_WIDGET (f)),
- win_x, win_y, x, y, &child_window) == False)
- /* Huh? */
- return 0;
-
- *w = find_window_by_pixel_pos (*x, *y, f->root_window);
- if (!*w)
- return 0;
-
- /* Adjust the position to be relative to the window. */
- *x -= (*w)->pixel_left;
- *y -= (*w)->pixel_top;
-
- return 1;
- }
-
- static void
- x_cant_notify_wm_error (void)
- {
- error ("Can't notify window manager of iconification.");
- }
-
- /* Raise frame F. */
- static void
- x_raise_frame_1 (struct frame *f, int force)
- {
- Widget bottom_dialog;
- Window emacs_window;
- XWindowChanges xwc;
- unsigned int flags;
- Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device));
-
- if (f->visible || force)
- {
- emacs_window = XtWindow (FRAME_X_SHELL_WIDGET (f));
- /* first raises all the dialog boxes, then put emacs just below the
- * bottom most dialog box */
- bottom_dialog = lw_raise_all_pop_up_widgets ();
- if (bottom_dialog && XtWindow (bottom_dialog))
- {
- xwc.sibling = XtWindow (bottom_dialog);
- xwc.stack_mode = Below;
- flags = CWSibling | CWStackMode;
- }
- else
- {
- xwc.stack_mode = Above;
- flags = CWStackMode;
- }
-
- if (!XReconfigureWMWindow (display, emacs_window,
- DefaultScreen (display),
- flags, &xwc))
- x_cant_notify_wm_error ();
- }
- }
-
- static void
- x_raise_frame (struct frame *f)
- {
- x_raise_frame_1 (f, 1);
- }
-
- /* Lower frame F. */
- static void
- x_lower_frame (struct frame *f)
- {
- Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device));
- XWindowChanges xwc;
- unsigned int flags;
-
- if (f->visible)
- {
- xwc.stack_mode = Below;
- flags = CWStackMode;
- if (!XReconfigureWMWindow (display, XtWindow (FRAME_X_SHELL_WIDGET (f)),
- DefaultScreen (display), flags, &xwc))
- x_cant_notify_wm_error ();
- }
- }
-
- /* Change from withdrawn state to mapped state. */
- static void
- x_make_frame_visible (struct frame *f)
- {
- Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device));
-
- if (!f->visible)
- XMapRaised (display, XtWindow (FRAME_X_SHELL_WIDGET (f)));
- else
- x_raise_frame_1 (f, 0);
- }
-
- /* Change from mapped state to withdrawn state. */
- static void
- x_make_frame_invisible (struct frame *f)
- {
- Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device));
-
- if (!f->visible)
- return;
-
- if (!XWithdrawWindow (display,
- XtWindow (FRAME_X_SHELL_WIDGET (f)),
- DefaultScreen (display)))
- x_cant_notify_wm_error ();
- }
-
- static int
- x_frame_totally_visible_p (struct frame *f)
- {
- return FRAME_X_TOTALLY_VISIBLE_P (f);
- }
-
- /* Change window state from mapped to iconified. */
- static void
- x_iconify_frame (struct frame *f)
- {
- Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device));
-
- if (!XIconifyWindow (display,
- XtWindow (FRAME_X_SHELL_WIDGET (f)),
- DefaultScreen (display)))
- x_cant_notify_wm_error ();
-
- f->iconified = 1;
- }
-
- /* Sets the X focus to frame f. */
- static void
- x_focus_on_frame (struct frame *f)
- {
- XWindowAttributes xwa;
- Widget shell_widget;
-
- assert (FRAME_IS_X (f));
-
- shell_widget = FRAME_X_SHELL_WIDGET (f);
- if (!XtWindow (shell_widget))
- return;
-
- #ifdef EXTERNAL_WIDGET
- if (FRAME_X_EXTERNAL_WINDOW_P (f))
- ExternalShellSetFocus (shell_widget);
- #endif /* EXTERNAL_WIDGET */
-
- /* Do the ICCCM focus change if the window is still visible.
- The s->visible flag might not be up-to-date, because we might
- not have processed magic events recently. So make a server
- round-trip to find out whether it's really mapped right now.
- We grab the server to do this, because that's the only way to
- eliminate the race condition.
- */
- XGrabServer (XtDisplay (shell_widget));
- if (XGetWindowAttributes (XtDisplay (shell_widget),
- XtWindow (shell_widget),
- &xwa))
- f->visible = xwa.map_state == IsViewable;
-
- if (f->visible)
- {
- Window focus;
- int revert_to;
- XGetInputFocus (XtDisplay (shell_widget), &focus, &revert_to);
- /* Don't explicitly set the focus on this window unless the focus
- was on some other window (not PointerRoot). Note that, even when
- running a point-to-type window manager like *twm, there is always
- a focus window; the window manager maintains that based on the
- mouse position. If you set the "NoTitleFocus" option in these
- window managers, then the server itself maintains the focus via
- PointerRoot, and changing that to focus on the window would make
- the window grab the focus. Very bad.
- */
- if (focus != PointerRoot)
- {
- XSetInputFocus (XtDisplay (shell_widget),
- XtWindow (shell_widget),
- RevertToParent,
- DEVICE_X_MOUSE_TIMESTAMP
- (XDEVICE (FRAME_DEVICE (f))));
- XFlush (XtDisplay (shell_widget));
- }
- }
- XUngrabServer (XtDisplay (shell_widget));
- XFlush (XtDisplay (shell_widget)); /* hey, I'd like to DEBUG this... */
- }
-
- /* Destroy the X window of frame S. */
- static void
- x_delete_frame (struct frame *f)
- {
- Widget w = FRAME_X_SHELL_WIDGET (f);
-
- free_frame_menubar (f);
- free_frame_scrollbars (f);
- free_frame_toolbars (f);
-
- if (FRAME_X_TOP_LEVEL_FRAME_P (f))
- x_wm_maybe_move_wm_command (f);
-
- #ifdef EXTERNAL_WIDGET
- {
- Display *dpy = XtDisplay (w);
- expect_x_error (dpy);
- /* for obscure reasons having (I think) to do with the internal
- window-to-widget hierarchy maintained by Xt, we have to call
- XtUnrealizeWidget() here. Xt can really suck. */
- if (f->being_deleted)
- XtUnrealizeWidget (w);
- XtDestroyWidget (w);
- x_error_occurred_p (dpy);
- }
- #else
- XtDestroyWidget (w);
- #endif /* EXTERNAL_WIDGET */
-
- xfree (FRAME_X_GEOM_FREE_ME_PLEASE (f));
- xfree (f->frame_data);
- f->frame_data = 0;
- }
-
-
- /************************************************************************/
- /* initialization */
- /************************************************************************/
-
- void
- syms_of_frame_x (void)
- {
- defsymbol (&Qwindow_id, "window-id");
- defsymbol (&Qpopup, "popup");
- defsymbol (&Qpointer, "pointer");
- defsymbol (&Qscrollbar_pointer, "scrollbar-pointer");
- defsymbol (&Qx_resource_name, "x-resource-name");
-
- defsubr (&Sx_set_frame_icon_pixmap);
- defsubr (&Sx_set_frame_pointer);
- defsubr (&Sx_set_scrollbar_pointer);
- defsubr (&Sx_window_id);
- }
-
- void
- device_type_create_frame_x (void)
- {
- /* frame methods */
- DEVICE_HAS_METHOD (x, init_frame);
- DEVICE_HAS_METHOD (x, finish_init_frame);
- DEVICE_HAS_METHOD (x, mark_frame);
- DEVICE_HAS_METHOD (x, focus_on_frame);
- DEVICE_HAS_METHOD (x, delete_frame);
- DEVICE_HAS_METHOD (x, get_mouse_position);
- DEVICE_HAS_METHOD (x, set_mouse_position);
- DEVICE_HAS_METHOD (x, raise_frame);
- DEVICE_HAS_METHOD (x, lower_frame);
- DEVICE_HAS_METHOD (x, make_frame_visible);
- DEVICE_HAS_METHOD (x, make_frame_invisible);
- DEVICE_HAS_METHOD (x, iconify_frame);
- DEVICE_HAS_METHOD (x, set_frame_size);
- DEVICE_HAS_METHOD (x, set_frame_position);
- DEVICE_HAS_METHOD (x, get_frame_params);
- DEVICE_HAS_METHOD (x, set_frame_params);
- DEVICE_HAS_METHOD (x, set_title_from_char);
- DEVICE_HAS_METHOD (x, set_icon_name_from_char);
- DEVICE_HAS_METHOD (x, frame_totally_visible_p);
- DEVICE_HAS_METHOD (x, frame_iconified_p);
- }
-
- void
- vars_of_frame_x (void)
- {
- DEFVAR_LISP ("x-gc-pointer-shape", &Vx_gc_pointer_shape,
- "The shape of the mouse-pointer during garbage collection.\n\
- If this is nil, then the cursor will not be changed, and echo-area messages\n\
- will be used instead.");
- Vx_gc_pointer_shape = Qnil;
-
- DEFVAR_LISP ("x-scrollbar-pointer-shape", &Vx_scrollbar_pointer_shape,
- "Currently under construction. Use `x-set-scrollbar-pointer' instead.");
- Vx_scrollbar_pointer_shape = Qnil;
-
- staticpro (&Vpre_gc_cursor);
- Vpre_gc_cursor = Qnil;
-
- #ifdef EXTERNAL_WIDGET
- Fprovide (intern ("external-widget"));
- #endif
-
- /* this call uses only safe functions from emacs.c */
- init_x_parm_symbols ();
-
- DEFVAR_LISP ("default-x-frame-alist", &Vdefault_x_frame_alist,
- "Alist of default frame-creation parameters for X frames.\n\
- These override what is specified in the resource database and in\n\
- `default-frame-alist', but are overridden by the arguments to the\n\
- particular call to `make-frame'.\n\
- \n\
- Note: frame parameters are pretty much out-of-fashion. Using\n\
- the functions `modify-frame-parameters' and `frame-parameters' is\n\
- definitely out-of-fashion, and soon these functions will be made\n\
- obsolete. Most uses of the frame parameters below can be replaced\n\
- more flexibly with uses of a specifier, and soon, all frame parameters\n\
- will have specifier equivalents.\n\
- \n\
- Here is a list of recognized frame parameters (they can be queried and\n\
- set at any time, except as otherwise noted):\n\
- \n\
- window-id The X window ID corresponding to the\n\
- frame. May be set only at startup, and\n\
- only if external widget support was\n\
- compiled in; doing so causes the frame\n\
- to be created as an \"external widget\"\n\
- in another program that uses an existing\n\
- window in the program rather than creating\n\
- a new one.\n\
- initially-unmapped If non-nil, the frame will not be visible\n\
- when it is created. In this case, you\n\
- need to call `make-frame-visible' to make\n\
- the frame appear.\n\
- popup If non-nil, it should be a frame, and this\n\
- frame will be created as a \"popup\" frame\n\
- whose parent is the given frame. This\n\
- will make the window manager treat the\n\
- frame as a dialog box, which may entail\n\
- doing different things (e.g. not asking\n\
- for positioning, and not iconifying\n\
- separate from its parent).\n\
- inter-line-space Not currently implemented.\n\
- toolbar-shadow-thickness Thickness of toolbar shadows.\n\
- background-toolbar-color Color of toolbar background.\n\
- bottom-toolbar-shadow-color Color of bottom shadows on toolbars.\n\
- (*Not* specific to the bottom-toolbar.)\n\
- top-toolbar-shadow-color Color of top shadows on toolbars.\n\
- (*Not* specifier to the top-toolbar.)\n\
- scrollbar-height Going to be removed.\n\
- internal-border-width Width of internal border around text area.\n\
- border-width Width of external border around text area.\n\
- top Y position (in pixels) of the upper-left\n\
- outermost corner of the frame (i.e. the\n\
- upper-left of the window-manager\n\
- decorations).\n\
- left X position (in pixels) of the upper-left\n\
- outermost corner of the frame (i.e. the\n\
- upper-left of the window-manager\n\
- decorations).\n\
- border-color Color of external border around text area.\n\
- cursor-color Color of text cursor.\n\
- unsplittable Not currently implemented.\n\
- minibuffer Not currently implemented.\n\
- width See `default-frame-alist'.\n\
- height See `default-frame-alist'.\n\
- name See `default-frame-alist'.\n\
- scrollbar-pointer Doesn't really work.\n\
- pointer Doesn't really work.\n\
- \n\
- See also `default-frame-alist', which specifies parameters which apply\n\
- to all frames, not just X frames.");
- Vdefault_x_frame_alist = Qnil;
-
- x_device_methods->device_specific_frame_params = &Vdefault_x_frame_alist;
- }
-